## 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
120 lines
9.4 KiB
Markdown
120 lines
9.4 KiB
Markdown
# Implementation Plan: Filament Table UX Standardization & List Consistency
|
||
|
||
**Branch**: `125-table-ux-standardization` | **Date**: 2026-03-08 | **Spec**: `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/125-table-ux-standardization/spec.md`
|
||
**Input**: Feature specification from `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/125-table-ux-standardization/spec.md`
|
||
|
||
**Note**: This template is filled in by the `/speckit.plan` command. See `.specify/scripts/` for helper scripts.
|
||
|
||
## Summary
|
||
|
||
Standardize the product’s Filament list surfaces with a convention-first, native-Filament rollout that keeps table behavior explicit in existing `table()` definitions, adds resource-list state persistence, normalizes default sort and empty-state behavior, and reduces default column sprawl through a documented Primary / Context / Detail model. The implementation will avoid a heavy helper framework, preserve existing action and RBAC behavior, keep centralized badge semantics intact, and allow only a tiny pagination-profile helper early in the rollout where the reuse is purely mechanical and does not hide per-surface table logic.
|
||
|
||
## Technical Context
|
||
|
||
**Language/Version**: PHP 8.4.15
|
||
**Primary Dependencies**: Laravel 12, Filament 5, Livewire 4, Tailwind CSS 4, existing `BadgeCatalog` / `BadgeRenderer`, existing UI enforcement helpers, existing Filament resources, relation managers, widgets, and Livewire table components
|
||
**Storage**: PostgreSQL remains unchanged; this feature is presentation-layer and behavior-layer only
|
||
**Testing**: Pest 4 feature tests for critical Filament list surfaces, relation manager coverage where applicable, targeted regression tests for persistence and empty states, plus manual QA for layout calmness and overflow edge cases
|
||
**Target Platform**: Laravel Sail local development, Filament admin and system panels in a web application deployed through Dokploy
|
||
**Project Type**: web application
|
||
**Performance Goals**: No material query regression on existing hot tables; no new obvious N+1 patterns; key list surfaces remain responsive under enterprise-sized datasets; resource-list refresh preserves state without custom client logic
|
||
**Constraints**: No new plugin dependency, no macro-first strategy, no heavy base table abstraction, no action redesign, no general search redesign, no panel-wide CSS width hacks, no authorization behavior changes, no new asset pipeline work
|
||
**Scale/Scope**: Approximately 36 production Filament table surfaces across resources, relation managers, widgets, custom pages, system pages, and picker tables, with a first-wave focus on critical resource lists plus the most overloaded relation-manager hotspot. Query-risk system tables remain part of the broader rollout and must be aligned conservatively with documented exceptions where needed.
|
||
|
||
## Constitution Check
|
||
|
||
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
|
||
|
||
| Gate | Pre-Research | Post-Design | Notes |
|
||
|------|--------------|-------------|-------|
|
||
| Inventory-first / snapshots-second | PASS | PASS | The feature changes only list presentation and interaction patterns on existing inventory-, snapshot-, and operations-related surfaces; it does not redefine storage semantics. |
|
||
| Read/write separation | PASS | PASS | No new write workflows are introduced. Existing destructive or operational actions remain table-local and unchanged in behavior. |
|
||
| Graph contract path | N/A | N/A | No Graph calls or contract registry changes are part of this feature. |
|
||
| Deterministic capabilities | PASS | PASS | Existing capability resolution and UI enforcement remain the source of truth; the rollout does not introduce raw capability strings or role checks. |
|
||
| Workspace + tenant isolation | PASS | PASS | The feature spans `/admin`, `/admin/t/{tenant}/...`, and `/system`, but keeps each surface inside its current entitlement boundary. |
|
||
| RBAC-UX authorization semantics | PASS | PASS | Non-member 404 and member-without-capability 403 semantics remain unchanged; empty-state CTAs must remain capability-gated. |
|
||
| Run observability / Ops-UX | N/A | N/A | No new long-running, queued, or remote work is introduced. Existing operation actions remain governed by current `OperationRun` patterns outside this feature’s scope. |
|
||
| Data minimization and safe logging | PASS | PASS | The rollout changes table rendering only and does not add new payload logging or persistence. |
|
||
| BADGE-001 centralized badge semantics | PASS | PASS | Existing `BadgeCatalog` / `BadgeRenderer` infrastructure stays authoritative. The standard does not create table-local badge mappings. |
|
||
| Filament Action Surface Contract | PASS | PASS | Actions remain explicit per surface. The rollout standardizes list consistency without redesigning header, row, bulk, or view actions. |
|
||
| UX-001 table obligations | PASS | PASS | The feature directly strengthens empty states, search/sort behavior, and table clarity while leaving create/edit/view layouts untouched. |
|
||
| Filament v5 / Livewire v4 compliance | PASS | PASS | The repo already runs Filament v5 on Livewire v4, which remains unchanged by this plan. |
|
||
| Panel provider registration | PASS | PASS | No panel provider changes are required; Laravel 11+ panel registration remains in `bootstrap/providers.php`. |
|
||
| Global search safety for first-wave resources | PASS | PASS | Tenant, Policy, BackupSet, BackupSchedule, and Finding resources already have View or Edit pages. ProviderConnectionResource and OperationRunResource are explicitly not globally searchable. |
|
||
| Asset strategy | PASS | PASS | No new assets are required. Existing deployment expectations, including `php artisan filament:assets`, remain unchanged. |
|
||
|
||
## Implementation Notes
|
||
|
||
- The first-wave critical resource surfaces are `TenantResource`, `PolicyResource`, `BackupSetResource`, `BackupScheduleResource`, `ProviderConnectionResource`, `FindingResource`, `OperationRunResource`, and the most overloaded relation-backed table `BackupItemsRelationManager`.
|
||
- The current codebase already uses native Filament table features such as `defaultSort()`, `toggleable()`, `emptyStateHeading()`, `emptyStateDescription()`, `emptyStateActions()`, and `paginated([...])`, but session persistence methods are effectively absent and there is no existing shared `StandardTableDefaults` helper. A narrow pagination-profile helper is acceptable as an early foundational aid because it captures only repeated page-size options and keeps search, sort, visibility, and empty-state behavior explicit in each surface.
|
||
- `app/Filament/System/Pages/Directory/Workspaces.php` is a confirmed query-risk hotspot because it computes health and recent-failure metrics per row; any new sort/search behavior there must remain conservative.
|
||
- `app/Filament/Resources/BackupSetResource/RelationManagers/BackupItemsRelationManager.php` is a confirmed density and action-heavy hotspot; the rollout must calm the default surface without disturbing its existing operational actions.
|
||
- Destructive actions are not redesigned here. Existing destructive actions must continue to use `->requiresConfirmation()` and current UI enforcement helpers.
|
||
|
||
## Project Structure
|
||
|
||
### Documentation (this feature)
|
||
|
||
```text
|
||
specs/125-table-ux-standardization/
|
||
├── plan.md
|
||
├── research.md
|
||
├── data-model.md
|
||
├── quickstart.md
|
||
├── contracts/
|
||
│ └── filament-table-state.openapi.yaml
|
||
└── tasks.md
|
||
```
|
||
|
||
### Source Code (repository root)
|
||
|
||
```text
|
||
app/
|
||
├── Filament/
|
||
│ ├── Pages/
|
||
│ │ ├── InventoryCoverage.php
|
||
│ │ └── Monitoring/Operations.php
|
||
│ ├── Resources/
|
||
│ │ ├── TenantResource.php
|
||
│ │ ├── PolicyResource.php
|
||
│ │ ├── BackupSetResource.php
|
||
│ │ ├── BackupScheduleResource.php
|
||
│ │ ├── ProviderConnectionResource.php
|
||
│ │ ├── FindingResource.php
|
||
│ │ ├── OperationRunResource.php
|
||
│ │ ├── BackupSetResource/RelationManagers/BackupItemsRelationManager.php
|
||
│ │ ├── PolicyResource/RelationManagers/VersionsRelationManager.php
|
||
│ │ └── Workspaces/WorkspaceResource.php
|
||
│ ├── System/Pages/
|
||
│ │ ├── Directory/Tenants.php
|
||
│ │ ├── Directory/Workspaces.php
|
||
│ │ ├── Ops/Runs.php
|
||
│ │ ├── Ops/Failures.php
|
||
│ │ ├── Ops/Stuck.php
|
||
│ │ └── Security/AccessLogs.php
|
||
│ └── Widgets/
|
||
│ └── Dashboard/
|
||
│ ├── RecentDriftFindings.php
|
||
│ └── RecentOperations.php
|
||
├── Livewire/
|
||
│ ├── BackupSetPolicyPickerTable.php
|
||
│ ├── EntraGroupCachePickerTable.php
|
||
│ └── SettingsCatalogSettingsTable.php
|
||
└── Support/
|
||
└── Badges/
|
||
├── BadgeCatalog.php
|
||
└── BadgeRenderer.php
|
||
|
||
tests/
|
||
├── Feature/Filament/
|
||
└── Feature/Rbac/
|
||
```
|
||
|
||
**Structure Decision**: Keep the existing single Laravel application structure and update table behavior at the current surface boundaries. If a tiny shared helper emerges as justified during implementation, it should live under `app/Support/Filament/` or an equally local support namespace and remain limited to mechanical repetition such as pagination profiles.
|
||
|
||
## Complexity Tracking
|
||
|
||
| Violation | Why Needed | Simpler Alternative Rejected Because |
|
||
|-----------|------------|-------------------------------------|
|
||
| None | Not applicable | The design stays within the constitution and the spec’s anti-abstraction constraints |
|