feat: 展示 TaskTree 分组完成度
This commit is contained in:
@@ -54,6 +54,7 @@ export type TaskGroupOverview = {
|
||||
taskCount: number;
|
||||
subtaskCount: number;
|
||||
subsubtaskCount: number;
|
||||
completedCount: number;
|
||||
reportCount: number;
|
||||
startAt: string | null;
|
||||
dueAt: string | null;
|
||||
|
||||
@@ -145,6 +145,7 @@ export class TaskTreeStore {
|
||||
COUNT(DISTINCT t.id) FILTER (WHERE t.kind='task')::int AS task_count,
|
||||
COUNT(DISTINCT t.id) FILTER (WHERE t.kind='subtask')::int AS subtask_count,
|
||||
COUNT(DISTINCT t.id) FILTER (WHERE t.kind='subsubtask')::int AS subsubtask_count,
|
||||
COUNT(DISTINCT t.id) FILTER (WHERE t.status='completed')::int AS completed_count,
|
||||
COUNT(DISTINCT r.id)::int AS report_count,
|
||||
MIN(CASE
|
||||
WHEN t.id IS NULL THEN NULL
|
||||
@@ -696,7 +697,7 @@ async function schemaIsCurrent(pool: pg.Pool): Promise<boolean> {
|
||||
}
|
||||
|
||||
function groupRow(row: any): TaskGroup { return { id: row.id, name: row.name, description: row.description, createdAt: iso(row.created_at), updatedAt: iso(row.updated_at) }; }
|
||||
function overviewRow(row: any): TaskGroupOverview { return { group: groupRow(row), taskCount: Number(row.task_count), subtaskCount: Number(row.subtask_count), subsubtaskCount: Number(row.subsubtask_count), reportCount: Number(row.report_count), startAt: nullableIso(row.start_at), dueAt: nullableIso(row.due_at) }; }
|
||||
function overviewRow(row: any): TaskGroupOverview { return { group: groupRow(row), taskCount: Number(row.task_count), subtaskCount: Number(row.subtask_count), subsubtaskCount: Number(row.subsubtask_count), completedCount: Number(row.completed_count), reportCount: Number(row.report_count), startAt: nullableIso(row.start_at), dueAt: nullableIso(row.due_at) }; }
|
||||
function taskRow(row: any): TaskItem { return { id: row.id, groupId: row.group_id, parentId: row.parent_id, kind: row.kind, title: row.title, description: row.description, status: row.status, startAt: nullableIso(row.start_at), dueAt: nullableIso(row.due_at), sortOrder: row.sort_order, createdAt: iso(row.created_at), updatedAt: iso(row.updated_at) }; }
|
||||
function milestoneRow(row: any): Milestone { return { id: row.id, groupId: row.group_id, taskId: row.task_id, title: row.title, occursAt: iso(row.occurs_at), createdAt: iso(row.created_at) }; }
|
||||
function reportRow(row: any): ExecutionReport { return { id: row.id, taskId: row.task_id, title: row.title, body: row.body, status: row.status, createdAt: iso(row.created_at) }; }
|
||||
|
||||
@@ -217,6 +217,7 @@ test("native PostgreSQL store exposes overview and three task levels", async ()
|
||||
assert.equal(overview?.taskCount, 1);
|
||||
assert.equal(overview?.subtaskCount, 3);
|
||||
assert.equal(overview?.subsubtaskCount, 1);
|
||||
assert.equal(overview?.completedCount, 1);
|
||||
assert.equal(overview?.reportCount, 1);
|
||||
assert.equal(overview?.startAt, new Date(timelineStart).toISOString());
|
||||
assert.equal(overview?.dueAt, new Date(timelineDue).toISOString());
|
||||
|
||||
Reference in New Issue
Block a user