Owners page: two-column repos, last-active stamps, clearer owner headers #142

Closed
opened 2026-09-05 16:13:19 +00:00 by crueber · 3 comments
Owner

Owners page: two-column repos, last-active stamps, clearer owner headers

Follow-up to #117/#137 (the calm divider redesign). Three improvements:

  1. Two-column repo lists. Each owner's repo list flows in two columns (single column on narrow widths) instead of one long single column.
  2. Last-active datetime per repo. Each repo row shows when the repo was last active, using the app-wide <DateTime> component from #133 (relative + local-tz hover). Source of truth: decide in the change — latest commit date, manifest/head activity, or summary field (document the choice + cost; capped lists keep it bounded; never block first paint on it).
  3. Owner headers stand out more. The owner name/link should read clearly as the section header — stronger type scale, spacing, or treatment (not just link color).

Acceptance criteria

  • Two-column repo grids (responsive collapse), last-active stamps, distinct owner headers.
  • node --test green; browser check dark + light, zero console errors; no new deps.
# Owners page: two-column repos, last-active stamps, clearer owner headers Follow-up to #117/#137 (the calm divider redesign). Three improvements: 1. **Two-column repo lists.** Each owner's repo list flows in two columns (single column on narrow widths) instead of one long single column. 2. **Last-active datetime per repo.** Each repo row shows when the repo was last active, using the app-wide `<DateTime>` component from #133 (relative + local-tz hover). Source of truth: decide in the change — latest commit date, manifest/head activity, or summary field (document the choice + cost; capped lists keep it bounded; never block first paint on it). 3. **Owner headers stand out more.** The owner name/link should read clearly as the section header — stronger type scale, spacing, or treatment (not just link color). ## Acceptance criteria - [ ] Two-column repo grids (responsive collapse), last-active stamps, distinct owner headers. - [ ] `node --test` green; browser check dark + light, zero console errors; no new deps.
Author
Owner

Fix is up: #144 (branch fix/issue-142, scratch worktree off origin/main — main worktree untouched).

What it does (frontend + doc only, §2.3.1 + FIXED entry in 12_web_ui.md):

  1. Two-column repo lists on / and /:owner via one shared (Repos.jsx: link + + new ) in grid grid-cols-1 sm:grid-cols-2; newest-first order, #117 caps/overflow links unchanged.
  2. Last-active stamp = latest COMMIT date from GET …/commits?n=1 (ref defaults to HEAD server-side: one GET/row, no summary fetch first), rendered through the #133 (relative + local-tz title) with an active label. Rejected: summary has no date field (would need a new backend field); overview manifest.last_push is push-time from a no-store heavyweight (more cost, less precision). Honest proxy: pushes adding no commits don't move the stamp; empty repos render 'no commits yet' (the unborn-HEAD 404 maps to {commits: []} in the fetch, no tray spam). Placeholder-first like StarCount (shared activity:{o}/{r} 30s useData key).
  3. Owner headers text-sm font-semibold → text-base font-bold tracking-tight (scale + weight, not just link color).

Tests: node --test web/test/unit/*.test.js 317/317 green (incl. new activity.test.js: commit_date preference, author_date fallback, empty→null, TTL contract). Browser (shared chrome-cdp vs local server on scratch port, seeded alice/bob repos): dark+light @1280 two columns with resolved stamps + time titles, 500px single column, /alice grid verified; rows keyboard-unchanged (plain anchors, DOM order = visual order). No new npm deps.

Deviations/notes: (a) 'zero console errors' holds except ONE handled entry: the empty repo's commits 404 is logged by Chrome as a failed resource even though the UI handles it (no tray error, correct text) — avoiding it would cost an extra summary GET per row or a wire-behavior change (404→200, Rust-compat risk under law 5), so documented as accepted. (b) / rows lose the text-sm link size (now share /:owner base-size rows — one row markup everywhere). (c) Env note: scratch servers on :18081 were SIGTERM'd twice by persons unknown (shared box, other agents active); verification completed on :18771.

Fix is up: #144 (branch fix/issue-142, scratch worktree off origin/main — main worktree untouched). What it does (frontend + doc only, §2.3.1 + FIXED entry in 12_web_ui.md): 1. Two-column repo lists on / and /:owner via one shared <RepoRow> (Repos.jsx: link + <StarCount> + new <ActivityStamp>) in grid grid-cols-1 sm:grid-cols-2; newest-first order, #117 caps/overflow links unchanged. 2. Last-active stamp = latest COMMIT date from GET …/commits?n=1 (ref defaults to HEAD server-side: one GET/row, no summary fetch first), rendered through the #133 <DateTime> (relative + local-tz title) with an active label. Rejected: summary has no date field (would need a new backend field); overview manifest.last_push is push-time from a no-store heavyweight (more cost, less precision). Honest proxy: pushes adding no commits don't move the stamp; empty repos render 'no commits yet' (the unborn-HEAD 404 maps to {commits: []} in the fetch, no tray spam). Placeholder-first like StarCount (shared activity:{o}/{r} 30s useData key). 3. Owner headers text-sm font-semibold → text-base font-bold tracking-tight (scale + weight, not just link color). Tests: node --test web/test/unit/*.test.js 317/317 green (incl. new activity.test.js: commit_date preference, author_date fallback, empty→null, TTL contract). Browser (shared chrome-cdp vs local server on scratch port, seeded alice/bob repos): dark+light @1280 two columns with resolved stamps + time titles, 500px single column, /alice grid verified; rows keyboard-unchanged (plain anchors, DOM order = visual order). No new npm deps. Deviations/notes: (a) 'zero console errors' holds except ONE handled entry: the empty repo's commits 404 is logged by Chrome as a failed resource even though the UI handles it (no tray error, correct text) — avoiding it would cost an extra summary GET per row or a wire-behavior change (404→200, Rust-compat risk under law 5), so documented as accepted. (b) / rows lose the text-sm link size (now share /:owner base-size rows — one row markup everywhere). (c) Env note: scratch servers on :18081 were SIGTERM'd twice by persons unknown (shared box, other agents active); verification completed on :18771.
Author
Owner

Review of PR #144 (fix/issue-142) — verified in scratch worktree off origin/fix/issue-142 (removed afterward). No browser (per brief); node tests + reasoning + vite build. Main worktree untouched (read-only).

TESTS (scratch): node --test web/test/unit/*.test.js → 317/317 pass (incl. new activity.test.js: commit_date preference, author_date fallback, empty/missing → null, TTL contract). Note: first run showed 2 fails (data-guard, reaction-cache) purely from missing web/node_modules in the fresh worktree (ERR_MODULE_NOT_FOUND solid-js); green after provisioning node_modules. Vite build → clean (121 modules, built in ~1.5s).

REVIEW, point by point:

  • Two-column grid: OK. grid grid-cols-1 gap-x-6 gap-y-1 sm:grid-cols-2 in Owners.jsx:50 and Repos.jsx:54 — collapses to one column below sm; no order-* utilities so DOM order = visual order = newest-first; #117 caps/overflow (newestFirst/pageSlice/MAX_*, "+N more →" Owners.jsx:56-62) untouched. /:owner stays uncapped and now shares RepoRow — link classes identical to its old row, so no /:owner regression (only addition is the stamp).
  • Last-active source decision: truthful and well-documented. commits?n=1 with server-side ref→HEAD default verified (internal/api/commits.go:18); "last commit" meaning + honest-proxy note (branch-delete/tag-only pushes don't move it) make the active label honest; summary-shape claim verified (summaryBody has no date field, internal/api/summary.go:12-22). commit_date/author_date fields verified in SDK types (web/sdk/src/types.js:9); 404→{commits: []} mapping via SDK err.notFound verified (web/sdk/src/errors.js:25) with backend unborn-HEAD→404 verified (internal/api/bind_wal.go:178-187).
  • Cost (law 6), judged explicitly: worst case doubles the #137 fan-out (500 social + 500 activity = up to 1000 GETs cold at max 50×10 caps). ACCEPTABLE as-is, no batching required: 30s shared activity:{o}/{r} keys with cross-page reuse, placeholder-first + non-blocking independent rows, #117 caps bound it, and batching would need a new backend endpoint (dependency/seam cost disproportionate here). Honest worst case is stated in the component header + doc. One observation (not blocking, pre-exists from #137): data.js LRU cap is 400 entries, so a maxed-out page (1051 keys) churns within the TTL — typical instances are far below caps.
  • Empty-repo "no commits yet": OK. 404 is caught in the fetch (ActivityStamp.jsx:45-52), never reaches the tray. The Chrome-devtools network 404 line is acceptable — it's the wire truth for unborn HEAD, with no console.error and no tray spam.
  • Owner headers: OK as section headers — text-base font-bold tracking-tight + repo-count meta + divide-y sections (Owners.jsx:31-42). Non-blocking nit: the doc (§2.3.1 + FIXED entry) says "a full step above the text-sm rows," but shared RepoRow dropped the old owners-row text-sm on the link (Repos.jsx:22-27), so header-vs-link is distinguished by weight/tracking/spacing, not scale. Suggest a one-word doc touch-up ("by weight" / "above the text-xs meta"); not worth a push on its own.
  • No new deps (diff = 6 files, no package manifests); dark+light via shared .muted/emerald classes only; keyboard unchanged (plain A anchors; placeholder aria-hidden, stamp readable).
  • Doc entries (§2.3.1 + FIXED #142) accurate against backend (commits default ref, summary shape, overview rationale, cache/TLL/cap story, no-new-endpoint/SDK claims all check out). Law 12 satisfied.

No fixes pushed — nothing found that rises above the doc nit. MERGE RECOMMENDATION: ready to merge.

Review of PR #144 (fix/issue-142) — verified in scratch worktree off origin/fix/issue-142 (removed afterward). No browser (per brief); node tests + reasoning + vite build. Main worktree untouched (read-only). TESTS (scratch): `node --test web/test/unit/*.test.js` → 317/317 pass (incl. new activity.test.js: commit_date preference, author_date fallback, empty/missing → null, TTL contract). Note: first run showed 2 fails (data-guard, reaction-cache) purely from missing web/node_modules in the fresh worktree (ERR_MODULE_NOT_FOUND solid-js); green after provisioning node_modules. Vite build → clean (121 modules, built in ~1.5s). REVIEW, point by point: - Two-column grid: OK. `grid grid-cols-1 gap-x-6 gap-y-1 sm:grid-cols-2` in Owners.jsx:50 and Repos.jsx:54 — collapses to one column below sm; no order-* utilities so DOM order = visual order = newest-first; #117 caps/overflow (`newestFirst`/`pageSlice`/`MAX_*`, "+N more →" Owners.jsx:56-62) untouched. /:owner stays uncapped and now shares RepoRow — link classes identical to its old row, so no /:owner regression (only addition is the stamp). - Last-active source decision: truthful and well-documented. `commits?n=1` with server-side ref→HEAD default verified (internal/api/commits.go:18); "last commit" meaning + honest-proxy note (branch-delete/tag-only pushes don't move it) make the `active` label honest; summary-shape claim verified (summaryBody has no date field, internal/api/summary.go:12-22). commit_date/author_date fields verified in SDK types (web/sdk/src/types.js:9); 404→`{commits: []}` mapping via SDK `err.notFound` verified (web/sdk/src/errors.js:25) with backend unborn-HEAD→404 verified (internal/api/bind_wal.go:178-187). - Cost (law 6), judged explicitly: worst case doubles the #137 fan-out (500 social + 500 activity = up to 1000 GETs cold at max 50×10 caps). ACCEPTABLE as-is, no batching required: 30s shared `activity:{o}/{r}` keys with cross-page reuse, placeholder-first + non-blocking independent rows, #117 caps bound it, and batching would need a new backend endpoint (dependency/seam cost disproportionate here). Honest worst case is stated in the component header + doc. One observation (not blocking, pre-exists from #137): data.js LRU cap is 400 entries, so a maxed-out page (1051 keys) churns within the TTL — typical instances are far below caps. - Empty-repo "no commits yet": OK. 404 is caught in the fetch (ActivityStamp.jsx:45-52), never reaches the tray. The Chrome-devtools network 404 line is acceptable — it's the wire truth for unborn HEAD, with no console.error and no tray spam. - Owner headers: OK as section headers — `text-base font-bold tracking-tight` + repo-count meta + divide-y sections (Owners.jsx:31-42). Non-blocking nit: the doc (§2.3.1 + FIXED entry) says "a full step above the text-sm rows," but shared RepoRow dropped the old owners-row `text-sm` on the link (Repos.jsx:22-27), so header-vs-link is distinguished by weight/tracking/spacing, not scale. Suggest a one-word doc touch-up ("by weight" / "above the text-xs meta"); not worth a push on its own. - No new deps (diff = 6 files, no package manifests); dark+light via shared .muted/emerald classes only; keyboard unchanged (plain A anchors; placeholder aria-hidden, stamp readable). - Doc entries (§2.3.1 + FIXED #142) accurate against backend (commits default ref, summary shape, overview rationale, cache/TLL/cap story, no-new-endpoint/SDK claims all check out). Law 12 satisfied. No fixes pushed — nothing found that rises above the doc nit. MERGE RECOMMENDATION: ready to merge.
Author
Owner

Fixed by PR #144 (review: cost explicitly accepted, source verified truthful; 317/317 node tests), merged. Closing.

Fixed by PR #144 (review: cost explicitly accepted, source verified truthful; 317/317 node tests), merged. Closing.
crueber added this to the v1 milestone 2026-09-10 22:27:17 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
crueber/walhub#142
No description provided.