F
Filament4w ago
3rgo

Dynamic table record Action label

Hello, I've been trying unsuccessfully to set a dynamic label to a recordAction in a filament resource table. In v3 I could do this easily:
Tables\Actions\Action::make('evaluations')
->label(fn(Application $record) => __('admin.application.evaluations', ['count' => $record->evaluations->count()]))
->url(fn(Application $record) => route('filament.admin.resources.applications.evaluations', ['record' => $record]))
Tables\Actions\Action::make('evaluations')
->label(fn(Application $record) => __('admin.application.evaluations', ['count' => $record->evaluations->count()]))
->url(fn(Application $record) => route('filament.admin.resources.applications.evaluations', ['record' => $record]))
But the same code now throws an error, because the $record given to the callback is null. I tried dumping it and even with a full page (10 records) the callback is only called once without the record. Am i missing something ? This seems in direct contradiction to the documentation stating "All methods on the action accept callback functions, where you can access the current table $record that was clicked."
Solution:
After checking this is not an issue with the framework, because a minimal repository could not reproduce the issue. I checked over my project and remembered that I set up some global overrides when I upgraded to Filament v4 a month ago, using the modifyUngroupedRecordActionsUsing as described in the documentation (https://filamentphp.com/docs/4.x/tables/actions#global-record-action-settings), to ensure table actions labels were using my own label translations. The unfortunate side effect of this was forcing the label for all actions, not just the View/Edit/Delete : ```php Table::configureUsing( fn (Table $table): Table => $table...
Jump to solution
17 Replies
toeknee
toeknee4w ago
Tables\Actions\Action::make('evaluations')
->label(fn(Application|null $record) => __('admin.application.evaluations', ['count' => $record?->evaluations->count()]))
->url(fn(Application|null $record) => route('filament.admin.resources.applications.evaluations', ['record' => $record]))
Tables\Actions\Action::make('evaluations')
->label(fn(Application|null $record) => __('admin.application.evaluations', ['count' => $record?->evaluations->count()]))
->url(fn(Application|null $record) => route('filament.admin.resources.applications.evaluations', ['record' => $record]))
3rgo
3rgoOP4w ago
Thanks I tried that already, seemed pretty obvious given the error 😅 But the point is not the error, it's the discrepency between the documentation and actual behaviour (v4.1.10), meaning the label function callback is not given the record because it is evaluated once for the entire page, not once for every record
toeknee
toeknee4w ago
Seems strange, could try passing in $livewire and getting it from there
3rgo
3rgoOP4w ago
$livewire contains an instance of my list page so I cannot get the record
toeknee
toeknee4w ago
And does $livewire not contain ->record or ownerREcord or form? or data
3rgo
3rgoOP4w ago
No, like I said I’m on the list page so no record, owner record or form. And even if data was there how am I supposed to have different labels for each record if the label method is called only once ?
toeknee
toeknee4w ago
I thought the action would have contained it in the livewire object of the record. So you are basically saying that you want to customise the label in a record action, but can't. I would suggest a PR to support $record within the label but suspect Dan may have removaed it because it often doesn't make sense in an actual action.. Else, use a normal column but chuck a custom action into the TextColumn. ? If you are just using a url though... you should be able to do:
TextColumn::make('evaluations_count')
->counts('evaluations')
->url(fn($record) => route('filament.admin.resources.applications.evaluations', ['record' => $record])
TextColumn::make('evaluations_count')
->counts('evaluations')
->url(fn($record) => route('filament.admin.resources.applications.evaluations', ['record' => $record])
Something like that?
3rgo
3rgoOP4w ago
Yes I want to use the record to customise the record action label Doing a PR would be great except I can’t even find why the label method is evaluated only once
toeknee
toeknee4w ago
I suspect it's Dan's way to improve table performance and reducing the need to avaulate the cloure on a record action which is usually an action that's name wouldn't change makes sense. @Dan Harrin can you offer some insight here for the change in v4 with the closure on $record for the label on an action?
Dan Harrin
Dan Harrin4w ago
please open an issue with a reproduction repository
3rgo
3rgoOP4w ago
Thanks Dan ! Should I do it on the tables repository ?
toeknee
toeknee4w ago
Just do your own minimal repository than you can re-create the issue on. So the team can download migrate, and test the reported bug with as little work as possible to narrow down the bug.
3rgo
3rgoOP4w ago
I understand the concept of reproduction repository, my question was where to create the issue
toeknee
toeknee4w ago
GitHub
GitHub - filamentphp/filament: A powerful open source UI framework ...
A powerful open source UI framework for Laravel • Build and ship admin panels & apps fast with Livewire - filamentphp/filament
Solution
3rgo
3rgo4w ago
After checking this is not an issue with the framework, because a minimal repository could not reproduce the issue. I checked over my project and remembered that I set up some global overrides when I upgraded to Filament v4 a month ago, using the modifyUngroupedRecordActionsUsing as described in the documentation (https://filamentphp.com/docs/4.x/tables/actions#global-record-action-settings), to ensure table actions labels were using my own label translations. The unfortunate side effect of this was forcing the label for all actions, not just the View/Edit/Delete :
Table::configureUsing(
fn (Table $table): Table => $table
->modifyUngroupedRecordActionsUsing(fn (Action $action): Action => $action
->label(match ($action->getName()) {
'view' => __('generic.actions.view'),
'edit' => __('generic.actions.edit'),
'delete' => __('generic.actions.delete'),
default => $action->getLabel(),
})
)
);
Table::configureUsing(
fn (Table $table): Table => $table
->modifyUngroupedRecordActionsUsing(fn (Action $action): Action => $action
->label(match ($action->getName()) {
'view' => __('generic.actions.view'),
'edit' => __('generic.actions.edit'),
'delete' => __('generic.actions.delete'),
default => $action->getLabel(),
})
)
);
The default case is the root cause of my initial issue I believe. I've replaced this behaviour with ViewAction/EditAction/DeleteAction overrides and everything now works. Thank you @toeknee and @Dan Harrin and sorry for taking up your time with this.
Dan Harrin
Dan Harrin4w ago
great. exactly why we ask for a reproduction :)
toeknee
toeknee4w ago
That's explains the evulation hehe, good spot

Did you find this page helpful?