From d91966e5686e1fd2a448719ed9d36cb4b0182282 Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Tue, 16 Sep 2025 11:06:11 +0100 Subject: [PATCH 1/2] fix: Deferred query builder --- packages/tables/src/Concerns/HasFilters.php | 5 +++++ packages/tables/src/Contracts/HasTable.php | 5 +++++ packages/tables/src/Filters/Concerns/BelongsToTable.php | 8 ++++++++ packages/tables/src/Filters/QueryBuilder.php | 2 +- 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/tables/src/Concerns/HasFilters.php b/packages/tables/src/Concerns/HasFilters.php index 686c171fad..c5d6565d42 100644 --- a/packages/tables/src/Concerns/HasFilters.php +++ b/packages/tables/src/Concerns/HasFilters.php @@ -178,6 +178,11 @@ trait HasFilters return Arr::get($this->tableFilters, $this->parseTableFilterName($name)); } + public function getTableFilterFormState(string $name): ?array + { + return Arr::get($this->getTable()->hasDeferredFilters() ? $this->tableDeferredFilters : $this->tableFilters, $this->parseTableFilterName($name)); + } + public function parseTableFilterName(string $name): string { if (! class_exists($name)) { diff --git a/packages/tables/src/Contracts/HasTable.php b/packages/tables/src/Contracts/HasTable.php index e611c4eb01..2277b2e39c 100644 --- a/packages/tables/src/Contracts/HasTable.php +++ b/packages/tables/src/Contracts/HasTable.php @@ -38,6 +38,11 @@ interface HasTable */ public function getTableFilterState(string $name): ?array; + /** + * @return array | null + */ + public function getTableFilterFormState(string $name): ?array; + public function getSelectedTableRecords(bool $shouldFetchSelectedRecords = true, ?int $chunkSize = null): EloquentCollection | Collection | LazyCollection; public function getSelectedTableRecordsQuery(bool $shouldFetchSelectedRecords = true, ?int $chunkSize = null): Builder; diff --git a/packages/tables/src/Filters/Concerns/BelongsToTable.php b/packages/tables/src/Filters/Concerns/BelongsToTable.php index 03bd117852..0645985817 100644 --- a/packages/tables/src/Filters/Concerns/BelongsToTable.php +++ b/packages/tables/src/Filters/Concerns/BelongsToTable.php @@ -33,4 +33,12 @@ trait BelongsToTable { return $this->getLivewire()->getTableFilterState($this->getName()) ?? []; } + + /** + * @return array + */ + public function getFormState(): array + { + return $this->getLivewire()->getTableFilterFormState($this->getName()) ?? []; + } } diff --git a/packages/tables/src/Filters/QueryBuilder.php b/packages/tables/src/Filters/QueryBuilder.php index 1d75b243b9..668a2c4f47 100644 --- a/packages/tables/src/Filters/QueryBuilder.php +++ b/packages/tables/src/Filters/QueryBuilder.php @@ -57,7 +57,7 @@ class QueryBuilder extends BaseFilter public function getActiveCount(): int { - return $this->countRules($this->getState()['rules'], $this->getRuleBuilder()); + return $this->countRules($this->getFormState()['rules'], $this->getRuleBuilder()); } /** From af14ebad90e304fbf2c937157981781caa3bec3f Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Tue, 16 Sep 2025 11:17:26 +0100 Subject: [PATCH 2/2] fix: Partially rendering --- packages/forms/src/Components/Builder.php | 28 ++++++++++++++----- packages/forms/src/Components/Repeater.php | 28 ++++++++++++++----- packages/tables/src/Filters/QueryBuilder.php | 3 +- .../Forms/Components/RuleBuilder.php | 7 +++-- 4 files changed, 48 insertions(+), 18 deletions(-) diff --git a/packages/forms/src/Components/Builder.php b/packages/forms/src/Components/Builder.php index b14d39c733..6583cdc7d5 100644 --- a/packages/forms/src/Components/Builder.php +++ b/packages/forms/src/Components/Builder.php @@ -97,6 +97,8 @@ class Builder extends Field implements CanConcealComponents, HasExtraItemActions protected Width | string | Closure | null $blockPickerWidth = null; + protected bool | Closure $shouldPartiallyRenderAfterActionsCalled = true; + protected function setUp(): void { parent::setUp(); @@ -270,7 +272,7 @@ class Builder extends Field implements CanConcealComponents, HasExtraItemActions $component->callAfterStateUpdated(); - $component->partiallyRender(); + $component->shouldPartiallyRenderAfterActionsCalled() ? $component->partiallyRender() : null; }) ->livewireClickHandlerEnabled(false) ->button() @@ -332,7 +334,7 @@ class Builder extends Field implements CanConcealComponents, HasExtraItemActions $component->callAfterStateUpdated(); - $component->partiallyRender(); + $component->shouldPartiallyRenderAfterActionsCalled() ? $component->partiallyRender() : null; }) ->iconButton() ->size(Size::Small) @@ -373,7 +375,7 @@ class Builder extends Field implements CanConcealComponents, HasExtraItemActions $component->callAfterStateUpdated(); - $component->partiallyRender(); + $component->shouldPartiallyRenderAfterActionsCalled() ? $component->partiallyRender() : null; }) ->iconButton() ->size(Size::Small) @@ -413,7 +415,7 @@ class Builder extends Field implements CanConcealComponents, HasExtraItemActions $component->callAfterStateUpdated(); - $component->partiallyRender(); + $component->shouldPartiallyRenderAfterActionsCalled() ? $component->partiallyRender() : null; }) ->iconButton() ->size(Size::Small) @@ -453,7 +455,7 @@ class Builder extends Field implements CanConcealComponents, HasExtraItemActions $component->callAfterStateUpdated(); - $component->partiallyRender(); + $component->shouldPartiallyRenderAfterActionsCalled() ? $component->partiallyRender() : null; }) ->iconButton() ->size(Size::Small) @@ -503,7 +505,7 @@ class Builder extends Field implements CanConcealComponents, HasExtraItemActions $component->callAfterStateUpdated(); - $component->partiallyRender(); + $component->shouldPartiallyRenderAfterActionsCalled() ? $component->partiallyRender() : null; }) ->livewireClickHandlerEnabled(false) ->iconButton() @@ -680,7 +682,7 @@ class Builder extends Field implements CanConcealComponents, HasExtraItemActions $component->callAfterStateUpdated(); - $component->partiallyRender(); + $component->shouldPartiallyRenderAfterActionsCalled() ? $component->partiallyRender() : null; }) ->iconButton() ->icon(Heroicon::Cog6Tooth) @@ -1156,4 +1158,16 @@ class Builder extends Field implements CanConcealComponents, HasExtraItemActions $rules["{$this->getStatePath()}.*.type"] = ['required']; } + + public function partiallyRenderAfterActionsCalled(bool | Closure $condition = true): static + { + $this->shouldPartiallyRenderAfterActionsCalled = $condition; + + return $this; + } + + public function shouldPartiallyRenderAfterActionsCalled(): bool + { + return (bool) $this->evaluate($this->shouldPartiallyRenderAfterActionsCalled); + } } diff --git a/packages/forms/src/Components/Repeater.php b/packages/forms/src/Components/Repeater.php index aa3adffbce..06f2b1fa65 100644 --- a/packages/forms/src/Components/Repeater.php +++ b/packages/forms/src/Components/Repeater.php @@ -115,6 +115,8 @@ class Repeater extends Field implements CanConcealComponents, HasExtraItemAction protected bool $shouldMergeHydratedDefaultStateWithItemsStateAfterStateHydrated = true; + protected bool | Closure $shouldPartiallyRenderAfterActionsCalled = true; + protected function setUp(): void { parent::setUp(); @@ -202,7 +204,7 @@ class Repeater extends Field implements CanConcealComponents, HasExtraItemAction $component->callAfterStateUpdated(); - $component->partiallyRender(); + $component->shouldPartiallyRenderAfterActionsCalled() ? $component->partiallyRender() : null; }) ->button() ->size(Size::Small) @@ -279,7 +281,7 @@ class Repeater extends Field implements CanConcealComponents, HasExtraItemAction $component->callAfterStateUpdated(); - $component->partiallyRender(); + $component->shouldPartiallyRenderAfterActionsCalled() ? $component->partiallyRender() : null; }) ->button() ->size(Size::Small) @@ -341,7 +343,7 @@ class Repeater extends Field implements CanConcealComponents, HasExtraItemAction $component->callAfterStateUpdated(); - $component->partiallyRender(); + $component->shouldPartiallyRenderAfterActionsCalled() ? $component->partiallyRender() : null; }) ->iconButton() ->size(Size::Small) @@ -382,7 +384,7 @@ class Repeater extends Field implements CanConcealComponents, HasExtraItemAction $component->callAfterStateUpdated(); - $component->partiallyRender(); + $component->shouldPartiallyRenderAfterActionsCalled() ? $component->partiallyRender() : null; }) ->iconButton() ->size(Size::Small) @@ -422,7 +424,7 @@ class Repeater extends Field implements CanConcealComponents, HasExtraItemAction $component->callAfterStateUpdated(); - $component->partiallyRender(); + $component->shouldPartiallyRenderAfterActionsCalled() ? $component->partiallyRender() : null; }) ->iconButton() ->size(Size::Small) @@ -462,7 +464,7 @@ class Repeater extends Field implements CanConcealComponents, HasExtraItemAction $component->callAfterStateUpdated(); - $component->partiallyRender(); + $component->shouldPartiallyRenderAfterActionsCalled() ? $component->partiallyRender() : null; }) ->iconButton() ->size(Size::Small) @@ -505,7 +507,7 @@ class Repeater extends Field implements CanConcealComponents, HasExtraItemAction $component->callAfterStateUpdated(); - $component->partiallyRender(); + $component->shouldPartiallyRenderAfterActionsCalled() ? $component->partiallyRender() : null; }) ->livewireClickHandlerEnabled(false) ->iconButton() @@ -1375,4 +1377,16 @@ class Repeater extends Field implements CanConcealComponents, HasExtraItemAction return 1; } + + public function partiallyRenderAfterActionsCalled(bool | Closure $condition = true): static + { + $this->shouldPartiallyRenderAfterActionsCalled = $condition; + + return $this; + } + + public function shouldPartiallyRenderAfterActionsCalled(): bool + { + return (bool) $this->evaluate($this->shouldPartiallyRenderAfterActionsCalled); + } } diff --git a/packages/tables/src/Filters/QueryBuilder.php b/packages/tables/src/Filters/QueryBuilder.php index 668a2c4f47..a670c5ee1a 100644 --- a/packages/tables/src/Filters/QueryBuilder.php +++ b/packages/tables/src/Filters/QueryBuilder.php @@ -35,8 +35,7 @@ class QueryBuilder extends BaseFilter ->label($filter->getLabel()) ->constraints($filter->getConstraints()) ->blockPickerColumns($filter->getConstraintPickerColumns()) - ->blockPickerWidth($filter->getConstraintPickerWidth()) - ->live(onBlur: true), + ->blockPickerWidth($filter->getConstraintPickerWidth()), ]); $this->query(function (Builder $query, array $data): void { diff --git a/packages/tables/src/Filters/QueryBuilder/Forms/Components/RuleBuilder.php b/packages/tables/src/Filters/QueryBuilder/Forms/Components/RuleBuilder.php index 576f78debc..3af066e258 100644 --- a/packages/tables/src/Filters/QueryBuilder/Forms/Components/RuleBuilder.php +++ b/packages/tables/src/Filters/QueryBuilder/Forms/Components/RuleBuilder.php @@ -107,7 +107,8 @@ class RuleBuilder extends Builder ->cloneable() ->reorderable(false) ->hiddenLabel() - ->generateUuidUsing(fn (): string => Str::random(4)), + ->generateUuidUsing(fn (): string => Str::random(4)) + ->partiallyRenderAfterActionsCalled($component->shouldPartiallyRenderAfterActionsCalled()), ]), ]; }) @@ -125,6 +126,8 @@ class RuleBuilder extends Builder ->expandAllAction(fn (Action $action) => $action->hidden()) ->collapseAllAction(fn (Action $action) => $action->hidden()) ->truncateBlockLabel(false) - ->generateUuidUsing(fn (): string => Str::random(4)); + ->generateUuidUsing(fn (): string => Str::random(4)) + ->live(onBlur: true) + ->partiallyRenderAfterActionsCalled(false); } }