import React, { FC } from 'react'; import { pagePathUtils } from '@growi/core'; import { IPage } from '../../../interfaces/page'; import { ItemNode } from './ItemNode'; import Item from './Item'; import { useSWRxPageAncestorsChildren } from '../../../stores/page-listing'; import { useTargetAndAncestors } from '../../../stores/context'; import { HasObjectId } from '../../../interfaces/has-object-id'; const { isTopPage } = pagePathUtils; /* * Utility to generate initial node */ const generateInitialNodeBeforeResponse = (targetAndAncestors: Partial[]): ItemNode => { const rootPage = targetAndAncestors[targetAndAncestors.length - 1]; // the last item is the root if (!isTopPage(rootPage?.path as string)) throw new Error('/ not exist in ancestors'); const nodes = targetAndAncestors.map((page): ItemNode => { return new ItemNode(page, []); }); // update children for each node const rootNode = nodes.reduce((child, parent) => { parent.children = [child]; return parent; }); return rootNode; }; const generateInitialNodeAfterResponse = (ancestorsChildren: Record[]>, rootNode: ItemNode): ItemNode => { const paths = Object.keys(ancestorsChildren); const rootPath = paths[paths.length - 1]; // the last item is the root if (!isTopPage(rootPath)) throw new Error('rootPath must be "/"'); let currentNode = rootNode; paths.reverse().forEach((path) => { const childPages = ancestorsChildren[path]; currentNode.children = ItemNode.generateNodesFromPages(childPages); const nextNode = currentNode.children.filter((node) => { return paths.includes(node.page.path as string); })[0]; currentNode = nextNode; }); return rootNode; }; /* * ItemsTree */ const ItemsTree: FC = () => { // TODO: get from static SWR const path = '/Sandbox'; const { data: targetAndAncestors, error } = useTargetAndAncestors(); const { data: ancestorsChildrenData, error: error2 } = useSWRxPageAncestorsChildren(path); if (error != null || error2 != null) { return null; } if (targetAndAncestors == null) { return null; } let initialNode: ItemNode; /* * Before swr response comes back */ if (ancestorsChildrenData == null) { initialNode = generateInitialNodeBeforeResponse(targetAndAncestors); } /* * When swr request finishes */ else { const { ancestorsChildren } = ancestorsChildrenData; const rootPage = targetAndAncestors[targetAndAncestors.length - 1]; const rootNode = new ItemNode(rootPage); initialNode = generateInitialNodeAfterResponse(ancestorsChildren, rootNode); } const isOpen = true; return ( <> ); }; export default ItemsTree;