8.1 KiB
| phase | plan | subsystem | tags | dependency_graph | tech_stack | key_files | decisions | metrics | |||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 16-tablo-detail | 03 | templates |
|
|
|
|
|
|
Phase 16 Plan 03: Kanban Restyle + Etape Grouping Summary
One-liner: Added groupTasksByEtape helper and EtapeGroupHeader component to tasks.templ; restyled KanbanColumn to tasks-section layout, TaskCard to task-row layout, AddTaskTrigger to tasks-add-button; removed @EtapeStrip OOB calls from TaskCardGone/TaskCardOOB; updated all three KanbanBoard call sites to accept etapes []sqlc.Etape as 5th parameter.
Tasks Completed
| Task | Name | Commit | Files |
|---|---|---|---|
| 1 | Add groupTasksByEtape helper, EtapeGroup type, EtapeGroupHeader component; update KanbanBoard/Column signatures and restyled column/card/trigger | 084fc0e |
backend/templates/tasks.templ |
| 2 | Update all three KanbanBoard call sites (tablos.templ + handlers_tasks.go) and verify full test suite | e2ee434 |
backend/internal/web/handlers_tasks.go, backend/templates/tablos.templ |
What Was Built
Task 1 — tasks.templ:
-
EtapeGroup type: Struct with
EtapeID string,EtapeTitle string,EtapeColor string,Tasks []sqlc.Task. EtapeColor always empty (schema has no color field). -
groupTasksByEtape helper: Iterates tasks, uses
!t.EtapeID.Validto detect unassigned (pgtype.UUID nil check), converts valid UUIDs viauuid.UUID(t.EtapeID.Bytes).String()(same pattern astaskEtapeIDStringintasks_forms.go). Iterates etapes in declaration order, only adds groups with tasks. Appends unassigned group last only if any unassigned tasks exist. -
EtapeGroupHeader component: Renders
div class="etape-group-header". IfEtapeColor != ""renders color dot span with inline style. Rendersspan class="etape-group-label is-unassigned"for unassigned group (EtapeID == ""), plainetape-group-labelotherwise. -
KanbanBoard signature: Added
etapes []sqlc.Etapeas 5th parameter. Passesetapesthrough to each@KanbanColumn(...)call. -
KanbanColumn restyled: Outer
div class="kanban-column"wrapsdiv class="tasks-section". Header:div class="tasks-section-header"with left side (h3 + badge) and right side (div id="add-task-slot-{status}"containing@AddTaskTrigger). Body:div class="task-list sortable-column"— empty state usesp class="task-list-empty", else computesgroups := groupTasksByEtape(tasks, etapes)and renders@EtapeGroupHeader(group)+ task loop. -
TaskCard restyled: Inner div changed from
task-card bg-white rounded border...totask-row task-card. Drag handle removed. HTMX edit attributes moved to the outer task-row div (making the whole row clickable). Children:div class="task-check"(round checkbox),div class="task-body"(task title p),@ui.IconButtonwith trash/danger/ghost for delete confirm. -
AddTaskTrigger restyled: Button class changed from
ui-button ui-button-soft ui-button-neutral ui-button-md w-full text-left text-sm mt-2totasks-add-button. All HTMX attributes preserved unchanged. -
EtapeStrip OOB removal: Deleted
@EtapeStrip(tabloID, etapes, counts, filter, csrfToken, true)from bothTaskCardGoneandTaskCardOOB. Keptetapes []sqlc.Etapeandcounts EtapeTaskCountsparams on both signatures (avoids handler signature changes that would break tests). Added// TODO: remove etapes and counts params after Phase 16 cleanupcomments.
Task 2 — call site updates:
-
backend/templates/tablos.templTasksTabFragment:@KanbanBoard(tablo.ID, csrfToken, tasks, filter)→@KanbanBoard(tablo.ID, csrfToken, tasks, filter, etapes).etapesis already a parameter ofTasksTabFragment. -
backend/internal/web/handlers_tasks.goline 589 (single reorder path):tasks, _, _, filter, ok→tasks, etapes, _, filter, ok; KanbanBoard call updated to passetapes. -
backend/internal/web/handlers_tasks.goline 639 (batch reorder path): same change.
Verification
grep -c "groupTasksByEtape" tasks.templ → 3 (func decl + call inside KanbanColumn)
grep -c "EtapeGroupHeader" tasks.templ → 3 (templ decl + usage in KanbanColumn)
grep -c "kanban-column" tasks.templ → 1
grep -c "tasks-section" tasks.templ → 2 (tasks-section + tasks-section-header)
grep -c "task-row" tasks.templ → 1
grep -c "EtapeStrip" tasks.templ → 0
grep -c "KanbanBoard.*etapes" handlers_tasks.go → 2
grep -c "KanbanBoard.*etapes" tablos.templ → 1
go build ./backend/... → exit 0
go test ./backend/internal/web/... -count=1 → ok (all tests pass)
Deviations from Plan
Auto-fixed Issues
1. [Rule 1 - Bug] sqlc.Etape has no Color field
- Found during: Task 1 — first build attempt
- Issue: Plan specified
etape.Color.Validandetape.Color.Stringfield access onsqlc.Etape. The actual schematype Etape structhas noColorfield — onlyID, TabloID, Title, Description, Position, CreatedAt, UpdatedAt. - Fix: Set
EtapeGroup.EtapeColorto""unconditionally ingroupTasksByEtape.EtapeGroupHeaderwill not render a color dot for any group (sinceEtapeColoris always empty). Theis-unassignedlabel logic still works correctly. - Files modified:
backend/templates/tasks.templ - Commit:
084fc0e
2. [Rule 3 - Blocking] tablos.templ KanbanBoard call updated in Task 2 (not deferred)
- Found during: Task 1 —
go build ./backend/...fails after tasks_templ.go regeneration becausetablos_templ.gostill calls old 4-arg KanbanBoard - Issue: Plan intended tablos.templ to be updated in Task 2, but the templ compiler regenerates
tablos_templ.gofromtablos.templimmediately, causing a compile-time argument count mismatch. - Fix: Updated
@KanbanBoard(tablo.ID, csrfToken, tasks, filter)→@KanbanBoard(tablo.ID, csrfToken, tasks, filter, etapes)in tablos.templ during the Task 1/Task 2 boundary (before the first commit), then committed tasks.templ alone and tablos.templ + handlers_tasks.go together. The work was still split into two commits as planned. - Files modified:
backend/templates/tablos.templ - Commit:
e2ee434
Known Stubs
- EtapeGroup color dot:
EtapeColoris always""becausesqlc.Etapehas noColorfield. Theetape-group-color-dotCSS andEtapeGroupHeadercolor dot rendering are wired but will never fire unless aColorfield is added to the schema in a future phase.
Threat Flags
No new trust boundaries introduced. All changes are HTML/CSS restructuring of existing authenticated routes. T-16-03-01 through T-16-03-04 dispositions unchanged (accept).
Self-Check: PASSED
backend/templates/tasks.templ— FOUND, containsgroupTasksByEtape,EtapeGroupHeader,kanban-column,tasks-section,task-row task-card,tasks-add-button, zeroEtapeStripbackend/templates/tablos.templ— FOUND, containsKanbanBoard.*etapesbackend/internal/web/handlers_tasks.go— FOUND, contains 2xKanbanBoard.*etapes- Commit
084fc0e— FOUND (Task 1) - Commit
e2ee434— FOUND (Task 2) go build ./backend/...— exit 0go test ./backend/internal/web/... -count=1— PASSED (ok backend/internal/web + ok backend/internal/web/ui)