39 lines
1.8 KiB
TypeScript
39 lines
1.8 KiB
TypeScript
import type { MdtodoTaskRecord } from "@/api";
|
|
|
|
export type TreeKeyAction = "previous" | "next" | "expand" | "collapse" | "parent" | "none";
|
|
|
|
export function taskParentRefs(task: MdtodoTaskRecord, tasks: MdtodoTaskRecord[]): string[] {
|
|
const byRef = new Map(tasks.map((item) => [item.taskRef, item]));
|
|
const parents: string[] = [];
|
|
const visited = new Set<string>();
|
|
let parentRef = task.parentTaskRef || null;
|
|
while (parentRef && !visited.has(parentRef)) {
|
|
visited.add(parentRef);
|
|
parents.unshift(parentRef);
|
|
parentRef = byRef.get(parentRef)?.parentTaskRef || null;
|
|
}
|
|
if (parents.length) return parents;
|
|
const taskId = task.taskId || task.rxxId || "";
|
|
const parts = taskId.split(".");
|
|
const ids = parts.slice(1).map((_, index) => parts.slice(0, index + 1).join("."));
|
|
return ids.map((id) => tasks.find((item) => (item.taskId || item.rxxId) === id)?.taskRef).filter((value): value is string => Boolean(value));
|
|
}
|
|
|
|
export function visibleTasks(tasks: MdtodoTaskRecord[], collapsed: Set<string>, selectedTaskRef: string | null): MdtodoTaskRecord[] {
|
|
const selected = tasks.find((task) => task.taskRef === selectedTaskRef);
|
|
const selectedPath = new Set(selected ? [...taskParentRefs(selected, tasks), selected.taskRef] : []);
|
|
return tasks.filter((task) => {
|
|
const hiddenByCollapsedParent = taskParentRefs(task, tasks).some((parentRef) => collapsed.has(parentRef));
|
|
return !hiddenByCollapsedParent || selectedPath.has(task.taskRef);
|
|
});
|
|
}
|
|
|
|
export function treeKeyAction(key: string, expanded: boolean, hasChildren: boolean): TreeKeyAction {
|
|
if (key === "ArrowUp") return "previous";
|
|
if (key === "ArrowDown") return "next";
|
|
if (key === "ArrowRight" && hasChildren && !expanded) return "expand";
|
|
if (key === "ArrowLeft" && hasChildren && expanded) return "collapse";
|
|
if (key === "ArrowLeft") return "parent";
|
|
return "none";
|
|
}
|