Skip to content

Actions

Resources offer own actions on single records and on selections. This page shows how they belong to a resource; all options of actions are in Actions.

use Anvil\Resource\Action;
public function actions(): array
{
return [
Action::make('approve')
->label('Approve')->icon('check2')->color('success')
->permission('orders.approve')
->visible(fn ($order) => $order->status === 'open')
->confirm('Approve the order?')
->inRow()
->handle(function ($order): string {
service('orders')->approve($order);
return 'The order has been approved.';
}),
];
}
  • Shown in the header of the detail and edit page; with inRow() also in the rows and cards of the list, see Actions in lists.
  • The permission defaults to <slug>.update and is checked with the policy of the record.
  • Permission and visibility are checked again when the action runs, so a stale button cannot run an action that is no longer allowed.
  • handle() runs in a transaction and is audited; it returns a success message or null. With form() a dialog asks for data first.
  • Link actions open a page instead (Action::link(), Action::url()).
use Anvil\Resource\BulkAction;
public function bulkActions(): array
{
return [
BulkAction::make('markWon')
->label('Mark as won')->icon('trophy')
->allowed(fn (array $deal) => $deal['stage'] !== 'lost') // checked per record
->confirm('Mark the selected deals as won?')
->handle(function (array $deals, array $data): string {
// ...
return count($deals) . ' deals updated.';
}),
BulkAction::make('setStage')
->label('Set stage')
->form(fn (Form $form) => $form->schema([Select::make('stage')->options(self::STAGES)->required()]))
->handle(fn (array $deals, array $data) => service('deals')->setStage($deals, $data['stage'])),
];
}
  • The buttons appear when records are selected; selection checkboxes are shown when the user may delete or run at least one bulk action.
  • Every selected record is loaded through the resource (tenant and scopeQuery()) and checked: allowed() and the permission (default <slug>.update) with policies. If one record is not found or not allowed, nothing is changed (404 / 403).
  • maxRecords() limits the selection (default 500).
  • The handler runs in one transaction and is audited.

Details: Bulk actions.

Actions on related records belong to the relation, see Relation actions.