optimistdigital/nova-detached-filters
A Laravel Nova package that lets you detach filters from the default filter dropdown and show them separately, keeping applied filters persistent across page loads and navigation. Useful for building shareable, always-visible filtered views of Nova resources without re-applying filters each time.
Architecture fit. This is a thin presentation-layer decorator over Laravel Nova's existing filter contract, not a framework or a subsystem. It adds exactly one concept — DetachedFilter::make(new OrderStatus) — that wraps a filter class you already own and renders it outside the dropdown. Because it's presentation-only, the native semantics of apply() and canSee() are untouched: authorization and query behavior are identical whether a filter sits in the dropdown or on a toolbar. Architecturally there is nothing to integrate with — no migrations, no config to publish, no asset build step, provider auto-discovered, assets precompiled and registered through Nova's asset API. Blast radius is confined to the Nova admin panel.
Integration feasibility. High, with a short checklist. One composer require, one wrapper per filter, and detachment is opt-in per filter, not per resource — mixed arrays are the idiomatic shape, so adoption is incremental and reversible. Two things must be verified before any code is written: the exact FQCN (Composer name is optimistdigital, repo is outl1ne, wrapper class historically DetachedFilter — read vendor/optimistdigital/nova-detached-filters/src/) and which Nova major the installed release explicitly targets. Install cost is quoted at roughly an afternoon; a credible pilot on two or three high-traffic resources fits in a sprint.
Technical risk. Low in the data/security dimension, moderate in the lifecycle dimension. There is no data risk, no auth surface, no migration — the worst realistic failure is a UI that looks broken, not a query that silently corrupts results. The lifecycle risk is real and structural: a single-maintainer lineage, 63 stars, 0 dependents, meaning no crowd to surface breakage before you do. The release history confirms a reactive maintenance model — 3.0.1 exists solely as a Nova 5 type-compatibility fix. That argues for an exact version pin (3.0.1, not ^3.0) and for gating any Nova major upgrade on a manual pass over every resource using detached filters. Secondary risk concentrates in your custom Vue filter components, which may assume they live inside Nova's dropdown container (absolute positioning, dropdown-relative widths, portals) and will render broken when detached.
Key questions.
default().Stack fit. Laravel + Nova only; outside Nova the package is meaningless. It assumes you already have Nova filter classes defined — which most mature Nova installs do — and requires nothing else. Do not carry over a config/ publish step or asset build step from another Outl1ne plugin; check the vendor directory before adding runbook steps that don't exist.
Migration path. Greenfield add with no data or state migration. Crucially, adoption is per-filter and fully reversible: unwrapping a filter returns it to the dropdown with no residue. That reversibility is the strongest argument available to a TPM — it converts this from "a dependency we're adopting" into "a timeboxed experiment we can back out of in one commit."
Compatibility. Pin the exact version. Confirm the release targets your Nova major (3.0.1 is explicitly a Nova 5 fix — if you're on Nova 4, verify the installed release rather than assuming). Verify the FQCN from vendor source, not from documentation or a blog post; a wrong use statement is the most common first-five-minutes failure. Validate against your most complex custom filter component during the spike, not your simplest. If you use lenses, verify each detached filter against your primary lens — a lens that already constrains the same column will make a detached filter look like it "doesn't work."
Sequencing.
src/, one wrapped filter rendering correctly on a single resource.->get('/nova/resources/orders')->assertOk()->assertSee(...) on each resource with detached filters. It won't catch layout regressions, but it catches the Nova-upgrade class of failure where the component fails to mount.Maintenance. Near-zero day-to-day; the recurring cost is Nova-major validation. Pin the exact version, and include Nova's cache and asset-clear commands in the runbook after any deploy that touches vendor/. The package is deliberately thin — small enough to read in one sitting — which matters because the extension point is the fork, not configuration. If you need grouped sidebar filters, persisted selections, or dashboard-specific placement, the realistic options are an MIT fork or an in-house Nova component (≈1 day per resource). Name that fallback and its cost before adoption, not after.
Support. The predictable support event is a transient spike in "where did my filter go" questions right after rollout — this is a relocation of familiar UI, and it will be reported as a bug at least once. Two prevention measures: document the convention and apply it uniformly across resources, and set the persistence expectation early. Two specific defects to engineer against: a filter wrapped and returned raw (renders twice, applies its constraint twice — enforce in code review as the most likely PR defect), and a "reset/clear filters" affordance that clears only the visible detached filters while leaving a hidden dropdown filter applied. The latter is genuinely confusing for operators because the results look wrong with no visible cause.
Scaling. Effort scales linearly per resource; risk does not scale with breadth so much as concentrate at the layout boundary. Detaching six filters produces a wall of controls that pushes the table below the fold on a 13" laptop — where most back-office work actually happens. Narrow viewports are the visible degradation point: verify at ~1280px and ~1024px during the spike, and consider detaching fewer filters (or none) on tablet and phone rather than assuming the toolbar inherits Nova's responsiveness. Order filters by visual weight — narrow selects and toggles first, wide date ranges and multi-selects last.
Failure modes and the debugging order. (1) Does the filter appear correctly in the dropdown when unwrapped? (2) Is it returned exactly once from filters()? (3) Does the FQCN resolve from actual vendor source? (4) Do the package's script/style assets load — check the network tab? (5) Is the Nova major supported by the pinned version? Working that order prevents reading package source when the answer is a cache clear. The classic "worked in staging" failure is asset staleness after a deploy touching vendor/.
Ramp-up. A Laravel/Nova developer learns the API in half a day; the install itself is an afternoon. The organizational ramp-up is the convention decision and the pilot observation window — that's where the time actually goes. Budget the pilot as a sprint-scoped polish item, not a roadmap commitment: this is internal-tooling efficiency work that removes repeated clicks for ops, support, and finance, and it is measurable in reduced filter-related tickets. The meta-value for a TPM is that it forces two overdue conversations into the open: how many small Nova plugins we carry, and who owns upgrade risk for each.
How can I help you explore Laravel packages today?