Fix: Full N-depth recursive subtask tree rendering in main list, universal custom context menu on all subtask levels, and bidirectional realtime sync
This commit is contained in:
+72
-20
@@ -20,7 +20,7 @@ export interface MockTask {
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
children: MockTask[];
|
||||
tags: { tag: { id: string; name: string; color: string } }[];
|
||||
tags?: { tag: { id: string; name: string; color: string } }[];
|
||||
}
|
||||
|
||||
const STORAGE_KEY_LISTS = "checkflow_demo_lists";
|
||||
@@ -52,7 +52,7 @@ export const INITIAL_DEMO_TASKS: MockTask[] = [
|
||||
listId: "list-1",
|
||||
parentId: "task-1",
|
||||
title: "Configure .env environment variables",
|
||||
note: null,
|
||||
note: "Database URL, NextAuth secret, and port settings",
|
||||
completed: true,
|
||||
completedAt: new Date().toISOString(),
|
||||
dueDate: null,
|
||||
@@ -60,7 +60,24 @@ export const INITIAL_DEMO_TASKS: MockTask[] = [
|
||||
sortOrder: 0,
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
children: [],
|
||||
children: [
|
||||
{
|
||||
id: "sub-1-1-1",
|
||||
listId: "list-1",
|
||||
parentId: "sub-1-1",
|
||||
title: "Database connection string verification",
|
||||
note: null,
|
||||
completed: false,
|
||||
completedAt: null,
|
||||
dueDate: null,
|
||||
priority: 2,
|
||||
sortOrder: 0,
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
children: [],
|
||||
tags: [],
|
||||
},
|
||||
],
|
||||
tags: [],
|
||||
},
|
||||
{
|
||||
@@ -87,7 +104,7 @@ export const INITIAL_DEMO_TASKS: MockTask[] = [
|
||||
listId: "list-1",
|
||||
parentId: null,
|
||||
title: "Import existing tasks from TickTick",
|
||||
note: "1. Export CSV/ICS in TickTick Settings\n2. Click 'Import Tasks' in CheckFlow Sidebar\n3. Select target project",
|
||||
note: "1. Export CSV/ICS in TickTick Settings\n2. Click user profile at bottom-left\n3. Select 'Import Tasks'",
|
||||
completed: false,
|
||||
completedAt: null,
|
||||
dueDate: null,
|
||||
@@ -98,22 +115,6 @@ export const INITIAL_DEMO_TASKS: MockTask[] = [
|
||||
children: [],
|
||||
tags: [],
|
||||
},
|
||||
{
|
||||
id: "task-3",
|
||||
listId: "list-2",
|
||||
parentId: null,
|
||||
title: "Install CheckFlow PWA on mobile home screen",
|
||||
note: "Open in Chrome/Samsung Internet -> Menu -> **Install app** or **Add to Home Screen**",
|
||||
completed: true,
|
||||
completedAt: new Date().toISOString(),
|
||||
dueDate: new Date().toISOString(),
|
||||
priority: 1,
|
||||
sortOrder: 0,
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
children: [],
|
||||
tags: [],
|
||||
},
|
||||
];
|
||||
|
||||
export function getDemoStore() {
|
||||
@@ -147,4 +148,55 @@ export function saveDemoStore(lists: MockList[], tasks: MockTask[]) {
|
||||
} catch (e) {
|
||||
console.error("Failed to save demo storage", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Recursive tree helpers for N-depth sub-tasks
|
||||
export function updateTaskInTree(tree: MockTask[], updated: MockTask): MockTask[] {
|
||||
return tree.map((node) => {
|
||||
if (node.id === updated.id) {
|
||||
return { ...updated, children: updated.children || node.children || [] };
|
||||
}
|
||||
if (node.children && node.children.length > 0) {
|
||||
return { ...node, children: updateTaskInTree(node.children, updated) };
|
||||
}
|
||||
return node;
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteTaskInTree(tree: MockTask[], idToDelete: string): MockTask[] {
|
||||
return tree
|
||||
.filter((node) => node.id !== idToDelete)
|
||||
.map((node) => {
|
||||
if (node.children && node.children.length > 0) {
|
||||
return { ...node, children: deleteTaskInTree(node.children, idToDelete) };
|
||||
}
|
||||
return node;
|
||||
});
|
||||
}
|
||||
|
||||
export function addTaskToTree(tree: MockTask[], parentId: string | null, newTask: MockTask): MockTask[] {
|
||||
if (!parentId) {
|
||||
return [...tree, newTask];
|
||||
}
|
||||
return tree.map((node) => {
|
||||
if (node.id === parentId) {
|
||||
const currentChildren = node.children || [];
|
||||
return { ...node, children: [...currentChildren, newTask] };
|
||||
}
|
||||
if (node.children && node.children.length > 0) {
|
||||
return { ...node, children: addTaskToTree(node.children, parentId, newTask) };
|
||||
}
|
||||
return node;
|
||||
});
|
||||
}
|
||||
|
||||
export function findTaskInTree(tree: MockTask[], id: string): MockTask | null {
|
||||
for (const node of tree) {
|
||||
if (node.id === id) return node;
|
||||
if (node.children && node.children.length > 0) {
|
||||
const found = findTaskInTree(node.children, id);
|
||||
if (found) return found;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user