updated shift index template and implemented delete shift as modal instead of js alert

This commit is contained in:
Adam Piontek 2022-08-14 10:30:57 -04:00
parent ada166fb41
commit a99c5eea35
5 changed files with 129 additions and 51 deletions

View file

@ -86,8 +86,12 @@ defmodule Shift73k.Shifts do
** (Ecto.NoResultsError) ** (Ecto.NoResultsError)
""" """
def get_shift!(nil), do: nil
def get_shift!(id), do: Repo.get!(Shift, id) def get_shift!(id), do: Repo.get!(Shift, id)
def get_shift(nil), do: nil
def get_shift(id), do: Repo.get(Shift, id)
@doc """ @doc """
Creates a shift. Creates a shift.

View file

@ -0,0 +1,46 @@
defmodule Shift73kWeb.ShiftLive.DeleteComponent do
use Shift73kWeb, :live_component
alias Shift73k.Shifts
@impl true
def update(assigns, socket) do
socket
|> assign(assigns)
|> live_okreply()
end
@impl true
def handle_event("confirm", %{"id" => id, "subject" => subject, "datetime" => datetime}, socket) do
shift = Shifts.get_shift(id)
if (shift) do
shift
|> Shifts.delete_shift()
|> case do
{:ok, _} ->
flash = {:info, "Shift deleted successfully: \"#{subject}\""}
send(self(), {:put_flash_message, flash})
socket
|> push_event("modal-please-hide", %{})
|> live_noreply()
{:error, _} ->
handle_error(socket, subject, datetime)
end
end
end
defp handle_error(socket, subject, datetime) do
flash =
{:error,
"Some error trying to delete shift \"#{subject} (#{datetime})\". Possibly already deleted? Reloading list..."}
send(self(), {:put_flash_message, flash})
socket
|> push_event("modal-please-hide", %{})
|> live_noreply()
end
end

View file

@ -0,0 +1,22 @@
<div>
<div class="modal-body">
<% shift_datetime = "#{Calendar.strftime(@delete_shift.date, "%A, %b %-d")}, #{format_shift_time(@delete_shift.time_start)} — #{format_shift_time(@delete_shift.time_end)}" %>
Are you sure you want to delete "<%= @delete_shift.subject %> (<%= shift_datetime %>)?"
</div>
<div class="modal-footer">
<%= link "Cancel", to: "#", class: "btn btn-outline-dark", phx_click: "hide", phx_target: "##{@modal_id}" %>
<%= link "Confirm Delete", to: "#",
class: "btn btn-danger",
phx_click: "confirm",
phx_target: @myself,
phx_value_id: @delete_shift.id,
phx_value_subject: @delete_shift.subject,
phx_value_datetime: shift_datetime %>
</div>
</div>

View file

@ -22,6 +22,7 @@ defmodule Shift73kWeb.ShiftLive.Index do
socket socket
|> init_today(Date.utc_today()) |> init_today(Date.utc_today())
|> update_agenda() |> update_agenda()
|> assign_modal_close_handlers()
|> assign(:delete_shift, nil) |> assign(:delete_shift, nil)
|> apply_action(socket.assigns.live_action, params) |> apply_action(socket.assigns.live_action, params)
|> live_noreply() |> live_noreply()
@ -33,6 +34,11 @@ defmodule Shift73kWeb.ShiftLive.Index do
end end
end end
defp assign_modal_close_handlers(socket) do
to = Routes.shift_index_path(socket, :index)
assign(socket, modal_return_to: to, modal_close_action: :return)
end
defp apply_action(socket, :index, _params) do defp apply_action(socket, :index, _params) do
socket socket
|> assign(:page_title, "My Shifts") |> assign(:page_title, "My Shifts")
@ -76,6 +82,14 @@ defmodule Shift73kWeb.ShiftLive.Index do
|> assign_known_shifts() |> assign_known_shifts()
end end
@impl true
def handle_event("delete-modal", %{"id" => id}, socket) do
socket
|> assign(:modal_close_action, :delete_shift)
|> assign(:delete_shift, Shifts.get_shift!(id))
|> live_noreply()
end
@impl true @impl true
def handle_event("delete", %{"id" => id}, socket) do def handle_event("delete", %{"id" => id}, socket) do
shift = Shifts.get_shift!(id) shift = Shifts.get_shift!(id)
@ -94,6 +108,28 @@ defmodule Shift73kWeb.ShiftLive.Index do
|> live_noreply() |> live_noreply()
end end
@impl true
def handle_info({:close_modal, _}, %{assigns: %{modal_close_action: :return}} = socket) do
socket
|> copy_flash()
|> push_patch(to: socket.assigns.modal_return_to)
|> live_noreply()
end
@impl true
def handle_info({:close_modal, _}, %{assigns: %{modal_close_action: assign_key}} = socket) do
socket
|> assign(assign_key, nil)
|> assign_modal_close_handlers()
|> assign_known_shifts()
|> live_noreply()
end
@impl true
def handle_info({:put_flash_message, {flash_type, msg}}, socket) do
socket |> put_flash(flash_type, msg) |> live_noreply()
end
defp new_nav_cursor("now", _cursor_date), do: Date.utc_today() defp new_nav_cursor("now", _cursor_date), do: Date.utc_today()
defp new_nav_cursor(nav, cursor_date) do defp new_nav_cursor(nav, cursor_date) do

View file

@ -1,40 +1,42 @@
<%= if @delete_shift do %>
<%= live_modal @socket, Shift73kWeb.ShiftLive.DeleteComponent,
id: @delete_shift.id,
title: "Delete Shift Template",
delete_shift: @delete_shift %>
<% end %>
<div class="row justify-content-start justify-content-sm-center"> <div class="row justify-content-start justify-content-sm-center">
<div class="col-md-10 col-xl-10"> <div class="col-md-10 col-xl-10">
<h2 class="mb-3 mb-sm-0"> <h2 class="mb-3 mb-sm-0">
<%= icon_div @socket, "bi-card-list", [class: "icon baseline"] %> <i class="bi bi-card-list me-1"></i> My Shifts
My Shifts
</h2> </h2>
<div class="row justify-content-start justify-content-sm-center"> <div class="row justify-content-start justify-content-sm-center">
<div class="col-md-10 col-xl-10"> <div class="col-md-10 col-xl-10">
<%# month navigation %> <%# month navigation %>
<div class="d-flex justify-content-between align-items-end my-4"> <div class="d-flex justify-content-between align-items-end my-4">
<h3 class="text-muted mb-0"> <h3 class="text-muted mb-0">
<%= Calendar.strftime(@cursor_date, "%B %Y") %> <%= Calendar.strftime(@cursor_date, "%B %Y") %>
</h3> </h3>
<div> <div>
<button type="button" phx-click="month-nav" phx-value-month="now" class="btn btn-info text-white" <%= if Map.get(@cursor_date, :month) == Map.get(Date.utc_today(), :month), do: "disabled" %>> <button type="button" phx-click="month-nav" phx-value-month="now" class="btn btn-info text-white" disabled={if Map.get(@cursor_date, :month) == Map.get(Date.utc_today(), :month), do: :true, else: :false}>
<%= icon_div @socket, "bi-asterisk", [class: "icon baseline"] %> <i class="bi bi-asterisk me-sm-1"></i>
<span class="d-none d-sm-inline">Today</span> <span class="d-none d-sm-inline">Today</span>
</button> </button>
<button type="button" phx-click="month-nav" phx-value-month="prev" class="btn btn-primary"> <button type="button" phx-click="month-nav" phx-value-month="prev" class="btn btn-primary">
<%= icon_div @socket, "bi-chevron-left", [class: "icon baseline"] %> <i class="bi bi-chevron-left me-sm-1"></i>
<span class="d-none d-sm-inline">Prev</span> <span class="d-none d-sm-inline">Prev</span>
</button> </button>
<button type="button" phx-click="month-nav" phx-value-month="next" class="btn btn-primary"> <button type="button" phx-click="month-nav" phx-value-month="next" class="btn btn-primary">
<span class="d-none d-sm-inline">Next</span> <span class="d-none d-sm-inline">Next</span>
<%= icon_div @socket, "bi-chevron-right", [class: "icon baseline", style: "margin-left:0.125rem;"] %> <i class="bi bi-chevron-right ms-sm-1"></i>
</button> </button>
</div> </div>
</div> </div>
<%= for day <- Enum.to_list(@date_range) do %> <%= for day <- Enum.to_list(@date_range) do %>
<%= if Date.day_of_week(day, @current_user.week_start_at) == 1 do %> <%= if Date.day_of_week(day, @current_user.week_start_at) == 1 do %>
<div class="border-top mt-4 mb-4"></div> <div class="border-top mt-4 mb-4"></div>
@ -45,24 +47,21 @@
<% day_shifts = Enum.filter(@shifts, fn s -> s.date == day end) %> <% day_shifts = Enum.filter(@shifts, fn s -> s.date == day end) %>
<%= if !Enum.empty?(day_shifts) do %> <%= if !Enum.empty?(day_shifts) do %>
<%= for shift <- day_shifts do %> <%= for shift <- day_shifts do %>
<div class="card mt-2 mb-4 col-12 ms-sm-3 ms-md-4 col-lg-10 ms-lg-5 col-xxl-8" id={"shift-#{shift.id}"}>
<div class="card mt-2 mb-4 col-12 ms-sm-3 ms-md-4 col-lg-10 ms-lg-5 col-xxl-8" id="shift-<%= shift.id %>">
<div class="card-body"> <div class="card-body">
<h5 class="card-title"> <h5 class="card-title">
<%= icon_div @socket, "bi-tag", [class: "icon baseline text-muted me-1"] %> <i class="bi bi-tag text-muted me-1"></i>
<%= shift.subject %> <%= shift.subject %>
</h5> </h5>
<table class="table table-borderless table-nonfluid table-sm"> <table class="table table-borderless table-nonfluid table-sm">
<tbody> <tbody>
<tr> <tr>
<th scope="row" class="text-end"> <th scope="row" class="text-end">
<%= icon_div @socket, "bi-hourglass", [class: "icon baseline text-muted"] %> <i class="bi bi-hourglass text-muted"></i>
<span class="visually-hidden">Hours:</span> <span class="visually-hidden">Hours:</span>
</th> </th>
<td> <td>
@ -79,7 +78,7 @@
<tr> <tr>
<th scope="row" class="text-end"> <th scope="row" class="text-end">
<%= icon_div @socket, "bi-geo", [class: "icon baseline text-muted"] %> <i class="bi bi-geo text-muted"></i>
<span class="visually-hidden">Location:</span> <span class="visually-hidden">Location:</span>
</th> </th>
<td> <td>
@ -92,7 +91,7 @@
</tr> </tr>
<tr> <tr>
<th scope="row" class="text-end"> <th scope="row" class="text-end">
<%= icon_div @socket, "bi-justify-left", [class: "icon baseline text-muted"] %> <i class="bi bi-justify-left text-muted"></i>
<span class="visually-hidden">Description:</span> <span class="visually-hidden">Description:</span>
</th> </th>
<td class="shift-description"> <td class="shift-description">
@ -106,51 +105,22 @@
</tbody> </tbody>
</table> </table>
<%#= if Roles.can?(@current_user, template, :edit) do %> <button class="btn btn-outline-danger btn-sm text-nowrap" phx-click="delete-modal" phx-value-id={shift.id}>
<%#= live_patch to: Routes.shift_template_index_path(@socket, :edit, template), class: "btn btn-primary btn-sm text-nowrap" do %> <i class="bi bi-trash me-1"></i> Delete
<%#= icon_div @socket, "bi-pencil", [class: "icon baseline"] %> </button>
<%# Edit %>
<%# end %>
<%# end %>
<%#= if Roles.can?(@current_user, template, :delete) do %>
<%# <button class="btn btn-outline-danger btn-sm text-nowrap" phx-click="delete-modal" phx-value-id=" %>
<%#= shift.id %>
<%# "> %>
<%#= icon_div @socket, "bi-trash", [class: "icon baseline"] %>
<%# Delete %>
<%# </button> %>
<%# end %>
<%= button to: "#", phx_click: "delete", phx_value_id: shift.id, data: [confirm: "Are you sure?"], class: "btn btn-outline-danger btn-sm text-nowrap" do %>
<%= icon_div @socket, "bi-trash", [class: "icon baseline"] %>
Delete
<% end %>
</div> </div>
</div> </div>
<% end %> <% end %>
<% else %> <% else %>
<p class="text-muted"><em>Nothing scheduled</em></p> <p class="text-muted"><em>Nothing scheduled</em></p>
<% end %> <% end %>
<% end %> <% end %>
</div> </div>
</div> </div>
</div> </div>
</div> </div>