Skip to content

Commit 99d7f46

Browse files
committed
wip datatables query
1 parent de72a8d commit 99d7f46

File tree

3 files changed

+114
-126
lines changed

3 files changed

+114
-126
lines changed

src/Datatables/Concerns/HasResponse.php

Lines changed: 0 additions & 124 deletions
This file was deleted.

src/Datatables/Concerns/InteractsWithQueryBuilder.php

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,28 @@
33
namespace Flavorly\VanillaComponents\Datatables\Concerns;
44

55
use Closure;
6+
use Flavorly\VanillaComponents\Datatables\Columns\Column;
7+
use Flavorly\VanillaComponents\Datatables\Filters\Filter;
8+
use Flavorly\VanillaComponents\Datatables\Http\Payload\RequestPayload;
9+
use Flavorly\VanillaComponents\Datatables\Http\Resources\DatatableResource;
610
use Illuminate\Database\Eloquent\Builder;
11+
use Illuminate\Database\Eloquent\Model;
712
use Illuminate\Database\Eloquent\Relations\Relation;
813
use Laravel\Scout\Builder as ScoutBuilder;
14+
use Laravel\Scout\Searchable;
915

1016
trait InteractsWithQueryBuilder
1117
{
1218
protected Builder|ScoutBuilder|null|Closure $query = null;
1319

20+
protected RequestPayload $data;
21+
1422
public function query(): mixed
1523
{
1624
return $this->query;
1725
}
1826

19-
public function getQuery()
27+
protected function getQuery()
2028
{
2129
return $this->query;
2230
}
@@ -57,4 +65,109 @@ protected function resolveQueryOrModel(mixed $queryOrModel = null): Builder
5765
// Attempt to always get a query builder
5866
return $queryOrModel instanceof Builder ? $queryOrModel : $queryOrModel->query();
5967
}
68+
69+
protected function dispatchAction(): void
70+
{
71+
if (
72+
$this->data->hasAction() &&
73+
($this->data->isAllSelected() || $this->data->hasSelectedRows())
74+
) {
75+
// Execute the action
76+
$this->data->getAction()->execute();
77+
}
78+
}
79+
80+
protected function applyQueryFilters(Builder $query, RequestPayload $payload): Builder
81+
{
82+
return $query->when($payload->hasFilters(), function (Builder $subQuery) use($payload){
83+
// Each column that needs to be sorted
84+
$payload
85+
->getFilters()
86+
// Apply Sorting
87+
->each(fn (Filter $filter) => $filter->apply($subQuery, $filter->getName(), $filter->getValue()));
88+
return $subQuery;
89+
});
90+
}
91+
92+
protected function applyQuerySorting(Builder $query, RequestPayload $payload): Builder
93+
{
94+
return $query->when($payload->hasSorting(), function (Builder $subQuery) use($payload) {
95+
// Each column that needs to be sorted
96+
$payload
97+
->getSorting()
98+
->each(fn (Column $column) => $subQuery->orderBy($column->getName(), $column->getSortDirection()));
99+
100+
return $subQuery;
101+
});
102+
}
103+
104+
protected function applySearch(Builder $query, RequestPayload $payload): Builder
105+
{
106+
$model = $this->getQuery()->getModel();
107+
$usingScout = is_a($model, Searchable::class, true);
108+
109+
return $query
110+
// Model is using Scout, we can use it.
111+
->when($usingScout && $payload->hasSearch(), function (Builder $subQuery) use($payload, $model) {
112+
// Each column that needs to be sorted
113+
/** @var Searchable $model */
114+
$subQuery->whereIn('id', $model::search($this->data->getSearch())->keys());
115+
return $subQuery;
116+
})
117+
// Without Scout
118+
->when(!$usingScout && $payload->hasSearch(), function (Builder $subQuery) use($payload) {
119+
// Each column that needs to be sorted
120+
$subQuery
121+
->where(fn($query) => $this
122+
->getColumns()
123+
->each(fn (Column $column) => $query->orWhere($column->getName(), 'like', "%{$payload->getSearch()}%"))
124+
);
125+
return $subQuery;
126+
});
127+
}
128+
129+
public function response(?Builder $queryOrModel = null): DatatableResource
130+
{
131+
// Create the data from the request payload
132+
// First we need to infer the table.
133+
$this->data = RequestPayload::make()
134+
->table($this)
135+
->fromRequest();
136+
137+
// Attempt to always get a query builder
138+
if ($queryOrModel !== null) {
139+
$this->withQuery($queryOrModel);
140+
}
141+
142+
$query = tap($this->getQuery(), function(Builder $query) {
143+
$query = $this->applyQueryFilters($query, $this->data);
144+
$query = $this->applyQuerySorting($query, $this->data);
145+
return $this->applySearch($query, $this->data);
146+
});
147+
148+
$this->query = $query;
149+
150+
$paginatedQuery = $query->paginate($this->data->getPerPage());
151+
152+
// Append the query, because at this point we are done with it.
153+
$this->data->withQuery($this->query);
154+
155+
// Dispatch the action
156+
$this->dispatchAction();
157+
158+
$response = (new DatatableResource($paginatedQuery));
159+
160+
// Ensure we can transform the data that is being displayed
161+
if (method_exists($this, 'transform')) {
162+
$response->transformResponseUsing(fn ($record) => $this->transform($record));
163+
}
164+
165+
// Ensure we can transform the data that is being displayed
166+
$pagination = 3;
167+
if (property_exists($this, 'paginationItems')) {
168+
$pagination = $this->paginationItems;
169+
}
170+
171+
return $response->rightSideMaximumPages($pagination);
172+
}
60173
}

src/Datatables/Datatable.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ abstract class Datatable
2121
use Concerns\HasPrimaryKey;
2222
use Concerns\HasPageOptions;
2323
use Concerns\HasEndpoint;
24-
use Concerns\HasResponse;
2524
use Concerns\HasOriginUrl;
2625
use Macroable;
2726

0 commit comments

Comments
 (0)