feat(ui): refresh-status widget on auto-polling pages#821
feat(ui): refresh-status widget on auto-polling pages#821arlenvasconcelos wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 2cdb3bc. Configure here.
There was a problem hiding this comment.
Reviewed + visual-tested against a live cluster (Home / GitOps / Audit). The component itself is solid — useRefreshAnimation/Tooltip wired correctly, 1s ticker is widget-local so it doesn't re-render the page, refresh resets freshness as expected, tsc clean, zero console errors. The interaction works.
One blocking concern: the widget must not cost vertical space. A freshness indicator is low-value chrome; it's only worth shipping if it slots into space we already have. Right now it's inconsistent across the three surfaces:
- Audit ✅ — slotted into the existing header control cluster (next to "N namespaces hidden" + settings). Zero added height. This is the pattern. Keep it.
- GitOps ❌ — adds a brand-new bordered toolbar band (
border-b ... px-4 py-1.5) above the table, eating ~32px of table height. Worse,SharedGitOpsTableViewalready has anonRefreshbutton in its own header (GitOpsTableView.tsx:636), so this partly duplicates an existing affordance while adding a band on top of it. - Home ❌ — adds a near-empty right-aligned row before the first card (the only content is the widget; the rest of the band is whitespace).
There's already an in-app precedent for doing this right: ResourcesView renders LastUpdatedLabel inline in its existing filter/toolbar row (ResourcesView.tsx:3858), next to Clear-filters and the column picker — no new band. That's the bar.
Asks:
- GitOps — drop the new toolbar. Slot freshness into the shared table's existing header instead: add an optional prop to
GitOpsTableViewProps(e.g.lastUpdatedAt/headerSlot) and render the label next to the existing refresh button, or fold it into that button. Don't stack a band. - Home — there's no existing header row here, so slot it into the
ClusterHealthCardheader (which already shows cluster name + auto-refresh info) rather than minting a band. If there's no clean slot, drop Home — an empty strip isn't worth it. - Keep Audit as-is.
Net rule: no surface should grow vertically just to host this. If we can slot it in everywhere cleanly, great; if a surface can't take it without a new band, that surface is better off without the widget.
|
@arlenvasconcelos showing how many seconds ago is a bit too much distraction. Let's do: 1m – 59m: Xm ago (e.g., 14m ago) 1h – 23h: Xh ago (e.g., 2h ago)
|
We have logic for this already somewhere in the repo, reuse it |
Adds a live freshness label + manual refresh to the pages that auto-poll, slotted into each surface's existing header (no new bands, no duplicate refresh buttons). - New shared UpdatedAtLabel (k8s-ui) — a dumb "Updated N ago" label that re-renders exactly on each bucket boundary. Each surface owns its own refresh button. - Centralized bucket/format logic (formatLastUpdatedBucket, msToNextBucket, formatUpdatedAgo) in utils/format.ts; ResourcesView reuses it. - GitOpsTableView gains optional dataUpdatedAt/isFetching props and renders the label in its existing toolbar; GitOps refresh refetches rows + counts. - Audit renders an inline label + button in its existing header. - Wording: just now / Xm ago / Xh ago / over a day ago. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2cdb3bc to
1f3388b
Compare
|
reworked the initial solution:
|

What
Adds a small "Updated 12s ago · ↻" widget to the header of the pages that auto-poll — Home (cluster status + certs), Audit (Issues), and GitOps.
Why
These pages refresh on a timer but gave the user no signal: no last-updated timestamp and no way to force a refresh. The widget surfaces data freshness and puts a manual refresh within reach.
Details
RefreshStatuscomponent (web/src/components/ui/RefreshStatus.tsx):HomeView(30s),AuditView(1m), andGitOpsViewtable (2m), matching each query's existingrefetchInterval.Follow-up
packages/k8s-uialready has an equivalent inline pattern insideResourcesView(LastUpdatedLabel+ refresh button). A future change should extract this widget into k8s-ui and refactorResourcesViewonto it to avoid drift.🤖 Generated with Claude Code
Note
Low Risk
UI-only freshness and refresh wiring on existing React Query hooks; no auth, data model, or API changes.
Overview
Adds a shared Updated N ago freshness indicator and tighter refresh behavior on GitOps and Checks (Audit) surfaces that poll in the background.
In k8s-ui, a new
UpdatedAtLabeluses bucketed time helpers moved intoformat.ts(formatLastUpdatedBucket,msToNextBucket,formatUpdatedAgo) so labels tick only when the displayed bucket changes, not every second.ResourcesViewdrops its duplicate local helpers and keeps its existingLastUpdatedLabelwired to the shared utilities.GitOpsTableView accepts optional
dataUpdatedAtandisFetching: the toolbar shows the label beside refresh, and the refresh icon spins during initial load or background refetches. GitOpsView passes React Query timestamps, combines row/count fetching for the spinner, and routes manual refresh throughrefetchTableso counts stay aligned with rows.AuditView surfaces the same label plus a manual refresh control using
useRefreshAnimationand queryrefetch, with the icon spinning while fetches run.Reviewed by Cursor Bugbot for commit 1f3388b. Bugbot is set up for automated code reviews on this repo. Configure here.