diff options
| author | Mohamed Bassem <me@mbassem.com> | 2024-04-19 00:09:27 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-19 00:09:27 +0100 |
| commit | e0999f701cd1834c3d940113cd8dd5247c5fe95f (patch) | |
| tree | c4169a564ecd3f933e711bcc8ef7db20532174ea /packages/shared/utils | |
| parent | deba31ee010f785a9739fd4df8a64a3056c9593d (diff) | |
| download | karakeep-e0999f701cd1834c3d940113cd8dd5247c5fe95f.tar.zst | |
feature: Nested lists (#110). Fixes #62
* feature: Add support for nested lists
* prevent moving the parent to a subtree
Diffstat (limited to 'packages/shared/utils')
| -rw-r--r-- | packages/shared/utils/listUtils.ts | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/packages/shared/utils/listUtils.ts b/packages/shared/utils/listUtils.ts new file mode 100644 index 00000000..1dd3d476 --- /dev/null +++ b/packages/shared/utils/listUtils.ts @@ -0,0 +1,55 @@ +import { ZBookmarkList } from "../types/lists"; + +export interface ZBookmarkListTreeNode { + item: ZBookmarkList; + children: ZBookmarkListTreeNode[]; +} + +export type ZBookmarkListRoot = Record<string, ZBookmarkListTreeNode>; + +export function listsToTree(lists: ZBookmarkList[]) { + const idToList = lists.reduce<Record<string, ZBookmarkList>>((acc, list) => { + acc[list.id] = list; + return acc; + }, {}); + + const root: ZBookmarkListRoot = {}; + + // Prepare all refs + const refIdx = lists.reduce<Record<string, ZBookmarkListTreeNode>>( + (acc, l) => { + acc[l.id] = { + item: l, + children: [], + }; + return acc; + }, + {}, + ); + + // Build the tree + lists.forEach((list) => { + const node = refIdx[list.id]; + if (list.parentId) { + refIdx[list.parentId].children.push(node); + } else { + root[list.id] = node; + } + }); + + const allPaths: ZBookmarkList[][] = []; + const dfs = (node: ZBookmarkListTreeNode, path: ZBookmarkList[]) => { + const list = idToList[node.item.id]; + const newPath = [...path, list]; + allPaths.push(newPath); + node.children.forEach((child) => { + dfs(child, newPath); + }); + }; + + Object.values(root).forEach((node) => { + dfs(node, []); + }); + + return { allPaths, root }; +} |
