diff --git a/changelog.d/804-work-page.changed.md b/changelog.d/804-work-page.changed.md new file mode 100644 index 00000000..e0ca8e01 --- /dev/null +++ b/changelog.d/804-work-page.changed.md @@ -0,0 +1 @@ +The Work page now shows a compact state summary with counts and shares, keeps row actions behind one disclosure, moves the new-work-item form into a header dialog and names why ready work is waiting; the work-item table stays the compact list it is. diff --git a/docs/architecture.md b/docs/architecture.md index 14c2d358..143bdac1 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -843,12 +843,13 @@ becomes a card whose cells carry their column name in a `data-label` attribute behind a horizontal scroll on a phone, and a new column must emit `data-label` in `jobRows` to stay readable there. The rest of the data tables reuse the same block through one class, `table-cards`: the `/admin` users and audit tables, the -dashboard repository table, the repository page's delivery, board and work-item -tables, and the support view's repository and job tables. Adding the class and a +dashboard repository table, the repository page's delivery and work-item tables, +and the support view's repository and job tables. Adding the class and a `data-label` per cell is the whole change; a table must not grow a second card -mechanism. The delivery board is the one exception, `table-cards table-cards-head`: -its header row is the stage filter, so it stays in the flow and reflows as a -wrapping row of links above the cards instead of disappearing. Above 640px the scroller is also bounded vertically +mechanism. The delivery board is a compact summary of state links with counts +and shares, not a carded table; it wraps above the work-item list and each state +link filters the list. A share needs a denominator: with no work items at all +each state shows `—` rather than a confident `0%`. Above 640px the scroller is also bounded vertically (`100dvh` minus `--header-h` and `--space-7`, and minus the repository subnav's `--subnav-h` on a repository page) and its `thead th` is sticky on an opaque `--panel`, so column names stay above the rows they label; the two rules @@ -874,9 +875,8 @@ attribute states, the meta shapes, the 44px control and the two palette tokens the sticky header and the account pill used to hardcode. Signed-out pages honour the saved palette but render no control: the chooser rides inside `#main-nav`, so below 961px the compact header's panel carries it and the phone row gains no -child. Between 641px and 960px a wide table (the -delivery board is 952px wide at 768) can still be wider than its `.table-scroll` -box, so that band draws an always-present classic scrollbar — an explicit track +child. Between 641px and 960px a wide data table can still be wider than its +`.table-scroll` box, so that band draws an always-present classic scrollbar — an explicit track plus `scrollbar-width`/`scrollbar-color` for Firefox — instead of relying on a thumb that is 1.5:1 on the panel. The band has its own `(min-width: 641px) and (max-width: 960px)` block in `public/app.css`; the cards @@ -929,7 +929,7 @@ timeline as the token to search, and it is the `job_events.job_id` of that job, so one search returns the whole job. Pass-level lines (a scheduler pass, the shutdown check) have no job in scope and deliberately carry no `trace`. -The repository page adds a compact delivery board grouped by work-item state; each state header links to a filtered work-item list (`?workState=`). The dashboard has two scopes. `/dashboard?window=7|30` shows the signed-in +The repository page adds a compact delivery board grouped by work-item state; each state tile links to a filtered work-item list (`?workState=`) and shows its share of the total, or `—` while the board has no items and there is nothing to divide by. The work-item rows keep their actions behind one disclosure, and the create form is a header button and dialog. The dashboard has two scopes. `/dashboard?window=7|30` shows the signed-in user's own delivery metrics: jobs, success rate, PRs, merged PRs, cost, open work items and the last job. `/admin/metrics` shows the global window with the product funnel, delivery efficiency (success and merge rate, median job and diff --git a/public/app.css b/public/app.css index cf4832f8..d8846d1a 100644 --- a/public/app.css +++ b/public/app.css @@ -514,6 +514,15 @@ p { margin: 0 0 12px; } inner-id offset, so the two cannot drift apart. */ .repo-page { --subnav-h: calc(var(--touch) + 2 * var(--space-2) + 1px); } .repo-page [id] { scroll-margin-top: calc(var(--header-h) + var(--subnav-h) + var(--space-4)); } +.work-summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 8px; margin: 12px 0 8px; } +.work-summary a { display: grid; gap: 2px; min-width: 0; padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--field); color: var(--text); text-decoration: none; } +.work-summary a:hover, .work-summary a.is-active { border-color: var(--accent); } +.work-summary strong { font-size: var(--text-md); font-variant-numeric: tabular-nums; } +.work-summary span { font-size: var(--text-sm); color: var(--muted); } +.work-summary small { font-size: var(--text-sm); color: var(--muted-2); } +.work-actions summary { cursor: pointer; color: var(--accent); font-size: var(--text-sm); font-weight: 650; } +.work-actions .row { margin-top: 8px; } +@media (max-width: 680px) { .work-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); } } .repo-subnav { position: sticky; top: var(--header-h); z-index: 15; display: flex; gap: var(--space-2); margin: 0 0 var(--space-4); min-height: var(--subnav-h); diff --git a/src/views/pages.ts b/src/views/pages.ts index c7ada444..f1ea9d8c 100644 --- a/src/views/pages.ts +++ b/src/views/pages.ts @@ -1573,37 +1573,65 @@ export function repoPage(input: { config: Config; locale: Locale; viewer: Viewer
${escapeHtml(item.job_id)}`}| ${escapeHtml(workItemStateLabel(t, state))} | `).join('')}
|---|
| ${workCounts.get(state) ?? 0} | `).join('')}