## Summary - add a shared diff presentation layer under `app/Support/Diff` with deterministic row classification, summary derivation, and value stringification - centralize diff-state badge semantics through `BadgeCatalog` with a dedicated `DiffRowStatusBadge` - add reusable Filament diff partials, focused Pest coverage, and the full SpecKit artifact set for spec 141 ## Testing - `vendor/bin/sail artisan test --compact tests/Unit/Support/Diff/DiffRowStatusTest.php tests/Unit/Support/Diff/DiffRowTest.php tests/Unit/Support/Diff/DiffPresenterTest.php tests/Unit/Support/Diff/ValueStringifierTest.php tests/Unit/Badges/DiffRowStatusBadgeTest.php tests/Feature/Support/Diff/SharedDiffSummaryPartialTest.php tests/Feature/Support/Diff/SharedDiffRowPartialTest.php tests/Feature/Support/Diff/SharedInlineListDiffPartialTest.php` - `vendor/bin/sail bin pint --dirty --format agent` ## Filament / Livewire Contract - Livewire v4.0+ compliance: unchanged and respected; this feature adds presentation support only within the existing Filament v5 / Livewire v4 stack - Provider registration: unchanged; no panel/provider changes were required, so `bootstrap/providers.php` remains the correct registration location - Global search: unchanged; no Resource or global-search behavior was added or modified - Destructive actions: none introduced in this feature - Asset strategy: no new registered Filament assets; shared Blade partials rely on the existing asset pipeline and standard deploy step for `php artisan filament:assets` when assets change generally - Testing coverage: presenter, DTOs, stringifier, badge semantics, summary partial, row partial, and inline-list partial are covered by focused Pest unit and feature tests ## Notes - Spec checklist status is complete for `specs/141-shared-diff-presentation-foundation/checklists/requirements.md` - This PR preserves specialized diff renderers and documents incremental adoption rather than forcing migration in the same change Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #170
2.6 KiB
2.6 KiB
Quickstart: Shared Diff Presentation Foundation
Purpose
Use this foundation when a screen already has simple structured compare data and needs consistent change-state semantics, summary badges, row rendering, inline list add/remove display, and shared value formatting.
Do not use it to replace specialized normalized diff, script diff, or other advanced compare experiences that need domain-specific layout or token/line-level logic.
Prerequisites
- The consuming surface already has authorized baseline/current compare data.
- The values can be represented as simple keyed fields or simple lists.
- The consumer does not need a new route, new persistence model, or new compare engine.
Basic adoption flow
- Build or adapt a simple compare input:
- Baseline associative values
- Current associative values
- Optional changed keys
- Optional label map
- Pass that input into
DiffPresenter. - Render the returned summary with the shared summary partial.
- Loop over the returned rows and render each row through the shared row partial.
- If a row is list-like, let the row partial delegate to the inline list diff partial.
Example adoption pattern
Presenter usage
$presentation = app(DiffPresenter::class)->present(
baseline: $baseline,
current: $current,
changedKeys: $changedKeys,
labels: $labels,
);
Blade usage
@include('filament.partials.diff.summary-badges', ['summary' => $presentation->summary])
@foreach ($presentation->rows as $row)
@include('filament.partials.diff.row', [
'row' => $row,
'compact' => false,
'dimUnchanged' => true,
])
@endforeach
Standalone stringifier usage
If a specialized view should not use DiffPresenter, it can still reuse ValueStringifier to standardize how nulls, booleans, scalars, simple lists, and compact structured values appear.
When not to use the foundation
- The screen requires line-level or token-level script diff behavior.
- The screen needs heavily specialized comparison layout that would become less clear if flattened into generic rows.
- The screen would need new domain comparison rules rather than presentation reuse.
Testing expectations
- Add Pest unit tests for any new presenter or stringifier behavior.
- Add view-level tests for shared partial usage and state-specific rendering.
- If a consumer adds a new diff-state badge domain mapping, cover it with badge tests.
- Keep
docs/ui/shared-diff-presentation-foundation.mdaligned with the same presenter and partial names when adoption guidance changes.