3

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.

1 Answer 1

1
+100

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.

2
  • Your main question is to show the dropdown in the Mass Action section. For assigning and all that will depend upon your own logic. Please ask another question about that. Mar 25, 2021 at 22:13
  • Thank you its worked, if you can update about select All issue if you have the fix that will be great! Mar 26, 2021 at 5:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.