Files
2022-12-09 08:36:26 -06:00

326 lines
10 KiB
JavaScript

import {createAction, handleActions} from 'redux-actions'
import {fromJS} from 'immutable'
import * as categoriesApi from '../../../api/sidebarCategoriesApi'
import * as feedsApi from '../../../api/feedsApi'
import {addAlert} from '../common/alerts'
import {thunkAction} from '../../utils/common'
import * as helpers from '../../utils/helpers/sidebar'
import {getRestrictions} from '../common/auth'
import {actions as searchActions} from './search'
import {actions as searchFiltersActions} from './searchByFilters'
/*
* Constants
* */
export const TYPES = {
FOLDER: 'folder',
FEED: 'feed',
CLIP_ARTICLE: 'clipArticle'
}
const NS = '[Sidebar]'
const GET_SIDEBAR_CATEGORIES = `${NS} Get categories`
const ADD_CLIPPINGS_FEED = `${NS} Add clippings feed`
const ADD_CATEGORY = `${NS} Add category`
const RENAME_FEED = `${NS} Rename feed`
const RENAME_CATEGORY = `${NS} Rename category`
const TOGGLE_EXPORT_FEED = `${NS} Toggle export feed`
const TOGGLE_EXPORT_CATEGORY = `${NS} Toggle export category`
const MOVE_FEED = `${NS} Move feed`
const MOVE_CATEGORY = `${NS} Move category`
const DELETE_FEED = `${NS} Delete feed`
const DELETE_CATEGORY = `${NS} Delete category`
const SET_CATEGORIES = `${NS} Set categories`
export const SET_FILTERED_CATEGORIES = 'SET_FILTERED_CATEGORIES'
export const CLEAR_FILTERED_CATEGORIES = 'CLEAR_FILTERED_CATEGORIES'
export const SHOW_DELETE_POPUP = 'SHOW_DELETE_POPUP'
export const HIDE_DELETE_POPUP = 'HIDE_DELETE_POPUP'
export const SHOW_RENAME_POPUP = 'SHOW_RENAME_POPUP'
export const HIDE_RENAME_POPUP = 'HIDE_RENAME_POPUP'
export const SHOW_ADD_CATEGORY_POPUP = 'SHOW_ADD_CATEGORY_POPUP'
export const HIDE_ADD_CATEGORY_POPUP = 'HIDE_ADD_CATEGORY_POPUP'
export const SHOW_ADD_CLIPPINGS_POPUP = 'SHOW_ADD_CLIPPINGS_POPUP'
export const HIDE_ADD_CLIPPINGS_POPUP = 'HIDE_ADD_CLIPPINGS_POPUP'
/*
* Actions
* */
export const getSidebarCategories = thunkAction(GET_SIDEBAR_CATEGORIES, ({token, fulfilled}) => {
return categoriesApi
.getCategories(token)
.then((categories) => {
fulfilled(categories)
})
})
export const setFilteredCategories = createAction(SET_FILTERED_CATEGORIES, (filteredCategories) => filteredCategories)
export const _clearFilteredCategories = createAction(CLEAR_FILTERED_CATEGORIES)
export const clearFilteredCategories = () => {
return (dispatch, state) => {
document.getElementById('sidebar-search').value = ''
dispatch(_clearFilteredCategories())
}
}
export const setCategories = createAction(SET_CATEGORIES, (changedCategories) => changedCategories)
export const showDeletePopup = createAction(SHOW_DELETE_POPUP, (itemId, itemType, itemName, parentId) => {
return {itemId, itemType, itemName, parentId}
})
export const hideDeletePopup = createAction(HIDE_DELETE_POPUP)
export const showRenamePopup = createAction(SHOW_RENAME_POPUP, (itemId, itemType, itemName, parentId) => {
return {itemId, itemType, itemName, parentId}
})
export const hideRenamePopup = createAction(HIDE_RENAME_POPUP)
export const showAddCategoryPopup = createAction(SHOW_ADD_CATEGORY_POPUP, (parentId) => ({parentId}))
export const hideAddCategoryPopup = createAction(HIDE_ADD_CATEGORY_POPUP)
export const showAddClippingsFeedPopup = createAction(SHOW_ADD_CLIPPINGS_POPUP, (parentId) => ({parentId}))
export const hideAddClippingsFeedPopup = createAction(HIDE_ADD_CLIPPINGS_POPUP)
export const addCategory = thunkAction(ADD_CATEGORY, (name, parentId, {token, dispatch, getState, fulfilled}) => {
return categoriesApi
.addCategory(token, {name: name, parent: parentId})
.then((newCategory) => {
fulfilled(newCategory)
const newCategories = helpers.addCategory(getState(), parentId, newCategory)
dispatch(setCategories(newCategories))
dispatch(clearFilteredCategories())
})
})
export const moveCategory = thunkAction(MOVE_CATEGORY, (category, newCategoryId, {token, dispatch, fulfilled}) => {
const draggedCategoryId = category.id
const notCategoryItself = newCategoryId !== draggedCategoryId
const notCategoryInChild = !helpers.checkIfDraggedCategoryDragToItsChild(category.childes, newCategoryId)
// check if category trying to move to it's child or itself
if (notCategoryItself && notCategoryInChild) {
return categoriesApi
.moveCategory(token, undefined, draggedCategoryId, newCategoryId)
.then((response) => {
fulfilled()
const newCategories = fromJS(response.data)
dispatch(setCategories(newCategories))
})
}
})
export const renameCategory = thunkAction(RENAME_CATEGORY, (categoryId, categoryName, parentId, {token, dispatch, getState, fulfilled}) => {
return categoriesApi
.renameCategory(token, {name: categoryName, parent: parentId}, categoryId)
.then(() => {
fulfilled()
const newCategories = helpers.renameCategory(getState(), categoryId, categoryName)
dispatch(setCategories(newCategories))
dispatch(clearFilteredCategories())
})
})
export const deleteCategory = thunkAction(DELETE_CATEGORY, (categoryId, {token, dispatch, getState, fulfilled}) => {
return categoriesApi
.deleteCategory(token, undefined, categoryId)
.then(() => {
fulfilled()
const newCategories = helpers.deleteCategory(getState(), categoryId)
dispatch(setCategories(newCategories))
dispatch(clearFilteredCategories())
})
})
export const addClippingsFeed = thunkAction(ADD_CLIPPINGS_FEED, (feedName, categoryId, {token, dispatch, fulfilled, getState}) => {
const payload = {
feed: {
name: feedName,
category: categoryId,
subType: 'clip_feed'
}
}
return feedsApi
.createFeed(token, payload)
.then((newFeed) => {
fulfilled(newFeed)
const newCategories = helpers.addFeed(getState(), categoryId, newFeed)
dispatch(setCategories(newCategories))
dispatch(getRestrictions())
dispatch(addAlert({
type: 'notice',
transKey: 'saveFeed',
id: 'saveFeed'
}))
})
})
export const moveFeed = thunkAction(MOVE_FEED, (feedId, categoryId, {token, dispatch, fulfilled}) => {
return feedsApi
.moveFeed(token, undefined, feedId, categoryId)
.then((response) => {
fulfilled()
const newCategories = fromJS(response.data)
dispatch(setCategories(newCategories))
})
})
export const toggleExportFeed = thunkAction(TOGGLE_EXPORT_FEED, (feedId, isExported, {token, dispatch, fulfilled}) => {
return feedsApi
.toggleExportFeed(token, {export: isExported}, feedId)
.then(() => {
fulfilled()
dispatch(getSidebarCategories())
dispatch(getRestrictions())
})
})
const toggleExportCategory = thunkAction(TOGGLE_EXPORT_CATEGORY, (categoryId, isExported, {token, dispatch, fulfilled}) => {
return feedsApi
.toggleExportCategory(token, {export: isExported}, categoryId)
.then(() => {
fulfilled()
dispatch(getSidebarCategories())
})
})
export const renameFeed = thunkAction(RENAME_FEED, (feedId, newName, parentId, {token, dispatch, fulfilled, getState}) => {
return feedsApi
.renameFeed(token, {name: newName}, feedId)
.then(() => {
fulfilled()
const newCategories = helpers.renameFeed(getState(), feedId, newName, parentId)
dispatch(setCategories(newCategories))
})
})
export const deleteFeed = thunkAction(DELETE_FEED, (feedId, categoryId, {token, dispatch, getState, fulfilled}) => {
const currentFeedId = getState().getIn(['appState', 'search', 'activeFeed', 'id'])
const isCurrent = currentFeedId && (parseInt(currentFeedId) === parseInt(feedId))
return feedsApi
.deleteFeed(token, undefined, feedId)
.then(() => {
fulfilled()
if (isCurrent) {
dispatch(searchActions.setNewSearch())
dispatch(searchFiltersActions.renewSearchBy())
}
const newCategories = helpers.deleteFeed(getState(), categoryId, feedId)
dispatch(setCategories(newCategories))
dispatch(getRestrictions())
dispatch(clearFilteredCategories())
})
})
export const actions = {
getSidebarCategories,
setFilteredCategories,
clearFilteredCategories,
setCategories,
addCategory,
addClippingsFeed,
moveCategory,
moveFeed,
deleteFeed,
deleteCategory,
renameFeed,
renameCategory,
showDeletePopup,
hideDeletePopup,
showRenamePopup,
hideRenamePopup,
showAddCategoryPopup,
hideAddCategoryPopup,
showAddClippingsFeedPopup,
hideAddClippingsFeedPopup,
toggleExportFeed,
toggleExportCategory
}
/*
* State
* */
export const initialState = fromJS({
areCategoriesLoaded: false,
categories: [],
filteredCategories: [],
areFeedsFiltered: false,
popupVisible: {
'delete': false,
rename: false,
addCategory: false,
addClippingsFeed: false
},
popupItems: {
'delete': {}, //feed or category
rename: {}, //feed or category
addCategory: {}, //{parentId}
addClippingsFeed: {} //{parentId}
}
})
/*
* Reducers
* */
const hidePopup = (type) => (state) => {
return state
.setIn(['popupVisible', type], false)
.setIn(['popupItems', type], {})
}
const showPopup = (type) => (state, {payload}) => {
return state
.setIn(['popupVisible', type], true)
.setIn(['popupItems', type], payload)
}
export default handleActions({
[`${GET_SIDEBAR_CATEGORIES} fulfilled`]: (state, { payload }) => {
const response = payload.data
return state.merge({
'categories': response,
'areCategoriesLoaded': true
})
},
[SET_FILTERED_CATEGORIES]: (state, { payload: filteredCategories }) => {
return state.merge({
'filteredCategories': filteredCategories,
'areFeedsFiltered': true
})
},
[CLEAR_FILTERED_CATEGORIES]: (state, { payload }) => {
return state.merge({
'filteredCategories': [],
'areFeedsFiltered': false
})
},
[SET_CATEGORIES]: (state, { payload: changedCategories }) => {
return state.set('categories', changedCategories)
},
[SHOW_DELETE_POPUP]: showPopup('delete'),
[HIDE_DELETE_POPUP]: hidePopup('delete'),
[SHOW_RENAME_POPUP]: showPopup('rename'),
[HIDE_RENAME_POPUP]: hidePopup('rename'),
[SHOW_ADD_CATEGORY_POPUP]: showPopup('addCategory'),
[HIDE_ADD_CATEGORY_POPUP]: hidePopup('addCategory'),
[SHOW_ADD_CLIPPINGS_POPUP]: showPopup('addClippingsFeed'),
[HIDE_ADD_CLIPPINGS_POPUP]: hidePopup('addClippingsFeed')
}, initialState)