NEW: form-based many-to-many plans-tasks (#39)
This commit is contained in:
parent
5d91febec5
commit
7cbb884ef0
3 changed files with 52 additions and 8 deletions
|
@ -17,6 +17,7 @@ defmodule Planner.Tasks do
|
|||
order_by: [desc: t.updated_at]
|
||||
)
|
||||
|> Repo.all()
|
||||
|> Repo.preload(:plans)
|
||||
end
|
||||
|
||||
def list_unfinished_tasks_by_plan_id(plan_id) do
|
||||
|
@ -40,6 +41,7 @@ defmodule Planner.Tasks do
|
|||
order_by: [desc: t.updated_at]
|
||||
)
|
||||
|> Repo.all()
|
||||
|> Repo.preload(:plans)
|
||||
end
|
||||
|
||||
def get_task!(id), do: Repo.get!(Task, id)
|
||||
|
@ -60,9 +62,33 @@ defmodule Planner.Tasks do
|
|||
end
|
||||
|
||||
def update_task(%Task{} = task, attrs) do
|
||||
task
|
||||
|> Task.changeset(attrs)
|
||||
|> Repo.update()
|
||||
new_plan_details_changesets = Enum.map(attrs["plans"], fn(plan_id) ->
|
||||
PlanDetail.changeset(%PlanDetail{}, %{"task_id" => task.id, "plan_id" => plan_id})
|
||||
end)
|
||||
|
||||
deleted_plan_details =
|
||||
Ecto.Query.from(
|
||||
pd in PlanDetail,
|
||||
where: pd.task_id == ^task.id and pd.plan_id not in ^attrs["plans"]
|
||||
)
|
||||
|
||||
multi =
|
||||
Enum.reduce(
|
||||
new_plan_details_changesets,
|
||||
Multi.new()
|
||||
|> Multi.update(:task, Task.changeset(task, attrs))
|
||||
|> Multi.delete_all(:deleted_plan_details, deleted_plan_details),
|
||||
fn(changeset, new_multi) ->
|
||||
Multi.insert(
|
||||
new_multi,
|
||||
changeset.params["plan_id"],
|
||||
changeset,
|
||||
on_conflict: :nothing
|
||||
)
|
||||
end
|
||||
)
|
||||
|
||||
Repo.transaction(multi)
|
||||
end
|
||||
|
||||
def delete_task_by_id!(id) do
|
||||
|
|
|
@ -50,6 +50,7 @@ defmodule TasksComponent do
|
|||
TaskComponent,
|
||||
id: "task:#{task.id}",
|
||||
task: task,
|
||||
plans: @plans,
|
||||
live_action: @live_action,
|
||||
is_active: @active_task == task.id,
|
||||
route_show_task: @route_show_task,
|
||||
|
@ -96,7 +97,8 @@ defmodule TaskComponent do
|
|||
<%= live_component(@socket,
|
||||
TaskEditComponent,
|
||||
id: "task_edit:#{@task.id}",
|
||||
task: @task
|
||||
task: @task,
|
||||
plans: @plans
|
||||
)%>
|
||||
<% end %>
|
||||
<% else %>
|
||||
|
@ -225,8 +227,23 @@ defmodule TaskEditComponent do
|
|||
<%= error_tag(f, :due_at) %>
|
||||
</div>
|
||||
|
||||
<div class="control">
|
||||
<%= submit("save", class: "button is-dark is-small") %>
|
||||
<div class="field">
|
||||
<label class="label">plans</label>
|
||||
<div class="control">
|
||||
<div class="select is-multiple is-dark">
|
||||
<%= multiple_select(f,
|
||||
:plans,
|
||||
Enum.map(@plans, &({&1.name, &1.id})),
|
||||
selected: Enum.map(@task.plans, &(&1.id))
|
||||
) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<%= submit("save", class: "button is-dark is-small") %>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -128,6 +128,7 @@ defmodule PlannerWeb.TasksLive do
|
|||
id: :tasks,
|
||||
live_action: @live_action,
|
||||
tasks: @tasks,
|
||||
plans: @plans,
|
||||
active_plan: @active_plan,
|
||||
active_task: @active_task,
|
||||
route_show_task: @route_show_task,
|
||||
|
@ -168,11 +169,11 @@ defmodule PlannerWeb.TasksLive do
|
|||
task = Tasks.get_task!(task_params["id"])
|
||||
|
||||
case Tasks.update_task(task, task_params) do
|
||||
{:ok, task} ->
|
||||
{:ok, changes} ->
|
||||
# I suspect splicing in the updated task isn't much faster than just refreshing the whole list
|
||||
socket =
|
||||
socket
|
||||
|> refresh_tasks_and_flash_msg("task \"#{task.value}\" updated")
|
||||
|> refresh_tasks_and_flash_msg("task \"#{changes.task.value}\" updated")
|
||||
|
||||
route = get_index_route(socket)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue