Skip to content

Admin Record State UX Follow-up Design

Task: CAP-0080 Date: 2026-08-01 Status: Implemented and locally verified — 2026-08-02

Extend the completed record-state visibility work so editors can find, understand, and safely act on exceptional records without opening every resource. The follow-up applies the same availability, publication, usage, and integrity language to discovery filters, navigation, deletion decisions, and a small health summary.

It remains an authoring-only improvement. It does not automatically delete, enable, publish, repair, or change customer-visible output.

Use a layered experience rather than a new broad dashboard or a package-wide mechanical rewrite:

  1. Surface exceptional state in the resource where an editor is already working, using saved filter-compatible table filters and visible tab/count affordances where the resource already supports them.
  2. Make non-zero relationship counts actionable by linking to the filtered, authorized list of known references.
  3. Show a narrow impact summary before destructive actions, based only on relationships that the owning package can resolve safely and completely for that action.
  4. Aggregate only the highest-value signals in the existing Layout Builder health widget. Do not add a competing global dashboard.

This preserves the initial presentation contract and keeps all fact discovery in the record-owning package.

Each supported resource gets a small, explicit set of exceptional-state filters. Filter labels and counts use the existing translated state language; they are never icon-only.

ResourceFilters / discovery statesCount meaning
PagesNo active URL, scheduled, expired, draft, and URLs disabledCount is the current scoped query result, never a global claim.
LayoutsDisabled and unusedUnused is available only from the existing exhaustive variation-aware layout-use aggregate.
MediaUnused or no tracked usesThe label follows the attachment tracker authority flag.
WidgetsUnused and unavailableUnused uses the complete Layout Builder-owned usage boundary; unavailable does not imply removal of existing placements.
Widget assetsBroken reference and unscopedThese are integrity states, not usage states.

Tables retain their ordinary default order and quiet enabled/in-use rows. Exceptional filters may appear as tabs only when the resource already uses tabs; otherwise they are table filters with query indicators. This avoids inventing a divergent table-navigation pattern.

Counts answer a dependency question only when they lead to the evidence behind the count. Positive count metadata therefore links to the corresponding authorized, filtered resource list:

  • page URL counts link to the page URL management context;
  • layout use counts link to pages using that layout, across registered page variations;
  • widget layout counts link to layouts with the widget key filter;
  • media usage counts retain the existing usage list;
  • valid widget asset references link to the owning target where the target still exists and the actor is authorized.

If a reference list cannot be represented by a stable, authorized query, the count remains plain metadata. No per-row queries are introduced to construct links.

Headers and confirmation copy state the consequence in plain language. For example, a scheduled page with no active URL explains that scheduling alone will not make it publicly reachable; a disabled layout says that it is not available for new use. Tooltip text may supplement this copy but never carry the only explanation.

Before a delete action is confirmed, the resource resolves a typed impact summary for the specific record(s): known direct references, their count, whether that count is authoritative for the action, and a safe navigation URL where possible.

The confirmation has three outcomes:

  • No known references: retain the normal confirmation. Say Unused only when the relevant usage query is authoritative; otherwise say No tracked uses.
  • Known references: show the number and type of direct records that will be affected or left without their dependency. Provide a view-uses link when available.
  • Broken / incomplete evidence: identify the record as requiring review; do not convert it into an “unused” cleanup suggestion.

The follow-up does not change deletion authorization or add a new cleanup bulk action. Existing domain deletion behaviour remains the authority. Bulk-action confirmations show aggregate counts and exceptional selections, not an unbounded list of record names.

The shared select-option contract is adopted only by selectors that expose a page, layout, widget, or referenced target to editors. Existing selected records must keep rendering even if unavailable. New-selection eligibility continues to be enforced by the relevant field rule rather than by a decorative badge.

The focused adoption inventory covers page/navigation/link/redirect choices, layout pickers, widget pickers, and widget-asset target pickers. It does not attempt to update every package-owned Filament field. Surfaces outside the shared contract become a separately ranked extension-adoption task.

Global search keeps the compact state summary already established in the first slice. It does not grow a second set of filters or counts.

Layout Builder’s existing LayoutHealthFilamentWidget is the single aggregation surface for this follow-up. It receives scoped counts and deep links for:

  • unused or unavailable widgets;
  • broken or unscoped widget assets;
  • disabled or unused layouts when the admin resource is available;
  • page reachability exceptions when the current actor can access Pages.

Every card describes its scope and uses the same authority-aware wording as the underlying table. It is deliberately a short work queue, not an analytics dashboard: no trends, no historical scoring, no background scan, and no cross-site totals the actor cannot inspect.

  • packages/admin owns presentation data, reusable filters, impact-summary display, and Admin resource wiring. It does not own Layout Builder models.
  • Each owning package supplies an Action plus immutable Data object for its queryable state or destructive impact facts.
  • Every list, picker, header, health card, and confirmation preloads required facts or uses one bounded aggregate query. Views and closures never query.
  • authoritative is propagated to labels and confirmations. Actor-scoped or extension-limited zero counts render No tracked uses or No accessible uses, never Unused.
  • URLs respect resource authorization, site, language, page variation, and current table filter conventions. A missing safe URL leaves the count non-clickable.
  • No raw layout/widget content is decoded per table row. Existing indexed usage data and proven query helpers are reused.

Focused tests cover:

  • each exceptional filter’s query and indicator wording;
  • authoritative versus non-authoritative zero usage labels;
  • action URLs and the absence of links where a safe target is unavailable;
  • single and bulk deletion-impact summaries for no-use, known-use, and broken cases;
  • selected unavailable records remaining comprehensible in shared selectors;
  • health-widget query bounds, actor scoping, and deep-link parameters;
  • regression coverage for existing state summaries, page variation-aware layout counts, and broken widget asset records.

Run the narrow Admin and Layout Builder Pest suites first, then the relevant package static analysis. The companion repository’s full analysis remains a separate gate if its existing NavigationSelect nullable-string finding persists.

  • Core/Admin: 46 focused tests / 297 assertions, the record-state fixture suite (5 / 37), and composer analyze pass.
  • Layout Builder: 33 focused tests / 555 assertions, targeted PHPStan and Pint pass. The full companion analysis remains blocked only by the pre-existing nullable-label issue in packages/navigation’s NavigationSelect.
  • Authenticated documentation captures pass: Core 12 light/dark variants and Layout Builder’s two integrity tables, all with zero failures. The page layout selector capture renders Filament’s HTML option markup with explicit Disabled and Unused layout states.
  • Sol’s final review approved the implementation after the media projection, direct-login removal, workbench-only fixture seeding, and read-only presenter fixes.