import * as R from 'ramda'; import { split } from '../array/split'; import { treeReduce } from '../search/treeReduce'; interface RouteAndMenu { menus: RM[]; defaultSelectedMenus: string[]; defaultOpenMenus: string[]; defaultMenu: RM; permissions: string[]; } interface DefaultConfig { primaryDefaultMenu?: string; secondaryDefaultMenu?: string; } interface BaseP

{ url: string; childMenus?: P[] | null; resourceId: string; name: string; resourceType: string; [key: string]: any; } type BaseType = Record; interface BaseMenu { name: string; origion_url: string; url?: string; children?: M[]; } export const getRoutes = < P extends BaseP

, C extends BaseType, M extends BaseMenu >( permissionList: P[], routerConfig: C, defaultConfig: DefaultConfig, pathname: string, ): RouteAndMenu => { if (R.isEmpty(permissionList) || R.isEmpty(routerConfig)) { return { menus: [], defaultSelectedMenus: [], defaultOpenMenus: [], defaultMenu: {} as M, permissions: [], }; } let paths: string[]; if (pathname !== '/' && pathname !== '/undefined' && pathname !== '/null') { paths = split('/', pathname); } else { paths = []; } let defaultOpenMenus: string[] = []; let defaultSelectedMenus: string[] = []; let defaultMenu = {}; const resetData = (item: P): M => { const currentItem = routerConfig[item.url]; if (!currentItem) { return {} as M; } const path = item.url.indexOf('/') === 0 ? item.url || '' : `/${item.url}`; const result = ({ path, param: currentItem.param || '', url: currentItem.url, name: item.resourceId, meta: { title: item.name, icon: currentItem.icon, }, component: currentItem.component, hidden: currentItem.hidden, origion_url: path, } as unknown) as M; if ( (defaultConfig?.primaryDefaultMenu && item.url === defaultConfig?.primaryDefaultMenu) || (defaultConfig?.secondaryDefaultMenu && item.url === defaultConfig?.secondaryDefaultMenu) ) { defaultOpenMenus = [item.resourceParentId]; defaultSelectedMenus = [item.resourceId]; defaultMenu = result; } return result; }; const result: M[] = []; let permissions: string[] = []; permissionList.map((item: P) => { const children = [] as M[]; const currentItem = routerConfig[item.url]; const btns = treeReduce( { key: 'resourceType', value: 'BUTTON' }, 'childMenus', item, ); if (btns && btns.length) { const urls = R.pipe(R.map(R.prop('url')))(btns); permissions = R.concat(permissions, urls) as string[]; } if (item.childMenus && item.childMenus.length) { const childMenus = treeReduce( { key: 'resourceId' }, 'childMenus', item.childMenus, ); childMenus.map((child: P) => { if (child) { const data = resetData(child); if (data && data.name) { children.push(data); } } }); } const data = resetData(item); if (currentItem) { result.push({ ...data, children, }); } }); if (paths.length && result.length) { const res = setPathToDefaultMenu(paths, result); defaultSelectedMenus = res.defaultSelectedMenus; defaultOpenMenus = res.defaultOpenMenus; defaultMenu = res.defaultMenu; } else if ( !defaultSelectedMenus.length || !defaultOpenMenus.length || !defaultMenu ) { const res = setFistChildToDefaultMenu(result); defaultSelectedMenus = res.defaultSelectedMenus; defaultOpenMenus = res.defaultOpenMenus; defaultMenu = res.defaultMenu; } return { menus: result, defaultSelectedMenus, defaultOpenMenus, defaultMenu: defaultMenu as M, permissions, }; }; const setPathToDefaultMenu = >( paths: string[], menus: M[], ) => { let defaultOpenMenus: string[] = []; let defaultSelectedMenus: string[] = []; let defaultMenu = {} as M; const openMenus = R.find(R.propEq('origion_url', `/${paths[0]}`))( menus, ) as M; if (openMenus) { defaultOpenMenus = [openMenus.name]; if (paths.length > 1 && openMenus.children && openMenus.children.length) { const defaultPath = paths.join('/'); defaultMenu = R.find( R.propEq('origion_url', `/${defaultPath}`), )(openMenus.children) as M; } else { defaultMenu = openMenus.children && openMenus.children.length ? openMenus.children[0] : (openMenus as M); } defaultSelectedMenus = defaultMenu?.name ? [defaultMenu.name] : []; } return { defaultOpenMenus, defaultSelectedMenus, defaultMenu, }; }; const setFistChildToDefaultMenu = >(menus: M[]) => { let defaultOpenMenus: string[] = []; let defaultSelectedMenus: string[] = []; let defaultMenu = {} as M; if (menus[0] && menus[0].children && menus[0].children.length) { defaultOpenMenus = [menus[0].name]; defaultSelectedMenus = [menus[0].children[0].name]; defaultMenu = menus[0].children[0]; } else if (menus[0]) { defaultOpenMenus = [menus[0]?.name as string]; defaultSelectedMenus = [menus[0]?.name as string]; defaultMenu = menus[0]; } return { defaultOpenMenus, defaultSelectedMenus, defaultMenu, }; };