UNPKG

@adaptabletools/adaptable

Version:

Powerful AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements

127 lines (126 loc) 5.18 kB
import { isArray } from '../../Utilities/Extensions/ArrayExtensions'; import { isObject, merge, mergeWith, } from '../../Utilities/Extensions/ObjectExtensions'; import { AdaptableLogger } from '../../agGrid/AdaptableLogger'; import AdaptableHelper from '../../Utilities/Helpers/AdaptableHelper'; function customizer(objValue, srcValue) { if (isArray(objValue)) { if (!Array.isArray(srcValue)) { return srcValue; } const length = srcValue ? srcValue.length : null; const result = mergeWith(objValue, srcValue, customizer); if (length != null) { result.length = length; } return result; } } export function AddStateSource(stateObject = {}, source) { const traverseStateObject = (object) => { Object.values(object).forEach((value) => { if (AdaptableHelper.isAdaptableObject(value) && value.Source == null) { value.Source = source; } if (value !== null && typeof value === 'object') { traverseStateObject(value); } }); }; traverseStateObject(stateObject); return stateObject; } export function ProcessKeepUserDefinedRevision(configState, currentUserState) { const traverseStateObject = (configObject, stateObject) => { Object.entries(configObject).forEach(([key, configValue]) => { const stateValue = stateObject[key]; if (Array.isArray(configValue) && Array.isArray(stateValue)) { const userDefinedItems = stateValue.filter((item) => { return AdaptableHelper.isAdaptableObject(item) && item.Source !== 'InitialState'; }); configObject[key] = configValue.concat(userDefinedItems); } else { if (configValue !== null && typeof configValue === 'object' && typeof stateValue === 'object') { traverseStateObject(configValue, stateValue); } } }); }; traverseStateObject(configState, currentUserState); return configState; } function deepClone(obj) { return JSON.parse(JSON.stringify(obj)); } export function MergeStateFunction(oldState, newState) { if (newState === '') { newState = {}; } const initialState = AddStateSource(oldState, 'InitialState'); let state = newState; if (!state || typeof state !== 'object') { AdaptableLogger.consoleWarnBase('State is something different than expected; expected an object, but received: ', state); state = {}; } for (const initialStateModuleName in initialState) { if (!state[initialStateModuleName]) { const { Revision, ...moduleState } = initialState[initialStateModuleName]; state[initialStateModuleName] = moduleState; } } for (const stateModuleName in state) { if (initialState[stateModuleName] != undefined) { const stateRevision = state[stateModuleName].Revision ?? 0; const initialStateRevision = initialState[stateModuleName].Revision ?? 0; const stateRevisionKey = typeof stateRevision === 'object' ? stateRevision.Key : stateRevision; const initialStateRevisionBehaviour = typeof initialStateRevision === 'object' ? initialStateRevision.Behavior : 'Override'; const initialStateRevisionKey = typeof initialStateRevision === 'object' ? initialStateRevision.Key : initialStateRevision; if (initialStateRevisionKey > stateRevisionKey) { if (initialStateRevisionBehaviour === 'Override') { state[stateModuleName] = initialState[stateModuleName]; } else { state[stateModuleName] = ProcessKeepUserDefinedRevision(deepClone(initialState[stateModuleName]), state[stateModuleName]); } } } } const finalState = AddStateSource(state, 'User'); return finalState; } export function MergeState(oldState, newState) { const result = Object.assign({}, oldState); for (const key in newState) { if (!newState.hasOwnProperty(key)) { continue; } const value = newState[key]; if (!result.hasOwnProperty(key)) { result[key] = isObject(value) && !Array.isArray(value) ? merge({}, value) : value; continue; } const oldValue = result[key]; if (isObject(value) && !Array.isArray(value)) { result[key] = mergeWith({}, oldValue, value, customizer); } else { result[key] = value; } } return result; } let initialState; export const mergeReducer = (rootReducer, LOAD_STATE_TYPE) => { let finalReducer = rootReducer; finalReducer = (state, action) => { if (action.type === LOAD_STATE_TYPE) { initialState = initialState ?? state; state = MergeState(initialState, action.State); action.State = state; } return rootReducer(state, action); }; return finalReducer; };