## Summary - implement the Action Surface Contract v1.1 runtime changes for Spec 169 - add the new explicit ActionSurfaceType contract, validator/discovery updates, and enrolled surface declarations - update Filament action-surface documentation, focused guard tests, and spec artifacts for the completed feature ## Included - clickable-row vs explicit-inspect enforcement across monitoring, reporting, CRUD, and system reference surfaces - helper-first, workflow-next, destructive-last overflow ordering checks - system panel list discovery in the primary action-surface validator - Spec 169 artifacts: spec, plan, tasks, research, data model, quickstart, and logical contract ## Verification - focused Pest verification pack completed for: - tests/Feature/Guards/ActionSurfaceValidatorTest.php - tests/Feature/Guards/ActionSurfaceContractTest.php - tests/Feature/Rbac/TenantActionSurfaceConsistencyTest.php - integrated browser smoke test completed for admin-side reference surfaces: - /admin/operations - /admin/audit-log - /admin/finding-exceptions/queue - /admin/reviews - /admin/tenants ## Notes - system panel browser smoke coverage could not be exercised in the same session because /system routes require platform authentication in the integrated browser - Livewire target remains v4-compliant and no provider registration or asset strategy changes are introduced by this PR Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #200
153 lines
4.8 KiB
Markdown
153 lines
4.8 KiB
Markdown
# Filament Actions UX Standard
|
|
|
|
> Canonical rules for row actions, bulk actions, header actions, and inspect affordances on all Filament table surfaces.
|
|
> This standard consolidates the Action Surface Contract from the constitution and `docs/ui/action-surface-contract.md`.
|
|
|
|
**Last reviewed**: 2026-03-30
|
|
|
|
---
|
|
|
|
## Governing Principle
|
|
|
|
**Filament-native first.**
|
|
Action patterns use native Filament action APIs.
|
|
The constitution's Action Surface Contract (in `.specify/memory/constitution.md`) is the authoritative source for safety and RBAC rules.
|
|
This document provides the quick-reference standard for implementation.
|
|
|
|
---
|
|
|
|
## Required Surfaces
|
|
|
|
Every list/table must define:
|
|
|
|
- **Header Actions** — primary CTA (create, sync, etc.)
|
|
- **Row Actions** — inspect + contextual operations
|
|
- **Bulk Actions** — where batch operations exist
|
|
- **Empty-State CTA** — exactly 1 primary action, RBAC-gated
|
|
|
|
---
|
|
|
|
## Inspect Affordance (Required)
|
|
|
|
Every list-style surface must provide a way to open a record.
|
|
|
|
### Default: clickable rows for list-first and registry surfaces
|
|
|
|
```php
|
|
$table->recordUrl(fn ($record) => /* route to view/edit */)
|
|
```
|
|
|
|
Use this default for:
|
|
|
|
- CRUD / List-first resources
|
|
- Read-only registries / reports
|
|
- Reporting and evidence registers such as Review Register and Evidence Overview
|
|
|
|
### Explicit inspect for queue and audit surfaces
|
|
|
|
Use an `Inspect` row action or equivalent same-page selected detail when chronology or queue context must remain visible.
|
|
|
|
- Audit / history pages use explicit inspect
|
|
- Queue / review pages use explicit inspect
|
|
- These surfaces should not also expose row click as a competing open path
|
|
|
|
### Alternative: primary link column
|
|
|
|
Use only when clickable rows are impractical on a clickable-row surface.
|
|
|
|
- `PrimaryLinkColumn` requires a non-empty declaration reason
|
|
- It is not a fallback for queue / review or audit surfaces
|
|
|
|
### Rule: no lone "View" button
|
|
|
|
If an open action is the only row action on a clickable-row surface, prefer row click and set `actions([])` to avoid an unnecessary Actions column.
|
|
|
|
---
|
|
|
|
## Row Action Limits
|
|
|
|
- **Max 2 visible** row actions (typically View/Edit or Edit/Delete)
|
|
- Everything else goes into an `ActionGroup` labeled "More"
|
|
- Destructive actions must never be the primary visible action
|
|
- On clickable-row surfaces, prefer zero inline row actions unless a single justified shortcut materially improves the workflow
|
|
|
|
---
|
|
|
|
## Bulk Actions
|
|
|
|
- Bulk actions must be grouped via `BulkActionGroup`
|
|
- Destructive bulk actions require confirmation
|
|
- Typed confirmation may be required for large/bulk changes
|
|
- Do not leave an empty `BulkActionGroup` placeholder visible once filters, record state, or RBAC remove every effective action
|
|
|
|
---
|
|
|
|
## Destructive Action Safety
|
|
|
|
- All destructive actions must use `->requiresConfirmation()`
|
|
- Destructive actions must not be styled as primary
|
|
- Confirmation text must clearly describe the consequence
|
|
- Server-side authorization must still enforce the action regardless of UI confirmation
|
|
|
|
This is a constitution-level non-negotiable (RBAC-UX-005).
|
|
|
|
---
|
|
|
|
## Action Consistency
|
|
|
|
### Standard action labels
|
|
|
|
| Action | Label | Icon guidance |
|
|
|---|---|---|
|
|
| Inspect record | "Inspect" | heroicon-o-eye |
|
|
| Edit record | "Edit" | heroicon-o-pencil-square |
|
|
| Delete record | "Delete" | heroicon-o-trash |
|
|
| Archive record | "Archive" | heroicon-o-archive-box |
|
|
| Restore record | "Restore" | heroicon-o-arrow-uturn-left |
|
|
| Force delete | "Force Delete" | heroicon-o-trash |
|
|
|
|
Notes:
|
|
- Clickable-row surfaces normally do not render a `View` or `Inspect` row action at all.
|
|
- Reporting/evidence registers keep row click primary and should not add a duplicate `View review`-style action.
|
|
|
|
### Action ordering in "More" group
|
|
|
|
1. Navigation or inspect helpers first
|
|
2. Non-destructive workflow or lifecycle actions next
|
|
3. Destructive actions last
|
|
4. Do not render an empty `ActionGroup` placeholder
|
|
|
|
Representative expectations:
|
|
|
|
- `Policies`: `Export`, then `Sync`, then destructive ignore/delete actions
|
|
- `Backup schedules`: `Run now` / `Retry` before archive or force delete
|
|
- `Workspaces`: row click stays primary and the secondary `Edit` shortcut lives under `More`
|
|
|
|
---
|
|
|
|
## RBAC Enforcement
|
|
|
|
- Non-member access: abort(404), do not leak existence
|
|
- Member without capability: visible but disabled with tooltip
|
|
- Server-side must enforce via `Gate::authorize(...)` or Policy method
|
|
- Missing server-side authorization is a P0 security bug
|
|
|
|
---
|
|
|
|
## Spec / DoD Gate
|
|
|
|
Every spec with UI changes must include a **UI Action Matrix** listing:
|
|
|
|
- Which actions exist on which surfaces
|
|
- Which are destructive and how confirmation is handled
|
|
- Which capabilities gate each action
|
|
|
|
A change is not "Done" unless the Action Surface Contract is met.
|
|
|
|
---
|
|
|
|
## Canonical Sources
|
|
|
|
- Constitution: `.specify/memory/constitution.md` → "Filament UI — Action Surface Contract"
|
|
- Detailed reference: `docs/ui/action-surface-contract.md`
|