diff --git a/src/Http/Livewire/LfCheckboxFilter.php b/src/Http/Livewire/LfCheckboxFilter.php index 550a474..9db4884 100644 --- a/src/Http/Livewire/LfCheckboxFilter.php +++ b/src/Http/Livewire/LfCheckboxFilter.php @@ -33,32 +33,13 @@ public function updatedSelected() $this->validate(); } - $optionsToAdd = array_diff($this->selected, $this->previousSelected); - $optionsToRemove = array_diff($this->previousSelected, $this->selected); - - foreach ($optionsToAdd as $option) { - $this->dispatch('filter-updated', - field: $this->field, - condition: $this->condition, - payload: $option, - command: 'add', - modifier: $this->modifier, - ) - ->to(LivewireCollection::class); - } - - foreach ($optionsToRemove as $option) { - $this->dispatch('filter-updated', - field: $this->field, - condition: $this->condition, - payload: $option, - command: 'remove', - modifier: $this->modifier, - ) - ->to(LivewireCollection::class); - } - - $this->previousSelected = $this->selected; + $this->dispatch('filter-updated', + field: $this->field, + condition: $this->condition, + payload: $this->selected, + modifier: $this->modifier, + ) + ->to(LivewireCollection::class); } public function clear() diff --git a/src/Http/Livewire/LfDateFilter.php b/src/Http/Livewire/LfDateFilter.php index 7a6c469..3bc4e4f 100644 --- a/src/Http/Livewire/LfDateFilter.php +++ b/src/Http/Livewire/LfDateFilter.php @@ -20,7 +20,6 @@ public function updatedSelected() field: $this->field, condition: $this->condition, payload: $this->selected, - command: 'replace', modifier: $this->modifier, ) ->to(LivewireCollection::class); diff --git a/src/Http/Livewire/LfDualRangeFilter.php b/src/Http/Livewire/LfDualRangeFilter.php index 451e4b9..977312d 100644 --- a/src/Http/Livewire/LfDualRangeFilter.php +++ b/src/Http/Livewire/LfDualRangeFilter.php @@ -61,7 +61,6 @@ public function dispatchEvent() 'min' => $min, 'max' => $max, ], - command: 'replace', modifier: $this->modifier, ) ->to(LivewireCollection::class); diff --git a/src/Http/Livewire/LfRadioFilter.php b/src/Http/Livewire/LfRadioFilter.php index 8870191..392a393 100644 --- a/src/Http/Livewire/LfRadioFilter.php +++ b/src/Http/Livewire/LfRadioFilter.php @@ -35,7 +35,6 @@ public function updatedSelected() field: $this->field, condition: $this->condition, payload: $this->selected, - command: 'replace', modifier: $this->modifier, ) ->to(LivewireCollection::class); diff --git a/src/Http/Livewire/LfRangeFilter.php b/src/Http/Livewire/LfRangeFilter.php index fda4e9e..fd8ecfe 100644 --- a/src/Http/Livewire/LfRangeFilter.php +++ b/src/Http/Livewire/LfRangeFilter.php @@ -36,7 +36,6 @@ public function dispatchEvent() field: $this->field, condition: $this->condition, payload: $this->selected, - command: 'replace', modifier: null, ) ->to(LivewireCollection::class); diff --git a/src/Http/Livewire/LfTextFilter.php b/src/Http/Livewire/LfTextFilter.php index 04cdd09..d695621 100644 --- a/src/Http/Livewire/LfTextFilter.php +++ b/src/Http/Livewire/LfTextFilter.php @@ -19,7 +19,6 @@ public function updatedSelected() field: $this->field, condition: $this->condition, payload: $this->selected, - command: 'replace', modifier: $this->modifier, ) ->to(LivewireCollection::class); diff --git a/src/Http/Livewire/LivewireCollection.php b/src/Http/Livewire/LivewireCollection.php index fa5914e..8076681 100644 --- a/src/Http/Livewire/LivewireCollection.php +++ b/src/Http/Livewire/LivewireCollection.php @@ -42,25 +42,31 @@ public function mount($params) } #[On('filter-updated')] - public function filterUpdated($field, $condition, $payload, $command, $modifier) + public function filterUpdated($field, $condition, $payload, $modifier) { $this->resetPagination(); + if ($payload === '' || $payload === null || $payload === []) { + $this->clearFilter($field, $condition, $modifier); + $this->dispatchParamsUpdated(); + + return; + } if ($condition === 'query_scope') { - $this->handleQueryScopeCondition($field, $payload, $command, $modifier); + $this->handleQueryScopeCondition($field, $payload, $modifier); return; } if ($condition === 'taxonomy') { - $this->handleTaxonomyCondition($field, $payload, $command, $modifier); + $this->handleTaxonomyCondition($field, $payload, $modifier); return; } if ($condition === 'dual_range') { - $this->handleDualRangeCondition($field, $payload, $command, $modifier); + $this->handleDualRangeCondition($field, $payload, $modifier); return; } - $this->handleCondition($field, $condition, $payload, $command); + $this->handleCondition($field, $condition, $payload); } #[On('sort-updated')] diff --git a/src/Http/Livewire/Traits/HandleParams.php b/src/Http/Livewire/Traits/HandleParams.php index 978f6e8..b0dddfa 100644 --- a/src/Http/Livewire/Traits/HandleParams.php +++ b/src/Http/Livewire/Traits/HandleParams.php @@ -3,7 +3,6 @@ namespace Reach\StatamicLivewireFilters\Http\Livewire\Traits; use Livewire\Attributes\On; -use Reach\StatamicLivewireFilters\Exceptions\CommandNotFoundException; use Reach\StatamicLivewireFilters\Http\Livewire\LfTags; trait HandleParams @@ -69,153 +68,78 @@ protected function extractAllowedFilters($paramsCollection) } } - protected function handleCondition($field, $condition, $payload, $command) + protected function handleCondition($field, $condition, $payload) { $paramKey = $field.':'.$condition; - $this->runCommand($command, $paramKey, $payload); + $this->params[$paramKey] = $this->toPipeSeparatedString($payload); + + $this->dispatchParamsUpdated(); } - protected function handleTaxonomyCondition($field, $payload, $command, $modifier) + protected function handleTaxonomyCondition($field, $payload, $modifier) { $paramKey = 'taxonomy:'.$field.':'.$modifier; - $this->runCommand($command, $paramKey, $payload); + $this->params[$paramKey] = $this->toPipeSeparatedString($payload); + + $this->dispatchParamsUpdated(); } - protected function handleQueryScopeCondition($field, $payload, $command, $modifier) + protected function handleQueryScopeCondition($field, $payload, $modifier) { $queryScopeKey = 'query_scope'; $modifierKey = $modifier.':'.$field; - switch ($command) { - case 'add': - $this->params[$queryScopeKey] = $modifier; - if (! isset($this->params[$modifierKey])) { - $this->params[$modifierKey] = $payload; - } else { - $payloads = collect(explode('|', $this->params[$modifierKey])); - if (! $payloads->contains($payload)) { - $payloads->push($payload); - $this->params[$modifierKey] = $payloads->implode('|'); - } - } - break; - - case 'remove': - if (isset($this->params[$modifierKey])) { - $payloads = collect(explode('|', $this->params[$modifierKey])); - $payloads = $payloads->reject(fn ($item) => $item === $payload); - if ($payloads->isNotEmpty()) { - $this->params[$modifierKey] = $payloads->implode('|'); - } else { - unset($this->params[$modifierKey], $this->params[$queryScopeKey]); - } - } - break; - - case 'replace': - $this->params[$queryScopeKey] = $modifier; - $this->params[$modifierKey] = $payload; - break; - - case 'clear': - unset($this->params[$queryScopeKey], $this->params[$modifierKey]); - break; - - default: - throw new CommandNotFoundException($command); - } + $this->params[$queryScopeKey] = $modifier; + $this->params[$modifierKey] = $this->toPipeSeparatedString($payload); + $this->dispatchParamsUpdated(); } - protected function handleDualRangeCondition($field, $payload, $command, $modifier) + protected function handleDualRangeCondition($field, $payload, $modifier) { - $minModifier = 'gte'; - $maxModifier = 'lte'; - - // If the modifier is set, we need to extract the min and max modifiers - if ($modifier !== 'any') { - [$minModifier, $maxModifier] = explode('|', $modifier); - } + [$minModifier, $maxModifier] = $this->getDualRangeConditions($modifier); $minParamKey = $field.':'.$minModifier; $maxParamKey = $field.':'.$maxModifier; - switch ($command) { - case 'replace': - $this->params[$minParamKey] = $payload['min']; - $this->params[$maxParamKey] = $payload['max']; - break; - - case 'clear': - unset($this->params[$minParamKey]); - unset($this->params[$maxParamKey]); - break; + $this->params[$minParamKey] = $payload['min']; + $this->params[$maxParamKey] = $payload['max']; - default: - throw new CommandNotFoundException($command); - } $this->dispatchParamsUpdated(); } - protected function runCommand($command, $paramKey, $value) + #[On('clear-filter')] + public function clearFilter($field, $condition, $modifier): void { - switch ($command) { - case 'add': - $this->addValueToParam($paramKey, $value); - break; - case 'replace': - $this->replaceValueOfParam($paramKey, $value); - break; - case 'remove': - $this->removeValueFromParam($paramKey, $value); - break; - case 'clear': - $this->clearParam($paramKey); - break; - default: - throw new CommandNotFoundException($command); - break; - } + if ($condition === 'query_scope') { + $queryScopeKey = 'query_scope'; + $modifierKey = $modifier.':'.$field; + unset($this->params[$queryScopeKey], $this->params[$modifierKey]); - $this->dispatchParamsUpdated(); - } + return; + } + if ($condition === 'taxonomy') { + $paramKey = 'taxonomy:'.$field.':'.$modifier; + unset($this->params[$paramKey]); - protected function addValueToParam($paramKey, $value) - { - if (! isset($this->params[$paramKey])) { - $this->params[$paramKey] = $value; - } else { - $values = collect(explode('|', $this->params[$paramKey])); - if (! $values->contains($value)) { - $values->push($value); - $this->params[$paramKey] = $values->implode('|'); - } + return; } - } + if ($condition === 'dual_range') { + [$minModifier, $maxModifier] = $this->getDualRangeConditions($modifier); - protected function replaceValueOfParam($paramKey, $value) - { - $this->params[$paramKey] = $value; - } + $minParamKey = $field.':'.$minModifier; + $maxParamKey = $field.':'.$maxModifier; - protected function clearParam($paramKey) - { - unset($this->params[$paramKey]); + unset($this->params[$minParamKey], $this->params[$maxParamKey]); + + return; + } + unset($this->params[$field.':'.$condition]); } - protected function removeValueFromParam($paramKey, $value) + protected function toPipeSeparatedString($payload): string { - if (isset($this->params[$paramKey])) { - $values = collect(explode('|', $this->params[$paramKey])); - - $values = $values->reject(fn ($item) => $item === $value); - - if ($values->isNotEmpty()) { - $this->params[$paramKey] = $values->implode('|'); - } else { - unset($this->params[$paramKey]); - } - } + return is_array($payload) ? implode('|', $payload) : $payload; } protected function handlePresetParams() @@ -281,6 +205,17 @@ protected function getConfigAliases(): array ->all(); } + protected function getDualRangeConditions($modifer): array + { + $modifiers = ['gte', 'lte']; + + if ($modifer === 'any') { + return $modifiers; + } + + return explode('|', $modifer); + } + protected function dispatchParamsUpdated(): void { if (config('statamic-livewire-filters.enable_filter_values_count')) { diff --git a/src/Http/Livewire/Traits/IsLivewireFilter.php b/src/Http/Livewire/Traits/IsLivewireFilter.php index b452ee5..9ed7d33 100644 --- a/src/Http/Livewire/Traits/IsLivewireFilter.php +++ b/src/Http/Livewire/Traits/IsLivewireFilter.php @@ -49,11 +49,9 @@ public function initiateField() public function clearFilters() { - $this->dispatch('filter-updated', + $this->dispatch('clear-filter', field: $this->field, condition: $this->condition, - payload: false, - command: 'clear', modifier: $this->modifier, ) ->to(LivewireCollection::class); diff --git a/tests/Feature/LfCheckboxFilterTest.php b/tests/Feature/LfCheckboxFilterTest.php index 7d82b36..f6120e1 100644 --- a/tests/Feature/LfCheckboxFilterTest.php +++ b/tests/Feature/LfCheckboxFilterTest.php @@ -137,16 +137,14 @@ public function it_changes_the_value_of_selected_property_when_an_option_is_set_ ->assertDispatched('filter-updated', field: 'item_options', condition: 'is', - payload: 'option1', - command: 'add', + payload: ['option1'], ) ->set('selected', ['option1', 'option2']) ->assertSet('selected', ['option1', 'option2']) ->assertDispatched('filter-updated', field: 'item_options', condition: 'is', - payload: 'option2', - command: 'add', + payload: ['option1', 'option2'], ); } @@ -172,8 +170,7 @@ public function it_can_turn_off_validation_of_values_in_the_config() ->assertDispatched('filter-updated', field: 'item_options', condition: 'is', - payload: 'not-an-option', - command: 'add', + payload: ['not-an-option'], ); } @@ -189,16 +186,14 @@ public function it_shows_taxonomy_terms_and_submits_the_right_events() ->assertDispatched('filter-updated', field: 'colors', condition: 'taxonomy', - payload: 'red', - command: 'add', + payload: ['red'], ) ->set('selected', ['yellow']) ->assertSet('selected', ['yellow']) ->assertDispatched('filter-updated', field: 'colors', condition: 'taxonomy', - payload: 'red', - command: 'remove', + payload: ['yellow'], ); } diff --git a/tests/Feature/LivewireCollectionComponentTest.php b/tests/Feature/LivewireCollectionComponentTest.php index 95d87d3..a41c636 100644 --- a/tests/Feature/LivewireCollectionComponentTest.php +++ b/tests/Feature/LivewireCollectionComponentTest.php @@ -89,7 +89,6 @@ public function it_loads_the_livewire_component_with_parameters_and_changes_them field: 'item_options', condition: 'is', payload: 'option1', - command: 'add', modifier: 'any', ) ->assertSet('params', [ @@ -101,7 +100,6 @@ public function it_loads_the_livewire_component_with_parameters_and_changes_them field: 'title', condition: 'is', payload: 'Test', - command: 'replace', modifier: 'any', ) ->assertSet('params', [ @@ -112,8 +110,7 @@ public function it_loads_the_livewire_component_with_parameters_and_changes_them ->dispatch('filter-updated', field: 'item_options', condition: 'is', - payload: 'option2', - command: 'add', + payload: ['option1', 'option2'], modifier: 'any', ) ->assertSet('params', [ @@ -124,8 +121,7 @@ public function it_loads_the_livewire_component_with_parameters_and_changes_them ->dispatch('filter-updated', field: 'item_options', condition: 'is', - payload: 'option1', - command: 'remove', + payload: ['option2'], modifier: 'any', ) ->assertDispatched('entries-updated') @@ -147,8 +143,7 @@ public function it_works_for_taxonomy_terms() ->dispatch('filter-updated', field: 'colors', condition: 'taxonomy', - payload: 'red', - command: 'add', + payload: ['red'], modifier: 'any', ) ->assertSet('params', [ @@ -157,8 +152,7 @@ public function it_works_for_taxonomy_terms() ->dispatch('filter-updated', field: 'colors', condition: 'taxonomy', - payload: 'yellow', - command: 'add', + payload: ['red', 'yellow'], modifier: 'any', ) ->assertSet('params', [ @@ -167,8 +161,7 @@ public function it_works_for_taxonomy_terms() ->dispatch('filter-updated', field: 'colors', condition: 'taxonomy', - payload: 'red', - command: 'remove', + payload: ['yellow'], modifier: 'any', ) ->assertSet('params', [ @@ -257,8 +250,7 @@ public function it_sets_query_scope_parameters() ->dispatch('filter-updated', field: 'sizes', condition: 'query_scope', - payload: 'xl', - command: 'add', + payload: ['xl'], modifier: 'multiselect', ) ->assertSet('params', [ @@ -268,8 +260,7 @@ public function it_sets_query_scope_parameters() ->dispatch('filter-updated', field: 'sizes', condition: 'query_scope', - payload: 'l', - command: 'add', + payload: ['xl', 'l'], modifier: 'multiselect', ) ->assertSet('params', [ @@ -279,8 +270,7 @@ public function it_sets_query_scope_parameters() ->dispatch('filter-updated', field: 'sizes', condition: 'query_scope', - payload: 'l', - command: 'remove', + payload: ['xl'], modifier: 'multiselect', ) ->assertSet('params', [ @@ -290,16 +280,14 @@ public function it_sets_query_scope_parameters() ->dispatch('filter-updated', field: 'sizes', condition: 'query_scope', - payload: 'xl', - command: 'remove', + payload: [], modifier: 'multiselect', ) ->assertSet('params', []) ->dispatch('filter-updated', field: 'sizes', condition: 'query_scope', - payload: 'xl', - command: 'replace', + payload: ['xl'], modifier: 'multiselect', ) ->assertSet('params', [ @@ -309,22 +297,13 @@ public function it_sets_query_scope_parameters() ->dispatch('filter-updated', field: 'sizes', condition: 'query_scope', - payload: 'l', - command: 'replace', + payload: ['l'], modifier: 'multiselect', ) ->assertSet('params', [ 'query_scope' => 'multiselect', 'multiselect:sizes' => 'l', - ]) - ->dispatch('filter-updated', - field: 'sizes', - condition: 'query_scope', - payload: '', - command: 'clear', - modifier: 'multiselect', - ) - ->assertSet('params', []); + ]); } /** @test */ @@ -361,11 +340,9 @@ public function it_clears_all_filters_for_a_field() 'title:is' => 'I Love Guitars', 'item_options:is' => 'option1|option2', ]) - ->dispatch('filter-updated', + ->dispatch('clear-filter', field: 'item_options', condition: 'is', - payload: false, - command: 'clear', modifier: 'any', ) ->assertSet('params', [ @@ -404,16 +381,14 @@ public function it_dispatches_the_params_updated_event_if_enabled() ->dispatch('filter-updated', field: 'colors', condition: 'taxonomy', - payload: 'yellow', - command: 'add', + payload: ['yellow'], modifier: 'any', ) ->assertDispatched('params-updated') ->dispatch('filter-updated', field: 'colors', condition: 'taxonomy', - payload: 'yellow', - command: 'remove', + payload: [], modifier: 'any', ) ->assertDispatched('params-updated')