## 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
66 lines
7.1 KiB
Markdown
66 lines
7.1 KiB
Markdown
# Research: Filament Table UX Standardization & List Consistency
|
||
|
||
## Decision 1: Use native Filament table configuration as the primary implementation path
|
||
|
||
- Decision: Standardize behavior directly in each table’s existing `table()` definition and page-level empty-state hooks, using native Filament methods as the default approach.
|
||
- Rationale: The repo already defines table behavior locally across resources, relation managers, widgets, system pages, and Livewire picker tables. Keeping the standard inline preserves clarity, aligns with the spec’s convention-first goal, and avoids introducing a second configuration language on top of Filament.
|
||
- Alternatives considered:
|
||
- Build a generic table DSL with primary/context/detail declarations: rejected because it would hide normal Filament behavior and create a parallel framework to maintain.
|
||
- Make macros the default rollout path: rejected because the current inconsistencies are mostly judgment and information-architecture issues, not missing framework capability.
|
||
|
||
## Decision 2: Keep shared support intentionally tiny and mechanical
|
||
|
||
- Decision: Do not introduce a large shared base class or trait hierarchy. Only allow tiny shared support where duplication is purely mechanical, with pagination-profile helpers as the most likely candidate.
|
||
- Rationale: The workspace currently has no shared `StandardTableDefaults` or equivalent helper. Introducing a broad helper layer at the same time as a repo-wide cleanup would increase migration risk and make reviews harder.
|
||
- Alternatives considered:
|
||
- Add a `StandardTableDefaults` trait and force every table through it: rejected because it would centralize too many domain-specific decisions and make exceptions harder to reason about.
|
||
- Keep every pagination and persistence setting fully duplicated forever: rejected because a very small helper for page-size arrays may be justified once the first rollout wave proves the pattern is stable.
|
||
|
||
## Decision 3: Treat resource-list persistence as mandatory and relation-manager persistence as optional
|
||
|
||
- Decision: Enable session persistence for search, sort, and filters on resource list tables in the first rollout wave. Leave relation managers, widgets, picker tables, and custom pages on an opt-in basis where the behavior fits naturally.
|
||
- Rationale: The audit gap is strongest on resource lists, and Filament-native session persistence maps directly to that need. Extending persistence to every table surface immediately would expand scope and create more state-management edge cases than the spec requires.
|
||
- Alternatives considered:
|
||
- Add persistence to every table surface immediately: rejected because it increases rollout complexity without matching the strongest user pain first.
|
||
- Skip persistence and rely only on query-string state: rejected because the spec explicitly targets keeping list context across refreshes.
|
||
|
||
## Decision 4: Use a documented Primary / Context / Detail model rather than code-level column metadata
|
||
|
||
- Decision: Express Primary, Context, and Detail as a repo review convention backed by examples, not as a new code abstraction.
|
||
- Rationale: The missing consistency is mostly a design-review problem. A documented tier model gives reviewers and implementers a common language while letting each table remain explicit and readable.
|
||
- Alternatives considered:
|
||
- Add a `primaryColumn()` / `detailColumn()` API wrapper: rejected because it would obscure normal Filament column configuration and encourage over-abstraction.
|
||
- Leave visibility choices fully ad hoc: rejected because that is the exact drift pattern the spec is meant to stop.
|
||
|
||
## Decision 5: Standardize timestamps, nulls, and IDs using native column methods
|
||
|
||
- Decision: Use native Filament column behavior for relative timestamps, placeholders, toggle-hidden detail fields, copyable identifiers, truncation, and tooltips instead of custom renderers wherever possible.
|
||
- Rationale: The repo already uses `since()`, `dateTime()`, `toggleable()`, `copyable()`, and empty-state APIs in several places. Extending those patterns is lower risk than inventing custom rendering helpers.
|
||
- Alternatives considered:
|
||
- Introduce custom Blade column views for standard timestamp and ID rendering: rejected because it would be more fragile and harder to apply consistently across many surfaces.
|
||
- Leave timestamp and null formatting untouched during rollout: rejected because inconsistent rendering is one of the audited usability defects.
|
||
|
||
## Decision 6: Preserve existing badge, action, and RBAC architecture
|
||
|
||
- Decision: Do not redesign actions, badge mappings, or authorization mechanics as part of this feature. Keep actions and empty-state CTAs table-local, preserve centralized badge rendering through `BadgeCatalog` and `BadgeRenderer`, and maintain existing UI enforcement helpers.
|
||
- Rationale: The repo already has centralized badge infrastructure and explicit action-level UI enforcement patterns. The spec explicitly excludes action redesign, and mixing that work into the rollout would create unnecessary risk.
|
||
- Alternatives considered:
|
||
- Standardize row actions and header actions in the same feature: rejected because actions are comparatively consistent and would create avoidable scope creep.
|
||
- Rebuild badges as part of a broader “table facelift”: rejected because BADGE-001 requires centralized semantics and the current badge layer already exists.
|
||
|
||
## Decision 7: Use performance exceptions deliberately and document them per table
|
||
|
||
- Decision: Any new sort or search behavior on relation-backed or computed columns requires explicit query review, and some tables may keep documented exceptions instead of forcing full compliance.
|
||
- Rationale: Direct code inspection already shows query-sensitive surfaces. `app/Filament/System/Pages/Directory/Workspaces.php` computes health and recent failures per row, and `app/Filament/Resources/BackupSetResource/RelationManagers/BackupItemsRelationManager.php` already mixes operational actions with a dense relation-backed list. The standard must not worsen those hotspots.
|
||
- Alternatives considered:
|
||
- Force every meaningful-looking column to become sortable or searchable: rejected because that would create hidden N+1 or aggregate query regressions.
|
||
- Exclude risk tables from the rollout entirely: rejected because the spec requires broad alignment, but exceptions can be documented where needed.
|
||
|
||
## Decision 8: Roll out by table class and business criticality, not alphabetically
|
||
|
||
- Decision: Implement the standard in phases: documentation and baseline, first-wave critical resource tables, then remaining resources and relation managers, then widgets, custom pages, and picker tables, followed by performance hardening.
|
||
- Rationale: The current table surface spans roughly three dozen screens with uneven complexity. A phased rollout lets the project prove the standard on high-value tables before applying it repo-wide.
|
||
- Alternatives considered:
|
||
- Update every table in one large pass: rejected because it would be hard to review and too risky for query behavior.
|
||
- Limit the effort to a small set of flagship resources: rejected because the spec is explicitly repo-wide and aims to stop future drift.
|