Files
mnote/wolai-frontend/src/lib/documents.ts
T
2025-11-23 10:55:04 +08:00

64 lines
1.8 KiB
TypeScript

export interface DocumentRecord {
access_scope: "private" | "shared" | "public";
id: string;
workspace_id: string;
title: string | null;
parent_id: string | null;
sort_order: number | null;
is_starred: boolean | null;
is_template: boolean;
created_at: string;
updated_at: string | null;
}
export interface DocumentNode extends DocumentRecord {
children: DocumentNode[];
}
export function buildDocumentTree(records: DocumentRecord[]): DocumentNode[] {
const nodeMap = new Map<string, DocumentNode>();
records.forEach((record) => {
nodeMap.set(record.id, { ...record, children: [] });
});
const roots: DocumentNode[] = [];
records.forEach((record) => {
const node = nodeMap.get(record.id);
if (!node) return;
if (record.parent_id && nodeMap.has(record.parent_id)) {
nodeMap.get(record.parent_id)!.children.push(node);
} else {
roots.push(node);
}
});
const sortTree = (nodes: DocumentNode[]) => {
nodes.sort((a, b) => {
const orderA = a.sort_order ?? Number.MAX_SAFE_INTEGER;
const orderB = b.sort_order ?? Number.MAX_SAFE_INTEGER;
if (orderA !== orderB) {
return orderA - orderB;
}
return new Date(a.created_at).getTime() - new Date(b.created_at).getTime();
});
nodes.forEach((child) => sortTree(child.children));
};
sortTree(roots);
return roots;
}
export function findBreadcrumb(records: DocumentRecord[], targetId: string): DocumentRecord[] {
const map = new Map<string, DocumentRecord>();
records.forEach((item) => map.set(item.id, item));
const path: DocumentRecord[] = [];
let current: DocumentRecord | undefined = map.get(targetId);
while (current) {
path.unshift(current);
current = current.parent_id ? map.get(current.parent_id) : undefined;
}
return path;
}