Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
afonic committed Feb 28, 2024
2 parents 7b741ec + 018befe commit 57c62df
Show file tree
Hide file tree
Showing 15 changed files with 176 additions and 10 deletions.
2 changes: 2 additions & 0 deletions config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@
// If enabled the addon will preset the term parameters in any taxonomy term routes
'enable_term_routes' => false,

// The addon will calculate the number of entries for each filter value (can be slow for a large number of entries)
'enable_filter_values_count' => false,
];
3 changes: 3 additions & 0 deletions resources/views/livewire/filters/lf-checkbox.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ class="form-checkbox w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded f
class="ml-2 text-gray-900"
>
{{ $label }}
@if ($this->counts[$value] !== null)
<span class="text-gray-500 ml-1">({{ $this->counts[$value] }})</span>
@endif
</label>
</div>
@endforeach
Expand Down
3 changes: 3 additions & 0 deletions resources/views/livewire/filters/lf-radio.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ class="form-radio w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 focus:ring-b
class="ml-2 text-gray-900"
>
{{ $label }}
@if ($this->counts[$value] !== null)
<span class="text-gray-500 ml-1">({{ $this->counts[$value] }})</span>
@endif
</label>
</div>
@endforeach
Expand Down
3 changes: 3 additions & 0 deletions resources/views/livewire/filters/lf-select.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ class="form-select bg-gray-50 border border-gray-300 text-gray-900 text-sm round
<option
value="{{ $value }}">
{{ $label }}
@if ($this->counts[$value] !== null)
<span class="text-gray-500 ml-1">({{ $this->counts[$value] }})</span>
@endif
</option>
@endforeach
</select>
Expand Down
2 changes: 1 addition & 1 deletion src/Http/Livewire/LfCheckboxFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

class LfCheckboxFilter extends Component
{
use Traits\IsLivewireFilter;
use Traits\HandleEntriesCount, Traits\IsLivewireFilter;

public $view = 'lf-checkbox';

Expand Down
2 changes: 1 addition & 1 deletion src/Http/Livewire/LfRadioFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

class LfRadioFilter extends Component
{
use Traits\IsLivewireFilter;
use Traits\HandleEntriesCount, Traits\IsLivewireFilter;

public $view = 'lf-radio';

Expand Down
1 change: 1 addition & 0 deletions src/Http/Livewire/LivewireCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public function mount($params)
} else {
$this->setParameters(array_merge($params, $this->params));
}
$this->dispatchParamsUpdated();
}

#[On('filter-mounted')]
Expand Down
10 changes: 10 additions & 0 deletions src/Http/Livewire/Traits/GenerateParams.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ protected function generateParams()
);
}

protected function generateParamsForCount($collection, $params)
{
return Parameters::make(array_merge(
['from' => $collection],
$params,
),
Context::make([])
);
}

protected function removeParamsNotInFiltersCollection()
{
return collect($this->params)->filter(function ($value, $key) {
Expand Down
39 changes: 39 additions & 0 deletions src/Http/Livewire/Traits/HandleEntriesCount.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace Reach\StatamicLivewireFilters\Http\Livewire\Traits;

use Livewire\Attributes\Computed;
use Livewire\Attributes\On;
use Statamic\Tags\Collection\Entries;

trait HandleEntriesCount
{
use GenerateParams;

#[Computed]
public function counts()
{
return $this->statamic_field['counts'];
}

#[On('params-updated')]
public function updateCounts($params)
{
foreach ($this->statamic_field['options'] as $option => $label) {
$params = array_merge($params, $this->getOptionParam($option));
$this->statamic_field['counts'][$option] = (new Entries($this->generateParamsForCount($this->collection, $params)))->count();
}
}

protected function getOptionParam($option)
{
if ($this->condition === 'query_scope') {
return [
'query_scope' => $this->modifier,
$this->getParamKey() => $option,
];
}

return [$this->getParamKey() => $option];
}
}
10 changes: 10 additions & 0 deletions src/Http/Livewire/Traits/HandleParams.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ protected function handleQueryScopeCondition($field, $payload, $command, $modifi
default:
throw new CommandNotFoundException($command);
}
$this->dispatchParamsUpdated();
}

protected function runCommand($command, $paramKey, $value)
Expand All @@ -119,6 +120,8 @@ protected function runCommand($command, $paramKey, $value)
throw new CommandNotFoundException($command);
break;
}

$this->dispatchParamsUpdated();
}

protected function addValueToParam($paramKey, $value)
Expand Down Expand Up @@ -168,4 +171,11 @@ protected function handlePresetParams()
$this->dispatch('preset-params', $restOfParams->all());
}
}

protected function dispatchParamsUpdated()
{
if (config('statamic-livewire-filters.enable_filter_values_count')) {
$this->dispatch('params-updated', $this->params);
}
}
}
13 changes: 12 additions & 1 deletion src/Http/Livewire/Traits/IsLivewireFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,19 @@ public function initiateField()
collect($field->config()['taxonomies'])->each(function ($taxonomy) use ($terms) {
$terms->push(($this->getTaxonomyTerms($taxonomy)->all()));
});
$field->setConfig(['options' => $terms->collapse()->all()]);
$field->setConfig([
'options' => $terms->collapse()->all(),
'counts' => $terms->collapse()->keys()->flatMap(fn ($slug) => [$slug => null])->all(),
]);
} else {
if (array_key_exists('options', $field->toArray())) {
$field->setConfig(array_merge(
$field->config(),
['counts' => collect($field->get('options'))->keys()->flatMap(fn ($option) => [$option => null])->all()]
));
}
}

$this->statamic_field = $field->toArray();
}

Expand Down
20 changes: 16 additions & 4 deletions tests/Feature/LfCheckboxFilterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function setUp(): void

'handle' => 'item_options',
'field' => [
'type' => 'checkbox',
'type' => 'checkboxes',
'display' => 'Checkbox',
'listable' => 'hidden',
'options' => [
Expand All @@ -54,9 +54,9 @@ public function setUp(): void
]);
$this->blueprint->setHandle('pages')->setNamespace('collections.'.$this->collection->handle())->save();

$this->makeEntry($this->collection, 'a')->set('title', 'I Love Guitars')->save();
$this->makeEntry($this->collection, 'b')->set('title', 'I Love Drums')->save();
$this->makeEntry($this->collection, 'c')->set('title', 'I Hate Flutes')->save();
$this->makeEntry($this->collection, 'a')->set('title', 'I Love Guitars')->set('item_options', 'option1')->save();
$this->makeEntry($this->collection, 'b')->set('title', 'I Love Drums')->set('item_options', 'option1')->save();
$this->makeEntry($this->collection, 'c')->set('title', 'I Hate Flutes')->set('item_options', 'option2')->save();

Facades\Taxonomy::make('colors')->save();
Facades\Term::make()->taxonomy('colors')->inDefaultLocale()->slug('red')->data(['title' => 'Red'])->save();
Expand Down Expand Up @@ -243,6 +243,18 @@ public function it_loads_a_param_that_is_preset_for_a_query_scope()
->assertSet('selected', ['option1']);
}

/** @test */
public function it_calculates_the_count_for_each_entry()
{
Livewire::test(LfCheckboxFilter::class, ['field' => 'item_options', 'blueprint' => 'pages.pages', 'condition' => 'is'])
->assertSet('selected', [])
->dispatch('params-updated', ['item_options:is' => 'option1'])
->assertViewHas('statamic_field', function ($statamic_field) {
return $statamic_field['counts'] === ['option1' => 2, 'option2' => 1, 'option3' => 0];
})
->assertSeeHtml('<span class="text-gray-500 ml-1">(2)</span>');
}

protected function makeEntry($collection, $slug)
{
return EntryFactory::id($slug)->collection($collection)->slug($slug)->make();
Expand Down
19 changes: 16 additions & 3 deletions tests/Feature/LfRadioFilterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ public function setUp(): void
]);
$this->blueprint->setHandle('pages')->setNamespace('collections.'.$this->collection->handle())->save();

$this->makeEntry($this->collection, 'a')->set('title', 'I Love Guitars')->save();
$this->makeEntry($this->collection, 'b')->set('title', 'I Love Drums')->save();
$this->makeEntry($this->collection, 'c')->set('title', 'I Hate Flutes')->save();
$this->makeEntry($this->collection, 'a')->set('title', 'I Love Guitars')->set('item_options', 'option1')->save();
$this->makeEntry($this->collection, 'b')->set('title', 'I Love Drums')->set('item_options', 'option1')->save();
$this->makeEntry($this->collection, 'c')->set('title', 'I Hate Flutes')->set('item_options', 'option2')->save();
}

/** @test */
Expand Down Expand Up @@ -157,6 +157,19 @@ public function it_loads_a_param_that_is_preset()
->assertSet('selected', 'option1');
}

/** @test */
public function it_calculates_the_count_for_each_entry()
{
Livewire::test(LfRadioFilter::class, ['field' => 'item_options', 'blueprint' => 'pages.pages', 'condition' => 'is'])
->assertSet('selected', '')
->dispatch('params-updated', ['item_options:is' => 'option1'])
->assertViewHas('statamic_field', function ($statamic_field) {
return $statamic_field['counts'] === ['option1' => 2, 'option2' => 1, 'option3' => 0];
})
->assertSeeHtml('<span class="text-gray-500 ml-1">(2)</span>');

}

protected function makeEntry($collection, $slug)
{
return EntryFactory::id($slug)->collection($collection)->slug($slug)->make();
Expand Down
58 changes: 58 additions & 0 deletions tests/Feature/LivewireCollectionComponentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -410,4 +410,62 @@ public function it_gets_a_list_of_active_filters_on_the_page()
return true;
});
}

/** @test */
public function it_does_not_dispatch_the_params_updated_event_by_default()
{
//Config::set('statamic-livewire-filters.only_allow_active_filters', false);
$params = [
'from' => 'clothes',
];

Livewire::test(LivewireCollectionComponent::class, ['params' => $params])
->dispatch('filter-updated',
field: 'colors',
condition: 'taxonomy',
payload: 'yellow',
command: 'add',
modifier: 'any',
)
->assertNotDispatched('params-updated');
}

/** @test */
public function it_dispatches_the_params_updated_event_if_enabled()
{
Config::set('statamic-livewire-filters.enable_filter_values_count', true);

$params = [
'from' => 'clothes',
];

// Also add some tests to make sure it's not dispatched when it's not needed
Livewire::test(LivewireCollectionComponent::class, ['params' => $params])
->dispatch('filter-updated',
field: 'colors',
condition: 'taxonomy',
payload: 'yellow',
command: 'add',
modifier: 'any',
)
->assertDispatched('params-updated')
->dispatch('filter-mounted',
field: 'colors',
condition: 'taxonomy',
modifier: 'any',
)
->assertNotDispatched('params-updated')
->dispatch('filter-updated',
field: 'colors',
condition: 'taxonomy',
payload: 'yellow',
command: 'remove',
modifier: 'any',
)
->assertDispatched('params-updated')
->dispatch('sort-updated',
sort: 'title:asc'
)
->assertNotDispatched('params-updated');
}
}
1 change: 1 addition & 0 deletions tests/__fixtures__/content/collections/pages.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
revisions: false

0 comments on commit 57c62df

Please sign in to comment.