Preserve filters_changed flag in confirmed item action return URL#1978
Merged
Flo0807 merged 1 commit intoMay 12, 2026
Merged
Conversation
When a LiveResource declares a filter with a `default:` value, performing a confirmed item action (e.g. built-in Delete or any custom ItemAction with a confirm modal) caused the index to silently snap back to the default filters even when the user had explicitly cleared them. The form component navigates back to `socket.assigns.return_to` after a successful confirmed action via `push_navigate/2`, which remounts the index. `apply_index_return_to/1` built that URL from `query_options`, which never carries the transient `filters_changed` flag. After remount, `maybe_redirect_to_default_filters/1` saw `filters_changed: false` plus empty filters and re-applied the defaults, overwriting the user's cleared state. Carry `filters_changed=true` through the `return_to` URL whenever the flag is currently set, so the redirect-to-defaults logic correctly recognises that the user has interacted with filters.
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes a LiveResource navigation bug where confirmed item actions (e.g., delete with confirmation) could cause the index to remount without filters_changed=true, leading maybe_redirect_to_default_filters/1 to silently re-apply default filters even after a user explicitly cleared them.
Changes:
- Preserve
filters_changed=truein the computedreturn_toURL when the socket indicates filters were changed. - Add a regression test in the demo app to ensure confirmed delete actions don’t snap default filters back after clearing.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| lib/backpex/live_resource/index.ex | Includes filters_changed=true in return_to options when socket.assigns.filters_changed is set, so confirmed actions navigate back with the flag preserved. |
| demo/test/demo_web/live/post/filter_live_test.exs | Adds an end-to-end LiveView test verifying cleared default filters remain cleared after a confirmed delete action round-trip. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
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.
Summary
Fixes a bug where confirmed item actions (built-in
Backpex.ItemActions.Deleteor any customItemActionwith aconfirm/1callback) silently re-apply default filters on aLiveResourcewhosefilters/1declares a filter with adefault:value, even when the user has explicitly cleared them.Reproduced on Backpex 0.18.0 /
develop.Root cause
Three pieces interacted to lose the user's cleared-filter state:
apply_index_return_to/1inlib/backpex/live_resource/index.exbuiltsocket.assigns.return_tofromquery_options, which carries:filters,:page,:per_page,:order_by,:order_direction,:search— but not the transientfilters_changedflag (which lives only insocket.assigns.filters_changedand as a URL query param).Backpex.FormComponent.handle_form_item_action/3callspush_navigate(to: return_to)after a successful confirmed action, so the URL it lands on is missingfilters_changed=true.assign_filters_changed_status/2readsparams["filters_changed"](now missing) →filters_changed: false.maybe_redirect_to_default_filters/1then seesfilters_changed == falseANDquery_options.filters == %{}AND filters withdefault:exist → push-navigates to a URL with defaults applied. The user's cleared state is silently overwritten.Fix
Carry
filters_changed=truethrough thereturn_toURL whenever the flag is currently set on the socket. This is the smallest correct change: it keepsmaybe_redirect_to_default_filters/1intact for fresh navigation while preserving user state acrosspush_navigateround-trips through the form component.The router-level
Backpex.Router.get_path/5is intentionally not changed, becausemaybe_redirect_to_default_filters/1itself calls it — that path must NOT gainfilters_changed=true, since it represents the system applying defaults, not the user.Regression test
Added
describe "filters_changed preservation across confirmed item actions"indemo/test/demo_web/live/post/filter_live_test.exs. The demo'sPostLivealready had the perfect fixture — apublishedfilter withdefault: ["published"]plus the built-in delete item action. The test:/admin/postsand confirms only the published post is visible (default filter applied).publishedfilter via the existing clear-filter UI control.filters_changed=trueand that the surviving unpublished post is still visible (i.e. the default filter has not snapped back).Verified the test catches the bug by temporarily reverting the fix — the assertion fails with the URL becoming
filters[published][]=published&....Verification
mix lint(Backpex library): passes — 95 doctests, 164 tests, 0 failures.mix test test/demo_web/live/post/filter_live_test.exs(demo): passes — 24 tests, 0 failures./admin/posts: cleared the defaultpublishedfilter, opened the delete modal on an unpublished post, confirmed. After navigation the URL is?order_by=id&order_direction=asc&per_page=15&page=1&filters_changed=true(flag preserved, defaults not re-applied) and unpublished posts remain visible.Test plan
mix linton Backpex librarymix test test/demo_web/live/post/filter_live_test.exsin the demo/admin/posts