From 2469a77d2e0d37edc58a689ee3cb4be7eca589d2 Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Tue, 16 Sep 2025 11:44:07 +0100 Subject: [PATCH 1/9] fix: Partially render deferred filters form after action used --- .../src/Concerns/InteractsWithActions.php | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/packages/actions/src/Concerns/InteractsWithActions.php b/packages/actions/src/Concerns/InteractsWithActions.php index 318a88329a..bf5e5cace8 100644 --- a/packages/actions/src/Concerns/InteractsWithActions.php +++ b/packages/actions/src/Concerns/InteractsWithActions.php @@ -14,6 +14,7 @@ use Filament\Schemas\Contracts\HasSchemas; use Filament\Schemas\Schema; use Filament\Support\Exceptions\Cancel; use Filament\Support\Exceptions\Halt; +use Filament\Support\Livewire\Partials\PartialsComponentHook; use Filament\Tables\Contracts\HasTable; use Illuminate\Auth\Access\Response; use Illuminate\Database\Eloquent\Model; @@ -309,6 +310,8 @@ trait InteractsWithActions return $result; } + $this->partiallyRenderActionParentSchema($action); + $action->resetArguments(); $action->resetData(); @@ -329,6 +332,28 @@ trait InteractsWithActions return $result; } + protected function partiallyRenderActionParentSchema(Action $action): void + { + $actionSchema = $action->getSchemaContainer() ?? $action->getSchemaComponent()?->getContainer(); + $schemaToPartiallyRender = null; + + while ($actionSchema !== null) { + if ($actionSchema->shouldPartiallyRender()) { + $schemaToPartiallyRender = $actionSchema; + } + + $actionSchema = $actionSchema->getParentComponent()?->getContainer(); + } + + if (! $schemaToPartiallyRender) { + return; + } + + app(PartialsComponentHook::class)->renderPartial($this, fn (): array => [ + "schema.{$schemaToPartiallyRender->getKey()}" => $schemaToPartiallyRender->toHtml(...), + ]); + } + protected function afterActionCalled(): void {} /** From 539544e9db70f8bfce76d2afcdfa7822125ccc5b Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Tue, 16 Sep 2025 11:48:23 +0100 Subject: [PATCH 2/9] Update HasFileAttachments.php --- packages/forms/src/Components/Concerns/HasFileAttachments.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/forms/src/Components/Concerns/HasFileAttachments.php b/packages/forms/src/Components/Concerns/HasFileAttachments.php index 04c299a7ae..a881b7b712 100644 --- a/packages/forms/src/Components/Concerns/HasFileAttachments.php +++ b/packages/forms/src/Components/Concerns/HasFileAttachments.php @@ -8,6 +8,7 @@ use Illuminate\Contracts\Filesystem\Filesystem; use Illuminate\Filesystem\FilesystemAdapter; use Illuminate\Support\Facades\Storage; use League\Flysystem\UnableToCheckFileExistence; +use Livewire\Attributes\Renderless; use Livewire\Features\SupportFileUploads\TemporaryUploadedFile; use Throwable; @@ -38,6 +39,7 @@ trait HasFileAttachments } #[ExposedLivewireMethod] + #[Renderless] public function getUploadedFileAttachmentTemporaryUrl(TemporaryUploadedFile | string | null $attachment = null): ?string { return $this->getUploadedFileAttachment($attachment)?->temporaryUrl(); @@ -77,6 +79,7 @@ trait HasFileAttachments } #[ExposedLivewireMethod] + #[Renderless] public function saveUploadedFileAttachmentAndGetUrl(): ?string { $attachment = $this->getUploadedFileAttachment(); From 8f869c1b69c645b68834391f55c7853a863ced1e Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Tue, 16 Sep 2025 11:53:15 +0100 Subject: [PATCH 3/9] Update InteractsWithSchemas.php --- .../src/Concerns/InteractsWithSchemas.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/schemas/src/Concerns/InteractsWithSchemas.php b/packages/schemas/src/Concerns/InteractsWithSchemas.php index 192fb1dbe6..731ff8f7b8 100644 --- a/packages/schemas/src/Concerns/InteractsWithSchemas.php +++ b/packages/schemas/src/Concerns/InteractsWithSchemas.php @@ -9,6 +9,7 @@ use Filament\Schemas\Components\Component; use Filament\Schemas\Schema; use Filament\Support\Components\Attributes\ExposedLivewireMethod; use Filament\Support\Contracts\TranslatableContentDriver; +use Filament\Support\Livewire\Partials\PartialsComponentHook; use Illuminate\Support\Arr; use Illuminate\Validation\ValidationException; use Livewire\Attributes\Locked; @@ -79,6 +80,23 @@ trait InteractsWithSchemas if ($methodReflection->getAttributes(Renderless::class)) { $this->skipRender(); + } else { + $schema = $component->getContainer(); + $schemaToPartiallyRender = null; + + while ($schema !== null) { + if ($schema->shouldPartiallyRender()) { + $schemaToPartiallyRender = $schema; + } + + $schema = $schema->getParentComponent()?->getContainer(); + } + + if ($schemaToPartiallyRender) { + app(PartialsComponentHook::class)->renderPartial($this, fn (): array => [ + "schema.{$schemaToPartiallyRender->getKey()}" => $schemaToPartiallyRender->toHtml(...), + ]); + } } return $component->{$method}(...$arguments); From 67e29cfaec6516a33038ef15e86f134c14f94a55 Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Tue, 16 Sep 2025 16:50:03 +0100 Subject: [PATCH 4/9] fix: Merge action arguments without overwriting --- packages/actions/src/Concerns/HasArguments.php | 17 ++++++++++++----- .../src/Concerns/InteractsWithActions.php | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/packages/actions/src/Concerns/HasArguments.php b/packages/actions/src/Concerns/HasArguments.php index 0b8d6152a2..8e022558e6 100644 --- a/packages/actions/src/Concerns/HasArguments.php +++ b/packages/actions/src/Concerns/HasArguments.php @@ -29,12 +29,19 @@ trait HasArguments /** * @param array $arguments */ - public function mergeArguments(array $arguments): static + public function mergeArguments(array $arguments, bool $shouldOverwriteExistingArguments = true): static { - $this->arguments = [ - ...$this->arguments ?? [], - ...$arguments, - ]; + if ($shouldOverwriteExistingArguments) { + $this->arguments = [ + ...$this->arguments ?? [], + ...$arguments, + ]; + } else { + $this->arguments = [ + ...$arguments, + ...$this->arguments ?? [], + ]; + } return $this; } diff --git a/packages/actions/src/Concerns/InteractsWithActions.php b/packages/actions/src/Concerns/InteractsWithActions.php index bf5e5cace8..bbcc2a3678 100644 --- a/packages/actions/src/Concerns/InteractsWithActions.php +++ b/packages/actions/src/Concerns/InteractsWithActions.php @@ -495,7 +495,7 @@ trait InteractsWithActions continue; } - $resolvedAction->mergeArguments($action['arguments'] ?? []); + $resolvedAction->mergeArguments($action['arguments'] ?? [], shouldOverwriteExistingArguments: false); $resolvedAction->nestingIndex($actionNestingIndex); $resolvedAction->boot(); From 5719f62a799e61dd5d83c9c0f25834cc92f21dcc Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Tue, 16 Sep 2025 17:03:03 +0100 Subject: [PATCH 5/9] Revert "fix: Merge action arguments without overwriting" This reverts commit 67e29cfaec6516a33038ef15e86f134c14f94a55. --- packages/actions/src/Concerns/HasArguments.php | 17 +++++------------ .../src/Concerns/InteractsWithActions.php | 2 +- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/packages/actions/src/Concerns/HasArguments.php b/packages/actions/src/Concerns/HasArguments.php index 8e022558e6..0b8d6152a2 100644 --- a/packages/actions/src/Concerns/HasArguments.php +++ b/packages/actions/src/Concerns/HasArguments.php @@ -29,19 +29,12 @@ trait HasArguments /** * @param array $arguments */ - public function mergeArguments(array $arguments, bool $shouldOverwriteExistingArguments = true): static + public function mergeArguments(array $arguments): static { - if ($shouldOverwriteExistingArguments) { - $this->arguments = [ - ...$this->arguments ?? [], - ...$arguments, - ]; - } else { - $this->arguments = [ - ...$arguments, - ...$this->arguments ?? [], - ]; - } + $this->arguments = [ + ...$this->arguments ?? [], + ...$arguments, + ]; return $this; } diff --git a/packages/actions/src/Concerns/InteractsWithActions.php b/packages/actions/src/Concerns/InteractsWithActions.php index bbcc2a3678..bf5e5cace8 100644 --- a/packages/actions/src/Concerns/InteractsWithActions.php +++ b/packages/actions/src/Concerns/InteractsWithActions.php @@ -495,7 +495,7 @@ trait InteractsWithActions continue; } - $resolvedAction->mergeArguments($action['arguments'] ?? [], shouldOverwriteExistingArguments: false); + $resolvedAction->mergeArguments($action['arguments'] ?? []); $resolvedAction->nestingIndex($actionNestingIndex); $resolvedAction->boot(); From 246f547c524e2779288636cf9a7d6e0a23632418 Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Tue, 16 Sep 2025 17:03:31 +0100 Subject: [PATCH 6/9] fix --- packages/actions/src/Concerns/InteractsWithActions.php | 1 - packages/actions/src/Testing/TestsActions.php | 8 ++++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/actions/src/Concerns/InteractsWithActions.php b/packages/actions/src/Concerns/InteractsWithActions.php index bf5e5cace8..d09ac6590d 100644 --- a/packages/actions/src/Concerns/InteractsWithActions.php +++ b/packages/actions/src/Concerns/InteractsWithActions.php @@ -495,7 +495,6 @@ trait InteractsWithActions continue; } - $resolvedAction->mergeArguments($action['arguments'] ?? []); $resolvedAction->nestingIndex($actionNestingIndex); $resolvedAction->boot(); diff --git a/packages/actions/src/Testing/TestsActions.php b/packages/actions/src/Testing/TestsActions.php index 7967b0c789..0952e5c599 100644 --- a/packages/actions/src/Testing/TestsActions.php +++ b/packages/actions/src/Testing/TestsActions.php @@ -145,6 +145,10 @@ class TestsActions ...$actions, ]); + if ($action && filled($arguments = Arr::last($actions)['arguments'])) { + $action->mergeArguments($arguments); + } + $livewireClass = $this->instance()::class; $prettyName = implode(' > ', Arr::pluck($actions, 'name')); @@ -184,6 +188,10 @@ class TestsActions return $this; } + if ($action && filled($arguments = Arr::last($actions)['arguments'])) { + $action->mergeArguments($arguments); + } + $livewireClass = $this->instance()::class; $prettyName = implode(' > ', Arr::pluck($actions, 'name')); From b2c14a5ab357ce4bb0eab671529d77b78c0870bd Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Tue, 16 Sep 2025 17:07:02 +0100 Subject: [PATCH 7/9] Update TestsActions.php --- packages/actions/src/Testing/TestsActions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/actions/src/Testing/TestsActions.php b/packages/actions/src/Testing/TestsActions.php index 0952e5c599..ed0ee03f61 100644 --- a/packages/actions/src/Testing/TestsActions.php +++ b/packages/actions/src/Testing/TestsActions.php @@ -145,7 +145,7 @@ class TestsActions ...$actions, ]); - if ($action && filled($arguments = Arr::last($actions)['arguments'])) { + if ($action && filled($arguments = Arr::last($actions)['arguments'] ?? [])) { $action->mergeArguments($arguments); } @@ -188,7 +188,7 @@ class TestsActions return $this; } - if ($action && filled($arguments = Arr::last($actions)['arguments'])) { + if ($action && filled($arguments = Arr::last($actions)['arguments'] ?? [])) { $action->mergeArguments($arguments); } From c84f15ae7f2d76d8f2016efa1b1092fe5e7fcb4a Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Tue, 16 Sep 2025 17:15:55 +0100 Subject: [PATCH 8/9] Remove Laravel 10 docs refs --- docs/05-panel-configuration.md | 2 +- packages/actions/docs/11-import.md | 9 --------- packages/actions/docs/12-export.md | 9 --------- packages/notifications/docs/02-database-notifications.md | 4 ---- 4 files changed, 1 insertion(+), 23 deletions(-) diff --git a/docs/05-panel-configuration.md b/docs/05-panel-configuration.md index f436acfa27..a54db08872 100644 --- a/docs/05-panel-configuration.md +++ b/docs/05-panel-configuration.md @@ -31,7 +31,7 @@ php artisan make:filament-panel app This command will create a new panel called "app". A configuration file will be created at `app/Providers/Filament/AppPanelProvider.php`. You can access this panel at `/app`, but you can [customize the path](#changing-the-path) if you don't want that. -Since this configuration file is also a [Laravel service provider](https://laravel.com/docs/providers), it needs to be registered in `bootstrap/providers.php` (Laravel 11 and above) or `config/app.php` (Laravel 10 and below). Filament will attempt to do this for you, but if you get an error while trying to access your panel then this process has probably failed. +Since this configuration file is also a [Laravel service provider](https://laravel.com/docs/providers), it needs to be registered in `bootstrap/providers.php` (Laravel 11 app structure and above) or `config/app.php` (Laravel 10 app structure and below). Filament will attempt to do this for you, but if you get an error while trying to access your panel then this process has probably failed. ## Changing the path diff --git a/packages/actions/docs/11-import.md b/packages/actions/docs/11-import.md index 89b0c2501d..890fb8a431 100644 --- a/packages/actions/docs/11-import.md +++ b/packages/actions/docs/11-import.md @@ -11,17 +11,8 @@ Filament includes an action that is able to import rows from a CSV. When the tri This feature uses [job batches](https://laravel.com/docs/queues#job-batching) and [database notifications](../../notifications/database-notifications), so you need to publish those migrations from Laravel. Also, you need to publish the migrations for tables that Filament uses to store information about imports: ```bash -# Laravel 11 and higher php artisan make:queue-batches-table php artisan make:notifications-table - -# Laravel 10 -php artisan queue:batches-table -php artisan notifications:table -``` - -```bash -# All apps php artisan vendor:publish --tag=filament-actions-migrations php artisan migrate ``` diff --git a/packages/actions/docs/12-export.md b/packages/actions/docs/12-export.md index 08cb28d936..8e84ce1e1a 100644 --- a/packages/actions/docs/12-export.md +++ b/packages/actions/docs/12-export.md @@ -9,17 +9,8 @@ import UtilityInjection from "@components/UtilityInjection.astro" Filament includes an action that is able to export rows to a CSV or XLSX file. When the trigger button is clicked, a modal asks for the columns that they want to export, and what they should be labeled. This feature uses [job batches](https://laravel.com/docs/queues#job-batching) and [database notifications](../../notifications/database-notifications), so you need to publish those migrations from Laravel. Also, you need to publish the migrations for tables that Filament uses to store information about exports: ```bash -# Laravel 11 and higher php artisan make:queue-batches-table php artisan make:notifications-table - -# Laravel 10 -php artisan queue:batches-table -php artisan notifications:table -``` - -```bash -# All apps php artisan vendor:publish --tag=filament-actions-migrations php artisan migrate ``` diff --git a/packages/notifications/docs/02-database-notifications.md b/packages/notifications/docs/02-database-notifications.md index 588e57c097..25049e4d46 100644 --- a/packages/notifications/docs/02-database-notifications.md +++ b/packages/notifications/docs/02-database-notifications.md @@ -11,11 +11,7 @@ import AutoScreenshot from "@components/AutoScreenshot.astro" Before we start, make sure that the [Laravel notifications table](https://laravel.com/docs/notifications#database-prerequisites) is added to your database: ```bash -# Laravel 11 and higher php artisan make:notifications-table - -# Laravel 10 -php artisan notifications:table ``` > If you're using PostgreSQL, make sure that the `data` column in the migration is using `json()`: `$table->json('data')`. From 8f429138ebb9d3902ef97dd60adc086b383422cc Mon Sep 17 00:00:00 2001 From: Kenneth Sese Date: Tue, 16 Sep 2025 11:33:35 -0600 Subject: [PATCH 9/9] Allow html in table grouping label and title --- packages/tables/src/Grouping/Group.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/tables/src/Grouping/Group.php b/packages/tables/src/Grouping/Group.php index 2c33255f50..95662ea69d 100644 --- a/packages/tables/src/Grouping/Group.php +++ b/packages/tables/src/Grouping/Group.php @@ -9,6 +9,7 @@ use Closure; use Filament\Support\Components\Component; use Filament\Support\Contracts\HasLabel as LabelInterface; use Filament\Tables\Table; +use Illuminate\Contracts\Support\Htmlable; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\Relation; @@ -35,7 +36,7 @@ class Group extends Component protected ?Closure $scopeQueryByKeyUsing = null; - protected string | Closure | null $label = null; + protected string | Htmlable | Closure | null $label = null; protected string $id; @@ -88,7 +89,7 @@ class Group extends Component return $this; } - public function label(string | Closure | null $label): static + public function label(string | Htmlable | Closure | null $label): static { $this->label = $label; @@ -181,7 +182,7 @@ class Group extends Component return $this->id; } - public function getLabel(): string + public function getLabel(): string | Htmlable { return $this->evaluate($this->label) ?? (string) str($this->getId()) ->beforeLast('.') @@ -191,7 +192,7 @@ class Group extends Component ->ucfirst(); } - public function getDescription(Model $record, ?string $title): ?string + public function getDescription(Model $record, string | Htmlable | null $title): string | Htmlable | null { if (! $this->getDescriptionFromRecordUsing) { return null; @@ -250,7 +251,7 @@ class Group extends Component return Arr::get($record, $this->getColumn()); } - public function getTitle(Model $record): ?string + public function getTitle(Model $record): string | Htmlable | null { $column = $this->getColumn();