Adapt todo widget hierarchy

This commit is contained in:
jb
2026-08-26 17:04:19 -04:00
parent 1a437f50b4
commit 91a019de29
3 changed files with 73 additions and 36 deletions
+40 -21
View File
@@ -92,11 +92,11 @@ test("collapses completed widget subtrees while keeping list trees expanded", ()
const widgetLines = renderWidgetTree(state.list(), plainTheme as never, 80).map(stripAnsi);
assert.deepEqual(widgetLines, [
" I. ○ Release",
" ├─ 1. ○ Completed branch · 2/2 done",
" └─ 2. ○ Open branch",
" └─ ○ Open leaf",
" II. ○ Pending parent · 1/1 done",
" ├─ I. ○ Release",
" │ ├─ 1. ○ Completed branch · 2/2 done",
" │ └─ 2. ○ Open branch",
" │ └─ ○ Open leaf",
" └─ II. ○ Pending parent · 1/1 done",
]);
const fullTree = renderTree(state.list(), plainTheme as never, 80).map(stripAnsi);
@@ -109,7 +109,26 @@ test("collapses completed widget subtrees while keeping list trees expanded", ()
assert.ok(reopened.some((line) => line.includes("Done two")));
});
test("uses sibling-local Roman and numeric widget labels while leaving leaf sub-items unlabeled", () => {
test("uses only the outline levels needed while leaving leaf tasks unlabeled", () => {
const flatState = new TaskState(() => 0);
flatState.add([{ name: "First leaf" }, { name: "Second leaf" }]);
assert.deepEqual(renderWidgetTree(flatState.list(), plainTheme as never, 80).map(stripAnsi), [
" ├─ ○ First leaf",
" └─ ○ Second leaf",
]);
const twoLevelState = new TaskState(() => 0);
twoLevelState.add([
{ name: "First group", children: [{ name: "First nested leaf" }] },
{ name: "Second group", children: [{ name: "Second nested leaf" }] },
]);
assert.deepEqual(renderWidgetTree(twoLevelState.list(), plainTheme as never, 80).map(stripAnsi), [
" ├─ 1. ○ First group",
" │ └─ ○ First nested leaf",
" └─ 2. ○ Second group",
" └─ ○ Second nested leaf",
]);
const state = new TaskState(() => 0);
state.add([
{ name: "Category one" },
@@ -127,15 +146,15 @@ test("uses sibling-local Roman and numeric widget labels while leaving leaf sub-
const lines = renderWidgetTree(state.list(), plainTheme as never, 80).map(stripAnsi);
assert.deepEqual(lines, [
" I. ○ Category one",
" II. ○ Category two",
" III. ○ Category three",
" IV. ○ Category four",
" ├─ 1. ○ First item",
" │ └─ ○ Leaf sub-item",
" └─ 2. ○ Second item",
" V. ○ Category five",
" └─ 1. ○ Reset item numbering",
" ├─ I. ○ Category one",
" ├─ II. ○ Category two",
" ├─ III. ○ Category three",
" ├─ IV. ○ Category four",
" │ ├─ 1. ○ First item",
" │ │ └─ ○ Leaf sub-item",
" │ └─ 2. ○ Second item",
" └─ V. ○ Category five",
" └─ 1. ○ Reset item numbering",
]);
const narrow = renderWidgetTree(state.list(), plainTheme as never, 18);
@@ -143,7 +162,7 @@ test("uses sibling-local Roman and numeric widget labels while leaving leaf sub-
const statusPriority = renderWidgetTree(state.list(), plainTheme as never, 6).map(stripAnsi);
assert.match(statusPriority[3] ?? "", /○/);
const childStatusPriority = renderWidgetTree(state.list(), plainTheme as never, 8).map(stripAnsi);
const childStatusPriority = renderWidgetTree(state.list(), plainTheme as never, 10).map(stripAnsi);
assert.match(childStatusPriority[4] ?? "", /○/);
const timedState = new TaskState(() => 0);
@@ -194,11 +213,11 @@ test("renumbers widget labels after task reordering and reparenting", () => {
const lines = renderWidgetTree(state.list(), plainTheme as never, 80).map(stripAnsi);
assert.deepEqual(lines, [
" I. ○ Category B",
" ├─ 1. ○ A2",
" └─ 2. ○ B1",
" II. ○ Category A",
" └─ 1. ○ A1",
" ├─ 1. ○ Category B",
" │ ├─ ○ A2",
" │ └─ ○ B1",
" └─ 2. ○ Category A",
" └─ ○ A1",
]);
});