Saved Filter by Jefferson Gonçalves
CommunityLet your users save the state of any Filament table — applied filters, sort, search term and visible columns — under a name, and get back to it in one click. Saved filters show up as tabs above the table or in a "Views" dropdown, can be shared with the team, marked as default, managed in a slide-over and moved around as JSON. Built on jeffersongoncalves/laravel-saved-filter, which holds the model, the presets, the prune/export/import commands and the events.
Author:
Jefferson Gonçalves
Package health
Automated checks of this plugin's Composer package
15 checks
- Passed: GitHub Actions pinned to SHA
- Skipped: GitLab CI includes pinned to SHA
- Passed: Open security advisories
- Passed: Dependabot PR responsiveness — No open Dependabot PRs.
- Skipped: Renovate MR responsiveness
- Passed: Dependabot or Renovate configured
- Passed: Dependency update cooldown configured
- Passed: Provides a security policy
- Passed: Abandoned or archived — No consulted source marks the package abandoned (packagist, github).
- Passed: Commit and release recency — Active: last commit 1 days ago; last release 1 days ago.
-
Passed:
composer.lock not committed by library
—
composer.lockis absent from the released dist archive. - Passed: Dist archive is lean
-
Passed:
Current Laravel version supported
—
Package dependencies resolve together with current Laravel
13.0. -
Passed:
Current PHP version supported
—
Constraint
^8.2supports current PHP8.5. - Skipped: Current Symfony version supported
filament/
namespace. Review the source and install at your own risk. Found
malware or an unresolved security issue the author won't
address?
Report it
.
Documentation
- Features
- Compatibility
- Installation
- Configuration
- Email reports
- Presets
- Multi-tenancy
- Auditing
- Translations
- Roadmap
- Requirements
- Testing
- Changelog
- Contributing
- Security Vulnerabilities
- Credits
- License

Let your users save the state of any Filament table — applied filters, sort, search term and visible columns — under a name, and get back to it in one click. Saved filters show up as tabs above the table or in a "Views" dropdown, can be shared with the team, marked as default, managed in a slide-over and moved around as JSON.
Built on jeffersongoncalves/laravel-saved-filter, which holds the model, the presets, the prune/export/import commands and the events.
#Features
- Save current view — filters, sort, search, per-column searches, toggled columns, column order, records per page and grouping, with a name, icon and color.
- Tabs or dropdown — one tab per saved filter (plus "All"), or a list in the "Views" menu.
- Default view — opened automatically when the user lands on the table (a URL with filters still wins).
- Team views — share a filter with the other users of the tenant. Tabs show who else sees a view: Preset, Shared, or the colleague who created it.
- Keyboard shortcuts —
Ctrl/Cmd+Shift+Ssaves the current view,Ctrl/Cmd+Shift+Mopens "Manage views"; opt-inAlt+1…9andAlt+]/Alt+[to switch views. Shortcuts never fire while typing in a field. - Locked presets — created in a seeder or by users you allow; everyone sees them, nobody changes them.
- Manage views — rename, reorder, change icon/color, set the default and delete, in a slide-over.
- Update view — overwrite the active filter with the current table state.
- Modified badge + revert — once the table drifts from the active view, the "Views" button shows Modified and Revert changes restores the saved state.
- Email reports (opt-in) — "Email this view" sends the records as CSV/XLSX now; each user can schedule the report of any view they see (daily, weekly or monthly), for themselves only.
- Export / import (opt-in) — download the views as JSON and upload them in another environment (files up to 1 MB; rows with malformed fields are skipped; a view with the same name is overwritten, skipped or imported as "Name (2)", your choice).
- Shareable links — the active view is in the URL (
?view=4), so a link opens it, in the dropdown mode too. - Any table page — list pages,
ManageRelatedRecordsand custom pages withInteractsWithTable. - Safe restores — filters, columns and sort columns that no longer exist in the table are skipped, no exceptions.
- Multi-tenancy — scoped to the Filament tenant; database-per-tenant setups work as is.
- Events for auditing, 19 languages, Filament 3, 4 and 5.
#Compatibility
| Branch | Filament | Package version |
|---|---|---|
| 1.x | 3.x | ^1.0 |
| 2.x | 4.x | ^2.0 |
| 3.x | 5.x | ^3.0 |
#Installation
composer require jeffersongoncalves/filament-saved-filter:"^3.0"
php artisan vendor:publish --tag="saved-filter-migrations"
php artisan migrate
Upgrading? Run the same
vendor:publish+migrateagain after each update: new columns (likecolumn_searches) come as new migrations, and the ones you already ran are skipped.
Register the plugin in your panel provider:
use JeffersonGoncalves\Filament\SavedFilter\SavedFilterPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
SavedFilterPlugin::make(),
]);
}
Add the trait to the list page of every resource that should have saved filters:
use Filament\Resources\Pages\ListRecords;
use JeffersonGoncalves\Filament\SavedFilter\Concerns\HasSavedFilters;
class ListOrders extends ListRecords
{
use HasSavedFilters;
protected static string $resource = OrderResource::class;
}
A Views button appears in the table header. Once the user saves a view, the tabs show up.
#Configuration
SavedFilterPlugin::make()
->dropdown() // list the views in the "Views" menu instead of tabs
->canShare(fn () => auth()->user()->can('share-views')) // who may share views with the team (default: everyone)
->canManagePresets(fn () => auth()->user()->isAdmin()) // who may create/edit locked presets (default: nobody)
->scopedToTenant(false) // ignore the Filament tenant (default: scoped)
->exportable() // show "Export views" (default: off)
->importable() // show "Import views" (default: off)
->emailReports() // "Email this view" + scheduled email reports (default: off)
->keyBindings(save: ['mod+shift+s'], manage: null) // change or disable (null) the action shortcuts
->tabShortcuts(), // Alt+1…9 / Alt+] / Alt+[ to switch views (default: off)
With tabShortcuts(), Alt+1 opens "All", Alt+2 the first saved view and so on, Alt+] / Alt+[ cycle through them. Physical keys are used, so it works on any keyboard layout and with the macOS Option key.
On tables with ->reorderableColumns() (Filament 4 and 5), a view also keeps the column order the user dragged in the column manager; columns added to the table later go last, removed ones are skipped. Until the user reorders, a view follows the table's own order.
Records per page and grouping are only restored when the table still offers them (->paginationPageOptions(), ->groups()); otherwise the table's defaults are used.
#Your own tabs
If the page already has tabs, the page's getTabs() wins over the trait's. Combine both by spreading the saved filter tabs:
public function getTabs(): array
{
return [
'active' => Tab::make()->modifyQueryUsing(fn ($query) => $query->where('active', true)),
...$this->getSavedFilterTabs(),
];
}
#Your own table()
The trait adds its actions in table(). If your list page overrides table(), call the hook yourself:
public function table(Table $table): Table
{
return $this->configureSavedFilters(parent::table($table)->striped());
}
#Other table pages
The trait works on ManageRelatedRecords pages (tabs included) and on any page with InteractsWithTable. Such pages define their own table(), so call configureSavedFilters() there:
class SalesReport extends Page implements HasTable
{
use HasSavedFilters;
use InteractsWithTable;
public function table(Table $table): Table
{
return $this->configureSavedFilters($table->query(Order::query())->columns([...])->filters([...]));
}
}
Pages without tabs list the views in the "Views" menu. Email reports stay on list pages: they rebuild the page outside a request, which needs nothing but its class.
#Table key
Filters are stored per resource class on list pages and per page class anywhere else. Override getSavedFilterResource() to share them between pages or to key them differently:
public function getSavedFilterResource(): string
{
return 'orders';
}
#Email reports
Turn them on with ->emailReports() and tell each list page which Filament exporter builds the file. Pages without one don't show the actions.
use App\Filament\Exports\OrderExporter;
public function getSavedFilterExporter(): ?string
{
return OrderExporter::class;
}
- Email this view sends the current table state (saved or not) to the user, as CSV or XLSX.
- Email report (in the "Views" menu, opens on the active view or lets you pick one): each user turns a report on or off for themselves, on their own views, shared ones and presets, and picks daily, weekly or monthly, the day, the time, the timezone (their own
timezoneattribute by default, else the app's) and the format. The form tells what is scheduled for the picked view. It goes only to that user. - My email reports lists the user's reports on every table of the tenant, to turn them on or off or remove them in one place.
- The email has an Open the view button (
?tab=saved-4with tabs,?view=4with the dropdown). - The file uses the exporter's columns enabled by default and its formatting, on the records of the view as that user sees them: the report is built with their login and tenant, and nothing is sent when they lost access to the resource or the tenant, or when the view is no longer shared with them.
- "Don't send when there are no records" skips the occurrences where the view is empty.
- Text that a spreadsheet would run as a formula (starting with
=,+,-or@) is prefixed with'. - The users need an
emailattribute and the app needs a working mailer and queue.
Scheduling and delivery come from laravel-saved-filter: saved-filter:send-reports is registered on the scheduler every 15 minutes, so the server only needs php artisan schedule:run in cron. Files over reports_max_attachment_size (10 MB) aren't attached: install laravel-report-url to send them as temporary download links.
#Presets
Presets are saved filters without owner: every user of the tenant sees them and they are locked. Create them in a seeder:
use JeffersonGoncalves\SavedFilter\Models\SavedFilter;
SavedFilter::query()->updateOrCreate(
['resource' => OrderResource::class, 'name' => 'Waiting for payment', 'owner_id' => null, 'tenant_id' => null],
['filters' => ['status' => ['value' => 'pending']], 'icon' => 'heroicon-o-clock', 'is_public' => true, 'is_locked' => true],
);
…or let users allowed by canManagePresets() tick Save as a locked preset for everyone when saving. Provision them between environments with php artisan saved-filter:export / saved-filter:import (see laravel-saved-filter).
#Multi-tenancy
With Filament tenancy the views are stored with the current tenant's key and listed per tenant. For database-per-tenant packages (stancl/tenancy) run the migration in the tenant databases; tenant_id stays null and the connection keeps each tenant apart.
#Auditing
SavedFilterCreated, SavedFilterDeleted and SavedFilterApplied (with the user) are dispatched from JeffersonGoncalves\SavedFilter\Events — listen to them to feed spatie/laravel-activitylog or any audit log.
#Translations
The UI ships in 19 languages: ar, az, de, en, es, fa, fr, hi, it, ja, nl, pl, pt, pt_BR, ru, tr, uk, uz and zh_CN. Publish them to change any string:
php artisan vendor:publish --tag=filament-saved-filter-translations
Missing your language? Copy resources/lang/en/saved-filter.php and open a pull request.
#Roadmap
- Saved filters inside relation managers on edit/view pages.
- Per-view badge with the record count.
- One-click unsubscribe link in the report email.
#Requirements
- PHP 8.2 or higher
- Filament 5.x
#Testing
composer test
#Changelog
Please see CHANGELOG for more information on what has changed recently.
#Contributing
Please see CONTRIBUTING for details.
#Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
#Credits
#License
The MIT License (MIT). Please see License File for more information.
The author
I'm a Full Stack PHP Developer from Assis, SP, Brazil with over 18 years of hands-on experience building robust platforms, managing server infrastructures, and crafting scalable solutions for businesses of all sizes.
My passion lives in the open source world — I actively maintain 20+ Filament plugins and a growing collection of Laravel packages used by thousands of developers worldwide. I believe great software should be accessible to everyone.
From the same author
Scanner Guard
Filament UI for jeffersongoncalves/laravel-scanner-guard: list, filter and unban vulnerability-scanner IPs directly from your admin panel. This plugin ships a read-only Resource over the scanner_guard_bans table, an active/expired filter, and unban / bulk unban actions.
Author:
Jefferson Gonçalves
Short URL
A complete Filament v5 admin layer for jeffersongoncalves/laravel-short-url — the headless core package that owns the models, migrations, redirect pipeline, tracking and every business rule. This package duplicates none of that: it's the presentation layer (Resources, Pages and Filament components) built on top of the core's Facade and contracts.
Author:
Jefferson Gonçalves
TeamKit v5
Teamkit is a robust starter kit, designed to accelerate the development of modern web applications with a ready-to-use multi-panel structure.
Author:
Jefferson Gonçalves
Ban
Ban and unban any Eloquent model directly from your Filament panel. This package wraps cybercog/laravel-ban and ships ready-to-use actions, bulk actions, an icon column and a status filter for your Filament resources and tables. Inspired by cybercog/laravel-nova-ban.
Author:
Jefferson Gonçalves
Featured Plugins
A selection of plugins curated by the Filament team
Sharp Theme
A theme that gives panels a precise, technical look with square corners, strong borders, and clear contrast.
Filament
Spotlight Pro
Browse your Filament Panel with ease. Filament Spotlight Pro adds a Spotlight like Command Palette to your Filament Panel.
Dennis Koch
Soft Theme
A theme that gives panels a warm, approachable look with rounded shapes, gentle colors, and serif headings.
Filament