From 954e5a869c699f6dc11bea6c535127a6fe20c5be Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Mon, 9 Mar 2026 10:06:37 -0500 Subject: [PATCH 01/11] Remove unused requires --- lib/backpex/html/core_components.ex | 2 -- lib/backpex/live_resource.ex | 2 -- lib/backpex/live_resource/show.ex | 2 -- 3 files changed, 6 deletions(-) diff --git a/lib/backpex/html/core_components.ex b/lib/backpex/html/core_components.ex index 8d31e6858..fdb84fff6 100644 --- a/lib/backpex/html/core_components.ex +++ b/lib/backpex/html/core_components.ex @@ -4,8 +4,6 @@ defmodule Backpex.HTML.CoreComponents do """ use BackpexWeb, :html - require Backpex - @doc """ Renders a Heroicons icon. """ diff --git a/lib/backpex/live_resource.ex b/lib/backpex/live_resource.ex index cd99d8a8a..ff5d13cdd 100644 --- a/lib/backpex/live_resource.ex +++ b/lib/backpex/live_resource.ex @@ -12,8 +12,6 @@ defmodule Backpex.LiveResource do alias Backpex.Resource alias Backpex.Router - require Backpex - @options_schema [ adapter: [ doc: "The data layer adapter to use.", diff --git a/lib/backpex/live_resource/show.ex b/lib/backpex/live_resource/show.ex index 62f17dcf1..5770c7a63 100644 --- a/lib/backpex/live_resource/show.ex +++ b/lib/backpex/live_resource/show.ex @@ -7,8 +7,6 @@ defmodule Backpex.LiveResource.Show do alias Backpex.Resource alias Backpex.Router - require Backpex - def mount(params, _session, socket, live_resource) do socket |> Backpex.LiveResource.maybe_subscribe_to_pubsub(live_resource) From 87f1763ab76cb8d1374abc1f3be0c1671f3baaed Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Mon, 9 Mar 2026 11:30:01 -0500 Subject: [PATCH 02/11] Remove redundant use Phoenix.Component --- lib/backpex_web.ex | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/backpex_web.ex b/lib/backpex_web.ex index 6052833f6..d4eb67cdd 100644 --- a/lib/backpex_web.ex +++ b/lib/backpex_web.ex @@ -23,7 +23,6 @@ defmodule BackpexWeb do """ def field do quote do - use Phoenix.Component use Phoenix.LiveComponent alias Backpex.HTML alias Backpex.HTML.Form, as: BackpexForm From b68eaf6ec1bdbbdf93790a3607b26882e8fc0af9 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Mon, 9 Mar 2026 11:30:28 -0500 Subject: [PATCH 03/11] Move Field and ItemAction default function definitions out of before_compile --- lib/backpex/field.ex | 57 ++++++++++++++----------- lib/backpex/item_actions/item_action.ex | 18 ++++---- 2 files changed, 42 insertions(+), 33 deletions(-) diff --git a/lib/backpex/field.ex b/lib/backpex/field.ex index 7dc82554d..b155000f6 100644 --- a/lib/backpex/field.ex +++ b/lib/backpex/field.ex @@ -232,6 +232,38 @@ defmodule Backpex.Field do use BackpexWeb, :field + import Ecto.Query + + @impl Backpex.Field + def display_field({name, _field_options} = _field), do: name + + @impl Backpex.Field + def schema(_field, schema), do: schema + + @impl Backpex.Field + def association?(_field), do: false + + @impl Backpex.Field + def assign_uploads(_field, socket), do: socket + + @impl Backpex.Field + def search_condition(schema_name, field_name, search_string) do + dynamic( + [{^schema_name, schema_name}], + schema_name |> field(^field_name) |> ilike(^search_string) + ) + end + + @impl Backpex.Field + def before_changeset(changeset, _attrs, _metadata, _repo, _field, _assigns), do: changeset + + defoverridable display_field: 1, + schema: 2, + association?: 1, + assign_uploads: 2, + search_condition: 3, + before_changeset: 6 + @doc """ Returns the schema of configurable options for this field. @@ -260,8 +292,6 @@ defmodule Backpex.Field do defmacro __before_compile__(_env) do quote do - import Ecto.Query - @impl Phoenix.LiveComponent def render(%{type: :index} = assigns) do if Backpex.Field.index_editable_enabled?(assigns.field_options, assigns) do @@ -281,29 +311,6 @@ defmodule Backpex.Field do nil -> apply(__MODULE__, :render_form, [assigns]) end end - - @impl Backpex.Field - def display_field({name, _field_options} = _field), do: name - - @impl Backpex.Field - def schema(_field, schema), do: schema - - @impl Backpex.Field - def association?(_field), do: false - - @impl Backpex.Field - def assign_uploads(_field, socket), do: socket - - @impl Backpex.Field - def search_condition(schema_name, field_name, search_string) do - dynamic( - [{^schema_name, schema_name}], - schema_name |> field(^field_name) |> ilike(^search_string) - ) - end - - @impl Backpex.Field - def before_changeset(changeset, _attrs, _metadata, _repo, _field, _assigns), do: changeset end end diff --git a/lib/backpex/item_actions/item_action.ex b/lib/backpex/item_actions/item_action.ex index 3502f1783..4ea6b2517 100644 --- a/lib/backpex/item_actions/item_action.ex +++ b/lib/backpex/item_actions/item_action.ex @@ -111,14 +111,6 @@ defmodule Backpex.ItemAction do @behaviour Backpex.ItemAction require Backpex - end - end - - defmacro __before_compile__(env) do - validate_handle_or_link!(env) - - quote do - @after_compile Backpex.ItemAction @impl Backpex.ItemAction def confirm_label(assigns), do: Backpex.__("Apply", assigns.live_resource) @@ -135,6 +127,16 @@ defmodule Backpex.ItemAction do {%{}, types} end + + defoverridable confirm_label: 1, cancel_label: 1, fields: 0, base_schema: 1 + end + end + + defmacro __before_compile__(env) do + validate_handle_or_link!(env) + + quote do + @after_compile Backpex.ItemAction end end From 7e1f6bec433ac84461a981e319e7125ffaa1d2ec Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Wed, 11 Mar 2026 08:30:47 -0500 Subject: [PATCH 04/11] Move LiveResource default methods out of before_compile to use defoverridable --- lib/backpex/live_resource.ex | 136 ++++++++++++++++++----------------- 1 file changed, 69 insertions(+), 67 deletions(-) diff --git a/lib/backpex/live_resource.ex b/lib/backpex/live_resource.ex index ff5d13cdd..0a9270c7a 100644 --- a/lib/backpex/live_resource.ex +++ b/lib/backpex/live_resource.ex @@ -262,8 +262,8 @@ defmodule Backpex.LiveResource do #{NimbleOptions.docs(@options_schema)} """ defmacro __using__(opts) do + # credo:disable-for-next-line Credo.Check.Refactor.LongQuoteBlocks quote bind_quoted: [opts: opts, options_schema: @options_schema] do - @before_compile Backpex.LiveResource @behaviour Backpex.LiveResource @resource_opts NimbleOptions.validate!(opts, options_schema) @@ -320,77 +320,11 @@ defmodule Backpex.LiveResource do @impl Backpex.LiveResource def item_actions(default_actions), do: default_actions - defoverridable can?: 3, - fields: 0, - filters: 0, - filters: 1, - layout: 1, - resource_actions: 0, - item_actions: 1, - index_row_class: 4 - - live_resource = __MODULE__ - - for action <- ~w(Index Form Show)a do - # credo:disable-for-next-line Credo.Check.Warning.UnsafeToAtom - defmodule String.to_atom("#{__MODULE__}.#{action}") do - @resource_opts NimbleOptions.validate!(opts, options_schema) - - use Phoenix.LiveView - - @action_module String.to_existing_atom("Elixir.Backpex.LiveResource.#{action}") - - insert_on_mount_hooks(@resource_opts[:on_mount]) - - def mount(params, session, socket), do: @action_module.mount(params, session, socket, unquote(live_resource)) - def handle_params(params, url, socket), do: @action_module.handle_params(params, url, socket) - def render(assigns), do: @action_module.render(assigns) - def handle_info(msg, socket), do: @action_module.handle_info(msg, socket) - def handle_event(event, params, socket), do: @action_module.handle_event(event, params, socket) - end - end - end - end - - defmacro insert_on_mount_hooks(hooks) do - quote bind_quoted: [hooks: hooks] do - case hooks do - hooks when is_nil(hooks) -> nil - hooks when is_list(hooks) -> for hook <- hooks, do: on_mount(hook) - hook -> on_mount hook - end - end - end - - # credo:disable-for-next-line Credo.Check.Refactor.CyclomaticComplexity - defmacro __before_compile__(_env) do - quote do import Backpex.HTML.Layout import Backpex.HTML.Resource - alias Backpex.LiveResource alias Backpex.Router - @impl Backpex.LiveResource - def panels, do: [] - - @impl Backpex.LiveResource - def metrics, do: [] - - @impl Backpex.LiveResource - def on_item_created(socket, _item), do: socket - - @impl Backpex.LiveResource - def on_item_updated(socket, _item), do: socket - - @impl Backpex.LiveResource - def on_item_deleted(socket, _item), do: socket - - @impl Backpex.LiveResource - def return_to(socket, assigns, _live_action, _form_action, _item) do - Map.get(assigns, :return_to, Router.get_path(socket, assigns.live_resource, assigns.params, :index)) - end - @impl Backpex.LiveResource def render_resource_slot(var!(assigns), :index, :page_title) do ~H""" @@ -511,8 +445,76 @@ defmodule Backpex.LiveResource do @impl Backpex.LiveResource def render_resource_slot(var!(assigns), _action, _position), do: ~H"" + @impl Backpex.LiveResource + def panels, do: [] + + @impl Backpex.LiveResource + def metrics, do: [] + + @impl Backpex.LiveResource + def on_item_created(socket, _item), do: socket + + @impl Backpex.LiveResource + def on_item_updated(socket, _item), do: socket + + @impl Backpex.LiveResource + def on_item_deleted(socket, _item), do: socket + + @impl Backpex.LiveResource + def return_to(socket, assigns, _live_action, _form_action, _item) do + Map.get(assigns, :return_to, Router.get_path(socket, assigns.live_resource, assigns.params, :index)) + end + @impl Backpex.LiveResource def translate({msg, opts}), do: Backpex.translate({msg, opts}) + + defoverridable can?: 3, + fields: 0, + filters: 0, + filters: 1, + layout: 1, + resource_actions: 0, + item_actions: 1, + index_row_class: 4, + render_resource_slot: 3, + panels: 0, + metrics: 0, + on_item_created: 2, + on_item_updated: 2, + on_item_deleted: 2, + return_to: 5, + translate: 1 + + live_resource = __MODULE__ + + for action <- ~w(Index Form Show)a do + # credo:disable-for-next-line Credo.Check.Warning.UnsafeToAtom + defmodule String.to_atom("#{__MODULE__}.#{action}") do + @resource_opts NimbleOptions.validate!(opts, options_schema) + + use Phoenix.LiveView + + @action_module String.to_existing_atom("Elixir.Backpex.LiveResource.#{action}") + + insert_on_mount_hooks(@resource_opts[:on_mount]) + + def mount(params, session, socket), do: @action_module.mount(params, session, socket, unquote(live_resource)) + def handle_params(params, url, socket), do: @action_module.handle_params(params, url, socket) + def render(assigns), do: @action_module.render(assigns) + def handle_info(msg, socket), do: @action_module.handle_info(msg, socket) + def handle_event(event, params, socket), do: @action_module.handle_event(event, params, socket) + end + end + end + end + + defmacro insert_on_mount_hooks(hooks) do + quote bind_quoted: [hooks: hooks] do + case hooks do + hooks when is_nil(hooks) -> nil + hooks when is_list(hooks) -> for hook <- hooks, do: on_mount(hook) + hook -> on_mount hook + end end end From 4100947cf1e76417ad4fbc07ac34769ae786ff86 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Wed, 11 Mar 2026 08:50:14 -0500 Subject: [PATCH 05/11] fix demo app dependency conflict --- demo/mix.exs | 1 + 1 file changed, 1 insertion(+) diff --git a/demo/mix.exs b/demo/mix.exs index 2a4c0aa84..1bfba2a33 100644 --- a/demo/mix.exs +++ b/demo/mix.exs @@ -56,6 +56,7 @@ defmodule Demo.MixProject do {:gettext, "~> 1.0"}, {:sentry, "~> 12.0"}, {:circular_buffer, "~> 1.0.0"}, + {:finch, "~> 0.21"}, # phoenix {:bandit, "~> 1.0"}, From d55d45791368a897aeab4414981ad25bad743a68 Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Wed, 11 Mar 2026 09:32:27 -0500 Subject: [PATCH 06/11] Fix demo app errors --- demo/lib/demo_web/live/film_review_live.ex | 4 ++++ demo/lib/demo_web/live/short_link_live.ex | 4 ++++ demo/lib/demo_web/live/user_live.ex | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/demo/lib/demo_web/live/film_review_live.ex b/demo/lib/demo_web/live/film_review_live.ex index cb08653f0..a62c0b3a5 100644 --- a/demo/lib/demo_web/live/film_review_live.ex +++ b/demo/lib/demo_web/live/film_review_live.ex @@ -27,6 +27,10 @@ defmodule DemoWeb.FilmReviewLive do """ end + def render_resource_slot(assigns, action, position) do + super(assigns, action, position) + end + @impl Backpex.LiveResource def can?(_assigns, :delete, _item), do: false diff --git a/demo/lib/demo_web/live/short_link_live.ex b/demo/lib/demo_web/live/short_link_live.ex index 25341f4cd..6c665e17c 100644 --- a/demo/lib/demo_web/live/short_link_live.ex +++ b/demo/lib/demo_web/live/short_link_live.ex @@ -30,6 +30,10 @@ defmodule DemoWeb.ShortLinkLive do ~p"/admin/short-links" end + def return_to(socket, assigns, live_action, form_action, item) do + super(socket, assigns, live_action, form_action, item) + end + @impl Backpex.LiveResource def fields do [ diff --git a/demo/lib/demo_web/live/user_live.ex b/demo/lib/demo_web/live/user_live.ex index 3dea7f29c..fbb208f3b 100644 --- a/demo/lib/demo_web/live/user_live.ex +++ b/demo/lib/demo_web/live/user_live.ex @@ -40,6 +40,10 @@ defmodule DemoWeb.UserLive do def translate({"Cancel", _opts}), do: "Go back" def translate({"Save", _opts}), do: "Save User" + def translate({msg, opts}) do + super({msg, opts}) + end + @impl Backpex.LiveResource def resource_actions do [ From ae1cd92257bcd2e50ce70a95d6cf4003c687479e Mon Sep 17 00:00:00 2001 From: Mitchell Henke Date: Wed, 11 Mar 2026 09:46:51 -0500 Subject: [PATCH 07/11] Fix demo app macro warnings --- demo/test/support/live_resource_tests.ex | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/demo/test/support/live_resource_tests.ex b/demo/test/support/live_resource_tests.ex index 67274d335..eaad400aa 100644 --- a/demo/test/support/live_resource_tests.ex +++ b/demo/test/support/live_resource_tests.ex @@ -234,7 +234,6 @@ defmodule Demo.Support.LiveResourceTests do item = unquote(item) display_field = unquote(display_field) display_value = unquote(display_value) - success_message = unquote(success_message) result = conn @@ -253,10 +252,12 @@ defmodule Demo.Support.LiveResourceTests do |> assert_path(base_path) |> refute_has("td", text: display_value, exact: true) - if success_message do - result |> assert_has("div", text: success_message, exact: true) - else - result + case unquote(success_message) do + message when is_nil(message) -> + result + + message -> + result |> assert_has("div", text: message, exact: true) end end end @@ -271,7 +272,6 @@ defmodule Demo.Support.LiveResourceTests do item = unquote(item) display_field = unquote(display_field) display_value = unquote(display_value) - success_message = unquote(success_message) result = conn @@ -291,10 +291,12 @@ defmodule Demo.Support.LiveResourceTests do |> assert_path(base_path) |> refute_has("td", text: display_value, exact: true) - if success_message do - result |> assert_has("div", text: success_message, exact: true) - else - result + case unquote(success_message) do + message when is_nil(message) -> + result + + message -> + result |> assert_has("div", text: message, exact: true) end end end From 4416479c96b78f68ecd7c989328d2a78fcb7ea14 Mon Sep 17 00:00:00 2001 From: Florian Arens <60519307+Flo0807@users.noreply.github.com> Date: Fri, 27 Mar 2026 08:12:20 +0100 Subject: [PATCH 08/11] Update demo/test/support/live_resource_tests.ex --- demo/test/support/live_resource_tests.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/test/support/live_resource_tests.ex b/demo/test/support/live_resource_tests.ex index eaad400aa..646598eb3 100644 --- a/demo/test/support/live_resource_tests.ex +++ b/demo/test/support/live_resource_tests.ex @@ -257,7 +257,7 @@ defmodule Demo.Support.LiveResourceTests do result message -> - result |> assert_has("div", text: message, exact: true) + assert_has(result, "div", text: message, exact: true) end end end From ab6ef8b8393d0b4875f6c707ae49538e6d2a5e76 Mon Sep 17 00:00:00 2001 From: Florian Arens <60519307+Flo0807@users.noreply.github.com> Date: Fri, 27 Mar 2026 08:12:25 +0100 Subject: [PATCH 09/11] Update demo/test/support/live_resource_tests.ex --- demo/test/support/live_resource_tests.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/test/support/live_resource_tests.ex b/demo/test/support/live_resource_tests.ex index 646598eb3..c2dd40735 100644 --- a/demo/test/support/live_resource_tests.ex +++ b/demo/test/support/live_resource_tests.ex @@ -296,7 +296,7 @@ defmodule Demo.Support.LiveResourceTests do result message -> - result |> assert_has("div", text: message, exact: true) + assert_has(result, "div", text: message, exact: true) end end end From 6838477cdd63d2cbd06cb9f840bb77d3b0f909df Mon Sep 17 00:00:00 2001 From: Florian Arens <60519307+Flo0807@users.noreply.github.com> Date: Fri, 27 Mar 2026 09:17:22 +0100 Subject: [PATCH 10/11] Use `generated: true` to fix compiler warnings --- demo/lib/demo_web/live/film_review_live.ex | 4 - demo/lib/demo_web/live/short_link_live.ex | 4 - demo/lib/demo_web/live/user_live.ex | 4 - lib/backpex/field.ex | 59 ++++----- lib/backpex/item_actions/item_action.ex | 18 ++- lib/backpex/live_resource.ex | 136 ++++++++++----------- 6 files changed, 101 insertions(+), 124 deletions(-) diff --git a/demo/lib/demo_web/live/film_review_live.ex b/demo/lib/demo_web/live/film_review_live.ex index a62c0b3a5..cb08653f0 100644 --- a/demo/lib/demo_web/live/film_review_live.ex +++ b/demo/lib/demo_web/live/film_review_live.ex @@ -27,10 +27,6 @@ defmodule DemoWeb.FilmReviewLive do """ end - def render_resource_slot(assigns, action, position) do - super(assigns, action, position) - end - @impl Backpex.LiveResource def can?(_assigns, :delete, _item), do: false diff --git a/demo/lib/demo_web/live/short_link_live.ex b/demo/lib/demo_web/live/short_link_live.ex index 6c665e17c..25341f4cd 100644 --- a/demo/lib/demo_web/live/short_link_live.ex +++ b/demo/lib/demo_web/live/short_link_live.ex @@ -30,10 +30,6 @@ defmodule DemoWeb.ShortLinkLive do ~p"/admin/short-links" end - def return_to(socket, assigns, live_action, form_action, item) do - super(socket, assigns, live_action, form_action, item) - end - @impl Backpex.LiveResource def fields do [ diff --git a/demo/lib/demo_web/live/user_live.ex b/demo/lib/demo_web/live/user_live.ex index fbb208f3b..3dea7f29c 100644 --- a/demo/lib/demo_web/live/user_live.ex +++ b/demo/lib/demo_web/live/user_live.ex @@ -40,10 +40,6 @@ defmodule DemoWeb.UserLive do def translate({"Cancel", _opts}), do: "Go back" def translate({"Save", _opts}), do: "Save User" - def translate({msg, opts}) do - super({msg, opts}) - end - @impl Backpex.LiveResource def resource_actions do [ diff --git a/lib/backpex/field.ex b/lib/backpex/field.ex index b155000f6..2e549be99 100644 --- a/lib/backpex/field.ex +++ b/lib/backpex/field.ex @@ -232,38 +232,6 @@ defmodule Backpex.Field do use BackpexWeb, :field - import Ecto.Query - - @impl Backpex.Field - def display_field({name, _field_options} = _field), do: name - - @impl Backpex.Field - def schema(_field, schema), do: schema - - @impl Backpex.Field - def association?(_field), do: false - - @impl Backpex.Field - def assign_uploads(_field, socket), do: socket - - @impl Backpex.Field - def search_condition(schema_name, field_name, search_string) do - dynamic( - [{^schema_name, schema_name}], - schema_name |> field(^field_name) |> ilike(^search_string) - ) - end - - @impl Backpex.Field - def before_changeset(changeset, _attrs, _metadata, _repo, _field, _assigns), do: changeset - - defoverridable display_field: 1, - schema: 2, - association?: 1, - assign_uploads: 2, - search_condition: 3, - before_changeset: 6 - @doc """ Returns the schema of configurable options for this field. @@ -291,7 +259,9 @@ defmodule Backpex.Field do end defmacro __before_compile__(_env) do - quote do + quote generated: true do + import Ecto.Query + @impl Phoenix.LiveComponent def render(%{type: :index} = assigns) do if Backpex.Field.index_editable_enabled?(assigns.field_options, assigns) do @@ -311,6 +281,29 @@ defmodule Backpex.Field do nil -> apply(__MODULE__, :render_form, [assigns]) end end + + @impl Backpex.Field + def display_field({name, _field_options} = _field), do: name + + @impl Backpex.Field + def schema(_field, schema), do: schema + + @impl Backpex.Field + def association?(_field), do: false + + @impl Backpex.Field + def assign_uploads(_field, socket), do: socket + + @impl Backpex.Field + def search_condition(schema_name, field_name, search_string) do + dynamic( + [{^schema_name, schema_name}], + schema_name |> field(^field_name) |> ilike(^search_string) + ) + end + + @impl Backpex.Field + def before_changeset(changeset, _attrs, _metadata, _repo, _field, _assigns), do: changeset end end diff --git a/lib/backpex/item_actions/item_action.ex b/lib/backpex/item_actions/item_action.ex index 4ea6b2517..06b6eedd9 100644 --- a/lib/backpex/item_actions/item_action.ex +++ b/lib/backpex/item_actions/item_action.ex @@ -111,6 +111,14 @@ defmodule Backpex.ItemAction do @behaviour Backpex.ItemAction require Backpex + end + end + + defmacro __before_compile__(env) do + validate_handle_or_link!(env) + + quote generated: true do + @after_compile Backpex.ItemAction @impl Backpex.ItemAction def confirm_label(assigns), do: Backpex.__("Apply", assigns.live_resource) @@ -127,16 +135,6 @@ defmodule Backpex.ItemAction do {%{}, types} end - - defoverridable confirm_label: 1, cancel_label: 1, fields: 0, base_schema: 1 - end - end - - defmacro __before_compile__(env) do - validate_handle_or_link!(env) - - quote do - @after_compile Backpex.ItemAction end end diff --git a/lib/backpex/live_resource.ex b/lib/backpex/live_resource.ex index 0a9270c7a..1be692652 100644 --- a/lib/backpex/live_resource.ex +++ b/lib/backpex/live_resource.ex @@ -262,8 +262,8 @@ defmodule Backpex.LiveResource do #{NimbleOptions.docs(@options_schema)} """ defmacro __using__(opts) do - # credo:disable-for-next-line Credo.Check.Refactor.LongQuoteBlocks quote bind_quoted: [opts: opts, options_schema: @options_schema] do + @before_compile Backpex.LiveResource @behaviour Backpex.LiveResource @resource_opts NimbleOptions.validate!(opts, options_schema) @@ -320,11 +320,77 @@ defmodule Backpex.LiveResource do @impl Backpex.LiveResource def item_actions(default_actions), do: default_actions + defoverridable can?: 3, + fields: 0, + filters: 0, + filters: 1, + layout: 1, + resource_actions: 0, + item_actions: 1, + index_row_class: 4 + + live_resource = __MODULE__ + + for action <- ~w(Index Form Show)a do + # credo:disable-for-next-line Credo.Check.Warning.UnsafeToAtom + defmodule String.to_atom("#{__MODULE__}.#{action}") do + @resource_opts NimbleOptions.validate!(opts, options_schema) + + use Phoenix.LiveView + + @action_module String.to_existing_atom("Elixir.Backpex.LiveResource.#{action}") + + insert_on_mount_hooks(@resource_opts[:on_mount]) + + def mount(params, session, socket), do: @action_module.mount(params, session, socket, unquote(live_resource)) + def handle_params(params, url, socket), do: @action_module.handle_params(params, url, socket) + def render(assigns), do: @action_module.render(assigns) + def handle_info(msg, socket), do: @action_module.handle_info(msg, socket) + def handle_event(event, params, socket), do: @action_module.handle_event(event, params, socket) + end + end + end + end + + defmacro insert_on_mount_hooks(hooks) do + quote bind_quoted: [hooks: hooks] do + case hooks do + hooks when is_nil(hooks) -> nil + hooks when is_list(hooks) -> for hook <- hooks, do: on_mount(hook) + hook -> on_mount hook + end + end + end + + # credo:disable-for-next-line Credo.Check.Refactor.CyclomaticComplexity + defmacro __before_compile__(_env) do + quote generated: true do import Backpex.HTML.Layout import Backpex.HTML.Resource + alias Backpex.LiveResource alias Backpex.Router + @impl Backpex.LiveResource + def panels, do: [] + + @impl Backpex.LiveResource + def metrics, do: [] + + @impl Backpex.LiveResource + def on_item_created(socket, _item), do: socket + + @impl Backpex.LiveResource + def on_item_updated(socket, _item), do: socket + + @impl Backpex.LiveResource + def on_item_deleted(socket, _item), do: socket + + @impl Backpex.LiveResource + def return_to(socket, assigns, _live_action, _form_action, _item) do + Map.get(assigns, :return_to, Router.get_path(socket, assigns.live_resource, assigns.params, :index)) + end + @impl Backpex.LiveResource def render_resource_slot(var!(assigns), :index, :page_title) do ~H""" @@ -445,76 +511,8 @@ defmodule Backpex.LiveResource do @impl Backpex.LiveResource def render_resource_slot(var!(assigns), _action, _position), do: ~H"" - @impl Backpex.LiveResource - def panels, do: [] - - @impl Backpex.LiveResource - def metrics, do: [] - - @impl Backpex.LiveResource - def on_item_created(socket, _item), do: socket - - @impl Backpex.LiveResource - def on_item_updated(socket, _item), do: socket - - @impl Backpex.LiveResource - def on_item_deleted(socket, _item), do: socket - - @impl Backpex.LiveResource - def return_to(socket, assigns, _live_action, _form_action, _item) do - Map.get(assigns, :return_to, Router.get_path(socket, assigns.live_resource, assigns.params, :index)) - end - @impl Backpex.LiveResource def translate({msg, opts}), do: Backpex.translate({msg, opts}) - - defoverridable can?: 3, - fields: 0, - filters: 0, - filters: 1, - layout: 1, - resource_actions: 0, - item_actions: 1, - index_row_class: 4, - render_resource_slot: 3, - panels: 0, - metrics: 0, - on_item_created: 2, - on_item_updated: 2, - on_item_deleted: 2, - return_to: 5, - translate: 1 - - live_resource = __MODULE__ - - for action <- ~w(Index Form Show)a do - # credo:disable-for-next-line Credo.Check.Warning.UnsafeToAtom - defmodule String.to_atom("#{__MODULE__}.#{action}") do - @resource_opts NimbleOptions.validate!(opts, options_schema) - - use Phoenix.LiveView - - @action_module String.to_existing_atom("Elixir.Backpex.LiveResource.#{action}") - - insert_on_mount_hooks(@resource_opts[:on_mount]) - - def mount(params, session, socket), do: @action_module.mount(params, session, socket, unquote(live_resource)) - def handle_params(params, url, socket), do: @action_module.handle_params(params, url, socket) - def render(assigns), do: @action_module.render(assigns) - def handle_info(msg, socket), do: @action_module.handle_info(msg, socket) - def handle_event(event, params, socket), do: @action_module.handle_event(event, params, socket) - end - end - end - end - - defmacro insert_on_mount_hooks(hooks) do - quote bind_quoted: [hooks: hooks] do - case hooks do - hooks when is_nil(hooks) -> nil - hooks when is_list(hooks) -> for hook <- hooks, do: on_mount(hook) - hook -> on_mount hook - end end end From 8823643d2f04c3becb803327f1598e9e7683e542 Mon Sep 17 00:00:00 2001 From: Florian Arens <60519307+Flo0807@users.noreply.github.com> Date: Fri, 27 Mar 2026 09:30:11 +0100 Subject: [PATCH 11/11] Remove finch from demo --- demo/mix.exs | 1 - 1 file changed, 1 deletion(-) diff --git a/demo/mix.exs b/demo/mix.exs index 1bfba2a33..2a4c0aa84 100644 --- a/demo/mix.exs +++ b/demo/mix.exs @@ -56,7 +56,6 @@ defmodule Demo.MixProject do {:gettext, "~> 1.0"}, {:sentry, "~> 12.0"}, {:circular_buffer, "~> 1.0.0"}, - {:finch, "~> 0.21"}, # phoenix {:bandit, "~> 1.0"},