diff --git a/lib/backpex/html/item_action.ex b/lib/backpex/html/item_action.ex index 01a4f568f..cb0a9938b 100644 --- a/lib/backpex/html/item_action.ex +++ b/lib/backpex/html/item_action.ex @@ -36,7 +36,7 @@ defmodule Backpex.HTML.ItemAction do id={:item_action_modal} live_resource={@live_resource} action_type={:item} - {Map.drop(assigns, [:socket, :flash, :fields])} + {Map.drop(assigns, [:fields | Backpex.HTML.Resource.lv_reserved_assigns()])} /> diff --git a/lib/backpex/html/resource.ex b/lib/backpex/html/resource.ex index 6a1d9ee51..48816e2fe 100644 --- a/lib/backpex/html/resource.ex +++ b/lib/backpex/html/resource.ex @@ -17,6 +17,16 @@ defmodule Backpex.HTML.Resource do embed_templates("resource/*") + @doc """ + Returns the list of assigns that `Phoenix.LiveView` reserves and that must be dropped + before spreading parent assigns into a child `Phoenix.LiveComponent`. + + `Phoenix.Component.assign/3` rejects these keys with an `ArgumentError`. Centralizing + the list here ensures every spread site forwards the same safe subset of the parent's + assigns. + """ + def lv_reserved_assigns, do: [:flash, :uploads, :streams, :socket, :myself] + @doc """ Renders a resource table. """ @@ -112,7 +122,7 @@ defmodule Backpex.HTML.Resource do id={"resource_#{@name}_#{@primary_key}"} module={@field_options.module} type={@type} - {Map.drop(assigns, [:socket, :flash, :myself, :uploads])} + {Map.drop(assigns, lv_reserved_assigns())} /> """ end @@ -148,7 +158,7 @@ defmodule Backpex.HTML.Resource do id={@id} module={@field_options.module} type={@type} - {Map.drop(assigns, [:socket, :flash, :myself, :uploads])} + {Map.drop(assigns, lv_reserved_assigns())} /> """ end @@ -183,7 +193,7 @@ defmodule Backpex.HTML.Resource do module={@field_options.module} lv_uploads={assigns[:uploads]} type={@type} - {Map.drop(assigns, [:socket, :flash, :myself, :uploads])} + {Map.drop(assigns, lv_reserved_assigns())} /> """ end diff --git a/lib/backpex/html/resource/resource_form_main.html.heex b/lib/backpex/html/resource/resource_form_main.html.heex index 414e97df8..f82018822 100644 --- a/lib/backpex/html/resource/resource_form_main.html.heex +++ b/lib/backpex/html/resource/resource_form_main.html.heex @@ -3,6 +3,6 @@ module={Backpex.FormComponent} id={:edit} live_resource={@live_resource} - {Map.drop(assigns, [:socket, :flash])} + {Map.drop(assigns, lv_reserved_assigns())} /> diff --git a/lib/backpex/html/resource/resource_index.html.heex b/lib/backpex/html/resource/resource_index.html.heex index 1b776fa9a..be97f8dbb 100644 --- a/lib/backpex/html/resource/resource_index.html.heex +++ b/lib/backpex/html/resource/resource_index.html.heex @@ -12,7 +12,7 @@ id={:modal} live_resource={@live_resource} action_type={:resource} - {Map.drop(assigns, [:socket, :flash, :fields])} + {Map.drop(assigns, [:fields | lv_reserved_assigns()])} /> diff --git a/test/backpex/html/resource_test.exs b/test/backpex/html/resource_test.exs new file mode 100644 index 000000000..1d93dd288 --- /dev/null +++ b/test/backpex/html/resource_test.exs @@ -0,0 +1,24 @@ +defmodule Backpex.HTML.ResourceTest do + use ExUnit.Case, async: true + + alias Backpex.HTML.Resource + + describe "lv_reserved_assigns/0" do + test "includes every assign reserved by Phoenix.LiveView" do + reserved = Resource.lv_reserved_assigns() + + for key <- [:flash, :uploads, :streams, :socket, :myself] do + assert key in reserved, "expected #{inspect(key)} in lv_reserved_assigns/0" + end + end + + test "dropping the reserved set removes :streams from a parent-style assigns map" do + assigns = %{streams: %{example: :ref}, foo: 1, bar: 2} + + result = Map.drop(assigns, Resource.lv_reserved_assigns()) + + refute Map.has_key?(result, :streams) + assert result == %{foo: 1, bar: 2} + end + end +end