From edbaf697885fd393eab77db56201b307c4333740 Mon Sep 17 00:00:00 2001 From: Hussam Alhennawi Date: Tue, 14 Jan 2025 21:40:31 +0400 Subject: [PATCH 01/24] Enable setting styles for column select (button and menu option checkbox) as a configuration. --- docs/columns/column-selection.md | 66 ++- .../toolbar/items/column-select.blade.php | 421 ++++++++++-------- .../ColumnSelectStylingConfiguration.php | 20 + src/Traits/Styling/HasColumnSelectStyling.php | 15 + .../Helpers/ColumnSelectStylingHelpers.php | 21 + src/Traits/WithColumnSelect.php | 4 +- 6 files changed, 353 insertions(+), 194 deletions(-) create mode 100644 src/Traits/Styling/Configuration/ColumnSelectStylingConfiguration.php create mode 100644 src/Traits/Styling/HasColumnSelectStyling.php create mode 100644 src/Traits/Styling/Helpers/ColumnSelectStylingHelpers.php diff --git a/docs/columns/column-selection.md b/docs/columns/column-selection.md index fae9eb906..0d5872fbb 100644 --- a/docs/columns/column-selection.md +++ b/docs/columns/column-selection.md @@ -222,4 +222,68 @@ class DataTableColumnsSelectedListener } } -``` \ No newline at end of file +``` + +## Styling + +### setColumnSelectButtonAttributes +Allows for customisation of the appearance of the "Column Select" button + +Note that this utilises a refreshed approach for attributes, and allows for appending to, or replacing the styles and colors independently, via the below methods. + +#### default-colors +Setting to false will disable the default colors for the Column Select button, the default colors are: + +Bootstrap: None + +Tailwind: `text-gray-700 bg-white border-gray-300 hover:bg-gray-50 focus:border-indigo-300 focus:ring-indigo-200 dark:bg-gray-700 dark:text-white dark:border-gray-600 dark:hover:bg-gray-600` + +#### default-styling +Setting to false will disable the default styling for the Column Select button, the default styling is: + +Bootstrap: `btn dropdown-toggle d-block w-100 d-md-inline` + +Tailwind: `inline-flex justify-center px-4 py-2 w-full text-sm font-medium rounded-md border shadow-sm focus:ring focus:ring-opacity-50` + +```php +public function configure(): void +{ + $this->setColumnSelectButtonAttributes([ + 'class' => 'focus:border-rose-300 focus:ring-1 focus:ring-rose-300 focus-visible:outline-rose-300', // Add these classes to the column select button + 'default-colors' => false, // Do not output the default colors + 'default-styling' => true // Output the default styling + ]); +} +``` + +### setColumnSelectMenuOptionCheckboxAttributes +Allows for customisation of the appearance of the "Column Select" menu option checkbox + +Note that this utilises a refreshed approach for attributes, and allows for appending to, or replacing the styles and colors independently, via the below methods. + +#### default-colors +Setting to false will disable the default colors for the Column Select menu option checkbox, the default colors are: + +Bootstrap: None + +Tailwind: `text-indigo-600 border-gray-300 focus:border-indigo-300 focus:ring-indigo-200 dark:bg-gray-900 dark:text-white dark:border-gray-600 dark:hover:bg-gray-600 dark:focus:bg-gray-600` +#### default-styling + +Setting to false will disable the default styling for the Column Select menu option checkbox, the default styling is: + +Bootstrap 4: None + +Bootstrap 5: `form-check-input` + +Tailwind: `transition duration-150 ease-in-out rounded shadow-sm focus:ring focus:ring-opacity-50 disabled:opacity-50 disabled:cursor-wait` + +```php +public function configure(): void +{ + $this->setColumnSelectMenuOptionCheckboxAttributes([ + 'class' => 'text-rose-300 focus:border-rose-300 focus:ring-rose-300', // Add these classes to the column select menu option checkbox + 'default-colors' => false, // Do not output the default colors + 'default-styling' => true // Output the default styling + ]); +} +``` diff --git a/resources/views/components/tools/toolbar/items/column-select.blade.php b/resources/views/components/tools/toolbar/items/column-select.blade.php index e239fb211..60de81110 100644 --- a/resources/views/components/tools/toolbar/items/column-select.blade.php +++ b/resources/views/components/tools/toolbar/items/column-select.blade.php @@ -1,192 +1,229 @@ -@aware([ 'tableName','isTailwind','isBootstrap','isBootstrap4','isBootstrap5']) -@if ($isTailwind) - -@elseif ($isBootstrap) -
$this->getColumnSelectIsHiddenOnMobile() && $isBootstrap4, - 'd-none d-md-block mb-3 mb-md-0 pl-0 pl-md-2' => $this->getColumnSelectIsHiddenOnTablet() && $isBootstrap4, - 'd-none d-sm-block mb-3 mb-md-0 md-0 ms-md-2' => $this->getColumnSelectIsHiddenOnMobile() && $isBootstrap5, - 'd-none d-md-block mb-3 mb-md-0 md-0 ms-md-2' => $this->getColumnSelectIsHiddenOnTablet() && $isBootstrap5, - ]) - > -
$isBootstrap, - ]) - wire:key="{{ $tableName }}-column-select-button" - > - - -
$isBootstrap4, - 'dropdown-menu dropdown-menu-end w-100' => $isBootstrap5, - ]) - aria-labelledby="columnSelect-{{ $tableName }}" - > - @if($isBootstrap4) -
- -
- @elseif($isBootstrap5) -
- getSelectableSelectedColumns()->count() == $this->getSelectableColumns()->count()) checked wire:click="deselectAllColumns" @else unchecked wire:click="selectAllColumns" @endif - /> - - -
- @endif - - @foreach ($this->getColumnsForColumnSelect() as $columnSlug => $columnTitle) -
$isBootstrap5, - ]) - > - @if ($isBootstrap4) - - @elseif($isBootstrap5) - - - @endif -
- @endforeach -
-
-
-@endif +@aware([ 'tableName','isTailwind','isBootstrap','isBootstrap4','isBootstrap5']) +@if ($isTailwind) + +@elseif ($isBootstrap) +
$this->getColumnSelectIsHiddenOnMobile() && $isBootstrap4, + 'd-none d-md-block mb-3 mb-md-0 pl-0 pl-md-2' => $this->getColumnSelectIsHiddenOnTablet() && $isBootstrap4, + 'd-none d-sm-block mb-3 mb-md-0 md-0 ms-md-2' => $this->getColumnSelectIsHiddenOnMobile() && $isBootstrap5, + 'd-none d-md-block mb-3 mb-md-0 md-0 ms-md-2' => $this->getColumnSelectIsHiddenOnTablet() && $isBootstrap5, + ]) + > +
$isBootstrap, + ]) + wire:key="{{ $tableName }}-column-select-button" + > + + +
$isBootstrap4, + 'dropdown-menu dropdown-menu-end w-100' => $isBootstrap5, + ]) + aria-labelledby="columnSelect-{{ $tableName }}" + > + @if($isBootstrap4) +
+ +
+ @elseif($isBootstrap5) +
+ merge($this->getColumnSelectMenuOptionCheckboxAttributes()) + ->class([ + 'form-check-input' => $this->getColumnSelectMenuOptionCheckboxAttributes()['default-styling'], + ]) + ->except(['default-styling', 'default-colors']) + }} + @if($this->getSelectableSelectedColumns()->count() == $this->getSelectableColumns()->count()) checked wire:click="deselectAllColumns" @else unchecked wire:click="selectAllColumns" @endif + /> + + +
+ @endif + + @foreach ($this->getColumnsForColumnSelect() as $columnSlug => $columnTitle) +
$isBootstrap5, + ]) + > + @if ($isBootstrap4) + + @elseif($isBootstrap5) + merge($this->getColumnSelectMenuOptionCheckboxAttributes()) + ->class([ + 'form-check-input' => $this->getColumnSelectMenuOptionCheckboxAttributes()['default-styling'], + ]) + ->except(['default-styling', 'default-colors']) + }} + value="{{ $columnSlug }}" + /> + + @endif +
+ @endforeach +
+
+
+@endif diff --git a/src/Traits/Styling/Configuration/ColumnSelectStylingConfiguration.php b/src/Traits/Styling/Configuration/ColumnSelectStylingConfiguration.php new file mode 100644 index 000000000..242d48d57 --- /dev/null +++ b/src/Traits/Styling/Configuration/ColumnSelectStylingConfiguration.php @@ -0,0 +1,20 @@ +columnSelectButtonAttributes = [...$this->columnSelectButtonAttributes, ...$attributes]; + + return $this; + } + + public function setColumnSelectMenuOptionCheckboxAttributes(array $attributes = []): self + { + $this->columnSelectMenuOptionCheckboxAttributes = [...$this->columnSelectMenuOptionCheckboxAttributes, ...$attributes]; + + return $this; + } +} diff --git a/src/Traits/Styling/HasColumnSelectStyling.php b/src/Traits/Styling/HasColumnSelectStyling.php new file mode 100644 index 000000000..d6b851d33 --- /dev/null +++ b/src/Traits/Styling/HasColumnSelectStyling.php @@ -0,0 +1,15 @@ + true, 'default-colors' => true, 'class' => '']; + protected array $columnSelectMenuOptionCheckboxAttributes = ['default-styling' => true, 'default-colors' => true, 'class' => '']; +} diff --git a/src/Traits/Styling/Helpers/ColumnSelectStylingHelpers.php b/src/Traits/Styling/Helpers/ColumnSelectStylingHelpers.php new file mode 100644 index 000000000..3d0d7c093 --- /dev/null +++ b/src/Traits/Styling/Helpers/ColumnSelectStylingHelpers.php @@ -0,0 +1,21 @@ +columnSelectButtonAttributes; + } + + #[Computed] + public function getColumnSelectMenuOptionCheckboxAttributes(): array + { + return $this->columnSelectMenuOptionCheckboxAttributes; + } +} diff --git a/src/Traits/WithColumnSelect.php b/src/Traits/WithColumnSelect.php index e992c72a8..0ae5364d5 100644 --- a/src/Traits/WithColumnSelect.php +++ b/src/Traits/WithColumnSelect.php @@ -7,12 +7,14 @@ use Rappasoft\LaravelLivewireTables\Traits\Configuration\ColumnSelectConfiguration; use Rappasoft\LaravelLivewireTables\Traits\Core\QueryStrings\HasQueryStringForColumnSelect; use Rappasoft\LaravelLivewireTables\Traits\Helpers\ColumnSelectHelpers; +use Rappasoft\LaravelLivewireTables\Traits\Styling\HasColumnSelectStyling; trait WithColumnSelect { use ColumnSelectConfiguration, ColumnSelectHelpers, - HasQueryStringForColumnSelect; + HasQueryStringForColumnSelect, + HasColumnSelectStyling; #[Locked] public array $columnSelectColumns = ['setupRun' => false, 'selected' => [], 'deselected' => [], 'defaultdeselected' => []]; From 19ebe02f9a86a34b7ab15107fa38972f9881a383 Mon Sep 17 00:00:00 2001 From: lrljoe <104938042+lrljoe@users.noreply.github.com> Date: Thu, 16 Jan 2025 23:51:18 +0000 Subject: [PATCH 02/24] Fix styling --- src/Traits/Styling/HasColumnSelectStyling.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Traits/Styling/HasColumnSelectStyling.php b/src/Traits/Styling/HasColumnSelectStyling.php index d6b851d33..9362c44d5 100644 --- a/src/Traits/Styling/HasColumnSelectStyling.php +++ b/src/Traits/Styling/HasColumnSelectStyling.php @@ -11,5 +11,6 @@ trait HasColumnSelectStyling ColumnSelectStylingHelpers; protected array $columnSelectButtonAttributes = ['default-styling' => true, 'default-colors' => true, 'class' => '']; + protected array $columnSelectMenuOptionCheckboxAttributes = ['default-styling' => true, 'default-colors' => true, 'class' => '']; } From 4f0c1c2ab3f9b41e2572c3526e77d0fa56a9db36 Mon Sep 17 00:00:00 2001 From: Hussam Alhennawi Date: Fri, 17 Jan 2025 23:46:53 +0400 Subject: [PATCH 03/24] Enable setting styles for filter pills (item, reset button and reset all button) as a configuration. --- docs/filters/available-component-methods.md | 94 +++++++++++++++++++ .../filter-pills/buttons/reset-all.blade.php | 61 +++++++----- .../buttons/reset-filter.blade.php | 22 +++-- .../tools/filter-pills/item.blade.php | 17 ++-- .../Core/Filters/HasFilterPillsStyling.php | 11 +++ .../FilterPillsStylingConfiguration.php | 27 ++++++ .../Helpers/FilterPillsStylingHelpers.php | 26 +++++ 7 files changed, 220 insertions(+), 38 deletions(-) create mode 100644 src/Traits/Styling/Configuration/FilterPillsStylingConfiguration.php create mode 100644 src/Traits/Styling/Helpers/FilterPillsStylingHelpers.php diff --git a/docs/filters/available-component-methods.md b/docs/filters/available-component-methods.md index 9a463edbf..bf3c51c43 100644 --- a/docs/filters/available-component-methods.md +++ b/docs/filters/available-component-methods.md @@ -121,6 +121,100 @@ public function configure(): void } ``` +## setFilterPillsItemAttributes +Allows for customisation of the appearance of the "Filter Pills Item" + +Note that this utilises a refreshed approach for attributes, and allows for appending to, or replacing the styles and colors independently, via the below methods. + +#### default-colors +Setting to false will disable the default colors for the Filter Pills Item, the default colors are: + +Bootstrap: None + +Tailwind: `bg-indigo-100 text-indigo-800 dark:bg-indigo-200 dark:text-indigo-900` + +#### default-styling +Setting to false will disable the default styling for the Filter Pills Item, the default styling is: + +Bootstrap 4: `badge badge-pill badge-info d-inline-flex align-items-center` + +Bootstrap 5: `badge rounded-pill bg-info d-inline-flex align-items-center` + +Tailwind: `inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium leading-4 capitalize` + +```php +public function configure(): void +{ + $this->setFilterPillsItemAttributes([ + 'class' => 'bg-rose-300 text-rose-800 dark:bg-indigo-200 dark:text-indigo-900', // Add these classes to the filter pills item + 'default-colors' => false, // Do not output the default colors + 'default-styling' => true // Output the default styling + ]); +} +``` + +## setFilterPillsResetFilterButtonAttributes +Allows for customisation of the appearance of the "Filter Pills Reset Filter Button" + +Note that this utilises a refreshed approach for attributes, and allows for appending to, or replacing the styles and colors independently, via the below methods. + +#### default-colors +Setting to false will disable the default colors for the Filter Pills Reset Filter Button, the default colors are: + +Bootstrap: None + +Tailwind: `text-indigo-400 hover:bg-indigo-200 hover:text-indigo-500 focus:bg-indigo-500 focus:text-white` + +#### default-styling +Setting to false will disable the default styling for the Filter Pills Reset Filter Button, the default styling is: + +Bootstrap: `text-white ml-2` + +Tailwind: `flex-shrink-0 ml-0.5 h-4 w-4 rounded-full inline-flex items-center justify-center focus:outline-none` + +```php +public function configure(): void +{ + $this->setFilterPillsResetFilterButtonAttributes([ + 'class' => 'text-rose-400 hover:bg-rose-200 hover:text-rose-500 focus:bg-rose-500', // Add these classes to the filter pills reset filter button + 'default-colors' => false, // Do not output the default colors + 'default-styling' => true // Output the default styling + ]); +} +``` + +## setFilterPillsResetAllButtonAttributes +Allows for customisation of the appearance of the "Filter Pills Reset All Button" + +Note that this utilises a refreshed approach for attributes, and allows for appending to, or replacing the styles and colors independently, via the below methods. + +#### default-colors +Setting to false will disable the default colors for the Filter Pills Reset All Button, the default colors are: + +Bootstrap: None + +Tailwind: `bg-gray-100 text-gray-800 dark:bg-gray-200 dark:text-gray-900` + +#### default-styling +Setting to false will disable the default styling for the Filter Pills Reset All Button, the default styling is: + +Bootstrap 4: `badge badge-pill badge-light` + +Bootstrap 5: `badge rounded-pill bg-light text-dark text-decoration-none` + +Tailwind: `inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium` + +```php +public function configure(): void +{ + $this->setFilterPillsResetAllButtonAttributes([ + 'class' => 'bg-rose-100 text-rose-800 dark:bg-gray-200 dark:text-gray-900', // Add these classes to the filter pills reset all button + 'default-colors' => false, // Do not output the default colors + 'default-styling' => true // Output the default styling + ]); +} +``` + --- ## setFilterLayout diff --git a/resources/views/components/tools/filter-pills/buttons/reset-all.blade.php b/resources/views/components/tools/filter-pills/buttons/reset-all.blade.php index 508c3e201..7acdc1904 100644 --- a/resources/views/components/tools/filter-pills/buttons/reset-all.blade.php +++ b/resources/views/components/tools/filter-pills/buttons/reset-all.blade.php @@ -1,25 +1,36 @@ -@aware(['isTailwind','isBootstrap','isBootstrap4','isBootstrap5']) -@if ($isTailwind) - -@else - $isBootstrap4, - 'badge rounded-pill bg-light text-dark text-decoration-none' => $isBootstrap5, - ])> - {{ __($this->getLocalisationPath.'Clear') }} - -@endif +@aware(['isTailwind','isBootstrap','isBootstrap4','isBootstrap5']) +@if ($isTailwind) + +@else + merge($this->getFilterPillsResetAllButtonAttributes()) + ->class([ + 'badge badge-pill badge-light' => $isBootstrap4 && $this->getFilterPillsResetAllButtonAttributes()['default-styling'], + 'badge rounded-pill bg-light text-dark text-decoration-none' => $isBootstrap5 && $this->getFilterPillsResetAllButtonAttributes()['default-styling'], + ]) + ->except(['default-styling', 'default-colors']) + }} + > + {{ __($this->getLocalisationPath.'Clear') }} + +@endif diff --git a/resources/views/components/tools/filter-pills/buttons/reset-filter.blade.php b/resources/views/components/tools/filter-pills/buttons/reset-filter.blade.php index c52e42a96..1a02d413e 100644 --- a/resources/views/components/tools/filter-pills/buttons/reset-filter.blade.php +++ b/resources/views/components/tools/filter-pills/buttons/reset-filter.blade.php @@ -4,10 +4,14 @@ @@ -56,14 +79,26 @@ class="focus:outline-none active:outline-none" merge($this->getSortingPillsItemAttributes()) + ->class([ + 'badge badge-pill badge-info d-inline-flex align-items-center' => $this->getSortingPillsItemAttributes()['default-styling'], + ]) + ->except(['default-styling', 'default-colors']) + }} > {{ $column->getSortingPillTitle() }}: {{ $column->getSortingPillDirectionLabel($direction, $this->getDefaultSortingLabelAsc, $this->getDefaultSortingLabelDesc) }} merge($this->getSortingPillsClearSortButtonAttributes()) + ->class([ + 'text-white ml-2' => $this->getSortingPillsClearSortButtonAttributes()['default-styling'], + ]) + ->except(['default-styling', 'default-colors']) + }} > {{ __($this->getLocalisationPath.'Remove sort option') }} @@ -74,7 +109,13 @@ class="text-white ml-2" merge($this->getSortingPillsClearAllButtonAttributes()) + ->class([ + 'badge badge-pill badge-light' => $this->getSortingPillsClearAllButtonAttributes()['default-styling'], + ]) + ->except(['default-styling', 'default-colors']) + }} > {{ __($this->getLocalisationPath.'Clear') }} @@ -96,14 +137,26 @@ class="badge badge-pill badge-light" merge($this->getSortingPillsItemAttributes()) + ->class([ + 'badge rounded-pill bg-info d-inline-flex align-items-center' => $this->getSortingPillsItemAttributes()['default-styling'], + ]) + ->except(['default-styling', 'default-colors']) + }} > {{ $column->getSortingPillTitle() }}: {{ $column->getSortingPillDirectionLabel($direction, $this->getDefaultSortingLabelAsc, $this->getDefaultSortingLabelDesc) }} merge($this->getSortingPillsClearSortButtonAttributes()) + ->class([ + 'text-white ms-2' => $this->getSortingPillsClearSortButtonAttributes()['default-styling'], + ]) + ->except(['default-styling', 'default-colors']) + }} > {{ __($this->getLocalisationPath.'Remove sort option') }} @@ -114,7 +167,13 @@ class="text-white ms-2" merge($this->getSortingPillsClearAllButtonAttributes()) + ->class([ + 'badge rounded-pill bg-light text-dark text-decoration-none' => $this->getSortingPillsClearAllButtonAttributes()['default-styling'], + ]) + ->except(['default-styling', 'default-colors']) + }} > {{ __($this->getLocalisationPath.'Clear') }} diff --git a/src/Traits/Styling/Configuration/SortingPillsStylingConfiguration.php b/src/Traits/Styling/Configuration/SortingPillsStylingConfiguration.php new file mode 100644 index 000000000..846a7a11e --- /dev/null +++ b/src/Traits/Styling/Configuration/SortingPillsStylingConfiguration.php @@ -0,0 +1,27 @@ +sortingPillsItemAttributes = [...$this->sortingPillsItemAttributes, ...$attributes]; + + return $this; + } + + public function setSortingPillsClearSortButtonAttributes(array $attributes = []): self + { + $this->sortingPillsClearSortButtonAttributes = [...$this->sortingPillsClearSortButtonAttributes, ...$attributes]; + + return $this; + } + + public function setSortingPillsClearAllButtonAttributes(array $attributes = []): self + { + $this->sortingPillsClearAllButtonAttributes = [...$this->sortingPillsClearAllButtonAttributes, ...$attributes]; + + return $this; + } +} diff --git a/src/Traits/Styling/HasSortingPillsStyling.php b/src/Traits/Styling/HasSortingPillsStyling.php new file mode 100644 index 000000000..ecb8044e3 --- /dev/null +++ b/src/Traits/Styling/HasSortingPillsStyling.php @@ -0,0 +1,18 @@ + true, 'default-colors' => true, 'class' => '']; + + protected array $sortingPillsClearSortButtonAttributes = ['default-styling' => true, 'default-colors' => true, 'class' => '']; + + protected array $sortingPillsClearAllButtonAttributes = ['default-styling' => true, 'default-colors' => true, 'class' => '']; +} diff --git a/src/Traits/Styling/Helpers/SortingPillsStylingHelpers.php b/src/Traits/Styling/Helpers/SortingPillsStylingHelpers.php new file mode 100644 index 000000000..a6d560797 --- /dev/null +++ b/src/Traits/Styling/Helpers/SortingPillsStylingHelpers.php @@ -0,0 +1,26 @@ +sortingPillsItemAttributes; + } + + #[Computed] + public function getSortingPillsClearSortButtonAttributes(): array + { + return $this->sortingPillsClearSortButtonAttributes; + } + + #[Computed] + public function getSortingPillsClearAllButtonAttributes(): array + { + return $this->sortingPillsClearAllButtonAttributes; + } +} diff --git a/src/Traits/WithSorting.php b/src/Traits/WithSorting.php index a4c093d7f..6d44fd91b 100644 --- a/src/Traits/WithSorting.php +++ b/src/Traits/WithSorting.php @@ -7,12 +7,14 @@ use Rappasoft\LaravelLivewireTables\Traits\Configuration\SortingConfiguration; use Rappasoft\LaravelLivewireTables\Traits\Core\QueryStrings\HasQueryStringForSort; use Rappasoft\LaravelLivewireTables\Traits\Helpers\SortingHelpers; +use Rappasoft\LaravelLivewireTables\Traits\Styling\HasSortingPillsStyling; trait WithSorting { use SortingConfiguration, - SortingHelpers; - use HasQueryStringForSort; + SortingHelpers, + HasQueryStringForSort, + HasSortingPillsStyling; public array $sorts = []; From 06ee93d90838759ce6b0ff4dec67c1a92019a73f Mon Sep 17 00:00:00 2001 From: Joe <104938042+lrljoe@users.noreply.github.com> Date: Sun, 19 Jan 2025 11:46:43 +0000 Subject: [PATCH 05/24] Add "after-tools" configurable area --- docs/datatable/configurable-areas.md | 1 + resources/views/datatable.blade.php | 6 ++++++ src/Traits/WithConfigurableAreas.php | 1 + 3 files changed, 8 insertions(+) diff --git a/docs/datatable/configurable-areas.md b/docs/datatable/configurable-areas.md index 4661be63b..489a42cd6 100644 --- a/docs/datatable/configurable-areas.md +++ b/docs/datatable/configurable-areas.md @@ -34,6 +34,7 @@ public function configure(): void 'toolbar-right-end' => 'path.to.my.view', 'before-toolbar' => 'path.to.my.view', 'after-toolbar' => 'path.to.my.view', + 'after-tools' => 'path.to.my.view', 'before-pagination' => 'path.to.my.view', 'after-pagination' => 'path.to.my.view', 'after-wrapper' => 'path.to.my.view', diff --git a/resources/views/datatable.blade.php b/resources/views/datatable.blade.php index 4b4feab5a..5a089ce88 100644 --- a/resources/views/datatable.blade.php +++ b/resources/views/datatable.blade.php @@ -54,6 +54,12 @@ @endif + @includeWhen( + $this->hasConfigurableAreaFor('after-tools'), + $this->getConfigurableAreaFor('after-tools'), + $this->getParametersForConfigurableArea('after-tools') + ) + diff --git a/src/Traits/WithConfigurableAreas.php b/src/Traits/WithConfigurableAreas.php index 4fcf55634..f6956484c 100644 --- a/src/Traits/WithConfigurableAreas.php +++ b/src/Traits/WithConfigurableAreas.php @@ -20,6 +20,7 @@ trait WithConfigurableAreas 'toolbar-right-end' => null, 'before-toolbar' => null, 'after-toolbar' => null, + 'after-tools' => null, 'before-pagination' => null, 'after-pagination' => null, ]; From 74f6a5fbac6ffa8e5285c566054ec48d6bcff275 Mon Sep 17 00:00:00 2001 From: Joe <104938042+lrljoe@users.noreply.github.com> Date: Sun, 19 Jan 2025 12:03:29 +0000 Subject: [PATCH 06/24] Adjust configurable areas test --- tests/Unit/Traits/Helpers/ComponentHelpersTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Unit/Traits/Helpers/ComponentHelpersTest.php b/tests/Unit/Traits/Helpers/ComponentHelpersTest.php index d9deb58f4..ffacd11ec 100644 --- a/tests/Unit/Traits/Helpers/ComponentHelpersTest.php +++ b/tests/Unit/Traits/Helpers/ComponentHelpersTest.php @@ -191,6 +191,7 @@ public function test_can_get_configurable_areas(): void 'toolbar-right-end' => null, 'before-toolbar' => null, 'after-toolbar' => null, + 'after-tools' => null, 'before-pagination' => null, 'after-pagination' => null, ], $this->basicTable->getConfigurableAreas()); From bdf338e8ccf1cded96ac378fa6ddb2d8c5faa025 Mon Sep 17 00:00:00 2001 From: Yechiel Date: Mon, 20 Jan 2025 10:42:39 -0500 Subject: [PATCH 07/24] Fix Search Field in bootstrap Flex is only for tailwind, this wa broken when splitting out the styles for the search icon --- .../views/components/tools/toolbar/items/search-field.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/components/tools/toolbar/items/search-field.blade.php b/resources/views/components/tools/toolbar/items/search-field.blade.php index 406b8e9ce..51795a70c 100644 --- a/resources/views/components/tools/toolbar/items/search-field.blade.php +++ b/resources/views/components/tools/toolbar/items/search-field.blade.php @@ -4,7 +4,7 @@ @class([ 'mb-3 mb-md-0 input-group' => $isBootstrap, 'rounded-md shadow-sm' => $isTailwind, - 'flex' => !$this->hasSearchIcon, + 'flex' => ($isTailwind && !$this->hasSearchIcon), 'relative inline-flex flex-row' => $this->hasSearchIcon, ])> From 31561e558dfae51fdc3cdaf4541f3d095dc3f7e3 Mon Sep 17 00:00:00 2001 From: LRLJoe Date: Thu, 23 Jan 2025 22:26:23 +0000 Subject: [PATCH 08/24] ConfigurableArea Test Tidying --- .../ComponentConfigurationTest.php | 20 ----- .../ConfigurableAreaConfigurationTest.php | 89 ++++++++++++++++++- .../Traits/Helpers/ComponentHelpersTest.php | 61 ------------- .../Helpers/ConfigurableAreaHelpersTest.php | 72 +++++++++++++++ 4 files changed, 158 insertions(+), 84 deletions(-) create mode 100644 tests/Unit/Traits/Helpers/ConfigurableAreaHelpersTest.php diff --git a/tests/Unit/Traits/Configuration/ComponentConfigurationTest.php b/tests/Unit/Traits/Configuration/ComponentConfigurationTest.php index bd593eeab..575dfaa7a 100644 --- a/tests/Unit/Traits/Configuration/ComponentConfigurationTest.php +++ b/tests/Unit/Traits/Configuration/ComponentConfigurationTest.php @@ -294,26 +294,6 @@ public function test_can_set_tr_url_target_advanced(): void $this->assertSame($this->basicTable->getTableRowUrlTarget(2), 'navigate'); } - public function test_can_set_hide_configurable_areas_when_reordering_status(): void - { - $this->assertTrue($this->basicTable->getHideConfigurableAreasWhenReorderingStatus()); - - $this->basicTable->setHideConfigurableAreasWhenReorderingStatus(false); - - $this->assertFalse($this->basicTable->getHideConfigurableAreasWhenReorderingStatus()); - - $this->basicTable->setHideConfigurableAreasWhenReorderingStatus(true); - - $this->assertTrue($this->basicTable->getHideConfigurableAreasWhenReorderingStatus()); - - $this->basicTable->setHideConfigurableAreasWhenReorderingDisabled(); - - $this->assertFalse($this->basicTable->getHideConfigurableAreasWhenReorderingStatus()); - - $this->basicTable->setHideConfigurableAreasWhenReorderingEnabled(); - - $this->basicTable->setHideConfigurableAreasWhenReorderingStatus(true); - } public function test_no_extra_withs_by_default(): void { diff --git a/tests/Unit/Traits/Configuration/ConfigurableAreaConfigurationTest.php b/tests/Unit/Traits/Configuration/ConfigurableAreaConfigurationTest.php index 1be72604e..2661a8061 100644 --- a/tests/Unit/Traits/Configuration/ConfigurableAreaConfigurationTest.php +++ b/tests/Unit/Traits/Configuration/ConfigurableAreaConfigurationTest.php @@ -2,16 +2,99 @@ namespace Rappasoft\LaravelLivewireTables\Tests\Unit\Traits\Configuration; +use PHPUnit\Framework\Attributes\DataProvider; use Rappasoft\LaravelLivewireTables\Tests\TestCase; final class ConfigurableAreaConfigurationTest extends TestCase { - public function test_can_set_configurable_area(): void + + public static function configurableAreaProvider(): array + { + return [ + ['before-tools', 'path.to.my.before-tools.view'], + ['toolbar-left-start', 'path.to.my.toolbar-left-start.view'], + ['toolbar-left-end', 'path.to.my.toolbar-left-end.view'], + ['toolbar-right-start', 'path.to.my.toolbar-right-start.view'], + ['toolbar-right-end', 'path.to.my.toolbar-right-end.view'], + ['before-toolbar', 'path.to.my.before-toolbar.view'], + ['after-toolbar', 'path.to.my.after-toolbar.view'], + ['after-tools', 'path.to.my.after-tools.view'], + ['before-pagination', 'path.to.my.before-pagination.view'], + ['after-pagination', 'path.to.my.after-pagination.view'], + ]; + } + + #[DataProvider('configurableAreaProvider')] + public function test_can_set_configurable_area(string $configurableArea, string $configurableAreaViewPath): void + { + $defaults = [ + 'before-tools' => null, + 'toolbar-left-start' => null, + 'toolbar-left-end' => null, + 'toolbar-right-start' => null, + 'toolbar-right-end' => null, + 'before-toolbar' => null, + 'after-toolbar' => null, + 'after-tools' => null, + 'before-pagination' => null, + 'after-pagination' => null, + ]; + $this->basicTable->setConfigurableAreas($defaults); + + $this->assertNull($this->basicTable->getConfigurableAreaFor($configurableArea)); + + $this->basicTable->setConfigurableArea($configurableArea, $configurableAreaViewPath); + + $this->assertSame($configurableAreaViewPath, $this->basicTable->getConfigurableAreaFor($configurableArea)); + } + + public function test_can_set_multiple_configurable_areas(): void { + $defaults = [ + 'before-tools' => null, + 'toolbar-left-start' => null, + 'toolbar-left-end' => null, + 'toolbar-right-start' => null, + 'toolbar-right-end' => null, + 'before-toolbar' => null, + 'after-toolbar' => null, + 'after-tools' => null, + 'before-pagination' => null, + 'after-pagination' => null, + ]; + $this->basicTable->setConfigurableAreas($defaults); + $this->assertNull($this->basicTable->getConfigurableAreaFor('before-tools')); + $this->assertNull($this->basicTable->getConfigurableAreaFor('after-toolbar')); + + $this->basicTable->setConfigurableArea('before-tools', 'path.to.before-tools.view'); + $this->assertSame('path.to.before-tools.view', $this->basicTable->getConfigurableAreaFor('before-tools')); - $this->basicTable->setConfigurableArea('before-tools', 'path.to.my.view'); + $this->basicTable->setConfigurableArea('after-toolbar', 'path.to.after-toolbar.view'); + $this->assertSame('path.to.after-toolbar.view', $this->basicTable->getConfigurableAreaFor('after-toolbar')); + $this->assertSame('path.to.before-tools.view', $this->basicTable->getConfigurableAreaFor('before-tools')); - $this->assertSame('path.to.my.view', $this->basicTable->getConfigurableAreaFor('before-tools')); } + + public function test_can_set_hide_configurable_areas_when_reordering_status(): void + { + $this->assertTrue($this->basicTable->getHideConfigurableAreasWhenReorderingStatus()); + + $this->basicTable->setHideConfigurableAreasWhenReorderingStatus(false); + + $this->assertFalse($this->basicTable->getHideConfigurableAreasWhenReorderingStatus()); + + $this->basicTable->setHideConfigurableAreasWhenReorderingStatus(true); + + $this->assertTrue($this->basicTable->getHideConfigurableAreasWhenReorderingStatus()); + + $this->basicTable->setHideConfigurableAreasWhenReorderingDisabled(); + + $this->assertFalse($this->basicTable->getHideConfigurableAreasWhenReorderingStatus()); + + $this->basicTable->setHideConfigurableAreasWhenReorderingEnabled(); + + $this->basicTable->setHideConfigurableAreasWhenReorderingStatus(true); + } + } diff --git a/tests/Unit/Traits/Helpers/ComponentHelpersTest.php b/tests/Unit/Traits/Helpers/ComponentHelpersTest.php index ffacd11ec..d1a617119 100644 --- a/tests/Unit/Traits/Helpers/ComponentHelpersTest.php +++ b/tests/Unit/Traits/Helpers/ComponentHelpersTest.php @@ -181,67 +181,6 @@ public function test_can_add_additional_selects_nonarray(): void $this->assertEquals(['name', 'updated_at'], $this->basicTable->getAdditionalSelects()); } - public function test_can_get_configurable_areas(): void - { - $this->assertEquals([ - 'before-tools' => null, - 'toolbar-left-start' => null, - 'toolbar-left-end' => null, - 'toolbar-right-start' => null, - 'toolbar-right-end' => null, - 'before-toolbar' => null, - 'after-toolbar' => null, - 'after-tools' => null, - 'before-pagination' => null, - 'after-pagination' => null, - ], $this->basicTable->getConfigurableAreas()); - - $this->basicTable->setConfigurableAreas([ - 'toolbar-left-start' => 'includes.areas.toolbar-left-start', - ]); - - $this->assertEquals('includes.areas.toolbar-left-start', $this->basicTable->getConfigurableAreaFor('toolbar-left-start')); - - $this->basicTable->setConfigurableAreas([ - 'toolbar-left-start' => ['includes.areas.toolbar-left-start', ['param1' => 'hello']], - ]); - - $this->assertEquals('includes.areas.toolbar-left-start', $this->basicTable->getConfigurableAreaFor('toolbar-left-start')); - } - - public function test_can_get_configurable_area_parameters(): void - { - $this->basicTable->setConfigurableAreas([ - 'toolbar-left-start' => 'includes.areas.toolbar-left-start', - ]); - - $this->assertEquals([], $this->basicTable->getParametersForConfigurableArea('toolbar-left-start')); - - $this->basicTable->setConfigurableAreas([ - 'toolbar-left-start' => ['includes.areas.toolbar-left-start', ['param1' => 'hello']], - ]); - - $this->assertEquals(['param1' => 'hello'], $this->basicTable->getParametersForConfigurableArea('toolbar-left-start')); - } - - public function test_can_get_hide_configurable_areas_when_reordering_status(): void - { - $this->assertTrue($this->basicTable->getHideConfigurableAreasWhenReorderingStatus()); - - $this->assertTrue($this->basicTable->hideConfigurableAreasWhenReorderingIsEnabled()); - - $this->basicTable->setHideConfigurableAreasWhenReorderingDisabled(); - - $this->assertTrue($this->basicTable->hideConfigurableAreasWhenReorderingIsDisabled()); - - $this->assertFalse($this->basicTable->hideConfigurableAreasWhenReorderingIsEnabled()); - - $this->basicTable->setHideConfigurableAreasWhenReorderingEnabled(); - - $this->assertTrue($this->basicTable->hideConfigurableAreasWhenReorderingIsEnabled()); - - $this->assertFalse($this->basicTable->hideConfigurableAreasWhenReorderingIsDisabled()); - } // Exists in DataTableComponentTest // public function test_can_get_dataTable_fingerprint(): void diff --git a/tests/Unit/Traits/Helpers/ConfigurableAreaHelpersTest.php b/tests/Unit/Traits/Helpers/ConfigurableAreaHelpersTest.php new file mode 100644 index 000000000..924fcbfab --- /dev/null +++ b/tests/Unit/Traits/Helpers/ConfigurableAreaHelpersTest.php @@ -0,0 +1,72 @@ +assertEquals([ + 'before-tools' => null, + 'toolbar-left-start' => null, + 'toolbar-left-end' => null, + 'toolbar-right-start' => null, + 'toolbar-right-end' => null, + 'before-toolbar' => null, + 'after-toolbar' => null, + 'after-tools' => null, + 'before-pagination' => null, + 'after-pagination' => null, + ], $this->basicTable->getConfigurableAreas()); + + $this->basicTable->setConfigurableAreas([ + 'toolbar-left-start' => 'includes.areas.toolbar-left-start', + ]); + + $this->assertEquals('includes.areas.toolbar-left-start', $this->basicTable->getConfigurableAreaFor('toolbar-left-start')); + + $this->basicTable->setConfigurableAreas([ + 'toolbar-left-start' => ['includes.areas.toolbar-left-start', ['param1' => 'hello']], + ]); + + $this->assertEquals('includes.areas.toolbar-left-start', $this->basicTable->getConfigurableAreaFor('toolbar-left-start')); + } + + public function test_can_get_configurable_area_parameters(): void + { + $this->basicTable->setConfigurableAreas([ + 'toolbar-left-start' => 'includes.areas.toolbar-left-start', + ]); + + $this->assertEquals([], $this->basicTable->getParametersForConfigurableArea('toolbar-left-start')); + + $this->basicTable->setConfigurableAreas([ + 'toolbar-left-start' => ['includes.areas.toolbar-left-start', ['param1' => 'hello']], + ]); + + $this->assertEquals(['param1' => 'hello'], $this->basicTable->getParametersForConfigurableArea('toolbar-left-start')); + } + + public function test_can_get_hide_configurable_areas_when_reordering_status(): void + { + $this->assertTrue($this->basicTable->getHideConfigurableAreasWhenReorderingStatus()); + + $this->assertTrue($this->basicTable->hideConfigurableAreasWhenReorderingIsEnabled()); + + $this->basicTable->setHideConfigurableAreasWhenReorderingDisabled(); + + $this->assertTrue($this->basicTable->hideConfigurableAreasWhenReorderingIsDisabled()); + + $this->assertFalse($this->basicTable->hideConfigurableAreasWhenReorderingIsEnabled()); + + $this->basicTable->setHideConfigurableAreasWhenReorderingEnabled(); + + $this->assertTrue($this->basicTable->hideConfigurableAreasWhenReorderingIsEnabled()); + + $this->assertFalse($this->basicTable->hideConfigurableAreasWhenReorderingIsDisabled()); + } + +} \ No newline at end of file From 731349b0c6298b25c038385583c9dfa9a024d7fe Mon Sep 17 00:00:00 2001 From: lrljoe <104938042+lrljoe@users.noreply.github.com> Date: Thu, 23 Jan 2025 22:27:02 +0000 Subject: [PATCH 09/24] Fix styling --- tests/Unit/Traits/Configuration/ComponentConfigurationTest.php | 1 - .../Traits/Configuration/ConfigurableAreaConfigurationTest.php | 2 -- tests/Unit/Traits/Helpers/ComponentHelpersTest.php | 1 - tests/Unit/Traits/Helpers/ConfigurableAreaHelpersTest.php | 3 +-- 4 files changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/Unit/Traits/Configuration/ComponentConfigurationTest.php b/tests/Unit/Traits/Configuration/ComponentConfigurationTest.php index 575dfaa7a..901bb04d1 100644 --- a/tests/Unit/Traits/Configuration/ComponentConfigurationTest.php +++ b/tests/Unit/Traits/Configuration/ComponentConfigurationTest.php @@ -294,7 +294,6 @@ public function test_can_set_tr_url_target_advanced(): void $this->assertSame($this->basicTable->getTableRowUrlTarget(2), 'navigate'); } - public function test_no_extra_withs_by_default(): void { $this->assertFalse($this->basicTable->hasExtraWiths()); diff --git a/tests/Unit/Traits/Configuration/ConfigurableAreaConfigurationTest.php b/tests/Unit/Traits/Configuration/ConfigurableAreaConfigurationTest.php index 2661a8061..fd8265783 100644 --- a/tests/Unit/Traits/Configuration/ConfigurableAreaConfigurationTest.php +++ b/tests/Unit/Traits/Configuration/ConfigurableAreaConfigurationTest.php @@ -7,7 +7,6 @@ final class ConfigurableAreaConfigurationTest extends TestCase { - public static function configurableAreaProvider(): array { return [ @@ -96,5 +95,4 @@ public function test_can_set_hide_configurable_areas_when_reordering_status(): v $this->basicTable->setHideConfigurableAreasWhenReorderingStatus(true); } - } diff --git a/tests/Unit/Traits/Helpers/ComponentHelpersTest.php b/tests/Unit/Traits/Helpers/ComponentHelpersTest.php index d1a617119..9a7307c0b 100644 --- a/tests/Unit/Traits/Helpers/ComponentHelpersTest.php +++ b/tests/Unit/Traits/Helpers/ComponentHelpersTest.php @@ -181,7 +181,6 @@ public function test_can_add_additional_selects_nonarray(): void $this->assertEquals(['name', 'updated_at'], $this->basicTable->getAdditionalSelects()); } - // Exists in DataTableComponentTest // public function test_can_get_dataTable_fingerprint(): void // { diff --git a/tests/Unit/Traits/Helpers/ConfigurableAreaHelpersTest.php b/tests/Unit/Traits/Helpers/ConfigurableAreaHelpersTest.php index 924fcbfab..22ef65970 100644 --- a/tests/Unit/Traits/Helpers/ConfigurableAreaHelpersTest.php +++ b/tests/Unit/Traits/Helpers/ConfigurableAreaHelpersTest.php @@ -68,5 +68,4 @@ public function test_can_get_hide_configurable_areas_when_reordering_status(): v $this->assertFalse($this->basicTable->hideConfigurableAreasWhenReorderingIsDisabled()); } - -} \ No newline at end of file +} From 9259ceb501de4009bc5faf9b7dac5ad1241b5362 Mon Sep 17 00:00:00 2001 From: Joe <104938042+lrljoe@users.noreply.github.com> Date: Fri, 24 Jan 2025 01:04:13 +0000 Subject: [PATCH 10/24] Add PHPDoc --- .../Configuration/ConfigurableAreasConfiguration.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Traits/Configuration/ConfigurableAreasConfiguration.php b/src/Traits/Configuration/ConfigurableAreasConfiguration.php index 043c2964c..401704b53 100644 --- a/src/Traits/Configuration/ConfigurableAreasConfiguration.php +++ b/src/Traits/Configuration/ConfigurableAreasConfiguration.php @@ -5,6 +5,8 @@ trait ConfigurableAreasConfiguration { /** + * Set all configurable areas to this array of configuration data + * * @param array $areas */ public function setConfigurableAreas(array $areas): self @@ -14,6 +16,12 @@ public function setConfigurableAreas(array $areas): self return $this; } + /** + * Configure a specific Configurable Area + * + * @param string $configurableArea + * @param array $config + */ public function setConfigurableArea(string $configurableArea, mixed $config): self { if (array_key_exists($configurableArea, $this->configurableAreas)) { From 880f583b0aeb841e1a6bf85a5efc9c0259d1ea36 Mon Sep 17 00:00:00 2001 From: lrljoe <104938042+lrljoe@users.noreply.github.com> Date: Fri, 24 Jan 2025 01:04:44 +0000 Subject: [PATCH 11/24] Fix styling --- src/Traits/Configuration/ConfigurableAreasConfiguration.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Traits/Configuration/ConfigurableAreasConfiguration.php b/src/Traits/Configuration/ConfigurableAreasConfiguration.php index 401704b53..aa3f7def6 100644 --- a/src/Traits/Configuration/ConfigurableAreasConfiguration.php +++ b/src/Traits/Configuration/ConfigurableAreasConfiguration.php @@ -6,7 +6,7 @@ trait ConfigurableAreasConfiguration { /** * Set all configurable areas to this array of configuration data - * + * * @param array $areas */ public function setConfigurableAreas(array $areas): self @@ -18,8 +18,7 @@ public function setConfigurableAreas(array $areas): self /** * Configure a specific Configurable Area - * - * @param string $configurableArea + * * @param array $config */ public function setConfigurableArea(string $configurableArea, mixed $config): self From 424ab845b3ceadf8e3944016b1a277429d132c36 Mon Sep 17 00:00:00 2001 From: Joe <104938042+lrljoe@users.noreply.github.com> Date: Fri, 24 Jan 2025 01:52:39 +0000 Subject: [PATCH 12/24] Filter Trait - Reorganization (#2181) * Initial Commits * Fix styling * Fix namespace * Fix styling * Remove superfluous filter traits * Fixes for Filter Trait Tidy Up * Fix styling * Tweaks for Lazy Tables & Tidying Item * Roll back to allow HTML separator * Add tests for new methods * Fix styling * Remove duplicate traits * Add additional tests * Add filter slidedown tests * Fix styling * Add Filter Slidedown Row Test * Fix styling * Test Adjustments * Add test for filter slidedown row * Fix styling * Merging * Add setFilterDefaultValue Test * Fix styling --- .../components/tools/filter-pills.blade.php | 55 +++-- .../tools/filter-pills/item.blade.php | 10 +- resources/views/datatable.blade.php | 208 ++++++++--------- .../Configuration/FilterConfiguration.php | 5 - .../Core/Filters/HandlesFilterTraits.php | 14 -- .../Core/Filters/HasFilterGenericData.php | 36 --- .../Core/Filters/HasFilterMenuStyling.php | 212 ------------------ .../Core/Filters/HasFilterPillsStyling.php | 73 ------ src/Traits/Core/Filters/HasFiltersStatus.php | 47 ---- src/Traits/Core/HasCustomAttributes.php | 25 +++ .../Configuration/FilterConfiguration.php} | 83 +++++-- .../FilterGenericDataConfiguration.php | 18 ++ .../Configuration/FilterMenuConfiguration.php | 46 ++++ .../FilterPillsConfiguration.php | 23 ++ .../FilterStatusConfiguration.php | 23 ++ .../FilterVisibilityConfiguration.php | 23 ++ src/Traits/Filters/HasFilterGenericData.php | 14 ++ src/Traits/Filters/HasFilterMenu.php | 21 ++ src/Traits/Filters/HasFilterPills.php | 18 ++ .../Filters/HasFilterQueryString.php | 36 +-- src/Traits/Filters/HasFiltersStatus.php | 16 ++ src/Traits/Filters/HasFiltersVisibility.php | 16 ++ .../Helpers/FilterGenericDataHelpers.php | 23 ++ .../{ => Filters}/Helpers/FilterHelpers.php | 76 +------ .../Filters/Helpers/FilterMenuHelpers.php | 81 +++++++ .../Filters/Helpers/FilterPillsHelpers.php | 38 ++++ .../Filters/Helpers/FilterStatusHelpers.php | 24 ++ .../Helpers/FilterVisibilityHelpers.php} | 29 +-- src/Traits/Filters/ManagesFilters.php | 37 +++ .../FilterMenuStylingConfiguration.php | 34 +++ .../FilterPillsStylingConfiguration.php | 21 ++ .../Filters/Styling/HasFilterMenuStyling.php | 19 ++ .../Filters/Styling/HasFilterPillsStyling.php | 18 ++ .../Helpers/FilterMenuStylingHelpers.php | 48 ++++ .../Helpers/FilterPillsStylingHelpers.php | 26 +++ src/Traits/WithFilters.php | 20 +- src/Traits/WithQueryString.php | 2 +- .../Configuration/FilterConfigurationTest.php | 24 +- .../QueryStringForFiltersTest.php | 3 + .../Traits/Filters/FilterDefaultValueTest.php | 45 ++++ tests/Unit/Traits/Filters/FilterMenuTest.php | 200 +++++++++++++++++ tests/Unit/Traits/Filters/FilterPillsTest.php | 131 +++++++++++ .../Unit/Traits/Helpers/FilterHelpersTest.php | 19 ++ .../Styling/FilterPopoverStylingTest.php | 8 +- 44 files changed, 1251 insertions(+), 697 deletions(-) delete mode 100644 src/Traits/Configuration/FilterConfiguration.php delete mode 100644 src/Traits/Core/Filters/HandlesFilterTraits.php delete mode 100644 src/Traits/Core/Filters/HasFilterGenericData.php delete mode 100644 src/Traits/Core/Filters/HasFilterMenuStyling.php delete mode 100644 src/Traits/Core/Filters/HasFilterPillsStyling.php delete mode 100644 src/Traits/Core/Filters/HasFiltersStatus.php rename src/Traits/{Core/Filters/ManagesFilters.php => Filters/Configuration/FilterConfiguration.php} (51%) create mode 100644 src/Traits/Filters/Configuration/FilterGenericDataConfiguration.php create mode 100644 src/Traits/Filters/Configuration/FilterMenuConfiguration.php create mode 100644 src/Traits/Filters/Configuration/FilterPillsConfiguration.php create mode 100644 src/Traits/Filters/Configuration/FilterStatusConfiguration.php create mode 100644 src/Traits/Filters/Configuration/FilterVisibilityConfiguration.php create mode 100644 src/Traits/Filters/HasFilterGenericData.php create mode 100644 src/Traits/Filters/HasFilterMenu.php create mode 100644 src/Traits/Filters/HasFilterPills.php rename src/Traits/{Core => }/Filters/HasFilterQueryString.php (58%) create mode 100644 src/Traits/Filters/HasFiltersStatus.php create mode 100644 src/Traits/Filters/HasFiltersVisibility.php create mode 100644 src/Traits/Filters/Helpers/FilterGenericDataHelpers.php rename src/Traits/{ => Filters}/Helpers/FilterHelpers.php (55%) create mode 100644 src/Traits/Filters/Helpers/FilterMenuHelpers.php create mode 100644 src/Traits/Filters/Helpers/FilterPillsHelpers.php create mode 100644 src/Traits/Filters/Helpers/FilterStatusHelpers.php rename src/Traits/{Core/Filters/HasFiltersVisibility.php => Filters/Helpers/FilterVisibilityHelpers.php} (59%) create mode 100644 src/Traits/Filters/ManagesFilters.php create mode 100644 src/Traits/Filters/Styling/Configuration/FilterMenuStylingConfiguration.php create mode 100644 src/Traits/Filters/Styling/Configuration/FilterPillsStylingConfiguration.php create mode 100644 src/Traits/Filters/Styling/HasFilterMenuStyling.php create mode 100644 src/Traits/Filters/Styling/HasFilterPillsStyling.php create mode 100644 src/Traits/Filters/Styling/Helpers/FilterMenuStylingHelpers.php create mode 100644 src/Traits/Filters/Styling/Helpers/FilterPillsStylingHelpers.php create mode 100644 tests/Unit/Traits/Filters/FilterDefaultValueTest.php create mode 100644 tests/Unit/Traits/Filters/FilterMenuTest.php create mode 100644 tests/Unit/Traits/Filters/FilterPillsTest.php diff --git a/resources/views/components/tools/filter-pills.blade.php b/resources/views/components/tools/filter-pills.blade.php index c0817ea97..613c5b906 100644 --- a/resources/views/components/tools/filter-pills.blade.php +++ b/resources/views/components/tools/filter-pills.blade.php @@ -1,33 +1,30 @@ @aware([ 'tableName','isTailwind','isBootstrap','isBootstrap4','isBootstrap5']) -@if ($this->filtersAreEnabled() && $this->filterPillsAreEnabled() && $this->hasAppliedVisibleFiltersForPills()) -
-
$isTailwind, - 'mb-3' => $isBootstrap, - ]) x-cloak x-show="!currentlyReorderingStatus"> - $isTailwind, - '' => $isBootstrap, - ])> - {{ __($this->getLocalisationPath.'Applied Filters') }}: - +
+
$isTailwind, + 'mb-3' => $isBootstrap, + ]) x-cloak x-show="!currentlyReorderingStatus"> + $isTailwind, + '' => $isBootstrap, + ])> + {{ __($this->getLocalisationPath.'Applied Filters') }}: + - @foreach($this->getAppliedFiltersWithValues() as $filterSelectName => $value) - @php($filter = $this->getFilterByKey($filterSelectName)) - @continue(is_null($filter) || $filter->isHiddenFromPills()) - @php( $filterPillTitle = $filter->getFilterPillTitle()) - @php( $filterPillValue = $filter->getFilterPillValue($value)) - @php( $separator = method_exists($filter, 'getPillsSeparator') ? $filter->getPillsSeparator() : ', ') - @continue((is_array($filterPillValue) && empty($filterPillValue))) - - @if ($filter->hasCustomPillBlade()) - @include($filter->getCustomPillBlade(), ['filter' => $filter]) - @else - - @endif - @endforeach - -
+ @tableloop($this->getAppliedFiltersWithValues() as $filterSelectName => $value) + @php($filter = $this->getFilterByKey($filterSelectName)) + @continue(is_null($filter) || $filter->isHiddenFromPills()) + @php( $filterPillValue = $filter->getFilterPillValue($value)) + @continue((is_array($filterPillValue) && empty($filterPillValue))) + @php( $filterPillTitle = $filter->getFilterPillTitle()) + @php( $separator = method_exists($filter, 'getPillsSeparator') ? $filter->getPillsSeparator() : ', ') + @if ($filter->hasCustomPillBlade()) + @include($filter->getCustomPillBlade(), ['filter' => $filter]) + @else + + @endif + @endtableloop +
-@endif +
diff --git a/resources/views/components/tools/filter-pills/item.blade.php b/resources/views/components/tools/filter-pills/item.blade.php index 110766238..740c86512 100644 --- a/resources/views/components/tools/filter-pills/item.blade.php +++ b/resources/views/components/tools/filter-pills/item.blade.php @@ -3,12 +3,12 @@ merge($this->getFilterPillsItemAttributes()) + $attributes->merge($this->getFilterPillsItemAttributes) ->class([ - 'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium leading-4 capitalize' => $isTailwind && $this->getFilterPillsItemAttributes()['default-styling'], - 'bg-indigo-100 text-indigo-800 dark:bg-indigo-200 dark:text-indigo-900' => $isTailwind && $this->getFilterPillsItemAttributes()['default-colors'], - 'badge badge-pill badge-info d-inline-flex align-items-center' => $isBootstrap4 && $this->getFilterPillsItemAttributes()['default-styling'], - 'badge rounded-pill bg-info d-inline-flex align-items-center' => $isBootstrap5 && $this->getFilterPillsItemAttributes()['default-styling'], + 'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium leading-4 capitalize' => $isTailwind && $this->getFilterPillsItemAttributes['default-styling'], + 'bg-indigo-100 text-indigo-800 dark:bg-indigo-200 dark:text-indigo-900' => $isTailwind && $this->getFilterPillsItemAttributes['default-colors'], + 'badge badge-pill badge-info d-inline-flex align-items-center' => $isBootstrap4 && $this->getFilterPillsItemAttributes['default-styling'], + 'badge rounded-pill bg-info d-inline-flex align-items-center' => $isBootstrap5 && $this->getFilterPillsItemAttributes['default-styling'], ]) ->except(['default-styling', 'default-colors']) }} diff --git a/resources/views/datatable.blade.php b/resources/views/datatable.blade.php index 5a089ce88..2fb08a7b9 100644 --- a/resources/views/datatable.blade.php +++ b/resources/views/datatable.blade.php @@ -7,139 +7,141 @@ @php($isBootstrap5 = $this->isBootstrap5)
-
getTopLevelAttributes() }}> - - @includeWhen( - $this->hasConfigurableAreaFor('before-wrapper'), - $this->getConfigurableAreaFor('before-wrapper'), - $this->getParametersForConfigurableArea('before-wrapper') - ) - - - @if($this->hasActions && !$this->showActionsInToolbar) - - @endif +
+
getTopLevelAttributes() }}> @includeWhen( - $this->hasConfigurableAreaFor('before-tools'), - $this->getConfigurableAreaFor('before-tools'), - $this->getParametersForConfigurableArea('before-tools') + $this->hasConfigurableAreaFor('before-wrapper'), + $this->getConfigurableAreaFor('before-wrapper'), + $this->getParametersForConfigurableArea('before-wrapper') ) - @if($this->shouldShowTools) - - @if ($this->showSortPillsSection) - - @endif - @if($this->showFilterPillsSection) - + + @if($this->hasActions && !$this->showActionsInToolbar) + @endif @includeWhen( - $this->hasConfigurableAreaFor('before-toolbar'), - $this->getConfigurableAreaFor('before-toolbar'), - $this->getParametersForConfigurableArea('before-toolbar') + $this->hasConfigurableAreaFor('before-tools'), + $this->getConfigurableAreaFor('before-tools'), + $this->getParametersForConfigurableArea('before-tools') ) - @if($this->shouldShowToolBar) - - @endif - - @includeWhen( - $this->hasConfigurableAreaFor('after-toolbar'), - $this->getConfigurableAreaFor('after-toolbar'), - $this->getParametersForConfigurableArea('after-toolbar') - ) - - - @endif - - @includeWhen( - $this->hasConfigurableAreaFor('after-tools'), - $this->getConfigurableAreaFor('after-tools'), - $this->getParametersForConfigurableArea('after-tools') - ) + @if($this->shouldShowTools) + + @if ($this->showSortPillsSection) + + @endif + @if($this->showFilterPillsSection) + + @endif - + @includeWhen( + $this->hasConfigurableAreaFor('before-toolbar'), + $this->getConfigurableAreaFor('before-toolbar'), + $this->getParametersForConfigurableArea('before-toolbar') + ) - - @if($this->getCurrentlyReorderingStatus) - - @endif - @if($this->showBulkActionsSections) - - @endif - @if ($this->showCollapsingColumnSections) - - @endif + @if($this->shouldShowToolBar) + + @endif - @foreach($this->selectedVisibleColumns as $index => $column) - - @endforeach - + @includeWhen( + $this->hasConfigurableAreaFor('after-toolbar'), + $this->getConfigurableAreaFor('after-toolbar'), + $this->getParametersForConfigurableArea('after-toolbar') + ) - @if($this->secondaryHeaderIsEnabled() && $this->hasColumnsWithSecondaryHeader()) - - @endif - @if($this->hasDisplayLoadingPlaceholder()) - + @endif - @if($this->showBulkActionsSections) - - @endif + @includeWhen( + $this->hasConfigurableAreaFor('after-tools'), + $this->getConfigurableAreaFor('after-tools'), + $this->getParametersForConfigurableArea('after-tools') + ) + + - @forelse ($this->getRows as $rowIndex => $row) - + @if($this->getCurrentlyReorderingStatus) - + @endif @if($this->showBulkActionsSections) - + @endif @if ($this->showCollapsingColumnSections) - + @endif - @foreach($this->selectedVisibleColumns as $colIndex => $column) - - @if($column->isHtml()) - {!! $column->setIndexes($rowIndex, $colIndex)->renderContents($row) !!} - @else - {{ $column->setIndexes($rowIndex, $colIndex)->renderContents($row) }} - @endif - + @foreach($this->selectedVisibleColumns as $index => $column) + @endforeach - + + + @if($this->secondaryHeaderIsEnabled() && $this->hasColumnsWithSecondaryHeader()) + + @endif + @if($this->hasDisplayLoadingPlaceholder()) + + @endif - @if ($this->showCollapsingColumnSections) - + @if($this->showBulkActionsSections) + @endif - @empty - - @endforelse - - @if ($this->footerIsEnabled() && $this->hasColumnsWithFooter()) - - @if ($this->useHeaderAsFooterIsEnabled()) - - @else - + + @forelse ($this->getRows as $rowIndex => $row) + + @if($this->getCurrentlyReorderingStatus) + + @endif + @if($this->showBulkActionsSections) + + @endif + @if ($this->showCollapsingColumnSections) + + @endif + + @foreach($this->selectedVisibleColumns as $colIndex => $column) + + @if($column->isHtml()) + {!! $column->setIndexes($rowIndex, $colIndex)->renderContents($row) !!} + @else + {{ $column->setIndexes($rowIndex, $colIndex)->renderContents($row) }} + @endif + + @endforeach + + + @if ($this->showCollapsingColumnSections) + @endif - - @endif - + @empty + + @endforelse + + @if ($this->footerIsEnabled() && $this->hasColumnsWithFooter()) + + @if ($this->useHeaderAsFooterIsEnabled()) + + @else + + @endif + + @endif + - + - @includeIf($customView) - + @includeIf($customView) + - @includeWhen( - $this->hasConfigurableAreaFor('after-wrapper'), - $this->getConfigurableAreaFor('after-wrapper'), - $this->getParametersForConfigurableArea('after-wrapper') - ) + @includeWhen( + $this->hasConfigurableAreaFor('after-wrapper'), + $this->getConfigurableAreaFor('after-wrapper'), + $this->getParametersForConfigurableArea('after-wrapper') + ) +
diff --git a/src/Traits/Configuration/FilterConfiguration.php b/src/Traits/Configuration/FilterConfiguration.php deleted file mode 100644 index 059637361..000000000 --- a/src/Traits/Configuration/FilterConfiguration.php +++ /dev/null @@ -1,5 +0,0 @@ -getTableName(), $this->getFilterLayout(), $this->isTailwind(), $this->isBootstrap4(), $this->isBootstrap5()))->toArray(); - } - - public function setFilterGenericData(array $filterGenericData = []): void - { - $this->filterGenericData = $filterGenericData; - } - - public function hasFilterGenericData(): bool - { - return ! empty($this->filterGenericData); - } - - #[Computed] - public function getFilterGenericData(): array - { - if (! $this->hasFilterGenericData()) { - $this->setFilterGenericData($this->generateFilterGenericData()); - } - - return $this->filterGenericData; - } -} diff --git a/src/Traits/Core/Filters/HasFilterMenuStyling.php b/src/Traits/Core/Filters/HasFilterMenuStyling.php deleted file mode 100644 index cf511e8cd..000000000 --- a/src/Traits/Core/Filters/HasFilterMenuStyling.php +++ /dev/null @@ -1,212 +0,0 @@ - '', 'default-width' => true, 'default-colors' => true, 'default-styling' => true]; - - protected array $filterSlidedownWrapperAttributes = ['class' => '', 'default-colors' => true, 'default-styling' => true]; - - protected ?Closure $filterSlidedownRowCallback; - - /** - * Used to set attributes for the Filter Popover - */ - public function setFilterPopoverAttributes(array $filterPopoverAttributes): self - { - $this->filterPopoverAttributes = array_merge($this->filterPopoverAttributes, $filterPopoverAttributes); - - return $this; - } - - /** - * Used to set attributes for the Filter Slidedown Wrapper - */ - public function setFilterSlidedownWrapperAttributes(array $filterSlidedownWrapperAttributes): self - { - $this->filterSlidedownWrapperAttributes = array_merge($this->filterSlidedownWrapperAttributes, $filterSlidedownWrapperAttributes); - - return $this; - } - - /** - * Set a list of attributes to override on the th sort button elements - */ - public function setFilterSlidedownRowAttributes(Closure $callback): self - { - $this->filterSlidedownRowCallback = $callback; - - return $this; - } - - public function setFilterLayout(string $type): self - { - if (! in_array($type, ['popover', 'slide-down'], true)) { - throw new DataTableConfigurationException('Invalid filter layout type'); - } - - $this->filterLayout = $type; - - return $this; - } - - public function setFilterLayoutPopover(): self - { - $this->setFilterLayout('popover'); - - return $this; - } - - public function setFilterLayoutSlideDown(): self - { - $this->setFilterLayout('slide-down'); - - return $this; - } - - public function setFilterSlideDownDefaultStatus(bool $status): self - { - $this->filterSlideDownDefaultVisible = $status; - - return $this; - } - - public function setFilterSlideDownDefaultStatusDisabled(): self - { - $this->setFilterSlideDownDefaultStatus(false); - - return $this; - } - - public function setFilterSlideDownDefaultStatusEnabled(): self - { - $this->setFilterSlideDownDefaultStatus(true); - - return $this; - } - - /** - * Used to get attributes for the Filter Popover - * - * @return array - */ - #[Computed] - public function getFilterPopoverAttributes(): array - { - return $this->filterPopoverAttributes; - - } - - /** - * Used to get attributes for the Filter Slidedown Wrapper - * - * @return array - */ - #[Computed] - public function getFilterSlidedownWrapperAttributes(): array - { - return $this->filterSlidedownWrapperAttributes; - - } - - /** - * Used to get attributes for the Filter Slidedown Row - * - * @return array - */ - #[Computed] - public function getFilterSlidedownRowAttributes(string $rowIndex): array - { - - if (isset($this->filterSlidedownRowCallback)) { - return array_merge(['class' => '', 'default-colors' => true, 'default-styling' => true, 'row' => (int) $rowIndex], call_user_func($this->filterSlidedownRowCallback, (int) $rowIndex)); - } - - return ['class' => '', 'default-colors' => true, 'default-styling' => true, 'row' => (int) $rowIndex]; - } - - public function getFilterSlideDownDefaultStatus(): bool - { - return $this->filterSlideDownDefaultVisible; - } - - public function filtersSlideDownIsDefaultVisible(): bool - { - return $this->getFilterSlideDownDefaultStatus() === true; - } - - public function filtersSlideDownIsDefaultHidden(): bool - { - return $this->getFilterSlideDownDefaultStatus() === false; - } - - public function getFilterLayout(): string - { - return $this->filterLayout; - } - - public function isFilterLayoutPopover(): bool - { - return $this->getFilterLayout() === 'popover'; - } - - public function isFilterLayoutSlideDown(): bool - { - return $this->getFilterLayout() === 'slide-down'; - } - - /** - * Get whether any filter has a configured slide down row. - */ - public function hasFiltersWithSlidedownRows(): bool - { - return $this->getFilters() - ->reject(fn (Filter $filter) => ! $filter->hasFilterSlidedownRow()) - ->count() > 0; - } - - /** - * Get filters sorted by row - * - * @return array - */ - public function getFiltersByRow(): array - { - $orderedFilters = []; - $filterList = ($this->hasFiltersWithSlidedownRows()) ? $this->getVisibleFilters()->sortBy('filterSlidedownRow') : $this->getVisibleFilters(); - if ($this->hasFiltersWithSlidedownRows()) { - foreach ($filterList as $filter) { - $orderedFilters[(string) $filter->getFilterSlidedownRow()][] = $filter; - } - - if (empty($orderedFilters['1'])) { - $orderedFilters['1'] = (isset($orderedFilters['99']) ? $orderedFilters['99'] : []); - if (isset($orderedFilters['99'])) { - unset($orderedFilters['99']); - } - } - } else { - $orderedFilters = Arr::wrap($filterList); - $orderedFilters['1'] = $orderedFilters['0'] ?? []; - if (isset($orderedFilters['0'])) { - unset($orderedFilters['0']); - } - } - ksort($orderedFilters); - - return $orderedFilters; - } -} diff --git a/src/Traits/Core/Filters/HasFilterPillsStyling.php b/src/Traits/Core/Filters/HasFilterPillsStyling.php deleted file mode 100644 index 907dec0b2..000000000 --- a/src/Traits/Core/Filters/HasFilterPillsStyling.php +++ /dev/null @@ -1,73 +0,0 @@ - true, 'default-colors' => true, 'class' => '']; - - protected array $filterPillsResetFilterButtonAttributes = ['default-styling' => true, 'default-colors' => true, 'class' => '']; - - protected array $filterPillsResetAllButtonAttributes = ['default-styling' => true, 'default-colors' => true, 'class' => '']; - - public function setFilterPillsStatus(bool $status): self - { - $this->filterPillsStatus = $status; - - return $this; - } - - public function setFilterPillsEnabled(): self - { - $this->setFilterPillsStatus(true); - - return $this; - } - - public function setFilterPillsDisabled(): self - { - $this->setFilterPillsStatus(false); - - return $this; - } - - #[Computed] - public function showFilterPillsSection(): bool - { - return $this->filtersAreEnabled() && $this->filterPillsAreEnabled() && $this->hasAppliedVisibleFiltersForPills(); - } - - public function getFilterPillsStatus(): bool - { - return $this->filterPillsStatus; - } - - public function filterPillsAreEnabled(): bool - { - return $this->getFilterPillsStatus() === true; - } - - public function filterPillsAreDisabled(): bool - { - return $this->getFilterPillsStatus() === false; - } - - public function hasAppliedVisibleFiltersForPills(): bool - { - return collect($this->getAppliedFiltersWithValues()) - ->map(fn ($_item, $key) => $this->getFilterByKey($key)) - ->reject(fn (Filter $filter) => $filter->isHiddenFromPills()) - ->count() > 0; - } -} diff --git a/src/Traits/Core/Filters/HasFiltersStatus.php b/src/Traits/Core/Filters/HasFiltersStatus.php deleted file mode 100644 index 9558b896f..000000000 --- a/src/Traits/Core/Filters/HasFiltersStatus.php +++ /dev/null @@ -1,47 +0,0 @@ -filtersStatus; - } - - public function filtersAreEnabled(): bool - { - return $this->getFiltersStatus() === true; - } - - public function filtersAreDisabled(): bool - { - return $this->getFiltersStatus() === false; - } - - public function setFiltersStatus(bool $status): self - { - $this->filtersStatus = $status; - - return $this; - } - - public function setFiltersEnabled(): self - { - $this->setFiltersStatus(true); - - return $this; - } - - public function setFiltersDisabled(): self - { - $this->setFiltersStatus(false); - - return $this; - } -} diff --git a/src/Traits/Core/HasCustomAttributes.php b/src/Traits/Core/HasCustomAttributes.php index cbc3bcd85..a642c3cac 100644 --- a/src/Traits/Core/HasCustomAttributes.php +++ b/src/Traits/Core/HasCustomAttributes.php @@ -47,6 +47,31 @@ public function setCustomAttributes(string $propertyName, array $customAttribute return $this; } + protected function mergeCustomAttributes(string $propertyName, array $customAttributes): self + { + $mergedArray = array_merge($this->{$propertyName}, $customAttributes); + ksort($mergedArray); + $this->{$propertyName} = $mergedArray; + + return $this; + } + + protected function mergeCustomAttributesClassic(string $propertyName, array $customAttributes): self + { + $attributes = [...$this->getCustomAttributes(propertyName: $propertyName, default: false, classicMode: true), ...$customAttributes]; + ksort($attributes); + + return $this->setCustomAttributes($propertyName, $attributes); + } + + protected function mergeCustomAttributesModern(string $propertyName, array $customAttributes): self + { + $attributes = [...$this->getCustomAttributes(propertyName: $propertyName, default: false, classicMode: false), ...$customAttributes]; + ksort($attributes); + + return $this->setCustomAttributes($propertyName, $attributes); + } + public function getCustomAttributesBagFromArray(array $attributesArray): ComponentAttributeBag { return new ComponentAttributeBag($attributesArray); diff --git a/src/Traits/Core/Filters/ManagesFilters.php b/src/Traits/Filters/Configuration/FilterConfiguration.php similarity index 51% rename from src/Traits/Core/Filters/ManagesFilters.php rename to src/Traits/Filters/Configuration/FilterConfiguration.php index 72bf73ad2..c0b408870 100644 --- a/src/Traits/Core/Filters/ManagesFilters.php +++ b/src/Traits/Filters/Configuration/FilterConfiguration.php @@ -1,45 +1,82 @@ appliedFilters[$filterKey] = $this->filterComponents[$filterKey] = $value; + + $this->callHook('filterSet', ['filter' => $filterKey, 'value' => $value]); + $this->callTraitHook('filterSet', ['filter' => $filterKey, 'value' => $value]); + if ($this->getEventStatusFilterApplied() && $filterKey != null && $value != null) { + event(new FilterApplied($this->getTableName(), $filterKey, $value)); + } + $this->dispatch('filter-was-set', tableName: $this->getTableName(), filterKey: $filterKey, value: $value); + $this->storeFilterValues(); + + } + + #[On('clearFilters')] + #[On('clear-filters')] + public function setFilterDefaults(): void + { + foreach ($this->getFilters() as $filter) { + if ($filter->isResetByClearButton()) { + $this->resetFilter($filter); + } + } - // Set in Frontend - public array $appliedFilters = []; + } /** - * Sets Filter Default Values + * @param mixed $filter */ - public function mountManagesFilters(): void + public function resetFilter($filter): void { - $this->restoreFilterValues(); + if (! $filter instanceof Filter) { + $filter = $this->getFilterByKey($filter); + } + $this->callHook('filterReset', ['filter' => $filter->getKey()]); + $this->callTraitHook('filterReset', ['filter' => $filter->getKey()]); + $this->setFilter($filter->getKey(), $filter->getDefaultValue()); - foreach ($this->getFilters() as $filter) { - if (! isset($this->appliedFilters[$filter->getKey()])) { - if ($filter->hasFilterDefaultValue()) { - $this->setFilter($filter->getKey(), $filter->getFilterDefaultValue()); - } else { - $this->resetFilter($filter); - } - } else { - $this->setFilter($filter->getKey(), $this->appliedFilters[$filter->getKey()]); - } + } + + #[On('livewireArrayFilterUpdateValues')] + public function updateLivewireArrayFilterValues(string $filterKey, string $tableName, array $values): void + { + if ($this->tableName == $tableName) { + $filter = $this->getFilterByKey($filterKey); + $filter->options($values); } + } - public function bootedManagesFilters(): void + public function selectAllFilterOptions(string $filterKey): void { - $this->setBuilder($this->builder()); + $filter = $this->getFilterByKey($filterKey); - foreach ($this->filterComponents as $filterKey => $value) { - $this->appliedFilters[$filterKey] = $value; + if (! $filter instanceof MultiSelectFilter && ! $filter instanceof MultiSelectDropdownFilter) { + return; } + + if (count($this->getAppliedFilterWithValue($filterKey) ?? []) === count($filter->getOptions())) { + $this->resetFilter($filterKey); + + return; + } + + $this->setFilter($filterKey, array_keys($filter->getOptions())); } public function applyFilters(): Builder diff --git a/src/Traits/Filters/Configuration/FilterGenericDataConfiguration.php b/src/Traits/Filters/Configuration/FilterGenericDataConfiguration.php new file mode 100644 index 000000000..e2dbb7f0f --- /dev/null +++ b/src/Traits/Filters/Configuration/FilterGenericDataConfiguration.php @@ -0,0 +1,18 @@ +getTableName(), $this->getFilterLayout(), $this->isTailwind(), $this->isBootstrap4(), $this->isBootstrap5()))->toArray(); + } + + public function setFilterGenericData(array $filterGenericData = []): void + { + $this->filterGenericData = $filterGenericData; + } +} diff --git a/src/Traits/Filters/Configuration/FilterMenuConfiguration.php b/src/Traits/Filters/Configuration/FilterMenuConfiguration.php new file mode 100644 index 000000000..b9f71d4b6 --- /dev/null +++ b/src/Traits/Filters/Configuration/FilterMenuConfiguration.php @@ -0,0 +1,46 @@ +filterLayout = $type; + + return $this; + } + + public function setFilterLayoutPopover(): self + { + return $this->setFilterLayout('popover'); + } + + public function setFilterLayoutSlideDown(): self + { + return $this->setFilterLayout('slide-down'); + } + + public function setFilterSlideDownDefaultStatus(bool $status): self + { + $this->filterSlideDownDefaultVisible = $status; + + return $this; + } + + public function setFilterSlideDownDefaultStatusDisabled(): self + { + return $this->setFilterSlideDownDefaultStatus(false); + } + + public function setFilterSlideDownDefaultStatusEnabled(): self + { + return $this->setFilterSlideDownDefaultStatus(true); + } +} diff --git a/src/Traits/Filters/Configuration/FilterPillsConfiguration.php b/src/Traits/Filters/Configuration/FilterPillsConfiguration.php new file mode 100644 index 000000000..8de1de45a --- /dev/null +++ b/src/Traits/Filters/Configuration/FilterPillsConfiguration.php @@ -0,0 +1,23 @@ +filterPillsStatus = $status; + + return $this; + } + + public function setFilterPillsEnabled(): self + { + return $this->setFilterPillsStatus(true); + } + + public function setFilterPillsDisabled(): self + { + return $this->setFilterPillsStatus(false); + } +} diff --git a/src/Traits/Filters/Configuration/FilterStatusConfiguration.php b/src/Traits/Filters/Configuration/FilterStatusConfiguration.php new file mode 100644 index 000000000..970b72c27 --- /dev/null +++ b/src/Traits/Filters/Configuration/FilterStatusConfiguration.php @@ -0,0 +1,23 @@ +filtersStatus = $status; + + return $this; + } + + public function setFiltersEnabled(): self + { + return $this->setFiltersStatus(true); + } + + public function setFiltersDisabled(): self + { + return $this->setFiltersStatus(false); + } +} diff --git a/src/Traits/Filters/Configuration/FilterVisibilityConfiguration.php b/src/Traits/Filters/Configuration/FilterVisibilityConfiguration.php new file mode 100644 index 000000000..6c3a1d8f0 --- /dev/null +++ b/src/Traits/Filters/Configuration/FilterVisibilityConfiguration.php @@ -0,0 +1,23 @@ +filtersVisibilityStatus = $status; + + return $this; + } + + public function setFiltersVisibilityEnabled(): self + { + return $this->setFiltersVisibilityStatus(true); + } + + public function setFiltersVisibilityDisabled(): self + { + return $this->setFiltersVisibilityStatus(false); + } +} diff --git a/src/Traits/Filters/HasFilterGenericData.php b/src/Traits/Filters/HasFilterGenericData.php new file mode 100644 index 000000000..d60873da1 --- /dev/null +++ b/src/Traits/Filters/HasFilterGenericData.php @@ -0,0 +1,14 @@ +queryStringForFilterIsEnabled()) ? [ @@ -20,65 +20,49 @@ protected function queryStringHasQueryStringForFilter(): array ] : []; } - protected function setupQueryStringStatusForFilter(): void - { - if (! $this->hasQueryStringStatusForFilter()) { - $this->setQueryStringForFilterEnabled(); - } - } - public function hasQueryStringStatusForFilter(): bool { - return isset($this->queryStringStatusForFilter); + return $this->hasQueryStringConfigStatus('filters'); } public function getQueryStringStatusForFilter(): bool { - return $this->queryStringStatusForFilter ?? true; + return $this->getQueryStringConfigStatus('filters'); } public function queryStringForFilterIsEnabled(): bool { - $this->setupQueryStringStatusForFilter(); return $this->getQueryStringStatusForFilter() && $this->filtersAreEnabled(); } public function setQueryStringStatusForFilter(bool $status): self { - $this->queryStringStatusForFilter = $status; - - return $this; + return $this->setQueryStringConfigStatus('filters', $status); } public function setQueryStringForFilterEnabled(): self { - $this->setQueryStringStatusForFilter(true); - - return $this; + return $this->setQueryStringStatusForFilter(true); } public function setQueryStringForFilterDisabled(): self { - $this->setQueryStringStatusForFilter(false); - - return $this; + return $this->setQueryStringStatusForFilter(false); } public function hasQueryStringAliasForFilter(): bool { - return isset($this->queryStringAliasForFilter); + return $this->hasQueryStringConfigAlias('filters'); } public function getQueryStringAliasForFilter(): string { - return $this->queryStringAliasForFilter ?? $this->getQueryStringAlias().'-filters'; + return $this->getQueryStringConfigAlias('filters'); } public function setQueryStringAliasForFilter(string $alias): self { - $this->queryStringAliasForFilter = $alias; - - return $this; + return $this->setQueryStringConfigAlias('filters', $alias); } } diff --git a/src/Traits/Filters/HasFiltersStatus.php b/src/Traits/Filters/HasFiltersStatus.php new file mode 100644 index 000000000..9e043b16b --- /dev/null +++ b/src/Traits/Filters/HasFiltersStatus.php @@ -0,0 +1,16 @@ +filterGenericData); + } + + #[Computed] + public function getFilterGenericData(): array + { + if (! $this->hasFilterGenericData()) { + $this->setFilterGenericData($this->generateFilterGenericData()); + } + + return $this->filterGenericData; + } +} diff --git a/src/Traits/Helpers/FilterHelpers.php b/src/Traits/Filters/Helpers/FilterHelpers.php similarity index 55% rename from src/Traits/Helpers/FilterHelpers.php rename to src/Traits/Filters/Helpers/FilterHelpers.php index f2924c883..0c538653e 100644 --- a/src/Traits/Helpers/FilterHelpers.php +++ b/src/Traits/Filters/Helpers/FilterHelpers.php @@ -1,13 +1,10 @@ appliedFilters[$filterKey] = $this->filterComponents[$filterKey] = $value; - - $this->callHook('filterSet', ['filter' => $filterKey, 'value' => $value]); - $this->callTraitHook('filterSet', ['filter' => $filterKey, 'value' => $value]); - if ($this->getEventStatusFilterApplied() && $filterKey != null && $value != null) { - event(new FilterApplied($this->getTableName(), $filterKey, $value)); - } - $this->dispatch('filter-was-set', tableName: $this->getTableName(), filterKey: $filterKey, value: $value); - $this->storeFilterValues(); - - } - - public function selectAllFilterOptions(string $filterKey): void - { - $filter = $this->getFilterByKey($filterKey); - - if (! $filter instanceof MultiSelectFilter && ! $filter instanceof MultiSelectDropdownFilter) { - return; - } - - if (count($this->getAppliedFilterWithValue($filterKey) ?? []) === count($filter->getOptions())) { - $this->resetFilter($filterKey); - - return; - } - - $this->setFilter($filterKey, array_keys($filter->getOptions())); - } - - #[On('clearFilters')] - #[On('clear-filters')] - public function setFilterDefaults(): void - { - foreach ($this->getFilters() as $filter) { - if ($filter->isResetByClearButton()) { - $this->resetFilter($filter); - } - } - - } - /** * @return array */ @@ -159,28 +111,4 @@ public function getAppliedFiltersWithValuesCount(): int { return count($this->getAppliedFiltersWithValues()); } - - /** - * @param mixed $filter - */ - public function resetFilter($filter): void - { - if (! $filter instanceof Filter) { - $filter = $this->getFilterByKey($filter); - } - $this->callHook('filterReset', ['filter' => $filter->getKey()]); - $this->callTraitHook('filterReset', ['filter' => $filter->getKey()]); - $this->setFilter($filter->getKey(), $filter->getDefaultValue()); - - } - - #[On('livewireArrayFilterUpdateValues')] - public function updateLivewireArrayFilterValues(string $filterKey, string $tableName, array $values): void - { - if ($this->tableName == $tableName) { - $filter = $this->getFilterByKey($filterKey); - $filter->options($values); - } - - } } diff --git a/src/Traits/Filters/Helpers/FilterMenuHelpers.php b/src/Traits/Filters/Helpers/FilterMenuHelpers.php new file mode 100644 index 000000000..267346556 --- /dev/null +++ b/src/Traits/Filters/Helpers/FilterMenuHelpers.php @@ -0,0 +1,81 @@ +filterSlideDownDefaultVisible; + } + + public function filtersSlideDownIsDefaultVisible(): bool + { + return $this->getFilterSlideDownDefaultStatus() === true; + } + + public function filtersSlideDownIsDefaultHidden(): bool + { + return $this->getFilterSlideDownDefaultStatus() === false; + } + + public function getFilterLayout(): string + { + return $this->filterLayout; + } + + public function isFilterLayoutPopover(): bool + { + return $this->getFilterLayout() === 'popover'; + } + + public function isFilterLayoutSlideDown(): bool + { + return $this->getFilterLayout() === 'slide-down'; + } + + /** + * Get whether any filter has a configured slide down row. + */ + public function hasFiltersWithSlidedownRows(): bool + { + return $this->getFilters() + ->reject(fn (Filter $filter) => ! $filter->hasFilterSlidedownRow()) + ->count() > 0; + } + + /** + * Get filters sorted by row + * + * @return array + */ + public function getFiltersByRow(): array + { + $orderedFilters = []; + $filterList = ($this->hasFiltersWithSlidedownRows()) ? $this->getVisibleFilters()->sortBy('filterSlidedownRow') : $this->getVisibleFilters(); + if ($this->hasFiltersWithSlidedownRows()) { + foreach ($filterList as $filter) { + $orderedFilters[(string) $filter->getFilterSlidedownRow()][] = $filter; + } + + if (empty($orderedFilters['1'])) { + $orderedFilters['1'] = (isset($orderedFilters['99']) ? $orderedFilters['99'] : []); + if (isset($orderedFilters['99'])) { + unset($orderedFilters['99']); + } + } + } else { + $orderedFilters = Arr::wrap($filterList); + $orderedFilters['1'] = $orderedFilters['0'] ?? []; + if (isset($orderedFilters['0'])) { + unset($orderedFilters['0']); + } + } + ksort($orderedFilters); + + return $orderedFilters; + } +} diff --git a/src/Traits/Filters/Helpers/FilterPillsHelpers.php b/src/Traits/Filters/Helpers/FilterPillsHelpers.php new file mode 100644 index 000000000..f12cad696 --- /dev/null +++ b/src/Traits/Filters/Helpers/FilterPillsHelpers.php @@ -0,0 +1,38 @@ +filtersAreEnabled() && $this->filterPillsAreEnabled() && $this->hasAppliedVisibleFiltersForPills(); + } + + public function getFilterPillsStatus(): bool + { + return $this->filterPillsStatus; + } + + public function filterPillsAreEnabled(): bool + { + return $this->getFilterPillsStatus() === true; + } + + public function filterPillsAreDisabled(): bool + { + return $this->getFilterPillsStatus() === false; + } + + public function hasAppliedVisibleFiltersForPills(): bool + { + return collect($this->getAppliedFiltersWithValues()) + ->map(fn ($_item, $key) => $this->getFilterByKey($key)) + ->reject(fn (Filter $filter) => $filter->isHiddenFromPills()) + ->count() > 0; + } +} diff --git a/src/Traits/Filters/Helpers/FilterStatusHelpers.php b/src/Traits/Filters/Helpers/FilterStatusHelpers.php new file mode 100644 index 000000000..47d4f697e --- /dev/null +++ b/src/Traits/Filters/Helpers/FilterStatusHelpers.php @@ -0,0 +1,24 @@ +filtersStatus; + } + + #[Computed] + public function filtersAreEnabled(): bool + { + return $this->getFiltersStatus() === true; + } + + public function filtersAreDisabled(): bool + { + return $this->getFiltersStatus() === false; + } +} diff --git a/src/Traits/Core/Filters/HasFiltersVisibility.php b/src/Traits/Filters/Helpers/FilterVisibilityHelpers.php similarity index 59% rename from src/Traits/Core/Filters/HasFiltersVisibility.php rename to src/Traits/Filters/Helpers/FilterVisibilityHelpers.php index ddb80778b..e66efc516 100644 --- a/src/Traits/Core/Filters/HasFiltersVisibility.php +++ b/src/Traits/Filters/Helpers/FilterVisibilityHelpers.php @@ -1,12 +1,11 @@ getFilters()->reject(fn (Filter $filter) => $filter->isHiddenFromMenus()); } - - #[Locked] - public bool $filtersVisibilityStatus = true; - - public function setFiltersVisibilityStatus(bool $status): self - { - $this->filtersVisibilityStatus = $status; - - return $this; - } - - public function setFiltersVisibilityEnabled(): self - { - $this->setFiltersVisibilityStatus(true); - - return $this; - } - - public function setFiltersVisibilityDisabled(): self - { - $this->setFiltersVisibilityStatus(false); - - return $this; - } } diff --git a/src/Traits/Filters/ManagesFilters.php b/src/Traits/Filters/ManagesFilters.php new file mode 100644 index 000000000..bc2a454dd --- /dev/null +++ b/src/Traits/Filters/ManagesFilters.php @@ -0,0 +1,37 @@ +restoreFilterValues(); + + foreach ($this->getFilters() as $filter) { + if (! isset($this->appliedFilters[$filter->getKey()])) { + if ($filter->hasFilterDefaultValue()) { + $this->setFilter($filter->getKey(), $filter->getFilterDefaultValue()); + } else { + $this->resetFilter($filter); + } + } else { + $this->setFilter($filter->getKey(), $this->appliedFilters[$filter->getKey()]); + } + } + } + + public function bootedManagesFilters(): void + { + $this->setBuilder($this->builder()); + + foreach ($this->filterComponents as $filterKey => $value) { + $this->appliedFilters[$filterKey] = $value; + } + } +} diff --git a/src/Traits/Filters/Styling/Configuration/FilterMenuStylingConfiguration.php b/src/Traits/Filters/Styling/Configuration/FilterMenuStylingConfiguration.php new file mode 100644 index 000000000..d7bd20356 --- /dev/null +++ b/src/Traits/Filters/Styling/Configuration/FilterMenuStylingConfiguration.php @@ -0,0 +1,34 @@ +mergeCustomAttributes(propertyName: 'filterPopoverAttributes', customAttributes: $attributes); + } + + /** + * Used to set attributes for the Filter Slidedown Wrapper + */ + public function setFilterSlidedownWrapperAttributes(array $attributes): self + { + return $this->mergeCustomAttributes(propertyName: 'filterSlidedownWrapperAttributes', customAttributes: $attributes); + } + + /** + * Set a list of attributes to override on the th sort button elements + */ + public function setFilterSlidedownRowAttributes(Closure $callback): self + { + $this->filterSlidedownRowCallback = $callback; + + return $this; + } +} diff --git a/src/Traits/Filters/Styling/Configuration/FilterPillsStylingConfiguration.php b/src/Traits/Filters/Styling/Configuration/FilterPillsStylingConfiguration.php new file mode 100644 index 000000000..107428920 --- /dev/null +++ b/src/Traits/Filters/Styling/Configuration/FilterPillsStylingConfiguration.php @@ -0,0 +1,21 @@ +mergeCustomAttributes(propertyName: 'filterPillsItemAttributes', customAttributes: $attributes); + } + + protected function setFilterPillsResetFilterButtonAttributes(array $attributes = []): self + { + return $this->mergeCustomAttributes(propertyName: 'filterPillsResetFilterButtonAttributes', customAttributes: $attributes); + } + + protected function setFilterPillsResetAllButtonAttributes(array $attributes = []): self + { + return $this->mergeCustomAttributes(propertyName: 'filterPillsResetAllButtonAttributes', customAttributes: $attributes); + } +} diff --git a/src/Traits/Filters/Styling/HasFilterMenuStyling.php b/src/Traits/Filters/Styling/HasFilterMenuStyling.php new file mode 100644 index 000000000..e65ba7d53 --- /dev/null +++ b/src/Traits/Filters/Styling/HasFilterMenuStyling.php @@ -0,0 +1,19 @@ + '', 'default-colors' => true, 'default-styling' => true, 'default-width' => true]; + + protected array $filterSlidedownWrapperAttributes = ['class' => '', 'default-colors' => true, 'default-styling' => true]; + + protected ?Closure $filterSlidedownRowCallback; +} diff --git a/src/Traits/Filters/Styling/HasFilterPillsStyling.php b/src/Traits/Filters/Styling/HasFilterPillsStyling.php new file mode 100644 index 000000000..78c0b829a --- /dev/null +++ b/src/Traits/Filters/Styling/HasFilterPillsStyling.php @@ -0,0 +1,18 @@ + '', 'default-colors' => true, 'default-styling' => true]; + + protected array $filterPillsResetFilterButtonAttributes = ['class' => '', 'default-colors' => true, 'default-styling' => true]; + + protected array $filterPillsResetAllButtonAttributes = ['class' => '', 'default-colors' => true, 'default-styling' => true]; +} diff --git a/src/Traits/Filters/Styling/Helpers/FilterMenuStylingHelpers.php b/src/Traits/Filters/Styling/Helpers/FilterMenuStylingHelpers.php new file mode 100644 index 000000000..c17e2de76 --- /dev/null +++ b/src/Traits/Filters/Styling/Helpers/FilterMenuStylingHelpers.php @@ -0,0 +1,48 @@ + + */ + #[Computed] + public function getFilterPopoverAttributes(): array + { + return $this->filterPopoverAttributes; + + } + + /** + * Used to get attributes for the Filter Slidedown Wrapper + * + * @return array + */ + #[Computed] + public function getFilterSlidedownWrapperAttributes(): array + { + return $this->filterSlidedownWrapperAttributes; + + } + + /** + * Used to get attributes for the Filter Slidedown Row + * + * @return array + */ + #[Computed] + public function getFilterSlidedownRowAttributes(string $rowIndex): array + { + + if (isset($this->filterSlidedownRowCallback)) { + return array_merge(['class' => '', 'default-colors' => true, 'default-styling' => true, 'row' => (int) $rowIndex], call_user_func($this->filterSlidedownRowCallback, (int) $rowIndex)); + } + + return ['class' => '', 'default-colors' => true, 'default-styling' => true, 'row' => (int) $rowIndex]; + } +} diff --git a/src/Traits/Filters/Styling/Helpers/FilterPillsStylingHelpers.php b/src/Traits/Filters/Styling/Helpers/FilterPillsStylingHelpers.php new file mode 100644 index 000000000..c3bd0d9d5 --- /dev/null +++ b/src/Traits/Filters/Styling/Helpers/FilterPillsStylingHelpers.php @@ -0,0 +1,26 @@ +filterPillsItemAttributes; + } + + #[Computed] + public function getFilterPillsResetFilterButtonAttributes(): array + { + return $this->filterPillsResetFilterButtonAttributes; + } + + #[Computed] + public function getFilterPillsResetAllButtonAttributes(): array + { + return $this->filterPillsResetAllButtonAttributes; + } +} diff --git a/src/Traits/WithFilters.php b/src/Traits/WithFilters.php index 19ff8306b..b80e30b3e 100644 --- a/src/Traits/WithFilters.php +++ b/src/Traits/WithFilters.php @@ -4,15 +4,25 @@ use Illuminate\Support\Collection; use Livewire\Attributes\Locked; -use Rappasoft\LaravelLivewireTables\Traits\Configuration\FilterConfiguration; -use Rappasoft\LaravelLivewireTables\Traits\Core\Filters\HandlesFilterTraits; -use Rappasoft\LaravelLivewireTables\Traits\Helpers\FilterHelpers; +use Rappasoft\LaravelLivewireTables\Traits\Filters\{Configuration\FilterConfiguration, HasFilterGenericData, HasFilterMenu, HasFilterPills, HasFilterQueryString, HasFiltersStatus, HasFiltersVisibility, Helpers\FilterHelpers, ManagesFilters}; trait WithFilters { use FilterConfiguration, - FilterHelpers; - use HandlesFilterTraits; + FilterHelpers, + HasFiltersStatus, + HasFilterGenericData, + HasFilterMenu, + HasFilterPills, + HasFilterQueryString, + HasFiltersVisibility, + ManagesFilters; + + // Set in JS + public array $filterComponents = []; + + // Set in Frontend + public array $appliedFilters = []; #[Locked] public int $filterCount; diff --git a/src/Traits/WithQueryString.php b/src/Traits/WithQueryString.php index 52b2b37f8..b6b37eabf 100644 --- a/src/Traits/WithQueryString.php +++ b/src/Traits/WithQueryString.php @@ -14,7 +14,7 @@ trait WithQueryString #[Locked] public array $queryStringConfig = [ 'columns' => ['status' => false, 'alias' => null], - 'filter' => ['status' => false, 'alias' => null], + 'filters' => ['status' => true, 'alias' => null], 'search' => ['status' => true, 'alias' => null], 'sorts' => ['status' => true, 'alias' => null], ]; diff --git a/tests/Unit/Traits/Configuration/FilterConfigurationTest.php b/tests/Unit/Traits/Configuration/FilterConfigurationTest.php index d9756b5e6..6b4e4c9ff 100644 --- a/tests/Unit/Traits/Configuration/FilterConfigurationTest.php +++ b/tests/Unit/Traits/Configuration/FilterConfigurationTest.php @@ -78,25 +78,18 @@ public function test_filters_layout_can_be_set(): void $this->assertSame('popover', $this->basicTable->getFilterLayout()); - $this->basicTable->setFilterLayout('slide-down'); + $this->assertSame('slide-down', $this->basicTable->setFilterLayout('slide-down')->getFilterLayout()); - $this->assertSame('slide-down', $this->basicTable->getFilterLayout()); + $this->assertSame('popover', $this->basicTable->setFilterLayout('popover')->getFilterLayout()); - $this->basicTable->setFilterLayout('popover'); + $this->assertSame('slide-down', $this->basicTable->setFilterLayoutSlideDown()->getFilterLayout()); - $this->assertSame('popover', $this->basicTable->getFilterLayout()); - - $this->basicTable->setFilterLayout('popover2'); - - $this->assertSame('popover', $this->basicTable->getFilterLayout()); + $this->assertSame('popover', $this->basicTable->setFilterLayout('popover2')->getFilterLayout()); - $this->basicTable->setFilterLayoutSlideDown(); + $this->assertSame('slide-down', $this->basicTable->setFilterLayout('slide-down')->getFilterLayout()); - $this->basicTable->setFilterLayout('slide-down'); + $this->assertSame('popover', $this->basicTable->setFilterLayoutPopover()->getFilterLayout()); - $this->basicTable->setFilterLayoutPopover(); - - $this->basicTable->setFilterLayout('popover'); } public function test_filters_layout_popover_default_can_be_set(): void @@ -118,5 +111,10 @@ public function test_filters_layout_popover_default_can_be_set(): void $this->basicTable->setFilterSlideDownDefaultStatus(false); $this->assertFalse($this->basicTable->filterSlideDownDefaultVisible); + + $this->assertSame('slide-down', $this->basicTable->setFilterLayout('slide-down')->getFilterLayout()); + + $this->assertSame('popover', $this->basicTable->setFilterLayoutPopover()->getFilterLayout()); + } } diff --git a/tests/Unit/Traits/Core/QueryStrings/QueryStringForFiltersTest.php b/tests/Unit/Traits/Core/QueryStrings/QueryStringForFiltersTest.php index 63ae05085..e1117c4ef 100644 --- a/tests/Unit/Traits/Core/QueryStrings/QueryStringForFiltersTest.php +++ b/tests/Unit/Traits/Core/QueryStrings/QueryStringForFiltersTest.php @@ -29,8 +29,11 @@ public function test_can_disable_filter_query_string_status(): void parent::$mock->configure(); parent::$mock->boot(); $this->assertSame(true, parent::$mock->getQueryStringStatusForFilter()); + $this->assertTrue(parent::$mock->hasQueryStringStatusForFilter()); parent::$mock->setQueryStringForFilterDisabled(); $this->assertSame(false, parent::$mock->getQueryStringStatusForFilter()); + $this->assertTrue(parent::$mock->hasQueryStringStatusForFilter()); + } public function test_can_enable_filter_query_string_status(): void diff --git a/tests/Unit/Traits/Filters/FilterDefaultValueTest.php b/tests/Unit/Traits/Filters/FilterDefaultValueTest.php new file mode 100644 index 000000000..176cd9364 --- /dev/null +++ b/tests/Unit/Traits/Filters/FilterDefaultValueTest.php @@ -0,0 +1,45 @@ +useComputedPropertiesDisabled(); + + } + + public function filters(): array + { + return [ + TextFilter::make('Pet Name', 'pet_name_filter') + ->filter(function (Builder $builder, string $value) { + return $builder->where('pets.name', '=', $value); + }) + ->setFilterDefaultValue('car'), + ]; + } + }; + $this->assertSame([], $mock->getAppliedFilters()); + + $mock->bootAll(); + + $this->assertSame(['pet_name_filter' => 'car'], $mock->getAppliedFilters()); + + } +} diff --git a/tests/Unit/Traits/Filters/FilterMenuTest.php b/tests/Unit/Traits/Filters/FilterMenuTest.php new file mode 100644 index 000000000..2019d083f --- /dev/null +++ b/tests/Unit/Traits/Filters/FilterMenuTest.php @@ -0,0 +1,200 @@ +assertSame(['class' => '', 'default-colors' => true, 'default-styling' => true, 'default-width' => true], $this->basicTable->getFilterPopoverAttributes()); + } + + public function test_can_get_default_filter_slidedown_attributes(): void + { + $this->assertSame(['class' => '', 'default-colors' => true, 'default-styling' => true], $this->basicTable->getFilterSlidedownWrapperAttributes()); + } + + public function test_can_get_default_filter_slidedown_row_attributes(): void + { + $this->assertSame(['class' => '', 'default-colors' => true, 'default-styling' => true, 'row' => 1], $this->basicTable->getFilterSlidedownRowAttributes(1)); + $this->assertSame(['class' => '', 'default-colors' => true, 'default-styling' => true, 'row' => 2], $this->basicTable->getFilterSlidedownRowAttributes('2')); + + } + + public function test_can_check_filters_with_no_defined_slidedown_rows(): void + { + $testTableDefault = new class extends PetsTable + { + public function configure(): void + { + parent::configure(); + $this->useComputedPropertiesDisabled(); + + } + + public function publiclySetFilterPillsItemAttributes(array $attributes = []) + { + $this->setFilterPillsItemAttributes($attributes); + } + + public function publiclySetResetFilterButtonAttributes(array $attributes = []) + { + $this->setFilterPillsResetFilterButtonAttributes($attributes); + } + + public function publiclySetResetFilterAllButtonAttributes(array $attributes = []) + { + $this->setFilterPillsResetAllButtonAttributes($attributes); + } + }; + $this->assertFalse($testTableDefault->hasFiltersWithSlidedownRows()); + } + + public function test_can_check_filters_with_defined_slidedown_rows(): void + { + $testTableDefault = new class extends PetsTable + { + public function configure(): void + { + parent::configure(); + $this->useComputedPropertiesDisabled(); + + } + + public function filters(): array + { + return [ + MultiSelectFilter::make('Breed', 'breed') + ->setFilterSlidedownRow(2) + ->options( + Breed::query() + ->orderBy('name') + ->get() + ->keyBy('id') + ->map(fn ($breed) => $breed->name) + ->toArray() + ) + ->filter(function (Builder $builder, array $values) { + return $builder->whereIn('breed_id', $values); + }), + ]; + } + + public function publiclySetFilterPillsItemAttributes(array $attributes = []) + { + $this->setFilterPillsItemAttributes($attributes); + } + + public function publiclySetResetFilterButtonAttributes(array $attributes = []) + { + $this->setFilterPillsResetFilterButtonAttributes($attributes); + } + + public function publiclySetResetFilterAllButtonAttributes(array $attributes = []) + { + $this->setFilterPillsResetAllButtonAttributes($attributes); + } + }; + $this->assertTrue($testTableDefault->hasFiltersWithSlidedownRows()); + } + + public function test_can_get_filter_slidedown_rows(): void + { + $testTableDefault = new class extends PetsTable + { + public function configure(): void + { + parent::configure(); + $this->useComputedPropertiesDisabled(); + + } + + public function filters(): array + { + return [ + MultiSelectFilter::make('Breed 1', 'breed') + ->setFilterSlidedownRow(1) + ->options( + Breed::query() + ->orderBy('name') + ->get() + ->keyBy('id') + ->map(fn ($breed) => $breed->name) + ->toArray() + ) + ->filter(function (Builder $builder, array $values) { + return $builder->whereIn('breed_id', $values); + }), + MultiSelectFilter::make('Breed 3', 'breed3') + ->setFilterSlidedownRow(1) + ->options( + Breed::query() + ->orderBy('name') + ->get() + ->keyBy('id') + ->map(fn ($breed) => $breed->name) + ->toArray() + ) + ->filter(function (Builder $builder, array $values) { + return $builder->whereIn('breed_id', $values); + }), + MultiSelectFilter::make('Breed 2', 'breed2') + ->setFilterSlidedownRow(2) + ->options( + Breed::query() + ->orderBy('name') + ->get() + ->keyBy('id') + ->map(fn ($breed) => $breed->name) + ->toArray() + ) + ->filter(function (Builder $builder, array $values) { + return $builder->whereIn('breed_id', $values); + }), + + MultiSelectFilter::make('Breed 4', 'breed4') + ->options( + Breed::query() + ->orderBy('name') + ->get() + ->keyBy('id') + ->map(fn ($breed) => $breed->name) + ->toArray() + ) + ->filter(function (Builder $builder, array $values) { + return $builder->whereIn('breed_id', $values); + }), + ]; + } + + public function publiclySetFilterPillsItemAttributes(array $attributes = []) + { + $this->setFilterPillsItemAttributes($attributes); + } + + public function publiclySetResetFilterButtonAttributes(array $attributes = []) + { + $this->setFilterPillsResetFilterButtonAttributes($attributes); + } + + public function publiclySetResetFilterAllButtonAttributes(array $attributes = []) + { + $this->setFilterPillsResetAllButtonAttributes($attributes); + } + }; + $this->assertSame('Breed 1', $testTableDefault->getFiltersByRow()[1][0]->getName()); + $this->assertSame('Breed 3', $testTableDefault->getFiltersByRow()[1][1]->getName()); + $this->assertSame('Breed 2', $testTableDefault->getFiltersByRow()[2][0]->getName()); + $this->assertSame('Breed 4', $testTableDefault->getFiltersByRow()[''][0]->getName()); + + } +} diff --git a/tests/Unit/Traits/Filters/FilterPillsTest.php b/tests/Unit/Traits/Filters/FilterPillsTest.php new file mode 100644 index 000000000..4f579beea --- /dev/null +++ b/tests/Unit/Traits/Filters/FilterPillsTest.php @@ -0,0 +1,131 @@ +assertSame(['class' => '', 'default-colors' => true, 'default-styling' => true], $this->basicTable->getFilterPillsItemAttributes()); + } + + public function test_can_get_default_filter_reset_filter_button_attributes(): void + { + $this->assertSame(['class' => '', 'default-colors' => true, 'default-styling' => true], $this->basicTable->getFilterPillsResetFilterButtonAttributes()); + } + + public function test_can_get_default_filter_reset_all_filter_button_attributes(): void + { + $this->assertSame(['class' => '', 'default-colors' => true, 'default-styling' => true], $this->basicTable->getFilterPillsResetAllButtonAttributes()); + } + + public function test_can_change_default_filter_pills_item_attributes(): void + { + $testTableDefault = new class extends PetsTable + { + public function configure(): void + { + parent::configure(); + $this->useComputedPropertiesDisabled(); + + } + + public function publiclySetFilterPillsItemAttributes(array $attributes = []) + { + $this->setFilterPillsItemAttributes($attributes); + } + + public function publiclySetResetFilterButtonAttributes(array $attributes = []) + { + $this->setFilterPillsResetFilterButtonAttributes($attributes); + } + + public function publiclySetResetFilterAllButtonAttributes(array $attributes = []) + { + $this->setFilterPillsResetAllButtonAttributes($attributes); + } + }; + $this->assertSame(['class' => '', 'default-colors' => true, 'default-styling' => true], $testTableDefault->getFilterPillsItemAttributes()); + $testTableDefault->publiclySetFilterPillsItemAttributes(['class' => 'bg-blue-500']); + $this->assertSame(['class' => 'bg-blue-500', 'default-colors' => true, 'default-styling' => true], $testTableDefault->getFilterPillsItemAttributes()); + $testTableDefault->publiclySetFilterPillsItemAttributes(['class' => 'bg-blue-500', 'default-colors' => false]); + $this->assertSame(['class' => 'bg-blue-500', 'default-colors' => false, 'default-styling' => true], $testTableDefault->getFilterPillsItemAttributes()); + + } + + public function test_can_change_default_filter_pills_reset_button_attributes(): void + { + $testTableDefault = new class extends PetsTable + { + public function configure(): void + { + parent::configure(); + $this->useComputedPropertiesDisabled(); + + } + + public function publiclySetFilterPillsItemAttributes(array $attributes = []) + { + $this->setFilterPillsItemAttributes($attributes); + } + + public function publiclySetResetFilterButtonAttributes(array $attributes = []) + { + $this->setFilterPillsResetFilterButtonAttributes($attributes); + } + + public function publiclySetResetFilterAllButtonAttributes(array $attributes = []) + { + $this->setFilterPillsResetAllButtonAttributes($attributes); + } + }; + + $this->assertSame(['class' => '', 'default-colors' => true, 'default-styling' => true], $testTableDefault->getFilterPillsResetFilterButtonAttributes()); + $testTableDefault->publiclySetResetFilterButtonAttributes(['class' => 'bg-red-500']); + $this->assertSame(['class' => 'bg-red-500', 'default-colors' => true, 'default-styling' => true], $testTableDefault->getFilterPillsResetFilterButtonAttributes()); + $testTableDefault->publiclySetResetFilterButtonAttributes(['class' => 'bg-red-500', 'default-colors' => false]); + $this->assertSame(['class' => 'bg-red-500', 'default-colors' => false, 'default-styling' => true], $testTableDefault->getFilterPillsResetFilterButtonAttributes()); + + } + + public function test_can_change_default_filter_pills_reset_all_button_attributes(): void + { + $testTableDefault = new class extends PetsTable + { + public function configure(): void + { + parent::configure(); + $this->useComputedPropertiesDisabled(); + + } + + public function publiclySetFilterPillsItemAttributes(array $attributes = []) + { + $this->setFilterPillsItemAttributes($attributes); + } + + public function publiclySetResetFilterButtonAttributes(array $attributes = []) + { + $this->setFilterPillsResetFilterButtonAttributes($attributes); + } + + public function publiclySetResetFilterAllButtonAttributes(array $attributes = []) + { + $this->setFilterPillsResetAllButtonAttributes($attributes); + } + }; + + $this->assertSame(['class' => '', 'default-colors' => true, 'default-styling' => true], $testTableDefault->getFilterPillsResetAllButtonAttributes()); + $testTableDefault->publiclySetResetFilterAllButtonAttributes(['class' => 'bg-red-500']); + $this->assertSame(['class' => 'bg-red-500', 'default-colors' => true, 'default-styling' => true], $testTableDefault->getFilterPillsResetAllButtonAttributes()); + $testTableDefault->publiclySetResetFilterAllButtonAttributes(['class' => 'bg-red-500', 'default-colors' => false]); + $this->assertSame(['class' => 'bg-red-500', 'default-colors' => false, 'default-styling' => true], $testTableDefault->getFilterPillsResetAllButtonAttributes()); + + } +} diff --git a/tests/Unit/Traits/Helpers/FilterHelpersTest.php b/tests/Unit/Traits/Helpers/FilterHelpersTest.php index b9104cbd0..bab153264 100644 --- a/tests/Unit/Traits/Helpers/FilterHelpersTest.php +++ b/tests/Unit/Traits/Helpers/FilterHelpersTest.php @@ -204,6 +204,25 @@ public function test_can_check_if_filter_layout_slidedown_is_visible(): void $this->assertTrue($this->basicTable->getFilterSlideDownDefaultStatus()); } + public function test_can_check_if_filter_layout_slidedown_is_visible_directly(): void + { + $this->assertFalse($this->basicTable->filtersSlideDownIsDefaultVisible()); + + $this->basicTable->setFilterSlideDownDefaultStatusEnabled(); + + $this->assertTrue($this->basicTable->filtersSlideDownIsDefaultVisible()); + } + + public function test_can_check_if_filter_layout_slidedown_is_hidden_directly(): void + { + $this->assertTrue($this->basicTable->filtersSlideDownIsDefaultHidden()); + + $this->basicTable->setFilterSlideDownDefaultStatusEnabled(); + + $this->assertFalse($this->basicTable->filtersSlideDownIsDefaultHidden()); + + } + public function test_can_check_if_filter_layout_slidedown_is_hidden(): void { $this->assertFalse($this->basicTable->getFilterSlideDownDefaultStatus()); diff --git a/tests/Unit/Traits/Styling/FilterPopoverStylingTest.php b/tests/Unit/Traits/Styling/FilterPopoverStylingTest.php index 48980ee48..6b43720a5 100644 --- a/tests/Unit/Traits/Styling/FilterPopoverStylingTest.php +++ b/tests/Unit/Traits/Styling/FilterPopoverStylingTest.php @@ -10,20 +10,20 @@ final class FilterPopoverStylingTest extends TestCase { public function test_filter_popover_attributes_returns_default_if_not_set(): void { - $this->assertSame(['class' => '', 'default-width' => true, 'default-colors' => true, 'default-styling' => true], $this->basicTable->getFilterPopoverAttributes()); + $this->assertSame(['class' => '', 'default-colors' => true, 'default-styling' => true, 'default-width' => true], $this->basicTable->getFilterPopoverAttributes()); } public function test_filter_popover_attributes_can_be_changed(): void { - $this->assertSame(['class' => '', 'default-width' => true, 'default-colors' => true, 'default-styling' => true], $this->basicTable->getFilterPopoverAttributes()); + $this->assertSame(['class' => '', 'default-colors' => true, 'default-styling' => true, 'default-width' => true], $this->basicTable->getFilterPopoverAttributes()); $this->basicTable->setFilterPopoverAttributes(['class' => 'bg-blue-500']); - $this->assertSame(['class' => 'bg-blue-500', 'default-width' => true, 'default-colors' => true, 'default-styling' => true], $this->basicTable->getFilterPopoverAttributes()); + $this->assertSame(['class' => 'bg-blue-500', 'default-colors' => true, 'default-styling' => true, 'default-width' => true], $this->basicTable->getFilterPopoverAttributes()); $this->basicTable->setFilterPopoverAttributes(['class' => 'bg-red-500', 'default-colors' => false]); - $this->assertSame(['class' => 'bg-red-500', 'default-width' => true, 'default-colors' => false, 'default-styling' => true], $this->basicTable->getFilterPopoverAttributes()); + $this->assertSame(['class' => 'bg-red-500', 'default-colors' => false, 'default-styling' => true, 'default-width' => true], $this->basicTable->getFilterPopoverAttributes()); } } From 3f18055a8184fa2b8e2ff9b72e8565564f0fd79c Mon Sep 17 00:00:00 2001 From: Joe <104938042+lrljoe@users.noreply.github.com> Date: Sun, 26 Jan 2025 02:06:28 +0000 Subject: [PATCH 13/24] Filters urgent fixes - correct Filter Default QueryString (#2188) * Fixes for QueryString & Centralising Methods * Tweaks for Filters --- src/Traits/Filters/HasFilterQueryString.php | 36 +++++------- ...{ManagesFilters.php => HasFiltersCore.php} | 12 ++-- src/Traits/WithFilters.php | 8 +-- tests/Http/Livewire/BaseTable.php | 55 +------------------ tests/Http/Livewire/Traits/TestHelpers.php | 40 ++++++++++++++ .../Livewire/Traits/TestPaginationHelpers.php | 26 +++++++++ tests/Unit/DataTableComponentTest.php | 4 +- .../Core/QueryStrings/QueryStringTestBase.php | 15 +++++ tests/Unit/Traits/WithMountTest.php | 10 ++-- 9 files changed, 117 insertions(+), 89 deletions(-) rename src/Traits/Filters/{ManagesFilters.php => HasFiltersCore.php} (72%) create mode 100644 tests/Http/Livewire/Traits/TestHelpers.php create mode 100644 tests/Http/Livewire/Traits/TestPaginationHelpers.php diff --git a/src/Traits/Filters/HasFilterQueryString.php b/src/Traits/Filters/HasFilterQueryString.php index a3fd56dea..179d1b9cc 100644 --- a/src/Traits/Filters/HasFilterQueryString.php +++ b/src/Traits/Filters/HasFilterQueryString.php @@ -6,11 +6,6 @@ trait HasFilterQueryString { - #[Locked] - public ?bool $queryStringStatusForFilter; - - protected ?string $queryStringAliasForFilter; - protected function queryStringHasFilterQueryString(): array { return ($this->queryStringForFilterIsEnabled()) ? @@ -20,6 +15,11 @@ protected function queryStringHasFilterQueryString(): array ] : []; } + public function queryStringForFilterIsEnabled(): bool + { + return $this->getQueryStringStatusForFilter() && $this->filtersAreEnabled(); + } + public function hasQueryStringStatusForFilter(): bool { return $this->hasQueryStringConfigStatus('filters'); @@ -30,38 +30,32 @@ public function getQueryStringStatusForFilter(): bool return $this->getQueryStringConfigStatus('filters'); } - public function queryStringForFilterIsEnabled(): bool + public function hasQueryStringAliasForFilter(): bool { + return $this->hasQueryStringConfigAlias('filters'); + } - return $this->getQueryStringStatusForFilter() && $this->filtersAreEnabled(); + public function getQueryStringAliasForFilter(): string + { + return $this->getQueryStringConfigAlias('filters'); } - public function setQueryStringStatusForFilter(bool $status): self + protected function setQueryStringStatusForFilter(bool $status): self { return $this->setQueryStringConfigStatus('filters', $status); } - public function setQueryStringForFilterEnabled(): self + protected function setQueryStringForFilterEnabled(): self { return $this->setQueryStringStatusForFilter(true); } - public function setQueryStringForFilterDisabled(): self + protected function setQueryStringForFilterDisabled(): self { return $this->setQueryStringStatusForFilter(false); } - public function hasQueryStringAliasForFilter(): bool - { - return $this->hasQueryStringConfigAlias('filters'); - } - - public function getQueryStringAliasForFilter(): string - { - return $this->getQueryStringConfigAlias('filters'); - } - - public function setQueryStringAliasForFilter(string $alias): self + protected function setQueryStringAliasForFilter(string $alias): self { return $this->setQueryStringConfigAlias('filters', $alias); } diff --git a/src/Traits/Filters/ManagesFilters.php b/src/Traits/Filters/HasFiltersCore.php similarity index 72% rename from src/Traits/Filters/ManagesFilters.php rename to src/Traits/Filters/HasFiltersCore.php index bc2a454dd..06a6fa1de 100644 --- a/src/Traits/Filters/ManagesFilters.php +++ b/src/Traits/Filters/HasFiltersCore.php @@ -2,14 +2,18 @@ namespace Rappasoft\LaravelLivewireTables\Traits\Filters; -use Illuminate\Database\Eloquent\Builder; +use Rappasoft\LaravelLivewireTables\Traits\Filters\Configuration\FilterConfiguration; +use Rappasoft\LaravelLivewireTables\Traits\Filters\Helpers\FilterHelpers; -trait ManagesFilters +trait HasFiltersCore { + use FilterConfiguration, + FilterHelpers; + /** * Sets Filter Default Values */ - public function mountManagesFilters(): void + public function mountHasFiltersCore(): void { $this->restoreFilterValues(); @@ -26,7 +30,7 @@ public function mountManagesFilters(): void } } - public function bootedManagesFilters(): void + public function bootedHasFiltersCore(): void { $this->setBuilder($this->builder()); diff --git a/src/Traits/WithFilters.php b/src/Traits/WithFilters.php index b80e30b3e..08f66a8a8 100644 --- a/src/Traits/WithFilters.php +++ b/src/Traits/WithFilters.php @@ -4,19 +4,17 @@ use Illuminate\Support\Collection; use Livewire\Attributes\Locked; -use Rappasoft\LaravelLivewireTables\Traits\Filters\{Configuration\FilterConfiguration, HasFilterGenericData, HasFilterMenu, HasFilterPills, HasFilterQueryString, HasFiltersStatus, HasFiltersVisibility, Helpers\FilterHelpers, ManagesFilters}; +use Rappasoft\LaravelLivewireTables\Traits\Filters\{HasFilterGenericData, HasFilterMenu, HasFilterPills, HasFilterQueryString, HasFiltersCore, HasFiltersStatus, HasFiltersVisibility}; trait WithFilters { - use FilterConfiguration, - FilterHelpers, - HasFiltersStatus, + use HasFiltersStatus, HasFilterGenericData, HasFilterMenu, HasFilterPills, HasFilterQueryString, HasFiltersVisibility, - ManagesFilters; + HasFiltersCore; // Set in JS public array $filterComponents = []; diff --git a/tests/Http/Livewire/BaseTable.php b/tests/Http/Livewire/BaseTable.php index 98394bfba..b71ff951b 100644 --- a/tests/Http/Livewire/BaseTable.php +++ b/tests/Http/Livewire/BaseTable.php @@ -3,60 +3,11 @@ namespace Rappasoft\LaravelLivewireTables\Tests\Http\Livewire; use Rappasoft\LaravelLivewireTables\DataTableComponent; +use Rappasoft\LaravelLivewireTables\Tests\Http\Livewire\Traits\TestHelpers; abstract class BaseTable extends DataTableComponent { - public string $paginationTest = 'standard'; - - public function enableDetailedPagination(string $type = 'standard') - { - $this->setPerPageAccepted([1, 3, 5, 10, 15, 25, 50])->setPerPage(3); - $this->setPaginationMethod($type); - $this->setDisplayPaginationDetailsEnabled(); - - } - - public function disableDetailedPagination(string $type = 'standard') - { - $this->setPerPageAccepted([1, 3, 5, 10, 15, 25, 50])->setPerPage(3); - $this->setPaginationMethod($type); - $this->setDisplayPaginationDetailsDisabled(); - } - - public function setPaginationTest(string $type) - { - $this->paginationTest = $type; - } + use TestHelpers; - public function bootAll() - { - $view = view('livewire-tables::datatable'); - - $this->boot(); - $this->bootedComponentUtilities(); - $this->bootedManagesFilters(); - $this->bootedWithColumns(); - $this->bootedWithColumnSelect(); - $this->booted(); - $this->mountManagesFilters(); - $this->mountComponentUtilities(); - $this->mountWithSorting(); - $this->renderAll($view); - } - - public function renderAll($view = null) - { - if (is_null($view)) { - $view = view('livewire-tables::datatable'); - } - $this->renderingWithColumns($view, $view->getData()); - $this->renderingWithColumnSelect($view, $view->getData()); - $this->renderingWithCustomisations($view, $view->getData()); - $this->renderingWithData($view, $view->getData()); - $this->renderingWithReordering($view, $view->getData()); - $this->renderingWithPagination($view, $view->getData()); - $this->render(); - - return $view; - } + public string $paginationTest = 'standard'; } diff --git a/tests/Http/Livewire/Traits/TestHelpers.php b/tests/Http/Livewire/Traits/TestHelpers.php new file mode 100644 index 000000000..726de7c6d --- /dev/null +++ b/tests/Http/Livewire/Traits/TestHelpers.php @@ -0,0 +1,40 @@ +boot(); + $this->bootedComponentUtilities(); + $this->bootedHasFiltersCore(); + $this->bootedWithColumns(); + $this->bootedWithColumnSelect(); + $this->booted(); + $this->mountHasFiltersCore(); + $this->mountComponentUtilities(); + $this->mountWithSorting(); + $this->renderAll($view); + } + + public function renderAll($view = null) + { + if (is_null($view)) { + $view = view('livewire-tables::datatable'); + } + $this->renderingWithColumns($view, $view->getData()); + $this->renderingWithColumnSelect($view, $view->getData()); + $this->renderingWithCustomisations($view, $view->getData()); + $this->renderingWithData($view, $view->getData()); + $this->renderingWithReordering($view, $view->getData()); + $this->renderingWithPagination($view, $view->getData()); + $this->render(); + + return $view; + } +} diff --git a/tests/Http/Livewire/Traits/TestPaginationHelpers.php b/tests/Http/Livewire/Traits/TestPaginationHelpers.php new file mode 100644 index 000000000..0d7efa359 --- /dev/null +++ b/tests/Http/Livewire/Traits/TestPaginationHelpers.php @@ -0,0 +1,26 @@ +setPerPageAccepted([1, 3, 5, 10, 15, 25, 50])->setPerPage(3); + $this->setPaginationMethod($type); + $this->setDisplayPaginationDetailsEnabled(); + + } + + public function disableDetailedPagination(string $type = 'standard') + { + $this->setPerPageAccepted([1, 3, 5, 10, 15, 25, 50])->setPerPage(3); + $this->setPaginationMethod($type); + $this->setDisplayPaginationDetailsDisabled(); + } + + public function setPaginationTest(string $type) + { + $this->paginationTest = $type; + } +} diff --git a/tests/Unit/DataTableComponentTest.php b/tests/Unit/DataTableComponentTest.php index 46502d83d..0292feafd 100644 --- a/tests/Unit/DataTableComponentTest.php +++ b/tests/Unit/DataTableComponentTest.php @@ -68,9 +68,9 @@ public function test_minimum_one_column_expected(): void { $this->expectException(\Rappasoft\LaravelLivewireTables\Exceptions\NoColumnsException::class); $table = new NoColumnsTable; - $table->mountManagesFilters(); + $table->mountHasFiltersCore(); $table->boot(); - $table->bootedManagesFilters(); + $table->bootedHasFiltersCore(); $table->bootedComponentUtilities(); $table->bootedWithColumns(); $table->bootedWithColumnSelect(); diff --git a/tests/Unit/Traits/Core/QueryStrings/QueryStringTestBase.php b/tests/Unit/Traits/Core/QueryStrings/QueryStringTestBase.php index 769ae168f..a55a70c9a 100644 --- a/tests/Unit/Traits/Core/QueryStrings/QueryStringTestBase.php +++ b/tests/Unit/Traits/Core/QueryStrings/QueryStringTestBase.php @@ -23,6 +23,21 @@ public function configure(): void { $this->setDataTableFingerprint('test'); } + + public function setQueryStringAliasForFilter(string $alias): self + { + return parent::setQueryStringAliasForFilter($alias); + } + + public function setQueryStringForFilterEnabled(): self + { + return parent::setQueryStringForFilterEnabled(); + } + + public function setQueryStringForFilterDisabled(): self + { + return parent::setQueryStringForFilterDisabled(); + } }; } } diff --git a/tests/Unit/Traits/WithMountTest.php b/tests/Unit/Traits/WithMountTest.php index 3a8b1e49d..35350da69 100644 --- a/tests/Unit/Traits/WithMountTest.php +++ b/tests/Unit/Traits/WithMountTest.php @@ -14,7 +14,7 @@ public function test_mounttable_gets_correct_first_item(): void $table = new PetsTableMount; $table->boot(); $table->mount(102); - $table->mountManagesFilters(); + $table->mountHasFiltersCore(); $table->bootedComponentUtilities(); $table->bootedWithColumns(); $table->bootedWithColumnSelect(); @@ -30,9 +30,9 @@ public function test_mounttable_gets_correct_first_item(): void $table2 = new PetsTableMount; $table2->boot(); $table2->mount(202); - $table2->mountManagesFilters(); + $table2->mountHasFiltersCore(); $table2->bootedComponentUtilities(); - $table2->bootedManagesFilters(); + $table2->bootedHasFiltersCore(); $table2->bootedWithColumns(); $table2->bootedWithColumnSelect(); $table2->booted(); @@ -46,8 +46,8 @@ public function test_mounttable_gets_correct_first_item(): void $table3 = new PetsTableMount; $table3->boot(); $table3->mount(); - $table3->mountManagesFilters(); - $table3->bootedManagesFilters(); + $table3->mountHasFiltersCore(); + $table3->bootedHasFiltersCore(); $table3->bootedComponentUtilities(); $table3->bootedWithColumns(); $table3->bootedWithColumnSelect(); From d56dc789109b960eb5d9f0752a3a51903d5dccc6 Mon Sep 17 00:00:00 2001 From: Joe <104938042+lrljoe@users.noreply.github.com> Date: Sun, 26 Jan 2025 02:35:43 +0000 Subject: [PATCH 14/24] Move Filter View Traits (#2189) * Initial Migration for FilterView Traits * Fix styling --- src/Views/Filter.php | 2 +- src/Views/Filters/BooleanFilter.php | 2 +- src/Views/Filters/DateFilter.php | 3 +-- src/Views/Filters/DateRangeFilter.php | 3 +-- src/Views/Filters/DateTimeFilter.php | 3 +-- src/Views/Filters/LivewireComponentArrayFilter.php | 3 +-- src/Views/Filters/LivewireComponentFilter.php | 3 +-- src/Views/Filters/MultiSelectDropdownFilter.php | 3 +-- src/Views/Filters/MultiSelectFilter.php | 3 +-- src/Views/Filters/NumberFilter.php | 3 +-- src/Views/Filters/NumberRangeFilter.php | 3 +-- src/Views/Filters/SelectFilter.php | 3 +-- src/Views/Filters/TextFilter.php | 3 +-- .../Traits}/FilterConfiguration.php | 2 +- .../Helpers => Filters/Traits}/FilterHelpers.php | 2 +- .../Traits}/HandlesApplyingFilter.php | 2 +- .../Filters => Filters/Traits}/HandlesDates.php | 2 +- .../Filters => Filters/Traits}/HandlesFieldName.php | 2 +- .../Traits}/HandlesWildcardStrings.php | 2 +- .../{Traits/Filters => Filters/Traits}/HasConfig.php | 2 +- .../Filters => Filters/Traits}/HasCustomPosition.php | 2 +- .../{Traits/Filters => Filters/Traits}/HasOptions.php | 2 +- .../Filters => Filters/Traits}/HasPillsLocale.php | 2 +- .../Filters => Filters/Traits}/HasVisibility.php | 2 +- src/Views/Filters/Traits/HasWireables.php | 10 ++++++++++ .../Filters => Filters/Traits}/IsArrayFilter.php | 2 +- .../{ => Filters}/Traits/IsExternalArrayFilter.php | 2 +- src/Views/{ => Filters}/Traits/IsExternalFilter.php | 2 +- src/Views/{ => Filters}/Traits/IsFilter.php | 7 ++----- .../Traits}/IsLivewireComponentFilter.php | 2 +- .../Filters => Filters/Traits}/IsNumericFilter.php | 2 +- .../Filters => Filters/Traits}/IsStringFilter.php | 2 +- .../Traits/Styling/HandlesFilterInputAttributes.php | 2 +- .../Traits/Styling/HandlesFilterLabelAttributes.php | 2 +- 34 files changed, 44 insertions(+), 48 deletions(-) rename src/Views/{Traits/Configuration => Filters/Traits}/FilterConfiguration.php (96%) rename src/Views/{Traits/Helpers => Filters/Traits}/FilterHelpers.php (98%) rename src/Views/{Traits/Filters => Filters/Traits}/HandlesApplyingFilter.php (89%) rename src/Views/{Traits/Filters => Filters/Traits}/HandlesDates.php (95%) rename src/Views/{Traits/Filters => Filters/Traits}/HandlesFieldName.php (85%) rename src/Views/{Traits/Filters => Filters/Traits}/HandlesWildcardStrings.php (97%) rename src/Views/{Traits/Filters => Filters/Traits}/HasConfig.php (84%) rename src/Views/{Traits/Filters => Filters/Traits}/HasCustomPosition.php (96%) rename src/Views/{Traits/Filters => Filters/Traits}/HasOptions.php (93%) rename src/Views/{Traits/Filters => Filters/Traits}/HasPillsLocale.php (88%) rename src/Views/{Traits/Filters => Filters/Traits}/HasVisibility.php (92%) create mode 100644 src/Views/Filters/Traits/HasWireables.php rename src/Views/{Traits/Filters => Filters/Traits}/IsArrayFilter.php (92%) rename src/Views/{ => Filters}/Traits/IsExternalArrayFilter.php (96%) rename src/Views/{ => Filters}/Traits/IsExternalFilter.php (68%) rename src/Views/{ => Filters}/Traits/IsFilter.php (67%) rename src/Views/{Traits/Filters => Filters/Traits}/IsLivewireComponentFilter.php (95%) rename src/Views/{Traits/Filters => Filters/Traits}/IsNumericFilter.php (85%) rename src/Views/{Traits/Filters => Filters/Traits}/IsStringFilter.php (84%) rename src/Views/{ => Filters}/Traits/Styling/HandlesFilterInputAttributes.php (93%) rename src/Views/{ => Filters}/Traits/Styling/HandlesFilterLabelAttributes.php (90%) diff --git a/src/Views/Filter.php b/src/Views/Filter.php index 966772149..76527c66f 100644 --- a/src/Views/Filter.php +++ b/src/Views/Filter.php @@ -3,7 +3,7 @@ namespace Rappasoft\LaravelLivewireTables\Views; use Illuminate\Support\Str; -use Rappasoft\LaravelLivewireTables\Views\Traits\IsFilter; +use Rappasoft\LaravelLivewireTables\Views\Filters\Traits\IsFilter; abstract class Filter { diff --git a/src/Views/Filters/BooleanFilter.php b/src/Views/Filters/BooleanFilter.php index f629a2c48..f15a494ec 100644 --- a/src/Views/Filters/BooleanFilter.php +++ b/src/Views/Filters/BooleanFilter.php @@ -3,7 +3,7 @@ namespace Rappasoft\LaravelLivewireTables\Views\Filters; use Rappasoft\LaravelLivewireTables\Views\Filter; -use Rappasoft\LaravelLivewireTables\Views\Traits\Core\HasWireables; +use Rappasoft\LaravelLivewireTables\Views\Filters\Traits\HasWireables; class BooleanFilter extends Filter { diff --git a/src/Views/Filters/DateFilter.php b/src/Views/Filters/DateFilter.php index 44e2aed51..d3d29ad52 100644 --- a/src/Views/Filters/DateFilter.php +++ b/src/Views/Filters/DateFilter.php @@ -3,8 +3,7 @@ namespace Rappasoft\LaravelLivewireTables\Views\Filters; use Rappasoft\LaravelLivewireTables\Views\Filter; -use Rappasoft\LaravelLivewireTables\Views\Traits\Core\HasWireables; -use Rappasoft\LaravelLivewireTables\Views\Traits\Filters\{HandlesDates, HasConfig, IsStringFilter}; +use Rappasoft\LaravelLivewireTables\Views\Filters\Traits\{HandlesDates, HasConfig, HasWireables, IsStringFilter}; class DateFilter extends Filter { diff --git a/src/Views/Filters/DateRangeFilter.php b/src/Views/Filters/DateRangeFilter.php index 4fe6fb67c..eb8777d2b 100644 --- a/src/Views/Filters/DateRangeFilter.php +++ b/src/Views/Filters/DateRangeFilter.php @@ -5,8 +5,7 @@ use Carbon\Carbon; use Illuminate\Support\Facades\Validator; use Rappasoft\LaravelLivewireTables\Views\Filter; -use Rappasoft\LaravelLivewireTables\Views\Traits\Core\HasWireables; -use Rappasoft\LaravelLivewireTables\Views\Traits\Filters\{HandlesDates, HasConfig, HasOptions}; +use Rappasoft\LaravelLivewireTables\Views\Filters\Traits\{HandlesDates, HasConfig, HasOptions, HasWireables}; class DateRangeFilter extends Filter { diff --git a/src/Views/Filters/DateTimeFilter.php b/src/Views/Filters/DateTimeFilter.php index 8bb2f05d0..5c3a77339 100644 --- a/src/Views/Filters/DateTimeFilter.php +++ b/src/Views/Filters/DateTimeFilter.php @@ -3,8 +3,7 @@ namespace Rappasoft\LaravelLivewireTables\Views\Filters; use Rappasoft\LaravelLivewireTables\Views\Filter; -use Rappasoft\LaravelLivewireTables\Views\Traits\Core\HasWireables; -use Rappasoft\LaravelLivewireTables\Views\Traits\Filters\{HandlesDates, HasConfig, IsStringFilter}; +use Rappasoft\LaravelLivewireTables\Views\Filters\Traits\{HandlesDates, HasConfig, HasWireables, IsStringFilter}; class DateTimeFilter extends Filter { diff --git a/src/Views/Filters/LivewireComponentArrayFilter.php b/src/Views/Filters/LivewireComponentArrayFilter.php index ce2c005a3..bc5ed5f92 100644 --- a/src/Views/Filters/LivewireComponentArrayFilter.php +++ b/src/Views/Filters/LivewireComponentArrayFilter.php @@ -3,8 +3,7 @@ namespace Rappasoft\LaravelLivewireTables\Views\Filters; use Rappasoft\LaravelLivewireTables\Views\Filter; -use Rappasoft\LaravelLivewireTables\Views\Traits\Core\HasWireables; -use Rappasoft\LaravelLivewireTables\Views\Traits\Filters\{HasOptions, IsArrayFilter, IsLivewireComponentFilter}; +use Rappasoft\LaravelLivewireTables\Views\Filters\Traits\{HasOptions, HasWireables, IsArrayFilter, IsLivewireComponentFilter}; class LivewireComponentArrayFilter extends Filter { diff --git a/src/Views/Filters/LivewireComponentFilter.php b/src/Views/Filters/LivewireComponentFilter.php index 82300635a..24555566b 100644 --- a/src/Views/Filters/LivewireComponentFilter.php +++ b/src/Views/Filters/LivewireComponentFilter.php @@ -3,8 +3,7 @@ namespace Rappasoft\LaravelLivewireTables\Views\Filters; use Rappasoft\LaravelLivewireTables\Views\Filter; -use Rappasoft\LaravelLivewireTables\Views\Traits\Core\HasWireables; -use Rappasoft\LaravelLivewireTables\Views\Traits\Filters\IsLivewireComponentFilter; +use Rappasoft\LaravelLivewireTables\Views\Filters\Traits\{HasWireables, IsLivewireComponentFilter}; class LivewireComponentFilter extends Filter { diff --git a/src/Views/Filters/MultiSelectDropdownFilter.php b/src/Views/Filters/MultiSelectDropdownFilter.php index 5e8ed566f..9a2283083 100644 --- a/src/Views/Filters/MultiSelectDropdownFilter.php +++ b/src/Views/Filters/MultiSelectDropdownFilter.php @@ -4,8 +4,7 @@ use Illuminate\Support\Collection; use Rappasoft\LaravelLivewireTables\Views\Filter; -use Rappasoft\LaravelLivewireTables\Views\Traits\Core\HasWireables; -use Rappasoft\LaravelLivewireTables\Views\Traits\Filters\{HasOptions, IsArrayFilter}; +use Rappasoft\LaravelLivewireTables\Views\Filters\Traits\{HasOptions, HasWireables, IsArrayFilter}; class MultiSelectDropdownFilter extends Filter { diff --git a/src/Views/Filters/MultiSelectFilter.php b/src/Views/Filters/MultiSelectFilter.php index c271354aa..d2cbb69e8 100644 --- a/src/Views/Filters/MultiSelectFilter.php +++ b/src/Views/Filters/MultiSelectFilter.php @@ -3,8 +3,7 @@ namespace Rappasoft\LaravelLivewireTables\Views\Filters; use Rappasoft\LaravelLivewireTables\Views\Filter; -use Rappasoft\LaravelLivewireTables\Views\Traits\Core\HasWireables; -use Rappasoft\LaravelLivewireTables\Views\Traits\Filters\{HasOptions, IsArrayFilter}; +use Rappasoft\LaravelLivewireTables\Views\Filters\Traits\{HasOptions, HasWireables, IsArrayFilter}; class MultiSelectFilter extends Filter { diff --git a/src/Views/Filters/NumberFilter.php b/src/Views/Filters/NumberFilter.php index 9aa8249ce..c45b7982b 100644 --- a/src/Views/Filters/NumberFilter.php +++ b/src/Views/Filters/NumberFilter.php @@ -3,8 +3,7 @@ namespace Rappasoft\LaravelLivewireTables\Views\Filters; use Rappasoft\LaravelLivewireTables\Views\Filter; -use Rappasoft\LaravelLivewireTables\Views\Traits\Core\HasWireables; -use Rappasoft\LaravelLivewireTables\Views\Traits\Filters\{IsNumericFilter}; +use Rappasoft\LaravelLivewireTables\Views\Filters\Traits\{HasWireables, IsNumericFilter}; class NumberFilter extends Filter { diff --git a/src/Views/Filters/NumberRangeFilter.php b/src/Views/Filters/NumberRangeFilter.php index ae3430b7d..fe3e47dde 100644 --- a/src/Views/Filters/NumberRangeFilter.php +++ b/src/Views/Filters/NumberRangeFilter.php @@ -3,8 +3,7 @@ namespace Rappasoft\LaravelLivewireTables\Views\Filters; use Rappasoft\LaravelLivewireTables\Views\Filter; -use Rappasoft\LaravelLivewireTables\Views\Traits\Core\HasWireables; -use Rappasoft\LaravelLivewireTables\Views\Traits\Filters\{HasOptions}; +use Rappasoft\LaravelLivewireTables\Views\Filters\Traits\{HasOptions, HasWireables}; class NumberRangeFilter extends Filter { diff --git a/src/Views/Filters/SelectFilter.php b/src/Views/Filters/SelectFilter.php index 4066f91cb..ec56c0fb5 100644 --- a/src/Views/Filters/SelectFilter.php +++ b/src/Views/Filters/SelectFilter.php @@ -4,8 +4,7 @@ use Illuminate\Support\Collection; use Rappasoft\LaravelLivewireTables\Views\Filter; -use Rappasoft\LaravelLivewireTables\Views\Traits\Core\HasWireables; -use Rappasoft\LaravelLivewireTables\Views\Traits\Filters\{HasOptions, IsStringFilter}; +use Rappasoft\LaravelLivewireTables\Views\Filters\Traits\{HasOptions, HasWireables, IsStringFilter}; class SelectFilter extends Filter { diff --git a/src/Views/Filters/TextFilter.php b/src/Views/Filters/TextFilter.php index 173c5c95c..6477acf67 100644 --- a/src/Views/Filters/TextFilter.php +++ b/src/Views/Filters/TextFilter.php @@ -3,8 +3,7 @@ namespace Rappasoft\LaravelLivewireTables\Views\Filters; use Rappasoft\LaravelLivewireTables\Views\Filter; -use Rappasoft\LaravelLivewireTables\Views\Traits\Core\HasWireables; -use Rappasoft\LaravelLivewireTables\Views\Traits\Filters\{HandlesWildcardStrings, IsStringFilter}; +use Rappasoft\LaravelLivewireTables\Views\Filters\Traits\{HandlesWildcardStrings, HasWireables, IsStringFilter}; class TextFilter extends Filter { diff --git a/src/Views/Traits/Configuration/FilterConfiguration.php b/src/Views/Filters/Traits/FilterConfiguration.php similarity index 96% rename from src/Views/Traits/Configuration/FilterConfiguration.php rename to src/Views/Filters/Traits/FilterConfiguration.php index 2bc40c32a..2bf3f11b5 100644 --- a/src/Views/Traits/Configuration/FilterConfiguration.php +++ b/src/Views/Filters/Traits/FilterConfiguration.php @@ -1,6 +1,6 @@ Date: Sun, 9 Feb 2025 06:51:25 +0000 Subject: [PATCH 15/24] Filter Rationalisation & Livewire Array Filter improvements (#2191) * Partial Merges * Fix styling * Minor adjustments * Fix styling * Minor tweaks for return type * Minor dochint fixes * Migration to support Livewire Filter Array filter pills, docs updates, and reverting away from computed properties for the theme determination * Fix styling * Minor tweaks to handle HTML array separators * Fix broken separator * Minor tweaks * Tweaks & Adjustments * Fix styling * Minor Tweaks to Tests * Fix styling * Test Fixes * Fix styling * Test Tweaks * Fix styling * Tweaks for tests * Fix styling * Tweaks to Base * Fix styling --- docs/column-types/array_column.md | 4 +- docs/column-types/avg_column.md | 2 +- docs/column-types/count_column.md | 2 +- .../column-types/livewire_component_column.md | 2 +- .../filters-livewire-component-array.md | 51 +++ docs/filters/available-component-methods.md | 130 +------ docs/filters/available-filter-methods.md | 279 ++++++--------- docs/filters/filter-pills.md | 315 ++++++++++++++++ docs/start/recommended.md | 2 +- resources/js/laravel-livewire-tables.js | 335 +++++++++++++++++- resources/js/laravel-livewire-tables.min.js | 2 +- .../filters/livewire-array-filter.blade.php | 4 + .../components/includes/actions.blade.php | 12 +- .../components/includes/loading.blade.php | 14 +- .../views/components/pagination.blade.php | 76 ++-- .../table/td/bulk-actions.blade.php | 11 +- .../components/table/td/reorder.blade.php | 10 +- resources/views/components/table/th.blade.php | 23 +- .../table/th/bulk-actions.blade.php | 11 +- .../table/th/collapsed-columns.blade.php | 17 +- .../views/components/table/th/plain.blade.php | 7 +- .../components/table/th/sort-icons.blade.php | 7 +- .../table/tr/bulk-actions.blade.php | 44 +-- resources/views/components/tools.blade.php | 7 +- .../components/tools/filter-label.blade.php | 12 +- .../components/tools/filter-pills.blade.php | 56 +-- .../filter-pills/buttons/reset-all.blade.php | 22 +- .../buttons/reset-filter.blade.php | 34 +- .../tools/filter-pills/item.blade.php | 28 -- .../tools/filter-pills/pills-item.blade.php | 28 ++ .../components/tools/sorting-pills.blade.php | 32 +- .../views/components/tools/toolbar.blade.php | 41 +-- .../toolbar/items/bulk-actions.blade.php | 38 +- .../toolbar/items/column-select.blade.php | 12 +- .../toolbar/items/filter-button.blade.php | 26 +- .../filter-popover/clear-button.blade.php | 9 +- .../toolbar/items/filter-slidedown.blade.php | 28 +- .../items/pagination-dropdown.blade.php | 16 +- .../toolbar/items/reorder-buttons.blade.php | 20 +- resources/views/datatable.blade.php | 83 +++-- resources/views/includes/offline.blade.php | 10 +- .../Filters/FilterPillData.php | 179 ++++++++++ .../Filters/StandardFilterPillData.php | 43 +++ .../Filters/LivewireArrayExternalFilter.php | 35 ++ .../HandlesCoreMethodsForExternalFilter.php | 13 + ...HandlesCorePropertiesForExternalFilter.php | 48 +++ .../HandlesTableEventsForExternalFilter.php | 25 ++ .../HandlesUpdateStatusForExternalFilter.php | 12 + .../Core/Search/HandlesSearchStatus.php | 6 + .../Configuration/FilterConfiguration.php | 15 +- .../HandlesLivewireComponentFilters.php | 44 +++ src/Traits/Filters/HandlesPillsData.php | 55 +++ src/Traits/Filters/HasFilterCore.php | 45 +++ src/Traits/Filters/HasFilterPills.php | 8 + src/Traits/Filters/Helpers/FilterHelpers.php | 10 + .../Filters/Helpers/FilterPillsHelpers.php | 35 +- .../Helpers/FilterVisibilityHelpers.php | 7 + .../FilterPillsStylingConfiguration.php | 35 +- .../Filters/Styling/HasFilterPillsStyling.php | 2 + .../Helpers/FilterPillsStylingHelpers.php | 6 + src/Traits/Helpers/ActionsHelpers.php | 12 + src/Traits/Helpers/ColumnSelectHelpers.php | 1 + src/Traits/Helpers/PaginationHelpers.php | 6 + src/Traits/Helpers/ReorderingHelpers.php | 7 + .../FilterPillsStylingConfiguration.php | 27 -- .../Helpers/FilterPillsStylingHelpers.php | 26 -- .../Styling/Helpers/ToolsStylingHelpers.php | 3 +- src/Traits/WithFilters.php | 6 +- .../Filters/LivewireComponentArrayFilter.php | 7 +- .../Filters/Traits/FilterConfiguration.php | 50 --- src/Views/Filters/Traits/FilterHelpers.php | 84 ----- .../Filters/Traits/HandlesClearButton.php | 20 ++ src/Views/Filters/Traits/HandlesDates.php | 3 +- .../Filters/Traits/HandlesDefaultValue.php | 36 ++ src/Views/Filters/Traits/HasFilterLabel.php | 35 ++ src/Views/Filters/Traits/HasFilterPills.php | 66 ++++ .../Filters/Traits/IsExternalArrayFilter.php | 2 +- src/Views/Filters/Traits/IsFilter.php | 21 +- .../Traits/IsLivewireComponentFilter.php | 5 + .../Traits/Pills/HandlesPillsAsHtml.php | 30 ++ .../Traits/Pills/HandlesPillsCustomBlade.php | 31 ++ .../HandlesPillsLocale.php} | 4 +- .../Styling/HandlesFilterPillsAttributes.php | 85 +++++ .../FilterPillDataTest.php | 183 ++++++++++ tests/Unit/Views/Filters/FilterTestCase.php | 89 +++++ 85 files changed, 2426 insertions(+), 898 deletions(-) create mode 100644 docs/filter-types/filters-livewire-component-array.md create mode 100644 docs/filters/filter-pills.md create mode 100644 resources/views/components/external/filters/livewire-array-filter.blade.php delete mode 100644 resources/views/components/tools/filter-pills/item.blade.php create mode 100644 resources/views/components/tools/filter-pills/pills-item.blade.php create mode 100644 src/DataTransferObjects/Filters/FilterPillData.php create mode 100644 src/DataTransferObjects/Filters/StandardFilterPillData.php create mode 100644 src/External/Filters/LivewireArrayExternalFilter.php create mode 100644 src/External/Filters/Traits/HandlesCoreMethodsForExternalFilter.php create mode 100644 src/External/Filters/Traits/HandlesCorePropertiesForExternalFilter.php create mode 100644 src/External/Filters/Traits/HandlesTableEventsForExternalFilter.php create mode 100644 src/External/Filters/Traits/HandlesUpdateStatusForExternalFilter.php create mode 100644 src/Traits/Filters/HandlesLivewireComponentFilters.php create mode 100644 src/Traits/Filters/HandlesPillsData.php create mode 100644 src/Traits/Filters/HasFilterCore.php delete mode 100644 src/Traits/Styling/Configuration/FilterPillsStylingConfiguration.php delete mode 100644 src/Traits/Styling/Helpers/FilterPillsStylingHelpers.php create mode 100644 src/Views/Filters/Traits/HandlesClearButton.php create mode 100644 src/Views/Filters/Traits/HandlesDefaultValue.php create mode 100644 src/Views/Filters/Traits/HasFilterLabel.php create mode 100644 src/Views/Filters/Traits/HasFilterPills.php create mode 100644 src/Views/Filters/Traits/Pills/HandlesPillsAsHtml.php create mode 100644 src/Views/Filters/Traits/Pills/HandlesPillsCustomBlade.php rename src/Views/Filters/Traits/{HasPillsLocale.php => Pills/HandlesPillsLocale.php} (83%) create mode 100644 src/Views/Filters/Traits/Styling/HandlesFilterPillsAttributes.php create mode 100644 tests/Unit/DataTransferObjects/FilterPillDataTest.php diff --git a/docs/column-types/array_column.md b/docs/column-types/array_column.md index 7802e78aa..3d612248d 100644 --- a/docs/column-types/array_column.md +++ b/docs/column-types/array_column.md @@ -5,7 +5,7 @@ weight: 2 Array columns provide an easy way to work with and display an array of data from a field. -``` +```php ArrayColumn::make('notes', 'name') ->data(fn($value, $row) => ($row->notes)) ->outputFormat(fn($index, $value) => "".$value->name."") @@ -16,7 +16,7 @@ ArrayColumn::make('notes', 'name') ### Empty Value You may define the default/empty value using the "emptyValue" method -``` +```php ArrayColumn::make('notes', 'name') ->emptyValue('Unknown'), ``` diff --git a/docs/column-types/avg_column.md b/docs/column-types/avg_column.md index d5e4b32fb..f0f7680ac 100644 --- a/docs/column-types/avg_column.md +++ b/docs/column-types/avg_column.md @@ -5,7 +5,7 @@ weight: 3 Avg columns provide an easy way to display the "Average" of a field on a relation. -``` +```php AvgColumn::make('Average Related User Age') ->setDataSource('users','age') ->sortable(), diff --git a/docs/column-types/count_column.md b/docs/column-types/count_column.md index 4b1fe6c3a..beb7d3437 100644 --- a/docs/column-types/count_column.md +++ b/docs/column-types/count_column.md @@ -5,7 +5,7 @@ weight: 8 Count columns provide an easy way to display the "Count" of a relation. -``` +```php CountColumn::make('Related Users') ->setDataSource('users') ->sortable(), diff --git a/docs/column-types/livewire_component_column.md b/docs/column-types/livewire_component_column.md index ebeb72724..f48859641 100644 --- a/docs/column-types/livewire_component_column.md +++ b/docs/column-types/livewire_component_column.md @@ -8,7 +8,7 @@ Livewire Component Columns allow for the use of a Livewire Component as a Column This is **not recommended** as due to the nature of Livewire, it becomes inefficient at scale. ## component -``` +```php LivewireComponentColumn::make('Action') ->component('PathToLivewireComponent'), diff --git a/docs/filter-types/filters-livewire-component-array.md b/docs/filter-types/filters-livewire-component-array.md new file mode 100644 index 000000000..86b2491dc --- /dev/null +++ b/docs/filter-types/filters-livewire-component-array.md @@ -0,0 +1,51 @@ +--- +title: Livewire Custom Array Filter (Beta) +weight: 13 +--- + +**IN BETA** +This feature is currently in beta, and use in production is not recommended. + +### Usage +This allows you to use a child/nested Livewire Component in place of the existing Filters, giving you more control over the look/feel/behaviour of a filter. This version supports use of returning an array of values for use in filtering. + +To use a LivewireComponentArrayFilter, you must include it in your namespace: +```php +use Rappasoft\LaravelLivewireTables\Views\Filters\LivewireComponentArrayFilter; +``` + +When creating a filter: +- Specify a unique name +- Set the path to a valid Livewire Component +- Define a filter() callback to define how the returned value will be used. + +```php + public function filters(): array + { + return [ + LivewireComponentArrayFilter::make('My External Filter') + ->setLivewireComponent('my-test-external-filter') + ->filter(function (Builder $builder, array $values) { + $builder->whereIn('foreign_id', $values); + }), + ]; + } +``` + +### setPillsSeparator +As this is an array, you can define the separator to use between pills values, by default this is set to ", " + +```php + public function filters(): array + { + return [ + LivewireComponentArrayFilter::make('My External Filter') + ->setLivewireComponent('my-test-external-filter') + ->setPillsSeparator(' OR ') + ->filter(function (Builder $builder, array $values) { + $builder->whereIn('foreign_id', $values); + }), + ]; + } +``` + diff --git a/docs/filters/available-component-methods.md b/docs/filters/available-component-methods.md index bf3c51c43..ffa02f29c 100644 --- a/docs/filters/available-component-methods.md +++ b/docs/filters/available-component-methods.md @@ -85,135 +85,9 @@ public function configure(): void --- -## setFilterPillsStatus +## Pills -**Enabled by default**, show/hide the filter pills. - -```php -public function configure(): void -{ - $this->setFilterPillsStatus(true); - $this->setFilterPillsStatus(false); -} -``` - -## setFilterPillsEnabled - -Show the filter pills for the component. - -```php -public function configure(): void -{ - // Shorthand for $this->setFilterPillsStatus(true) - $this->setFilterPillsEnabled(); -} -``` - -## setFilterPillsDisabled - -Hide the filter pills for the component. - -```php -public function configure(): void -{ - // Shorthand for $this->setFilterPillsStatus(false) - $this->setFilterPillsDisabled(); -} -``` - -## setFilterPillsItemAttributes -Allows for customisation of the appearance of the "Filter Pills Item" - -Note that this utilises a refreshed approach for attributes, and allows for appending to, or replacing the styles and colors independently, via the below methods. - -#### default-colors -Setting to false will disable the default colors for the Filter Pills Item, the default colors are: - -Bootstrap: None - -Tailwind: `bg-indigo-100 text-indigo-800 dark:bg-indigo-200 dark:text-indigo-900` - -#### default-styling -Setting to false will disable the default styling for the Filter Pills Item, the default styling is: - -Bootstrap 4: `badge badge-pill badge-info d-inline-flex align-items-center` - -Bootstrap 5: `badge rounded-pill bg-info d-inline-flex align-items-center` - -Tailwind: `inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium leading-4 capitalize` - -```php -public function configure(): void -{ - $this->setFilterPillsItemAttributes([ - 'class' => 'bg-rose-300 text-rose-800 dark:bg-indigo-200 dark:text-indigo-900', // Add these classes to the filter pills item - 'default-colors' => false, // Do not output the default colors - 'default-styling' => true // Output the default styling - ]); -} -``` - -## setFilterPillsResetFilterButtonAttributes -Allows for customisation of the appearance of the "Filter Pills Reset Filter Button" - -Note that this utilises a refreshed approach for attributes, and allows for appending to, or replacing the styles and colors independently, via the below methods. - -#### default-colors -Setting to false will disable the default colors for the Filter Pills Reset Filter Button, the default colors are: - -Bootstrap: None - -Tailwind: `text-indigo-400 hover:bg-indigo-200 hover:text-indigo-500 focus:bg-indigo-500 focus:text-white` - -#### default-styling -Setting to false will disable the default styling for the Filter Pills Reset Filter Button, the default styling is: - -Bootstrap: `text-white ml-2` - -Tailwind: `flex-shrink-0 ml-0.5 h-4 w-4 rounded-full inline-flex items-center justify-center focus:outline-none` - -```php -public function configure(): void -{ - $this->setFilterPillsResetFilterButtonAttributes([ - 'class' => 'text-rose-400 hover:bg-rose-200 hover:text-rose-500 focus:bg-rose-500', // Add these classes to the filter pills reset filter button - 'default-colors' => false, // Do not output the default colors - 'default-styling' => true // Output the default styling - ]); -} -``` - -## setFilterPillsResetAllButtonAttributes -Allows for customisation of the appearance of the "Filter Pills Reset All Button" - -Note that this utilises a refreshed approach for attributes, and allows for appending to, or replacing the styles and colors independently, via the below methods. - -#### default-colors -Setting to false will disable the default colors for the Filter Pills Reset All Button, the default colors are: - -Bootstrap: None - -Tailwind: `bg-gray-100 text-gray-800 dark:bg-gray-200 dark:text-gray-900` - -#### default-styling -Setting to false will disable the default styling for the Filter Pills Reset All Button, the default styling is: - -Bootstrap 4: `badge badge-pill badge-light` - -Bootstrap 5: `badge rounded-pill bg-light text-dark text-decoration-none` - -Tailwind: `inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium` - -```php -public function configure(): void -{ - $this->setFilterPillsResetAllButtonAttributes([ - 'class' => 'bg-rose-100 text-rose-800 dark:bg-gray-200 dark:text-gray-900', // Add these classes to the filter pills reset all button - 'default-colors' => false, // Do not output the default colors - 'default-styling' => true // Output the default styling - ]); -} -``` +See the [Filter Pills](./filter-pills) documentation for help with configuring the pills --- diff --git a/docs/filters/available-filter-methods.md b/docs/filters/available-filter-methods.md index 9597372d4..249273109 100644 --- a/docs/filters/available-filter-methods.md +++ b/docs/filters/available-filter-methods.md @@ -5,36 +5,10 @@ weight: 6 The following methods are available on the filter object. These are "filter-specific" methods. ----- +Ensure you check out: +- [Available Component Methods](./available-component-methods) documentation for Table Wide configuration +- [Filter Pills](./filter-pills) documentation for help with configuring the pills for a filter -## setFilterPillTitle - -By default, the filter pill title is the filter name, but you can make it whatever you want: - -```php -SelectFilter::make('Active') - ->setFilterPillTitle('User Status') -``` - -## setFilterPillValues - -If you have numeric, or generated keys as your filter option values, they probably don't look too nice in the filter pill. You can set the values to be displayed in the filter pill: - -```php -SelectFilter::make('Active') - ->setFilterPillTitle('User Status') - ->setFilterPillValues([ - '1' => 'Active', - '0' => 'Inactive', - ]) - ->options([ - '' => 'All', - '1' => 'Yes', - '0' => 'No', - ]) -``` - -Now instead of `Active: Yes` it will say `User Status: Active` ## hiddenFromMenus @@ -80,8 +54,96 @@ By default the `clear` button will reset all filters to their defaults. You can SelectFilter::make('Active') ->notResetByClearButton() ``` - -## setFilterSlidedownRow + +## setCustomView +Use a fully custom view for a filter. This will utilise solely your view when rendering this filter. Note that the following methods will no longer apply to a filter using this: +- setCustomFilterLabel +- setFilterLabelAttributes + +```php +TextFilter::make('Name') + ->setCustomView('text-custom-view'), +``` + +## Config + +If the filter takes any config options, you can set them with the `config` method: + +```php + DateFilter::make('Date') + ->config([ + 'min' => '2020-01-01', + 'max' => '2021-12-31', + ]) +``` + +## Customising Wireable Behaviour + +For the following Filters, you may customise how the input is wire:model into the Table Component: + +- DateFilter (Defaults to Live) +- DateTimeFilter (Defaults to Live) +- MultiSelectDropdownFilter (Defaults to live.debounce.250ms) +- MultiSelectFilter (Defaults to live.debounce.250ms) +- NumberFilter (Defaults to Blur) +- SelectFilter (Defaults to Live) +- TextFilter (Defaults to Blur) + +You may override this using the following methods, on any of the above Filter types: + +### setWireBlur() +Forces the filter to use a wire:model.blur approach +```php + TextFilter::make('Name') + ->config([ + 'placeholder' => 'Search Name', + 'maxlength' => '25', + ]) + ->setWireBlur() +``` + +### setWireDefer() +Forces the filter to use a wire:model approach +```php + TextFilter::make('Name') + ->config([ + 'placeholder' => 'Search Name', + 'maxlength' => '25', + ]) + ->setWireDefer() +``` + +### setWireLive() +Forces the fitler to use a wire:model.live approach +```php + TextFilter::make('Name') + ->config([ + 'placeholder' => 'Search Name', + 'maxlength' => '25', + ]) + ->setWireLive() +``` + +### setWireDebounce(int $debounceDelay) +Allows you to pass a string to use a wire:model.live.debounce.Xms approach +```php + TextFilter::make('Name') + ->config([ + 'placeholder' => 'Search Name', + 'maxlength' => '25', + ]) + ->setWireDebounce(50) +``` + +--- + +## Styling + +These methods allow you to over-ride default styling for individual Filters + +--- + +### setFilterSlidedownRow This method applies only when using the Slide Down approach to filter display. By default the filters will be displayed in the order that they are listed in the filters() method. This method allows you to specify the row that the filter will be listed. When multiple filters are placed on the same row, and a mobile device is used, then the first filter listed will "win" that row. @@ -92,7 +154,7 @@ SelectFilter::make('Active') ->setFilterSlidedownRow(1) ``` -## setFilterSlidedownColspan +### setFilterSlidedownColspan This method applies only when using the Slide Down approach to filter display. By default each filter will take up one column, with the number of columns determined by the size of the screen, this ranges from 1 on a mobile device, to a maximum of 5 on a large display. This method allows you to specify the number of columns that the filter should span. It will span the number of columns specified, up to the number of columns available (depending on screen size). @@ -107,37 +169,9 @@ DateFilter::make('Date') ->setFilterSlidedownColspan('2') ``` -## setFilterPillBlade - -Set a blade file for use in displaying the filter values in the pills area. You can use this in conjunction with setFilterPillValues() to prettify your applied filter values display. You will receive two properties ($filter) containing the filter instance, and ($value) containing the filter value. - -```php -SelectFilter::make('Active') - ->setFilterPillBlade('path.to.blade') -``` - -Example blade: -```php -@aware(['component']) -@props(['filter']) - - - {{ $filter->getFilterPillTitle() }} - ({{ $filter->getFilterPillValue($value) }}) - - - -``` +--- -## setCustomFilterLabel +### setCustomFilterLabel Set a custom blade file for the filter's label. This will be used in both the Pop-Over and SlideDown filter displays, you should therefore ensure that you cater for the different filter layouts. @@ -158,27 +192,27 @@ You will receive several properties to your blade, explained here: Example label blade: ```php -@props(['filter', 'filterLayout' => 'popover', 'tableName' => 'table', 'isTailwind' => false, 'isBootstrap' => false, 'isBootstrap4' => false, 'isBootstrap5' => false, 'customLabelAttributes' => []]) - - -