UNPKG

@talend/react-cmf

Version:

A framework built on top of best react libraries

177 lines (168 loc) 5.84 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.defaultState = exports.default = void 0; exports.getActionWithCollectionIdAsArray = getActionWithCollectionIdAsArray; exports.getId = getId; var _immutable = require("immutable"); var _invariant = _interopRequireDefault(require("invariant")); var _constant = _interopRequireDefault(require("../constant")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } /** * @module react-cmf/lib/reducers/collectionsReducers */ const defaultState = exports.defaultState = new _immutable.Map(); /** * Get element id. If it doesn't have "id" property, we consider it as immutable. */ function getId(element) { const id = element.id; if (id === undefined) { return element.get('id'); } return id; } /* * backward compatibility, as mutateCollection action creator still use 'id' field * to represent path to collection */ function getActionWithCollectionIdAsArray(action) { if (action.collectionId || action.id) { const collectionId = action.collectionId || action.id; return { ...action, collectionId: Array.isArray(collectionId) ? collectionId : collectionId.split('.') }; } return action; } /** * addElementToCollection * * @param state current redux state * @param action redux action * @returns {object} the new state */ function addCollectionElement(state, action) { if (action.operations.add) { return action.operations.add.reduce((s, e) => { const element = s.getIn(action.collectionId); if (_immutable.List.isList(element)) { return s.setIn(action.collectionId, element.push(e)); } if (_immutable.Map.isMap(element)) { return s.setIn(action.collectionId, element.merge(e)); } return state; }, state); } return state; } function deleteListElements(state, action) { function shouldBeRemoved(element) { return action.operations.delete.indexOf(getId(element)) >= 0; } const collection = state.getIn(action.collectionId); if (collection.some(shouldBeRemoved)) { return state.setIn(action.collectionId, collection.filterNot(shouldBeRemoved)); } return state; } function deleteMapElements(state, action) { const collection = state.getIn(action.collectionId); if (action.operations.delete.some(id => collection.has(id))) { const changedCollection = action.operations.delete.reduce((collectionAccu, element) => collectionAccu.delete(element), collection); return state.setIn(action.collectionId, changedCollection); } return state; } /** * deleteElementFromCollection * * @param state current redux state * @param action redux action * @returns {object} the new state */ function deleteCollectionElement(state, action) { if (action.operations.delete) { const collection = state.getIn(action.collectionId); if (_immutable.Map.isMap(collection)) { return deleteMapElements(state, action); } else if (_immutable.List.isList(collection)) { return deleteListElements(state, action); } throw new Error('CMF collection deletion is only compatible with ImmutableJs List and Map'); } return state; } function updateListElements(state, action) { const updates = action.operations.update; const changedCollection = state.getIn(action.collectionId).map(element => updates[getId(element)] || element); return state.setIn(action.collectionId, changedCollection); } function updateMapElements(state, action) { const updates = action.operations.update; const changedCollection = Object.keys(updates).reduce((collectionAccu, id) => collectionAccu.set(id, updates[id]), state.getIn(action.collectionId)); return state.setIn(action.collectionId, changedCollection); } /** * updateCollectionElement * * @param state current redux state * @param action redux action * @returns {object} the new state */ function updateCollectionElement(state, action) { if (action.operations.update) { const collection = state.getIn(action.collectionId); if (_immutable.Map.isMap(collection)) { return updateMapElements(state, action); } else if (_immutable.List.isList(collection)) { return updateListElements(state, action); } throw new Error('CMF collection update is only compatible with ImmutableJs List and Map'); } return state; } /** * mutateCollection * * @param {object} state the current redux state * @param {object} action redux action * @returns {object} the new state */ function mutateCollection(state, action) { if (!action.operations || !state.hasIn(action.collectionId) || state.isEmpty()) { return state; } let newState = addCollectionElement(state, action); newState = deleteCollectionElement(newState, action); return updateCollectionElement(newState, action); } /** * @param {object} state the state * @param {object} action redux action * @return {object} the new state */ function collectionsReducers(state = defaultState, action = { type: '' }) { const newAction = getActionWithCollectionIdAsArray(action); switch (newAction.type) { case _constant.default.COLLECTION_ADD_OR_REPLACE: return state.setIn(newAction.collectionId, (0, _immutable.fromJS)(newAction.data)); case _constant.default.COLLECTION_REMOVE: if (!state.getIn(newAction.collectionId)) { (0, _invariant.default)(process.env.NODE_ENV === 'production', `Can't remove collection ${newAction.collectionId} since it doesn't exist.`); return state; } return state.deleteIn(newAction.collectionId); case _constant.default.COLLECTION_MUTATE: return mutateCollection(state, newAction); default: return state; } } var _default = exports.default = collectionsReducers; //# sourceMappingURL=collectionsReducers.js.map