Skip to content

refactor(admin): edge config card grid and plain-language dialog copy - #2406

Merged
charlietlamb merged 3 commits into
devfrom
charlie/admin-edge-config-ui
Jul 27, 2026
Merged

refactor(admin): edge config card grid and plain-language dialog copy#2406
charlietlamb merged 3 commits into
devfrom
charlie/admin-edge-config-ui

Conversation

@charlietlamb

@charlietlamb charlietlamb commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Reworks the admin Edge Config UI. No functional changes — every endpoint, payload key, validation rule and min/max bound is byte-identical to dev (verified: 21 admin endpoints before, 21 after, identical set).

Why

The Edge Config tab was 14 undifferentiated rows of identical visual weight, and dialog help text read as engineering notes rather than operator instructions. You couldn't tell a queue was paused or a ramp was at 40% without opening every dialog.

What changed

Sectioned card grid. Both Edge Config and Queue/Cron now render a card grid grouped into sections (Access Control, Cache & Redis, Rollouts & Flags, Integrations). Each card shows a live status line derived from its own config endpoint — 2 orgs blocked, 40% ramped, 1 queue paused — so state is visible without opening anything. Card definitions live in one registry keyed by config id, so regrouping is a data edit.

Plain-language copy. Every field description rewritten to one short sentence. Representative:

before: Max queued (pending) DB hydrations for a single (org, env, customer), cluster-wide (enforced as this ÷ fleet process count per process) — reject with 429 before queueing at or above it. Bounds heap memory + worst-case wait.

after: Requests waiting per customer before new ones are rejected.

Cross-cutting caveats (the ÷ fleet-count rule) are now stated once in the dialog footer instead of repeated per field.

Fixed 5 factually wrong propagation claims. Several dialogs told operators the wrong refresh interval. Each is now checked against its store's actual pollIntervalMs:

Dialog Claimed Actual
Org Limits 5 minutes 30s
Feature Flags 30s 10s
Miscellaneous 30s 10s
Job Queues ~60s 10s
FullSubject Gate 30s 10s

Org Limits (30s) and Stripe Sync (60s) have custom intervals; everything else uses the 10s default. These were pre-existing bugs.

Consistency (/charlie). Extracted EdgeConfigDialogBody for the loading/error/retry states — removes 9 duplicated copies, including 3 nested ternaries. Migrated 4 dialogs from useEffect+axios to TanStack Query, each split into Dialog/Form/types per the existing ResetJobV2Config* pattern. Replaced hand-rolled toggles and a bespoke role="switch" div with shadcn Switch; swapped hardcoded bg-amber-50/emerald badges (which broke in dark mode) for theme-aware primitives; added aria-labels to previously unlabelled inputs.

Safety-relevant copy. Job Queues now states that paused work backs up rather than being dropped. Raw JSON editing spells out that it overwrites the file for every org, and surfaces the real parser error (Unexpected token } at position 214) instead of a bare "Invalid JSON".

Verification

  • bun ts clean, Biome clean on all 46 files
  • 13/13 existing admin tests pass
  • Endpoint set diffed against origin/dev — identical
  • PUT payloads confirmed unchanged (the hybrid Monaco dialogs still send JSON.parse(jsonText), the text buffer, not form state)

Notes for review

  • Not manually clicked through. Typecheck/tests/diff-level verification only — worth an eyeball on both tabs before merge, especially the 4 newly-split dialogs and the Cache V2 Ramp setup path (unconfigured ramps must still show the setup form, not an error).
  • Deferred deliberately: 4 large hybrid form+Monaco dialogs (Request Blocking, Customer Blocking, Rate Limit Overrides, Feature Flags) keep their useState/useEffect state. Their PUT body is the JSON text buffer, so converting risks changing what's written to S3. Copy and consistency fixes applied; restructure left for a follow-up.
  • Dead code left in place: 4 exports in rateLimitRedisAllowlistDialogState.ts are now unused in prod (the stale-data invariant they guarded is enforced structurally by EdgeConfigDialogBody), but ~5 tests still cover them. Deleting them drops regression coverage for a real past bug — left as a deliberate follow-up decision.
  • Out of scope: packages/ui Alert has no warning variant (several dialogs want one), and per-queue descriptions are server-owned in KNOWN_JOB_QUEUES.

Summary by cubic

Refactored the admin Edge Config and Queue/Cron tabs into a sectioned card grid with live status and clearer, plain‑language dialogs. No backend changes — endpoints, payloads, validation, and bounds are unchanged.

  • Refactors

    • Added a registry-driven card grid grouped by Access Control, Cache & Redis, Rollouts & Flags, and Integrations; each card shows a live status from its own endpoint.
    • Extracted EdgeConfigDialogBody for shared load/error/retry UI; migrated several dialogs to @tanstack/react-query and split them into Dialog/Form/types for consistency.
    • Replaced custom toggles/badges with theme-aware @autumn/ui components (e.g., Switch) and added ARIA labels for inputs; dark-mode friendly.
  • Bug Fixes

    • Corrected propagation interval copy to match actual pollIntervalMs (Org Limits 30s; Stripe Sync 60s; others 10s).
    • Clarified safety copy: paused queues back up work; raw JSON editing warns it overwrites all orgs and now surfaces real parse errors.

Written for commit 2c1e44d. Summary will update on new commits.

Review in cubic

Greptile Summary

Refactors the admin Edge Config interface and operator-facing copy without changing its API surface.

  • [Improvements] Replaces undifferentiated configuration rows with sectioned cards and live status summaries.
  • [Improvements] Extracts shared dialog loading, error, retry, form, and type components and migrates several dialogs to TanStack Query/Form.
  • [Bug fixes] Corrects propagation guidance, improves destructive-action warnings and JSON errors, and adopts accessible, theme-aware controls.

Confidence Score: 4/5

The incorrect Job Queues status should be fixed before merging because the new overview can claim every queue is active while a default-disabled queue remains paused.

The status registry derives queue state from only explicitly persisted entries, whereas runtime behavior applies server-owned defaults to omitted queues, producing a false operational summary in the default configuration.

vite/src/views/admin/components/edgeConfigCards.ts

Important Files Changed

Filename Overview
vite/src/views/admin/components/edgeConfigCards.ts Defines the new card registry and status derivation; Job Queues incorrectly ignores disabled-by-default queues absent from the sparse stored config.
vite/src/views/admin/components/EdgeConfigCard.tsx Adds reusable status-query cards with loading, unavailable, and derived-status presentation.
vite/src/views/admin/components/EdgeConfigTab.tsx Replaces the flat Edge Config list with grouped cards and centralized dialog selection.
vite/src/views/admin/components/EdgeConfigDialogBody.tsx Centralizes query loading, error, retry, and ready-state rendering for configuration dialogs.
vite/src/views/admin/components/JobQueuesForm.tsx Migrates queue editing to TanStack Form while preserving effective defaults and the existing PUT payload shape.
vite/src/views/admin/components/CacheV2RampDialog.tsx Splits configured and unconfigured ramp states into query-backed forms while retaining the setup path.
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
vite/src/views/admin/components/edgeConfigCards.ts:383-390
**Queue defaults produce false status**

When the sparse job-queue config omits the default-disabled Customer Creation Recovery Queue, this code counts only explicitly stored entries and reports “All active,” causing the overview to hide a queue that is paused at runtime.

Reviews (1): Last reviewed commit: "refactor(admin): plain-language copy and..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

@capy-ai

capy-ai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Capy auto-review is paused for this organization because the usage-cycle auto-review limit has been reached. Increase the limit or turn it off in billing settings to resume automatic reviews.

Comment on lines +383 to +390
deriveStatus: (data) => {
const entries = Object.values(asRecord(asRecord(data).queues));
const paused = entries.filter(
(entry) => asRecord(entry).enabled === false,
).length;

return paused === 0
? { label: "All active", tone: "neutral" }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Queue defaults produce false status

When the sparse job-queue config omits the default-disabled Customer Creation Recovery Queue, this code counts only explicitly stored entries and reports “All active,” causing the overview to hide a queue that is paused at runtime.

Prompt To Fix With AI
This is a comment left during a code review.
Path: vite/src/views/admin/components/edgeConfigCards.ts
Line: 383-390

Comment:
**Queue defaults produce false status**

When the sparse job-queue config omits the default-disabled Customer Creation Recovery Queue, this code counts only explicitly stored entries and reports “All active,” causing the overview to hide a queue that is paused at runtime.

How can I resolve this? If you propose a fix, please make it concise.

@charlietlamb
charlietlamb merged commit 0def936 into dev Jul 27, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant