kisame76/filament-db-table-state
Composer 安装命令:
composer require kisame76/filament-db-table-state
包简介
Persist Filament table state (filters, sort, search, column order & visibility) per user in the database, across devices and sessions.
README 文档
README
Filament DB Table State
Persist Filament table state — filters, sort, search, column order and column visibility — per user in the database, instead of only the session.
Filament can already persist table state with ->persistFiltersInSession(), ->persistSortInSession(), ->persistColumnsInSession() and friends. But the session is per-browser and short-lived: clear cookies, switch device or let the session expire and the state is gone.
This package mirrors that same state into a database row keyed by the user, so a user's filters and column layout survive new sessions and follow them across devices. By default it upgrades every table you already flag with ->persist*InSession(); flip one switch to cover every table.
How it works
Filament writes table state to the session (when the ->persist*InSession() flags are on). This package hooks into Livewire globally and:
- Seeds the session from the user's saved DB row on component boot — before Filament's
bootedInteractsWithTable()reads it. - Snapshots the session back to the DB at the end of the request — after Filament has written the latest state.
It reuses Filament's own session keys (getTableFiltersSessionKey(), getTableSortSessionKey(), getTableColumnsSessionKey(), …), so it stays compatible with how Filament stores state. Each table gets its own small row per user — keyed by the table's Livewire component class (e.g. App\Filament\Resources\Users\Pages\ListUsers), so rows are easy to identify in the database — holding just that table's state.
Requirements
- PHP 8.2+
- Filament v4 or v5
- Livewire v3.5+ / v4
Installation
composer require kisame76/filament-db-table-state
Publish and run the migration (creates the table_states table):
php artisan vendor:publish --tag=filament-db-table-state-migrations php artisan migrate
The migration adds a user_id foreign key with a cascade delete to your users
table. Using UUID/ULID keys or a custom users table? Edit the published migration
before running migrate — it has inline comments showing what to change.
That's it. Any table that uses Filament's session persistence (->persistFiltersInSession(), ->persistSortInSession(), ->persistColumnsInSession(), …) now also persists to the database — surviving new sessions and following the user across devices. To enable it for every table automatically, set auto_enable_persistence => true (see below).
Configuration (optional)
php artisan vendor:publish --tag=filament-db-table-state-config
return [ // Master switch. When false the package does nothing. 'enabled' => env('DB_TABLE_STATE_ENABLED', true), // Default false = only tables you've flagged with ->persist*InSession() // are mirrored. Set true to flip those flags on for EVERY table. 'auto_enable_persistence' => false, // Storage. user_column is a string so it supports integer and UUID keys. 'table' => 'table_states', 'user_column' => 'user_id', // Auth guard used to resolve the current user (null = default guard). 'guard' => null, ];
Custom user resolution
Need a custom guard or extra scoping? Set a resolver from any service provider's boot():
use Kisame76\FilamentDbTableState\Support\TableStatePersister; TableStatePersister::resolveUserIdUsing(fn () => auth('admin')->id());
What persists, and when
The package mirrors whatever Filament writes to the session — it never touches the URL:
- Column layout (visibility + order): Filament persists this to the session by default, so it is always mirrored to the database, on every table, while the package is enabled.
- Filters, sort, search: Filament keeps these in the URL query string by default (not the session), so they are mirrored only once you opt the table in (or enable every table — see below).
Default: opt in for filters, sort & search
Out of the box (auto_enable_persistence => false), turn on Filament's native
session persistence for the tables you care about:
public function table(Table $table): Table { return $table ->persistFiltersInSession() ->persistSortInSession(); // column layout already persists by default }
Those tables now persist filters and sort to the database as well — surviving new sessions and following the user across devices.
Filament's session-persistence methods
These are the native Filament Table methods this package mirrors to the
database. The defaults are Filament's own — note that only the column layout is
persisted out of the box:
| Method | Persists | Default |
|---|---|---|
->persistFiltersInSession() |
Filters | off |
->persistSortInSession() |
Sort | off |
->persistSearchInSession() |
Table search | off |
->persistColumnSearchesInSession() |
Per-column searches | off |
->persistColumnsInSession() |
Column visibility + order | on |
Enable all of them on a single table:
public function table(Table $table): Table { return $table ->persistFiltersInSession() ->persistSortInSession() ->persistSearchInSession() ->persistColumnSearchesInSession() ->persistColumnsInSession(); }
Every method also accepts false to turn it off — handy when
auto_enable_persistence is on and you want to exclude one table, e.g.
->persistColumnsInSession(false).
Persist every table automatically
Set auto_enable_persistence => true to flip Filament's session persistence on
for every table via Table::configureUsing() — no per-table changes needed.
// config/db-table-state.php 'auto_enable_persistence' => true,
When this is on, opt a single table back out by chaining the native flags in its
table() method — your call wins:
public function table(Table $table): Table { return $table ->persistFiltersInSession(false) ->persistColumnsInSession(false); }
Custom global combinations
auto_enable_persistence => true is a shortcut that turns everything on for
every table. For any other global combination — say, persist filters on every
table but never persist columns — leave auto_enable_persistence => false and
configure Filament yourself in your app's AppServiceProvider::boot():
use Filament\Tables\Table; public function boot(): void { Table::configureUsing(function (Table $table): void { $table ->persistFiltersInSession() // filters on every table → mirrored to the DB ->persistColumnsInSession(false); // never persist the column layout }); }
The package's hook mirrors whatever ends up in the session, so that is all you
need: filters now persist to the database everywhere, columns nowhere. Keep
auto_enable_persistence => false so the package doesn't flip its own defaults
on top of yours.
Turning it off
Set enabled => false to switch the whole package off — no hook, no mirroring.
Notes & caveats
-
Each table has its own small row per user (keyed by user and the table's Livewire component class), so reads and writes only ever touch that one table's state.
-
On panels using tenancy, Filament hashes the filters session key per tenant — those keys land in the same per-table row and are restored per tenant; nothing extra to configure.
-
Defaults of newly added filters don't reach users with saved state. Filament only applies filter defaults (
->default()) when no stored filter state exists for the table:bootedInteractsWithTable()fills the filter form straight from the stored array, missing filters become inactive, and that inactive value is immediately persisted back. This is core Filament session behavior — the DB mirror just makes it survive session expiry. After deploying a new filter that has a default, clear the affected rows:DELETE FROM table_states WHERE table_key = 'App\Filament\Resources\Users\Pages\ListUsers';
Note that the default still only applies once the user gets a fresh session (logout/login or session expiry): a live session still holds the old filter state, Filament keeps reading it from there, and the next request mirrors it right back into the database.
-
Persistence is fail-safe: any error while reading/writing state is swallowed so it can never break a page.
-
Two browser tabs editing the same table can race on the last write; the most recent request wins.
License
MIT — see LICENSE.md.
kisame76/filament-db-table-state 适用场景与选型建议
kisame76/filament-db-table-state 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 116 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 06 月 09 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「persistence」 「laravel」 「filters」 「tables」 「livewire」 「filament」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 kisame76/filament-db-table-state 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 kisame76/filament-db-table-state 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 kisame76/filament-db-table-state 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
This bundle provides tools to build persistence-agnostic storage layer.
Propel2 is an open-source Object-Relational Mapping (ORM) for PHP 5.5 and up.
Kinikit - PHP Application development framework MVC component
Simple filters for laravel
Livewire Filters is a series of Livewire components that provide you with the tools to do live filtering of your data from your own Livewire components.
A lightweight WordPress hook helper library. Register hooks before WordPress loads, run callbacks only once, and more.
统计信息
- 总下载量: 116
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 34
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-06-09