Files
the-custodian/workplans/CUST-WP-0030-dashboard-entity-list-ux.md
tegwick 3e54cb05c8 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-03-29:
  - T06: todo → done
2026-03-29 20:38:00 +02:00

6.6 KiB

id, type, title, domain, repo, status, owner, topic_slug, created, updated, state_hub_workstream_id
id type title domain repo status owner topic_slug created updated state_hub_workstream_id
CUST-WP-0030 workplan Dashboard Entity List UX custodian the-custodian done custodian custodian 2026-03-29 2026-03-29 9d8e1c33-2067-4593-a5d8-d28dda3b1d21

Dashboard Entity List UX

Goal

Make every entity table in the dashboard navigable and self-documenting. Two new UI primitives:

  1. REF cell — running row number (1-based); click copies a deep-link (<origin>/data/<recordtype>/<id>) to the clipboard; double-click opens the link in a new tab.
  2. Name cell — second column, titled after the record type; shows the entity name truncated at 80 chars with full-name tooltip on hover.

Support these cells with a landing page (/data/[type]/[id]) that renders a key-value view of every field in the record, each key decorated with a <help-tip> (one-sentence description + link to the relevant help-doc section).

Pilot all three features on the Token Cost page, then extend to other entity tables in later workplans.

Background

Current entity tables show only IDs (often truncated UUIDs) with no way to navigate to a record detail view or discover what a field means. For a person reviewing agent activity the tables are hard to parse. Providing a running reference number, an entity name column, and a click-through detail page substantially lowers the cognitive load.

The <help-tip> custom element already exists in src/components/help-tip.js and is used on several pages — the field-help registry will reuse it as the rendering layer.

Implementation Plan

The pilot targets the Token Cost page. Observable Framework supports parameterised pages via [param].md file naming. The API already exposes GET /token-events/?task_id=… and GET /token-events/summary/; a per-record GET endpoint is needed before the landing page can work.

Component layer

  • src/components/ref-cell.js — exports refCell(index, type, id) that returns an HTMLElement with click/dblclick handlers.
  • src/components/field-help.js — exports FIELD_HELP map and fieldRow(key, value) helper that wraps the key in <help-tip>.

API layer

  • GET /token-events/{event_id} — returns TokenEventRead for a single event; needed by the landing page data loader.

Dashboard pages

  • src/data/token-events/[id].json.py — data loader that calls the new single-event endpoint; returns JSON for the landing page.
  • src/data/token-events/[id].md — landing page: key-value table, each row built with fieldRow().
  • src/token-cost.md — updated: REF column (refCell) and Name column added to By Repo, By Workplan, and Top Tasks tables.

Tasks

id: T01
title: "REF cell component"
status: done
priority: high
description: >
  Create src/components/ref-cell.js.
  Export refCell(index, recordType, id) → HTMLElement.
  - Displays 1-based index as monospace text, cursor:pointer.
  - Single click: copies `${location.origin}/data/${recordType}/${id}` to
    clipboard; briefly flashes "Copied!" as a transient tooltip using the
    existing help-tip positioning pattern.
  - Double click: window.open(deeplink, '_blank').
  - No external dependencies; plain DOM.
state_hub_task_id: "8ee527cf-436b-4bab-bdb8-406314a38d99"
id: T02
title: "GET /token-events/{event_id} endpoint"
status: done
priority: high
description: >
  Add GET /token-events/{event_id} to api/routers/token_events.py.
  Returns TokenEventRead (already defined in schemas/token_event.py).
  404 if not found.
  No migration needed.
  Add a test in tests/test_token_events.py: get by id → 200, unknown id → 404.
state_hub_task_id: "02c27d25-d744-4da0-9bcb-b40ada54d5a5"
id: T03
title: "Field-help registry"
status: done
priority: medium
description: >
  Create src/components/field-help.js.
  Export FIELD_HELP: a plain object keyed by field name.
  Each entry: { label, description, doc } — matches help-tip attributes.
  Cover at minimum all TokenEventRead fields:
    id, tokens_in, tokens_out, tokens_total, task_id, workstream_id,
    repo_id, session_id, model, agent, ref_type, ref_id, note, created_at.
  Export fieldRow(key, value) → HTMLElement (<tr>) that wraps key in a
  <help-tip> (or plain <td> if key is not in FIELD_HELP) and value in a
  second <td>.
  Import HelpTip from ./help-tip.js to ensure the custom element is
  registered.
state_hub_task_id: "7721d884-bd70-459f-b36d-450d69aac549"
id: T04
title: "Token-event landing page"
status: done
priority: medium
description: >
  Create two files:
  1. src/data/token-events/[id].json.py — data loader.
     Reads `id` from argv[1]; calls GET /token-events/{id};
     exits 1 if 404 so Observable renders an error page.
  2. src/data/token-events/[id].md — landing page.
     Imports fieldRow from components/field-help.js.
     Fetches FileAttachment("token-events/{id}.json").json().
     Renders an HTML <table> with one row per field using fieldRow().
     Title: "Token Event · {id.slice(0,8)}…".
     Back link: "<a href='/token-cost'>← Token Cost</a>".
state_hub_task_id: "dc63746d-74b3-434a-925c-1cead480198f"
id: T05
title: "Apply REF and Name columns to Token Cost page"
status: done
priority: high
description: >
  Update src/token-cost.md.
  Import refCell from ./components/ref-cell.js.
  For each of the three entity tables (By Repo, By Workplan, Top Tasks):
  - Prepend a "REF" column using refCell(i+1, recordType, row.id).
    Record types: "repos" for By Repo (using repo_id), "workstreams" for
    By Workplan (using scope_id), "token-events" for Top Tasks (using
    task_id — note: links to the task landing page, not a token event page,
    until T04 is done; use recordType "tasks").
  - Add a Name column as the second data column:
    - By Repo: repo_slug (no truncation needed, slugs are short)
    - By Workplan: scope_id displayed as first 8 chars + "…" (unchanged)
      → replace with workstream title if available; for now show scope_id
      truncated to 36 chars with full UUID tooltip.
    - Top Tasks: task_id truncated to 80 chars with full-id tooltip.
  Keep all existing columns unchanged.
state_hub_task_id: "3225cc6c-2574-41e9-b8fd-e5e703a9dd7c"
id: T06
title: "Consistency gate and docs update"
status: done
priority: low
description: >
  1. Run `cd state-hub && make test` — all token_events tests must pass.
  2. Run `make fix-consistency REPO=the-custodian`.
  3. Add a one-paragraph entry to src/docs/reference.md describing the
     /data/<type>/<id> URL scheme and the REF column convention.
state_hub_task_id: "107cb5bb-ff0c-4c97-af04-2cdeff11f0b2"