Skip to content

UX: collapse task rows — every task renders a full always-expanded form #102

Closed

Description

@alexeygrigorev

Collapse workflow-detail task rows into scannable lines with progressive disclosure

Status: pending
Tags: enhancement, frontend, design, P1
Depends on: None
Blocks: None

Groomed from a live UX audit (logged in as Grace, real 15-task Newsletter
workflow). This was the #1 over-complication: every task in the workflow-detail
checklist renders its full action form, always expanded, so the checklist
cannot be scanned. A 15-task bundle renders 5711px tall on desktop and 10109px
on mobile. Evidence: .tmp/screenshots/ux-audit/14-bundle-onetask.png,
11-after-start-newsletter.png, 22-m-bundle.png.

Scope

The workflow-detail checklist (renderBundleTasksTable / buildTaskRow in
backend/src/public/app.js, currently ~lines 4246-4545, plus supporting CSS in
backend/src/pages/index.html) must adopt progressive disclosure. At rest each
task should be one scannable line. The completion, evidence, required-link,
required-file, waiting, skip-closure, and assistant controls that buildTaskRow
appends today should be hidden until the operator expands or opens that task.

This is presentation-only: no task API, data model, completion-gating, or
proof-blocking logic changes. All controls that exist today must still be
reachable and functional after expand — this issue reorganizes disclosure, it
does not remove capability.

Serves JTBD 1 (start the day with one queue), JTBD 3 (know what is blocking a
workflow — "Completed tasks are retained for audit but do not distract from
active work"), and JTBD 5 (complete with proof — proof controls remain, just
revealed on demand).

Acceptance Criteria

  • At rest, each task row in the workflow-detail checklist renders as a single
    scannable line showing: completion checkbox, task title (with the
    instructions icon when present), due date, assignee (when set), and a
    status/queue pill (e.g. Overdue / Today / Waiting / Missing evidence /
    Done) derived from the existing dashboardQueueLabels helper.
  • Each collapsed row shows exactly one primary next-action affordance
    (expand/"Complete" for a ready task, "Add link"/"Add evidence" when proof
    is missing, "Follow up" when waiting) instead of the full inline editor.
  • The completion-proof block, required-link input, required-file input,
    skip-closure ("Close as") dropdown, "Save evidence" button, waiting form,
    and assistant controls are hidden by default and revealed only when the
    row is expanded or opened.
  • Expanding a row reveals every control that buildTaskRow renders today,
    and all of them remain fully functional (save link, attach file, save
    evidence, mark waiting, follow-up actions, request assistant).
  • Completion gating is unchanged: a task whose required link/file/evidence is
    missing still cannot be checked done, and the "why completion is blocked"
    message is still shown (revealed on expand, and/or via the disabled
    checkbox title).
  • Done tasks remain grouped under the existing "Done (N)" section and stay
    collapsed by default.
  • A 15-task bundle's checklist is materially shorter at rest than today
    (target: collapsed checklist height well under the current 5711px desktop /
    10109px mobile) as shown by before/after screenshots at 1280px and mobile
    width.
  • Expand/collapse state is operable by keyboard and exposes an accessible
    expanded/collapsed state (e.g. aria-expanded); the existing
    accessibility.spec.js checks still pass.

Test Scenarios

Scenario: Checklist is scannable at rest

Given: Grace opens a bundle started from the Newsletter template with 15 tasks
When: the workflow-detail page finishes loading
Then: each task shows one line (checkbox, title, date, assignee, status pill,
one next-action affordance) and no completion-note, "What changed", "Close as",
"Save evidence", or waiting form is visible until a row is expanded.

Scenario: Expanding a row exposes the full editor

Given: a collapsed task that requires a link
When: Grace expands the row
Then: the required-link input, save button, and completion controls appear, and
saving a link works exactly as before.

Scenario: Completion stays blocked without proof

Given: a task with a required link and no link saved
When: Grace tries to check it done from the collapsed row
Then: completion is blocked and the app explains which proof is missing.

Scenario: Done tasks stay out of the way

Given: a bundle with several done tasks
When: the checklist renders
Then: done tasks appear collapsed under "Done (N)" and do not expand the active
checklist height.

Out of Scope

Dependencies

Verification

  • From backend/: npm run typecheck.
  • From backend/: npm run test:e2e — at minimum bundle-detail.spec.js,
    follow-up-actions.spec.js, and accessibility.spec.js; add/extend a spec
    asserting rows are collapsed at rest and expand to reveal controls.
  • Playwright screenshots of a 15-task bundle detail at 1280px and mobile width
    (collapsed and one row expanded) saved under
    .tmp/screenshots/ux-audit/ and read to confirm no truncation, 404, broken
    layout, or missing controls.

Activity

  1. added
    enhancementNew or improved functionality
    needs groomingRaw intake that needs PM grooming
    P1Important
    designDesign and UX
    and removed
    needs groomingRaw intake that needs PM grooming
    on Jul 2, 2026
  2. alexeygrigorev commented on Jul 2, 2026

    @alexeygrigorev
    MemberAuthor

    Grooming: sequencing & implementation order for the UX over-complication set (#102-#106)

    All five UX-audit issues are groomed and needs grooming is removed. They all
    touch backend/src/public/app.js (a ~6551-line vanilla-JS SPA), so ordering
    matters to avoid merge collisions.

    Dependency / collision graph

    #102 buildTaskRow (workflow-detail rows)      ── independent function
    #103 renderDashboardTaskTable (queue rows)    ── related pattern to #102
    #104 renderTemplates + first-run + Bundles    ── mostly independent functions
    #105 renderDashboard + queue grouping (IA)    ── Depends on #103 (same region)
    #106 bundleRiskSummary + grouping + backend   ── Depends on #105 (at-risk semantics)
    

    Recommended implementation order

    1. UX: collapse task rows — every task renders a full always-expanded form #102 (highest-value quick win, self-contained).
    2. UX: dashboard Daily Queue should surface next-action button, not embed the completion editor #103 (quick win; reuses UX: collapse task rows — every task renders a full always-expanded form #102's pattern).
    3. UX: consolidate workflow-start into the Templates library (add Start action; remove scattered launcher forms) #104 (can run in parallel with UX: collapse task rows — every task renders a full always-expanded form #102 in a separate worktree).
    4. UX: dashboard IA — lead with Today / Overdue / Follow-ups due / At-risk, demote intake counters #105 (after UX: dashboard Daily Queue should surface next-action button, not embed the completion editor #103; same dashboard region).
    5. UX: freshly-started workflows show all-red at t=0 — add scheduled/not-started state + richer bundle cards #106 (last; after UX: dashboard IA — lead with Today / Overdue / Follow-ups due / At-risk, demote intake counters #105).

    Parallel-safe pairs

    Every issue is UI-facing: acceptance requires before/after Playwright
    screenshots under .tmp/screenshots/ux-audit/ (read for truncation/404/broken
    layout) plus the named backend/ Playwright specs; #106 additionally needs
    backend unit tests and export round-trip if a bundle field is added.

  3. alexeygrigorev commented on Jul 2, 2026

    @alexeygrigorev
    MemberAuthor

    Software Engineer handoff — READY FOR TEST

    Implemented progressive disclosure for the workflow-detail task checklist
    (buildTaskRow). At rest every task is now one scannable line; all editing
    controls live in a collapsed disclosure region revealed on demand.

    Approach

    • buildTaskRow now renders a summary (checkbox stays in its always-visible
      column; title + instructions icon; date; assignee; status/queue pills from the
      existing dashboardQueueLabels helper — plus a Done pill for done tasks) and
      a single next-action disclosure toggle (<button data-task-expand> with
      aria-expanded/aria-controls, keyboard-operable). The completion-proof block,
      required-link/file inputs, "Close as" dropdown, "Save evidence", waiting form,
      instruction context, completion evidence, history, artifact refs, and assistant
      controls all moved into a .task-checklist-details region that is hidden at
      rest and toggled open on click/Enter/Space.
    • The toggle label is the one primary next-action: Add link / Add file /
      Add evidence
      (missing proof), Follow up (waiting), Details (done),
      Expand (ready) — via new taskNextActionLabel helper. Pill colours via new
      queuePillModifier helper.
    • focusTaskRow auto-expands a deep-linked target task so ?taskId= links land
      on an open row.
    • No task/bundle API, data-model, completion-gating, or proof logic changed —
      the existing end-of-function event bindings still bind by data-* selector.
    • CSS added to index.html for the summary/heading layout, pill variants,
      disclosure toggle (min-height 32px for tap targets), and the details region.

    Files changed

    • backend/src/public/app.js — buildTaskRow refactor, focusTaskRow
      auto-expand, taskNextActionLabel + queuePillModifier helpers.
    • backend/src/pages/index.html — progressive-disclosure CSS block.
    • backend/e2e/bundle-detail.spec.js — expandRow helper; expand rows before
      touching required-link / completion-proof controls; new collapse/expand +
      keyboard/aria-expanded test.
    • backend/e2e/follow-up-actions.spec.js — expandRow helper; expand workflow
      row before follow-up controls and before the post-reload waiting-form check.
    • backend/e2e/podcast-operator-slice.spec.js — podcastRow auto-expands;
      post-reload proof/waiting markers asserted via attached-state instead of
      visibility (rows re-collapse after reload).

    Verification

    • npm run typecheck — exit 0 (tsc x3, no errors).
    • npm test (Node unit suite) — 1109 passed / 0 failed (160 suites).
    • npx playwright test bundle-detail follow-up-actions accessibility —
      23 passed / 0 failed (includes the new UX: collapse task rows — every task renders a full always-expanded form #102 collapse/expand test).
    • npx playwright test podcast-operator-slice — passed (one pre-existing
      flake at line 42, the podcast start-button loading-state race, before any
      task-row interaction; green on re-run).
    • npx playwright test home-dashboard — passed (one pre-existing flake in a
      dashboard-queue save test at :897, on renderDashboardTaskTable which this
      issue does not touch; green on re-run in 1.1s; CI uses retries=2).

    Screenshots (.tmp/screenshots/ux-audit/)

    • 102-desktop-collapsed.png — 1280px: 15 tasks each one scannable line
      (checkbox, title, date, assignee, contextual pills, one next-action); Done
      grouped under "DONE (1)". Checklist height 1006px (was 5711px).
    • 102-desktop-expanded.png — two rows expanded showing revealed required-link
      input + Save + waiting form below a dashed separator; others stay collapsed.
    • 102-mobile-collapsed.png — 390px: all rows collapsed, no overflow. Checklist
      height 1170px (was 10109px).
    • 102-mobile-expanded.png — 390px expanded row: completion-note editor, Save
      evidence, missing-proof message, waiting form stacked cleanly, no overlap.

    Acceptance criteria — all 8 verified (checked in issue body)

    1. One scannable line (checkbox/title/date/assignee/status pill) — screenshots.
    2. Exactly one primary next-action affordance per row — screenshots.
    3. Proof/link/file/skip/waiting/assistant controls hidden by default — new spec
      asserts .task-checklist-details and .required-link-input hidden at rest.
    4. Expand reveals every control and they stay functional — bundle-detail,
      follow-up-actions, podcast slice exercise save-link/attach-file/save-evidence/
      mark-waiting/follow-up/assistant after expand.
    5. Completion gating unchanged — checkbox stays disabled without proof and the
      missing-proof message still shows (specs pass).
    6. Done tasks grouped under "Done (N)", collapsed by default — screenshots + the
      existing grouping spec still passes.
    7. 15-task checklist materially shorter — 1006px desktop / 1170px mobile vs
      5711px / 10109px.
    8. Keyboard-operable + aria-expanded; accessibility.spec.js passes — new spec
      focuses the toggle and expands/collapses with Enter and checks aria-expanded.

    Notes

    • backend/e2e/.auth-state.json is an untracked Playwright harness artifact
      (regenerated by playwright.config.js/global-setup), not part of this change.
    • Not committed or pushed — awaiting Tester + PM acceptance.
  4. alexeygrigorev commented on Jul 2, 2026

    @alexeygrigorev
    MemberAuthor

    Tester verdict: TEST PASS

    Verified the uncommitted implementation in the main checkout (backend/src/public/app.js, backend/src/pages/index.html, and three e2e specs). Untracked Playwright artifacts (backend/e2e/.auth-state.json, backend/test-results/) ignored as instructed.

    Commands run

    Command (from backend/) Result
    npm run typecheck exit 0 (tsc x3, no errors)
    npm test (Node unit suite) 1109 passed / 0 failed — 160 suites, exit 0
    npx playwright test bundle-detail follow-up-actions accessibility 23 passed / 0 failed (incl. the new #102 collapse/expand + keyboard/aria-expanded spec at bundle-detail.spec.js:1149)
    npx playwright test podcast-operator-slice home-dashboard 37 passed, 1 failed on first run
    npx playwright test home-dashboard (re-run) 37 passed / 0 failed

    Flake analysis: the single first-run failure was home-dashboard.spec.js:862 "Dashboard task rows save comment evidence from the queue" at markDashboardTaskDone (checkbox.check race). That test exercises renderDashboardTaskTable (the dashboard Daily Queue) — code this diff does not touch (that surface is #103). It passed clean on re-run (37/0); CI runs with retries=2. Confirmed pre-existing flake, not a regression from #102. Podcast slice passed in the combined run.

    Screenshots (fresh, captured by Tester on a real 15-task Newsletter bundle instantiated from the template; all read)

    Under .tmp/screenshots/:

    • 102-desktop-collapsed.png (1280px) — 15 tasks, each one scannable line: checkbox, title + instructions icon, date, assignee, contextual pills (Overdue / Today / Missing evidence / At risk), one next-action button (Add link / Add file / Add evidence). No inline forms. Collapsed task-row block height ~1115px (was 5711px).
    • 102-desktop-expanded.png (1280px) — two rows expanded revealing template/SOP reference, completion note, "Close as" dropdown, Save evidence, required-link input + Save, missing-proof message, and waiting form (Mark waiting); all other rows stay one-liners. No overlap.
    • 102-mobile-collapsed.png (390px) — compact stacked cards, one next-action each, no overflow/overlap. Collapsed height ~2078px (was 10109px).
    • 102-mobile-expanded.png (390px) — expanded rows stack the full editor vertically, no truncation or overlap.
    • 102-deeplink-autoexpand.png — ?taskId= deep link auto-expands the target row (verified aria-expanded=true, details visible), target-row highlight intact.

    No 404s, error pages, broken layout, text overlap, or missing controls in any screenshot.

    Acceptance criteria — all 8 verified

    1. Scannable single line at rest — PASS (desktop/mobile collapsed screenshots: checkbox, title+icon, date, assignee, status/queue pill).
    2. Exactly one primary next-action affordance per row — PASS (screenshots show single Add link/Add file/Add evidence/Follow up button; no inline editor).
    3. Proof block / required-link / required-file / "Close as" / Save evidence / waiting form / assistant controls hidden by default — PASS (new spec asserts .task-checklist-details and .required-link-input hidden at rest; collapsed screenshots confirm).
    4. Expand reveals every control and they stay functional — PASS (bundle-detail exercises required-link save + skip-closure + completion-proof after expandRow; follow-up-actions exercises follow-up/waiting after expand; podcast slice exercises attach-file + mark-waiting after expand; expanded screenshots show all controls).
    5. Completion gating unchanged — PASS (bundle-detail.spec.js:160 checkbox disabled until required link filled; :753 missing-proof message shown and completes only after proof/skip — both pass).
    6. Done tasks grouped under "Done (N)", collapsed by default — PASS (bundle-detail.spec.js:997 "Done tasks grouped at bottom" passes; grouping logic unchanged).
    7. 15-task checklist materially shorter — PASS (~1115px desktop / ~2078px mobile vs 5711px / 10109px).
    8. Keyboard-operable + aria-expanded — PASS (new spec focuses the toggle, expands/collapses with Enter, asserts aria-expanded flips; accessibility.spec.js 6/6 pass).

    No scope drift: presentation-only refactor of buildTaskRow + CSS + test updates; no task/bundle API, data-model, or completion-gating changes.

    TEST PASS.

  5. alexeygrigorev commented on Jul 2, 2026

    @alexeygrigorev
    MemberAuthor

    PM acceptance: ACCEPTED

    Final user-perspective acceptance for #102 (collapse workflow-detail task rows
    into scannable lines with progressive disclosure). Reviewed the groomed spec,
    both agent comments, the uncommitted git diff (backend/src/public/app.js,
    backend/src/pages/index.html, three e2e specs), and read all five Tester
    screenshots.

    Operator daily-loop assessment (JTBD 1 / 3 / 5)

    • Scannable at rest (JTBD 1): Confirmed on 102-desktop-collapsed.png and
      102-mobile-collapsed.png. Each of the 15 tasks is one line — completion
      checkbox, title + instructions icon, due date, assignee, contextual queue
      pills (Overdue / Today / Missing evidence / At risk / Done), and one
      next-action button. Collapsed checklist ~1115px desktop / ~2078px mobile vs
      5711px / 10109px before. This is a genuine, large scannability win.
    • Right single next-action per state: taskNextActionLabel maps state to the
      correct affordance — Add link (required link), Add file (required
      file), Add evidence (other proof), Follow up (waiting), Details
      (done), Expand (ready). Matches AC2 (which explicitly allows "Expand" for a
      ready task). The label communicates the next click and reveals the exact
      control on expand.
    • Coherent editor after expand (JTBD 5): 102-desktop-expanded.png,
      102-mobile-expanded.png, and 102-deeplink-autoexpand.png show every control
      present and cleanly stacked — template/SOP reference, completion note, "Close
      as" dropdown, Save evidence, required-link input + Save, waiting form, and the
      orange missing-proof message. No overlap or truncation on desktop or 390px
      mobile.
    • Completion gating preserved (JTBD 5): The checkbox stays in the
      always-visible column with disabled + title intact, and the missing-proof
      message ("Add … link to complete") is revealed on expand. bundle-detail
      specs confirm the checkbox is disabled until proof is saved/skipped and only
      then enabled. No data-model, API, or gating logic changed — presentation-only.
    • Done tasks (JTBD 3): Grouped under "Done (N)", collapsed by default, with a
      neutral "Details" toggle — retained for audit without cluttering active work.
    • Deep link: focusTaskRow auto-expands the ?taskId= target
      (aria-expanded=true, target highlight intact) so links land on an open row.
    • Accessibility: Disclosure is a real <button> with
      aria-expanded/aria-controls, keyboard-operable; the new spec flips state
      with Enter and accessibility.spec.js passes.

    Verification evidence (Tester)

    • npm run typecheck exit 0; npm test 1109/1109; bundle-detail +
      follow-up-actions + accessibility 23/23 including the new collapse/expand +
      keyboard spec (bundle-detail.spec.js:1149). The single first-run e2e flake
      was on home-dashboard.spec.js (renderDashboardTaskTable) — a different
      surface owned by UX: dashboard Daily Queue should surface next-action button, not embed the completion editor #103, not touched by this diff — and was green on re-run with
      CI retries=2. Accepted as a pre-existing flake, not a regression.

    Scope / drift

    No drift. All 8 acceptance criteria met. Presentation-only refactor of
    buildTaskRow + CSS + test updates; no task/bundle API, DynamoDB, or
    completion-gating changes; dashboard queue rows (#103) and bundle/at-risk
    semantics (#105/#106) correctly left out of scope.

    Minor notes for later (non-blocking, do not fix here)

    ACCEPTED. Ready for Software Engineer to commit with Closes #102.

  6. added a commit that references this issue on Aug 14, 2026
    d13ebbc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1ImportantdesignDesign and UXenhancementNew or improved functionalityfrontendFrontend UI

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions