TenantAtlas/specs/125-table-ux-standardization/plan.md
ahmido a4f5c4f122 Spec 125: standardize Filament table UX (#152)
## 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
2026-03-08 22:54:56 +00:00

9.4 KiB
Raw Permalink Blame History

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 products 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 features 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)

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)

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 specs anti-abstraction constraints