<?php namespace Lightscale\LaralightTables; use Livewire\Component; use Livewire\WithPagination; use Livewire\Attributes\Url; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Str; use Exception; abstract class TableComponent extends Component { use WithPagination; // 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; // Properties public string $search = ''; #[Url] public int $pageSize = 0; public array $activeColumns = []; public function __construct() { $this->pageSize = $this->pageSizes[0] ?? 0; } public function mount() { foreach($this->getColumns() as $column) { $this->activeColumns[] = $column->name; } } protected function query() : Builder { if($this->model === null) { throw new Exception('Requires $model to be set or query() method to be overridden'); } return $this->model::query(); } abstract protected function columns() : array; 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)) { $this->search($query, $this->search); } return $query; } private $columnsCache = null; protected function getColumns() { if($this->columnsCache === null) { $this->columnsCache = collect($this->columns())->each( fn($c) => $c->setTable($this) ); } return $this->columnsCache; } public function render() { $data = $this->buildQuery()->paginate($this->pageSize); $allColumns = $this->getColumns(); $columns = $allColumns->filter(fn($c) => in_array($c->name,$this->activeColumns)); return view('laralight-tables::table', [ 'searchable' => $this->searchable, 'searchDebounce' => $this->searchDebounce, 'showPageSizeSelect' => $this->showPageSizeSelect, 'showColumnSelect' => $this->showColumnSelect, 'pageSizes' => $this->pageSizes, ] + compact( 'data', 'allColumns', 'columns' )); } }