diff --git a/Api/Data/NodeInterface.php b/Api/Data/NodeInterface.php index bf831ddd..82d1a22f 100644 --- a/Api/Data/NodeInterface.php +++ b/Api/Data/NodeInterface.php @@ -18,11 +18,14 @@ interface NodeInterface const TARGET = 'target'; const IMAGE = 'image'; const IMAGE_ALT_TEXT = 'image_alt_text'; + const IMAGE_WIDTH = 'image_width'; + const IMAGE_HEIGHT = 'image_heigth'; const CREATION_TIME = 'creation_time'; const UPDATE_TIME = 'update_time'; const IS_ACTIVE = 'is_active'; const ADDITIONAL_DATA = 'additional_data'; const SELECTED_ITEM_ID = 'selected_item_id'; + const CUSTOMER_GROUPS = 'customer_groups'; /** * Get node id @@ -192,18 +195,40 @@ public function setImage($image); /** * Get image alt text * - * @return string + * @return string|null */ public function getImageAltText(); /** * Set image alt text * - * @param string $altText + * @param string|null $altText * @return $this */ public function setImageAltText($altText); + /** + * @return int|null + */ + public function getImageWidth(); + + /** + * @param int|null $width + * @return $this + */ + public function setImageWidth($width); + + /** + * @return int|null + */ + public function getImageHeight(); + + /** + * @param int|null $height + * @return $this + */ + public function setImageHeight($height); + /** * Get creation time * @@ -274,4 +299,21 @@ public function getSelectedItemId(); * @return $this */ public function setSelectedItemId($selectedItemId); + + /** + * Get customer groups + * + */ + public function getCustomerGroups(); + + /** + * @return $this + */ + public function setCustomerGroups($customerGroups); + + /** + * @param int $customerGroupId + * @return bool + */ + public function isVisible($customerGroupId); } diff --git a/Block/Adminhtml/Edit/Tab/Nodes.php b/Block/Adminhtml/Edit/Tab/Nodes.php index 2b8dbeaa..17e90769 100644 --- a/Block/Adminhtml/Edit/Tab/Nodes.php +++ b/Block/Adminhtml/Edit/Tab/Nodes.php @@ -7,6 +7,7 @@ use Magento\Framework\Registry; use Snowdog\Menu\Api\NodeRepositoryInterface; use Snowdog\Menu\Controller\Adminhtml\Menu\Edit; +use Snowdog\Menu\Model\CustomerGroupsProvider; use Snowdog\Menu\Model\Menu\Node\Image\File as ImageFile; use Snowdog\Menu\Model\NodeTypeProvider; use Snowdog\Menu\Model\VueProvider; @@ -45,6 +46,11 @@ class Nodes extends Template implements TabInterface */ private $vueProvider; + /** + * @var CustomerGroupsProvider + */ + private $customerGroupsProvider; + public function __construct( Template\Context $context, NodeRepositoryInterface $nodeRepository, @@ -52,6 +58,7 @@ public function __construct( NodeTypeProvider $nodeTypeProvider, Registry $registry, VueProvider $vueProvider, + CustomerGroupsProvider $customerGroupsProvider, array $data = [] ) { parent::__construct($context, $data); @@ -60,6 +67,7 @@ public function __construct( $this->nodeTypeProvider = $nodeTypeProvider; $this->imageFile = $imageFile; $this->vueProvider = $vueProvider; + $this->customerGroupsProvider = $customerGroupsProvider; } public function renderNodes() @@ -182,8 +190,11 @@ private function renderNodeList($level, $parent, $data) 'image' => $node->getImage(), 'image_url' => $node->getImage() ? $this->imageFile->getUrl($node->getImage()) : null, 'image_alt_text' => $node->getImageAltText(), + 'image_width' => $node->getImageWidth(), + 'image_height' => $node->getImageHeight(), 'columns' => $this->renderNodeList($level + 1, $node->getId(), $data) ?: [], - 'selected_item_id' => $node->getSelectedItemId() + 'selected_item_id' => $node->getSelectedItemId(), + 'customer_groups' => $node->getCustomerGroups() ]; } return $menu; @@ -206,4 +217,9 @@ public function getVueComponents(): array { return $this->vueProvider->getComponents(); } + + public function getCustomerGroups() + { + return $this->customerGroupsProvider->getAll(); + } } diff --git a/Block/Menu.php b/Block/Menu.php index 07a0853e..dd076269 100644 --- a/Block/Menu.php +++ b/Block/Menu.php @@ -2,13 +2,13 @@ namespace Snowdog\Menu\Block; -use Magento\Framework\Api\Search\FilterGroupBuilder; -use Magento\Framework\Api\Search\SearchCriteriaFactory; use Magento\Framework\App\Cache\Type\Block; +use Magento\Framework\App\Http\Context; use Magento\Framework\DataObject; use Magento\Framework\View\Element\Template; use Magento\Framework\Event\Manager as EventManager; use Magento\Framework\Escaper; +use Snowdog\Menu\Api\Data\NodeInterface; use Snowdog\Menu\Api\MenuRepositoryInterface; use Snowdog\Menu\Api\NodeRepositoryInterface; use Snowdog\Menu\Model\Menu\Node\Image\File as ImageFile; @@ -18,9 +18,13 @@ /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ class Menu extends Template implements DataObject\IdentityInterface { + const XML_SNOWMENU_GENERAL_CUSTOMER_GROUPS = 'snowmenu/general/customer_groups'; + /** * @var MenuRepositoryInterface */ @@ -40,15 +44,6 @@ class Menu extends Template implements DataObject\IdentityInterface private $menu = null; - /** - * @var SearchCriteriaFactory - */ - private $searchCriteriaFactory; - - /** - * @var FilterGroupBuilder - */ - private $filterGroupBuilder; /** * @var EventManager */ @@ -84,6 +79,11 @@ class Menu extends Template implements DataObject\IdentityInterface */ private $escaper; + /** + * @var Context + */ + private $httpContext; + /** * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ @@ -93,25 +93,23 @@ public function __construct( MenuRepositoryInterface $menuRepository, NodeRepositoryInterface $nodeRepository, NodeTypeProvider $nodeTypeProvider, - SearchCriteriaFactory $searchCriteriaFactory, - FilterGroupBuilder $filterGroupBuilder, TemplateResolver $templateResolver, ImageFile $imageFile, Escaper $escaper, + Context $httpContext, array $data = [] ) { parent::__construct($context, $data); $this->menuRepository = $menuRepository; $this->nodeRepository = $nodeRepository; $this->nodeTypeProvider = $nodeTypeProvider; - $this->searchCriteriaFactory = $searchCriteriaFactory; - $this->filterGroupBuilder = $filterGroupBuilder; $this->eventManager = $eventManager; $this->templateResolver = $templateResolver; $this->imageFile = $imageFile; $this->escaper = $escaper; $this->setTemplate($this->getMenuTemplate($this->_template)); $this->submenuTemplate = $this->getSubmenuTemplate(); + $this->httpContext = $httpContext; } /** @@ -177,6 +175,9 @@ public function getCacheKeyInfo() if ($nodeCacheKeyInfo) { $info = array_merge($info, $nodeCacheKeyInfo); } + if ($this->_scopeConfig->isSetFlag(self::XML_SNOWMENU_GENERAL_CUSTOMER_GROUPS)) { + $info[] = 'cust_group_' . $this->getCustomerGroupId(); + } return $info; } @@ -268,7 +269,7 @@ public function isViewAllLinkAllowed($nodeType) } /** - * @param NodeRepositoryInterface $node + * @param NodeInterface $node * @return string */ public function renderViewAllLink($node) @@ -279,7 +280,7 @@ public function renderViewAllLink($node) } /** - * @param NodeRepositoryInterface $node + * @param NodeInterface $node * @return string */ public function renderMenuNode($node) @@ -381,7 +382,7 @@ public function getMenuCssClass($defaultClass = '') } /** - * @param NodeRepositoryInterface $node + * @param NodeInterface $node * @return Template */ private function getMenuNodeBlock($node) @@ -404,9 +405,13 @@ private function getMenuNodeBlock($node) ->setImage($node->getImage()) ->setImageUrl($node->getImage() ? $this->imageFile->getUrl($node->getImage()) : null) ->setImageAltText($node->getImageAltText()) + ->setImageWidth($node->getImageWidth()) + ->setImageHeight($node->getImageHeight()) + ->setImageAltText($node->getImageAltText()) ->setCustomTemplate($node->getNodeTemplate()) ->setAdditionalData($node->getAdditionalData()) - ->setSelectedItemId($node->getSelectedItemId()); + ->setSelectedItemId($node->getSelectedItemId()) + ->setCustomerGroups($node->getCustomerGroups()); return $nodeBlock; } @@ -438,12 +443,17 @@ private function getSubmenuBlock($nodes, $parentNode, $level = 0) private function fetchData() { $nodes = $this->nodeRepository->getByMenu($this->loadMenu()->getId()); + $currentCustomerGroup = $this->getCustomerGroupId(); + $customerGroupEnabled = $this->_scopeConfig->getValue(self::XML_SNOWMENU_GENERAL_CUSTOMER_GROUPS); $result = []; $types = []; foreach ($nodes as $node) { if (!$node->getIsActive()) { continue; } + if ($customerGroupEnabled && !$node->isVisible($currentCustomerGroup)) { + continue; + } $level = $node->getLevel(); $parent = $node->getParentId() ?: 0; @@ -498,4 +508,9 @@ private function getSubmenuTemplate() return $this->getMenuTemplate($baseSubmenuTemplate); } + + public function getCustomerGroupId() + { + return $this->httpContext->getValue(\Magento\Customer\Model\Context::CONTEXT_GROUP); + } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f0931ab..b076c5cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +## [2.27.0] +### Added +- `width` and `height` attributes to menu node images (DEV-102271) +- Option to specify customer groups for each node (DEV-94738) +- Snowdog branding in admin panel (DEV-105762) +- Automatically open collapsed menu node when dragging another node inside (DEV-101986) +- Duplicate node functionality (DEV-104364) +### Fixed +- Impossible to change Cms block, Cms page link after selecting displayed block (DEV-104546) +- Submenu template name issue ([#321](https://github.com/SnowdogApps/magento2-menu/pull/321)) (DEV-105672) +- Issue with 'Import from Categories ([#315](https://github.com/SnowdogApps/magento2-menu/issues/315)) (DEV-105267 & DEV-101741) +### Updated +- vue-select to 3.20.0 (DEV-104546) + ## [2.26.0] - 2024-03-29 ### Fixed - The function getProductTitle() returns empty string (DEV-104749) diff --git a/Controller/Adminhtml/Menu/Edit.php b/Controller/Adminhtml/Menu/Edit.php index ed527850..41b30734 100644 --- a/Controller/Adminhtml/Menu/Edit.php +++ b/Controller/Adminhtml/Menu/Edit.php @@ -63,7 +63,7 @@ public function execute(): ResultInterface $resultPage = $this->resultPageFactory->create(); $title = $menuId ? __('Edit Menu %1', $menu->getTitle()) : __('New Menu'); $this->initPage($resultPage)->addBreadcrumb($title, $title); - $resultPage->getConfig()->getTitle()->prepend(__('Menus')); + $resultPage->getConfig()->getTitle()->prepend(__('Snowdog Menus')); $resultPage->getConfig()->getTitle()->prepend($menu->getId() ? $menu->getTitle() : __('New Menu')); return $resultPage; diff --git a/Controller/Adminhtml/Menu/Import.php b/Controller/Adminhtml/Menu/Import.php index 1b2a4c2d..bf11f41f 100755 --- a/Controller/Adminhtml/Menu/Import.php +++ b/Controller/Adminhtml/Menu/Import.php @@ -36,6 +36,7 @@ public function execute() $this->messageManager->addNoticeMessage($this->importExportHelper->getMaxUploadSizeMessage()); $resultPage = $this->resultFactory->create(ResultFactory::TYPE_PAGE); + $resultPage->getConfig()->getTitle()->prepend(__('Snowdog Menus')); $resultPage->getConfig()->getTitle()->prepend(__('Menu Import')); return $resultPage; diff --git a/Controller/Adminhtml/Menu/ImportCategories.php b/Controller/Adminhtml/Menu/ImportCategories.php index e244eb30..7651d775 100644 --- a/Controller/Adminhtml/Menu/ImportCategories.php +++ b/Controller/Adminhtml/Menu/ImportCategories.php @@ -4,12 +4,12 @@ namespace Snowdog\Menu\Controller\Adminhtml\Menu; +use Exception; use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Backend\App\Action; use Magento\Backend\App\Action\Context; use Magento\Framework\Controller\Result\JsonFactory; use Snowdog\Menu\Api\MenuManagementInterface; -use Magento\Framework\Exception\NoSuchEntityException; class ImportCategories extends Action implements HttpPostActionInterface { @@ -47,24 +47,27 @@ public function execute() { $categoryId = (int) $this->_request->getParam('category_id'); $depth = $this->_request->getParam('depth'); - if (!is_numeric($depth)) { - $depth = null; - } - $result = $this->resultJsonFactory->create(); try { + if ($depth != 'NaN' && !is_numeric($depth)) { + throw new Exception('Please add a valid number for Level of depth field'); + } + $categoryTree = $this->menuManagement->getCategoryNodeList($categoryId, $depth); + $output = [ 'success' => 1, 'list' => $categoryTree ]; - } catch (NoSuchEntityException $exception) { + } catch (Exception $exception) { $output = [ 'success' => 0, 'message' => $exception->getMessage(), 'list' => [] ]; } + + $result = $this->resultJsonFactory->create(); $result->setData($output); return $result; diff --git a/Controller/Adminhtml/Menu/Index.php b/Controller/Adminhtml/Menu/Index.php index cb58ab74..3b51f2b4 100644 --- a/Controller/Adminhtml/Menu/Index.php +++ b/Controller/Adminhtml/Menu/Index.php @@ -16,7 +16,7 @@ class Index extends Action public function execute() { $resultPage = $this->resultFactory->create(ResultFactory::TYPE_PAGE); - $resultPage->getConfig()->getTitle()->prepend(__('Menus')); + $resultPage->getConfig()->getTitle()->prepend(__('Snowdog Menus')); return $resultPage; } } diff --git a/Model/CustomerGroupsProvider.php b/Model/CustomerGroupsProvider.php new file mode 100644 index 00000000..ca5a9197 --- /dev/null +++ b/Model/CustomerGroupsProvider.php @@ -0,0 +1,35 @@ +groupCollectionFactory = $groupCollectionFactory; + } + + public function getAll() + { + $customerGroups = []; + + /** @var Group $customerGroup */ + foreach ($this->groupCollectionFactory->create() as $customerGroup) { + $customerGroups[] = [ + 'label' => $customerGroup->getCode(), + 'value' => $customerGroup->getId() + ]; + } + + return $customerGroups; + } +} diff --git a/Model/GraphQl/Resolver/DataProvider/Node.php b/Model/GraphQl/Resolver/DataProvider/Node.php index d21eb313..6c52e85e 100644 --- a/Model/GraphQl/Resolver/DataProvider/Node.php +++ b/Model/GraphQl/Resolver/DataProvider/Node.php @@ -105,11 +105,15 @@ private function convertData(NodeInterface $node): array NodeInterface::TARGET => (bool) $node->getTarget(), NodeInterface::IMAGE => $node->getImage(), NodeInterface::IMAGE_ALT_TEXT => $node->getImageAltText(), + NodeInterface::IMAGE_WIDTH => $node->getImageWidth(), + NodeInterface::IMAGE_HEIGHT => $node->getImageHeight(), self::TEMPLATE_FIELD => $node->getNodeTemplate(), self::SUBMENU_TEMPLATE_FIELD => $node->getSubmenuTemplate(), NodeInterface::CREATION_TIME => $node->getCreationTime(), NodeInterface::UPDATE_TIME => $node->getUpdateTime(), - NodeInterface::ADDITIONAL_DATA => $node->getAdditionalData() + NodeInterface::ADDITIONAL_DATA => $node->getAdditionalData(), + NodeInterface::SELECTED_ITEM_ID => $node->getSelectedItemId(), + NodeInterface::CUSTOMER_GROUPS => $node->getCustomerGroups() ]; } diff --git a/Model/Menu/Node.php b/Model/Menu/Node.php index be2e040f..4291d991 100644 --- a/Model/Menu/Node.php +++ b/Model/Menu/Node.php @@ -1,14 +1,36 @@ serializer = $serializer; + } + protected function _construct() { $this->_init(\Snowdog\Menu\Model\ResourceModel\Menu\Node::class); @@ -214,6 +236,38 @@ public function setImageAltText($altText) return $this->setData(NodeInterface::IMAGE_ALT_TEXT, $altText); } + /** + * @inheritdoc + */ + public function getImageWidth() + { + return $this->_getData(NodeInterface::IMAGE_WIDTH); + } + + /** + * @inheritdoc + */ + public function setImageWidth($width) + { + return $this->setData(NodeInterface::IMAGE_WIDTH, $width); + } + + /** + * @inheritdoc + */ + public function getImageHeight() + { + return $this->_getData(NodeInterface::IMAGE_HEIGHT); + } + + /** + * @inheritdoc + */ + public function setImageHeight($height) + { + return $this->setData(NodeInterface::IMAGE_HEIGHT, $height); + } + /** * @inheritdoc */ @@ -293,4 +347,48 @@ public function setSelectedItemId($selectedItemId) { return $this->setData(NodeInterface::SELECTED_ITEM_ID, $selectedItemId); } + + public function getCustomerGroups() + { + $customerGroups = $this->_getData(NodeInterface::CUSTOMER_GROUPS); + if ($customerGroups == null) { + return []; + } + $customerGroups = explode(',', $customerGroups); + if (is_array($customerGroups) && !empty($customerGroups)) { + return $customerGroups; + } + + return []; + } + + public function setCustomerGroups($customerGroups) + { + if (empty($customerGroups)) { + $this->setData(NodeInterface::CUSTOMER_GROUPS); + return $this; + } + + if (is_string($customerGroups) && $this->serializer->unserialize($customerGroups)) { + return $this->setData(NodeInterface::CUSTOMER_GROUPS, $customerGroups); + } + + return $this->setData(NodeInterface::CUSTOMER_GROUPS, $this->serializer->serialize($customerGroups)); + } + + public function isVisible($customerGroupId) + { + $customerGroups = $this->getCustomerGroups(); + if (empty($customerGroups)) { + return true; + } + + foreach ($customerGroups as $customerGroup) { + if ((int) $customerGroup === (int) $customerGroupId) { + return true; + } + } + + return false; + } } diff --git a/Model/Menu/Node/Image/File.php b/Model/Menu/Node/Image/File.php index e71ab8bb..0115aaf3 100644 --- a/Model/Menu/Node/Image/File.php +++ b/Model/Menu/Node/Image/File.php @@ -14,6 +14,7 @@ use Magento\MediaStorage\Model\File\UploaderFactory; use Magento\Store\Model\StoreManagerInterface; use Psr\Log\LoggerInterface; +use Snowdog\Menu\Api\Data\NodeInterface; class File { @@ -72,7 +73,11 @@ public function upload(): array $result = $uploader->save($this->getAbsolutePath()); - return ['file' => $result['file'], 'url' => $this->getUrl($result['file'])]; + return [ + 'file' => $result['file'], + 'url' => $this->getUrl($result['file']), + 'size' => $this->getReadableImageSizes($this->getImageSize($result['file'])) + ]; } public function getUrl(string $file): string @@ -113,9 +118,25 @@ public function clone(string $file): string return $fileClonePath; } + public function getImageSize(string $file): array + { + $mediaDirectory = $this->filesystem->getDirectoryRead(DirectoryList::MEDIA); + $fileFullPath = $mediaDirectory->getAbsolutePath(self::PATH . $file); + + return getimagesize($fileFullPath); + } + private function getAbsolutePath(): string { $mediaDirectory = $this->filesystem->getDirectoryRead(DirectoryList::MEDIA); return $mediaDirectory->getAbsolutePath(self::PATH); } + + private function getReadableImageSizes(array $imageSize): array + { + return [ + NodeInterface::IMAGE_WIDTH => $imageSize[0], + NodeInterface::IMAGE_HEIGHT => $imageSize[1] + ]; + } } diff --git a/Model/Menu/Node/Image/Node.php b/Model/Menu/Node/Image/Node.php index a984ce88..1ac72231 100644 --- a/Model/Menu/Node/Image/Node.php +++ b/Model/Menu/Node/Image/Node.php @@ -51,6 +51,11 @@ public function updateNodeImage(int $nodeId, ?string $image): void try { $node->setImage($image); + if (!$image) { + $node + ->setImageWidth(null) + ->setImageHeight(null); + } $this->nodeRepository->save($node); } catch (CouldNotSaveException $exception) { // Normally, this error should never happen. @@ -62,7 +67,7 @@ public function updateNodeImage(int $nodeId, ?string $image): void public function getNodeListImages(array $nodeIds): array { $searchCriteria = $this->searchCriteriaBuilder - ->addFilter(NodeInterface::NODE_ID, $nodeIds, 'in') + ->addFilter('main_table.' . NodeInterface::NODE_ID, $nodeIds, 'in') ->addFilter(NodeInterface::IMAGE, true, 'notnull') ->addFilter(NodeInterface::IMAGE, '', 'neq') ->create(); diff --git a/Model/Menu/NodeRepository.php b/Model/Menu/NodeRepository.php index dc69be42..5ef0831f 100644 --- a/Model/Menu/NodeRepository.php +++ b/Model/Menu/NodeRepository.php @@ -15,6 +15,7 @@ use Snowdog\Menu\Model\Menu\NodeFactory; use Snowdog\Menu\Model\ResourceModel\Menu\Node\CollectionFactory; use Magento\Framework\Api\SortOrder; +use Magento\Framework\DB\Sql\Expression; class NodeRepository implements NodeRepositoryInterface { diff --git a/Model/MenuManagement.php b/Model/MenuManagement.php index fc5a70b6..2c5ae695 100644 --- a/Model/MenuManagement.php +++ b/Model/MenuManagement.php @@ -101,6 +101,8 @@ private function getCategoriesNodeList($level, $parent, array $data): array 'node_template' => null, 'image' => null, 'image_alt_text' => null, + 'image_width' => null, + 'image_height' => null, 'submenu_template' => null, 'columns' => $this->getCategoriesNodeList($level + 1, $nodeId, $data) ?: [] ]; diff --git a/Model/ResourceModel/Menu/Node.php b/Model/ResourceModel/Menu/Node.php index 4f65adc5..8f0609fd 100644 --- a/Model/ResourceModel/Menu/Node.php +++ b/Model/ResourceModel/Menu/Node.php @@ -4,15 +4,52 @@ namespace Snowdog\Menu\Model\ResourceModel\Menu; +use Magento\Framework\Model\AbstractModel; use Magento\Framework\Model\ResourceModel\Db\AbstractDb; +use Magento\Framework\Model\ResourceModel\Db\Context; +use Magento\Framework\Serialize\SerializerInterface; class Node extends AbstractDb { + protected $serializer; + + public function __construct( + Context $context, + SerializerInterface $serializer, + $connectionName = null + ) { + $this->serializer = $serializer; + parent::__construct($context, $connectionName); + } + protected function _construct() { $this->_init('snowmenu_node', 'node_id'); } + protected function _afterSave(AbstractModel $object) + { + $connection = $this->getConnection(); + $connection->delete('snowmenu_customer', ['node_id = ?' => $object->getNodeId()]); + + $nodeCustomerGroups = $object->getData('customer_groups'); + if ($nodeCustomerGroups && is_string($nodeCustomerGroups)) { + $nodeCustomerGroups = $this->serializer->unserialize($nodeCustomerGroups); + } + $insertData = []; + foreach ($nodeCustomerGroups ?? [] as $customerGroup) { + $insertData[] = [ + 'node_id' => $object->getNodeId(), + 'group_id' => $customerGroup + ]; + } + if ($nodeCustomerGroups) { + $connection->insertMultiple('snowmenu_customer', $insertData); + } + + return parent::_afterSave($object); + } + public function getFields(): array { return $this->getConnection()->describeTable($this->getMainTable()); diff --git a/Model/ResourceModel/Menu/Node/Collection.php b/Model/ResourceModel/Menu/Node/Collection.php index dc015074..3076fecc 100644 --- a/Model/ResourceModel/Menu/Node/Collection.php +++ b/Model/ResourceModel/Menu/Node/Collection.php @@ -1,10 +1,37 @@ scopeConfig = $scopeConfig; + parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource); + } + protected function _construct() { $this->_init( @@ -12,4 +39,21 @@ protected function _construct() \Snowdog\Menu\Model\ResourceModel\Menu\Node::class ); } + + protected function _initSelect() + { + parent::_initSelect(); + + if (!$this->scopeConfig->isSetFlag(Menu::XML_SNOWMENU_GENERAL_CUSTOMER_GROUPS)) { + return $this; + } + + $this->getSelect()->joinLeft( + ['customer' => 'snowmenu_customer'], + 'main_table.node_id = customer.node_id', + ['customer_groups' => new Expression('GROUP_CONCAT(group_id SEPARATOR \',\')')] + )->group('main_table.node_id'); + + return $this; + } } diff --git a/Model/TemplateResolver.php b/Model/TemplateResolver.php index 1493f8aa..4550345e 100755 --- a/Model/TemplateResolver.php +++ b/Model/TemplateResolver.php @@ -39,12 +39,12 @@ class TemplateResolver * @var Registry */ private $registry; - + /** * @var Validator */ private $validator; - + /** * @var AssetRepository */ @@ -164,7 +164,7 @@ private function getTemplateList($nodeType = '', $defaultTemplateLabel = '') continue; } - $fileName = str_replace([$themeDir, '.' . $extension], '', $file); + $fileName = $this->ioFile->getPathInfo($file)['filename']; if (!in_array($fileName, array_column($result, 'id'))) { $result[] = ['id' => $fileName]; } diff --git a/Service/Menu/SaveRequestProcessor.php b/Service/Menu/SaveRequestProcessor.php index 546feec8..219a8072 100644 --- a/Service/Menu/SaveRequestProcessor.php +++ b/Service/Menu/SaveRequestProcessor.php @@ -202,14 +202,59 @@ private function processNodeObject( $nodeObject->setLevel((string) $level); $nodeObject->setPosition((string) $position); - if ($nodeObject->getImage() && empty($nodeData['image'])) { - $this->nodeImageFile->delete($nodeObject->getImage()); + $this->processImageParameters($nodeData, $nodeObject); + + $nodeObject->setSelectedItemId($nodeData['selected_item_id'] ?? null); + $nodeObject->setCustomerGroups($nodeData[NodeInterface::CUSTOMER_GROUPS] ?? null); + } + + /** + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + */ + private function processImageParameters(array $nodeData, NodeInterface &$nodeObject): void + { + $nodeObject->setImageAltText($nodeData[NodeInterface::IMAGE_ALT_TEXT] ?? null); + + if (empty($nodeData[NodeInterface::IMAGE])) { + $nodeObject->setImageWidth(null); + $nodeObject->setImageHeight(null); + $nodeObject->setImage(null); + + if ($nodeObject->getImage()) { + $this->nodeImageFile->delete($nodeObject->getImage()); + } + + return; } - $nodeObject->setImage($nodeData['image'] ?? null); - $nodeObject->setImageAltText($nodeData['image_alt_text'] ?? null); + if (!$nodeObject->getImage()) { + $nodeObject->setImage($nodeData[NodeInterface::IMAGE]); + } - $nodeObject->setSelectedItemId($nodeData['selected_item_id'] ?? null); + if (empty($nodeData[NodeInterface::IMAGE_WIDTH]) + || empty($nodeData[NodeInterface::IMAGE_HEIGHT]) + ) { + try { + $imageSize = $this->nodeImageFile->getImageSize($nodeData[NodeInterface::IMAGE]); + } catch (\Exception $e) { + $imageSize = null; + } + + if (!empty($imageSize)) { + $nodeObject + ->setImageWidth( + !empty($nodeData[NodeInterface::IMAGE_WIDTH]) + ? $nodeData[NodeInterface::IMAGE_WIDTH] + : $imageSize[0] + ); + $nodeObject + ->setImageHeight( + !empty($nodeData[NodeInterface::IMAGE_HEIGHT]) + ? $nodeData[NodeInterface::IMAGE_HEIGHT] + : $imageSize[1] + ); + } + } } /** diff --git a/Setup/InstallData.php b/Setup/InstallData.php deleted file mode 100644 index 57212099..00000000 --- a/Setup/InstallData.php +++ /dev/null @@ -1,16 +0,0 @@ -startSetup(); - - $table = $installer->getConnection()->newTable( - $installer->getTable('snowmenu_menu') - )->addColumn( - 'menu_id', - Table::TYPE_INTEGER, - null, - ['identity' => true, 'nullable' => false, 'primary' => true, 'unsigned' => true,], - 'Entity ID' - )->addColumn( - 'title', - Table::TYPE_TEXT, - 255, - ['nullable' => false,], - 'Demo Title' - )->addColumn( - 'identifier', - Table::TYPE_TEXT, - 255, - ['nullable' => false], - 'Menu identifier' - )->addColumn( - 'creation_time', - Table::TYPE_TIMESTAMP, - null, - ['nullable' => false, 'default' => Table::TIMESTAMP_INIT,], - 'Creation Time' - )->addColumn( - 'update_time', - Table::TYPE_TIMESTAMP, - null, - ['nullable' => false, 'default' => Table::TIMESTAMP_INIT_UPDATE,], - 'Modification Time' - )->addColumn( - 'is_active', - Table::TYPE_SMALLINT, - null, - ['nullable' => false, 'default' => '1',], - 'Is Active' - ); - $installer->getConnection()->createTable($table); - - $table = $installer->getConnection()->newTable( - $installer->getTable('snowmenu_node') - )->addColumn( - 'node_id', - Table::TYPE_INTEGER, - null, - ['identity' => true, 'nullable' => false, 'primary' => true, 'unsigned' => true,], - 'Node ID' - )->addColumn( - 'menu_id', - Table::TYPE_INTEGER, - null, - ['nullable' => false], - 'Menu ID' - )->addColumn( - 'type', - Table::TYPE_TEXT, - 255, - ['nullable' => false], - 'Node Type' - )->addColumn( - 'content', - Table::TYPE_TEXT, - null, - [], - 'Node contents' - )->addColumn( - 'classes', - Table::TYPE_TEXT, - 255, - [], - 'CSS class name' - )->addColumn( - 'parent_id', - Table::TYPE_INTEGER, - null, - ['unsigned' => true], - 'Parent Node ID' - )->addColumn( - 'position', - Table::TYPE_INTEGER, - null, - ['nullable' => false, 'unsigned' => true], - 'Node position' - )->addColumn( - 'level', - Table::TYPE_INTEGER, - null, - ['nullable' => false, 'unsigned' => true], - 'Node level' - )->addColumn( - 'title', - Table::TYPE_TEXT, - 255, - ['nullable' => false,], - 'Demo Title' - )->addColumn( - 'creation_time', - Table::TYPE_TIMESTAMP, - null, - ['nullable' => false, 'default' => Table::TIMESTAMP_INIT,], - 'Creation Time' - )->addColumn( - 'update_time', - Table::TYPE_TIMESTAMP, - null, - ['nullable' => false, 'default' => Table::TIMESTAMP_INIT_UPDATE,], - 'Modification Time' - )->addColumn( - 'is_active', - Table::TYPE_SMALLINT, - null, - ['nullable' => false, 'default' => '1',], - 'Is Active' - ); - $installer->getConnection()->createTable($table); - - $table = $installer->getConnection()->newTable( - $installer->getTable('snowmenu_store') - )->addColumn( - 'menu_id', - Table::TYPE_INTEGER, - null, - ['nullable' => false, 'primary' => true, 'unsigned' => true,], - 'Menu ID' - )->addColumn( - 'store_id', - Table::TYPE_INTEGER, - null, - ['nullable' => false, 'primary' => true, 'unsigned' => true,], - 'Store ID' - ); - $installer->getConnection()->createTable($table); - - $installer->endSetup(); - } -} diff --git a/Setup/UpgradeSchema.php b/Setup/UpgradeSchema.php deleted file mode 100644 index 69f29186..00000000 --- a/Setup/UpgradeSchema.php +++ /dev/null @@ -1,301 +0,0 @@ -. - * @category - * @package - * @copyright Copyright Snowdog (http://snow.dog) - */ - -namespace Snowdog\Menu\Setup; - -use Magento\Framework\DB\Ddl\Table; -use Magento\Framework\Setup\ModuleContextInterface; -use Magento\Framework\Setup\SchemaSetupInterface; -use Magento\Framework\Setup\UpgradeSchemaInterface; -use Snowdog\Menu\Api\Data\NodeInterface; - -// @codingStandardsIgnoreFile -class UpgradeSchema implements UpgradeSchemaInterface -{ - /** - * {@inheritdoc} - * @SuppressWarnings(PHPMD.NPathComplexity) - */ - public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context) - { - $setup->startSetup(); - - if (version_compare($context->getVersion(), '0.1.0', '<')) { - $this->changeTitleType($setup); - } - - if (version_compare($context->getVersion(), '0.2.0', '<')) { - $this->addMenuCssClassField($setup); - } - - if (version_compare($context->getVersion(), '0.2.1', '<')) { - $this->addTargetAttribute($setup); - } - - if (version_compare($context->getVersion(), '0.2.2', '<')) { - $this->updateTargetAttribute($setup); - } - - if (version_compare($context->getVersion(), '0.2.3', '<')) { - $this->addForeignKeys($setup); - } - - if (version_compare($context->getVersion(), '0.2.4', '<')) { - $this->addTemplateFields($setup); - } - - if (version_compare($context->getVersion(), '0.2.5', '<')) { - $this->addNodeImageFields($setup); - } - - if (version_compare($context->getVersion(), '0.2.6', '<')) { - $this->addNodeSelectedItemId($setup); - } - - $setup->endSetup(); - } - - /** - * @param SchemaSetupInterface $setup - * @return $this - */ - private function addMenuCssClassField(SchemaSetupInterface $setup) - { - $setup->getConnection()->addColumn( - $setup->getTable('snowmenu_menu'), - 'css_class', - [ - 'type' => Table::TYPE_TEXT, - 'length' => 255, - 'nullable' => true, - 'after' => 'identifier', - 'default' => 'menu', - 'comment' => 'CSS Class' - ] - ); - - return $this; - } - - private function changeTitleType(SchemaSetupInterface $setup) - { - $setup->getConnection()->modifyColumn( - $setup->getTable('snowmenu_node'), - 'title', - [ - 'type' => Table::TYPE_TEXT, - 'nullable' => false - ], - 'Demo Title' - ); - } - - private function addTargetAttribute(SchemaSetupInterface $setup) - { - $setup->getConnection()->addColumn( - $setup->getTable('snowmenu_node'), - 'target', - [ - 'type' => Table::TYPE_TEXT, - 'length' => 10, - 'nullable' => true, - 'after' => 'title', - 'default' => '_self', - 'comment' => 'Link target', - ] - ); - - return $this; - } - - private function updateTargetAttribute(SchemaSetupInterface $setup) - { - $table = $setup->getTable('snowmenu_node'); - $connection = $setup->getConnection(); - - $connection->update( - $table, - ['target' => 0], - "target = '_self'" - ); - $connection->update( - $table, - ['target' => 1], - "target = '_blank'" - ); - $connection->modifyColumn( - $table, - 'target', - [ - 'type' => Table::TYPE_BOOLEAN, - 'default' => 0, - ] - ); - } - - private function addForeignKeys(SchemaSetupInterface $setup) - { - $menuTable = $setup->getTable('snowmenu_menu'); - $nodeTable = $setup->getTable('snowmenu_node'); - $storeTable = $setup->getTable('snowmenu_store'); - $setup->getConnection()->modifyColumn( - $nodeTable, - 'menu_id', - [ - 'type' => Table::TYPE_INTEGER, - 'length' => 10, - 'nullable' => false, - 'unsigned' => true, - 'comment' => 'Menu ID' - ] - ); - - $setup->getConnection()->modifyColumn( - $storeTable, - 'store_id', - [ - 'type' => Table::TYPE_SMALLINT, - 'length' => 5, - 'nullable' => false, - 'primary' => true, - 'unsigned' => true, - 'comment' => 'Store ID' - ] - ); - - $setup->getConnection()->addForeignKey( - $setup->getFkName( - 'snowmenu_node', - 'menu_id', - 'snowmenu_menu', - 'menu_id' - ), - $nodeTable, - 'menu_id', - $menuTable, - 'menu_id', - Table::ACTION_CASCADE - ); - - $setup->getConnection()->addForeignKey( - $setup->getFkName( - 'snowmenu_store', - 'menu_id', - 'snowmenu_menu', - 'menu_id' - ), - $storeTable, - 'menu_id', - $menuTable, - 'menu_id', - Table::ACTION_CASCADE - ); - - $setup->getConnection()->addForeignKey( - $setup->getFkName( - 'snowmenu_store', - 'store_id', - 'store', - 'store_id' - ), - $storeTable, - 'store_id', - $setup->getTable('store'), - 'store_id', - Table::ACTION_CASCADE - ); - } - - /** - * @param SchemaSetupInterface $setup - * @return $this - */ - private function addTemplateFields(SchemaSetupInterface $setup) - { - $setup->getConnection()->addColumn( - $setup->getTable('snowmenu_node'), - 'submenu_template', - [ - 'type' => Table::TYPE_TEXT, - 'length' => 255, - 'nullable' => true, - 'after' => 'target', - 'comment' => 'Submenu Template', - ] - ); - - $setup->getConnection()->addColumn( - $setup->getTable('snowmenu_node'), - 'node_template', - [ - 'type' => Table::TYPE_TEXT, - 'length' => 255, - 'nullable' => true, - 'after' => 'target', - 'comment' => 'Node Template', - ] - ); - - return $this; - } - - /** - * @return $this - */ - private function addNodeImageFields(SchemaSetupInterface $setup) - { - $connection = $setup->getConnection(); - $table = $setup->getTable('snowmenu_node'); - - $connection->addColumn( - $table, - 'image', - [ - 'type' => Table::TYPE_TEXT, - 'nullable' => true, - 'after' => 'target', - 'comment' => 'Image' - ] - ); - - $connection->addColumn( - $table, - 'image_alt_text', - [ - 'type' => Table::TYPE_TEXT, - 'nullable' => true, - 'after' => 'image', - 'comment' => 'Image Alt Text' - ] - ); - - return $this; - } - - private function addNodeSelectedItemId(SchemaSetupInterface $setup) - { - $connection = $setup->getConnection(); - $table = $setup->getTable('snowmenu_node'); - - $connection->addColumn( - $table, - NodeInterface::SELECTED_ITEM_ID, - [ - 'type' => Table::TYPE_SMALLINT, - 'length' => 6, - 'unsigned' => true, - 'nullable' => true, - 'comment' => 'Selected Item Id' - ] - ); - - return $this; - } -} diff --git a/Ui/Component/Menu/Form/Element/Categories.php b/Ui/Component/Menu/Form/Element/Categories.php index d56391e2..87df22a6 100644 --- a/Ui/Component/Menu/Form/Element/Categories.php +++ b/Ui/Component/Menu/Form/Element/Categories.php @@ -11,8 +11,6 @@ class Categories implements ArrayInterface { - const DEFAULT_CATEGORY_ID = 2; - /** * @var CategoryCollectionFactory */ @@ -60,35 +58,47 @@ private function retrieveCategories(int $storeId = 0, $toOptionArray = true): ar $collection = $this->categoryCollectionFactory->create(); $collection->addAttributeToSelect(['name', 'is_active', 'parent_id']) - ->addFieldToFilter('level', 2) + ->addFieldToFilter('level', 1) ->setStoreId($storeId); + + $options = []; - if ($toOptionArray) { - $options[] = [ - 'label' => __('Default Category'), - 'value' => self::DEFAULT_CATEGORY_ID - ]; - } else { - $options[self::DEFAULT_CATEGORY_ID] = __('Default Category'); - } + foreach ($collection as $rootCategory) { + /* @var $collection Collection */ + $collection = $this->categoryCollectionFactory->create(); + + $collection->addAttributeToSelect(['name', 'is_active', 'parent_id']) + ->addFieldToFilter('level', 2) + ->addFieldToFilter('path', ['like' => '1/'.$rootCategory->getId().'/%']) + ->setStoreId($storeId); - $groupedOptions = []; - foreach ($collection as $category) { if ($toOptionArray) { - $groupedOptions[] = [ - 'label' => $category->getName(), - 'value' => $category->getId() + $options[] = [ + 'label' => $rootCategory->getName(), + 'value' => $rootCategory->getId() ]; } else { - $options[$category->getId()] = $category->getName(); + $options[$rootCategory->getId()] = $rootCategory->getName(); } - } - if ($toOptionArray && $groupedOptions) { - $options[] = [ - 'label' => __('Sub categories'), - 'value' => $groupedOptions - ]; + $groupedOptions = []; + foreach ($collection as $category) { + if ($toOptionArray) { + $groupedOptions[] = [ + 'label' => $category->getName(), + 'value' => $category->getId() + ]; + } else { + $options[$category->getId()] = $category->getName(); + } + } + + if ($toOptionArray && $groupedOptions) { + $options[] = [ + 'label' => __('Sub categories'), + 'value' => $groupedOptions + ]; + } } return $options; diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml new file mode 100644 index 00000000..0cd14336 --- /dev/null +++ b/etc/adminhtml/system.xml @@ -0,0 +1,21 @@ + + + + + + +
+ Snowdog_Menu::settings + + snowdog + + + + + Controls serving different menus to different customer groups + Magento\Config\Model\Config\Source\Yesno + + +
+
+
diff --git a/etc/config.xml b/etc/config.xml index b8246cd4..9ba186d7 100644 --- a/etc/config.xml +++ b/etc/config.xml @@ -11,6 +11,9 @@ + + 0 + 1 diff --git a/etc/db_schema.xml b/etc/db_schema.xml new file mode 100644 index 00000000..21d02c1d --- /dev/null +++ b/etc/db_schema.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+ + + + + + + +
+
diff --git a/etc/db_schema_whitelist.json b/etc/db_schema_whitelist.json new file mode 100644 index 00000000..94d4d708 --- /dev/null +++ b/etc/db_schema_whitelist.json @@ -0,0 +1,71 @@ +{ + "snowmenu_menu": { + "column": { + "menu_id": true, + "title": true, + "identifier": true, + "creation_time": true, + "update_time": true, + "is_active": true, + "css_class": true + }, + "constraint": { + "PRIMARY": true + } + }, + "snowmenu_node": { + "column": { + "node_id": true, + "menu_id": true, + "type": true, + "content": true, + "classes": true, + "parent_id": true, + "position": true, + "level": true, + "title": true, + "creation_time": true, + "update_time": true, + "is_active": true, + "target": true, + "submenu_template": true, + "node_template": true, + "image": true, + "image_alt_text": true, + "selected_item_id": true, + "image_width": true, + "image_heigth": true, + "customer_groups": true + }, + "constraint": { + "PRIMARY": true, + "SNOWMENU_NODE_MENU_ID_SNOWMENU_MENU_MENU_ID": true + }, + "index": { + "SNOWMENU_NODE_NODE_ID": true + } + }, + "snowmenu_store": { + "column": { + "menu_id": true, + "store_id": true + }, + "constraint": { + "PRIMARY": true, + "SNOWMENU_STORE_MENU_ID_SNOWMENU_MENU_MENU_ID": true, + "SNOWMENU_STORE_STORE_ID_STORE_STORE_ID": true + } + }, + "snowmenu_customer": { + "column": { + "node_id": true, + "group_id": true + }, + "index": { + "SNOWMENU_CUSTOMER_NODE_ID": true + }, + "constraint": { + "SNOWMENU_CUSTOMER_NODE_ID_SNOWMENU_NODE_NODE_ID": true + } + } +} \ No newline at end of file diff --git a/etc/module.xml b/etc/module.xml index f58fd655..1db65ee8 100644 --- a/etc/module.xml +++ b/etc/module.xml @@ -1,6 +1,6 @@ - + diff --git a/view/adminhtml/layout/snowmenu_menu_create.xml b/view/adminhtml/layout/snowmenu_menu_create.xml index 73ecebad..c7b54b2e 100644 --- a/view/adminhtml/layout/snowmenu_menu_create.xml +++ b/view/adminhtml/layout/snowmenu_menu_create.xml @@ -2,5 +2,8 @@ + + + diff --git a/view/adminhtml/layout/snowmenu_menu_edit.xml b/view/adminhtml/layout/snowmenu_menu_edit.xml index 00ce5a92..b85ffea8 100644 --- a/view/adminhtml/layout/snowmenu_menu_edit.xml +++ b/view/adminhtml/layout/snowmenu_menu_edit.xml @@ -2,6 +2,9 @@ + + + diff --git a/view/adminhtml/templates/menu/nodes.phtml b/view/adminhtml/templates/menu/nodes.phtml index e4a61867..2d1b2723 100644 --- a/view/adminhtml/templates/menu/nodes.phtml +++ b/view/adminhtml/templates/menu/nodes.phtml @@ -44,6 +44,7 @@ $vueComponents = $block->getVueComponents(); "imageDeleteUrl" : "getImageDeleteUrl() ?>", "imageUploadFileId": "getImageUploadFileId() ?>", "lazyMinItemsCount": "1000", + "customerGroups" : getCustomerGroups()) ?>, "translation": { "nodes" : "", "click" : "", @@ -51,6 +52,7 @@ $vueComponents = $block->getVueComponents(); "createSubNode" : "", "append" : "", "edit" : "", + "duplicate" : "", "delete" : "", "addNode" : "", "nodeType" : "", @@ -70,7 +72,11 @@ $vueComponents = $block->getVueComponents(); "product" : "", "productId" : "", "imageAltText" : "", - "selectedItemId" : "" + "imageWidth" : "", + "imageHeight" : "", + "selectedItemId" : "", + "customerGroups" : "", + "customerGroupsDescription" : "" } } } diff --git a/view/adminhtml/ui_component/snowmenu_menu_form.xml b/view/adminhtml/ui_component/snowmenu_menu_form.xml index 1e624e58..cae2ec9a 100644 --- a/view/adminhtml/ui_component/snowmenu_menu_form.xml +++ b/view/adminhtml/ui_component/snowmenu_menu_form.xml @@ -203,6 +203,7 @@ + Snowdog_Menu/form/element/depth-input int diff --git a/view/adminhtml/web/css/lib/v-select.css b/view/adminhtml/web/css/lib/v-select.css new file mode 100644 index 00000000..81c8ca7f --- /dev/null +++ b/view/adminhtml/web/css/lib/v-select.css @@ -0,0 +1 @@ +:root{--vs-colors--lightest:rgba(60,60,60,0.26);--vs-colors--light:rgba(60,60,60,0.5);--vs-colors--dark:#333;--vs-colors--darkest:rgba(0,0,0,0.15);--vs-search-input-color:inherit;--vs-search-input-bg:#fff;--vs-search-input-placeholder-color:inherit;--vs-line-height:1.4;--vs-state-disabled-bg:#f8f8f8;--vs-state-disabled-color:var(--vs-colors--light);--vs-state-disabled-controls-color:var(--vs-colors--light);--vs-state-disabled-cursor:not-allowed;--vs-border-color:var(--vs-colors--lightest);--vs-border-width:1px;--vs-border-style:solid;--vs-border-radius:0;--vs-actions-padding:4px 6px 0 3px;--vs-controls-color:var(--vs-colors--light);--vs-controls-size:1;--vs-controls--deselect-text-shadow:0 1px 0 #fff;--vs-selected-bg:#f0f0f0;--vs-selected-color:var(--vs-colors--dark);--vs-selected-border-color:var(--vs-border-color);--vs-selected-border-style:var(--vs-border-style);--vs-selected-border-width:var(--vs-border-width);--vs-dropdown-bg:#fff;--vs-dropdown-color:inherit;--vs-dropdown-z-index:1000;--vs-dropdown-min-width:160px;--vs-dropdown-max-height:350px;--vs-dropdown-box-shadow:0px 3px 6px 0px var(--vs-colors--darkest);--vs-dropdown-option-bg:#000;--vs-dropdown-option-color:var(--vs-dropdown-color);--vs-dropdown-option-padding:3px 20px;--vs-dropdown-option--active-bg:#5897fb;--vs-dropdown-option--active-color:#fff;--vs-dropdown-option--deselect-bg:#fb5858;--vs-dropdown-option--deselect-color:#fff;--vs-transition-timing-function:cubic-bezier(1,-0.115,0.975,0.855);--vs-transition-duration:150ms}.v-select{font-family:inherit;position:relative}.v-select,.v-select *{box-sizing:border-box}:root{--vs-transition-timing-function:cubic-bezier(1,0.5,0.8,1);--vs-transition-duration:0.15s}@-webkit-keyframes vSelectSpinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes vSelectSpinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.vs__fade-enter-active,.vs__fade-leave-active{pointer-events:none;transition:opacity var(--vs-transition-duration) var(--vs-transition-timing-function)}.vs__fade-enter,.vs__fade-leave-to{opacity:0}:root{--vs-disabled-bg:var(--vs-state-disabled-bg);--vs-disabled-color:var(--vs-state-disabled-color);--vs-disabled-cursor:var(--vs-state-disabled-cursor)}.vs--disabled .vs__clear,.vs--disabled .vs__dropdown-toggle,.vs--disabled .vs__open-indicator,.vs--disabled .vs__search,.vs--disabled .vs__selected{background-color:var(--vs-disabled-bg);cursor:var(--vs-disabled-cursor)}.v-select[dir=rtl] .vs__actions{padding:0 3px 0 6px}.v-select[dir=rtl] .vs__clear{margin-left:6px;margin-right:0}.v-select[dir=rtl] .vs__deselect{margin-left:0;margin-right:2px}.v-select[dir=rtl] .vs__dropdown-menu{text-align:right}.vs__dropdown-toggle{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:var(--vs-search-input-bg);border:var(--vs-border-width) var(--vs-border-style) var(--vs-border-color);border-radius:var(--vs-border-radius);display:flex;padding:0 0 4px;white-space:normal}.vs__selected-options{display:flex;flex-basis:100%;flex-grow:1;flex-wrap:wrap;padding:0 2px;position:relative}.vs__actions{align-items:center;display:flex;padding:var(--vs-actions-padding)}.vs--searchable .vs__dropdown-toggle{cursor:text}.vs--unsearchable .vs__dropdown-toggle{cursor:pointer}.vs--open .vs__dropdown-toggle{border-bottom-color:transparent;border-bottom-left-radius:0;border-bottom-right-radius:0}.vs__open-indicator{fill:var(--vs-controls-color);transform:scale(var(--vs-controls-size));transition:transform var(--vs-transition-duration) var(--vs-transition-timing-function);transition-timing-function:var(--vs-transition-timing-function)}.vs--open .vs__open-indicator{transform:rotate(180deg) scale(var(--vs-controls-size))}.vs--loading .vs__open-indicator{opacity:0}.vs__clear{fill:var(--vs-controls-color);background-color:transparent;border:0;cursor:pointer;margin-right:8px;padding:0}.vs__dropdown-menu{background:var(--vs-dropdown-bg);border:var(--vs-border-width) var(--vs-border-style) var(--vs-border-color);border-radius:0 0 var(--vs-border-radius) var(--vs-border-radius);border-top-style:none;box-shadow:var(--vs-dropdown-box-shadow);box-sizing:border-box;color:var(--vs-dropdown-color);display:block;left:0;list-style:none;margin:0;max-height:var(--vs-dropdown-max-height);min-width:var(--vs-dropdown-min-width);overflow-y:auto;padding:5px 0;position:absolute;text-align:left;top:calc(100% - var(--vs-border-width));width:100%;z-index:var(--vs-dropdown-z-index)}.vs__no-options{text-align:center}.vs__dropdown-option{clear:both;color:var(--vs-dropdown-option-color);cursor:pointer;display:block;line-height:1.42857143;padding:var(--vs-dropdown-option-padding);white-space:nowrap}.vs__dropdown-option--highlight{background:var(--vs-dropdown-option--active-bg);color:var(--vs-dropdown-option--active-color)}.vs__dropdown-option--deselect{background:var(--vs-dropdown-option--deselect-bg);color:var(--vs-dropdown-option--deselect-color)}.vs__dropdown-option--disabled{background:var(--vs-state-disabled-bg);color:var(--vs-state-disabled-color);cursor:var(--vs-state-disabled-cursor)}.vs__selected{align-items:center;background-color:var(--vs-selected-bg);border:var(--vs-selected-border-width) var(--vs-selected-border-style) var(--vs-selected-border-color);border-radius:var(--vs-border-radius);color:var(--vs-selected-color);display:flex;line-height:var(--vs-line-height);margin:4px 2px 0;padding:0 .25em;z-index:0}.vs__deselect{fill:var(--vs-controls-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;cursor:pointer;display:inline-flex;margin-left:4px;padding:0;text-shadow:var(--vs-controls--deselect-text-shadow)}.vs--single .vs__selected{background-color:transparent;border-color:transparent}.vs--single.vs--loading .vs__selected,.vs--single.vs--open .vs__selected{opacity:.4;position:absolute}.vs--single.vs--searching .vs__selected{display:none}.vs__search::-webkit-search-cancel-button{display:none}.vs__search::-ms-clear,.vs__search::-webkit-search-decoration,.vs__search::-webkit-search-results-button,.vs__search::-webkit-search-results-decoration{display:none}.vs__search,.vs__search:focus{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:1px solid transparent;border-left:none;box-shadow:none;color:var(--vs-search-input-color);flex-grow:1;line-height:var(--vs-line-height);margin:4px 0 0;max-width:100%;outline:none;padding:0 7px;width:0;z-index:1}.vs__search::-moz-placeholder{color:var(--vs-search-input-placeholder-color)}.vs__search:-ms-input-placeholder{color:var(--vs-search-input-placeholder-color)}.vs__search::placeholder{color:var(--vs-search-input-placeholder-color)}.vs--unsearchable .vs__search{opacity:1}.vs--unsearchable:not(.vs--disabled) .vs__search{cursor:pointer}.vs--single.vs--searching:not(.vs--open):not(.vs--loading) .vs__search{opacity:.2}.vs__spinner{align-self:center;-webkit-animation:vSelectSpinner 1.1s linear infinite;animation:vSelectSpinner 1.1s linear infinite;border:.9em solid hsla(0,0%,39%,.1);border-left-color:rgba(60,60,60,.45);font-size:5px;opacity:0;overflow:hidden;text-indent:-9999em;transform:translateZ(0) scale(var(--vs-controls--spinner-size,var(--vs-controls-size)));transition:opacity .1s}.vs__spinner,.vs__spinner:after{border-radius:50%;height:5em;transform:scale(var(--vs-controls--spinner-size,var(--vs-controls-size)));width:5em}.vs--loading .vs__spinner{opacity:1} diff --git a/view/adminhtml/web/css/source/_module.less b/view/adminhtml/web/css/source/_module.less index 653dd34f..0d155853 100644 --- a/view/adminhtml/web/css/source/_module.less +++ b/view/adminhtml/web/css/source/_module.less @@ -1,4 +1,3 @@ -@import './lib/_v-select.less'; @import './lib/_vue-treeselect.less'; @import './blocks/_image-upload'; @@ -9,3 +8,5 @@ @import './blocks/_vue-treeselect.less'; @import './blocks/_var.less'; @import './blocks/_vddl-base.less'; + +@import 'module/menu/_menu'; diff --git a/view/adminhtml/web/css/source/blocks/_panel.less b/view/adminhtml/web/css/source/blocks/_panel.less index edb61c03..584ba40f 100644 --- a/view/adminhtml/web/css/source/blocks/_panel.less +++ b/view/adminhtml/web/css/source/blocks/_panel.less @@ -64,7 +64,7 @@ padding-left: 5px; } - &__buttom { + &__button { border-color: transparent; color: @primary__color; background-color: transparent; @@ -107,6 +107,12 @@ content: @icon-delete__content; } } + + &--duplicate { + height: @snow-menu__item-height; + padding-top: 4px; + vertical-align: middle; + } } &__collapse { diff --git a/view/adminhtml/web/css/source/lib/_v-select.less b/view/adminhtml/web/css/source/lib/_v-select.less deleted file mode 100644 index 32e00d28..00000000 --- a/view/adminhtml/web/css/source/lib/_v-select.less +++ /dev/null @@ -1 +0,0 @@ -.v-select{position:relative;font-family:inherit}.v-select,.v-select *{box-sizing:border-box}@-webkit-keyframes vSelectSpinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes vSelectSpinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.vs__fade-enter-active,.vs__fade-leave-active{pointer-events:none;transition:opacity .15s cubic-bezier(1,.5,.8,1)}.vs__fade-enter,.vs__fade-leave-to{opacity:0}.vs--disabled .vs__clear,.vs--disabled .vs__dropdown-toggle,.vs--disabled .vs__open-indicator,.vs--disabled .vs__search,.vs--disabled .vs__selected{cursor:not-allowed;background-color:#f8f8f8}.v-select[dir=rtl] .vs__actions{padding:0 3px 0 6px}.v-select[dir=rtl] .vs__clear{margin-left:6px;margin-right:0}.v-select[dir=rtl] .vs__deselect{margin-left:0;margin-right:2px}.v-select[dir=rtl] .vs__dropdown-menu{text-align:right}.vs__dropdown-toggle{-webkit-appearance:none;-moz-appearance:none;appearance:none;display:flex;padding:0 0 4px;background:none;border:1px solid rgba(60,60,60,.26);border-radius:4px;white-space:normal}.vs__selected-options{display:flex;flex-basis:100%;flex-grow:1;flex-wrap:wrap;padding:0 2px;position:relative}.vs__actions{display:flex;align-items:center;padding:4px 6px 0 3px}.vs--searchable .vs__dropdown-toggle{cursor:text}.vs--unsearchable .vs__dropdown-toggle{cursor:pointer}.vs--open .vs__dropdown-toggle{border-bottom-color:transparent;border-bottom-left-radius:0;border-bottom-right-radius:0}.vs__open-indicator{fill:rgba(60,60,60,.5);transform:scale(1);transition:transform .15s cubic-bezier(1,-.115,.975,.855);transition-timing-function:cubic-bezier(1,-.115,.975,.855)}.vs--open .vs__open-indicator{transform:rotate(180deg) scale(1)}.vs--loading .vs__open-indicator{opacity:0}.vs__clear{fill:rgba(60,60,60,.5);padding:0;border:0;background-color:transparent;cursor:pointer;margin-right:8px}.vs__dropdown-menu{display:block;box-sizing:border-box;position:absolute;top:calc(100% - 1px);left:0;z-index:1000;padding:5px 0;margin:0;width:100%;max-height:350px;min-width:160px;overflow-y:auto;box-shadow:0 3px 6px 0 rgba(0,0,0,.15);border:1px solid rgba(60,60,60,.26);border-top-style:none;border-radius:0 0 4px 4px;text-align:left;list-style:none;background:#fff}.vs__no-options{text-align:center}.vs__dropdown-option{line-height:1.42857143;display:block;padding:3px 20px;clear:both;color:#333;white-space:nowrap}.vs__dropdown-option:hover{cursor:pointer}.vs__dropdown-option--highlight{background:#5897fb;color:#fff}.vs__dropdown-option--disabled{background:inherit;color:rgba(60,60,60,.5)}.vs__dropdown-option--disabled:hover{cursor:inherit}.vs__selected{display:flex;align-items:center;background-color:#f0f0f0;border:1px solid rgba(60,60,60,.26);border-radius:4px;color:#333;line-height:1.4;margin:4px 2px 0;padding:0 .25em}.vs__deselect{display:inline-flex;-webkit-appearance:none;-moz-appearance:none;appearance:none;margin-left:4px;padding:0;border:0;cursor:pointer;background:none;fill:rgba(60,60,60,.5);text-shadow:0 1px 0 #fff}.vs--single .vs__selected{background-color:transparent;border-color:transparent}.vs--single.vs--open .vs__selected{position:absolute;opacity:.4}.vs--single.vs--searching .vs__selected{display:none}.vs__search::-webkit-search-cancel-button{display:none}.vs__search::-ms-clear,.vs__search::-webkit-search-decoration,.vs__search::-webkit-search-results-button,.vs__search::-webkit-search-results-decoration{display:none}.vs__search,.vs__search:focus{-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1.4;font-size:1em;border:1px solid transparent;border-left:none;outline:none;margin:4px 0 0;padding:0 7px;background:none;box-shadow:none;width:0;max-width:100%;flex-grow:1}.vs__search::-webkit-input-placeholder{color:inherit}.vs__search::-moz-placeholder{color:inherit}.vs__search:-ms-input-placeholder{color:inherit}.vs__search::-ms-input-placeholder{color:inherit}.vs__search::placeholder{color:inherit}.vs--unsearchable .vs__search{opacity:1}.vs--unsearchable .vs__search:hover{cursor:pointer}.vs--single.vs--searching:not(.vs--open):not(.vs--loading) .vs__search{opacity:.2}.vs__spinner{align-self:center;opacity:0;font-size:5px;text-indent:-9999em;overflow:hidden;border:.9em solid hsla(0,0%,39.2%,.1);border-left-color:rgba(60,60,60,.45);transform:translateZ(0);-webkit-animation:vSelectSpinner 1.1s linear infinite;animation:vSelectSpinner 1.1s linear infinite;transition:opacity .1s}.vs__spinner,.vs__spinner:after{border-radius:50%;width:5em;height:5em}.vs--loading .vs__spinner{opacity:1} diff --git a/view/adminhtml/web/css/source/module/menu/_menu.less b/view/adminhtml/web/css/source/module/menu/_menu.less new file mode 100644 index 00000000..19ebe2c5 --- /dev/null +++ b/view/adminhtml/web/css/source/module/menu/_menu.less @@ -0,0 +1,9 @@ +.admin__menu [data-ui-id^='menu-snowdog-menu-menus'] span:before { + background: url('@{baseDir}Snowdog_Menu/images/logo-menu.svg') no-repeat center; + content: ''; + display: inline-block; + margin-right: 10px; + vertical-align: top; + width: 19px; + height: 19px; +} diff --git a/view/adminhtml/web/images/logo-menu.svg b/view/adminhtml/web/images/logo-menu.svg new file mode 100644 index 00000000..206e99bb --- /dev/null +++ b/view/adminhtml/web/images/logo-menu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/view/adminhtml/web/js/lib/vue-select.js b/view/adminhtml/web/js/lib/vue-select.js index f6703883..665ffd3b 100644 --- a/view/adminhtml/web/js/lib/vue-select.js +++ b/view/adminhtml/web/js/lib/vue-select.js @@ -1 +1 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.VueSelect=e():t.VueSelect=e()}("undefined"!=typeof self?self:this,(function(){return function(t){var e={};function n(o){if(e[o])return e[o].exports;var i=e[o]={i:o,l:!1,exports:{}};return t[o].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=t,n.c=e,n.d=function(t,e,o){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:o})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(o,i,function(e){return t[e]}.bind(null,i));return o},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="/",n(n.s=8)}([function(t,e,n){var o=n(4),i=n(5),s=n(6);t.exports=function(t){return o(t)||i(t)||s()}},function(t,e){function n(e){return"function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?t.exports=n=function(t){return typeof t}:t.exports=n=function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},n(e)}t.exports=n},function(t,e,n){},function(t,e){t.exports=function(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}},function(t,e){t.exports=function(t){if(Array.isArray(t)){for(var e=0,n=new Array(t.length);e=this.viewport().bottom?this.scrollTo(this.viewport().top+this.pointerHeight()):void 0},pixelsToPointerTop:function(){var t=0;if(this.$refs.dropdownMenu&&this.dropdownOpen)for(var e=0;e=0;t--)if(this.selectable(this.filteredOptions[t])){this.typeAheadPointer=t,this.maybeAdjustScroll&&this.maybeAdjustScroll();break}},typeAheadDown:function(){for(var t=this.typeAheadPointer+1;t0&&void 0!==arguments[0]?arguments[0]:null;return this.mutableLoading=null==t?!this.mutableLoading:t}}};function h(t,e,n,o,i,s,r,a){var l,c="function"==typeof t?t.options:t;if(e&&(c.render=e,c.staticRenderFns=n,c._compiled=!0),o&&(c.functional=!0),s&&(c._scopeId="data-v-"+s),r?(l=function(t){(t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),i&&i.call(this,t),t&&t._registeredComponents&&t._registeredComponents.add(r)},c._ssrRegister=l):i&&(l=a?function(){i.call(this,this.$root.$options.shadowRoot)}:i),l)if(c.functional){c._injectStyles=l;var u=c.render;c.render=function(t,e){return l.call(e),u(t,e)}}else{var p=c.beforeCreate;c.beforeCreate=p?[].concat(p,l):[l]}return{exports:t,options:c}}var d={Deselect:h({},(function(){var t=this.$createElement,e=this._self._c||t;return e("svg",{attrs:{xmlns:"http://www.w3.org/2000/svg",width:"10",height:"10"}},[e("path",{attrs:{d:"M6.895455 5l2.842897-2.842898c.348864-.348863.348864-.914488 0-1.263636L9.106534.261648c-.348864-.348864-.914489-.348864-1.263636 0L5 3.104545 2.157102.261648c-.348863-.348864-.914488-.348864-1.263636 0L.261648.893466c-.348864.348864-.348864.914489 0 1.263636L3.104545 5 .261648 7.842898c-.348864.348863-.348864.914488 0 1.263636l.631818.631818c.348864.348864.914773.348864 1.263636 0L5 6.895455l2.842898 2.842897c.348863.348864.914772.348864 1.263636 0l.631818-.631818c.348864-.348864.348864-.914489 0-1.263636L6.895455 5z"}})])}),[],!1,null,null,null).exports,OpenIndicator:h({},(function(){var t=this.$createElement,e=this._self._c||t;return e("svg",{attrs:{xmlns:"http://www.w3.org/2000/svg",width:"14",height:"10"}},[e("path",{attrs:{d:"M9.211364 7.59931l4.48338-4.867229c.407008-.441854.407008-1.158247 0-1.60046l-.73712-.80023c-.407008-.441854-1.066904-.441854-1.474243 0L7 5.198617 2.51662.33139c-.407008-.441853-1.066904-.441853-1.474243 0l-.737121.80023c-.407008.441854-.407008 1.158248 0 1.600461l4.48338 4.867228L7 10l2.211364-2.40069z"}})])}),[],!1,null,null,null).exports},f={inserted:function(t,e,n){var o=n.context;if(o.appendToBody){var i=o.$refs.toggle.getBoundingClientRect(),s=i.height,r=i.top,a=i.left,l=i.width;t.unbindPosition=o.calculatePosition(t,o,{width:l+"px",top:window.scrollY+r+s+"px",left:window.scrollX+a+"px"}),document.body.appendChild(t)}},unbind:function(t,e,n){n.context.appendToBody&&(t.unbindPosition&&"function"==typeof t.unbindPosition&&t.unbindPosition(),t.parentNode&&t.parentNode.removeChild(t))}};var y=function(t){var e={};return Object.keys(t).sort().forEach((function(n){e[n]=t[n]})),JSON.stringify(e)},b=0;var g=function(){return++b};function v(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);e&&(o=o.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,o)}return n}function m(t){for(var e=1;e-1}},filter:{type:Function,default:function(t,e){var n=this;return t.filter((function(t){var o=n.getOptionLabel(t);return"number"==typeof o&&(o=o.toString()),n.filterBy(t,o,e)}))}},createOption:{type:Function,default:function(t){return"object"===r()(this.optionList[0])?l()({},this.label,t):t}},resetOnOptionsChange:{default:!1,validator:function(t){return["function","boolean"].includes(r()(t))}},clearSearchOnBlur:{type:Function,default:function(t){var e=t.clearSearchOnSelect,n=t.multiple;return e&&!n}},noDrop:{type:Boolean,default:!1},inputId:{type:String},dir:{type:String,default:"auto"},selectOnTab:{type:Boolean,default:!1},selectOnKeyCodes:{type:Array,default:function(){return[13]}},searchInputQuerySelector:{type:String,default:"[type=search]"},mapKeydown:{type:Function,default:function(t,e){return t}},appendToBody:{type:Boolean,default:!1},calculatePosition:{type:Function,default:function(t,e,n){var o=n.width,i=n.top,s=n.left;t.style.top=i,t.style.left=s,t.style.width=o}}},data:function(){return{uid:g(),search:"",open:!1,isComposing:!1,pushedTags:[],_value:[]}},watch:{options:function(t,e){var n=this;!this.taggable&&("function"==typeof n.resetOnOptionsChange?n.resetOnOptionsChange(t,e,n.selectedValue):n.resetOnOptionsChange)&&this.clearSelection(),this.value&&this.isTrackingValues&&this.setInternalValueFromOptions(this.value)},value:function(t){this.isTrackingValues&&this.setInternalValueFromOptions(t)},multiple:function(){this.clearSelection()},open:function(t){this.$emit(t?"open":"close")}},created:function(){this.mutableLoading=this.loading,void 0!==this.value&&this.isTrackingValues&&this.setInternalValueFromOptions(this.value),this.$on("option:created",this.pushTag)},methods:{setInternalValueFromOptions:function(t){var e=this;Array.isArray(t)?this.$data._value=t.map((function(t){return e.findOptionFromReducedValue(t)})):this.$data._value=this.findOptionFromReducedValue(t)},select:function(t){this.isOptionSelected(t)||(this.taggable&&!this.optionExists(t)&&this.$emit("option:created",t),this.multiple&&(t=this.selectedValue.concat(t)),this.updateValue(t)),this.onAfterSelect(t)},deselect:function(t){var e=this;this.updateValue(this.selectedValue.filter((function(n){return!e.optionComparator(n,t)})))},clearSelection:function(){this.updateValue(this.multiple?[]:null)},onAfterSelect:function(t){this.closeOnSelect&&(this.open=!this.open,this.searchEl.blur()),this.clearSearchOnSelect&&(this.search="")},updateValue:function(t){var e=this;this.isTrackingValues&&(this.$data._value=t),null!==t&&(t=Array.isArray(t)?t.map((function(t){return e.reduce(t)})):this.reduce(t)),this.$emit("input",t)},toggleDropdown:function(t){var e=t.target;[].concat(i()(this.$refs.deselectButtons||[]),i()([this.$refs.clearButton]||!1)).some((function(t){return t.contains(e)||t===e}))||(this.open?this.searchEl.blur():this.disabled||(this.open=!0,this.searchEl.focus()))},isOptionSelected:function(t){var e=this;return this.selectedValue.some((function(n){return e.optionComparator(n,t)}))},optionComparator:function(t,e){return this.getOptionKey(t)===this.getOptionKey(e)},findOptionFromReducedValue:function(t){var e=this,n=[].concat(i()(this.options),i()(this.pushedTags)).filter((function(n){return JSON.stringify(e.reduce(n))===JSON.stringify(t)}));return 1===n.length?n[0]:n.find((function(t){return e.optionComparator(t,e.$data._value)}))||t},closeSearchOptions:function(){this.open=!1,this.$emit("search:blur")},maybeDeleteValue:function(){if(!this.searchEl.value.length&&this.selectedValue&&this.selectedValue.length&&this.clearable){var t=null;this.multiple&&(t=i()(this.selectedValue.slice(0,this.selectedValue.length-1))),this.updateValue(t)}},optionExists:function(t){var e=this;return this.optionList.some((function(n){return e.optionComparator(n,t)}))},normalizeOptionForSlot:function(t){return"object"===r()(t)?t:l()({},this.label,t)},pushTag:function(t){this.pushedTags.push(t)},onEscape:function(){this.search.length?this.search="":this.searchEl.blur()},onSearchBlur:function(){if(!this.mousedown||this.searching){var t=this.clearSearchOnSelect,e=this.multiple;return this.clearSearchOnBlur({clearSearchOnSelect:t,multiple:e})&&(this.search=""),void this.closeSearchOptions()}this.mousedown=!1,0!==this.search.length||0!==this.options.length||this.closeSearchOptions()},onSearchFocus:function(){this.open=!0,this.$emit("search:focus")},onMousedown:function(){this.mousedown=!0},onMouseUp:function(){this.mousedown=!1},onSearchKeyDown:function(t){var e=this,n=function(t){return t.preventDefault(),!e.isComposing&&e.typeAheadSelect()},o={8:function(t){return e.maybeDeleteValue()},9:function(t){return e.onTab()},27:function(t){return e.onEscape()},38:function(t){return t.preventDefault(),e.typeAheadUp()},40:function(t){return t.preventDefault(),e.typeAheadDown()}};this.selectOnKeyCodes.forEach((function(t){return o[t]=n}));var i=this.mapKeydown(o,this);if("function"==typeof i[t.keyCode])return i[t.keyCode](t)}},computed:{isTrackingValues:function(){return void 0===this.value||this.$options.propsData.hasOwnProperty("reduce")},selectedValue:function(){var t=this.value;return this.isTrackingValues&&(t=this.$data._value),t?[].concat(t):[]},optionList:function(){return this.options.concat(this.pushTags?this.pushedTags:[])},searchEl:function(){return this.$scopedSlots.search?this.$refs.selectedOptions.querySelector(this.searchInputQuerySelector):this.$refs.search},scope:function(){var t=this,e={search:this.search,loading:this.loading,searching:this.searching,filteredOptions:this.filteredOptions};return{search:{attributes:m({disabled:this.disabled,placeholder:this.searchPlaceholder,tabindex:this.tabindex,readonly:!this.searchable,id:this.inputId,"aria-autocomplete":"list","aria-labelledby":"vs".concat(this.uid,"__combobox"),"aria-controls":"vs".concat(this.uid,"__listbox"),ref:"search",type:"search",autocomplete:this.autocomplete,value:this.search},this.dropdownOpen&&this.filteredOptions[this.typeAheadPointer]?{"aria-activedescendant":"vs".concat(this.uid,"__option-").concat(this.typeAheadPointer)}:{}),events:{compositionstart:function(){return t.isComposing=!0},compositionend:function(){return t.isComposing=!1},keydown:this.onSearchKeyDown,blur:this.onSearchBlur,focus:this.onSearchFocus,input:function(e){return t.search=e.target.value}}},spinner:{loading:this.mutableLoading},noOptions:{search:this.search,loading:this.loading,searching:this.searching},openIndicator:{attributes:{ref:"openIndicator",role:"presentation",class:"vs__open-indicator"}},listHeader:e,listFooter:e,header:m({},e,{deselect:this.deselect}),footer:m({},e,{deselect:this.deselect})}},childComponents:function(){return m({},d,{},this.components)},stateClasses:function(){return{"vs--open":this.dropdownOpen,"vs--single":!this.multiple,"vs--searching":this.searching&&!this.noDrop,"vs--searchable":this.searchable&&!this.noDrop,"vs--unsearchable":!this.searchable,"vs--loading":this.mutableLoading,"vs--disabled":this.disabled}},searching:function(){return!!this.search},dropdownOpen:function(){return!this.noDrop&&(this.open&&!this.mutableLoading)},searchPlaceholder:function(){if(this.isValueEmpty&&this.placeholder)return this.placeholder},filteredOptions:function(){var t=[].concat(this.optionList);if(!this.filterable&&!this.taggable)return t;var e=this.search.length?this.filter(t,this.search,this):t;return this.taggable&&this.search.length&&!this.optionExists(this.createOption(this.search))&&e.unshift(this.search),e},isValueEmpty:function(){return 0===this.selectedValue.length},showClearButton:function(){return!this.multiple&&this.clearable&&!this.open&&!this.isValueEmpty}}},O=(n(7),h(_,(function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"v-select",class:t.stateClasses,attrs:{dir:t.dir}},[t._t("header",null,null,t.scope.header),t._v(" "),n("div",{ref:"toggle",staticClass:"vs__dropdown-toggle",attrs:{id:"vs"+t.uid+"__combobox",role:"combobox","aria-expanded":t.dropdownOpen.toString(),"aria-owns":"vs"+t.uid+"__listbox","aria-label":"Search for option"},on:{mousedown:function(e){return e.preventDefault(),t.toggleDropdown(e)}}},[n("div",{ref:"selectedOptions",staticClass:"vs__selected-options"},[t._l(t.selectedValue,(function(e){return t._t("selected-option-container",[n("span",{key:t.getOptionKey(e),staticClass:"vs__selected"},[t._t("selected-option",[t._v("\n "+t._s(t.getOptionLabel(e))+"\n ")],null,t.normalizeOptionForSlot(e)),t._v(" "),t.multiple?n("button",{ref:"deselectButtons",refInFor:!0,staticClass:"vs__deselect",attrs:{disabled:t.disabled,type:"button",title:"Deselect "+t.getOptionLabel(e),"aria-label":"Deselect "+t.getOptionLabel(e)},on:{click:function(n){return t.deselect(e)}}},[n(t.childComponents.Deselect,{tag:"component"})],1):t._e()],2)],{option:t.normalizeOptionForSlot(e),deselect:t.deselect,multiple:t.multiple,disabled:t.disabled})})),t._v(" "),t._t("search",[n("input",t._g(t._b({staticClass:"vs__search"},"input",t.scope.search.attributes,!1),t.scope.search.events))],null,t.scope.search)],2),t._v(" "),n("div",{ref:"actions",staticClass:"vs__actions"},[n("button",{directives:[{name:"show",rawName:"v-show",value:t.showClearButton,expression:"showClearButton"}],ref:"clearButton",staticClass:"vs__clear",attrs:{disabled:t.disabled,type:"button",title:"Clear Selected","aria-label":"Clear Selected"},on:{click:t.clearSelection}},[n(t.childComponents.Deselect,{tag:"component"})],1),t._v(" "),t._t("open-indicator",[t.noDrop?t._e():n(t.childComponents.OpenIndicator,t._b({tag:"component"},"component",t.scope.openIndicator.attributes,!1))],null,t.scope.openIndicator),t._v(" "),t._t("spinner",[n("div",{directives:[{name:"show",rawName:"v-show",value:t.mutableLoading,expression:"mutableLoading"}],staticClass:"vs__spinner"},[t._v("Loading...")])],null,t.scope.spinner)],2)]),t._v(" "),n("transition",{attrs:{name:t.transition}},[t.dropdownOpen?n("ul",{directives:[{name:"append-to-body",rawName:"v-append-to-body"}],ref:"dropdownMenu",staticClass:"vs__dropdown-menu",attrs:{id:"vs"+t.uid+"__listbox",role:"listbox"},on:{mousedown:function(e){return e.preventDefault(),t.onMousedown(e)},mouseup:t.onMouseUp}},[t._t("list-header",null,null,t.scope.listHeader),t._v(" "),t._l(t.filteredOptions,(function(e,o){return n("li",{key:t.getOptionKey(e),staticClass:"vs__dropdown-option",class:{"vs__dropdown-option--selected":t.isOptionSelected(e),"vs__dropdown-option--highlight":o===t.typeAheadPointer,"vs__dropdown-option--disabled":!t.selectable(e)},attrs:{role:"option",id:"vs"+t.uid+"__option-"+o,"aria-selected":o===t.typeAheadPointer||null},on:{mouseover:function(n){t.selectable(e)&&(t.typeAheadPointer=o)},mousedown:function(n){n.preventDefault(),n.stopPropagation(),t.selectable(e)&&t.select(e)}}},[t._t("option",[t._v("\n "+t._s(t.getOptionLabel(e))+"\n ")],null,t.normalizeOptionForSlot(e))],2)})),t._v(" "),0===t.filteredOptions.length?n("li",{staticClass:"vs__no-options"},[t._t("no-options",[t._v("Sorry, no matching options.")],null,t.scope.noOptions)],2):t._e(),t._v(" "),t._t("list-footer",null,null,t.scope.listFooter)],2):n("ul",{staticStyle:{display:"none",visibility:"hidden"},attrs:{id:"vs"+t.uid+"__listbox",role:"listbox"}})]),t._v(" "),t._t("footer",null,null,t.scope.footer)],2)}),[],!1,null,null,null).exports),w={ajax:p,pointer:u,pointerScroll:c};n.d(e,"VueSelect",(function(){return O})),n.d(e,"mixins",(function(){return w}));e.default=O}])})); +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.VueSelect=e():t.VueSelect=e()}("undefined"!=typeof self?self:this,(function(){return(()=>{var t={646:t=>{t.exports=function(t){if(Array.isArray(t)){for(var e=0,n=new Array(t.length);e{t.exports=function(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}},860:t=>{t.exports=function(t){if(Symbol.iterator in Object(t)||"[object Arguments]"===Object.prototype.toString.call(t))return Array.from(t)}},206:t=>{t.exports=function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}},319:(t,e,n)=>{var o=n(646),i=n(860),s=n(206);t.exports=function(t){return o(t)||i(t)||s()}},8:t=>{function e(n){return"function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?t.exports=e=function(t){return typeof t}:t.exports=e=function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},e(n)}t.exports=e}},e={};function n(o){var i=e[o];if(void 0!==i)return i.exports;var s=e[o]={exports:{}};return t[o](s,s.exports,n),s.exports}n.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var o in e)n.o(e,o)&&!n.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:e[o]})},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),n.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var o={};return(()=>{"use strict";n.r(o),n.d(o,{VueSelect:()=>m,default:()=>O,mixins:()=>_});var t=n(319),e=n.n(t),i=n(8),s=n.n(i),r=n(713),a=n.n(r);const l={props:{autoscroll:{type:Boolean,default:!0}},watch:{typeAheadPointer:function(){this.autoscroll&&this.maybeAdjustScroll()},open:function(t){var e=this;this.autoscroll&&t&&this.$nextTick((function(){return e.maybeAdjustScroll()}))}},methods:{maybeAdjustScroll:function(){var t,e=(null===(t=this.$refs.dropdownMenu)||void 0===t?void 0:t.children[this.typeAheadPointer])||!1;if(e){var n=this.getDropdownViewport(),o=e.getBoundingClientRect(),i=o.top,s=o.bottom,r=o.height;if(in.bottom)return this.$refs.dropdownMenu.scrollTop=e.offsetTop-(n.height-r)}},getDropdownViewport:function(){return this.$refs.dropdownMenu?this.$refs.dropdownMenu.getBoundingClientRect():{height:0,top:0,bottom:0}}}},c={data:function(){return{typeAheadPointer:-1}},watch:{filteredOptions:function(){for(var t=0;t=0;t--)if(this.selectable(this.filteredOptions[t])){this.typeAheadPointer=t;break}},typeAheadDown:function(){for(var t=this.typeAheadPointer+1;t0&&void 0!==arguments[0]?arguments[0]:null;return this.mutableLoading=null==t?!this.mutableLoading:t}}};function p(t,e,n,o,i,s,r,a){var l,c="function"==typeof t?t.options:t;if(e&&(c.render=e,c.staticRenderFns=n,c._compiled=!0),o&&(c.functional=!0),s&&(c._scopeId="data-v-"+s),r?(l=function(t){(t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),i&&i.call(this,t),t&&t._registeredComponents&&t._registeredComponents.add(r)},c._ssrRegister=l):i&&(l=a?function(){i.call(this,(c.functional?this.parent:this).$root.$options.shadowRoot)}:i),l)if(c.functional){c._injectStyles=l;var u=c.render;c.render=function(t,e){return l.call(e),u(t,e)}}else{var p=c.beforeCreate;c.beforeCreate=p?[].concat(p,l):[l]}return{exports:t,options:c}}const h={Deselect:p({},(function(){var t=this.$createElement,e=this._self._c||t;return e("svg",{attrs:{xmlns:"http://www.w3.org/2000/svg",width:"10",height:"10"}},[e("path",{attrs:{d:"M6.895455 5l2.842897-2.842898c.348864-.348863.348864-.914488 0-1.263636L9.106534.261648c-.348864-.348864-.914489-.348864-1.263636 0L5 3.104545 2.157102.261648c-.348863-.348864-.914488-.348864-1.263636 0L.261648.893466c-.348864.348864-.348864.914489 0 1.263636L3.104545 5 .261648 7.842898c-.348864.348863-.348864.914488 0 1.263636l.631818.631818c.348864.348864.914773.348864 1.263636 0L5 6.895455l2.842898 2.842897c.348863.348864.914772.348864 1.263636 0l.631818-.631818c.348864-.348864.348864-.914489 0-1.263636L6.895455 5z"}})])}),[],!1,null,null,null).exports,OpenIndicator:p({},(function(){var t=this.$createElement,e=this._self._c||t;return e("svg",{attrs:{xmlns:"http://www.w3.org/2000/svg",width:"14",height:"10"}},[e("path",{attrs:{d:"M9.211364 7.59931l4.48338-4.867229c.407008-.441854.407008-1.158247 0-1.60046l-.73712-.80023c-.407008-.441854-1.066904-.441854-1.474243 0L7 5.198617 2.51662.33139c-.407008-.441853-1.066904-.441853-1.474243 0l-.737121.80023c-.407008.441854-.407008 1.158248 0 1.600461l4.48338 4.867228L7 10l2.211364-2.40069z"}})])}),[],!1,null,null,null).exports},d={inserted:function(t,e,n){var o=n.context;if(o.appendToBody){var i=o.$refs.toggle.getBoundingClientRect(),s=i.height,r=i.top,a=i.left,l=i.width,c=window.scrollX||window.pageXOffset,u=window.scrollY||window.pageYOffset;t.unbindPosition=o.calculatePosition(t,o,{width:l+"px",left:c+a+"px",top:u+r+s+"px"}),document.body.appendChild(t)}},unbind:function(t,e,n){n.context.appendToBody&&(t.unbindPosition&&"function"==typeof t.unbindPosition&&t.unbindPosition(),t.parentNode&&t.parentNode.removeChild(t))}};const f=function(t){var e={};return Object.keys(t).sort().forEach((function(n){e[n]=t[n]})),JSON.stringify(e)};var y=0;const b=function(){return++y};function g(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);e&&(o=o.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,o)}return n}function v(t){for(var e=1;e-1}},filter:{type:Function,default:function(t,e){var n=this;return t.filter((function(t){var o=n.getOptionLabel(t);return"number"==typeof o&&(o=o.toString()),n.filterBy(t,o,e)}))}},createOption:{type:Function,default:function(t){return"object"===s()(this.optionList[0])?a()({},this.label,t):t}},resetOnOptionsChange:{default:!1,validator:function(t){return["function","boolean"].includes(s()(t))}},clearSearchOnBlur:{type:Function,default:function(t){var e=t.clearSearchOnSelect,n=t.multiple;return e&&!n}},noDrop:{type:Boolean,default:!1},inputId:{type:String},dir:{type:String,default:"auto"},selectOnTab:{type:Boolean,default:!1},selectOnKeyCodes:{type:Array,default:function(){return[13]}},searchInputQuerySelector:{type:String,default:"[type=search]"},mapKeydown:{type:Function,default:function(t,e){return t}},appendToBody:{type:Boolean,default:!1},calculatePosition:{type:Function,default:function(t,e,n){var o=n.width,i=n.top,s=n.left;t.style.top=i,t.style.left=s,t.style.width=o}},dropdownShouldOpen:{type:Function,default:function(t){var e=t.noDrop,n=t.open,o=t.mutableLoading;return!e&&(n&&!o)}},uid:{type:[String,Number],default:function(){return b()}}},data:function(){return{search:"",open:!1,isComposing:!1,pushedTags:[],_value:[]}},computed:{isTrackingValues:function(){return void 0===this.value||this.$options.propsData.hasOwnProperty("reduce")},selectedValue:function(){var t=this.value;return this.isTrackingValues&&(t=this.$data._value),null!=t&&""!==t?[].concat(t):[]},optionList:function(){return this.options.concat(this.pushTags?this.pushedTags:[])},searchEl:function(){return this.$scopedSlots.search?this.$refs.selectedOptions.querySelector(this.searchInputQuerySelector):this.$refs.search},scope:function(){var t=this,e={search:this.search,loading:this.loading,searching:this.searching,filteredOptions:this.filteredOptions};return{search:{attributes:v({disabled:this.disabled,placeholder:this.searchPlaceholder,tabindex:this.tabindex,readonly:!this.searchable,id:this.inputId,"aria-autocomplete":"list","aria-labelledby":"vs".concat(this.uid,"__combobox"),"aria-controls":"vs".concat(this.uid,"__listbox"),ref:"search",type:"search",autocomplete:this.autocomplete,value:this.search},this.dropdownOpen&&this.filteredOptions[this.typeAheadPointer]?{"aria-activedescendant":"vs".concat(this.uid,"__option-").concat(this.typeAheadPointer)}:{}),events:{compositionstart:function(){return t.isComposing=!0},compositionend:function(){return t.isComposing=!1},keydown:this.onSearchKeyDown,blur:this.onSearchBlur,focus:this.onSearchFocus,input:function(e){return t.search=e.target.value}}},spinner:{loading:this.mutableLoading},noOptions:{search:this.search,loading:this.mutableLoading,searching:this.searching},openIndicator:{attributes:{ref:"openIndicator",role:"presentation",class:"vs__open-indicator"}},listHeader:e,listFooter:e,header:v({},e,{deselect:this.deselect}),footer:v({},e,{deselect:this.deselect})}},childComponents:function(){return v({},h,{},this.components)},stateClasses:function(){return{"vs--open":this.dropdownOpen,"vs--single":!this.multiple,"vs--multiple":this.multiple,"vs--searching":this.searching&&!this.noDrop,"vs--searchable":this.searchable&&!this.noDrop,"vs--unsearchable":!this.searchable,"vs--loading":this.mutableLoading,"vs--disabled":this.disabled}},searching:function(){return!!this.search},dropdownOpen:function(){return this.dropdownShouldOpen(this)},searchPlaceholder:function(){return this.isValueEmpty&&this.placeholder?this.placeholder:void 0},filteredOptions:function(){var t=[].concat(this.optionList);if(!this.filterable&&!this.taggable)return t;var e=this.search.length?this.filter(t,this.search,this):t;if(this.taggable&&this.search.length){var n=this.createOption(this.search);this.optionExists(n)||e.unshift(n)}return e},isValueEmpty:function(){return 0===this.selectedValue.length},showClearButton:function(){return!this.multiple&&this.clearable&&!this.open&&!this.isValueEmpty}},watch:{options:function(t,e){var n=this;!this.taggable&&("function"==typeof n.resetOnOptionsChange?n.resetOnOptionsChange(t,e,n.selectedValue):n.resetOnOptionsChange)&&this.clearSelection(),this.value&&this.isTrackingValues&&this.setInternalValueFromOptions(this.value)},value:{immediate:!0,handler:function(t){this.isTrackingValues&&this.setInternalValueFromOptions(t)}},multiple:function(){this.clearSelection()},open:function(t){this.$emit(t?"open":"close")}},created:function(){this.mutableLoading=this.loading,this.$on("option:created",this.pushTag)},methods:{setInternalValueFromOptions:function(t){var e=this;Array.isArray(t)?this.$data._value=t.map((function(t){return e.findOptionFromReducedValue(t)})):this.$data._value=this.findOptionFromReducedValue(t)},select:function(t){this.$emit("option:selecting",t),this.isOptionSelected(t)?this.deselectFromDropdown&&(this.clearable||this.multiple&&this.selectedValue.length>1)&&this.deselect(t):(this.taggable&&!this.optionExists(t)&&this.$emit("option:created",t),this.multiple&&(t=this.selectedValue.concat(t)),this.updateValue(t),this.$emit("option:selected",t)),this.onAfterSelect(t)},deselect:function(t){var e=this;this.$emit("option:deselecting",t),this.updateValue(this.selectedValue.filter((function(n){return!e.optionComparator(n,t)}))),this.$emit("option:deselected",t)},clearSelection:function(){this.updateValue(this.multiple?[]:null)},onAfterSelect:function(t){var e=this;this.closeOnSelect&&(this.open=!this.open,this.searchEl.blur()),this.clearSearchOnSelect&&(this.search=""),this.noDrop&&this.multiple&&this.$nextTick((function(){return e.$refs.search.focus()}))},updateValue:function(t){var e=this;void 0===this.value&&(this.$data._value=t),null!==t&&(t=Array.isArray(t)?t.map((function(t){return e.reduce(t)})):this.reduce(t)),this.$emit("input",t)},toggleDropdown:function(t){var n=t.target!==this.searchEl;n&&t.preventDefault();var o=[].concat(e()(this.$refs.deselectButtons||[]),e()([this.$refs.clearButton]||0));void 0===this.searchEl||o.filter(Boolean).some((function(e){return e.contains(t.target)||e===t.target}))?t.preventDefault():this.open&&n?this.searchEl.blur():this.disabled||(this.open=!0,this.searchEl.focus())},isOptionSelected:function(t){var e=this;return this.selectedValue.some((function(n){return e.optionComparator(n,t)}))},isOptionDeselectable:function(t){return this.isOptionSelected(t)&&this.deselectFromDropdown},optionComparator:function(t,e){return this.getOptionKey(t)===this.getOptionKey(e)},findOptionFromReducedValue:function(t){var n=this,o=[].concat(e()(this.options),e()(this.pushedTags)).filter((function(e){return JSON.stringify(n.reduce(e))===JSON.stringify(t)}));return 1===o.length?o[0]:o.find((function(t){return n.optionComparator(t,n.$data._value)}))||t},closeSearchOptions:function(){this.open=!1,this.$emit("search:blur")},maybeDeleteValue:function(){if(!this.searchEl.value.length&&this.selectedValue&&this.selectedValue.length&&this.clearable){var t=null;this.multiple&&(t=e()(this.selectedValue.slice(0,this.selectedValue.length-1))),this.updateValue(t)}},optionExists:function(t){var e=this;return this.optionList.some((function(n){return e.optionComparator(n,t)}))},normalizeOptionForSlot:function(t){return"object"===s()(t)?t:a()({},this.label,t)},pushTag:function(t){this.pushedTags.push(t)},onEscape:function(){this.search.length?this.search="":this.searchEl.blur()},onSearchBlur:function(){if(!this.mousedown||this.searching){var t=this.clearSearchOnSelect,e=this.multiple;return this.clearSearchOnBlur({clearSearchOnSelect:t,multiple:e})&&(this.search=""),void this.closeSearchOptions()}this.mousedown=!1,0!==this.search.length||0!==this.options.length||this.closeSearchOptions()},onSearchFocus:function(){this.open=!0,this.$emit("search:focus")},onMousedown:function(){this.mousedown=!0},onMouseUp:function(){this.mousedown=!1},onSearchKeyDown:function(t){var e=this,n=function(t){return t.preventDefault(),!e.isComposing&&e.typeAheadSelect()},o={8:function(t){return e.maybeDeleteValue()},9:function(t){return e.onTab()},27:function(t){return e.onEscape()},38:function(t){return t.preventDefault(),e.typeAheadUp()},40:function(t){return t.preventDefault(),e.typeAheadDown()}};this.selectOnKeyCodes.forEach((function(t){return o[t]=n}));var i=this.mapKeydown(o,this);if("function"==typeof i[t.keyCode])return i[t.keyCode](t)}}},(function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"v-select",class:t.stateClasses,attrs:{dir:t.dir}},[t._t("header",null,null,t.scope.header),t._v(" "),n("div",{ref:"toggle",staticClass:"vs__dropdown-toggle",attrs:{id:"vs"+t.uid+"__combobox",role:"combobox","aria-expanded":t.dropdownOpen.toString(),"aria-owns":"vs"+t.uid+"__listbox","aria-label":"Search for option"},on:{mousedown:function(e){return t.toggleDropdown(e)}}},[n("div",{ref:"selectedOptions",staticClass:"vs__selected-options"},[t._l(t.selectedValue,(function(e){return t._t("selected-option-container",[n("span",{key:t.getOptionKey(e),staticClass:"vs__selected"},[t._t("selected-option",[t._v("\n "+t._s(t.getOptionLabel(e))+"\n ")],null,t.normalizeOptionForSlot(e)),t._v(" "),t.multiple?n("button",{ref:"deselectButtons",refInFor:!0,staticClass:"vs__deselect",attrs:{disabled:t.disabled,type:"button",title:"Deselect "+t.getOptionLabel(e),"aria-label":"Deselect "+t.getOptionLabel(e)},on:{click:function(n){return t.deselect(e)}}},[n(t.childComponents.Deselect,{tag:"component"})],1):t._e()],2)],{option:t.normalizeOptionForSlot(e),deselect:t.deselect,multiple:t.multiple,disabled:t.disabled})})),t._v(" "),t._t("search",[n("input",t._g(t._b({staticClass:"vs__search"},"input",t.scope.search.attributes,!1),t.scope.search.events))],null,t.scope.search)],2),t._v(" "),n("div",{ref:"actions",staticClass:"vs__actions"},[n("button",{directives:[{name:"show",rawName:"v-show",value:t.showClearButton,expression:"showClearButton"}],ref:"clearButton",staticClass:"vs__clear",attrs:{disabled:t.disabled,type:"button",title:"Clear Selected","aria-label":"Clear Selected"},on:{click:t.clearSelection}},[n(t.childComponents.Deselect,{tag:"component"})],1),t._v(" "),t._t("open-indicator",[t.noDrop?t._e():n(t.childComponents.OpenIndicator,t._b({tag:"component"},"component",t.scope.openIndicator.attributes,!1))],null,t.scope.openIndicator),t._v(" "),t._t("spinner",[n("div",{directives:[{name:"show",rawName:"v-show",value:t.mutableLoading,expression:"mutableLoading"}],staticClass:"vs__spinner"},[t._v("Loading...")])],null,t.scope.spinner)],2)]),t._v(" "),n("transition",{attrs:{name:t.transition}},[t.dropdownOpen?n("ul",{directives:[{name:"append-to-body",rawName:"v-append-to-body"}],key:"vs"+t.uid+"__listbox",ref:"dropdownMenu",staticClass:"vs__dropdown-menu",attrs:{id:"vs"+t.uid+"__listbox",role:"listbox",tabindex:"-1"},on:{mousedown:function(e){return e.preventDefault(),t.onMousedown(e)},mouseup:t.onMouseUp}},[t._t("list-header",null,null,t.scope.listHeader),t._v(" "),t._l(t.filteredOptions,(function(e,o){return n("li",{key:t.getOptionKey(e),staticClass:"vs__dropdown-option",class:{"vs__dropdown-option--deselect":t.isOptionDeselectable(e)&&o===t.typeAheadPointer,"vs__dropdown-option--selected":t.isOptionSelected(e),"vs__dropdown-option--highlight":o===t.typeAheadPointer,"vs__dropdown-option--disabled":!t.selectable(e)},attrs:{id:"vs"+t.uid+"__option-"+o,role:"option","aria-selected":o===t.typeAheadPointer||null},on:{mouseover:function(n){t.selectable(e)&&(t.typeAheadPointer=o)},click:function(n){n.preventDefault(),n.stopPropagation(),t.selectable(e)&&t.select(e)}}},[t._t("option",[t._v("\n "+t._s(t.getOptionLabel(e))+"\n ")],null,t.normalizeOptionForSlot(e))],2)})),t._v(" "),0===t.filteredOptions.length?n("li",{staticClass:"vs__no-options"},[t._t("no-options",[t._v("\n Sorry, no matching options.\n ")],null,t.scope.noOptions)],2):t._e(),t._v(" "),t._t("list-footer",null,null,t.scope.listFooter)],2):n("ul",{staticStyle:{display:"none",visibility:"hidden"},attrs:{id:"vs"+t.uid+"__listbox",role:"listbox"}})]),t._v(" "),t._t("footer",null,null,t.scope.footer)],2)}),[],!1,null,null,null).exports,_={ajax:u,pointer:c,pointerScroll:l},O=m})(),o})()})); diff --git a/view/adminhtml/web/template/form/element/depth-input.html b/view/adminhtml/web/template/form/element/depth-input.html new file mode 100644 index 00000000..c0e565dd --- /dev/null +++ b/view/adminhtml/web/template/form/element/depth-input.html @@ -0,0 +1,17 @@ + diff --git a/view/adminhtml/web/vue/app.vue b/view/adminhtml/web/vue/app.vue index 3e5494de..0efeaa4c 100644 --- a/view/adminhtml/web/vue/app.vue +++ b/view/adminhtml/web/vue/app.vue @@ -9,7 +9,7 @@