diff --git a/lib/mindwendel/brainstormings.ex b/lib/mindwendel/brainstormings.ex
index 3a1bb74b..3d941be6 100644
--- a/lib/mindwendel/brainstormings.ex
+++ b/lib/mindwendel/brainstormings.ex
@@ -98,6 +98,10 @@ defmodule Mindwendel.Brainstormings do
end
end
+ def get_bare_brainstorming!(id) do
+ Repo.get!(Brainstorming, id)
+ end
+
@doc """
Gets a single brainstorming with the admin url id
"""
diff --git a/lib/mindwendel/brainstormings/idea_idea_label.ex b/lib/mindwendel/brainstormings/idea_idea_label.ex
index ccb2bdf7..865ffadb 100644
--- a/lib/mindwendel/brainstormings/idea_idea_label.ex
+++ b/lib/mindwendel/brainstormings/idea_idea_label.ex
@@ -24,4 +24,13 @@ defmodule Mindwendel.Brainstormings.IdeaIdeaLabel do
name: :idea_idea_labels_idea_id_idea_label_id_index
)
end
+
+ def bare_creation_changeset(idea_idea_label \\ %__MODULE__{}, attrs) do
+ idea_idea_label
+ |> cast(attrs, [:idea_id, :idea_label_id])
+ |> validate_required([:idea_id, :idea_label_id])
+ |> unique_constraint([:idea_id, :idea_label_id],
+ name: :idea_idea_labels_idea_id_idea_label_id_index
+ )
+ end
end
diff --git a/lib/mindwendel/idea_labels.ex b/lib/mindwendel/idea_labels.ex
index 5e85f546..be4f479d 100644
--- a/lib/mindwendel/idea_labels.ex
+++ b/lib/mindwendel/idea_labels.ex
@@ -28,29 +28,24 @@ defmodule Mindwendel.IdeaLabels do
nil
end
- def add_idea_label_to_idea(%Idea{} = idea, %IdeaLabel{} = idea_label) do
- idea = Repo.preload(idea, :idea_labels)
-
- idea_labels =
- (idea.idea_labels ++ [idea_label])
- |> Enum.map(&Ecto.Changeset.change/1)
-
+ # As the broadcast results in a full reload of the ideas, we don't need to actually update
+ # the idea struct, a new association is enough
+ def add_idea_label_to_idea(idea, idea_label_id) do
result =
- idea
- |> Ecto.Changeset.change()
- |> Ecto.Changeset.put_assoc(:idea_labels, idea_labels)
- |> Repo.update()
+ %{idea_id: idea.id, idea_label_id: idea_label_id}
+ |> IdeaIdeaLabel.bare_creation_changeset()
+ |> Repo.insert()
Lanes.broadcast_lanes_update(idea.brainstorming_id)
result
end
- def remove_idea_label_from_idea(%Idea{} = idea, %IdeaLabel{} = idea_label) do
+ def remove_idea_label_from_idea(%Idea{} = idea, idea_label_id) do
result =
from(idea_idea_label in IdeaIdeaLabel,
where:
idea_idea_label.idea_id == ^idea.id and
- idea_idea_label.idea_label_id == ^idea_label.id
+ idea_idea_label.idea_label_id == ^idea_label_id
)
|> Repo.delete_all()
diff --git a/lib/mindwendel/lanes.ex b/lib/mindwendel/lanes.ex
index b1b35d14..8121cdd1 100644
--- a/lib/mindwendel/lanes.ex
+++ b/lib/mindwendel/lanes.ex
@@ -72,10 +72,7 @@ defmodule Mindwendel.Lanes do
def get_lanes_for_brainstorming_with_labels_filtered(id) do
{:ok, brainstorming} = Brainstormings.get_brainstorming(id)
- filter_label =
- if length(brainstorming.filter_labels_ids) > 0,
- do: %{filter_labels_ids: brainstorming.filter_labels_ids},
- else: %{}
+ filter_label = %{filter_labels_ids: brainstorming.filter_labels_ids}
get_lanes_for_brainstorming(id, filter_label)
end
@@ -89,7 +86,7 @@ defmodule Mindwendel.Lanes do
[%Lane{}, ...]
"""
- def get_lanes_for_brainstorming(id, filters \\ %{}) do
+ def get_lanes_for_brainstorming(id, filters \\ %{filter_labels_ids: []}) do
lane_query =
from lane in Lane,
where: lane.brainstorming_id == ^id,
@@ -105,6 +102,10 @@ defmodule Mindwendel.Lanes do
|> Repo.preload(ideas: {ideas_advanced_query, [:link, :likes, :idea_labels, :files]})
end
+ defp build_ideas_query_with_filter(%{filter_labels_ids: []}) do
+ from(idea in Idea)
+ end
+
defp build_ideas_query_with_filter(%{filter_labels_ids: filter_labels_ids}) do
distinct_ideas =
from idea in Idea,
@@ -118,10 +119,6 @@ defmodule Mindwendel.Lanes do
)
end
- defp build_ideas_query_with_filter(%{} = _filters) do
- from(idea in Idea)
- end
-
@doc """
Creates a lane.
diff --git a/lib/mindwendel/repo.ex b/lib/mindwendel/repo.ex
index a26ea71d..622ddd21 100644
--- a/lib/mindwendel/repo.ex
+++ b/lib/mindwendel/repo.ex
@@ -2,4 +2,8 @@ defmodule Mindwendel.Repo do
use Ecto.Repo,
otp_app: :mindwendel,
adapter: Ecto.Adapters.Postgres
+
+ def count(query) do
+ aggregate(query, :count)
+ end
end
diff --git a/lib/mindwendel_web/live/idea_live/card_component.ex b/lib/mindwendel_web/live/idea_live/card_component.ex
index 9a3c1b55..8f934c7c 100644
--- a/lib/mindwendel_web/live/idea_live/card_component.ex
+++ b/lib/mindwendel_web/live/idea_live/card_component.ex
@@ -6,8 +6,8 @@ defmodule MindwendelWeb.IdeaLive.CardComponent do
alias Mindwendel.Likes
@impl true
- def handle_event("delete_idea", %{"id" => id}, socket) do
- idea = Ideas.get_idea!(id)
+ def handle_event("delete_idea", _params, socket) do
+ idea = socket.assigns.idea
%{current_user: current_user, brainstorming: brainstorming} = socket.assigns
@@ -19,14 +19,14 @@ defmodule MindwendelWeb.IdeaLive.CardComponent do
{:noreply, socket}
end
- def handle_event("like", %{"id" => id}, socket) do
- Likes.add_like(id, socket.assigns.current_user.id)
+ def handle_event("like", _params, socket) do
+ Likes.add_like(socket.assigns.idea.id, socket.assigns.current_user.id)
{:noreply, socket}
end
- def handle_event("unlike", %{"id" => id}, socket) do
- Likes.delete_like(id, socket.assigns.current_user.id)
+ def handle_event("unlike", _params, socket) do
+ Likes.delete_like(socket.assigns.idea.id, socket.assigns.current_user.id)
{:noreply, socket}
end
@@ -34,35 +34,22 @@ defmodule MindwendelWeb.IdeaLive.CardComponent do
def handle_event(
"add_idea_label_to_idea",
%{
- "idea-id" => idea_id,
"idea-label-id" => idea_label_id
},
socket
) do
- idea = Ideas.get_idea!(idea_id)
- idea_label = IdeaLabels.get_idea_label(idea_label_id)
-
- case(IdeaLabels.add_idea_label_to_idea(idea, idea_label)) do
- {:ok, _idea} ->
- {:noreply, socket}
-
- {:error, _changeset} ->
- {:noreply, socket}
- end
+ IdeaLabels.add_idea_label_to_idea(socket.assigns.idea, idea_label_id)
+ {:noreply, socket}
end
def handle_event(
"remove_idea_label_from_idea",
%{
- "idea-id" => idea_id,
"idea-label-id" => idea_label_id
},
socket
) do
- idea = Ideas.get_idea!(idea_id)
- idea_label = IdeaLabels.get_idea_label(idea_label_id)
-
- IdeaLabels.remove_idea_label_from_idea(idea, idea_label)
+ IdeaLabels.remove_idea_label_from_idea(socket.assigns.idea, idea_label_id)
{:noreply, socket}
end
end
diff --git a/lib/mindwendel_web/live/idea_live/card_component.html.heex b/lib/mindwendel_web/live/idea_live/card_component.html.heex
index 07a84bee..ad3811a8 100644
--- a/lib/mindwendel_web/live/idea_live/card_component.html.heex
+++ b/lib/mindwendel_web/live/idea_live/card_component.html.heex
@@ -13,7 +13,6 @@
class="float-end ms-3 mb-3"
phx-click="delete_idea"
phx-target={@myself}
- phx-value-id={@idea.id}
title={gettext("Delete idea")}
data-confirm={gettext("Are you sure you want to delete this idea?")}
>
@@ -97,7 +96,6 @@
data-testid={brainstorming_idea_label.id}
phx-click="add_idea_label_to_idea"
phx-target={@myself}
- phx-value-idea-id={@idea.id}
title={"Label #{brainstorming_idea_label.name}"}
phx-value-idea-label-id={brainstorming_idea_label.id}
>
@@ -116,7 +114,6 @@
data-testid={brainstorming_idea_label.id}
phx-click="remove_idea_label_from_idea"
phx-target={@myself}
- phx-value-idea-id={@idea.id}
title={"Label #{brainstorming_idea_label.name}"}
phx-value-idea-label-id={brainstorming_idea_label.id}
>
@@ -145,11 +142,11 @@
{length(@idea.likes)}
<%= if Mindwendel.Likes.exists_user_in_likes?(@idea.likes, @current_user.id) do %>
- <.link phx-click="unlike" phx-target={@myself} phx-value-id={@idea.id} title="Unlike">
+ <.link phx-click="unlike" phx-target={@myself} title="Unlike">
<% else %>
- <.link phx-click="like" phx-target={@myself} phx-value-id={@idea.id} title="Like">
+ <.link phx-click="like" phx-target={@myself} title="Like">
<% end %>
diff --git a/priv/gettext/default.pot b/priv/gettext/default.pot
index a8d6e46d..9e168660 100644
--- a/priv/gettext/default.pot
+++ b/priv/gettext/default.pot
@@ -36,7 +36,7 @@ msgid "%{name} - New Idea"
msgstr ""
#: lib/mindwendel_web/live/comment_live/show_component.html.heex:22
-#: lib/mindwendel_web/live/idea_live/card_component.html.heex:18
+#: lib/mindwendel_web/live/idea_live/card_component.html.heex:17
#, elixir-autogen, elixir-format
msgid "Are you sure you want to delete this idea?"
msgstr ""
@@ -195,7 +195,7 @@ msgstr ""
#: lib/mindwendel_web/controllers/admin/brainstorming_html/export.html.heex:3
#: lib/mindwendel_web/live/comment_live/show_component.html.heex:40
-#: lib/mindwendel_web/live/idea_live/card_component.html.heex:85
+#: lib/mindwendel_web/live/idea_live/card_component.html.heex:84
#, elixir-autogen, elixir-format
msgid "By"
msgstr ""
@@ -451,13 +451,13 @@ msgstr ""
msgid "No lanes available"
msgstr ""
-#: lib/mindwendel_web/live/idea_live/card_component.html.heex:25
+#: lib/mindwendel_web/live/idea_live/card_component.html.heex:24
#, elixir-autogen, elixir-format
msgid "Edit idea"
msgstr ""
#: lib/mindwendel_web/live/comment_live/show_component.html.heex:30
-#: lib/mindwendel_web/live/idea_live/card_component.html.heex:17
+#: lib/mindwendel_web/live/idea_live/card_component.html.heex:16
#, elixir-autogen, elixir-format
msgid "Delete idea"
msgstr ""
@@ -472,7 +472,7 @@ msgstr ""
msgid "Additional Attachment"
msgstr ""
-#: lib/mindwendel_web/live/idea_live/card_component.html.heex:75
+#: lib/mindwendel_web/live/idea_live/card_component.html.heex:74
#: lib/mindwendel_web/live/idea_live/form_component.html.heex:43
#: lib/mindwendel_web/live/idea_live/show_component.html.heex:27
#, elixir-autogen, elixir-format
@@ -529,8 +529,8 @@ msgstr ""
msgid "No comments available"
msgstr ""
-#: lib/mindwendel_web/live/idea_live/card_component.html.heex:33
-#: lib/mindwendel_web/live/idea_live/card_component.html.heex:140
+#: lib/mindwendel_web/live/idea_live/card_component.html.heex:32
+#: lib/mindwendel_web/live/idea_live/card_component.html.heex:137
#, elixir-autogen, elixir-format
msgid "Show idea"
msgstr ""
diff --git a/test/mindwendel/brainstormings_test.exs b/test/mindwendel/brainstormings_test.exs
index 16772359..174eacef 100644
--- a/test/mindwendel/brainstormings_test.exs
+++ b/test/mindwendel/brainstormings_test.exs
@@ -322,8 +322,8 @@ defmodule Mindwendel.BrainstormingsTest do
like = Factory.insert!(:like, idea: idea)
- {:ok, idea} =
- IdeaLabels.add_idea_label_to_idea(idea, Enum.at(brainstorming.labels, 0))
+ {:ok, _idea_idea_label} =
+ IdeaLabels.add_idea_label_to_idea(idea, Enum.at(brainstorming.labels, 0).id)
idea = idea |> Repo.preload([:idea_labels])
diff --git a/test/mindwendel/idea_labels_test.exs b/test/mindwendel/idea_labels_test.exs
index 83991037..075cefe5 100644
--- a/test/mindwendel/idea_labels_test.exs
+++ b/test/mindwendel/idea_labels_test.exs
@@ -9,7 +9,7 @@ defmodule Mindwendel.IdeaLabelsTest do
setup do
brainstorming = Factory.insert!(:brainstorming, %{labels: [Factory.build(:idea_label)]})
- idea_label = brainstorming.labels |> Enum.at(0)
+ [idea_label] = brainstorming.labels
lane = Enum.at(brainstorming.lanes, 0)
idea = Factory.insert!(:idea, %{brainstorming: brainstorming, lane: lane})
@@ -18,16 +18,16 @@ defmodule Mindwendel.IdeaLabelsTest do
describe "#add_idea_label_to_idea" do
test "adds IdeaLabel to Idea", %{idea_label: idea_label, idea: idea} do
- {:ok, idea_changed} = IdeaLabels.add_idea_label_to_idea(idea, idea_label)
+ {:ok, _idea_idea_label} = IdeaLabels.add_idea_label_to_idea(idea, idea_label.id)
- assert idea_changed.idea_labels |> Enum.count() == 1
- assert Repo.all(IdeaIdeaLabel) |> Enum.count() == 1
+ assert [idea_label] == labels_of(idea)
+ assert Repo.count(IdeaIdeaLabel) == 1
end
test "creates one IdeaIdeaLabel", %{idea_label: idea_label, idea: idea} do
- {:ok, _idea_changed} = IdeaLabels.add_idea_label_to_idea(idea, idea_label)
+ {:ok, _idea_idea_label} = IdeaLabels.add_idea_label_to_idea(idea, idea_label.id)
- assert Repo.all(IdeaIdeaLabel) |> Enum.count() == 1
+ assert Repo.count(IdeaIdeaLabel) == 1
idea_idea_label = Repo.one(IdeaIdeaLabel)
assert idea_idea_label.idea_label_id == idea_label.id
@@ -35,26 +35,29 @@ defmodule Mindwendel.IdeaLabelsTest do
end
test "does not create additional IdeaLabel", %{idea_label: idea_label, idea: idea} do
- assert Repo.all(IdeaLabel) |> Enum.count() == 1
+ assert Repo.count(IdeaLabel) == 1
- {:ok, _idea_changed} = IdeaLabels.add_idea_label_to_idea(idea, idea_label)
+ {:ok, _idea_idea_label} = IdeaLabels.add_idea_label_to_idea(idea, idea_label.id)
- assert Repo.all(IdeaLabel) |> Enum.count() == 1
+ assert Repo.count(IdeaLabel) == 1
assert Repo.one(IdeaLabel) == idea_label
end
@tag :skip
test "does not add the same IdeaLabel twice to Idea", %{idea_label: idea_label, idea: idea} do
# Calling this method twice does not fail and does not create duplicates
- {:ok, idea_after_method_call_1} = IdeaLabels.add_idea_label_to_idea(idea, idea_label)
- {:ok, idea_after_method_call_2} = IdeaLabels.add_idea_label_to_idea(idea, idea_label)
+ {:ok, idea_idea_label_after_method_call_1} =
+ IdeaLabels.add_idea_label_to_idea(idea, idea_label.id)
+
+ {:ok, idea_idea_label_after_method_call_2} =
+ IdeaLabels.add_idea_label_to_idea(idea, idea_label.id)
# There should still be only one IdeaIdeaLabel
- assert Repo.all(IdeaIdeaLabel) |> Enum.count() == 1
+ assert Repo.count(IdeaIdeaLabel) == 1
- assert Repo.all(IdeaLabel) |> Enum.count() == 1
+ assert Repo.count(IdeaLabel) == 1
- assert idea_after_method_call_1 == idea_after_method_call_2
+ assert idea_idea_label_after_method_call_1 == idea_idea_label_after_method_call_2
end
@tag :skip
@@ -68,7 +71,7 @@ defmodule Mindwendel.IdeaLabelsTest do
})
{:error, _changeset} =
- IdeaLabels.add_idea_label_to_idea(idea, idea_label_from_another_brainstorming)
+ IdeaLabels.add_idea_label_to_idea(idea, idea_label_from_another_brainstorming.id)
end
@tag :skip
@@ -88,16 +91,16 @@ defmodule Mindwendel.IdeaLabelsTest do
@tag :skip
test "does not create idea_labels without brainstorming", %{idea: idea} do
- assert Repo.all(IdeaIdeaLabel) |> Enum.count() == 0
+ assert Repo.count(IdeaIdeaLabel) == 0
idea = Repo.preload(idea, [:idea_labels, :idea_idea_labels])
idea_label = idea.brainstorming.labels |> Enum.at(0)
- IdeaLabels.add_idea_label_to_idea(idea, idea_label)
+ IdeaLabels.add_idea_label_to_idea(idea, idea_label.id)
- assert Repo.all(IdeaIdeaLabel) |> Enum.count() == 1
+ assert Repo.count(IdeaIdeaLabel) == 1
assert Repo.one(IdeaIdeaLabel).idea_id == idea.id
assert Repo.one(IdeaIdeaLabel).idea_label_id == idea_label.id
- assert Repo.all(IdeaLabel) |> Enum.count() == 5
+ assert Repo.count(IdeaLabel) == 5
assert Enum.empty?(
Repo.all(
@@ -110,13 +113,14 @@ defmodule Mindwendel.IdeaLabelsTest do
describe "#delete_idea_label_from_idea" do
setup %{idea_label: idea_label, idea: idea} do
- {:ok, idea} = IdeaLabels.add_idea_label_to_idea(idea, idea_label)
- assert Repo.all(IdeaIdeaLabel) |> Enum.count() == 1
+ {:ok, _idea_idea_label} = IdeaLabels.add_idea_label_to_idea(idea, idea_label.id)
+ idea = idea |> Repo.reload!() |> Repo.preload(:idea_labels)
+ assert Repo.count(IdeaIdeaLabel) == 1
%{idea: idea}
end
test "removes successfully IdeaLabel from Idea", %{idea_label: idea_label, idea: idea} do
- IdeaLabels.remove_idea_label_from_idea(idea, idea_label)
+ IdeaLabels.remove_idea_label_from_idea(idea, idea_label.id)
assert Enum.empty?(Repo.all(IdeaIdeaLabel))
end
@@ -125,10 +129,18 @@ defmodule Mindwendel.IdeaLabelsTest do
idea: idea
} do
# Calling this method twice does not fail
- IdeaLabels.remove_idea_label_from_idea(idea, idea_label)
- IdeaLabels.remove_idea_label_from_idea(idea, idea_label)
+ IdeaLabels.remove_idea_label_from_idea(idea, idea_label.id)
+ IdeaLabels.remove_idea_label_from_idea(idea, idea_label.id)
assert Enum.empty?(Repo.all(IdeaIdeaLabel))
end
end
+
+ defp labels_of(idea_record) do
+ Repo.all(
+ from idea_label in IdeaLabel,
+ join: idea in assoc(idea_label, :ideas),
+ where: idea.id == ^idea_record.id
+ )
+ end
end