diff --git a/lib/live_admin/router.ex b/lib/live_admin/router.ex index 647a42f..f0a669e 100644 --- a/lib/live_admin/router.ex +++ b/lib/live_admin/router.ex @@ -22,6 +22,7 @@ defmodule LiveAdmin.Router do |> Map.fetch!(:path) @base_path Path.join(["/", current_path, unquote(path)]) + @__live_admin_scope_opts__ unquote(opts) scope unquote(path), alias: false, as: false do live_session :"live_admin_#{@base_path}", @@ -54,6 +55,14 @@ defmodule LiveAdmin.Router do import Phoenix.LiveView.Router, only: [live: 4] quote bind_quoted: [path: path, resource_mod: resource_mod] do + LiveAdmin.Router.__validate_config__!( + resource_mod, + @__live_admin_scope_opts__, + create_with: Application.compile_env(:live_admin, :create_with), + update_with: Application.compile_env(:live_admin, :update_with), + components: Application.compile_env(:live_admin, :components, []) + ) + full_path = Path.join(@base_path, path) live(path, LiveAdmin.Components.Container, :index, @@ -78,6 +87,31 @@ defmodule LiveAdmin.Router do end end + @disabled_with_custom_component [ + {:create_with, :create}, + {:update_with, :edit} + ] + + @doc false + def __validate_config__!(resource_mod, scope_opts, app_opts) do + Code.ensure_compiled!(resource_mod) + resource_opts = resource_mod.__live_admin_config__() + levels = [resource_opts, scope_opts, app_opts] + + Enum.each(@disabled_with_custom_component, fn {with_key, component_key} -> + disabled? = Enum.any?(levels, &(Keyword.get(&1, with_key) == false)) + + component_set? = + Enum.any?(levels, &Keyword.has_key?(Keyword.get(&1, :components, []), component_key)) + + if disabled? and component_set? do + raise ArgumentError, + "invalid config for resource #{inspect(resource_mod)}: " <> + "#{with_key}: false cannot be combined with a custom :#{component_key} component" + end + end) + end + def build_session(conn, base_path, opts) do opts_schema = LiveAdmin.base_configs_schema() ++ diff --git a/test/live_admin/router_test.exs b/test/live_admin/router_test.exs new file mode 100644 index 0000000..36c4051 --- /dev/null +++ b/test/live_admin/router_test.exs @@ -0,0 +1,39 @@ +defmodule LiveAdmin.RouterTest do + use ExUnit.Case, async: true + + alias LiveAdmin.Router + + describe "create_with: false at resource level with custom :create component at resource level" do + test "raises ArgumentError" do + assert_raise ArgumentError, ~r/create_with: false.*:create component/, fn -> + Router.__validate_config__!(LiveAdminTest.UserWithCustomCreate, [], []) + end + end + end + + describe "create_with: false at scope level with custom :create component at resource level" do + test "raises ArgumentError" do + assert_raise ArgumentError, ~r/create_with: false.*:create component/, fn -> + Router.__validate_config__!( + LiveAdminTest.UserWithCustomCreateOnly, + [create_with: false], + [] + ) + end + end + end + + describe "update_with: false at app level with custom :edit component at resource level" do + test "raises ArgumentError" do + assert_raise ArgumentError, ~r/update_with: false.*:edit component/, fn -> + Router.__validate_config__!(LiveAdminTest.UserWithCustomEditOnly, [], update_with: false) + end + end + end + + describe "resource without conflicting config" do + test "returns :ok" do + assert :ok == Router.__validate_config__!(LiveAdminTest.User, [], []) + end + end +end diff --git a/test/support/resources.ex b/test/support/resources.ex index 31932fb..2d90dde 100644 --- a/test/support/resources.ex +++ b/test/support/resources.ex @@ -1,3 +1,28 @@ +defmodule LiveAdminTest.CustomFormComponent do + use Phoenix.LiveComponent + + def render(assigns), do: ~H"