Skip to content

Commit 0887809

Browse files
committed
PoC Grid component
1 parent 08057ed commit 0887809

File tree

20 files changed

+530
-37
lines changed

20 files changed

+530
-37
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Sylius package.
5+
*
6+
* (c) Sylius Sp. z o.o.
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace App\Grid\Renderer;
15+
16+
use Sylius\Bundle\ResourceBundle\Grid\Parser\OptionsParserInterface;
17+
use Sylius\Component\Grid\Definition\Action;
18+
use Sylius\Component\Grid\Renderer\BulkActionGridRendererInterface;
19+
use Sylius\Component\Grid\View\GridViewInterface;
20+
use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
21+
use Symfony\Component\DependencyInjection\Attribute\Autowire;
22+
use Symfony\Component\HttpFoundation\Request;
23+
use Symfony\Component\HttpFoundation\RequestStack;
24+
use Twig\Environment;
25+
26+
#[AsDecorator(decorates: 'sylius.custom_bulk_action_grid_renderer.twig')]
27+
final class TwigBulkActionGridRenderer implements BulkActionGridRendererInterface
28+
{
29+
public function __construct(
30+
private Environment $twig,
31+
private OptionsParserInterface $optionsParser,
32+
#[Autowire(param: 'sylius.grid.templates.bulk_action')]
33+
private array $bulkActionTemplates = [],
34+
private readonly ?RequestStack $requestStack = null,
35+
) {
36+
}
37+
38+
public function renderBulkAction(GridViewInterface $gridView, Action $bulkAction, $data = null): string
39+
{
40+
$type = $bulkAction->getType();
41+
if (!isset($this->bulkActionTemplates[$type])) {
42+
throw new \InvalidArgumentException(sprintf('Missing template for bulk action type "%s".', $type));
43+
}
44+
45+
$options = $this->optionsParser->parseOptions(
46+
$bulkAction->getOptions(),
47+
$this->requestStack?->getCurrentRequest() ?? new Request(),
48+
$data,
49+
);
50+
51+
return $this->twig->render($this->bulkActionTemplates[$type], [
52+
'grid' => $gridView,
53+
'action' => $bulkAction,
54+
'data' => $data,
55+
'options' => $options,
56+
]);
57+
}
58+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Sylius package.
5+
*
6+
* (c) Sylius Sp. z o.o.
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace App\Grid\Renderer;
15+
16+
use Sylius\Bundle\ResourceBundle\Grid\Parser\OptionsParserInterface;
17+
use Sylius\Component\Grid\Definition\Action;
18+
use Sylius\Component\Grid\Definition\Field;
19+
use Sylius\Component\Grid\Definition\Filter;
20+
use Sylius\Component\Grid\Renderer\GridRendererInterface;
21+
use Sylius\Component\Grid\View\GridViewInterface;
22+
use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
23+
use Symfony\Component\DependencyInjection\Attribute\Autowire;
24+
use Symfony\Component\HttpFoundation\Request;
25+
use Symfony\Component\HttpFoundation\RequestStack;
26+
use Twig\Environment;
27+
28+
#[AsDecorator(decorates: 'sylius.custom_grid_renderer.twig')]
29+
final class TwigGridRenderer implements GridRendererInterface
30+
{
31+
private GridRendererInterface $gridRenderer;
32+
33+
private Environment $twig;
34+
35+
private OptionsParserInterface $optionsParser;
36+
37+
private array $actionTemplates;
38+
39+
public function __construct(
40+
GridRendererInterface $gridRenderer,
41+
Environment $twig,
42+
OptionsParserInterface $optionsParser,
43+
#[Autowire(param: 'sylius.grid.templates.action')]
44+
array $actionTemplates = [],
45+
private readonly ?RequestStack $requestStack = null,
46+
) {
47+
$this->gridRenderer = $gridRenderer;
48+
$this->twig = $twig;
49+
$this->optionsParser = $optionsParser;
50+
$this->actionTemplates = $actionTemplates;
51+
}
52+
53+
public function render(GridViewInterface $gridView, ?string $template = null): string
54+
{
55+
return $this->gridRenderer->render($gridView, $template);
56+
}
57+
58+
/**
59+
* @param mixed $data
60+
*/
61+
public function renderField(GridViewInterface $gridView, Field $field, $data): string
62+
{
63+
return $this->gridRenderer->renderField($gridView, $field, $data);
64+
}
65+
66+
/**
67+
* @param mixed $data
68+
*/
69+
public function renderAction(GridViewInterface $gridView, Action $action, $data = null): string
70+
{
71+
$type = $action->getType();
72+
if (!isset($this->actionTemplates[$type])) {
73+
throw new \InvalidArgumentException(sprintf('Missing template for action type "%s".', $type));
74+
}
75+
76+
$options = $this->optionsParser->parseOptions(
77+
$action->getOptions(),
78+
$this->requestStack?->getCurrentRequest() ?? new Request(),
79+
$data,
80+
);
81+
82+
return $this->twig->render($this->actionTemplates[$type], [
83+
'grid' => $gridView,
84+
'action' => $action,
85+
'data' => $data,
86+
'options' => $options,
87+
]);
88+
}
89+
90+
public function renderFilter(GridViewInterface $gridView, Filter $filter): string
91+
{
92+
return $this->gridRenderer->renderFilter($gridView, $filter);
93+
}
94+
}

app/Grid/SpeakerGrid.php

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public static function getName(): string
3838
public function buildGrid(GridBuilderInterface $gridBuilder): void
3939
{
4040
$gridBuilder
41+
->setLimits([10, 25, 50])
4142
->addFilter(
4243
StringFilter::create('search', ['firstName', 'lastName', 'companyName'])
4344
->setLabel('sylius.ui.search'),
@@ -64,7 +65,12 @@ public function buildGrid(GridBuilderInterface $gridBuilder): void
6465
)
6566
->addActionGroup(
6667
MainActionGroup::create(
67-
CreateAction::create(),
68+
CreateAction::create()
69+
->setOptions([
70+
'link' => [
71+
'route' => 'app_admin_speaker_create',
72+
],
73+
]),
6874
),
6975
)
7076
->addActionGroup(
@@ -82,15 +88,23 @@ public function buildGrid(GridBuilderInterface $gridBuilder): void
8288
],
8389
],
8490
]),
85-
UpdateAction::create(),
86-
DeleteAction::create(),
87-
),
88-
)
89-
->addActionGroup(
90-
BulkActionGroup::create(
91-
DeleteAction::create(),
91+
UpdateAction::create()
92+
->setOptions([
93+
'link' => [
94+
'route' => 'app_admin_speaker_update',
95+
'parameters' => [
96+
'id' => 'resource.id',
97+
],
98+
],
99+
]),
100+
// DeleteAction::create(),
92101
),
93102
)
103+
// ->addActionGroup(
104+
// BulkActionGroup::create(
105+
// DeleteAction::create(),
106+
// ),
107+
// )
94108
;
95109
}
96110

app/Grid/TalkGrid.php

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -92,17 +92,17 @@ public function buildGrid(GridBuilderInterface $gridBuilder): void
9292
CreateAction::create(),
9393
),
9494
)
95-
->addActionGroup(
96-
ItemActionGroup::create(
97-
UpdateAction::create(),
98-
DeleteAction::create(),
99-
),
100-
)
101-
->addActionGroup(
102-
BulkActionGroup::create(
103-
DeleteAction::create(),
104-
),
105-
)
95+
// ->addActionGroup(
96+
// ItemActionGroup::create(
97+
// UpdateAction::create(),
98+
// DeleteAction::create(),
99+
// ),
100+
// )
101+
// ->addActionGroup(
102+
// BulkActionGroup::create(
103+
// DeleteAction::create(),
104+
// ),
105+
// )
106106
;
107107
}
108108

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Sylius package.
5+
*
6+
* (c) Sylius Sp. z o.o.
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace App\Twig\Component\Grid;
15+
16+
use Pagerfanta\PagerfantaInterface;
17+
use Sylius\Component\Grid\Parameters;
18+
use Sylius\Component\Grid\Provider\ChainProvider;
19+
use Sylius\Component\Grid\Provider\GridProviderInterface;
20+
use Sylius\Component\Grid\View\GridViewFactoryInterface;
21+
use Sylius\Component\Grid\View\GridViewInterface;
22+
use Sylius\TwigHooks\Twig\Component\HookableComponentTrait;
23+
use Symfony\Component\DependencyInjection\Attribute\Autowire;
24+
use Symfony\Component\HttpFoundation\Request;
25+
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
26+
use Symfony\UX\LiveComponent\Attribute\LiveAction;
27+
use Symfony\UX\LiveComponent\Attribute\LiveArg;
28+
use Symfony\UX\LiveComponent\Attribute\LiveProp;
29+
use Symfony\UX\LiveComponent\DefaultActionTrait;
30+
31+
#[AsLiveComponent(
32+
name: 'sylius_grid_data_table',
33+
template: '@SyliusBootstrapAdminUi/shared/crud/index/content/grid/data_table.html.twig',
34+
)]
35+
final class DataTableComponent
36+
{
37+
use DefaultActionTrait;
38+
use HookableComponentTrait;
39+
40+
#[LiveProp(writable: true)]
41+
public ?string $grid = null;
42+
43+
#[LiveProp(writable: true)]
44+
public int $page;
45+
46+
/** @var array<string, mixed>|null */
47+
#[LiveProp(writable: true)]
48+
public ?array $criteria = null;
49+
50+
/** @var array<string, string>|null */
51+
#[LiveProp(writable: true)]
52+
public ?array $sorting = null;
53+
54+
#[LiveProp(writable: true)]
55+
public ?int $limit = null;
56+
57+
#[LiveProp(writable: true)]
58+
public bool $pushOnBrowserHistory = true;
59+
60+
private ?Request $request;
61+
62+
public function __construct(
63+
#[Autowire(service: ChainProvider::class)]
64+
private readonly GridProviderInterface $gridProvider,
65+
private readonly GridViewFactoryInterface $gridViewFactory,
66+
) {
67+
}
68+
69+
public function getResources(): GridViewInterface
70+
{
71+
if (null === $this->grid) {
72+
throw new \RuntimeException('No Grid has been passed to the component.');
73+
}
74+
75+
$gridDefinition = $this->gridProvider->get($this->grid);
76+
77+
$config = ['page' => $this->page];
78+
79+
if (null !== $this->criteria) {
80+
$config['criteria'] = $this->criteria;
81+
}
82+
83+
if (null !== $this->sorting) {
84+
$config['sorting'] = $this->sorting;
85+
}
86+
87+
$gridView = $this->gridViewFactory->create(
88+
$gridDefinition,
89+
new Parameters($config),
90+
);
91+
92+
$data = $gridView->getData();
93+
94+
if ($data instanceof PagerfantaInterface) {
95+
$data->setCurrentPage($this->page);
96+
97+
if (null !== $this->limit) {
98+
$data->setMaxPerPage($this->limit);
99+
}
100+
}
101+
102+
return $gridView;
103+
}
104+
105+
#[LiveAction]
106+
public function sortBy(#[LiveArg] string $field, #[LiveArg] string $order): void
107+
{
108+
$this->sorting = [$field => $order];
109+
}
110+
111+
#[LiveAction]
112+
public function updateLimit(#[LiveArg] int $limit): void
113+
{
114+
$this->page = 1;
115+
$this->criteria = null;
116+
$this->sorting = null;
117+
$this->limit = $limit;
118+
}
119+
120+
#[LiveAction]
121+
public function changePage(#[LiveArg] int $page): void
122+
{
123+
$this->page = $page;
124+
}
125+
126+
#[LiveAction]
127+
public function previousPage(): void
128+
{
129+
--$this->page;
130+
}
131+
132+
#[LiveAction]
133+
public function nextPage(): void
134+
{
135+
++$this->page;
136+
}
137+
}

assets/app.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
import './bootstrap.js';
12
import './scripts/statistics_chart.js';

assets/bootstrap.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { startStimulusApp } from '@symfony/stimulus-bundle';
2+
3+
const app = startStimulusApp();
4+
// register any custom, 3rd party controllers here
5+
// app.register('some_controller_name', SomeImportedController);

assets/controllers.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
"enabled": true,
66
"fetch": "eager",
77
"autoimport": {
8-
"tom-select/dist/css/tom-select.default.css": true,
8+
"tom-select/dist/css/tom-select.default.css": false,
99
"tom-select/dist/css/tom-select.bootstrap4.css": false,
10-
"tom-select/dist/css/tom-select.bootstrap5.css": false
10+
"tom-select/dist/css/tom-select.bootstrap5.css": true
1111
}
1212
}
1313
},

0 commit comments

Comments
 (0)