From f807a14aa75f4c77fa94c99c909c6dbd4cb2e6bd Mon Sep 17 00:00:00 2001 From: Tobias Pfeiffer Date: Sun, 3 Nov 2024 15:57:48 +0100 Subject: [PATCH] Transition to mainline `.inputs_for` code https://hexdocs.pm/phoenix_live_view/1.0.0-rc.7/Phoenix.Component.html#inputs_for/1 * makes a lot of code unnecessary * same time, the tests don't seem to be working any more, which isn't great and I have no idea how to really resolve --- .../brainstormings/brainstorming.ex | 14 +++- lib/mindwendel/brainstormings/idea_label.ex | 5 -- .../brainstormings/idea_label_factory.ex | 27 ------ .../live/admin/brainstorming_live/edit.ex | 82 +------------------ .../admin/brainstorming_live/edit.html.heex | 18 +++- .../admin/brainstorming_live/edit_test.exs | 10 +-- 6 files changed, 34 insertions(+), 122 deletions(-) delete mode 100644 lib/mindwendel/brainstormings/idea_label_factory.ex diff --git a/lib/mindwendel/brainstormings/brainstorming.ex b/lib/mindwendel/brainstormings/brainstorming.ex index 80ee5152..f8eab963 100644 --- a/lib/mindwendel/brainstormings/brainstorming.ex +++ b/lib/mindwendel/brainstormings/brainstorming.ex @@ -23,7 +23,7 @@ defmodule Mindwendel.Brainstormings.Brainstorming do belongs_to :creating_user, User has_many :ideas, Idea has_many :lanes, Lane, preload_order: [asc: :position_order] - has_many :labels, IdeaLabel + has_many :labels, IdeaLabel, on_replace: :delete many_to_many :users, User, join_through: BrainstormingUser many_to_many :moderating_users, User, join_through: BrainstormingModeratingUser @@ -40,11 +40,21 @@ defmodule Mindwendel.Brainstormings.Brainstorming do :filter_labels_ids ]) |> validate_required([:name]) - |> cast_assoc(:labels) + |> cast_assoc(:labels, + with: &child_label_changeset/3, + drop_param: :labels_drop, + sort_param: :labels_sort + ) |> shorten_name |> gen_admin_url_id(brainstorming) end + defp child_label_changeset(child, changes, position) do + child + |> change(position_order: position) + |> IdeaLabel.changeset(changes) + end + def changeset_with_upated_last_accessed_at(brainstorming) do brainstorming |> change(%{last_accessed_at: DateTime.truncate(DateTime.utc_now(), :second)}) diff --git a/lib/mindwendel/brainstormings/idea_label.ex b/lib/mindwendel/brainstormings/idea_label.ex index a62c9766..774f3251 100644 --- a/lib/mindwendel/brainstormings/idea_label.ex +++ b/lib/mindwendel/brainstormings/idea_label.ex @@ -23,11 +23,6 @@ defmodule Mindwendel.Brainstormings.IdeaLabel do def changeset(idea_label, params \\ %{}) - def changeset(idea_label, %{delete: true}) do - %{Ecto.Changeset.change(idea_label, delete: true) | action: :delete} - |> no_assoc_constraint(:idea_idea_labels, message: "idea label associated with idea") - end - def changeset(idea_label, params) do idea_label |> cast(params, [:name, :color]) diff --git a/lib/mindwendel/brainstormings/idea_label_factory.ex b/lib/mindwendel/brainstormings/idea_label_factory.ex deleted file mode 100644 index b0ed5dfc..00000000 --- a/lib/mindwendel/brainstormings/idea_label_factory.ex +++ /dev/null @@ -1,27 +0,0 @@ -defmodule Mindwendel.Brainstormings.IdeaLabelFactory do - alias Mindwendel.Brainstormings.Brainstorming - - def build_idea_label(list) when is_list(list) do - rem( - length(list), - length(idea_label_variants()) - ) - |> idea_label_variant() - end - - def build_idea_label(%Brainstorming{labels: brainstorming_labels}) do - build_idea_label(brainstorming_labels) - end - - def build_idea_label(nil) do - idea_label_variant(0) - end - - def idea_label_variant(variant_number) when is_integer(variant_number) do - Enum.at(idea_label_variants(), variant_number) - end - - def idea_label_variants do - Brainstorming.idea_label_factory() - end -end diff --git a/lib/mindwendel_web/live/admin/brainstorming_live/edit.ex b/lib/mindwendel_web/live/admin/brainstorming_live/edit.ex index 3f3f9bb3..8529246f 100644 --- a/lib/mindwendel_web/live/admin/brainstorming_live/edit.ex +++ b/lib/mindwendel_web/live/admin/brainstorming_live/edit.ex @@ -3,7 +3,6 @@ defmodule MindwendelWeb.Admin.BrainstormingLive.Edit do alias Mindwendel.Brainstormings alias Mindwendel.Brainstormings.Brainstorming - alias Mindwendel.Brainstormings.IdeaLabelFactory alias Mindwendel.Brainstormings.IdeaLabel alias Mindwendel.Repo @@ -43,6 +42,7 @@ defmodule MindwendelWeb.Admin.BrainstormingLive.Edit do do: {:noreply, assign(socket, uri: URI.parse(uri))} def handle_event("save", %{"brainstorming" => brainstorming_params}, socket) do + # why aren't we taking this from the socket? brainstorming = Brainstormings.get_brainstorming_by!(%{ admin_url_id: socket.assigns.brainstorming.admin_url_id @@ -76,85 +76,6 @@ defmodule MindwendelWeb.Admin.BrainstormingLive.Edit do end end - def handle_event("add_idea_label", _params, socket) do - brainstorming = socket.assigns.brainstorming - - idea_label_new = IdeaLabelFactory.build_idea_label(brainstorming) - - brainstorming_labels = - (brainstorming.labels ++ - [ - %{ - idea_label_new - | position_order: length(brainstorming.labels) + 1 - } - ]) - |> Enum.map(&Map.from_struct/1) - - case Brainstormings.update_brainstorming(brainstorming, %{labels: brainstorming_labels}) do - {:ok, brainstorming} -> - reset_changeset_timer_ref = reset_changeset_timer(socket) - - { - :noreply, - socket - |> assign(:brainstorming, brainstorming) - |> assign(:form, to_form(Brainstorming.changeset(brainstorming, %{}))) - |> assign(:reset_changeset_timer_ref, reset_changeset_timer_ref) - |> clear_flash() - } - - {:error, changeset} -> - cancel_changeset_timer(socket) - - { - :noreply, - socket - |> assign(form: to_form(changeset)) - |> put_flash(:error, gettext("Your brainstorming was not saved.")) - } - end - end - - def handle_event("remove_idea_label", %{"value" => idea_label_id}, socket) do - brainstorming = socket.assigns.brainstorming - - brainstorming_labels = - brainstorming.labels - |> Enum.map(fn label -> - if label.id == idea_label_id do - %{label | delete: true} - else - label - end - end) - |> Enum.map(&Map.from_struct/1) - - case Brainstormings.update_brainstorming(brainstorming, %{labels: brainstorming_labels}) do - {:ok, brainstorming} -> - reset_changeset_timer_ref = reset_changeset_timer(socket) - - { - :noreply, - socket - |> assign(:brainstorming, brainstorming) - |> assign(:form, to_form(Brainstorming.changeset(brainstorming, %{}))) - |> assign(:reset_changeset_timer_ref, reset_changeset_timer_ref) - |> clear_flash() - } - - {:error, changeset} -> - cancel_changeset_timer(socket) - - { - :noreply, - socket - |> assign(form: to_form(changeset)) - |> put_flash(:error, gettext("Your brainstorming was not saved.")) - } - end - end - def handle_event("empty", %{"value" => brainstorming_admin_url_id}, socket) when brainstorming_admin_url_id == socket.assigns.brainstorming.admin_url_id do brainstorming = socket.assigns.brainstorming @@ -164,6 +85,7 @@ defmodule MindwendelWeb.Admin.BrainstormingLive.Edit do {:noreply, push_navigate(socket, to: ~p"/brainstormings/#{brainstorming.id}")} end + # what is this timer? Maybe this should be FE only? defp cancel_changeset_timer(socket) do if socket.assigns[:reset_changeset_timer_ref], do: Process.cancel_timer(socket.assigns.reset_changeset_timer_ref) diff --git a/lib/mindwendel_web/live/admin/brainstorming_live/edit.html.heex b/lib/mindwendel_web/live/admin/brainstorming_live/edit.html.heex index b2646fe8..2eecd910 100644 --- a/lib/mindwendel_web/live/admin/brainstorming_live/edit.html.heex +++ b/lib/mindwendel_web/live/admin/brainstorming_live/edit.html.heex @@ -95,6 +95,7 @@
<.inputs_for :let={f_label} field={@form[:labels]}>
+ <.input type="color" field={f_label[:color]} @@ -108,24 +109,35 @@ field={f_label[:name]} placeholder={gettext("Type the label name")} /> + <.button type="button" - phx-click="remove_idea_label" - value={f_label.data.id} class="btn-outline-secondary" + name="brainstorming[labels_drop][]" + value={f_label.index} + phx-click={JS.dispatch("change")} > <%= gettext("Remove idea label") %> + <.error :for={msg <- Enum.map(f_label[:name].errors, &translate_error(&1))}> <%= msg %>
+ +
- <.button type="button" class="btn btn-secondary" phx-click="add_idea_label"> + <.button + type="button" + class="btn btn-secondary" + name="brainstorming[labels_sort][]" + value="new" + phx-click={JS.dispatch("change")} + > <%= gettext("Add idea label") %>
diff --git a/test/mindwendel_web/live/admin/brainstorming_live/edit_test.exs b/test/mindwendel_web/live/admin/brainstorming_live/edit_test.exs index 2b2d037c..3becf72f 100644 --- a/test/mindwendel_web/live/admin/brainstorming_live/edit_test.exs +++ b/test/mindwendel_web/live/admin/brainstorming_live/edit_test.exs @@ -101,16 +101,16 @@ defmodule MindwendelWeb.Admin.BrainstormingLive.EditTest do {:ok, edit_live_view, _html} = live(conn, ~p"/admin/brainstormings/#{brainstorming.admin_url_id}/edit") - brainstorming_label_first = Enum.at(brainstorming.labels, 0) + brainstorming_label_first = List.first(brainstorming.labels) edit_live_view - |> element("button[value=\"#{brainstorming_label_first.id}\"]", "Remove") + |> element(html_selector_remove_idea_label_button(brainstorming_label_first), "Remove") |> render_click() assert edit_live_view |> element("input#brainstorming_labels_0_name") |> has_element? refute edit_live_view - |> element("button[value=#{brainstorming_label_first.id}]", "Remove") + |> element("input[value=#{brainstorming_label_first.name}]") |> has_element? refute edit_live_view |> element("input#brainstorming_labels_4_name") |> has_element? @@ -120,7 +120,7 @@ defmodule MindwendelWeb.Admin.BrainstormingLive.EditTest do conn: conn, brainstorming: brainstorming } do - brainstorming_label_first = Enum.at(brainstorming.labels, 0) + brainstorming_label_first = List.first(brainstorming.labels) _idea = Factory.insert!(:idea, @@ -179,6 +179,6 @@ defmodule MindwendelWeb.Admin.BrainstormingLive.EditTest do end defp html_selector_remove_idea_label_button(idea_label) do - "button[value=\"#{idea_label.id}\"]" + "button[value=\"#{idea_label.position_order}\"]" end end