From f08f06bef47aac2c9effb4cec650d99c2deb2dd7 Mon Sep 17 00:00:00 2001 From: Peter Stone Date: Sat, 18 Jul 2026 00:14:45 +0000 Subject: Rework Tasks tab: Chains section, checklist modal, project visibility The flat Tasks-tab atom list was silently dumping every chain step (locked and unlocked) and dormant bucket-pool items in as ordinary undated cards, with no chain/project context and no protection against completing a locked step out of order. - CompleteNativeTask now rejects completing a locked chain task (ErrChainTaskLocked), mapped to 400 in both the widget and web complete-atom handlers. - Chain tasks and dormant bucket items are excluded from the flat atom list; a new "Chains" section shows one card per active/paused chain with the current step and N/M progress. - New chain checklist modal (GET /chains/{id}) lists every position in order with pause/resume/abandon -- the web view originally deferred as Android-only. - Fixed a real bug this surfaced: resuming a paused chain only flipped the status flag, never unlocking the deferred successor, so a chain paused right after a completion stayed stuck forever. SetChainStatus now catches up the deferred advancement on resume, idempotently. - Atom cards gained a project-name chip for general visibility. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01EZ7ikw2ukGJFTHE3bJS7zL --- web/templates/index.html | 17 +++++++++++ web/templates/partials/chain-detail.html | 52 ++++++++++++++++++++++++++++++++ web/templates/partials/tasks-tab.html | 40 ++++++++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 web/templates/partials/chain-detail.html (limited to 'web/templates') diff --git a/web/templates/index.html b/web/templates/index.html index 19f1c7e..7be2c52 100644 --- a/web/templates/index.html +++ b/web/templates/index.html @@ -262,11 +262,15 @@ if (e.key === 'Escape') { closeActionModal(); closeTaskModal(); + closeChainModal(); } }); function closeTaskModal() { document.getElementById('task-edit-modal').classList.add('hidden'); } + function closeChainModal() { + document.getElementById('chain-view-modal').classList.add('hidden'); + } @@ -282,6 +286,19 @@ + + +
{{.BuildVersion}}
diff --git a/web/templates/partials/chain-detail.html b/web/templates/partials/chain-detail.html new file mode 100644 index 0000000..3372f03 --- /dev/null +++ b/web/templates/partials/chain-detail.html @@ -0,0 +1,52 @@ +{{define "chain-detail"}} +
+
+
+

{{.ProjectName}}

+

+ {{.Chain.Status}} + {{range $i, $t := .Tasks}}{{if $t.ChainUnlocked}} · step {{add $i 1}} of {{len $.Tasks}}{{end}}{{end}} +

+
+
+ {{if eq .Chain.Status "active"}} + + {{else if eq .Chain.Status "paused"}} + + {{end}} + +
+
+ +
+ {{range $i, $t := .Tasks}} +
+ {{if $t.Completed}} + + {{else if $t.ChainUnlocked}} + + {{else}} + 🔒 + {{end}} +
+ {{add $i 1}}. {{$t.Content}} + {{if $t.Description}} +

{{$t.Description}}

+ {{end}} +
+
+ {{end}} +
+
+{{end}} diff --git a/web/templates/partials/tasks-tab.html b/web/templates/partials/tasks-tab.html index 04c20da..b506716 100644 --- a/web/templates/partials/tasks-tab.html +++ b/web/templates/partials/tasks-tab.html @@ -5,6 +5,40 @@ hx-target="#tab-content" hx-swap="innerHTML"> + + {{if .Chains}} +
+ {{range .Chains}} +
+
+ {{if .CurrentTask}} + + {{end}} + 🔗 +
+
+

{{if .CurrentTask}}{{.CurrentTask.Content}}{{else}}{{.ProjectName}}{{end}}

+
+
+ {{.ProjectName}} · {{.Position}}/{{.Total}} + {{if eq .Chain.Status "paused"}}paused{{end}} +
+
+
+
+ {{end}} +
+ {{end}} + {{if .Atoms}}
@@ -35,6 +69,9 @@ {{end}}
+ {{if .ProjectName}} + {{.ProjectName}} + {{end}} {{if .DueDate}} {{.DueDate.Format "Jan 2"}}{{if .HasSetTime}}, {{.DueDate.Format "3:04pm"}}{{end}} {{end}} @@ -92,6 +129,9 @@ {{end}}
+ {{if .ProjectName}} + {{.ProjectName}} + {{end}} {{if .DueDate}} {{.DueDate.Format "Jan 2"}}{{if .HasSetTime}}, {{.DueDate.Format "3:04pm"}}{{end}} {{end}} -- cgit v1.2.3