mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-09-21 18:13:26 +00:00
8a85eca713
* feat(web): add cheap aggregation columns to admin user table (TASK-1548)
Surfaces the per-user aggregations T1544 added to GET /admin/users:
- Workspaces (numeric, after Role)
- Storage (used bytes, formatted via the existing formatStorageBytes
helper — same units the storage-override field accepts)
- Last Write (relative time, color-coded by writeRecency: green <7d,
yellow <30d, red ≥30d, gray italic when never)
- Status pill (replaces the standalone "disabled" badge; renders for
disabled / no-workspace / inactive; suppressed for "active" to keep
the table calm)
Implementation:
- AdminUser interface in admin.svelte.ts gains last_write_at,
workspace_count, storage_bytes, status — matching the server-side
JSON shape from T1544.
- writeRecency() helper in +page.svelte buckets the timestamp into a
CSS class. Visual half of the API's status pill; same age windows.
- .num-cell utility: right-aligned, tabular-nums so digits line up
across rows (workspace_count and storage cells share it).
- edit-row colspan updated to 9 (cloud_mode) / 8 (self-hosted) to span
the new columns.
Frontend purely additive — no API changes, no Go changes. T1549 wires
up pagination + sort + filter; T1550-T1555 build the modal.
Part of PLAN-1542.
* fix: address Codex review on TASK-1548
1. handleAdminGetUser response now includes last_write_at, storage_bytes,
and status — matching handleAdminListUsers' shape. Without these,
the row-merge after PATCH (role change, disable, plan edit) kept
stale values; e.g. disabling an active user wouldn't show the new
"disabled" status pill until the full list reloaded.
- Store.UserStorageUsage: new helper that sums attachments across
all workspaces owned by the user. Mirrors WorkspaceStorageUsage's
definition.
- Store.ComputeAdminUserStatusValue: exported wrapper around the
existing private helper so handler code can compute the pill
value without round-tripping through SearchUsers.
2. writeRecency threshold: 30d is now "stale" (inclusive) rather than
"cold". Matches server-side computeAdminUserStatus which only flips
to "inactive" on > 30 days. Eliminates a 1-day boundary mismatch
between the recency color and the status pill.
3. A11y: write-recency cell now carries aria-label with the bucket
name ("Last write: 12d ago (stale)"), so screen-reader users get
the same meaning the color conveys.