UNPKG

keystone

Version:

Web Application Framework and Admin GUI / Content Management System built on Express.js and Mongoose

232 lines (226 loc) 4.98 kB
import assign from 'object-assign'; import List from '../../../../utils/List'; import { SELECT_LIST, ITEMS_LOADED, LOAD_ITEMS, ITEM_LOADING_ERROR, SET_CURRENT_PAGE, QUERY_HAS_CHANGED, SET_ROW_ALERT, RESET_DRAG_PAGE, RESET_DRAG_ITEMS, SET_DRAG_ITEM, SET_DRAG_INDEX, DRAG_MOVE_ITEM, } from '../constants'; import { DELETE_ITEM, } from '../../Item/constants'; const initialState = { loadingRef: null, loadCounter: 0, currentList: null, loading: false, ready: false, error: null, data: {}, items: { results: [], count: null, }, page: { size: null, index: undefined, }, rowAlert: { success: false, fail: false, }, drag: { page: 1, item: false, clonedItems: false, index: false, }, }; // Rekey the lists in the state with their paths for easier matching with the // URL parameters const initialLists = Keystone.lists; for (const name in initialLists) { if ({}.hasOwnProperty.call(initialLists, name)) { const currentList = initialLists[name]; initialState.data[currentList.path] = new List(currentList); initialState.data[currentList.path].items = { results: [], count: null, }; } } /** * Manage all lists */ function lists (state = initialState, action) { switch (action.type) { case SELECT_LIST: const list = state.data[action.id]; list.id = action.id; let items = { results: [], count: null, }; // If we have cached items, instead of resetting state.items put the // cached items in the state if (list.items.count !== null) { items = list.items; } return assign({}, state, { currentList: list, ready: false, items: items, page: { ...state.page, index: 1, size: list.perPage, }, }); case LOAD_ITEMS: let loading = true; let ready = state.ready; // If we have cached items ready, don't show a loading indicator // while we fetch the new items in the background if (state.items.count !== null && loading === false) { loading = false; ready = true; } return assign({}, state, { loading, ready, loadCounter: action.loadCounter, }); case ITEMS_LOADED: // Cache the items in state.data so we can show the already existing // items on the next round trip while fetching the new items in the // background const cachedList = state.data[state.currentList.id]; cachedList.items = action.items; return assign({}, state, { loading: false, ready: true, error: null, items: action.items, data: { ...state.data, [state.currentList.id]: cachedList, }, loadCounter: 0, }); case ITEM_LOADING_ERROR: return assign({}, state, { loading: true, ready: true, error: action.err, loadCounter: 0, }); case DELETE_ITEM: const newItems = { results: state.items.results.filter((el) => (el.id !== action.id)), count: state.items.count - 1, }; const newCachedList = state.data[state.currentList.id]; newCachedList.items = newItems; return assign({}, state, { items: newItems, data: { ...state.data, [state.currentList.id]: newCachedList, }, }); case SET_CURRENT_PAGE: console.log(action.index); return assign({}, state, { loading: true, page: { ...state.page, index: action.index, }, }); case SET_ROW_ALERT: if (action.data.reset === true) { return assign({}, state, { rowAlert: { success: false, fail: false, }, }); } return assign({}, state, { rowAlert: { ...state.rowAlert, ...action.data, }, }); case RESET_DRAG_PAGE: return assign({}, state, { drag: { ...state.drag, page: state.page.index, }, }); case RESET_DRAG_ITEMS: return assign({}, state, { drag: { ...state.drag, clonedItems: state.items, }, }); case SET_DRAG_ITEM: return assign({}, state, { drag: { ...state.drag, item: action.item, }, }); case SET_DRAG_INDEX: return assign({}, state, { drag: { ...state.drag, index: action.index, }, }); case QUERY_HAS_CHANGED: const index = parseInt(action.parsedQuery.currentPage) || 1; return assign({}, state, { loading: true, page: { ...state.page, index, }, }); case DRAG_MOVE_ITEM: // TODO: option to use manageMode for sortOrder const currentItems = state.items.results; const item = currentItems[action.prevIndex]; // Remove item at prevIndex from array and save that array in // itemsWithoutItem let itemsWithoutItem = currentItems .slice(0, action.prevIndex) .concat( currentItems.slice( action.prevIndex + 1, currentItems.length ) ); // Add item back in at new index itemsWithoutItem.splice(action.newIndex, 0, item); return assign({}, state, { items: { ...state.items, results: itemsWithoutItem, }, }); default: return state; } } export default lists;