diff --git a/.jeeves.yaml b/.jeeves.yaml
index c75a08f..2d5f830 100644
--- a/.jeeves.yaml
+++ b/.jeeves.yaml
@@ -42,7 +42,7 @@ Mygento:
unsigned: true
default: 0
source: 'Mygento\Navigation\Model\Source\EntityType'
- entity_slug:
+ entity_identifier:
type: varchar
nullable: true
comment: 'Link Identifier'
diff --git a/Api/Data/ItemInterface.php b/Api/Data/ItemInterface.php
index 8225717..8132069 100644
--- a/Api/Data/ItemInterface.php
+++ b/Api/Data/ItemInterface.php
@@ -15,7 +15,7 @@ interface ItemInterface
public const IS_ACTIVE = 'is_active';
public const NAME = 'name';
public const ENTITY_TYPE = 'entity_type';
- public const ENTITY_SLUG = 'entity_slug';
+ public const ENTITY_IDENTIFIER = 'entity_identifier';
public const SORT_ORDER = 'sort_order';
public const STORE_ID = 'store_id';
@@ -71,14 +71,14 @@ public function getEntityType(): string;
public function setEntityType(string $entityType): self;
/**
- * Get entity slug
+ * Get entity identifier
*/
- public function getEntitySlug(): ?string;
+ public function getEntityIdentifier(): ?string;
/**
- * Set entity slug
+ * Set entity identifier
*/
- public function setEntitySlug(?string $entitySlug): self;
+ public function setEntityIdentifier(?string $entityIdentifier): self;
/**
* Get sort order
diff --git a/Api/MenuRepositoryInterface.php b/Api/MenuRepositoryInterface.php
index 119d1e0..e6507d4 100644
--- a/Api/MenuRepositoryInterface.php
+++ b/Api/MenuRepositoryInterface.php
@@ -24,6 +24,14 @@ public function save(Data\MenuInterface $entity): Data\MenuInterface;
*/
public function getById(int $entityId): Data\MenuInterface;
+ /**
+ * Retrieve menu by code
+ *
+ * @throws \Magento\Framework\Exception\LocalizedException
+ * @return \Mygento\Navigation\Api\Data\MenuInterface
+ */
+ public function getByCode(string $code): Data\MenuInterface;
+
/**
* Retrieve Menu entities matching the specified criteria
* @throws \Magento\Framework\Exception\LocalizedException
diff --git a/Controller/Adminhtml/Item/Save.php b/Controller/Adminhtml/Item/Save.php
index 8ebcd57..201cd7a 100644
--- a/Controller/Adminhtml/Item/Save.php
+++ b/Controller/Adminhtml/Item/Save.php
@@ -14,6 +14,7 @@
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Registry;
+use Mygento\Base\Model\ImageUploader;
use Mygento\Navigation\Api\Data\ItemInterfaceFactory;
use Mygento\Navigation\Api\ItemRepositoryInterface;
use Mygento\Navigation\Controller\Adminhtml\Item;
@@ -23,6 +24,7 @@ class Save extends Item
public function __construct(
private readonly DataPersistorInterface $dataPersistor,
private readonly ItemInterfaceFactory $entityFactory,
+ private ImageUploader $imageUploader,
ItemRepositoryInterface $repository,
Registry $coreRegistry,
Context $context,
@@ -63,6 +65,16 @@ public function execute(): ResultInterface
$data['entity_id'] = null;
}
$entity->setData($data);
+ $entity->setImage($this->processImage($data, 'image') ?? '');
+
+ if (empty($data['entity_identifier'])) {
+ $this->messageManager->addErrorMessage(
+ __('The Entity Identifier is required. Please assign an entity.')->render(),
+ );
+ $this->dataPersistor->set('navigation_item', $data);
+
+ return $resultRedirect->setPath('*/*/edit', ['id' => $entity->getId()]);
+ }
try {
$this->repository->save($entity);
@@ -87,4 +99,25 @@ public function execute(): ResultInterface
return $resultRedirect->setPath('*/*/edit', ['id' => $this->getRequest()->getParam('id')]);
}
+
+ private function processImage(array $data, string $key): ?string
+ {
+ $value = $data[$key] ?? null;
+ if (!$value) {
+ return null;
+ }
+ if (!is_array($value)) {
+ return null;
+ }
+ $imageName = $value['0']['name'] ?? null;
+ if (!$imageName) {
+ return null;
+ }
+ if ($imageName && !isset($value[0]['tmp_name'])) {
+ return $imageName;
+ }
+
+ return $this->imageUploader->getBasePath()
+ . '/' . $this->imageUploader->moveFileFromTmp($imageName);
+ }
}
diff --git a/Controller/Adminhtml/Item/Upload.php b/Controller/Adminhtml/Item/Upload.php
new file mode 100644
index 0000000..b74f143
--- /dev/null
+++ b/Controller/Adminhtml/Item/Upload.php
@@ -0,0 +1,38 @@
+_request->getParam('param_name', 'image');
+
+ try {
+ $result = $this->imageUploader->saveFileToTmpDir($imageId);
+ } catch (\Exception $e) {
+ $result = ['error' => $e->getMessage(), 'errorcode' => $e->getCode()];
+ }
+
+ return $this->resultJsonFactory->create()->setData($result);
+ }
+}
diff --git a/Model/Builder/CustomLink.php b/Model/Builder/CustomLink.php
new file mode 100644
index 0000000..bbffd0b
--- /dev/null
+++ b/Model/Builder/CustomLink.php
@@ -0,0 +1,26 @@
+getRequestPaths($entityIds, $storeId);
+ foreach ($items as &$item) {
+ $entityId = (int) ($item['entity_identifier'] ?? 0);
+ $path = $requestPaths[$entityId] ?? sprintf($this->targetPathPattern, $entityId);
+ $item['link'] = $this->urlBuilder->getDirectUrl($path, ['_scope' => $storeId]);
+ }
+ unset($item);
+
+ return $items;
+ }
+
+ private function getRequestPaths(array $entityIds, int $storeId): array
+ {
+ $ids = array_map('intval', $entityIds);
+ if (!$ids) {
+ return [];
+ }
+
+ $connection = $this->resourceConnection->getConnection();
+ $select = $connection->select()
+ ->from(
+ ['ur' => $this->resourceConnection->getTableName(self::TABLE_URL_REWRITE)],
+ ['entity_id', 'request_path'],
+ )
+ ->where('ur.entity_type = ?', $this->urlRewriteEntityType)
+ ->where('ur.store_id = ?', $storeId)
+ ->where('ur.redirect_type = ?', 0)
+ ->where('ur.is_autogenerated = ?', 1)
+ ->where('ur.metadata IS NULL')
+ ->where('ur.entity_id IN (?)', $ids)
+ ->order('ur.url_rewrite_id ASC');
+
+ return $connection->fetchPairs($select);
+ }
+}
diff --git a/Model/EntityLabelResolver.php b/Model/EntityLabelResolver.php
new file mode 100644
index 0000000..a1d7b45
--- /dev/null
+++ b/Model/EntityLabelResolver.php
@@ -0,0 +1,49 @@
+ sprintf(
+ '[Page ID: %d] %s',
+ $entityId,
+ $this->pageRepository->getById($entityId)->getTitle(),
+ ),
+ 'cms_block' => sprintf(
+ '[Block ID: %d] %s',
+ $entityId,
+ $this->blockRepository->getById($entityId)->getTitle(),
+ ),
+ 'catalog_product' => sprintf(
+ '[Product ID: %d] %s',
+ $entityId,
+ $this->productRepository->getById($entityId)->getName(),
+ ),
+ default => null,
+ };
+ } catch (LocalizedException $e) {
+ return null;
+ }
+ }
+}
diff --git a/Model/FileInfo.php b/Model/FileInfo.php
new file mode 100644
index 0000000..41771bf
--- /dev/null
+++ b/Model/FileInfo.php
@@ -0,0 +1,81 @@
+storeManager->getStore()->getBaseUrl(UrlInterface::URL_TYPE_MEDIA);
+
+ return rtrim($mediaBaseUrl, '/') . '/' . $fileName;
+ }
+
+ public function getMediaUrl(string $fileName): string
+ {
+ return '/' . UrlInterface::URL_TYPE_MEDIA . '/' . $fileName;
+ }
+
+ public function isExist(string $fileName): bool
+ {
+ $filePath = $this->getFilePath($fileName);
+
+ return $this->getMediaDirectory()->isExist($filePath);
+ }
+
+ public function getStat($fileName): array
+ {
+ $filePath = $this->getFilePath($fileName);
+
+ return $this->getMediaDirectory()->stat($filePath);
+ }
+
+ public function getMimeType($fileName)
+ {
+ if ($this->getMediaDirectory()->getDriver() instanceof ExtendedDriverInterface) {
+ return $this->mediaDirectory->getDriver()->getMetadata($fileName)['mimetype'];
+ }
+
+ return $this->mime->getMimeType(
+ $this->getMediaDirectory()->getAbsolutePath(
+ $this->getFilePath($fileName),
+ ),
+ );
+ }
+
+ private function getFilePath(string $fileName): string
+ {
+ return ltrim($fileName, '/');
+ }
+
+ private function getMediaDirectory(): WriteInterface
+ {
+ if ($this->mediaDirectory === null) {
+ $this->mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA);
+ }
+
+ return $this->mediaDirectory;
+ }
+}
diff --git a/Model/Item.php b/Model/Item.php
index 4ecee23..53f94df 100644
--- a/Model/Item.php
+++ b/Model/Item.php
@@ -98,19 +98,19 @@ public function setEntityType(string $entityType): self
}
/**
- * Get entity slug
+ * Get entity identifier
*/
- public function getEntitySlug(): ?string
+ public function getEntityIdentifier(): ?string
{
- return $this->getData(self::ENTITY_SLUG);
+ return $this->getData(self::ENTITY_IDENTIFIER);
}
/**
- * Set entity slug
+ * Set entity identifier
*/
- public function setEntitySlug(?string $entitySlug): self
+ public function setEntityIdentifier(?string $entityIdentifier): self
{
- return $this->setData(self::ENTITY_SLUG, $entitySlug);
+ return $this->setData(self::ENTITY_IDENTIFIER, $entityIdentifier);
}
/**
diff --git a/Model/Item/DataProvider.php b/Model/Item/DataProvider.php
index f1c8bf5..621be6e 100644
--- a/Model/Item/DataProvider.php
+++ b/Model/Item/DataProvider.php
@@ -11,6 +11,8 @@
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Ui\DataProvider\Modifier\PoolInterface;
use Magento\Ui\DataProvider\ModifierPoolDataProvider;
+use Mygento\Navigation\Model\EntityLabelResolver;
+use Mygento\Navigation\Model\FileInfo;
use Mygento\Navigation\Model\ResourceModel\Item\Collection;
use Mygento\Navigation\Model\ResourceModel\Item\CollectionFactory;
@@ -19,12 +21,13 @@ class DataProvider extends ModifierPoolDataProvider
/** @var Collection */
protected $collection;
- private DataPersistorInterface $dataPersistor;
private array $loadedData = [];
public function __construct(
+ private FileInfo $fileInfo,
+ private DataPersistorInterface $dataPersistor,
+ private EntityLabelResolver $labelResolver,
CollectionFactory $collectionFactory,
- DataPersistorInterface $dataPersistor,
string $name,
string $primaryFieldName,
string $requestFieldName,
@@ -35,7 +38,6 @@ public function __construct(
parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data, $pool);
$this->collection = $collectionFactory->create();
- $this->dataPersistor = $dataPersistor;
}
public function getData(): array
@@ -45,7 +47,13 @@ public function getData(): array
}
$items = $this->collection->getItems();
foreach ($items as $model) {
- $this->loadedData[$model->getId()] = $model->getData();
+ $data = $model->getData();
+ $data['image'] = $this->getImageData($data, 'image');
+ $data['entity_label'] = $this->labelResolver->resolve(
+ $data['entity_type'],
+ $data['entity_identifier'],
+ );
+ $this->loadedData[$model->getId()] = $data;
}
$data = $this->dataPersistor->get('navigation_item');
if (!empty($data)) {
@@ -57,4 +65,28 @@ public function getData(): array
return $this->loadedData;
}
+
+ private function getImageData(array $data, string $key): ?array
+ {
+ $imageFileName = $data[$key];
+ if (!$imageFileName) {
+ return null;
+ }
+ $result = null;
+
+ if ($this->fileInfo->isExist($imageFileName)) {
+ $stat = $this->fileInfo->getStat($imageFileName);
+ $mime = $this->fileInfo->getMimeType($imageFileName);
+ $result = [
+ [
+ 'name' => $imageFileName,
+ 'url' => $this->fileInfo->getUrl($imageFileName),
+ 'size' => $stat['size'],
+ 'type' => $mime,
+ ],
+ ];
+ }
+
+ return $result;
+ }
}
diff --git a/Model/MenuRepository.php b/Model/MenuRepository.php
index a9ed934..8261ed3 100644
--- a/Model/MenuRepository.php
+++ b/Model/MenuRepository.php
@@ -91,6 +91,19 @@ public function deleteById(int $entityId): bool
return $this->delete($this->getById($entityId));
}
+ public function getByCode(string $code): MenuInterface
+ {
+ $entity = $this->entityFactory->create();
+ $this->resource->loadByCode($entity, $code);
+ if (!$entity->getId()) {
+ throw new NoSuchEntityException(
+ __('A menu with code "%1" does not exist', $code),
+ );
+ }
+
+ return $entity;
+ }
+
public function getList(SearchCriteriaInterface $criteria): MenuSearchResultsInterface
{
/** @var \Mygento\Navigation\Model\ResourceModel\Menu\Collection $collection */
diff --git a/Model/Resolver/NavigationMenu.php b/Model/Resolver/NavigationMenu.php
new file mode 100644
index 0000000..3a67644
--- /dev/null
+++ b/Model/Resolver/NavigationMenu.php
@@ -0,0 +1,118 @@
+dataBuilders = $this->prepareDataBuilders($dataBuilders);
+ }
+
+ /**
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ * @param Field $field
+ * @param $context
+ * @param ResolveInfo $info
+ * @param array|null $value
+ * @param array|null $args
+ *
+ * @throws GraphQlNoSuchEntityException
+ * @return array
+ */
+ public function resolve(
+ Field $field,
+ $context,
+ ResolveInfo $info,
+ ?array $value = null,
+ ?array $args = null,
+ ) {
+ $code = $args['code'] ?? null;
+
+ try {
+ $menu = $this->menuRepository->getByCode($code);
+ } catch (LocalizedException) {
+ throw new GraphQlNoSuchEntityException(__('Product menu "%1" not found or disabled', $code));
+ }
+ $storeId = (int) $context->getExtensionAttributes()->getStore()->getId();
+ $targetEntityIds = [];
+ $itemsByType = [];
+ $itemsData = $this->itemResource->getItemsWithTargetEntityId((int) $menu->getId(), $storeId);
+ foreach ($itemsData as $item) {
+ $item['image'] = $item['image'] ? $this->fileInfo->getMediaUrl($item['image']) : null;
+ $targetEntityIds[$item['entity_type']][$item['entity_identifier']] = $item['entity_identifier'];
+ $itemsByType[$item['entity_type']][] = $item;
+ }
+ $preparedItems = $this->prepareItems($itemsByType, $targetEntityIds, $storeId);
+
+ return [
+ 'code' => $code,
+ 'items' => $preparedItems,
+ ];
+ }
+
+ private function prepareItems(array $itemsByType, array $targetEntityIds, int $storeId): array
+ {
+ $preparedItems = [];
+ foreach ($itemsByType as $type => $items) {
+ $dataBuilders = $this->dataBuilders[$type] ?? [];
+ foreach ($dataBuilders as $dataBuilder) {
+ if ($dataBuilder instanceof DataBuilderInterface) {
+ $items = $dataBuilder->addData($items, $targetEntityIds[$type], $storeId);
+ }
+ }
+ $preparedItems = array_merge($preparedItems, $items);
+ }
+
+ return $preparedItems;
+ }
+
+ private function prepareDataBuilders(array $dataBuilders): array
+ {
+ $buildersByType = [];
+ foreach ($dataBuilders as $builderConfig) {
+ if (!isset($builderConfig['entity_type'], $builderConfig['class'], $builderConfig['sortOrder'])) {
+ continue;
+ }
+
+ $buildersByType[$builderConfig['entity_type']][] = [
+ 'class' => $builderConfig['class'],
+ 'sortOrder' => $builderConfig['sortOrder'],
+ ];
+ }
+
+ foreach ($buildersByType as $type => $builders) {
+ usort($builders, function ($a, $b) {
+ return $a['sortOrder'] <=> $b['sortOrder'];
+ });
+
+ $buildersByType[$type] = array_column($builders, 'class');
+ }
+
+ return $buildersByType;
+ }
+}
diff --git a/Model/ResourceModel/Item.php b/Model/ResourceModel/Item.php
index b8277a2..0794ee4 100644
--- a/Model/ResourceModel/Item.php
+++ b/Model/ResourceModel/Item.php
@@ -89,6 +89,35 @@ public function lookupStoreIds(int $id): array
return $connection->fetchCol($select, ['entity_id' => (int) $id]);
}
+ public function getItemsWithTargetEntityId(int $menuId, int $storeId): array
+ {
+ $connection = $this->getConnection();
+ $entityMetadata = $this->metadataPool->getMetadata(ItemInterface::class);
+ $linkField = $entityMetadata->getLinkField();
+ $select = $connection->select()->distinct()
+ ->from(
+ ['e' => $this->getMainTable()],
+ [
+ 'entity_id',
+ 'entity_type',
+ 'name',
+ 'sort_order',
+ 'image',
+ 'entity_identifier',
+ ],
+ )
+ ->joinInner(
+ ['es' => $this->getMainTable() . '_store'],
+ 'store_id = ' . $storeId . ' AND es.entity_id = e.' . $linkField,
+ [],
+ )
+ ->where('e.is_active = 1')
+ ->where('e.menu = ?', $menuId)
+ ->order('e.sort_order ASC');
+
+ return $connection->fetchAll($select);
+ }
+
/**
* Initialize resource model
*/
diff --git a/Model/ResourceModel/Item/Collection.php b/Model/ResourceModel/Item/Collection.php
index 7a29162..ecb1c18 100644
--- a/Model/ResourceModel/Item/Collection.php
+++ b/Model/ResourceModel/Item/Collection.php
@@ -79,11 +79,11 @@ protected function _afterLoad()
$stores = [];
foreach ($result as $r) {
- $stores[] = $r['store_id'];
+ $stores[$r['entity_id']][] = $r['store_id'];
}
foreach ($this as $item) {
- $item->setData('store_id', $stores);
+ $item->setData('store_id', $stores[$item->getId()]);
}
return parent::_afterLoad();
diff --git a/Model/ResourceModel/Menu.php b/Model/ResourceModel/Menu.php
index 7f9faef..20e8e64 100644
--- a/Model/ResourceModel/Menu.php
+++ b/Model/ResourceModel/Menu.php
@@ -8,6 +8,7 @@
namespace Mygento\Navigation\Model\ResourceModel;
+use Magento\Framework\Model\AbstractModel;
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
class Menu extends AbstractDb
@@ -15,6 +16,20 @@ class Menu extends AbstractDb
public const TABLE_NAME = 'mygento_navigation_menu';
public const TABLE_PRIMARY_KEY = 'entity_id';
+ public function loadByCode(AbstractModel $object, string $code): AbstractModel
+ {
+ $connection = $this->getConnection();
+ $select = $connection->select()
+ ->from($this->getMainTable())
+ ->where('code = :code');
+
+ $data = $connection->fetchRow($select, [':code' => $code]);
+
+ $object->setData($data);
+
+ return $object;
+ }
+
/**
* Initialize resource model
*/
diff --git a/etc/adminhtml/di.xml b/etc/adminhtml/di.xml
index dfeecf2..1d3e267 100644
--- a/etc/adminhtml/di.xml
+++ b/etc/adminhtml/di.xml
@@ -11,4 +11,42 @@
-
\ No newline at end of file
+
+
+ mygentonav/tmp/item
+ mygentonav/item
+
+ - jpg
+ - jpeg
+ - png
+
+
+ - image/jpg
+ - image/jpeg
+ - image/png
+
+
+
+
+
+ Mygento\Navigation\Model\ImageUploader
+
+
+
+
+ Mygento\Navigation\Model\ImageUploader
+
+
+
+
+ Magento\Catalog\Ui\DataProvider\Product\ProductCollectionFactory
+
+ - Magento\Catalog\Ui\DataProvider\Product\AddWebsitesFieldToCollection
+
+
+ - Magento\Catalog\Ui\DataProvider\Product\AddStoreFieldToCollection
+
+ Magento\Ui\DataProvider\Modifier\Pool
+
+
+
diff --git a/etc/db_schema.xml b/etc/db_schema.xml
index 2487bbe..3bfbd4b 100644
--- a/etc/db_schema.xml
+++ b/etc/db_schema.xml
@@ -13,7 +13,8 @@
-
+
+
diff --git a/etc/db_schema_whitelist.json b/etc/db_schema_whitelist.json
new file mode 100644
index 0000000..1e202ec
--- /dev/null
+++ b/etc/db_schema_whitelist.json
@@ -0,0 +1,26 @@
+{
+ "mygento_navigation_menu": {
+ "column": {
+ "entity_id": true,
+ "code": true
+ }
+ },
+ "mygento_navigation_item": {
+ "column": {
+ "entity_id": true,
+ "menu": true,
+ "is_active": true,
+ "name": true,
+ "entity_type": true,
+ "entity_slug": true,
+ "entity_identifier": true,
+ "sort_order": true
+ }
+ },
+ "mygento_navigation_item_store": {
+ "column": {
+ "entity_id": true,
+ "store_id": true
+ }
+ }
+}
diff --git a/etc/di.xml b/etc/di.xml
index 86f4ac3..72aa2db 100644
--- a/etc/di.xml
+++ b/etc/di.xml
@@ -109,4 +109,48 @@
Mygento\Navigation\Model\ResourceModel\Item
+
+
+ category
+ catalog/category/view/id/%d
+
+
+
+
+ product
+ catalog/product/view/id/%d
+
+
+
+
+ cms-page
+ cms/page/view/page_id/%d
+
+
+
+
+
+ -
+
- catalog_category
+ - Mygento\Navigation\Model\Builder\Category
+ - 10
+
+ -
+
- catalog_product
+ - Mygento\Navigation\Model\Builder\Product
+ - 20
+
+ -
+
- cms_page
+ - Mygento\Navigation\Model\Builder\CmsPage
+ - 30
+
+ -
+
- custom
+ - Mygento\Navigation\Model\Builder\CustomLink
+ - 40
+
+
+
+
diff --git a/etc/schema.graphqls b/etc/schema.graphqls
index b42e38e..80c8ed5 100644
--- a/etc/schema.graphqls
+++ b/etc/schema.graphqls
@@ -1,8 +1,17 @@
-type NavigationItem @doc(description: "Item") {
- menu: Int @doc(description: "Menu ID")
- is_active: Boolean! @doc(description: "Is_active")
- name: String! @doc(description: "Name")
- entity_type: String! @doc(description: "Link Type")
- entity_slug: String @doc(description: "Link Identifier")
- sort_order: Int! @doc(description: "Link Sort Order")
-}
\ No newline at end of file
+type NavigationMenuItem @doc(description: "Item") {
+ sort_order: Int! @doc(description: "Item Sort Order")
+ name: String! @doc(description: "Item name")
+ link: String @doc(description: "Link")
+ image: String @doc(description: "Item image")
+}
+
+type Query {
+ navigationMenu(
+ code: String!,
+ ): NavigationMenu @resolver(class: "Mygento\\Navigation\\Model\\Resolver\\NavigationMenu")
+}
+
+type NavigationMenu {
+ code: String!
+ items: [NavigationMenuItem!] @doc(description: "List of items in menu")
+}
diff --git a/view/adminhtml/ui_component/navigation_block_select_grid.xml b/view/adminhtml/ui_component/navigation_block_select_grid.xml
index fbecdbe..c3b6d1e 100644
--- a/view/adminhtml/ui_component/navigation_block_select_grid.xml
+++ b/view/adminhtml/ui_component/navigation_block_select_grid.xml
@@ -87,6 +87,12 @@
+
+ -
+
- title
+ - navigation_item_edit.navigation_item_edit.general.entity_label
+
+
block_id
diff --git a/view/adminhtml/ui_component/navigation_item_edit.xml b/view/adminhtml/ui_component/navigation_item_edit.xml
index b1a672f..a1346cd 100644
--- a/view/adminhtml/ui_component/navigation_item_edit.xml
+++ b/view/adminhtml/ui_component/navigation_item_edit.xml
@@ -119,11 +119,46 @@
-
+
+
+ -
+
- item
+
+
+
+ ui/form/element/uploader/image
+ string
+
+ true
+
+
+
+
+ true
+
+
+
+ Magento_Catalog/image-preview
+ Media Gallery
+ navigation/item
+ jpg jpeg png
+ 4194304
+ false
+
+
+
+
+
+
-
- item
- catalog_category
+ -
+
- navigation_item_edit.navigation_item_edit.general.entity_identifier
+ - navigation_item_edit.navigation_item_edit.general.entity_label
+ - navigation_item_edit.navigation_item_edit.general.catalog_category_entity
+
@@ -161,6 +196,10 @@
false
+
+ navigation_item_edit.navigation_item_edit.general.entity_identifier
+ hide
+
@@ -191,6 +230,10 @@
false
+
+ navigation_item_edit.navigation_item_edit.general.entity_identifier
+ show
+
@@ -221,6 +264,10 @@
false
+
+ navigation_item_edit.navigation_item_edit.general.entity_identifier
+ hide
+
@@ -251,6 +298,10 @@
false
+
+ navigation_item_edit.navigation_item_edit.general.entity_identifier
+ hide
+
@@ -281,6 +332,10 @@
false
+
+ navigation_item_edit.navigation_item_edit.general.entity_identifier
+ hide
+
@@ -311,6 +366,10 @@
true
+
+ navigation_item_edit.navigation_item_edit.general.entity_identifier
+ hide
+
@@ -329,6 +388,31 @@
+
+
+ -
+
- item
+
+
+
+
+ true
+
+ text
+
+ false
+ entity_identifier
+
+
+
+
+ text
+
+ false
+ true
+ entity_label
+
+
-
@@ -342,7 +426,7 @@
ui/grid/filters/elements/ui-select
- category_ids
+ entity_identifier
field
false
@@ -501,7 +585,7 @@
false
${ $.ns }.${ $.ns }.columns.ids
true
- page_id
+ entity_identifier
navigation_page_select_grid
false
@@ -529,7 +613,7 @@
false
${ $.ns }.${ $.ns }.columns.ids
true
- block_id
+ entity_identifier
navigation_block_select_grid
false
@@ -557,7 +641,7 @@
false
${ $.ns }.${ $.ns }.columns.ids
true
- entity_id
+ entity_identifier
navigation_product_select_grid
false
diff --git a/view/adminhtml/ui_component/navigation_item_listing.xml b/view/adminhtml/ui_component/navigation_item_listing.xml
index 537f01b..c24e709 100644
--- a/view/adminhtml/ui_component/navigation_item_listing.xml
+++ b/view/adminhtml/ui_component/navigation_item_listing.xml
@@ -165,14 +165,14 @@
-
+
text
text
text
-
+
diff --git a/view/adminhtml/ui_component/navigation_page_select_grid.xml b/view/adminhtml/ui_component/navigation_page_select_grid.xml
index 2a33a79..fd13e7b 100644
--- a/view/adminhtml/ui_component/navigation_page_select_grid.xml
+++ b/view/adminhtml/ui_component/navigation_page_select_grid.xml
@@ -87,6 +87,12 @@
+
+
-
+
- title
+ - navigation_item_edit.navigation_item_edit.general.entity_label
+
+
page_id
diff --git a/view/adminhtml/ui_component/navigation_product_select_grid.xml b/view/adminhtml/ui_component/navigation_product_select_grid.xml
index a7cfa86..f3a59a7 100644
--- a/view/adminhtml/ui_component/navigation_product_select_grid.xml
+++ b/view/adminhtml/ui_component/navigation_product_select_grid.xml
@@ -24,7 +24,7 @@
Magento_Catalog::products
-
+
id
entity_id
@@ -84,6 +84,12 @@
+
+ -
+
- name
+ - navigation_item_edit.navigation_item_edit.general.entity_label
+
+
entity_id
diff --git a/view/adminhtml/web/js/form/element/entity-type.js b/view/adminhtml/web/js/form/element/entity-type.js
new file mode 100644
index 0000000..27636c8
--- /dev/null
+++ b/view/adminhtml/web/js/form/element/entity-type.js
@@ -0,0 +1,24 @@
+define([
+ 'Magento_Ui/js/form/element/select',
+ 'uiRegistry'
+], function (Select, registry) {
+ 'use strict';
+
+ return Select.extend({
+ defaults: {
+ clearTargets: []
+ },
+
+ onUpdate: function () {
+ this.clearTargets.forEach(function (target) {
+ registry.get(target, function (component) {
+ if (component) {
+ component.clear();
+ }
+ });
+ });
+
+ return this._super();
+ }
+ });
+});
diff --git a/view/adminhtml/web/js/form/element/selected-label.js b/view/adminhtml/web/js/form/element/selected-label.js
new file mode 100644
index 0000000..9842069
--- /dev/null
+++ b/view/adminhtml/web/js/form/element/selected-label.js
@@ -0,0 +1,21 @@
+define([
+ 'Magento_Ui/js/form/element/abstract'
+], function (Abstract) {
+ 'use strict';
+
+ return Abstract.extend({
+ initialize: function () {
+ this._super();
+ this.value.subscribe(this.updateVisibility, this);
+ this.updateVisibility(this.value());
+
+ return this;
+ },
+
+ updateVisibility: function (value) {
+ this.visible(!!value);
+
+ return this;
+ }
+ });
+});
diff --git a/view/adminhtml/web/js/grid/single-select.js b/view/adminhtml/web/js/grid/single-select.js
index f47f334..25950be 100644
--- a/view/adminhtml/web/js/grid/single-select.js
+++ b/view/adminhtml/web/js/grid/single-select.js
@@ -1,7 +1,8 @@
define([
'Magento_Ui/js/grid/columns/multiselect',
- 'underscore'
-], function (Select, _) {
+ 'underscore',
+ 'uiRegistry'
+], function (Select, _, registry) {
'use strict';
return Select.extend({
@@ -9,6 +10,8 @@ define([
headerTmpl: 'ui/grid/columns/text',
bodyTmpl: 'Mygento_Navigation/grid/single-select',
label: '',
+ labelField: '',
+ labelTarget: '',
extendedSelections: [],
lastSelected: null,
listens: {
@@ -61,10 +64,34 @@ define([
select: function (id) {
this._super();
this.lastSelected(id);
+ this.exportLabel(id);
return this;
},
+ exportLabel: function (id) {
+ if (!this.labelField || !this.labelTarget) {
+ return;
+ }
+
+ const query = {
+ [this.indexField]: id
+ };
+ const row = _.findWhere(this.rows(), query);
+
+ if (!row) {
+ return;
+ }
+
+ const label = `[ID: ${id}] ${row[this.labelField]}`;
+
+ registry.get(this.labelTarget, function (field) {
+ if (field) {
+ field.value(label);
+ }
+ });
+ },
+
/** @inheritdoc */
_setSelection: function (id, isIndex, select) {
var selected = this.selected;