Skip to content

Commit

Permalink
Add task deletion (#251)
Browse files Browse the repository at this point in the history
  • Loading branch information
ruilopesm authored Mar 25, 2023
1 parent 0669acd commit 1107d70
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 43 deletions.
2 changes: 1 addition & 1 deletion lib/parzival/gamification/mission.ex
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ defmodule Parzival.Gamification.Mission do

belongs_to :difficulty, Difficulty

has_many :tasks, Task, on_replace: :delete_if_exists
has_many :tasks, Task, on_replace: :delete

many_to_many :users, User, join_through: MissionUser, preload_order: [desc: :inserted_at]

Expand Down
17 changes: 16 additions & 1 deletion lib/parzival/gamification/mission/task.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ defmodule Parzival.Gamification.Mission.Task do

@optional_fields [
:tokens,
:exp
:exp,
:delete
]

schema "tasks" do
Expand All @@ -22,6 +23,8 @@ defmodule Parzival.Gamification.Mission.Task do
field :tokens, :integer
field :exp, :integer

field :delete, :boolean, virtual: true

belongs_to :mission, Mission

many_to_many :users, User, join_through: TaskUser, on_delete: :delete_all
Expand All @@ -34,11 +37,23 @@ defmodule Parzival.Gamification.Mission.Task do
task
|> cast(attrs, @required_fields ++ @optional_fields)
|> validate_required(@required_fields)
|> maybe_mark_for_deletion()
end

def task_changeset(task, attrs) do
task
|> cast(attrs, @required_fields ++ @optional_fields)
|> validate_required(@required_fields -- [:mission_id])
|> maybe_mark_for_deletion()
end

defp maybe_mark_for_deletion(%{data: %{id: nil}} = changeset), do: changeset

defp maybe_mark_for_deletion(changeset) do
if get_change(changeset, :delete) do
%{changeset | action: :delete}
else
changeset
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,21 @@ defmodule ParzivalWeb.Backoffice.MissionLive.FormComponent do
{:noreply, assign(socket, changeset: changeset)}
end

def handle_event("rm-task", %{"index" => index}, socket) do
changeset = socket.assigns.changeset

tasks =
changeset
|> Ecto.Changeset.get_field(:tasks)
|> List.delete_at(String.to_integer(index))

changeset =
changeset
|> Ecto.Changeset.put_assoc(:tasks, tasks)

{:noreply, assign(socket, changeset: changeset)}
end

def handle_event("save", %{"mission" => mission_params}, socket) do
mission_params =
if socket.assigns.current_user.role in [:recruiter] do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,51 +106,67 @@
</div>
</div>
<div clas="flex flex-col">
<%= for {fs, index} <- Enum.with_index(inputs_for(f, :tasks)) do %>
<%= hidden_input(fs, :id) %>
<%= hidden_input(fs, :mission_id) %>
<div class="flex flex-col gap-2 py-3 px-4 border-b border-gray-200 sm:py-4 sm:px-6 lg:px-8">
<span class="text-lg font-bold sm:text-xl">
Task <%= index + 1 %>
</span>
<div>
<%= text_input(fs, :title, placeholder: "Choose title", phx_debounce: "blur", class: "leading-7 text-gray-700 text-base sm:text-lg sm:truncate mt-1 font-bold focus:ring-red-500 focus:border-red-500 block w-full shadow-sm border-gray-300 rounded-md") %>
<div class="flex text-red-500">
<%= error_tag(fs, :title) %>
<%= inputs_for f, :tasks, fn fs -> %>
<div x-bind:class="! show ? 'hidden' : 'block space-y-2'" x-data="{ show: true }">
<%= hidden_input(fs, :id) %>
<%= hidden_input(fs, :mission_id) %>
<div class="flex flex-col gap-2 py-3 px-4 border-b border-gray-200 sm:py-4 sm:px-6 lg:px-8">
<div class="flex flex-row justify-between">
<span class="text-lg font-bold sm:text-xl">
Task <%= fs.index + 1 %>
</span>
<%= if fs.index != 0 do %>
<%= if is_nil(fs.data.id) do %>
<a phx-click="rm-task" phx-target={@myself} phx-value-index={fs.index} class="justify-center py-2 px-4 text-sm font-medium bg-white rounded-md border border-gray-300 shadow-sm cursor-pointer hover:bg-gray-50 text-primary">
Delete
</a>
<% else %>
<a onclick={"document.getElementById('#{fs.data.id}').click()"} x-on:click="show = false" class="justify-center py-2 px-4 text-sm font-medium bg-white rounded-md border border-gray-300 shadow-sm cursor-pointer hover:bg-gray-50 text-primary">
Delete
</a>
<%= checkbox(fs, :delete, id: fs.data.id, class: "hidden") %>
<% end %>
<% end %>
</div>
</div>
<div class="flex flex-col gap-y-1">
<span class="pl-1 text-sm font-medium text-gray-800 sm:text-base">
Description
</span>
<span class="text-sm text-gray-700 line-clamp-3">
<%= textarea(fs, :description, placeholder: "Choose description", rows: 15, phx_debounce: "blur", class: "focus:ring-red-500 h-24 font-medium focus:border-red-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md") %>
</span>
<div class="flex text-red-500">
<%= error_tag(fs, :description) %>
<div>
<%= text_input(fs, :title, placeholder: "Choose title", phx_debounce: "blur", class: "leading-7 text-gray-700 text-base sm:text-lg sm:truncate mt-1 font-bold focus:ring-red-500 focus:border-red-500 block w-full shadow-sm border-gray-300 rounded-md") %>
<div class="flex text-red-500">
<%= error_tag(fs, :title) %>
</div>
</div>
</div>
<div class="flex flex-col gap-y-1">
<span class="pl-1 text-sm font-medium text-gray-800 sm:text-base">
Rewards
</span>
<div class="flex flex-col gap-4 sm:flex-row">
<div class="relative">
<div class="absolute ml-3 top-[22%]">
💰
</div>
<%= number_input(fs, :tokens, placeholder: "Choose tokens", phx_debounce: "blur", class: "w-64 pl-9 leading-7 text-gray-700 sm:truncate text-sm focus:ring-red-500 focus:border-red-500 block w-full shadow-sm border-gray-300 rounded-md") %>
<div class="text-red-500">
<%= error_tag(fs, :tokens) %>
</div>
<div class="flex flex-col gap-y-1">
<span class="pl-1 text-sm font-medium text-gray-800 sm:text-base">
Description
</span>
<span class="text-sm text-gray-700 line-clamp-3">
<%= textarea(fs, :description, placeholder: "Choose description", rows: 15, phx_debounce: "blur", class: "focus:ring-red-500 h-24 font-medium focus:border-red-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md") %>
</span>
<div class="flex text-red-500">
<%= error_tag(fs, :description) %>
</div>
<div class="relative">
<div class="absolute ml-2 top-[28%] text-gray-300 text-sm">
EXP
</div>
<div class="flex flex-col gap-y-1">
<span class="pl-1 text-sm font-medium text-gray-800 sm:text-base">
Rewards
</span>
<div class="flex flex-col gap-4 sm:flex-row">
<div class="relative">
<div class="absolute ml-3 top-[22%]">
💰
</div>
<%= number_input(fs, :tokens, placeholder: "Choose tokens", phx_debounce: "blur", class: "w-64 pl-9 leading-7 text-gray-700 sm:truncate text-sm focus:ring-red-500 focus:border-red-500 block w-full shadow-sm border-gray-300 rounded-md") %>
<div class="text-red-500">
<%= error_tag(fs, :tokens) %>
</div>
</div>
<%= number_input(fs, :exp, placeholder: "Choose experience", phx_debounce: "blur", class: "w-64 pl-9 leading-7 text-gray-700 sm:truncate text-sm focus:ring-red-500 focus:border-red-500 block w-full shadow-sm border-gray-300 rounded-md") %>
<div class="text-red-500">
<%= error_tag(fs, :exp) %>
<div class="relative">
<div class="absolute ml-2 top-[28%] text-gray-300 text-sm">
EXP
</div>
<%= number_input(fs, :exp, placeholder: "Choose experience", phx_debounce: "blur", class: "w-64 pl-9 leading-7 text-gray-700 sm:truncate text-sm focus:ring-red-500 focus:border-red-500 block w-full shadow-sm border-gray-300 rounded-md") %>
<div class="text-red-500">
<%= error_tag(fs, :exp) %>
</div>
</div>
</div>
</div>
Expand Down

0 comments on commit 1107d70

Please sign in to comment.