## Summary - standardize Filament table defaults across resources, relation managers, widgets, custom pages, and picker tables - add shared pagination profiles, calm default column visibility, explicit empty states, and session persistence on designated critical resource lists - complete Spec 125 artifacts, regression tests, and dashboard widget follow-up for lazy loading, sortable columns, and toggleable detail columns ## Verification - `docker exec tenantatlas-laravel.test-1 php artisan test --compact --filter=BaselineCompareNow` - `docker exec tenantatlas-laravel.test-1 php artisan test --compact --filter=TableStandardsBaseline` - `docker exec tenantatlas-laravel.test-1 php artisan test --compact --filter=TableDetailVisibility` - `docker exec tenantatlas-laravel.test-1 php artisan test --compact --filter=FilamentTableRiskExceptions` - full suite run completed: `2017 passed, 10 failed, 8 skipped` - manual browser QA completed on the tenant dashboard for lazy loading, sortable widget columns, toggleable hidden status columns, badges, and pagination ## Known Failures The full suite still has 10 pre-existing failures unrelated to this branch: - `Tests\\Unit\\OpsUx\\SummaryCountsNormalizerTest` - `Tests\\Feature\\BackupWithAssignmentsConsistencyTest` (2 tests) - `Tests\\Feature\\BaselineDriftEngine\\CaptureBaselineContentTest` - `Tests\\Feature\\BaselineDriftEngine\\CompareContentEvidenceTest` - `Tests\\Feature\\BaselineDriftEngine\\ResolverTest` - `Tests\\Feature\\Filament\\TenantDashboardDbOnlyTest` - `Tests\\Feature\\Operations\\ReconcileAdapterRunsJobTrackingTest` - `Tests\\Feature\\ReviewPack\\ReviewPackRbacTest` - `Tests\\Feature\\Verification\\VerificationReportRedactionTest` Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #152
111 lines
7.3 KiB
Markdown
111 lines
7.3 KiB
Markdown
# Filament Table Standard
|
||
|
||
## Standard
|
||
|
||
TenantPilot standardizes production Filament list surfaces with a convention-first model:
|
||
|
||
- Primary: searchable identifier or record title that anchors the row.
|
||
- Context: status, ownership, recency, and counts needed for a normal scan.
|
||
- Detail: technical IDs, secondary timestamps, verbose metadata, and low-frequency troubleshooting fields.
|
||
|
||
## Required Rules
|
||
|
||
- Every production table defines an explicit default sort unless a documented exception exists.
|
||
- Every production table provides a domain-specific empty state heading and description.
|
||
- General-purpose tables should expose seven or fewer columns by default unless density is part of the job.
|
||
- Primary identifiers should be searchable and sortable when query-safe.
|
||
- Technical identifiers and secondary metadata should be toggleable and hidden by default where practical.
|
||
- Resource lists in the critical set persist search, sort, and filters in session.
|
||
- Existing action surfaces, RBAC behavior, confirmations, and centralized badge semantics stay unchanged.
|
||
|
||
## Pagination Profiles
|
||
|
||
| Surface | Page sizes | Default |
|
||
|---|---|---|
|
||
| Resource | `25, 50, 100` | `25` |
|
||
| Relation manager | `10, 25, 50` | `10` |
|
||
| Widget | `10` | `10` |
|
||
| Picker | `25, 50, 100` | `25` |
|
||
| Custom page | `25, 50, all` | `25` unless a page overrides it explicitly |
|
||
|
||
Implementation uses [TablePaginationProfiles.php](/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Filament/TablePaginationProfiles.php).
|
||
|
||
## Timestamp, Null, and ID Rules
|
||
|
||
- Prefer `->since()` for scan-first timestamps unless exact chronology is the primary task.
|
||
- Use `—` for missing values unless the domain needs a more specific placeholder.
|
||
- Long identifiers should remain copyable and readable without dominating the default layout.
|
||
- Prefer monospaced styling and tooltips for truncated technical identifiers.
|
||
|
||
## Review Checklist
|
||
|
||
- Primary column is obvious and query-safe.
|
||
- Default sort matches the table’s operational purpose.
|
||
- Empty-state copy explains what the list is waiting for.
|
||
- Hidden detail can be revealed in one toggle or one drill-in.
|
||
- Pagination profile matches the table class.
|
||
- Critical resource lists declare session persistence.
|
||
- No destructive action lost its confirmation or authorization guard.
|
||
|
||
## Rollout Audit
|
||
|
||
### Persistence Surfaces
|
||
|
||
The following resource lists must persist search, sort, and filters in session:
|
||
|
||
- `TenantResource`
|
||
- `PolicyResource`
|
||
- `BackupSetResource`
|
||
- `BackupScheduleResource`
|
||
- `ProviderConnectionResource`
|
||
- `FindingResource`
|
||
- `OperationRunResource`
|
||
|
||
### Documented Exceptions
|
||
|
||
- `RecentDriftFindings` and `RecentOperations` do not add table search because dashboard widgets are glance surfaces, not investigative workbenches.
|
||
- `Directory/Workspaces` keeps computed health and recent-failure metrics non-sortable and non-searchable because those values are derived per row.
|
||
- `InventoryCoverage` uses the custom-page pagination profile but keeps the broader `all` option and a `50`-row default because operators sometimes need a full matrix pass.
|
||
- Picker tables keep workflow-local search only; they do not persist state in session.
|
||
|
||
### Surface Inventory
|
||
|
||
| Surface | Class | Pagination | Default sort | Empty state | Persistence | Notes |
|
||
|---|---|---|---|---|---|---|
|
||
| Tenant list | `resource` | resource | `name asc` | yes | yes | Workspace-scoped create CTA remains in list page |
|
||
| Policy list | `resource` | resource | `display_name asc` | yes | yes | Sync CTA remains list-local |
|
||
| Backup set list | `resource` | resource | `created_at desc` | yes | yes | Create CTA remains list-local |
|
||
| Backup schedule list | `resource` | resource | `next_run_at asc` | yes | yes | Create CTA remains list-local |
|
||
| Provider connections | `resource` | resource | `display_name asc` | yes | yes | Empty-state CTA remains tenant-aware |
|
||
| Findings | `resource` | resource | `created_at desc` | yes | yes | Open filter remains the default |
|
||
| Monitoring operations | `resource-backed page` | resource | `created_at desc` | yes | yes | Canonical operations view uses `OperationRunResource::table()` |
|
||
| Entra groups | `resource` | resource | `display_name asc` | yes | no | Directory browse remains read-only |
|
||
| Alert deliveries | `resource` | resource | `id desc` | yes | no | Delivery history stays read-only |
|
||
| Alert rules | `resource` | resource | `name asc` | yes | no | Rule actions remain explicit per row |
|
||
| Alert destinations | `resource` | resource | `name asc` | yes | no | Destination test/send actions remain unchanged |
|
||
| Baseline profiles | `resource` | resource | `name asc` | yes | no | Create CTA remains list-local |
|
||
| Baseline snapshots | `resource` | resource | `captured_at desc` | yes | no | Snapshot browsing remains read-only |
|
||
| Inventory items | `resource` | resource | `last_seen_at desc` | yes | no | Scan-first recency view |
|
||
| Policy versions resource | `resource` | resource | `captured_at desc` | yes | no | Version history remains inspectable and immutable |
|
||
| Review packs | `resource` | resource | `created_at desc` | yes | no | Review workflow actions unchanged |
|
||
| Workspace resource | `resource` | resource | `name asc` | yes | no | Workspace create CTA remains list-local |
|
||
| Backup items | `relation_manager` | relation manager | `policy.display_name asc` | yes | no | Action semantics unchanged |
|
||
| Policy versions | `relation_manager` | relation manager | `version_number desc` | yes | no | Existing relation query preserved |
|
||
| Backup schedule operation runs | `relation_manager` | relation manager | `created_at desc` | yes | no | Existing record view preserved |
|
||
| Tenant memberships | `relation_manager` | relation manager | `created_at desc` | yes | no | Role management unchanged |
|
||
| Workspace memberships | `relation_manager` | relation manager | `created_at desc` | yes | no | Role management unchanged |
|
||
| Baseline tenant assignments | `relation_manager` | relation manager | `created_at desc` | yes | no | Assignment action unchanged |
|
||
| Inventory coverage | `custom_page` | custom page | `label asc` | yes | no | Keeps `all` pagination option |
|
||
| System directory tenants | `custom_page` | custom page | `name asc` | yes | no | Search stays on meaningful identity fields |
|
||
| System directory workspaces | `custom_page` | custom page | `name asc` | yes | no | Computed metrics remain exceptions |
|
||
| Ops runs | `custom_page` | custom page | `id desc` | yes | no | Platform triage actions unchanged |
|
||
| Ops failures | `custom_page` | custom page | `id desc` | yes | no | Platform triage actions unchanged |
|
||
| Ops stuck | `custom_page` | custom page | `id desc` | yes | no | Platform triage actions unchanged |
|
||
| Access logs | `custom_page` | custom page | `recorded_at desc` | yes | no | Read-only operational surface |
|
||
| Repair workspace owners | `custom_page` | custom page | `name asc` | yes | no | Repair action unchanged |
|
||
| Recent drift findings | `widget` | widget | `created_at desc` | yes | no | No search by design |
|
||
| Recent operations | `widget` | widget | `created_at desc` | yes | no | No search by design |
|
||
| Backup set policy picker | `picker` | picker | `display_name asc` | yes | no | Workflow-local search only |
|
||
| Entra group picker | `picker` | picker | `display_name asc` | yes | no | Workflow-local search only |
|
||
| Settings catalog table | `picker` | picker | `definition asc` | yes | no | Workflow-local search only |
|