| 
1 | 1 | import * as R from "remeda";  | 
2 | 2 | 
 
  | 
3 |  | -import BackendAPISchemas from "../schemas/backendAPI";  | 
4 |  | - | 
5 |  | -export const buildNestedSiteMap: (flattened: BackendAPISchemas.FlattenedSiteMapSchema[]) => {  | 
6 |  | -  [key: string]: BackendAPISchemas.NestedSiteMapSchema;  | 
7 |  | -} = (flattened) => {  | 
8 |  | -  const map: Record<string, BackendAPISchemas.NestedSiteMapSchema> = {};  | 
9 |  | -  const roots: BackendAPISchemas.NestedSiteMapSchema[] = [];  | 
 | 3 | +type GFlatSiteMap = {  | 
 | 4 | +  id: string;  | 
 | 5 | +  route_code: string;  | 
 | 6 | +  order: number;  | 
 | 7 | +  parent_sitemap: string | null;  | 
 | 8 | +  page: string;  | 
 | 9 | +  hide: boolean;  | 
 | 10 | +};  | 
 | 11 | +type GNestedSiteMap<T = GFlatSiteMap> = T & { children: GNestedSiteMap<T>[] };  | 
 | 12 | +type MultiRootGNestedSiteMap<T = GFlatSiteMap> = { [key: string]: GNestedSiteMap<T> };  | 
10 | 13 | 
 
  | 
11 |  | -  const siteMapIdRouteCodeMap = flattened.reduce(  | 
12 |  | -    (acc, item) => {  | 
13 |  | -      acc[item.id] = item.route_code;  | 
14 |  | -      return acc;  | 
15 |  | -    },  | 
16 |  | -    {} as Record<string, string>  | 
17 |  | -  );  | 
 | 14 | +const _sortChildren = <T extends GFlatSiteMap>(children: GNestedSiteMap<T>[]) => {  | 
 | 15 | +  return children  | 
 | 16 | +    .sort((a, b) => a.order - b.order)  | 
 | 17 | +    .map(<Z extends GNestedSiteMap<T>>(child: Z): Z => ({ ...child, children: _sortChildren(child.children) }));  | 
 | 18 | +};  | 
18 | 19 | 
 
  | 
19 |  | -  flattened.forEach((item) => {  | 
20 |  | -    map[item.id] = {  | 
21 |  | -      ...item,  | 
22 |  | -      children: {},  | 
23 |  | -    };  | 
24 |  | -  });  | 
 | 20 | +export const buildNestedSiteMap = <T extends GFlatSiteMap>(flat: T[]) => {  | 
 | 21 | +  const roots: GNestedSiteMap<T>[] = [];  | 
 | 22 | +  const flatWithChildren = flat.map((item) => ({ ...item, children: [] as GNestedSiteMap<T>[] }));  | 
 | 23 | +  const map = flatWithChildren.reduce((a, i) => ({ ...a, [i.id]: i }), {} as MultiRootGNestedSiteMap<T>);  | 
25 | 24 | 
 
  | 
26 |  | -  flattened.forEach((item) => {  | 
 | 25 | +  flat.forEach((item) => {  | 
27 | 26 |     if (item.parent_sitemap) {  | 
28 |  | -      map[item.parent_sitemap].children[siteMapIdRouteCodeMap[item.id]] = map[item.id];  | 
 | 27 | +      map[item.parent_sitemap].children.push(map[item.id]);  | 
29 | 28 |     } else {  | 
30 | 29 |       roots.push(map[item.id]);  | 
31 | 30 |     }  | 
32 | 31 |   });  | 
33 | 32 | 
 
  | 
34 |  | -  return roots.reduce(  | 
35 |  | -    (acc, item) => {  | 
36 |  | -      acc[item.route_code] = item;  | 
37 |  | -      return acc;  | 
38 |  | -    },  | 
39 |  | -    {} as Record<string, BackendAPISchemas.NestedSiteMapSchema>  | 
40 |  | -  );  | 
 | 33 | +  return roots  | 
 | 34 | +    .map((root) => ({ ...root, children: _sortChildren(root.children) }))  | 
 | 35 | +    .reduce((a, i) => ({ ...a, [i.route_code]: i }), {} as MultiRootGNestedSiteMap<T>);  | 
41 | 36 | };  | 
42 | 37 | 
 
  | 
43 |  | -export const findSiteMapUsingRoute = (  | 
44 |  | -  route: string,  | 
45 |  | -  siteMapData: BackendAPISchemas.NestedSiteMapSchema  | 
46 |  | -): BackendAPISchemas.NestedSiteMapSchema | null => {  | 
47 |  | -  const currentRouteCodes = ["", ...route.split("/").filter((code) => !R.isEmpty(code))];  | 
 | 38 | +export const buildFlatSiteMap = <T extends GNestedSiteMap>(nested: GNestedSiteMap<T>) => {  | 
 | 39 | +  const flat: T[] = [];  | 
48 | 40 | 
 
  | 
49 |  | -  let currentSitemap: BackendAPISchemas.NestedSiteMapSchema | null | undefined = siteMapData.children[currentRouteCodes[0]];  | 
50 |  | -  if (currentSitemap === undefined) return null;  | 
 | 41 | +  const traverse = (node: GNestedSiteMap<T>) => {  | 
 | 42 | +    flat.push(node);  | 
 | 43 | +    node.children.forEach(traverse);  | 
 | 44 | +  };  | 
51 | 45 | 
 
  | 
52 |  | -  for (const routeCode of currentRouteCodes.slice(1)) {  | 
53 |  | -    if ((currentSitemap = currentSitemap.children[routeCode] || null) === null) {  | 
54 |  | -      break;  | 
55 |  | -    }  | 
56 |  | -  }  | 
57 |  | -  return currentSitemap;  | 
 | 46 | +  traverse(nested);  | 
 | 47 | +  return flat;  | 
58 | 48 | };  | 
59 | 49 | 
 
  | 
60 | 50 | export const parseCss = (t: unknown): React.CSSProperties => {  | 
 | 
0 commit comments