defmodule PutzplanWeb.TaskLive.Index do use PutzplanWeb, :live_view @impl true def render(assigns) do ~H""" <.header> Listing Tasks <:actions> <.link patch={~p"/tasks/new"}> <.button>New Task <.table id="tasks" rows={@streams.tasks} row_click={fn {_id, task} -> JS.navigate(~p"/tasks/#{task}") end} > <:col :let={{id, task}}> <.link phx-click={JS.push("complete", value: %{id: task.id})}> <:col :let={{_id, task}} label="Description">{task.description} <:col :let={{_id, task}} label="Due">{format_date(task.due)} <:action :let={{_id, task}}>
<.link navigate={~p"/tasks/#{task}"}>Show
<:col :let={{id, task}}> <.link patch={~p"/tasks/#{task}/edit"}> <:col :let={{id, task}}> <.link phx-click={JS.push("delete", value: %{id: task.id}) |> hide("##{id}")} data-confirm="Are you sure?" > <.modal :if={@live_action in [:new, :edit]} id="task-modal" show on_cancel={JS.patch(~p"/tasks")}> <.live_component module={PutzplanWeb.TaskLive.FormComponent} id={(@task && @task.id) || :new} title={@page_title} current_user={@current_user} action={@live_action} task={@task} patch={~p"/"} /> """ end @impl true def mount(_params, _session, socket) do {:ok, socket |> stream( :tasks, Ash.read!(Putzplan.Tasks.Task, load: [:due], actor: socket.assigns[:current_user]) ) |> assign_new(:current_user, fn -> nil end)} end @impl true def handle_params(params, _url, socket) do {:noreply, apply_action(socket, socket.assigns.live_action, params)} end defp apply_action(socket, :edit, %{"id" => id}) do socket |> assign(:page_title, "Edit Task") |> assign( :task, Ash.get!(Putzplan.Tasks.Task, id, load: [:due], actor: socket.assigns.current_user) ) end defp apply_action(socket, :new, _params) do socket |> assign(:page_title, "New Task") |> assign(:task, nil) end defp apply_action(socket, :index, _params) do socket |> assign(:page_title, "Listing Tasks") |> assign(:task, nil) end @impl true def handle_info({PutzplanWeb.TaskLive.FormComponent, {:saved, task}}, socket) do {:noreply, stream_insert(socket, :tasks, task)} end @impl true def handle_event("delete", %{"id" => id}, socket) do task = Ash.get!(Putzplan.Tasks.Task, id, actor: socket.assigns.current_user) Ash.destroy!(task, actor: socket.assigns.current_user) {:noreply, stream_delete(socket, :tasks, task)} end @impl true def handle_event("complete", %{"id" => id}, socket) do Putzplan.Tasks.CompletedTask |> Ash.Changeset.for_create(:create, %{task: id, user: socket.assigns.current_user.id}) |> Ash.create!(actor: socket.assigns.current_user) {:noreply, stream_insert(socket, :tasks, Ash.get!(Putzplan.Tasks.Task, id, load: [:due]))} end defp format_date(date) do string = case Date.diff(date, Date.utc_today()) do 0 -> "today" 1 -> "tomorrow" days when days > 0 and days < 7 -> "next " <> get_weekday(Date.day_of_week(date)) _ -> Date.to_string(date) end String.capitalize(string) end defp get_weekday(index) do days = %{ 1 => "monday", 2 => "tuesday", 3 => "wednesday", 4 => "thursday", 5 => "friday", 6 => "saturday", 7 => "sunday" } Map.get(days, index) end end