degecko/nova-filters-summary
Adds a compact summary of currently active Laravel Nova filters to resource index screens, so users can quickly see which filters are applied and clear them. A lightweight usability enhancement for Nova dashboards.
Architecture fit. This is a presentation-layer Nova card, not domain logic or infrastructure. It draws its value entirely from a condition that must already be true: the organization runs Laravel Nova as its admin surface, and its operators routinely stack filters on resource indexes or lenses. If Nova is licensed and in active use, the card slots in with no data model, no migration, and no service boundary; it reads $request->query('filter') and renders state. If Nova is not in the stack, the package has zero applicability and the evaluation ends here. A TPM should frame it as a tactical admin UX enhancement — a "make hidden state visible" fix — rather than a platform commitment. The 20-star, zero-dependent profile means there is no ecosystem validation to lean on; the adoption decision rests on a short, well-scoped pilot, not on a vendor relationship.
Integration feasibility. Implementation cost is trivial: one composer require, one registration line in NovaServiceProvider::cards() or in a resource/lens cards() method, and no configuration unless styling or localization is required. The real effort is validation, not build. Three feasibility checks dominate the schedule: (1) Nova major version and Vue runtime compatibility (Nova 4 = Vue 3, Nova 3 = Vue 2) plus clean publishing of the built dist/js/card.js; (2) whether the card refreshes on Nova's partial-page filter change or renders stale server-computed meta; (3) correct rendering across the filter shapes actually in use — date ranges, multi-selects, booleans, and any custom filters. A TPM should size this as a two-to-three-day spike in staging on one high-filter resource and one lens, not as a sprint.
Technical risk. The dominant risks are freshness and bus factor. Freshness: Nova applies filters via a partial page visit, so a server-computed payload may disagree with the table until a hard navigation — a summary that contradicts the data is worse than no summary, and this is the single go/no-go risk. Bus factor: single maintainer, zero dependents, last release January 2025 — treat the ~200 lines as code the team may own and budget for vendoring into nova-components/. Secondary risks are key drift (filter uriKey()s are derived from class names and renaming breaks the summary), unescaped values rendered into the admin UI, and asset-serving breakage after upgrades. None of these are exotic; all are cheap to detect in a spike and expensive to discover in production.
Key questions. Which Nova major are we on, and is the package's laravel/nova constraint satisfied? Does the card go stale on filter change, and if so do we accept a client-side patch or scope the card to lenses only? Which filter types are present on the pilot screens, and do their name()/option labels produce readable chips rather than raw values? Are filter uriKey()s explicit or class-derived? Where will the card be registered — globally, per-resource, or via a FilterHeavyResource base class with a canSee guard? Who owns the vendored fork if upstream goes quiet?
Stack fit. The package assumes Laravel + Nova + Composer, with JS assets shipped prebuilt so no npm install is needed at adoption time. That is a genuinely low-friction fit: no service boundary is crossed, no queue, no credentials, no external API. The only meaningful coupling is to the Nova/Vue runtime, which is versioned and known. A TPM can honestly describe this as a UI dependency, not an infrastructure one — it will not appear on an architecture diagram.
Migration path. There is no migration. Nothing is persisted; removal is a deleted registration line with no data cleanup and no rollback plan required. That makes the reversibility story unusually clean for a TPM to defend: worst case, the card is deleted and users return to scanning dropdowns. The decision that does carry forward is where to register it — global cards() puts it on dashboards where "active filters" is often meaningless and costs vertical space; scoped registration on an abstract base resource, or a canSee guard keyed to a non-empty filter query parameter, keeps the surface honest.
Compatibility. Two axes must be pinned: the Nova/Vue major and the PHP/Laravel constraint. Pin the package version in composer.json, run Composer audit, and republish assets after any composer update — the classic "it worked yesterday" failure is stale published assets, not a code regression. Chip copy quality is a compatibility concern too: the card renders whatever the filter classes expose, so filters returning raw values without labels yield "Status: 2," which is a filter-naming debt problem rather than a package problem. Set uriKey() explicitly on any filter that surfaces here so class renames don't silently break the summary.
Sequencing. Stage 1 — spike (2–3 days, staging only): verify rendering on one multi-filter resource (the canonical Order case: status + date range + customer relation) and on one lens; exercise every filter shape in use; confirm or refute staleness. Stage 2 — decision gate: if stale and the team won't fork the Vue component, stop or scope to lenses. Stage 3 — pilot: two or three high-traffic ops/support screens, per-resource registration with a canSee guard, plus a lightweight clear-all affordance since the card is read-only. Stage 4 — instrument and review: filter-related tickets, filter resets per session, mistaken exports, time-to-insight. Stage 5 — standardize, vendor the card into nova-components/ with desired customizations (chip colors, collapse-after-three), or walk away.
Maintenance. Low but non-zero. The package is one Card class plus one Vue component; once vendored, the maintenance burden is "keep the Vue component aligned with the Nova major," which the team will already be doing for any custom Nova tooling. Pin the version, watch composer.json and the release cadence (last release January 2025), and treat any Nova upgrade as a trigger to re-verify the card. If the card is not vendored and upstream stalls, the team inherits an unmaintained dependency on an admin surface — acceptable for a read-only card, not acceptable as a pattern.
Support. No vendor support, no SLA, no commercial backing. Support load falls internally and is bounded by the spike's coverage: filters in use are covered or the card is not rolled out. Two predictable support tickets should be documented in advance — "there's an empty box on the dashboard" (global registration, or assets not published) and "the summary is wrong after filtering" (staleness). Both have known answers and both are cheap to preempt with a short internal note and a canSee guard.
Scaling. Effectively irrelevant at the application level — the card is stateless, per-request, and does no queries beyond what Nova already did to compute the filter state. The scaling concern is organizational: the card's value grows with filter complexity (three or more stacked filters, lens-based segmentation) and shrinks to noise on single-filter indexes. Roll it out where indexes are filter-heavy and skip it where they aren't; a blanket rollout on every resource is how a good pilot becomes vertical-space clutter.
Failure modes. Ranked, with mitigations a TPM can carry into a review: (1) staleness — summary disagrees with the table after a partial-page filter change; mitigate by forking the component to read the query string client-side, or scope to lenses where switching is a full navigation; (2) blank card with no PHP exception — Vue major mismatch or unpublished assets; mitigate by matching the Nova constraint and republishing after updates; (3) garbled values — Date: Array or [object Object] from non-string filter shapes; mitigate by exercising every filter type in the spike; (4) key drift — renamed filter classes change uriKey() and the summary silently misreads; mitigate with explicit uriKey(); (5) escaping — verify v-text/interpolation rather than v-html before shipping user-influenced strings into the admin UI; (6) abandonment — upstream goes quiet; mitigate by vendoring.
Ramp-up. Hours, not weeks, for anyone who knows Nova. The learning curve is almost entirely Nova's card API rather than this package: register a card, publish views, understand withMeta(). Documentation is a README plus ~200 lines of source, which for a competent Nova engineer is a single afternoon. The realistic ramp-up risk is not the package — it is that the team has no prior experience customizing Nova cards, in which case the first custom card (chip colors, clear-all, collapse-after-three) is the real effort and the package is just the starting template. Plan the pilot so that learning is captured once and reused across the other screens rather than repeated per resource.
How can I help you explore Laravel packages today?