Skip to content

Commit 99756fe

Browse files
committed
Properly implement grid filtering
1 parent 7a37375 commit 99756fe

18 files changed

Lines changed: 260 additions & 55 deletions

File tree

Component/Grid/GridViewModel.php

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Loki\AdminComponents\Component\Grid;
44

55
use Loki\AdminComponents\Grid\Column\Column;
6+
use Loki\AdminComponents\Grid\Filter\FilterFactory;
67
use Magento\Framework\Data\OptionSourceInterface;
78
use Magento\Framework\DataObject;
89
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
@@ -14,14 +15,15 @@
1415
use Loki\AdminComponents\Grid\Cell\CellActionFactory;
1516
use Loki\AdminComponents\Grid\Cell\CellTemplateResolver;
1617
use Loki\AdminComponents\Grid\ColumnLoader;
17-
use Loki\AdminComponents\Grid\FilterInterface;
18+
use Loki\AdminComponents\Grid\Filter\FilterInterface;
1819
use Loki\AdminComponents\Grid\MassAction\MassActionInterface;
1920
use Loki\AdminComponents\Grid\State;
2021
use Loki\AdminComponents\Grid\StateManager;
2122
use Loki\AdminComponents\Ui\Button;
2223
use Loki\AdminComponents\Ui\ButtonFactory;
2324
use Loki\Components\Component\ComponentViewModel;
2425
use Loki\Components\Util\CamelCaseConvertor;
26+
use RuntimeException;
2527

2628
/**
2729
* @method GridRepository getRepository()
@@ -39,7 +41,8 @@ public function __construct(
3941
protected ColumnLoader $columnLoader,
4042
protected ObjectManagerInterface $objectManager,
4143
protected ButtonFactory $buttonFactory,
42-
protected FieldFactory $fieldFactory
44+
protected FieldFactory $fieldFactory,
45+
protected FilterFactory $filterFactory,
4346
) {
4447
}
4548

@@ -138,6 +141,7 @@ public function getJsData(): array
138141
return [
139142
...parent::getJsData(),
140143
...$this->getState()->toArray(),
144+
'gridFilters' => $this->getGridFilterValues(),
141145
'columnPositions' => $this->getColumnPositions(),
142146
'newUrl' => $this->getNewUrl(),
143147
'indexUrl' => $this->getIndexUrl(),
@@ -285,6 +289,34 @@ public function getRowAction(DataObject $item): CellAction
285289
return $this->cellActionFactory->create($editUrl, 'Edit');
286290
}
287291

292+
/**
293+
* @return FilterInterface[]
294+
*/
295+
public function getGridFilters(): array
296+
{
297+
$gridFilters = [];
298+
$gridFilterDefinitions = (array)$this->getBlock()->getGridFilters();
299+
if (empty($gridFilterDefinitions)) {
300+
return [];
301+
}
302+
303+
foreach($gridFilterDefinitions as $gridFilterDefinition) {
304+
$gridFilters[] = $this->filterFactory->createFromArray($gridFilterDefinition);
305+
}
306+
307+
return $gridFilters;
308+
}
309+
310+
public function getGridFilterValues(): array
311+
{
312+
$gridFilterValues = [];
313+
foreach ($this->getGridFilters() as $gridFilter) {
314+
$value = $this->getState()->getFilterValue($gridFilter->getCode());
315+
$gridFilterValues[$gridFilter->getCode()] = $value;
316+
}
317+
318+
return $gridFilterValues;
319+
}
288320

289321
/**
290322
* @return Field[]
@@ -305,7 +337,7 @@ public function getFilterFields(): array
305337
}
306338

307339
if (isset($filter['options']) && false === $filter['options'] instanceof OptionSourceInterface) {
308-
throw new \RuntimeException('Filter uses wrong options class');
340+
throw new RuntimeException('Filter uses wrong options class');
309341
}
310342

311343
$field = $this->fieldFactory->createWithBlock(
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Loki\AdminComponents\Exception;
4+
5+
use Exception;
6+
7+
class CreateGridFilterException extends Exception
8+
{
9+
10+
}

Form/Field/Field.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ public function getScope(): string
3535
return (string)$this->getData('scope');
3636
}
3737

38+
public function getAlpineSetter(): string
39+
{
40+
$alpineSetter = (string)$this->getData('alpine_setter');
41+
if ($alpineSetter) {
42+
return $alpineSetter;
43+
}
44+
45+
return 'setValue';
46+
}
47+
3848
public function getFieldType(): FieldTypeInterface
3949
{
4050
return $this->getData('field_type');

Grid/Action/FilterAction.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Loki\AdminComponents\Grid\Action;
4+
5+
use Loki\AdminComponents\Component\Grid\GridRepository;
6+
use Loki\AdminComponents\Grid\StateManager;
7+
8+
class FilterAction implements ActionInterface
9+
{
10+
public function __construct(
11+
private StateManager $stateManager,
12+
) {
13+
}
14+
15+
public function execute(GridRepository $gridRepository, array $value): void
16+
{
17+
if (!isset($value['filter'])) {
18+
return;
19+
}
20+
21+
if (!is_array($value['filter'])) {
22+
return;
23+
}
24+
25+
$state = $this->stateManager->get($gridRepository->getNamespace());
26+
$state->setFilter(
27+
(string)$value['filter']['name'],
28+
(string)$value['filter']['value'],
29+
);
30+
}
31+
}

Grid/Action/SortAction.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
namespace Loki\AdminComponents\Grid\Action;
44

55
use Loki\AdminComponents\Component\Grid\GridRepository;
6-
use Loki\AdminComponents\Grid\State;
76
use Loki\AdminComponents\Grid\StateManager;
87

98
class SortAction implements ActionInterface

Grid/Filter/Filter.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Loki\AdminComponents\Grid\Filter;
4+
5+
use Loki\AdminComponents\Form\Field\Field;
6+
use Loki\AdminComponents\Form\Field\FieldFactory;
7+
use Magento\Framework\View\Element\Template;
8+
use Magento\Framework\View\LayoutInterface;
9+
10+
class Filter implements FilterInterface
11+
{
12+
public function __construct(
13+
private LayoutInterface $layout,
14+
private FieldFactory $fieldFactory,
15+
private string $label,
16+
private string $code,
17+
private string $conditionType,
18+
private array $data = []
19+
) {
20+
}
21+
22+
public function getLabel(): string
23+
{
24+
return $this->label;
25+
}
26+
27+
public function getCode(): string
28+
{
29+
return $this->code;
30+
}
31+
32+
public function getConditionType(): string
33+
{
34+
return $this->conditionType;
35+
}
36+
37+
public function render(): string
38+
{
39+
$block = $this->layout->createBlock(Template::class);
40+
$block->setTemplate('Loki_AdminComponents::form/field.phtml');
41+
$block->setField($this->getFormField($block));
42+
43+
return $block->toHtml();
44+
}
45+
46+
private function getFormField(Template $block): Field
47+
{
48+
$fieldType = $this->getFieldType();
49+
$field = $this->fieldFactory->create($block, [
50+
'scope' => 'gridFilters',
51+
'alpine_setter' => 'setGridFilter',
52+
'field_type' => $fieldType,
53+
]);
54+
55+
$field->addData($this->data);
56+
57+
return $field;
58+
}
59+
60+
private function getFieldType(): string
61+
{
62+
if (isset($this->data['field_type'])) {
63+
return $this->data['field_type'];
64+
}
65+
66+
if (isset($this->data['options'])) {
67+
return 'select';
68+
}
69+
70+
return 'text';
71+
}
72+
}

Grid/Filter/FilterFactory.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Loki\AdminComponents\Grid\Filter;
4+
5+
use Loki\AdminComponents\Exception\CreateGridFilterException;
6+
use Magento\Framework\ObjectManagerInterface;
7+
8+
class FilterFactory
9+
{
10+
public function __construct(
11+
private ObjectManagerInterface $objectManager,
12+
) {
13+
}
14+
15+
public function create(
16+
string $label,
17+
string $code,
18+
string $conditionType = '',
19+
array $data = [],
20+
): Filter
21+
{
22+
return $this->objectManager->create(Filter::class, [
23+
'label' => $label,
24+
'code' => $code,
25+
'conditionType' => $conditionType,
26+
'data' => $data,
27+
]);
28+
}
29+
30+
public function createFromArray($data): Filter
31+
{
32+
if (false === isset($data['label'])) {
33+
throw new CreateGridFilterException('Grid filter requires a "label"');
34+
}
35+
36+
if (false === isset($data['code'])) {
37+
throw new CreateGridFilterException('Grid filter requires a "code"');
38+
}
39+
40+
return $this->create(
41+
$data['label'],
42+
$data['code'],
43+
'',
44+
$data
45+
);
46+
}
47+
}
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
<?php
22
declare(strict_types=1);
33

4-
namespace Loki\AdminComponents\Grid;
4+
namespace Loki\AdminComponents\Grid\Filter;
55

66
use Magento\Framework\View\Element\Block\ArgumentInterface;
77

88
interface FilterInterface extends ArgumentInterface
99
{
10-
public function getField(): string;
11-
12-
public function getValue(): mixed;
10+
public function getLabel(): string;
11+
public function getCode(): string;
1312

1413
public function getConditionType(): string;
14+
public function render(): string;
1515
}

Grid/State.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,28 @@ public function getFilters(): array
135135
return [];
136136
}
137137

138+
public function getFilterValue(string $name): mixed
139+
{
140+
$filters = $this->getFilters();
141+
if (isset($filters[$name])) {
142+
return $filters[$name];
143+
}
144+
145+
return null;
146+
}
147+
148+
public function setFilter(string $name, mixed $value): void
149+
{
150+
$filters = $this->getFilters();
151+
$filters[$name] = $value;
152+
$this->setFilters($filters);
153+
}
154+
155+
/**
156+
* @param Filter[] $filters
157+
*
158+
* @return void
159+
*/
138160
public function setFilters(array $filters): void
139161
{
140162
$this->save('filters', json_encode($filters));

etc/di.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
<item name="page" xsi:type="object">Loki\AdminComponents\Grid\Action\PageAction</item>
1919
<item name="limit" xsi:type="object">Loki\AdminComponents\Grid\Action\LimitAction</item>
2020
<item name="sort" xsi:type="object">Loki\AdminComponents\Grid\Action\SortAction</item>
21+
<item name="filter" xsi:type="object">Loki\AdminComponents\Grid\Action\FilterAction</item>
2122
<item name="reposition" xsi:type="object">Loki\AdminComponents\Grid\Action\RepositionAction</item>
2223
<item name="inline_edit" xsi:type="object">Loki\AdminComponents\Grid\Action\InlineEditAction</item>
2324
</argument>

0 commit comments

Comments
 (0)