import * as R from 'ramda'; import { YLocation, Route, HistoryState } from './router.interface'; import { RouterAction, RouterState } from './reducer.interface'; import { reducePath, getRoute } from './utils'; export const initialState: RouterState = { history: [], current: {} as unknown as YLocation, currentRute: {} as unknown as HistoryState, routes: {} as unknown as Route, currentPath: '', historyRoute: {} }; export const reducer = (state: RouterState, action: RouterAction) => { switch (action.type) { case 'register': { const { data } = action.payload; const newRoute = reducePath(data, state.routes); return { ...state, routes: { ...state.routes, ...newRoute, } }; } case 'update_current': { const {pathname, search = '', moduleData, deleteModuleName} = action.payload.data; const {routes, history, historyRoute} = state; const current = getRoute(pathname, routes, moduleData); let newHistoryRoute = {...historyRoute}; let newHistory = history; let newRoutes = routes; if(current.parentPath){ if(!newHistory.includes(current.parentPath)) { newHistory.push(current.parentPath); } } if(!newHistory.includes(current.path)) { newHistory.push(current.path); if(current.moduleName) { newHistoryRoute = { ...newHistoryRoute, [current.moduleName]: { ...newHistoryRoute[current.moduleName], [current.path]: { url: `${pathname}${search}`, path: current.path, title: current.title || '遥望云 ', parentPath: current.parentPath || '', grandPath: current.grandPath || '', } } } } } current.parentTitle = moduleData ? moduleData.moduleName : '遥望云'; if(deleteModuleName){ const deleteRoute = newHistoryRoute[deleteModuleName]; newHistory = newHistory.filter((item: string) => !deleteRoute[item]); newHistory = newHistory.filter((item: string) => !item.includes(`/${deleteModuleName}/`)); newHistoryRoute = R.omit([deleteModuleName], newHistoryRoute); const keys = Object.keys(newRoutes); keys.map((key) => { if(key.includes(`/${deleteModuleName}/`)){ newRoutes = R.omit([key], newRoutes) } }); } return { ...state, current, history: [...newHistory], historyRoute: {...newHistoryRoute}, currentPath: current.path, routes: {...newRoutes} }; } case 'update_changed': { const {newHistory, newHistoryRoute} = action.payload.data; const {history, historyRoute} = state; const currentHistory = Array.from(new Set(history.concat(newHistory))) || []; return { ...state, history: [...currentHistory], historyRoute: { ...historyRoute, ...newHistoryRoute } }; } case 'get_routes': { return state; } case 'pop': { const {history, current, prev} = action.payload.data; const {moduleName, path} = current || state.current; const {historyRoute} = state; const currentHistory = historyRoute[moduleName] || {}; historyRoute[moduleName] = R.omit([prev], currentHistory) return { ...state, current: current || state.current, history: [...history], currentPath: path, historyRoute } } default: return state; } };