fix: resolve nested schema component actions inside card actions - #165
Merged
Conversation
Filament adds `recordKey` to the context of any action that has a record. A schema component action nested inside a mounted card action (a Repeater's add/delete button, `Select::createOptionAction()`, a nested action modal) inherits the card's record, so it arrives with both `recordKey` and `schemaComponent` set. BoardResourcePage::resolveActions() checked `recordKey` first, routing those actions to resolveBoardAction(), which cannot find them. The mounted entry was silently dropped: the open modal closed without applying the change, and the orphaned entry left in `mountedActions` meant no card action could be mounted again until the page was reloaded. Check `schemaComponent` and `table` before `recordKey`, matching the ordering in Filament's own InteractsWithActions::resolveActions(). Fixes #156
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #156.
The bug
With an
EditActionincardActions()whose schema contains aRepeater, clicking the repeater's add (or remove) button closes the modal without applying the change. Afterwards no card action responds to clicks until the page is reloaded.Root cause
Filament\Actions\Action::getContext()addsrecordKeyto the context of any action that has a record. A schema component action nested inside a mounted card action inherits the card's record, so it arrives with both keys set:BoardResourcePage::resolveActions()checkedrecordKeyfirst, so the entry was routed toresolveBoardAction()→$parentAction->getModalAction('add')→null→continue. The mounted entry was silently dropped (no exception, nothing logged).Both reported symptoms follow from that one dropped entry:
mountedActionsholds 2 entries but only 1 resolves, sosyncActionModals()targets a nesting index that was never rendered and the open modal closes.getMountedAction()can never matchcount($mountedActions) - 1again. Every later card click appends another unreachable entry (["edit", "add", "edit"]), and nothing opens until reload.Filament core checks
schemaComponentandtablebefore falling back, so this is a divergence from upstream ordering rather than a new rule.The fix
Check
schemaComponentandtablebeforerecordKey, matchingInteractsWithActions::resolveActions(). Board card actions still route toresolveBoardAction(); they simply no longer shadow the more specific contexts.This also covers the repeater's delete/reorder/clone actions and every other nested schema component action inside a card action modal (Builder,
Select::createOptionAction(), nested->schema()modals).BoardPagewas never affected, it has no override.Backward compatibility
The reorder only changes routing for entries whose context has
recordKeyandschemaComponentortable. Everything else takes the same branch as before.schemaComponentortable. They are built bygetBoardRecordActions(), which sets onlylivewire()andrecord(), andAction::getTable()resolves from$this->table ?? $this->getGroup()?->getTable(), both null here. Confirmed against a running board: a mounted card action's context is{recordKey}and nothing else.getContext()returns early once an action has a parent action, so they carry onlyrecordKeyand keep resolving throughresolveBoardAction()'sgetModalAction()lookup. Covered by a dedicated test that passes both before and after the change.columnargument. The existingBoardResourcePageColumnActionTeststill passes.HasTable) previously resolved tonulland were dropped, so there is no working behaviour to preserve.Test plan
Five tests in
tests/Feature/BoardResourcePageNestedActionTest.php, driven throughTestBoardResourcePage(a realBoardResourcePagewith aRepeaterin a card action):Three of the five fail on
4.xwithFailed asserting that actual size 2 matches expected size 1, which is the orphaned entry. The other two pass before and after, which is the point of them. All five pass with the fix.Verified locally beyond the test suite:
vendor/bin/pest: 152 passedvendor/bin/pint: passedvendor/bin/phpstan analyse: 7 errors, identical to the count on unmodified4.x(pre-existing, none in the changed code)mountedActionsstays at a single entry, and a card action mounts normally afterwards