@talend/react-cmf
Version:
A framework built on top of best react libraries
177 lines (168 loc) • 5.84 kB
JavaScript
;
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