xtablo-source/.planning/phases/16-tablo-detail/16-01-PLAN.md
Arthur Belleville 965ec5e5ce
docs(16): create phase 16 tablo detail plan — 4 plans, 4 waves
Phase 16 delivers DETAIL-01/02/03/04: header restyling, kanban
tasks-section layout with server-side etape grouping, and files
table component. Ends with a browser verify checkpoint.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 23:20:49 +02:00

12 KiB
Raw Blame History

phase plan type wave depends_on files_modified autonomous requirements must_haves
16-tablo-detail 01 execute 1
backend/internal/web/ui/icon_button.templ
backend/internal/web/ui/app.css
true
DETAIL-01
DETAIL-02
DETAIL-03
DETAIL-04
truths artifacts key_links
icon_button.templ UIIcon switch contains a case for 'download' that emits a download SVG arrow
icon_button.templ UIIcon switch contains a case for 'chat' that emits a speech-bubble SVG
app.css contains .tasks-section, .task-row, .task-check, .task-list, .task-body, .task-meta, .tasks-add-button CSS rules using var(--...) tokens
app.css contains .project-progress-track and .project-progress-bar CSS rules
app.css contains .tab-nav, .tab-nav-item, .tab-nav-item.is-active, .tab-nav-item:hover CSS rules
app.css contains .tablo-metadata-row and .tablo-metadata-date CSS rules
app.css contains .kanban-column and scoped .kanban-column .tasks-section-header h3 { font-size: 1rem } override
app.css contains .etape-group-header, .etape-group-color-dot, .etape-group-label CSS rules
app.css contains .task-list-empty CSS rule
templ generate && go build ./... exits 0 after changes
path provides contains
backend/internal/web/ui/icon_button.templ Download and chat icon SVG cases in UIIcon switch case "download":
path provides contains
backend/internal/web/ui/app.css All new CSS sections for Phase 16 (1925) .tasks-section {
from to via pattern
backend/internal/web/ui/icon_button.templ backend/internal/web/ui/icon_button_templ.go templ generate case "download"
from to via pattern
backend/internal/web/ui/app.css browser render static asset embed .tab-nav-item.is-active

Phase Goal

As a tablo owner, I want to see a fully restyled tablo detail page — header, kanban, etapes, and files — so that the detail view looks visually consistent with the design system established in Phases 1315.

Add the two missing icon SVG cases (`download`, `chat`) to `UIIcon` in `icon_button.templ`, and append all Phase 16 CSS sections (1925) to `app.css`. This is the shared substrate that plans 0204 build on — without it, `@ui.IconButton` with `Icon: "download"` or `Icon: "chat"` renders the icon name as raw text.

Purpose: Unblock header restyling (Discussion/Download IconButtons), kanban restyling (task-row CSS), and files restyling (table + icons). Output: Updated icon_button.templ with download and chat cases; app.css with Sections 1925 appended.

<execution_context> @/Users/arthur.belleville/Documents/perso/projects/xtablo-source/.claude/get-shit-done/workflows/execute-plan.md @/Users/arthur.belleville/Documents/perso/projects/xtablo-source/.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/ROADMAP.md @.planning/phases/16-tablo-detail/16-CONTEXT.md @.planning/phases/16-tablo-detail/16-RESEARCH.md @.planning/phases/16-tablo-detail/16-PATTERNS.md @.planning/phases/16-tablo-detail/16-UI-SPEC.md

From backend/internal/web/ui/icon_button.templ (current UIIcon switch structure):

  • Package: package ui
  • Switch starts at line ~18, cases: "plus", "grid3x3", "list", "filter", "search", "calendar", "pencil", "trash"
  • default: case emits <span>{kind}</span> (renders icon name as text — this is the bug)
  • Insert case "download": and case "chat": BEFORE the default: case

From backend/internal/web/ui/app.css (current state):

  • File is 450 lines; ends after Section 18 (project-card-top, project-avatar)
  • Line 355-361: .overview-section-heading h3, .tasks-section-header h3 shared rule exists (do NOT add a second .tasks-section-header h3 rule; add only the scoped .kanban-column .tasks-section-header h3 { font-size: 1rem; } override)
  • Sections to append: 19 (tasks-section block), 20 (progress bar), 21 (tab nav), 22 (metadata row), 23 (kanban-column wrapper), 24 (etape group), 25 (task-list-empty)
  • All token names: var(--color-surface-default), var(--color-border-subtle), var(--color-border-muted), var(--color-border-strong), var(--color-text-secondary), var(--color-text-muted), var(--color-text-faint), var(--color-text-primary), var(--color-text-brand), var(--color-text-brand-strong), var(--color-text-inverse), var(--color-surface-muted), var(--color-surface-neutral-hover), var(--color-brand-primary), var(--color-project-fallback), var(--project-color, var(--color-project-fallback))
Task 1: Add `download` and `chat` icon cases to UIIcon switch backend/internal/web/ui/icon_button.templ - backend/internal/web/ui/icon_button.templ (read entire file — ~80 lines — before editing; understand the full switch structure and the `default:` position) Read the full `icon_button.templ` file. Find the UIIcon switch's `default:` case. Insert two new cases immediately before `default:`:
Case "download": emit an SVG with `viewBox="0 0 24 24"`, `fill="none"`, `stroke="currentColor"`, `stroke-width="2"`, `stroke-linecap="round"`, `stroke-linejoin="round"`, `aria-hidden="true"`. Contents: `path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"`, `polyline points="7 10 12 15 17 10"`, `line x1="12" x2="12" y1="15" y2="3"`.

Case "chat": emit an SVG with same attributes. Contents: `path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"`.

Do NOT modify any other part of the file. Do NOT change the `default:` case or any existing cases.

After editing, run: `just generate` (or `templ generate ./backend/...`) to regenerate `icon_button_templ.go`.
grep -c 'case "download"' /Users/arthur.belleville/Documents/perso/projects/xtablo-source/backend/internal/web/ui/icon_button.templ && grep -c 'case "chat"' /Users/arthur.belleville/Documents/perso/projects/xtablo-source/backend/internal/web/ui/icon_button.templ && cd /Users/arthur.belleville/Documents/perso/projects/xtablo-source && go build ./backend/... - `icon_button.templ` contains `case "download":` with a polyline + line SVG body - `icon_button.templ` contains `case "chat":` with a path SVG body - Both new cases appear before the `default:` case in the switch - `go build ./backend/...` exits 0 (templ-generated file updated, no compile errors) - The `default:` case and all 8 existing cases are unchanged UIIcon switch contains "download" and "chat" cases; project compiles cleanly. Task 2: Append CSS Sections 1925 to app.css backend/internal/web/ui/app.css - backend/internal/web/ui/app.css (read lines 340450 to confirm the end of the file and the existing shared `.tasks-section-header h3` rule at lines 355361; verify no duplication before appending) - .planning/phases/16-tablo-detail/16-PATTERNS.md (Pattern Assignments section: "New CSS blocks to append — Blocks 1, 2, 3" — these are the verbatim CSS blocks to append) - .planning/phases/16-tablo-detail/16-UI-SPEC.md (New CSS Classes Required section — additional property values that refine the blocks) Append the following seven CSS sections to the END of `backend/internal/web/ui/app.css`. Do NOT modify any existing rules. The shared `.tasks-section-header h3` rule at lines ~355-361 already exists — do NOT add another one; only add the scoped `.kanban-column .tasks-section-header h3 { font-size: 1rem; }` override.
Append in order:

Section 19 — Tasks section (ported from go-backend): `.tasks-section`, `.tasks-section-header`, `.tasks-add-button`, `.task-list`, `.task-row`, `.task-row:hover`, `.task-check`, `.task-check.is-complete`, `.task-body`, `.task-body p`, `.task-row.is-complete .task-body p`, `.task-meta`. All values from PATTERNS.md Block 1 verbatim.

Section 20 — Progress bar: `.project-progress-track`, `.project-progress-bar`. All values from PATTERNS.md Block 2 verbatim.

Section 21 — Tab nav: `.tab-nav`, `.tab-nav-item`, `.tab-nav-item.is-active`, `.tab-nav-item:hover:not(.is-active)`. Values from PATTERNS.md Block 3 / UI-SPEC.

Section 22 — Tablo detail metadata row: `.tablo-metadata-row`, `.tablo-metadata-date`, `.tablo-metadata-date svg`. Values from PATTERNS.md Block 3 / UI-SPEC.

Section 23 — Kanban column wrapper: `.kanban-column { flex-shrink: 0; width: 18rem; }` and `.kanban-column .tasks-section-header h3 { font-size: 1rem; }`.

Section 24 — Etape group sub-headings: `.etape-group-header`, `.etape-group-color-dot`, `.etape-group-label`, `.etape-group-label.is-unassigned`. Values from PATTERNS.md Block 3 / UI-SPEC.

Section 25 — Empty task list: `.task-list-empty { color: var(--color-text-faint); font-size: 0.875rem; font-style: italic; padding: 0.75rem 1rem; }`.

Every CSS value must use `var(--...)` tokens. No hardcoded hex values. No Tailwind utility classes.
grep -c "\.tasks-section {" /Users/arthur.belleville/Documents/perso/projects/xtablo-source/backend/internal/web/ui/app.css && grep -c "\.tab-nav-item\.is-active" /Users/arthur.belleville/Documents/perso/projects/xtablo-source/backend/internal/web/ui/app.css && grep -c "\.kanban-column" /Users/arthur.belleville/Documents/perso/projects/xtablo-source/backend/internal/web/ui/app.css && grep -c "\.etape-group-header" /Users/arthur.belleville/Documents/perso/projects/xtablo-source/backend/internal/web/ui/app.css && grep -c "\.task-list-empty" /Users/arthur.belleville/Documents/perso/projects/xtablo-source/backend/internal/web/ui/app.css - `app.css` contains exactly one `.tasks-section {` rule (no duplication) - `app.css` contains `.tab-nav-item.is-active` with `border-bottom-color: var(--color-brand-primary)` and `color: var(--color-text-brand)` - `app.css` contains `.kanban-column` with `width: 18rem` - `app.css` contains `.kanban-column .tasks-section-header h3` with `font-size: 1rem` - `app.css` contains `.etape-group-header` with `background: var(--color-surface-muted)` - `app.css` contains `.task-list-empty` with `font-style: italic` - `app.css` contains `.project-progress-track` and `.project-progress-bar` - `grep -c "#[0-9a-fA-F]\{3,6\}" app.css` returns 0 for newly appended lines (no hardcoded hex in new rules) - `go build ./backend/...` exits 0 (CSS is a static asset, build verifies no templ regressions) app.css has all Phase 16 CSS sections appended; no hardcoded hex values; project compiles cleanly.

<threat_model>

Trust Boundaries

Boundary Description
Static asset → browser CSS and templ-generated HTML served as static embed; no user input processed

STRIDE Threat Register

Threat ID Category Component Disposition Mitigation Plan
T-16-01-01 Tampering app.css static embed accept CSS is embedded at build time; no runtime user modification possible; existing CSP controls unchanged
T-16-01-02 Information Disclosure SVG icon markup accept SVG icons are decorative, contain no user data; aria-hidden="true" on all decorative SVGs

No new trust boundaries. No user input, no authentication changes, no handler changes. </threat_model>

After both tasks complete: ```bash cd /Users/arthur.belleville/Documents/perso/projects/xtablo-source go test ./backend/internal/web/... -count=1 ``` All existing tests must pass. The CSS and icon changes do not affect test behavior (tests verify handler output, not CSS class names in most cases).

<success_criteria>

  • icon_button.templ has case "download": and case "chat": before default:
  • app.css has 7 new sections (1925) appended with no hardcoded hex values
  • go test ./backend/internal/web/... -count=1 passes with no new failures
  • go build ./backend/... exits 0 </success_criteria>
After completion, create `.planning/phases/16-tablo-detail/16-01-SUMMARY.md` using the summary template.