Skip to content

Actions ​

Una Action es cualquier operación clicable asociada a un Resource: editar, eliminar, publicar, exportar, archivar en lote o enlazar a una página externa. Arqel las modela como cuatro variantes — RowAction, BulkAction, ToolbarAction, HeaderAction — todas construidas sobre la misma clase base Arqel\Actions\Action.

Referencia completa de métodos: arqel-dev/actions.

Lo mínimo ​

Según el ADR-019, las actions de serie vienen de la factory Actions; las personalizadas se construyen con la clase concreta de la variante (RowAction::make(), no un alias de factory):

php
use Arqel\Actions\Actions;

public function actions(): array
{
    return [
        Actions::edit(),      // RowAction → dirige a /edit
        Actions::view(),      // RowAction → dirige a /show
        Actions::delete(),    // RowAction → DELETE con modal de confirmación
    ];
}

Para cualquier cosa personalizada:

php
use Arqel\Actions\Types\RowAction;

RowAction::make('publish')
    ->label('Publish')
    ->icon('check-circle')
    ->color('success')
    ->visible(fn ($record) => $record->status === 'draft')
    ->action(fn ($record) => $record->update(['status' => 'published']))
    ->successNotification('Post published!');

Variantes ​

ClaseDónde apareceRecibe
RowActionCada fila de la tabla + la página de detalle$record: Model
BulkActionToolbar, una vez que selectable() está activo y hay 1 o más filas marcadas$records: Collection
ToolbarActionToolbar de la tabla, siempre visible—
HeaderActionHeader de la página de create/edit/show$record: ?Model
php
use Arqel\Actions\Types\{RowAction, BulkAction, ToolbarAction, HeaderAction};

Adjúntalas mediante el método correspondiente de Table (->actions(), ->bulkActions(), ->toolbarActions()) — consulta la guía de Table.

php
RowAction::make('archive')
    ->label('Archive')
    ->requiresConfirmation()
    ->modalHeading('Archive this post?')
    ->modalDescription('Can be reverted within 30 days.')
    ->modalColor('warning')
    ->modalConfirmationRequiresText('ARCHIVE')   // el usuario debe escribir este texto exacto
    ->action(fn ($record) => $record->archive());

modalConfirmationRequiresText mantiene el botón de envío deshabilitado hasta que el usuario escriba la cadena exacta — resérvalo para operaciones irreversibles o de alto impacto.

Una Action puede abrir un modal que recoge datos antes de ejecutarse:

php
RowAction::make('reject')
    ->label('Reject')
    ->color('destructive')
    ->form([
        Field::textarea('reason')->required()->maxLength(500),
    ])
    ->modalSize('lg')
    ->action(function ($record, array $data) {
        $record->reject($data['reason']);
    });

Los fields del modal se declaran igual que en Resource::fields(). El servidor valida el payload enviado contra getFormValidationRules() antes de que se ejecute action().

Bulk actions con troceado ​

php
BulkAction::make('publish_all')
    ->label('Publish selected')
    ->chunkSize(50)                     // por defecto 100
    ->deselectRecordsAfterCompletion()
    ->action(function (Collection $records) {
        $records->each(fn ($r) => $r->publish());
    });

execute(Collection) itera los registros seleccionados en trozos, invocando el callback una vez por trozo — esto mantiene acotada la memoria en selecciones de más de 10 000 filas, ya que ActionController recupera los registros con whereIn(getKeyName, ids).

Autorización ​

php
RowAction::make('approve')
    ->authorize(fn ($user, $record) =>
        $user?->hasRole('manager') && $record->status === 'pending'
    );

canBeExecutedBy(?Authenticatable $user, $record) es lo que ActionController verifica del lado del servidor antes de invocar action() — la visibilidad en el cliente (visible()) es solo UX, esta es la verdadera puerta de control.

Action como enlace ​

Usa url() en lugar de action() para que el botón navegue en vez de ejecutar lógica en el servidor:

php
ToolbarAction::make('docs')
    ->label('Documentation')
    ->icon('book-open')
    ->url('https://arqel.dev', 'GET');   // se abre en una pestaña nueva automáticamente

RowAction::make('open_pdf')
    ->url(fn ($record) => Storage::url($record->pdf_path), 'GET');

url() y action() son mutuamente excluyentes — establecer uno limpia el otro.

Notificaciones ​

php
RowAction::make('publish')
    ->successNotification('Published successfully!')
    ->failureNotification('Failed to publish.');

HandleArqelInertiaRequests vuelca estos mensajes en la prop compartida flash; <FlashContainer> en el cliente los renderiza como toasts.

Antipatrones ​

  • Lógica del lado del cliente dentro de action() — el callback se ejecuta enteramente en el servidor; las redirecciones, los diálogos y otras preocupaciones de UI pertenecen al frontend, guiados por la respuesta de la action.
  • Declarar ->action(fn () => ...) sin el parámetro $record en una RowAction/HeaderAction — lo más probable es que quisieras leer el registro. Si una action realmente no necesita ningún registro, modélala como una ToolbarAction.
  • Establecer ->requiresConfirmation(false) explícitamente — es el valor por defecto; simplemente omite la llamada.

Próximos pasos ​

Licencia MIT — construido con Inertia + React + Laravel.