Bulk Actions

WIP - Only examples 1 and 4 currently functions.

Add Bulk actions that can be applied in the index of the page for this Crud.

->setBulkActions([
    "actions" => [
        "delete" => [
            'route' => route('admin.posts.delete-many'),
            'method' => 'DELETE',
            'label' => "Delete",
            'help_text' => 'Delete selected items',
        ],
        "assignTo" => [
            'route' => route('admin.posts.assign-author', ['%user%']),
            'label' => "Delete",
            'method' => 'PATCH',
            "selection" => ['user'],
        ],
        "reassignPosts" => [
            'route' => route('admin.users.replace-author', ['%new_user%']),
            'label' => "Delete",
            'method' => 'PATCH',
            "selection" => ['old_user', 'new_user'],
        ],
        "downloadCSV" => [
            'route' => route('admin.users.download'),
            'label' => 'Download CSV',
            'help_text' => 'Download CSV based on Selections, or filters if none are selected'
        ],
    ],
    "selections" => [
        "user" = > [
            ...
        ],
    ],
])

Options

  • route (required) : The route that this action should post to
  • name (required) : The label that the filter should use
  • method : The request type to send as. It will default to POST
  • selections : A list of selection to provide additional data, either to build routes or pass information
  • help_text: Additional text to be displayed by the Bulk Action selected for each selection.

Selections

Selections are used to both build up a route, and to provide additonal data to it. They are constructed as Enso SelectFields, so pass data as you would to any specific select field in Enso e.g. settings => [ ajax_url => route(...

When you add a selection to an action, it can do one of two things. If a selection is used to build a route (between % symbols), then the route will have that section replaced with the value from the selection. e.g. /users/%user%/comment will become /users/1/comments when 1 is the value of the selection made.

Alternatively, if the selection is NOT used to build a route, then it will be passed as data alongside the ids that the bulk action is to be performed against.

In example 1 (delete), an array of post ids will be sent as a DELETE request to admin/posts/delete-many to be deleted.

In example 2 (assignTo), an array of post ids will be sent as a PATCH request to admin/users/1/assign-posts to assign a set of posts to a specific user.

In example 3 (reassignPosts), an array of post ids and the id of old_user will be sent as a PATCH request to admin/users/1/reassign-posts, so that the new user can be assigned as the owner of any of the matching posts, but only when they were owned by old_user.

In example 4 (downloadCSV), all data (selected values and filters) are passed to the route as part of GET request. The developer is currently responsible for setting the correct response headers and data.

Controller Responses

The BulkAction component expects the server to respond based on whether the action was successful or not.

A typical Success response can include:

    return Response::json([
        'status' => 'success',
        'message' => 'Override message', // optional - if left blank, the message will be 'Your changes were saved successfully.'
        'index_url' => route($this->getConfig()->getRoute('index')), // optional - if left blank, the index page will recall 'get-items' with the current filters
    ]);

A typical Error response should include.

    return Response::json([
        'status' => 'error',
        'message' => 'Unable to Restore all the requested Form Responses',
    ]);

To allow for error checking and returning useful messages before initiating file downloads, these Actions are expected to be two-step processes.

The route that is registered on the Bulk action should direct to a Controller method that determines if, given the current values and filters, a viable download can be provided. It should respond with a file_url in the data property, which is the url at which file can actually be downloaded.

    return Response::json([
        'status' => 'success',
        'data' => [
            'file_url' => route('admin.tests.download-file', $request->only(['filters', 'values'])),
        ],
    ]);

This will then be set as the window location, and should ideally direct to a controller action that contains the following style of response. An download method for getting a CSV file might contain:

$headers = [
    'Content-type' => 'text/csv',
    'Content-Disposition' => 'attachment; filename=form_responses.csv',
    'Pragma' => 'no-cache',
    'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
    'Expires' => '0'
];


$callback = function() {

    ... // Generate File

}

return Response::stream($callback, 200, $headers);

API:

/**
 * Boolean check to see whether and bulk actions are available for this item
 *
 * @return boolean
 */
(bool) hasBulkActions()
/**
 * Returns the bulk actions list
 *
 * @return array
 */
(array) getBulkActions()
/**
 * Set the entire bulk_actions array.
 *
 * @param array $bulk_actions
 *
 * @return self
 */
(self) setBulkActions($bulk_actions)
/**
 * Adds a named bulk action to the list of actions.
 *
 * @param string $name
 * @param array $bulk_action
 *
 * @return self
 */
(self) addBulkAction($name, $bulk_action)
/**
 * Defers to addBulkAction for each element of an array.
 *
 * @param array $bulk_actions
 *
 * @return self
 */
(self) addBulkActions($bulk_actions)
/**
 * Removes a Bulk Action, by name
 *
 * @param string $name
 *
 * @return self
 */
(self) removeBulkAction($name)
/**
 * Adds a selection type to the bulk_actions list.
 *
 * @param string $name
 * @param array $selection
 *
 * @return self
 */
(self) addBulkActionSelection($name, $selection)
/**
 * Adds an array of selections to the bulk_actions list.
 *
 * @param array $selections
 *
 * @return self
 */
(self) addBulkActionSelections($selections)
/**
 * Removes a selection from the bulk actions list, by name
 *
 * @param string $name
 *
 * @return self
 */
(self) removeBulkActionSelection($name)