Accions
Les accions són el que es pot fer amb un registre (o amb el Resource sencer). Es declaren dins d'actions():
public function actions(): array
{
return [
ViewAction::make(),
EditAction::make(),
DeleteAction::make()->bulk(),
RestoreAction::make(),
ForceDeleteAction::make(),
Action::make('publish')
->icon('check')
->requiresConfirmation()
->bulk()
->handle(function (array $data, Post $post): array {
$post->update(['is_published' => true]);
return $post->only(['id', 'title', 'is_published']);
}),
Action::make('purge_drafts')
->label('Purge drafts')
->icon('trash')
->standalone()
->requiresConfirmation()
->handle(function (array $data): array {
return ['deleted' => Post::where('is_published', false)->delete()];
}),
];
}API de Action
| Mètode | Descripció |
|---|---|
make(string $name) | Nom intern de l'acció (apareix a la URL de l'endpoint). |
label(string $label) | Etiqueta al botó. Per defecte, Str::headline($name). |
icon(string $icon) | Nom d'icona (vegeu «Icones» més avall). |
standalone(bool = true) | Acció sobre el Resource sencer, no sobre un registre concret (per exemple, «Purge drafts»). |
bulk(bool = true) | Es pot aplicar a una selecció de diversos registres a la vegada; reutilitza el mateix endpoint per-registre, no hi ha una API bulk separada. |
requiresConfirmation(bool = true) | El frontend demana confirmació abans d'executar-la. |
withTrashed(bool = true) | L'acció opera sobre registres amb soft delete (necessari per a restore/forceDelete). |
authorize(Closure $callback) | Decideix si l'acció és visible i executable. Rep els mateixos arguments que handle(). Vegeu «Autorització». |
schema(array<Field> $fields) | Camps d'un formulari propi de l'acció. Vegeu «Accions amb formulari». |
url(Closure $callback, bool $openInNewTab = false) | Converteix l'acció en un enllaç. Vegeu «Accions que són un enllaç». |
handle(Closure $callback) | La lògica de l'acció. Rep (array $data, Model $record) per a accions sobre un registre, o només (array $data) per a standalone(). |
Autorització
- Amb
authorize(), l'acció fa servir aquest closure i res més. - Sense
authorize(), l'acció exigeixcanEdit()sobre el registre, ocanCreate()si ésstandalone(). Una acció que ha de ser oberta a usuaris que no poden editar ha de declararauthorize()explícitament. - Les accions incloses segueixen la seva habilitat:
ViewActionambcanView(),EditActioniRestoreActionambcanEdit(),DeleteActioniForceDeleteActionambcanDelete(). Si declaresauthorize()a una d'elles, s'han de complir les dues condicions. - Un Resource que l'usuari no pot llistar (
canViewAny()fals) tanca totes les seves accions.
Accions amb formulari
schema() demana dades a l'usuari abans d'executar l'acció. Un standalone() amb schema() obre el formulari sense cap registre:
Action::make('invite')
->label('Invite people')
->icon('paper-airplane')
->standalone()
->schema([
Tags::make('emails')
->itemRules('email')
->rules('required', 'array'),
Select::make('role')
->options(['editor' => 'Editor', 'viewer' => 'Viewer'])
->rules('required'),
])
->handle(function (array $data): array {
Invitations::send($data['emails'], $data['role']);
return ['message' => count($data['emails']).' invitations sent'];
})handle() rep les dades ja validades contra les regles dels camps. Els errors de validació surten amb l'etiqueta del camp, no amb el seu nom intern. Els camps Relation d'una acció serveixen les seves opcions només als usuaris que poden executar-la, i el seu query() s'aplica també en enviar el formulari.
Missatges de l'acció
Si el handler retorna un array amb una clau message de tipus text, el panell el mostra a l'usuari un cop feta l'acció. La resta de claus es retornen al frontend tal qual. Un handler que no retorna res respon { "success": true }.
Accions que són un enllaç
Amb url(), una acció no executa cap handler: navega. El closure rep el registre i retorna la URL, o null per no mostrar l'acció en aquella fila.
Action::make('open_public')
->label('Open public page')
->icon('eye')
->url(fn (Post $post): ?string => $post->is_published ? route('posts.show', $post) : null, openInNewTab: true)Accions incloses
ViewAction, EditAction, DeleteAction, RestoreAction i ForceDeleteAction són Action amb una icona (i, per a les dues últimes, withTrashed()/requiresConfirmation()) predefinides:
ViewAction::make(); // icona 'eye'
EditAction::make(); // icona 'pencil'
DeleteAction::make(); // icona 'trash'
RestoreAction::make(); // icona 'arrow-uturn-left', withTrashed()
ForceDeleteAction::make(); // icona 'trash', withTrashed(), requiresConfirmation()DeleteAction, RestoreAction i ForceDeleteAction reben un handler per defecte si no en declares cap: esborrar/restaurar/forçar l'esborrat del registre via Eloquent (respectant SoftDeletes quan el model el fa servir). Només cal cridar handle() explícitament quan vulguis substituir aquest comportament.
Bloquejar un esborrat des del model: si un listener de l'esdeveniment deleting del teu model llança un RuntimeException (per exemple, «encara té dependents»), l'endpoint d'esborrat el captura i respon 422 amb el missatge de l'excepció, en lloc d'un 500 sense cos que el frontend no pugui mostrar. És el mateix patró que fa servir Filament amb DeleteAction::configureUsing().
protected static function booted(): void
{
static::deleting(function (AcademicYear $year): void {
if ($year->courses()->exists()) {
throw new RuntimeException('Aquest curs encara té assignatures.');
}
});
}AttachAction i DetachAction són específiques dels Relation managers; s'hi expliquen en detall.
Icones
icon() pren un nom d'un subconjunt curat de Heroicons que Arrel ja porta embegut. No és tot Heroicons: només les icones que Arrel fa servir a les seves pròpies accions, widgets i navegació, per no pagar mida de bundle per icones que cap panell utilitza.
eye, trash, pencil, pencil-square, check, plus, plus-circle, x-mark, inbox, paper-airplane, key, envelope-open, arrow-uturn-left, document-text, home, arrow-right-on-rectangle, academic-cap, book-open, shield-check, squares-2x2, user-group, users, clipboard-document-check, bars-3, cog-6-tooth, chart-bar, calendar-days, calendar, chat-bubble-left-right, document-duplicate, information-circle, clock, user, exclamation-triangle, arrow-down-tray i bell.
Un nom fora d'aquesta llista no es renderitza. Les icones són de resources/js/support/icons.ts al paquet.
Accions estàndard vs. accions a mida
ViewAction/EditAction/DeleteAction no fan res de màgic: són Action amb valors per defecte convenients. Qualsevol acció a mida es defineix exactament igual, amb el seu propi schema() i handle():
Action::make('rename')
->icon('pencil-square')
->schema([
Text::make('title')->rules('required', 'string', 'max:255'),
])
->handle(function (array $data, Post $post): array {
$post->update(['title' => $data['title']]);
return $post->only(['id', 'title']);
})