From 1f81ce361cb454b1655d6e2a7ac031bc1e3b2ede Mon Sep 17 00:00:00 2001 From: Sam Light Date: Thu, 27 Mar 2025 10:53:34 +0000 Subject: Seperating toolbar into its own class and views --- resources/views/table.blade.php | 39 +--------- resources/views/toolbar.blade.php | 17 +++++ resources/views/toolbar/column-select.blade.php | 16 ++++ resources/views/toolbar/page-size.blade.php | 5 ++ resources/views/toolbar/search.blade.php | 3 + src/Columns/Column.php | 19 ++--- src/TableComponent.php | 78 ++++++++++++------- src/Toolbar.php | 88 ++++++++++++++++++++++ src/Toolbar/ColumnSelect.php | 17 +++++ src/Toolbar/Filter.php | 8 ++ src/Toolbar/Item.php | 32 ++++++++ src/Toolbar/PageSize.php | 19 +++++ src/Toolbar/Search.php | 25 ++++++ workbench/app/Livewire/CategoriesTable.php | 3 +- workbench/app/Livewire/OrdersTable.php | 3 +- workbench/app/Livewire/ProductsTable.php | 17 ++++- workbench/app/Livewire/Table.php | 16 ++++ .../views/components/layouts/app.blade.php | 1 + 18 files changed, 324 insertions(+), 82 deletions(-) create mode 100644 resources/views/toolbar.blade.php create mode 100644 resources/views/toolbar/column-select.blade.php create mode 100644 resources/views/toolbar/page-size.blade.php create mode 100644 resources/views/toolbar/search.blade.php create mode 100644 src/Toolbar.php create mode 100644 src/Toolbar/ColumnSelect.php create mode 100644 src/Toolbar/Filter.php create mode 100644 src/Toolbar/Item.php create mode 100644 src/Toolbar/PageSize.php create mode 100644 src/Toolbar/Search.php create mode 100644 workbench/app/Livewire/Table.php diff --git a/resources/views/table.blade.php b/resources/views/table.blade.php index 783255e..bcefe57 100644 --- a/resources/views/table.blade.php +++ b/resources/views/table.blade.php @@ -1,42 +1,5 @@
- @if($searchable || $showColumnSelect || $showPageSizeSelect) -
-
- @if($searchable) - - @endif -
-
- @if($showColumnSelect) - - @endif - @if($showPageSizeSelect) - - @endif -
-
- @endif + {{ $toolbar?->render() }} @foreach($columns as $column) diff --git a/resources/views/toolbar.blade.php b/resources/views/toolbar.blade.php new file mode 100644 index 0000000..fee00b4 --- /dev/null +++ b/resources/views/toolbar.blade.php @@ -0,0 +1,17 @@ +
+
+ @foreach ($startItems as $item) + {{ $item->render() }} + @endforeach +
+
+ @foreach ($midItems as $item) + {{ $item->render() }} + @endforeach +
+
+ @foreach ($endItems as $item) + {{ $item->render() }} + @endforeach +
+
diff --git a/resources/views/toolbar/column-select.blade.php b/resources/views/toolbar/column-select.blade.php new file mode 100644 index 0000000..6fa7474 --- /dev/null +++ b/resources/views/toolbar/column-select.blade.php @@ -0,0 +1,16 @@ + diff --git a/resources/views/toolbar/page-size.blade.php b/resources/views/toolbar/page-size.blade.php new file mode 100644 index 0000000..cc35ff4 --- /dev/null +++ b/resources/views/toolbar/page-size.blade.php @@ -0,0 +1,5 @@ + diff --git a/resources/views/toolbar/search.blade.php b/resources/views/toolbar/search.blade.php new file mode 100644 index 0000000..04fd000 --- /dev/null +++ b/resources/views/toolbar/search.blade.php @@ -0,0 +1,3 @@ + diff --git a/src/Columns/Column.php b/src/Columns/Column.php index 94e386f..895708f 100644 --- a/src/Columns/Column.php +++ b/src/Columns/Column.php @@ -28,24 +28,24 @@ class Column { $this->showInSelect = $this->title !== null; } - public static function make(string $name, ?string $title = null) : static + public static function make(string $name, ?string $title = null): static { return new static($name, $title); } - public function setTable(TableComponent $table) : void + public function setTable(TableComponent $table): void { $this->table = $table; } - public function getTitle() + public function getTitle(): string { return $this->title; } - private function defaultSlot(Model $row) + private function defaultSlot(Model $row): string { - return $row->{$this->name}; + return (string) $row->{$this->name}; } public function slot(callable $fn) : static @@ -77,22 +77,23 @@ class Column { return $this; } - public function showInSelect($show = true) + public function showInSelect($show = true): static { $this->showInSelect = $show; + return $this; } - public function getShowInSelect() + public function getShowInSelect(): bool { return $this->showInSelect; } - protected function getContent(Model $row) + protected function getContent(Model $row): string { return $this->slotFn?->call($this, $row, $this) ?? $this->defaultSlot($row); } - public function view(Model $row) + public function view(Model $row): HtmlString { $attributes = $this->tdAttributesFn?->call($this, $row) ?? []; $attributes = (new ComponentAttributeBag($attributes))->toHtml(); diff --git a/src/TableComponent.php b/src/TableComponent.php index b8fae6a..0a55d5e 100644 --- a/src/TableComponent.php +++ b/src/TableComponent.php @@ -9,6 +9,7 @@ use Livewire\Attributes\Url; use Illuminate\Pagination\Paginator; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Str; +use Illuminate\Support\Collection; use Exception; @@ -18,35 +19,65 @@ abstract class TableComponent extends Component // Config protected $paginationTheme = 'bootstrap'; - protected bool $searchable = true; - protected int $searchMinLength = 2; - protected int $searchDebounce = 250; - protected bool $showPageSizeSelect = true; - protected bool $showColumnSelect = true; - - protected array $pageSizes = [10, 25, 50]; - protected $model = null; + protected int $defaultPageSize = 10; // Properties + #[Url] public string $search = ''; #[Url] - public int $pageSize = 0; + public int $pageSize; public array $activeColumns = []; - public function __construct() + public function mount() { - $this->pageSize = $this->pageSizes[0] ?? 0; + $this->setDefaultActiveColumns(); + $this->setDefaultPageSize(); } - public function mount() + protected function setDefaultPageSize(): void + { + if (!isset($this->pageSize)) { + $this->pageSize = $this->defaultPageSize; + } + } + + protected function setDefaultActiveColumns(): void { foreach($this->getColumns() as $column) { $this->activeColumns[] = $column->name; } } + protected function isSearching(): bool + { + $search = $this->getToolbar()->getSearch(); + return $search !== null && Str::length($this->search) >= $search->getMinLength(); + } + + public function updatedSearch(): void + { + if ($this->isSearching()) { + $this->resetPage(); + } + } + + protected function toolbar(): ?Toolbar + { + return null; + } + + private ?Toolbar $toolbarCache; + + protected function getToolbar(): ?Toolbar + { + if (!isset($this->_toolbar)) { + $this->toolbar = $this->toolbar(); + } + return $this->toolbar; + } + protected function query() : Builder { if($this->model === null) { @@ -60,25 +91,19 @@ abstract class TableComponent extends Component protected function search(Builder $builder, string $search) : void {} - protected function filters() : array - { - return []; - } - protected function buildQuery() : Builder { $query = $this->query(); - if($this->searchable && (Str::length($this->search) >= $this->searchMinLength)) { + if ($this->isSearching()) { $this->search($query, $this->search); } return $query; } - private $columnsCache = null; - - protected function getColumns() + private ?Collection $columnsCache = null; + public function getColumns() { if($this->columnsCache === null) { $this->columnsCache = collect($this->columns())->each( @@ -94,17 +119,12 @@ abstract class TableComponent extends Component $data = $this->buildQuery()->paginate($this->pageSize); $allColumns = $this->getColumns(); $columns = $allColumns->filter(fn($c) => in_array($c->name,$this->activeColumns)); + $toolbar = $this->toolbar(); Paginator::defaultView('laralight-tables::pagination'); - return view('laralight-tables::table', [ - 'searchable' => $this->searchable, - 'searchDebounce' => $this->searchDebounce, - 'showPageSizeSelect' => $this->showPageSizeSelect, - 'showColumnSelect' => $this->showColumnSelect, - 'pageSizes' => $this->pageSizes, - ] + compact( - 'data', 'allColumns', 'columns' + return view('laralight-tables::table', compact( + 'data', 'allColumns', 'columns', 'toolbar', )); } } diff --git a/src/Toolbar.php b/src/Toolbar.php new file mode 100644 index 0000000..2db39f5 --- /dev/null +++ b/src/Toolbar.php @@ -0,0 +1,88 @@ +startItems = collect(); + $this->midItems = collect(); + $this->endItems = collect(); + } + + private function addItem(Collection $list, ToolbarItem $item): static + { + $item->setToolbar($this); + + if ($item instanceof FilterItem) { + $this->filterItems->push($item); + } + else if ($item instanceof PageSizeItem) { + $this->pageSizeItem = $item; + } + else if ($item instanceof SearchItem) { + $this->searchItem = $item; + } + + $list->push($item); + return $this; + } + + public function addStartItem(ToolbarItem $item): static + { + return $this->addItem($this->startItems, $item); + } + + public function addMidItem(ToolbarItem $item): static + { + return $this->addItem($this->midItems, $item); + } + + public function addEndItem(ToolbarItem $item): static + { + return $this->addItem($this->endItems, $item); + } + + public function getTable(): TableComponent + { + return $this->table; + } + + public function getSearch(): ?SearchItem + { + return $this->searchItem; + } + + public function getPageSize(): ?PageSizeItem + { + return $this->pageSizeItem; + } + + public function render(): View + { + return view('laralight-tables::toolbar', [ + 'startItems' => $this->startItems, + 'midItems' => $this->midItems, + 'endItems' => $this->endItems, + ]); + } + +} diff --git a/src/Toolbar/ColumnSelect.php b/src/Toolbar/ColumnSelect.php new file mode 100644 index 0000000..a70c49a --- /dev/null +++ b/src/Toolbar/ColumnSelect.php @@ -0,0 +1,17 @@ + $this->getTable()->getColumns() + ]); + } +} diff --git a/src/Toolbar/Filter.php b/src/Toolbar/Filter.php new file mode 100644 index 0000000..ebda2c6 --- /dev/null +++ b/src/Toolbar/Filter.php @@ -0,0 +1,8 @@ +toolbar = $toolbar; + } + + public function getToolbar(): Toolbar + { + return $this->toolbar; + } + + public function getTable(): TableComponent + { + return $this->getToolbar()->getTable(); + } + + abstract public function render(): View|HtmlString|string|null; + +} diff --git a/src/Toolbar/PageSize.php b/src/Toolbar/PageSize.php new file mode 100644 index 0000000..9c2821a --- /dev/null +++ b/src/Toolbar/PageSize.php @@ -0,0 +1,19 @@ + $this->pageSizes, + ]); + } +} diff --git a/src/Toolbar/Search.php b/src/Toolbar/Search.php new file mode 100644 index 0000000..0b0dc37 --- /dev/null +++ b/src/Toolbar/Search.php @@ -0,0 +1,25 @@ +minLength; + } + + public function render(): View + { + return view('laralight-tables::toolbar.search', [ + 'debounce' => $this->debounce, + ]); + } +} diff --git a/workbench/app/Livewire/CategoriesTable.php b/workbench/app/Livewire/CategoriesTable.php index 92287b9..14cd5a8 100644 --- a/workbench/app/Livewire/CategoriesTable.php +++ b/workbench/app/Livewire/CategoriesTable.php @@ -4,10 +4,9 @@ namespace Workbench\App\Livewire; use Workbench\App\Models\Product; -use Lightscale\LaralightTables\TableComponent; use Lightscale\LaralightTables\Columns\Column; -class CategoriesTable extends TableComponent +class CategoriesTable extends Table { protected $model = Product::class; diff --git a/workbench/app/Livewire/OrdersTable.php b/workbench/app/Livewire/OrdersTable.php index 97ef195..bb909a3 100644 --- a/workbench/app/Livewire/OrdersTable.php +++ b/workbench/app/Livewire/OrdersTable.php @@ -4,10 +4,9 @@ namespace Workbench\App\Livewire; use Workbench\App\Models\Product; -use Lightscale\LaralightTables\TableComponent; use Lightscale\LaralightTables\Columns\Column; -class OrdersTable extends TableComponent +class OrdersTable extends Table { protected $model = Product::class; diff --git a/workbench/app/Livewire/ProductsTable.php b/workbench/app/Livewire/ProductsTable.php index 3b327d9..e3fefc3 100644 --- a/workbench/app/Livewire/ProductsTable.php +++ b/workbench/app/Livewire/ProductsTable.php @@ -4,15 +4,28 @@ namespace Workbench\App\Livewire; use Workbench\App\Models\Product; -use Lightscale\LaralightTables\TableComponent; use Lightscale\LaralightTables\Columns\Column; +use Lightscale\LaralightTables\Toolbar; +use Lightscale\LaralightTables\Toolbar\Search; +use Lightscale\LaralightTables\Toolbar\PageSize; +use Lightscale\LaralightTables\Toolbar\ColumnSelect; use Illuminate\Database\Eloquent\Builder; -class ProductsTable extends TableComponent +class ProductsTable extends Table { protected $model = Product::class; + public function toolbar(): Toolbar + { + return parent::toolbar() + ->addStartItem(new Search()) + ->addEndItem(new PageSize()) + ->addEndItem(new ColumnSelect()); + + return $toolbar; + } + protected function search(Builder $q, string $s): void { $q->search($s); diff --git a/workbench/app/Livewire/Table.php b/workbench/app/Livewire/Table.php new file mode 100644 index 0000000..5bffaed --- /dev/null +++ b/workbench/app/Livewire/Table.php @@ -0,0 +1,16 @@ + +
{{ $slot }}
-- cgit v1.2.3