feat(dashboard): entity list UX — REF column, name cells, detail pages (CUST-WP-0030)
- ref-cell.js: REF column component — click=copy deeplink, dblclick=open
- field-help.js: field registry + fieldRow helper with help-tip decoration;
FK fields (task_id, workstream_id, repo_id) render as async-linked cells
with entity-title bubble-help on hover
- GET /token-events/{id} endpoint + get-by-id tests
- GET /repos/by-id/{repo_id} UUID lookup endpoint
- Landing pages: /token-events/[id], /workstreams/[id], /repos/[slug], /tasks/[id]
- token-cost.md: REF + Name columns on all three tables; parallel fetch of
workstreams/tasks for title resolution
- reference.md: entity detail page URL scheme documented
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,7 +8,7 @@ status: done
|
||||
owner: custodian
|
||||
topic_slug: custodian
|
||||
created: "2026-03-29"
|
||||
updated: "2026-03-29"
|
||||
updated: "2026-03-30"
|
||||
state_hub_workstream_id: "9d8e1c33-2067-4593-a5d8-d28dda3b1d21"
|
||||
---
|
||||
|
||||
@@ -178,3 +178,78 @@ description: >
|
||||
/data/<type>/<id> URL scheme and the REF column convention.
|
||||
state_hub_task_id: "107cb5bb-ff0c-4c97-af04-2cdeff11f0b2"
|
||||
```
|
||||
|
||||
## Amendments & Improvements
|
||||
|
||||
Post-completion fixes and enhancements discovered during manual testing.
|
||||
|
||||
### A01 — amendment — Deep-link URL prefix wrong
|
||||
|
||||
`ref-cell.js` generated deep-links as `<origin>/data/<type>/<id>` but
|
||||
Observable Framework serves pages at `/<type>/<id>` (the `src/data/`
|
||||
directory is for data loaders, not pages). Fixed by removing the `/data/`
|
||||
prefix from the `deepLink` construction in `ref-cell.js`. The T01
|
||||
description was also inaccurate in stating the `/data/` path.
|
||||
|
||||
### A02 — amendment — FileAttachment rejects template literals
|
||||
|
||||
T04 used `` FileAttachment(`../data/token-events/${eventId}.json`) `` in
|
||||
the landing page. Observable Framework requires `FileAttachment` to be
|
||||
called with a single **literal** string (it processes them statically at
|
||||
compile time). This caused a `SyntaxError` that also aborted the cell
|
||||
defining `eventId`, cascading into a `RuntimeError: wsId is not defined`
|
||||
on the next cell. Fixed by replacing all `FileAttachment` calls in landing
|
||||
pages with direct `fetch(${API}/...)` calls.
|
||||
|
||||
### A03 — amendment — Workstream and repo landing pages missing
|
||||
|
||||
T04 only created a token-event landing page. The By Workplan and By Repo
|
||||
tables also had REF links (to `/workstreams/<id>` and `/repos/<slug>`),
|
||||
both returning 404. Added:
|
||||
- `src/workstreams/[id].md` — fetches `GET /workstreams/{id}`
|
||||
- `src/repos/[slug].md` — fetches `GET /repos/{slug}/`
|
||||
- Corresponding unused data loaders left in `src/data/` for reference.
|
||||
|
||||
### A04 — amendment — Repos router uses slug, not UUID
|
||||
|
||||
T05 passed `repo_id` (UUID) to `refCell` for the By Repo table, but the
|
||||
repos API uses slug-based routing (`GET /repos/{slug}/`). Passing a UUID
|
||||
returned 404. Fixed by passing `repo_slug` to `refCell` so the deep-link
|
||||
resolves correctly.
|
||||
|
||||
### A05 — amendment — Top Tasks refCell used wrong record type
|
||||
|
||||
T05 specified `"token-events"` as the record type for Top Tasks, but the
|
||||
column contains `task_id` (a task UUID, not a token-event UUID), so the
|
||||
landing page returned "Token event not found". Fixed by:
|
||||
- Changing record type to `"tasks"` in the `refCell` call.
|
||||
- Creating `src/tasks/[id].md` (fetches `GET /tasks/{task_id}`).
|
||||
|
||||
### I02 — improvement — Entity FK fields on detail pages link to their targets
|
||||
|
||||
On every detail page (token-event, task, workstream, repo), fields that hold
|
||||
a foreign-key UUID (`task_id`, `workstream_id`, `repo_id`) now render as
|
||||
clickable links with an async-loaded bubble-help showing the entity title.
|
||||
|
||||
Implementation:
|
||||
- `GET /repos/by-id/{repo_id}` added to `api/routers/repos.py` — UUID
|
||||
lookup needed because the existing repos router uses slug routing.
|
||||
- `FIELD_LINKS` registry added to `src/components/field-help.js` mapping
|
||||
each FK field to `{apiUrl, getUrl, getTitle}` resolution rules.
|
||||
`getUrl` receives `(id, data)` so slug-routed entities can derive their
|
||||
page URL from the fetched entity (e.g. `repo_id` → `/repos/{data.slug}`).
|
||||
- `_linkCell(key, id)` helper added: renders a short-UUID link immediately,
|
||||
then fetches the entity asynchronously and wraps the anchor in a
|
||||
`<help-tip label="{title}" description="{type} · {full-uuid}">` once
|
||||
the data arrives.
|
||||
- `fieldRow` updated to dispatch to `_linkCell` whenever the field key is
|
||||
in `FIELD_LINKS` and the value is non-null.
|
||||
|
||||
### I01 — improvement — Workstream and task Name columns show titles
|
||||
|
||||
T05 originally showed truncated UUIDs in the Workstream and Task name
|
||||
columns (the summary data carries only IDs, not titles). Improved by
|
||||
fetching `/workstreams/` and `/tasks/` in parallel with the token-event
|
||||
poll and building lookup maps (`wsMap`, `taskMap`). The Name column now
|
||||
displays `workstream.title` and `task.title` (truncated to 80 chars) with
|
||||
the full UUID as tooltip.
|
||||
|
||||
Reference in New Issue
Block a user