UNPKG

@conveyal/commute

Version:
135 lines (118 loc) 3.89 kB
import update from 'react-addons-update' import {addToEntityMap, addEntitiesToEntityMap, deleteFromEntityMap, deleteManyFromEntityMap} from './entities' function addChildEntityToParent (parentMap, newEntity, parentIdField, childPluralName) { return update(parentMap, { [newEntity[parentIdField]]: { [childPluralName]: { $push: [newEntity._id] } } }) } export function getGenericReducerInitialState () { return { _lastUpdate: now() } } /** * Make handlers for children creation and deletion events * * @param {Object} cfg An configuration object structured as follows: * - childPluralName (String): Plural name of child (parent's child id array) * - childSingularName (String): Singular name of child (for making reducer title) * - parentIdField (String): Id field of parent in child entity * @return {Object} Reducers */ export function makeChildrenHandlers (cfg) { const reducers = {} reducers[`add ${cfg.childSingularName}`] = function (state, action) { const newEntity = action.payload return updateTime(addChildEntityToParent( state, newEntity, cfg.parentIdField, cfg.childPluralName )) } reducers[`add many ${cfg.childPluralName}`] = function (state, action) { const newEntities = action.payload let updatedState = state newEntities.forEach(newEntity => { updatedState = addChildEntityToParent( updatedState, newEntity, cfg.parentIdField, cfg.childPluralName ) }) return updateTime(updatedState) } reducers[`delete ${cfg.childSingularName}`] = function (state, action) { const entity = action.payload const childIds = state[entity[cfg.parentIdField]][cfg.childPluralName] return updateTime(update(state, { [entity[cfg.parentIdField]]: { [cfg.childPluralName]: { $set: childIds.filter((id) => id !== entity._id) } } })) } return reducers } /** * Make generic reducers for an entity type * * @param {Object} cfg An object with name and handlers parameters structured as follows: * - name: must have singular and plural keys with the corresponding strings * - handlers: An array of strings of handlers. Possible values: ['add', 'add many', 'delete', 'set', 'set many'] * @return {Object} The generated reducers */ export function makeGenericReducerHandlers (cfg) { const reducers = { 'log out' (state, action) { return updateTime({}) } } if (cfg.handlers.indexOf('add') !== -1) { reducers[`add ${cfg.name.singular}`] = function (state, action) { return updateTime(addToEntityMap(state, action.payload)) } } if (cfg.handlers.indexOf('add many') !== -1) { reducers[`add many ${cfg.name.plural}`] = function (state, action) { return updateTime(addEntitiesToEntityMap(state, action.payload)) } } if (cfg.handlers.indexOf('delete') !== -1) { reducers[`delete ${cfg.name.singular}`] = function (state, action) { return updateTime(deleteFromEntityMap(state, action.payload._id)) } } if (cfg.handlers.indexOf('delete many') !== -1) { reducers[`delete many ${cfg.name.plural}`] = function (state, action) { return updateTime(deleteManyFromEntityMap(state, action.payload)) } } if (cfg.handlers.indexOf('set') !== -1) { reducers[`set ${cfg.name.singular}`] = function (state, action) { return updateTime(addToEntityMap(state, action.payload)) } } if (cfg.handlers.indexOf('set many') !== -1) { reducers[`set ${cfg.name.plural}`] = function (state, action) { return updateTime(addEntitiesToEntityMap(state, action.payload)) } } return reducers } function now () { return (new Date()).getTime() } export function updateTime (state) { return update(state, { _lastUpdate: { $set: now() } }) }