Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transition to mainline .inputs_for code #466

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions lib/mindwendel/brainstormings/brainstorming.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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)})
Expand Down
12 changes: 5 additions & 7 deletions lib/mindwendel/brainstormings/idea_label.ex
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,15 @@ defmodule Mindwendel.Brainstormings.IdeaLabel do
timestamps()
end

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])
|> validate_required([:name])
|> validate_format(:color, ~r/^#[0-9a-f]{6}$/)
|> foreign_key_constraint(:ideas,
name: "idea_idea_labels_idea_label_id_fkey",
message: "idea label associated with idea"
)
|> no_assoc_constraint(:idea_idea_labels, message: "idea label associated with idea")
end
end
27 changes: 0 additions & 27 deletions lib/mindwendel/brainstormings/idea_label_factory.ex

This file was deleted.

83 changes: 3 additions & 80 deletions lib/mindwendel_web/live/admin/brainstorming_live/edit.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -43,12 +42,14 @@ 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
})
|> Repo.preload(labels: from(idea_label in IdeaLabel, order_by: idea_label.position_order))

# this changeset is too much?!
changeset = Brainstorming.changeset(brainstorming, brainstorming_params)

case Brainstormings.update_brainstorming(brainstorming, brainstorming_params) do
Expand Down Expand Up @@ -76,85 +77,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
Expand All @@ -164,6 +86,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)
Expand Down
18 changes: 15 additions & 3 deletions lib/mindwendel_web/live/admin/brainstorming_live/edit.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
<div class="col">
<.inputs_for :let={f_label} field={@form[:labels]}>
<div class="input-group has-validation mb-2 mt-2">
<input type="hidden" name="brainstorming[labels_sort][]" value={f_label.index} />
<.input
type="color"
field={f_label[:color]}
Expand All @@ -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") %>
</.button>

<.error :for={msg <- Enum.map(f_label[:name].errors, &translate_error(&1))}>
<%= msg %>
</.error>
</div>
</.inputs_for>

<input type="hidden" name="brainstorming[labels_drop][]" />
</div>
</div>
<div class="row mb-3">
<div class="col-12 d-grid mt-2">
<.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") %>
</.button>
</div>
Expand Down
58 changes: 58 additions & 0 deletions test/mindwendel/brainstormings/brainstorming_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
defmodule Mindwendel.Brainstormings.BrainstormingTest do
use Mindwendel.DataCase, async: true

alias Mindwendel.Brainstormings.Brainstorming
alias Mindwendel.Brainstormings.IdeaLabel
# should be aliases in data case
alias Mindwendel.Factory

# improve ecto sandbox/test warnings when just in a describe
describe "freaking relationships and on_replace stuff" do
test "oof" do
labels = [
%IdeaLabel{name: "cyan", color: "#0dcaf0", position_order: 0}
]

brainstorming = Factory.insert!(:brainstorming, labels: labels)

# make it break we forein kay constraint
brainstorming_label_first = List.first(brainstorming.labels)

Factory.insert!(:idea,
brainstorming: brainstorming,
idea_labels: [
brainstorming_label_first
]
)

attrs = %{
"labels" => %{
"0" => %{
"color" => "#0dcaf0",
"name" => "cyan"
}
},
"labels_drop" => ["0"],
# 0? 1?
"labels_sort" => ["0"]
}

assert length(brainstorming.labels) == 1

IO.puts("\n\n\n\n\n\n")
IO.puts("CHANGESET")
IO.puts("\n\n\n\n\n\n")

changeset = Brainstorming.changeset(brainstorming, attrs)

IO.puts("\n\n\n\n\n\n")
IO.puts("UPDATE")
IO.puts("\n\n\n\n\n\n")

# boomzies
assert {:ok, new_brain} = Repo.update(changeset)

assert Enum.empty?(new_brain.labels)
end
end
end
Loading
Loading