~bigbes/sr-ht-dolt

ref: f91a2e80c6848098c00ef56d75f205e8eb88f744 sr-ht-dolt/web/beads.go -rw-r--r-- 8.1 KiB
dc918296 — Eugene Blikh 5 days ago
web: link issue ids to the tracker that owns them
0190aab3 — Eugene Blikh 5 days ago
web: register the views in one explicit list
fe616c89 — Eugene Blikh 5 days ago
beads: add a one-column stream layout beside the board

?layout=stream renders the same filtered set, the same buckets and the same
cards as one column of sections instead of four lanes side by side. It is a
layout of the Beads view and not a fifth tab: filters, the ready toggle, the
search box and ?issue= behave exactly as they do on the board.

A column read top to bottom can afford one sort per section, because each
section answers a different question: Rolling by started_at desc (what was
picked up last is what is being worked on), Lined Up ready-first then priority
then oldest, Stalled by blocker count (one blocker away is nearer than five),
Past Stand by closed_at desc. started_at and closed_at join the card model as
sort keys and are not displayed; a row missing one sorts last, because an unset
timestamp is not a very old one.

Past Stand opens collapsed in a <details> — the largest and least actionable
section, closed without a line of JavaScript. The sections are derived from the
finished lanes rather than bucketed again, so the section counts cannot drift
from the marquee, and the lanes keep the board order the board renders.

The Board/Stream toggle rebuilds the current query with layout replaced, via a
new withQuery template func, so every active filter survives the switch.
7d799ed0 — Eugene Blikh 5 days ago
beads: drop the Bead/Beads prefix from the moved types
f9c82b0b — Eugene Blikh 5 days ago
beads: extract the projection out of web/

web/beads.go held the one reading of the beads schema — the table
fingerprint, the lane bucketing, the ready rule, the status categories,
the transitive dependency walk, the event humanizer, the filter model and
the milestone rollup — where a second consumer could not reach it. The
MCP surface and the cross-database ready page both need it.

Move it to a new root package beads/ that depends on browse/ and the
standard library only: rows in, view model out, no net/http, no
html/template, no core. The BrowseSession seam is declared consumer-side
there and names the one method the projections call, so web's larger
BrowseSession satisfies it structurally and a session passes straight
through.

web/beads.go and web/milestones.go keep only their View adapters — slug,
label, template, Applies, and the hand-off of ref and query. The
templates are unchanged: the moved types keep their names and their
display methods, so every dot still resolves.

Pure move plus the beadsMax -> beads.Max export rename. The projection
tests move with the code and become testify; the render tests stay in
web/ unchanged. Same 63 tests pass before and after.
8e89f8a0 — Eugene Blikh 29 days ago
feat(web/beads): promote milestones to their own view/tab

Move the milestone rollup off the board and into a dedicated "Milestones" tab
(a registered View, companion to Beads via the same fingerprint). The tab is
richer than the old board panel: per-milestone progress bar, done/open/in-progress
counts, and the issue list under each milestone (open-work first, closed struck
through), each linking to its beads detail. Issues with no milestone label are
summarized in a footnote. A beads DB with no milestone labels still gets the tab,
showing an empty-state hint.

Removes the board's inline milestone panel and the collectMilestones/BeadMilestone
helpers it used; the grouping now lives in the milestones view.
5c5479c4 — Eugene Blikh 29 days ago
feat(web/beads): ready markers, milestone rollup, transitive dependency tree

Three additions surfacing more of the bd data model:

- Ready: a ⚡ marker on actionable-now cards and a "Ready only" board filter.
  "Ready" mirrors bd's ready set exactly — open, unblocked, not template/
  ephemeral. As part of this, parent-child edges no longer count as blockers
  (a subtask is not blocked by its open epic), which was over-filling Stalled
  and under-counting ready; the board now matches bd's is_blocked/ready
  accounting (verified: 111 ready on tarantool-etcd, == ready_issues).

- Milestone rollup: a board panel with per-"milestone:<name>" label progress
  bars (done/total), each linking to that label's filtered board.

- Transitive dependency tree on the detail page: the full prerequisite chain
  ("everything this waits on") and the reverse ("everything this unblocks"),
  walked from the edge set with depth/'node caps and cycle guard, indented by
  depth. Shown only when it reaches past the direct edges, so it never just
  repeats the flat Depends-on / Depended-on-by lists.
88a1d379 — Eugene Blikh 29 days ago
feat(web/beads): filters for the parade board

Add a filter bar to the beads board: text search (id/title), issue type,
priority, assignee, and label. Filters are query-param based (GET, sticky
across submits) and applied server-side before lane bucketing, so the marquee
counts reflect the filtered set. Dropdown options are collected from the full
issue set (they don't shrink as filters narrow the board); a Clear link shows
when any filter is active. Verified on the 143-issue tarantool-etcd board
(type=bug → 30).
57832d6c — Eugene Blikh 29 days ago
feat(web/beads): close reason in Comments tab; synthesize subtask-add history

- Close reason placement: show it as a block at the end of the Comments tab
  (which carries no closed event), while the History tab shows it inline as the
  closed event — so it appears in whichever tab you're on, without duplication
  within a tab. (Reverts the outright removal.)

- History now includes dependency/subtask additions. beads logs no audit event
  for a link, but the dependencies row records created_at/created_by, so
  buildDetail synthesizes "added subtask X" / "added dependency on X" timeline
  entries (Kind "dep", own accent). On an epic this surfaces when each child was
  linked. Guarded on created_at so older schemas without it emit nothing.

- pre.field-body style de-scoped from .bead-detail so the Comments-tab close
  reason wraps (overflow-wrap: anywhere) instead of overflowing.
1b35456a — Eugene Blikh 29 days ago
refine(web/beads): concise label events, drop standalone close reason, wrap long lines

- Label audit events collapse to one line ("added label milestone:m3") instead
  of a "label added" header plus a redundant "Added label: …" body. The label
  name is taken after the first colon so namespaced labels survive.
- Remove the standalone Close reason block below the activity: the reason
  already shows as the History tab's `closed` event, so it was a duplicate.
- Add overflow-wrap: anywhere to the timeline body, comment body, and
  field-body pre so a very long single-line reason wraps instead of overflowing.
2ee66fb8 — Eugene Blikh 29 days ago
feat(web/beads): epic view with subtask rollup, tabbed Comments/History

Three additions to the beads issue detail:

- Epic mode: when the viewed issue is issue_type=epic, render a Subtasks panel
  — its parent-child children (deps pointing at the epic) with a done/total
  progress meter, sorted open-work-first with closed sinking to the bottom.

- Activity is now a two-tab strip (pure-CSS, no JS): Comments keeps the plain
  thread; History merges comments and the audit-log events table into one
  time-sorted timeline with humanized change lines ("changed status to
  in_progress", "updated priority to 0", "closed the issue" + reason).

- Close reason moved from the top metadata table to its own block at the very
  bottom, after the activity — it reads as a closing note, not a header field.

Verified end-to-end against a real 143-issue beads store (tarantool-etcd) via
the env-guarded TestRealBeadsStore smoke test; unit-covered with a dedicated
epic/history fixture.
b7e8d134 — Eugene Blikh 30 days ago
feat(web): Overview/Tables/Beads tab bar + full issue fields on beads detail

Give every database page a consistent three-tab bar — Overview, Tables,
then the applicable views (Beads) — in that order. Previously the bar only
carried [views, Tables] and the Overview page marked Tables active, so there
was no way to tell you were on the overview. viewtabs now takes an explicit
Current sentinel ("overview" | "tables" | view slug) and the tree/table row
pages render the bar too (handlers compute applicable views for the ref).

Surface the issue fields the beads detail pane was dropping. The closure
reason (close_reason) recorded by `bd close -r` was never shown; auditing
against bd's own field set also turned up estimated_minutes, external_ref,
spec_id, and started_at. All render conditionally, so issues that don't set
them stay uncluttered.
76bf70dd — Eugene Blikh 30 days ago
fix(web): make the beads view inherit the SourceHut theme

The beads board shipped its own Mardi Gras palette — a purple→green
marquee gradient and saturated solid lane fills — that clashed with
SourceHut's flat, utilitarian dark theme, and the detail pane's field
labels were a hardcoded dark purple with no dark-mode override, leaving
"Created by / Owner / Description" unreadable on the dark background.

Drive everything from CSS variables that mirror core.sr.ht's Bootstrap
palette for both the light default and the prefers-color-scheme: dark
variant sourcehut ships (the same media query it uses), so the view
inherits the host theme instead of fighting it. Lane hues become muted
Mardi Gras accents (gold/green/violet/gray) used only as thin borders and
low-alpha tints — never as body text — so contrast holds on either theme.
The marquee is now a flat stat row, lanes an understated panel with an
accent underline, and detail labels a readable muted caption. Verified
light and dark via a headless render.
8f5ae3f0 — Eugene Blikh 30 days ago
feat(web): Mardi Gras beads view

Render a beads (bd) issue database as a Mardi Gras parade board: four
lanes — Rolling (in progress), Lined Up (open & ready), Stalled (open &
blocked), Past Stand (done) — plus a marquee of per-lane counts. Cards
show id/title/type/priority/assignee/labels and blocked-by/blocks counts;
an issue-detail pane (?issue=<id>) shows the full issue with its
dependency edges in both directions and its comments thread.

Fingerprints on the issues + dependencies tables and reads everything
through the browse layer (column-name-keyed, so column order is
irrelevant), capped at 2000 rows/table. Status is bucketed via
custom_statuses with name heuristics as a fallback; "blocked" means
is_blocked or an open blocking dependency. Plugs into the view registry
via init()+RegisterView with no framework edits. Purple/gold/green
palette scoped in the template (no scss rebuild needed).