diff --git a/src/Component/BaseGrid.php b/src/Component/BaseGrid.php index db0d9a1..94a1a45 100755 --- a/src/Component/BaseGrid.php +++ b/src/Component/BaseGrid.php @@ -42,6 +42,7 @@ abstract class BaseGrid extends Control /** @var callable */ protected $onDelete; protected bool $withoutIsActiveColumn = false; + protected ?string $treeViewParentProperty = null; public function __construct() { @@ -60,9 +61,38 @@ public function __construct() $this->initGrid($grid); $this->addIsActive($grid); + + if ($this->isTreeView()) { + $grid->setTreeView( + fn ($parentId) => $this->createTreeViewChildrenDataSource($parentId), + fn ($item) => $this->treeViewItemHasChildren($item), + ); + $grid->setTemplateFile(__DIR__ . '/DataGridTree.latte'); + } }); } + protected function isTreeView(): bool + { + return $this->treeViewParentProperty !== null; + } + + protected function createTreeViewChildrenDataSource(mixed $parentId): mixed + { + $parent = $this->createQueryObject()->byId($parentId)->fetchOne(); + + $queryObject = $this->createQueryObject(); + $this->initQueryObject($queryObject); + $queryObject->by($this->treeViewParentProperty, $parent); + + return $this->getQueryObjectDataSourceFactory()->create($queryObject); + } + + protected function treeViewItemHasChildren(object $item): bool + { + return $this->createQueryObject()->by($this->treeViewParentProperty, $item)->count() > 0; + } + protected function createQueryObject(): QueryObject { return $this->getDic()->getByType($this->getQueryObjectFactoryClass())->create(); @@ -130,6 +160,10 @@ protected function setGridDataSource(DataGrid $grid): void $queryObject = $this->createQueryObject(); $this->initQueryObject($queryObject); + if ($this->isTreeView()) { + $queryObject->by($this->treeViewParentProperty, null); + } + $queryObjectDataSource = $this->getQueryObjectDataSourceFactory()->create($queryObject); if ($this->getDataSourceFilterCallback()) { $queryObjectDataSource->setFilterCallback($this->getDataSourceFilterCallback()); @@ -206,8 +240,15 @@ public function handleSortRows(): void $itemId = $this->getParameter('item_id'); $nextId = $this->getParameter('next_id'); $previousId = $this->getParameter('prev_id'); + $parentId = $this->getParameter('parent_id'); $item = $this->createQueryObject()->byId($itemId)->fetchOne(); + if ($this->isTreeView()) { + $parent = $parentId ? $this->createQueryObject()->byId($parentId)->fetchOne() : null; + $setter = 'set' . ucfirst($this->treeViewParentProperty); + $item->$setter($parent); + } + if ($previousId) { $previousItem = $this->createQueryObject()->byId($previousId)->fetchOne(); $newPosition = $previousItem->getPosition() + 1; diff --git a/src/Component/DataGridTree.latte b/src/Component/DataGridTree.latte new file mode 100644 index 0000000..a4655b7 --- /dev/null +++ b/src/Component/DataGridTree.latte @@ -0,0 +1,126 @@ +{** + * Stromové zobrazení gridu kompatibilní se starým jQuery datagrid.js (datagrid.tree extension, + * datagridSortableTree). Liší se od stock contributte šablony tím, že: + * - šipka používá `data-toggle-tree` (ne `data-bs-toggle-tree`) a jedinou ikonu rotovanou přes .toggle-rotate + * - každý kontejner `.datagrid-tree-item-children` nese `data-sortable-url` (řazení i ve vnořených) + * + * @param array $columns + * @param array $actions + * @param Row[] $rows + * @param Datagrid $control + * @param string $originalTemplate + * @param string $iconPrefix + *} + +{extends $originalTemplate} + +