Hidden Action and action modal not opening. But if remove hidden the modal works

If i have a table and in the table i have actions that are hidden/visible based on some criteria. and the action is supposed to open a modal with a form, it's not opening the modal. I can see the request to the server to "open" modal but the modal does not open. If I remove the 'hidden" or 'visible' methods from the action, then the modal opens without a problem. This code does NOT open modal
Tables\Actions\Action::make('uploadCover')
->icon('iconoir-media-image-plus')
->hidden(fn ($record): bool => !$record->canAction($user, 'release_upload_cover'))
->form([
Forms\Components\FileUpload::make('cover')
->label('Cover')
->image()
->directory('covers')
])
->action(function (array $data, Model $record): void {
dd($data, $record);
})
Tables\Actions\Action::make('uploadCover')
->icon('iconoir-media-image-plus')
->hidden(fn ($record): bool => !$record->canAction($user, 'release_upload_cover'))
->form([
Forms\Components\FileUpload::make('cover')
->label('Cover')
->image()
->directory('covers')
])
->action(function (array $data, Model $record): void {
dd($data, $record);
})
This code WORKS as expected
Tables\Actions\Action::make('uploadCover')
->icon('iconoir-media-image-plus')
->form([
Forms\Components\FileUpload::make('cover')
->label('Cover')
->image()
->directory('covers')
])
->action(function (array $data, Model $record): void {
dd($data, $record);
})
Tables\Actions\Action::make('uploadCover')
->icon('iconoir-media-image-plus')
->form([
Forms\Components\FileUpload::make('cover')
->label('Cover')
->image()
->directory('covers')
])
->action(function (array $data, Model $record): void {
dd($data, $record);
})
Please help. Thanks
21 Replies
Kymset
Kymset6mo ago
I have had a go and have been unable to replicate your issue. I tried:
Tables\Actions\Action::make('uploadCover')
->hidden(fn ($record): bool => $record->id % 2 === 0)
->form([
Forms\Components\FileUpload::make('cover')
->label('Cover')
->image()
->directory('covers')
])
->action(function (array $data, Model $record): void {
dd($data, $record);
})
Tables\Actions\Action::make('uploadCover')
->hidden(fn ($record): bool => $record->id % 2 === 0)
->form([
Forms\Components\FileUpload::make('cover')
->label('Cover')
->image()
->directory('covers')
])
->action(function (array $data, Model $record): void {
dd($data, $record);
})
The only differences is your checking a users permissions and the icon. I would check your version of filament to make sure you are using the latest
No description
No description
Dennis Koch
Dennis Koch6mo ago
->hidden(fn ($record): bool => !$record->canAction($user, 'release_upload_cover'))
Where is $user coming from?!
julianwayu
julianwayuOP6mo ago
this worked for me as well. I declare it outside. but even if i swap it with auth()->user() i'm still experiencing the same problem. :S
Dennis Koch
Dennis Koch6mo ago
Can you debug the return value of the user and hidden or whether that hidden method is run at all when you click the button?
julianwayu
julianwayuOP6mo ago
yeah doing that right now. So.. i moved @Kymset hidden test logic into the canAction in the record.
->hidden(fn ($record): bool => $record->id % 2 === 0)
->hidden(fn ($record): bool => $record->id % 2 === 0)
moved it inside the "record"
public function canAction(): bool
{
return $this->id % 2 === 0;
}
public function canAction(): bool
{
return $this->id % 2 === 0;
}
so the new hidden is like this
->hidden(fn ($record): bool => $record->canAction())
->hidden(fn ($record): bool => $record->canAction())
and same problem occurs.. even though before the hidden() that Kimset suggested to test with worked. The click button runs. as I can see the requests. when the button is not hidden. but the modal does not appear. The return of the canAction() is as expected since things are getting hidden and showned as expected. the problem is the action button not triggering the modal.
Dennis Koch
Dennis Koch6mo ago
The return of the canAction() is as expected since things are getting hidden and showned as expected
But did you validate that after clicking. Trying to figure out what is off. Seems like your component is hidden on the request when clicked
julianwayu
julianwayuOP6mo ago
let me double check all that. not fully sure i understand how to check it. but let me try. lol What's weird is why this works: ->hidden(fn ($record): bool => $record->id % 2 === 0) but not when i moved the same logic to a method inside the record?
Dennis Koch
Dennis Koch6mo ago
E.g. via Xdebug. Or adding a simple dd() after the page was loaded Seems like something is wrong with $record then Is that model using a different primary key than id?
julianwayu
julianwayuOP6mo ago
No description
julianwayu
julianwayuOP6mo ago
thats the response inside of canAction. after i click on the action button.
Dennis Koch
Dennis Koch6mo ago
Hm. Looks good, right?
julianwayu
julianwayuOP6mo ago
19 is the id yeah so in theory it should open the modal.
julianwayu
julianwayuOP6mo ago
No description
Dennis Koch
Dennis Koch6mo ago
Hm. Sorry, I don't have an idea right now
julianwayu
julianwayuOP6mo ago
ok. thanks Dennis for your help. i'm going to keep trying things. will report. need to investigate how the callable inside the hidden works. maybe that can give me some insight to the problem
Dennis Koch
Dennis Koch6mo ago
The callables are evaluated by $this->evaluate()
julianwayu
julianwayuOP6mo ago
I give up. it's a mystery. some of my "task types" work some dont. but inspecting the return on the hidden callbacks everything is as expected. @Dennis Koch was looking for other ways to accomplish what i want. Quick question, have you guys considered having actions accept a callback? somehting like this:
$table->actions(fn($record): array => $record->actions())
$table->actions(fn($record): array => $record->actions())
This would be really nice, so that instead of relying on hiding stuff via the actions themselves, we can just take care of building the actions and maybe even caching them before hand and would also feel a little more clean or maybe there is already a way to accomplish something similar that I might be missing. I still think there is some bug or something weird happening with authorize(), hidden() and visible() i have done a bunch of tests. can you do me a huge favor @Kymset can you do the inverse of your test: so instead of ->hidden(fn ($record): bool => $record->id % 2 === 0) do ->hidden(fn ($record): bool => $record->id % 2 != 0) When i do the inverse the modal does not show on the active actions. but if i leave it like you originally did. it works fine and i cant for the life of me figure it out why..
Kymset
Kymset6mo ago
Hi @julianwayu, I can give it a go later on tonight 🙂 Will update you with the results Hey @julianwayu, I tried the following code:
Tables\Actions\Action::make('uploadCover')
->hidden(fn ($record): bool => $record->id % 2 != 0)
->form([
Forms\Components\FileUpload::make('cover')
->label('Cover')
->image()
->directory('covers')
])
->action(function (array $data, Model $record): void {
dd($data, $record);
})
Tables\Actions\Action::make('uploadCover')
->hidden(fn ($record): bool => $record->id % 2 != 0)
->form([
Forms\Components\FileUpload::make('cover')
->label('Cover')
->image()
->directory('covers')
])
->action(function (array $data, Model $record): void {
dd($data, $record);
})
This worked for me and opened up the modal
julianwayu
julianwayuOP6mo ago
Ugh. What the hell. Ok. Thanks so much for trying out. I’m going to start a new project and try from scratch on something simple. Not clue what’s going on with my current project. Is very bizarre. @Kymset i narrow it down. I did it in a regular resource and both conditions work as expected. The problem seems to be in my RalationManager. Ok.. its def my relationship:
public function tasks(): MorphMany
{
$releaseId = $this->id;
return $this->morphMany(Task::class, 'resource')
->orWhere(function($subQuery) use($releaseId) {
$subQuery
->where('tasks.parent_type', 'App\\Models\\Release')
->where('tasks.parent_id', $releaseId);
});
}
public function tasks(): MorphMany
{
$releaseId = $this->id;
return $this->morphMany(Task::class, 'resource')
->orWhere(function($subQuery) use($releaseId) {
$subQuery
->where('tasks.parent_type', 'App\\Models\\Release')
->where('tasks.parent_id', $releaseId);
});
}
It does not like my orWhere that bring additional tasks.. if i remove that and just leave it like
public function tasks(): MorphMany
{
return $this->morphMany(Task::class, 'resource');
}
public function tasks(): MorphMany
{
return $this->morphMany(Task::class, 'resource');
}
then it works as expected. no idea why it would cause that though.
Dennis Koch
Dennis Koch6mo ago
$releaseId = $this->id;
This part requires your relation to be always lazy loaded You probably should use ->whereColumn() if that works in the subquery (maybe not 🙈)
julianwayu
julianwayuOP6mo ago
Was trying to see if I could do it another way but not able to. might have to just use the table with a custom query. and not the relation Anything i add on top of the initial query.. stops my modals from working. even i do it as simple as
public function tasks(): MorphMany
{

return $this->morphMany(Task::class, 'resource')
->orWhere('parent_id', $this->id);
}
public function tasks(): MorphMany
{

return $this->morphMany(Task::class, 'resource')
->orWhere('parent_id', $this->id);
}
It works for pulling the right tasks. but the action buttons do not trigger a modal open
Want results from more Discord servers?
Add your server