import { omit } from '../../utils/helpers'; import { ACTIONS } from './constants'; import type { PortalType } from './contexts'; import type { ActionTypes, AddUpdatePortalAction, RemovePortalAction, } from './types'; type State = Record>; const registerHostIfNotExist = (state: State, hostName: string): State => { if (!(hostName in state)) { return { ...state, [hostName]: [], }; } return { ...state }; }; const deregisterHost = (state: State, hostName: string): State => { return { ...omit([hostName], state) }; }; const addUpdatePortal = ( state: Record>, hostName: string, portalName: string, node: React.ReactNode ) => { const newState = registerHostIfNotExist(state, hostName); const index = newState[hostName].findIndex( (item) => item.name === portalName ); if (index !== -1) { return { ...newState, [hostName]: newState[hostName].map((item, i) => { if (index === i) { return { ...item, node, }; } return item; }), }; } return { ...newState, [hostName]: [ ...newState[hostName], { name: portalName, node, }, ], }; }; const removePortal = ( state: Record>, hostName: string, portalName: string ) => { if (!(hostName in state)) { return { ...state }; } return { ...state, [hostName]: state[hostName].filter((item) => item.name !== portalName), }; }; export const reducer = ( state: Record>, action: ActionTypes ) => { const { type } = action; switch (type) { case ACTIONS.REGISTER_HOST: return registerHostIfNotExist(state, action.hostName); case ACTIONS.DEREGISTER_HOST: return deregisterHost(state, action.hostName); case ACTIONS.ADD_UPDATE_PORTAL: return addUpdatePortal( state, action.hostName, (action as AddUpdatePortalAction).portalName, (action as AddUpdatePortalAction).node ); case ACTIONS.REMOVE_PORTAL: return removePortal( state, action.hostName, (action as RemovePortalAction).portalName ); default: return { ...state }; } };