Question

I am trying to create a custom drop down option in Action section in the sales order Grid.

The main gold is to bring custom Option(Assign to User) in Action Drop down.

Then once Assign to user is clicked it should list all available users in next drop down. so if any user is selected then the selected order should assign to that particular user.

I have used this code so far. but I am not getting my custom option in the Action drop down.

<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<listingToolbar name="listing_top"> 
    <massaction>
        <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="component" xsi:type="string">Magento_Ui/js/grid/tree-massactions</item>
        </item>
        </argument>   
        <action name="assigned_user_id" class="Vendor\Module\Ui\Component\Listing\MassActions\DynamicAction">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="type" xsi:type="string">assigned_user_id</item>
                    <item name="label" xsi:type="string" translate="true">Bulk Assign</item>
                    <item name="assigned_user_id" xsi:type="object">Vendor\Module\Ui\DataProvider\UserActions</item>
                </item>
            </argument>
        </action>    
    </massaction>
   </listingToolbar>
</listing>

Vendor\Module\Ui\Component\Listing\MassActions\DynamicAction.php

 <?php
 namespace Vendor\Module\Ui\Component\Listing\MassActions;
 class DynamicAction extends \Magento\Ui\Component\Action
{
   /**
    * @inheritDoc
   */
  public function prepare()
  {
     $config = $this->getData('config');
     if(isset($config['assigned_user_id'])) {
         $this->actions = $config['assigned_user_id']->getActions();
     }
      parent::prepare();
   }
 }

Vendor\Module\Ui\DataProvider\UserActions.php

<?php
namespace Vendor\Module\Ui\DataProvider;

use Magento\User\Model\ResourceModel\User\CollectionFactory;
use Magento\Framework\UrlInterface;

class UserActions
{
protected $collectionFactory;
protected $urlBuilder;

public function __construct(CollectionFactory $collectionFactory, 
UrlInterface $urlBuilder)
{
    $this->collectionFactory = $collectionFactory;
    $this->urlBuilder = $urlBuilder;
}
public function getActions()
{
    $actions = [];
    $users = $this->collectionFactory->create();
    foreach($users as $user) {
    $actions[] = [
        'type' => $user->getUserName(),
        'label' => $user->getName(),
        'url' => $this->urlBuilder->getUrl('*/*/assignUser', ['user_id' => 
    $user->getId()]),
    ];
    }
   return $actions;
   }
}

Please someone look into it and help me to resolve this issue.

Was it helpful?

Solution

Below code should work:

First of all your view/adminhtml/ui_component/sales_order_grid.xml:

<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <container name="listing_top">
        <massaction name="listing_massaction">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="selectProvider" xsi:type="string">sales_order_grid.sales_order_grid.sales_order_columns.ids</item>
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/tree-massactions</item>
                    <item name="indexField" xsi:type="string">entity_id</item>
                </item>
            </argument>
            <action name="bulk_assign_to_user">
                <settings>
                    <type>assign_to_users</type>
                    <label translate="true">Bulk Assign to User</label>
                    <actions class="Vendor\Module\Ui\DataProvider\UserActions"/>
                </settings>
            </action>
        </massaction>
    </container>
</listing>

and now add this in etc/adminhtml/di.xml:

<type name="Vendor\Module\Ui\DataProvider\UserActions">
    <arguments>
        <argument name="data" xsi:type="array">
            <item name="urlPath" xsi:type="string">url/assignUsers</item>
            <item name="paramName" xsi:type="string">user_id</item>
            <item name="confirm" xsi:type="array">
                <item name="title" xsi:type="string" translatable="true">Bulk Assign to User</item>
                <item name="message" xsi:type="string" translatable="true">Are you sure to assign selected orders to users?</item>
            </item>
        </argument>
    </arguments>
</type>

Change urlPath to your own action path above.

And finally your class:

<?php

namespace Vendor\Module\Ui\DataProvider;

use Magento\Framework\UrlInterface;
use Magento\User\Model\ResourceModel\User\CollectionFactory;

class UserActions implements \JsonSerializable
{
    /**
     * @var array
     */
    protected $options;

    /**
     * @var CollectionFactory
     */
    protected $collectionFactory;

    /**
     * Additional options params
     *
     * @var array
     */
    protected $data;

    /**
     * @var UrlInterface
     */
    protected $urlBuilder;

    /**
     * Base URL for subactions
     *
     * @var string
     */
    protected $urlPath;

    /**
     * Param name for subactions
     *
     * @var string
     */
    protected $paramName;

    /**
     * Additional params for subactions
     *
     * @var array
     */
    protected $additionalData = [];

    /**
     * Constructor
     *
     * @param CollectionFactory $collectionFactory
     * @param UrlInterface $urlBuilder
     * @param array $data
     */
    public function __construct(
        CollectionFactory $collectionFactory,
        UrlInterface $urlBuilder,
        array $data = []
    ) {
        $this->collectionFactory = $collectionFactory;
        $this->data = $data;
        $this->urlBuilder = $urlBuilder;
    }

    /**
     * Get action options
     *
     * @return array
     */
    public function jsonSerialize()
    {
        $i=0;
        if ($this->options === null) {
            // get the massaction data from the database table
            $userCollection = $this->collectionFactory->create();

            if(!count($userCollection)){
                return $this->options;
            }
            $options = [];
            //make a array of massaction
            /**
             * @var  $key
             * @var \Magento\User\Model\User $user
             */
            foreach ($userCollection as $key => $user) {
                $options[$i]['value']=$user->getId();
                $options[$i]['label']=$user->getName();
                $i++;
            }
            $this->prepareData();
            foreach ($options as $optionCode) {
                $this->options[$optionCode['value']] = [
                    'type' => 'user_' . $optionCode['value'],
                    'label' => $optionCode['label'],
                ];

                if ($this->urlPath && $this->paramName) {
                    $this->options[$optionCode['value']]['url'] = $this->urlBuilder->getUrl(
                        $this->urlPath,
                        [$this->paramName => $optionCode['value']]
                    );
                }

                $this->options[$optionCode['value']] = array_merge_recursive(
                    $this->options[$optionCode['value']],
                    $this->additionalData
                );
            }

            // return the massaction data
            $this->options = array_values($this->options);
        }
        return $this->options;
    }

    /**
     * Prepare addition data for subactions
     *
     * @return void
     */
    protected function prepareData()
    {

        foreach ($this->data as $key => $value) {
            switch ($key) {
                case 'urlPath':
                    $this->urlPath = $value;
                    break;
                case 'paramName':
                    $this->paramName = $value;
                    break;
                default:
                    $this->additionalData[$key] = $value;
                    break;
            }
        }
    }
}

This should work. For reference, you should check Customer grid > Mass action -> Assign a Customer Group.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top