graschik / magento-2-admin-ui

This magento 2 module allows you to use UI components as input for widget and also use new UI components.
MIT License
38 stars 4 forks source link

Any chance of a complete usage example? #1

Open xtremevision opened 1 year ago

xtremevision commented 1 year ago

I am interested in adding a product selector to the admin product edit page, in a custom tab. How would that be possible? Thanks, Michael.

xtremevision commented 1 year ago

I've added a custom tab to the product form page as shown below:

image

Ideally I would like to add a button called "Add Superseding Products" much like the "Add Related Products" button in the Related Products section.

Added the custom tab module to make life easier. CustomTab.zip

graschik commented 1 year ago

Hello, Michael.

<?php
declare(strict_types=1);

namespace YourNamespace\YourNamespace\Ui\DataProvider\Product\Form\Modifier;

use Grasch\AdminUi\Component\EntitiesSelector;
use Grasch\AdminUi\Component\EntitiesSelectorFactory;
use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier;

class AddEntitiesSelector extends AbstractModifier
{
    /**
     * @var EntitiesSelectorFactory
     */
    private EntitiesSelectorFactory $entitiesSelectorFactory;

    /**
     * @var array
     */
    private array $data;

    /**
     * @param EntitiesSelectorFactory $entitiesSelectorFactory
     * @param array $data
     */
    public function __construct(
        EntitiesSelectorFactory $entitiesSelectorFactory,
        array $data
    ) {
        $this->entitiesSelectorFactory = $entitiesSelectorFactory;
        $this->data = $data;
    }

    /**
     * @param array $data
     * @return array
     */
    public function modifyData(array $data): array
    {
        return $data;
    }

    /**
     * @param array $meta
     * @return array
     */
    public function modifyMeta(array $meta): array
    {
        $meta['superseded_by'] = [
            'arguments' => [
                'data' => [
                    'config' => [
                        'componentType' => 'fieldset',
                        'label' => __('Superseded By'),
                        'collapsible' => true,
                        'sortOrder' => 5,
                        'opened' => true,
                        'canShow' => true,
                        'dataScope' => 'data.product',
                    ]
                ]
            ]
        ];

        $name = 'superseding_products';
        /** @var EntitiesSelector $entitiesSelector */
        $entitiesSelector = $this->entitiesSelectorFactory->create(['data' => $this->data]);
        $entitiesSelector->setData('name', $name);

        $meta['superseded_by']['children'][$name] = [
            'arguments' => [
                'data' => [
                    'config' => [
                        'componentName' => $name,
                        'componentType' => 'container'
                    ]
                ]
            ],
            'children' => $entitiesSelector->getChildComponentsAsArrayForMeta()
        ];

        return $meta;
    }
}
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <virtualType name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool">
        <arguments>
            <argument name="modifiers" xsi:type="array">
                <item name="addEntitiesSelector" xsi:type="array">
                    <item name="class" xsi:type="string">addEntitiesSelector</item>
                    <item name="sortOrder" xsi:type="number">100</item>
                </item>
            </argument>
        </arguments>
    </virtualType>

    <virtualType name="addEntitiesSelector" type="YourNamespace\YourNamespace\Ui\DataProvider\Product\Form\Modifier\AddEntitiesSelector">
        <arguments>
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="limit" xsi:type="array">
                        <item name="min" xsi:type="number">2</item>
                        <item name="max" xsi:type="number">4</item>
                    </item>
                    <item name="label" xsi:type="string">Add Superseding Products</item>
                    <item name="namespace" xsi:type="string">product_listing</item>
                    <item name="columnsName" xsi:type="string">product_columns</item>
                    <item name="selectionsColumnName" xsi:type="string">ids</item>
                    <item name="grid" xsi:type="array">
                        <item name="columns" xsi:type="array">
                            <item name="id" xsi:type="array">
                                <item name="original_name" xsi:type="string">entity_id</item>
                                <item name="type" xsi:type="string">text</item>
                                <item name="label" xsi:type="string">ID</item>
                                <item name="sortOrder" xsi:type="number">10</item>
                                <item name="fit" xsi:type="boolean">true</item>
                            </item>
                            <item name="sku" xsi:type="array">
                                <item name="original_name" xsi:type="string">sku</item>
                                <item name="type" xsi:type="string">text</item>
                                <item name="label" xsi:type="string">SKU</item>
                                <item name="sortOrder" xsi:type="number">15</item>
                                <item name="fit" xsi:type="boolean">false</item>
                            </item>
                            <item name="name" xsi:type="array">
                                <item name="original_name" xsi:type="string">name</item>
                                <item name="type" xsi:type="string">text</item>
                                <item name="label" xsi:type="string">Name</item>
                                <item name="sortOrder" xsi:type="number">20</item>
                                <item name="fit" xsi:type="boolean">false</item>
                            </item>
                            <item name="thumbnail" xsi:type="array">
                                <item name="original_name" xsi:type="string">thumbnail_src</item>
                                <item name="type" xsi:type="string">thumbnail</item>
                                <item name="label" xsi:type="string">Thumbnail</item>
                                <item name="sortOrder" xsi:type="number">16</item>
                                <item name="fit" xsi:type="boolean">true</item>
                            </item>
                        </item>
                    </item>
                </item>
            </argument>
        </arguments>
    </virtualType>
</config>
xtremevision commented 12 months ago

Hi Aliaksandr,

It worked, the product selector appeared and I can add items. However, even though I save the product, on reload they are lost. Either they are not saved anywhere, or there's something else wrong. How is data persistence handled?

Any ideas?

Thanks, Michael.

image

graschik commented 12 months ago

You need to write your own SaveHandler like for related products. vendor/magento/module-catalog/Model/Product/Link/SaveHandler.php. Automatic data saving is supported for UI Components Inside Widgets.

xtremevision commented 12 months ago

I see. What about displaying the grid inside the tab, once the items have been saved (on reload)? Does the module handle that automatically, or I have to add the grid myself?

graschik commented 12 months ago

Look here vendor/magento/module-catalog/Ui/DataProvider/Product/Form/Modifier/Related.php how the modifyData method works. You need to implement something like this.