Skip to content

Preserve filters_changed flag in confirmed item action return URL#1978

Merged
Flo0807 merged 1 commit into
developfrom
feature/preserve-filters-changed-on-confirmed-item-actions
May 12, 2026
Merged

Preserve filters_changed flag in confirmed item action return URL#1978
Flo0807 merged 1 commit into
developfrom
feature/preserve-filters-changed-on-confirmed-item-actions

Conversation

@Flo0807

@Flo0807 Flo0807 commented May 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes a bug where confirmed item actions (built-in Backpex.ItemActions.Delete or any custom ItemAction with a confirm/1 callback) silently re-apply default filters on a LiveResource whose filters/1 declares a filter with a default: 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:

  1. apply_index_return_to/1 in lib/backpex/live_resource/index.ex built socket.assigns.return_to from query_options, which carries :filters, :page, :per_page, :order_by, :order_direction, :search — but not the transient filters_changed flag (which lives only in socket.assigns.filters_changed and as a URL query param).
  2. Backpex.FormComponent.handle_form_item_action/3 calls push_navigate(to: return_to) after a successful confirmed action, so the URL it lands on is missing filters_changed=true.
  3. On the next mount, assign_filters_changed_status/2 reads params["filters_changed"] (now missing) → filters_changed: false. maybe_redirect_to_default_filters/1 then sees filters_changed == false AND query_options.filters == %{} AND filters with default: exist → push-navigates to a URL with defaults applied. The user's cleared state is silently overwritten.

Fix

Carry filters_changed=true through the return_to URL whenever the flag is currently set on the socket. This is the smallest correct change: it keeps maybe_redirect_to_default_filters/1 intact for fresh navigation while preserving user state across push_navigate round-trips through the form component.

The router-level Backpex.Router.get_path/5 is intentionally not changed, because maybe_redirect_to_default_filters/1 itself calls it — that path must NOT gain filters_changed=true, since it represents the system applying defaults, not the user.

Regression test

Added describe "filters_changed preservation across confirmed item actions" in demo/test/demo_web/live/post/filter_live_test.exs. The demo's PostLive already had the perfect fixture — a published filter with default: ["published"] plus the built-in delete item action. The test:

  1. Inserts one published and two unpublished posts.
  2. Visits /admin/posts and confirms only the published post is visible (default filter applied).
  3. Clears the published filter via the existing clear-filter UI control.
  4. Triggers the delete confirm modal on one of the unpublished rows and submits it.
  5. Asserts the URL still contains filters_changed=true and 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.
  • End-to-end browser verification through the running demo at /admin/posts: cleared the default published filter, 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 lint on Backpex library
  • mix test test/demo_web/live/post/filter_live_test.exs in the demo
  • End-to-end smoke test through the demo at /admin/posts
  • Confirmed regression test fails without the fix

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.
@Flo0807 Flo0807 requested a review from Copilot May 12, 2026 09:28
@Flo0807 Flo0807 self-assigned this May 12, 2026
@Flo0807 Flo0807 added the bug Something isn't working label May 12, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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=true in the computed return_to URL 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.

@Flo0807 Flo0807 added this pull request to the merge queue May 12, 2026
Merged via the queue into develop with commit 2718401 May 12, 2026
11 checks passed
@Flo0807 Flo0807 deleted the feature/preserve-filters-changed-on-confirmed-item-actions branch May 12, 2026 09:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants