2017-07-10 13:42:58 -07:00

163 lines
4.4 KiB
JavaScript

import _ from 'lodash';
import { mapEntitiesToIds } from 'wherehows-web/reducers/utils';
const { merge, union } = _;
// Initial state for entities (metrics, flows, datasets)
const _initialState = {
count: null,
page: null,
itemsPerPage: null,
totalPages: null,
query: {
urn: '',
page: ''
},
byId: {},
byPage: {},
byUrn: {}
};
/**
* Ensure we deep clone since this shape is shared amongst entities
* @return {Object}
*/
const initializeState = () => JSON.parse(JSON.stringify(_initialState));
/**
* Merges previous entities and a new map of ids to entities into a new map
* @param {String} entityName
*/
const appendEntityIdMap = (
entityName /**
*
* @param {Object} prevEntities current list of ids mapped to entities
* @param {Object} props
* @props {Array} props[entityName] list of received entities
*/
) => (prevEntities, props) => merge({}, prevEntities, mapEntitiesToIds(props[entityName]));
/**
* Appends a list of child entity ids for a given urn. urn is null for top level entities
* @param {String} entityName
*/
const appendUrnIdMap = (
entityName
/**
* @param {Object} urnEntities current mapping of Urns to ids
* @param {Object} props payload with new objects containing id, and urn prop
*/
) => (urnEntities, { parentUrn = null, [entityName]: entities = [] }) =>
Object.assign({}, urnEntities, {
[parentUrn]: union(urnEntities[parentUrn], entities.mapBy('id'))
});
/**
* Appends a list of child entities ids for a given name. name is null for top level entities
* @param {String} entityName
*/
const appendNamedIdMap = entityName => (nameEntities, { parentName = null, [entityName]: entities = [] }) =>
Object.assign({}, nameEntities, {
[parentName]: union(nameEntities[parentName], entities.mapBy('id'))
});
/**
* Returns a curried function that receives entityName to lookup on the props object
* @param {String} entityName
* @return {Function}
*/
const entitiesToPage = (
entityName
/**
* a new map of page numbers to datasetIds
* @param {Object} pagedEntities
* @param {Object} props
* @props {Array} props[entityName] list of received entities
* @return {Object} props.page page the page that contains the returned list of entities
*/
) => (pagedEntities = {}, props) => {
const entities = props[entityName];
const { page } = props;
return Object.assign({}, pagedEntities, {
[page]: union(pagedEntities[page], entities.mapBy('id'))
});
};
/**
* Maps a urn to a list of child nodes from the list api
* @param {Object} state
* @param {Array} nodes
* @param {String} parentUrn
* @return {*}
*/
const urnsToNodeUrn = (state, { nodes = [], parentUrn = null } = {}) => {
const { nodesByUrn } = state;
return Object.assign({}, nodesByUrn, {
[parentUrn]: union(nodes)
});
};
/**
* Maps a name to a list of child nodes from the list api
* @param {Object} state
* @param {Array} nodes
* @param {String} parentName
* @return {*}
*/
const namesToNodeName = (state, { nodes = [], parentName = null } = {}) => {
const { nodesByName } = state;
return Object.assign({}, nodesByName, {
[parentName]: union(nodes)
});
};
/**
* Takes an identifier for an entity and returns a reducing function with the entityName as context
* @param {String} entityName
*/
const receiveEntities = (
entityName /**
* entities (flows|metrics|datasets) for the ActionTypes.RECEIVE_PAGED_[ENTITY_NAME] action
* @param {Object} state previous state for datasets
* @param {Object} payload data received through ActionTypes.RECEIVE_PAGED_[ENTITY_NAME]
* @return {Object}
*/
) => (state, payload = {}) => {
return appendEntityIdMap(entityName)(state, payload);
};
/**
*
* @param {String} entityName
*/
const createUrnMapping = entityName => (state, payload = {}) => {
return appendUrnIdMap(entityName)(state, payload);
};
/**
* Curries an entityName into a function to append named entity entities
* @param {String} entityName
*/
const createNameMapping = entityName => (state, payload = {}) => {
return appendNamedIdMap(entityName)(state, payload);
};
/**
* Appends a list of entities to a page
* @param {String} entityName
*/
const createPageMapping = entityName => (state, payload = {}) => {
return entitiesToPage(entityName)(state, payload);
};
export {
initializeState,
namesToNodeName,
urnsToNodeUrn,
receiveEntities,
createUrnMapping,
createPageMapping,
createNameMapping
};