Skip to content

feat(dashboard): show tickets as a full page instead of a rail tab (#1144)#1226

Merged
brillout merged 14 commits into
mainfrom
claude/github-issue-1144-ko7ye7
Jul 26, 2026
Merged

feat(dashboard): show tickets as a full page instead of a rail tab (#1144)#1226
brillout merged 14 commits into
mainfrom
claude/github-issue-1144-ko7ye7

Conversation

@brillout

@brillout brillout commented Jul 26, 2026

Copy link
Copy Markdown
Member

Summary

  • Tickets is now a full-width page instead of a tab in the 27rem right rail, reached from a "Tickets" row in the sidebar below Overview — no project needs to be selected first.
  • The page is cross-project: every registered project's tickets/*.md backlog gets its own full-width section (new collectAllTickets/onAllTickets) — the table spans the whole pane rather than sharing it with grid columns — each with its own Import/Update-from-GitHub bar (the update button now sits adjacent to its "Updated from GitHub 2d ago" stamp, styled as an outline button).
  • Each ticket row shows topics, spiked/planned, the effort its spike/plan recorded, status, then a trailing meta cluster of fixed-width, aligned columns in the order "Priority: n" (an empty slot when the ticket names none, so rows stay aligned), date ("2d ago"), and its GitHub: issue link (icon + #42, linking out — beside the row's button, so the row still opens the detail page).
  • A "Sort by: Date/Priority" dropdown reorders the list (Date, the default, is the server's own newest-first order; Priority sorts highest-first, ties falling back to newest-first).
  • Ticket dates come from the ticket's own filename (YYYY-MM-DD_slug.md) rather than the file's mtime (which drifted every time an update-from-GitHub run touched the file), falling back to mtime only for tickets written before the dated-filename format.
  • A ticket whose .spike.md (else .plan.md) records an effort estimate — the "Human intervention effort: low" line the spike format asks for — surfaces it as WorkspaceTicket.effort, shown as "Effort: n" on the row and in the detail meta.
  • Open/Closed filter checkboxes (Open only, by default) filter the backlog by the Status: open/closed header (Add Status: open/closed to every ticket header #1230); a project with tickets hidden by the filter says so instead of offering an import for work that already exists.
  • Clicking a row opens its own page at /{projectId}/tickets/{filename} (same slug as the file), showing the ticket's entire markdown — not just the head a list row reads. All of a ticket's meta sits below the description, in one order: date, priority (spelled out as "Priority: n", not a bare number — the format's priority is a 0-10 scale), the ticket's GitHub: link, then status, topics, spiked/planned, and effort. The Queue button lives here too, since the list row no longer has room for it.
  • route.ts extended: /tickets is the cross-project list, /{projectId}/tickets/{slug} is one ticket's page, alongside the existing /settings.
  • Merged repeatedly with concurrent upstream work on the same tickets surface (feat(dashboard): update tickets/ from GitHub without re-importing #1222 "update tickets from GitHub", ticket-format doc changes, and Add Status: open/closed to every ticket header #1230's new Status:/Priority:/GitHub: headers) and reconciled cleanly each time.

Closes #1144. Required for the demo video per the issue.

Test plan

  • pnpm exec vitest run in packages/framework-dashboard — 555 tests pass.
  • pnpm exec tsc --noEmit in packages/framework-dashboard — clean.
  • pnpm test in packages/the-framework — 1405 tests pass, 1 pre-existing skip (readTicket/readTicketsMeta/collectAllTickets coverage, plus date/topics/status/github/effort parsing, filename-vs-mtime dating, and newest-first sort).
  • pnpm exec vite build in packages/framework-dashboard — clean, onAllTickets registered in the telefunc shield.

Generated by Claude Code

claude added 3 commits July 26, 2026 10:58
…1144)

Tickets move out of the 27rem right rail into their own page at
/{projectId}/tickets, reached from a new "Tickets" row in the sidebar
once a project is selected. TicketsPanel keeps rendering the list,
queue button, and GitHub import — just at full width now.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FzE7jX1qxv52V7xqKDvd3z
#1144)

The tickets page now lists each ticket as a single line; clicking one
opens /{projectId}/tickets/{filename}, showing the ticket's whole
markdown file (a new readTicket/onTicket read, not just the head
readTickets parses) plus the Queue button, which moved off the list
row. The GitHub import empty-state stays on the list.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FzE7jX1qxv52V7xqKDvd3z
…144-ko7ye7

# Conflicts:
#	packages/framework-dashboard/components/TicketsPanel.tsx
#	packages/framework-dashboard/server/reads.telefunc.ts
#	packages/the-framework/src/dashboard-rpc/index.ts
#	packages/the-framework/src/dashboard-rpc/reads.telefunc.ts
#	packages/the-framework/src/dashboard/index.ts
#	packages/the-framework/src/dashboard/tickets.test.ts
#	packages/the-framework/src/index.ts

Copy link
Copy Markdown
Member Author

CI failure investigated: the single failing test was binding a topic run re-homes it into the bound project... (#1122) in daemon-workspace.test.js, with ENOTEMPTY: directory not empty, rmdir '.../.the-framework'. That file is unrelated to this PR's diff (tickets list/detail page), and running it in isolation locally passed 5/5 — this reads as a filesystem-cleanup race under CI's parallel test load, not a regression from these changes. Requested a re-run of just the failed job.


Generated by Claude Code

Copy link
Copy Markdown
Member Author

Re-run failed the same way (ENOTEMPTY: directory not empty, rmdir '.../.the-framework' on the same test, daemon-workspace.test.ts:253). Worth noting: that test's own source comments already document CI-only flakiness for this exact scenario ("a real bind... on a loaded runner kills it before it records anything — the run then looks like it never spawned, which is the CI-only 1 !== 2 this test kept failing with"). This is a different symptom (an ENOTEMPTY during cleanup instead of that 1 !== 2), but the same root cause category: real subprocess + real filesystem timing against a loaded CI runner, in a test file this PR does not touch. Triggered a second re-run to see if it clears.


Generated by Claude Code

claude added 2 commits July 26, 2026 12:27
#1144)

Tickets moves below Overview in the sidebar and becomes cross-project:
the page now reads every registered project's backlog (new
collectAllTickets/onAllTickets) and renders one section per project,
each with its own Import/Update-from-GitHub bar, at /tickets.

Each row now shows priority, topics, and a human-readable age
("2d ago"), and the list sorts newest-first by the ticket file's
mtime (new WorkspaceTicket.date/topics fields, parsed by
readTickets/readTicket). Clicking a row still opens its own page at
/{projectId}/tickets/{filename}.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FzE7jX1qxv52V7xqKDvd3z

Copy link
Copy Markdown
Member Author

CI red on the ticket-format spec ships in the package (not materialized), with priority/topics (#684/#674) (src/tickets.test.ts) — but this fails on main itself too (main's own CI run 30201542698 at the same commit c7fb48f fails the identical assertion: TICKETING_FORMAT.includes('priority: low/medium/high/urgent')). A concurrent commit updated prompts/ticketing_format.md to the new Priority: 10-0 scale without updating this test's literal-string check. Unrelated to this PR's diff (I don't touch tickets.test.ts or ticketing_format.md) — will re-merge and re-run once the base recovers.


Generated by Claude Code

Copy link
Copy Markdown
Member Author

Base recovered — main's ticket-format test was fixed in #1228. Merged that in (now unrelated-CI-flake-free on my side too, confirmed by re-running the full suite locally: 538 dashboard tests + 1391 framework tests, all green) and pushed. Also worth noting: while checking, main's own CI hit the same daemon-workspace.test.js ENOTEMPTY flake I saw earlier on this PR — good confirmation it's a genuine environment/load-timing issue rather than anything diff-specific, and it looks like it's already tracked (tickets/2026-07-25_rehome-test-loses-bind-under-load.md).


Generated by Claude Code

claude added 8 commits July 26, 2026 13:05
Tickets now carry Status: open/closed (from #1230), parsed and surfaced
through the dashboard. The Tickets page gets Open/Closed filter checkboxes
(Open only by default) and a wider two-up grid; a project with tickets
hidden by the filter says so rather than offering an import for work that
already exists. List rows badge closed tickets. The detail page moves the
date to the left of the description and status into the meta row below it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FzE7jX1qxv52V7xqKDvd3z
…link and sort (#1144)

The detail page now puts every meta fact below the description in one order —
date, priority, GitHub link, then status/topics/spiked/planned — instead of
splitting date out beside the description. Priority reads "Priority: n"
rather than a bare number, and a ticket's GitHub: link renders as an icon
plus its issue number, linking out.

A ticket's date now comes from its <DATE>_<SLUG>.md filename rather than the
file's mtime (which drifted whenever an update-from-GitHub run touched it),
falling back to mtime only for tickets that predate the dated-filename
format. The Tickets page adds a "Sort by: Date/Priority" dropdown (ties fall
back to newest-first) and widens to a third column at large viewports.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FzE7jX1qxv52V7xqKDvd3z
…ort (#1144)

The Tickets page drops its column grid: each project's table now spans the
whole pane, which is the one dimension the rows actually need now that they
carry topics, spiked/planned, effort, age, "Priority: n", and a GitHub issue
link. The link sits beside the row's button (a link inside a button is
invalid HTML), so the row still opens the detail page while the link goes
out to the issue; the trailing meta keeps the date/priority/GitHub order the
detail page uses.

A ticket whose .spike.md (else .plan.md) records an effort estimate — the
"Human intervention effort: low" line the spike format asks for — now
surfaces it as WorkspaceTicket.effort, shown as "Effort: n" on the row and
in the detail page's meta.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FzE7jX1qxv52V7xqKDvd3z
…1144)

The trailing meta on a ticket row is now three fixed-width columns —
priority (an empty slot when the ticket names none), then the date, then
the GitHub issue link (an equal-width spacer when there is none) — so the
meta lines up down the table instead of drifting with whatever each row
happens to have. The Update-from-GitHub action now sits adjacent to the
"Updated from GitHub 2d ago" stamp it acts on rather than flush against
the panel's far edge, and wears the outline button style instead of ghost.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FzE7jX1qxv52V7xqKDvd3z
…1144)

The topics/spiked/planned/effort chips now live in a fixed-width column
between the title and the priority column, so they start at the same x on
every row — with each row's tags starting wherever its title ended, the
blank stretch between a short title and the right-hand meta read as dead
space rather than as a table. The GitHub issue link steps up from 10px text
with a 12px icon to text-xs with a 16px icon, on the row and the detail
page both.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FzE7jX1qxv52V7xqKDvd3z
The fixed 16rem tags column traded one gap for another: with the chips
left-aligned inside it, a row with one topic showed most of that column as
blank, pooling dead space mid-row between the tags and the priority. The
tags are now content-sized and right-packed, so the row's slack all lands in
the stretched title column — the one place a table carries it — and the
priority column narrows to hug its widest value ("Priority: 10") while
staying fixed so rows still align.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FzE7jX1qxv52V7xqKDvd3z
@brillout

Copy link
Copy Markdown
Member Author

@suleimansh I didn't read the code.

@brillout
brillout merged commit 2617720 into main Jul 26, 2026
1 check passed
@brillout
brillout deleted the claude/github-issue-1144-ko7ye7 branch July 26, 2026 16:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Show tickets as whole page instead of sidebar

2 participants