feat(web): add shared empty_state() and route every list through it #474

Merged
nrupard merged 1 commit from fix/BUNYIP-468-empty-state into main 2026-08-05 16:31:29 +02:00
Owner

Implements BUNYIP-468 (2026-08-04 bunyip UI audit, F11): list empty-states rendered four different ways across the app (and twice differently within a single page). This adds one shared component and routes every list empty branch through it.

Change

  • New views::ui::empty_state(icon_name, message, cta: Option<Markup>): a centered py-12 column with a large muted icon, a muted message, and an optional CTA below. Modeled on the richest existing pattern (the membership-invoices icon block). Carries a regression test covering both the CTA and no-CTA arms.
  • 24 list empty branches across 14 handler files now call it (admin entitlements/application-groups/dashboard/error-log/ip-bans/audit/rate-limits/feedback/seed/stripe/applications/users, plus the settings sessions/devices/invoices/payments lists and the public app-docs list). Each keeps its existing message; the one filtered-empty CTA ("Clear all filters" on the user list) is preserved via Some(...).
  • No ad-hoc empty markup remains: a grep for the old py-8 / py-6 / icon+py-12 empty patterns returns nothing in handlers.

Scope notes

  • Every is_empty() in bunyip-web was classified: 24 are list empty-states (routed); the ~90 others are input validation, query-string building, conditional-section omission, field placeholders, and error/loading branches (not list empties, left as-is).
  • Presence states that are not list-empties are untouched: the "No Active Membership" hero and the admin "environment has no applications yet" banner.
  • The unused icon import in entitlements.rs (it only used icon( inside its empty state) was swapped for empty_state to keep clippy green; every other file still uses icon elsewhere and only gained the new import.

Verification

just check-container (dockerized fmt + clippy + workspace tests, incl. the new empty_state test) green.

#BUNYIP-468

Implements BUNYIP-468 (2026-08-04 bunyip UI audit, F11): list empty-states rendered four different ways across the app (and twice differently within a single page). This adds one shared component and routes every list empty branch through it. ## Change - New `views::ui::empty_state(icon_name, message, cta: Option<Markup>)`: a centered `py-12` column with a large muted icon, a muted message, and an optional CTA below. Modeled on the richest existing pattern (the membership-invoices icon block). Carries a regression test covering both the CTA and no-CTA arms. - 24 list empty branches across 14 handler files now call it (admin entitlements/application-groups/dashboard/error-log/ip-bans/audit/rate-limits/feedback/seed/stripe/applications/users, plus the settings sessions/devices/invoices/payments lists and the public app-docs list). Each keeps its existing message; the one filtered-empty CTA ("Clear all filters" on the user list) is preserved via `Some(...)`. - No ad-hoc empty markup remains: a grep for the old py-8 / py-6 / icon+py-12 empty patterns returns nothing in handlers. ## Scope notes - Every `is_empty()` in bunyip-web was classified: 24 are list empty-states (routed); the ~90 others are input validation, query-string building, conditional-section omission, field placeholders, and error/loading branches (not list empties, left as-is). - Presence states that are not list-empties are untouched: the "No Active Membership" hero and the admin "environment has no applications yet" banner. - The unused `icon` import in entitlements.rs (it only used `icon(` inside its empty state) was swapped for `empty_state` to keep clippy green; every other file still uses `icon` elsewhere and only gained the new import. ## Verification `just check-container` (dockerized fmt + clippy + workspace tests, incl. the new empty_state test) green. #BUNYIP-468
feat(web): add shared empty_state() and route every list through it
All checks were successful
E2E PR gate / Install + reachability (no deployment secrets) (pull_request) Successful in 35s
Check / fmt + clippy + build + tests (pull_request) Successful in 24m14s
Create release / Create release from merged PR (pull_request) Has been skipped
fb83df3138
Implements BUNYIP-468 (2026-08-04 UI audit F11): list empty-states rendered four different ways across the app (and twice within a single page). Adds views::ui::empty_state(icon_name, message, cta: Option<Markup>), a centered py-12 column with a large muted icon, a muted message, and an optional CTA, modeled on the richest existing pattern. Routes 24 list empty branches across 14 handler files through it, preserving each message and the one filtered-empty "Clear all filters" CTA; no ad-hoc empty markup remains. The ~90 other is_empty() uses (validation, query building, conditional-section omission, error/loading branches) are not list empties and are left as-is.

#BUNYIP-468
nrupard scheduled this pull request to auto merge when all checks succeed 2026-08-05 16:18:50 +02:00
nrupard deleted branch fix/BUNYIP-468-empty-state 2026-08-05 16:31:30 +02:00
Sign in to join this conversation.
No reviewers
No labels
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
psa-systems/bunyip!474
No description provided.