basic shift display working
This commit is contained in:
parent
3cb8dcef18
commit
8a1b7a4852
12 changed files with 233 additions and 108 deletions
|
@ -36,6 +36,7 @@ import "../node_modules/bootstrap-icons/icons/people.svg"; // users management
|
||||||
// calendar/event icons
|
// calendar/event icons
|
||||||
import "../node_modules/bootstrap-icons/icons/calendar2.svg";
|
import "../node_modules/bootstrap-icons/icons/calendar2.svg";
|
||||||
import "../node_modules/bootstrap-icons/icons/calendar2-plus.svg";
|
import "../node_modules/bootstrap-icons/icons/calendar2-plus.svg";
|
||||||
|
import "../node_modules/bootstrap-icons/icons/calendar2-date.svg";
|
||||||
import "../node_modules/bootstrap-icons/icons/calendar2-event.svg";
|
import "../node_modules/bootstrap-icons/icons/calendar2-event.svg";
|
||||||
import "../node_modules/bootstrap-icons/icons/calendar2-range.svg";
|
import "../node_modules/bootstrap-icons/icons/calendar2-range.svg";
|
||||||
import "../node_modules/bootstrap-icons/icons/clock-history.svg"; // shift template
|
import "../node_modules/bootstrap-icons/icons/clock-history.svg"; // shift template
|
||||||
|
@ -53,6 +54,7 @@ import "../node_modules/bootstrap-icons/icons/binoculars-fill.svg";
|
||||||
import "../node_modules/bootstrap-icons/icons/eraser.svg";
|
import "../node_modules/bootstrap-icons/icons/eraser.svg";
|
||||||
import "../node_modules/bootstrap-icons/icons/save.svg";
|
import "../node_modules/bootstrap-icons/icons/save.svg";
|
||||||
import "../node_modules/bootstrap-icons/icons/asterisk.svg";
|
import "../node_modules/bootstrap-icons/icons/asterisk.svg";
|
||||||
|
import "../node_modules/bootstrap-icons/icons/card-list.svg";
|
||||||
|
|
||||||
// webpack automatically bundles all modules in your
|
// webpack automatically bundles all modules in your
|
||||||
// entry points. Those entry points can be configured
|
// entry points. Those entry points can be configured
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
defmodule Shift73k.EctoEnums do
|
defmodule Shift73k.EctoEnums do
|
||||||
import EctoEnum
|
import EctoEnum
|
||||||
|
|
||||||
@weekdays [:mon, :tue, :wed, :thu, :fri, :sat, :sun] |> Enum.with_index(1)
|
@weekdays [:monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday]
|
||||||
|
|> Enum.with_index(1)
|
||||||
|
|
||||||
defenum(WeekdayEnum, @weekdays)
|
defenum(WeekdayEnum, @weekdays)
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,26 +21,26 @@ defmodule Shift73k.Shifts do
|
||||||
Repo.all(Shift)
|
Repo.all(Shift)
|
||||||
end
|
end
|
||||||
|
|
||||||
def list_shifts_by_user_between_dates(user_id, start_date, end_date) do
|
defp query_shifts_by_user(user_id) do
|
||||||
from(s in Shift)
|
from(s in Shift)
|
||||||
|> select([s], %{
|
|> where([s], s.user_id == ^user_id)
|
||||||
date: s.date,
|
end
|
||||||
subject: s.subject,
|
|
||||||
time_start: s.time_start,
|
def list_shifts_by_user_in_date_range(user_id, %Date.Range{} = date_range) do
|
||||||
time_end: s.time_end
|
query_shifts_by_user(user_id)
|
||||||
})
|
|> where([s], s.date >= ^date_range.first)
|
||||||
|> where([s], s.user_id == ^user_id and s.date >= ^start_date and s.date <= ^end_date)
|
|> where([s], s.date <= ^date_range.last)
|
||||||
|> order_by([s], [s.date, s.time_start])
|
|> order_by([s], [s.date, s.time_start])
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
end
|
end
|
||||||
|
|
||||||
defp query_shifts_by_user_on_list_of_dates(user_id, date_list) do
|
defp query_shifts_by_user_from_list_of_dates(user_id, date_list) do
|
||||||
from(s in Shift)
|
query_shifts_by_user(user_id)
|
||||||
|> where([s], s.user_id == ^user_id and s.date in ^date_list)
|
|> where([s], s.date in ^date_list)
|
||||||
end
|
end
|
||||||
|
|
||||||
def list_shifts_by_user_on_list_of_dates(user_id, date_list) do
|
def list_shifts_by_user_from_list_of_dates(user_id, date_list) do
|
||||||
query_shifts_by_user_on_list_of_dates(user_id, date_list)
|
query_shifts_by_user_from_list_of_dates(user_id, date_list)
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -112,8 +112,8 @@ defmodule Shift73k.Shifts do
|
||||||
Repo.delete(shift)
|
Repo.delete(shift)
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_shifts_by_user_on_list_of_dates(user_id, date_list) do
|
def delete_shifts_by_user_from_list_of_dates(user_id, date_list) do
|
||||||
query_shifts_by_user_on_list_of_dates(user_id, date_list)
|
query_shifts_by_user_from_list_of_dates(user_id, date_list)
|
||||||
|> Repo.delete_all()
|
|> Repo.delete_all()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ defmodule Shift73kWeb.ShiftAssignLive.DeleteComponent do
|
||||||
def handle_event("confirm-delete-days-shifts", _params, socket) do
|
def handle_event("confirm-delete-days-shifts", _params, socket) do
|
||||||
user = socket.assigns.current_user
|
user = socket.assigns.current_user
|
||||||
date_list = socket.assigns.date_list
|
date_list = socket.assigns.date_list
|
||||||
{n, _} = Shifts.delete_shifts_by_user_on_list_of_dates(user.id, date_list)
|
{n, _} = Shifts.delete_shifts_by_user_from_list_of_dates(user.id, date_list)
|
||||||
s = (n > 1 && "s") || ""
|
s = (n > 1 && "s") || ""
|
||||||
flash = {:info, "Successfully deleted #{n} assigned shift#{s}"}
|
flash = {:info, "Successfully deleted #{n} assigned shift#{s}"}
|
||||||
send(self(), {:put_flash_message, flash})
|
send(self(), {:put_flash_message, flash})
|
||||||
|
|
|
@ -27,6 +27,8 @@ defmodule Shift73kWeb.ShiftAssignLive.Index do
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_params(_params, _url, socket) do
|
def handle_params(_params, _url, socket) do
|
||||||
|
user = socket.assigns.current_user
|
||||||
|
|
||||||
socket
|
socket
|
||||||
|> init_shift_templates()
|
|> init_shift_templates()
|
||||||
|> init_shift_template()
|
|> init_shift_template()
|
||||||
|
@ -34,9 +36,9 @@ defmodule Shift73kWeb.ShiftAssignLive.Index do
|
||||||
|> assign_shift_length()
|
|> assign_shift_length()
|
||||||
|> assign_shift_template_changeset()
|
|> assign_shift_template_changeset()
|
||||||
|> assign_modal_close_handlers()
|
|> assign_modal_close_handlers()
|
||||||
|
|> assign(:day_names, day_names(user.week_start_at))
|
||||||
|> init_today(Timex.today())
|
|> init_today(Timex.today())
|
||||||
|> init_calendar()
|
|> update_calendar()
|
||||||
|> assign_known_shifts()
|
|
||||||
|> live_noreply()
|
|> live_noreply()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -52,20 +54,12 @@ defmodule Shift73kWeb.ShiftAssignLive.Index do
|
||||||
assign(socket, :shift_length, format_shift_length(shift))
|
assign(socket, :shift_length, format_shift_length(shift))
|
||||||
end
|
end
|
||||||
|
|
||||||
defp assign_known_shifts(socket) do
|
defp assign_known_shifts(%{assigns: %{current_user: user}} = socket) do
|
||||||
user = socket.assigns.current_user
|
date_range = socket.assigns.date_range
|
||||||
first = socket.assigns.day_first
|
known_shifts = Shifts.list_shifts_by_user_in_date_range(user.id, date_range)
|
||||||
last = socket.assigns.day_last
|
|
||||||
known_shifts = Shifts.list_shifts_by_user_between_dates(user.id, first, last)
|
|
||||||
assign(socket, :known_shifts, known_shifts)
|
assign(socket, :known_shifts, known_shifts)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp init_calendar(%{assigns: %{current_user: user}} = socket) do
|
|
||||||
days = day_names(user.week_start_at)
|
|
||||||
{first, last, rows} = week_rows(socket.assigns.cursor_date, user.week_start_at)
|
|
||||||
assign(socket, day_names: days, week_rows: rows, day_first: first, day_last: last)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp init_today(socket, today) do
|
defp init_today(socket, today) do
|
||||||
assign(socket, current_date: today, cursor_date: today)
|
assign(socket, current_date: today, cursor_date: today)
|
||||||
end
|
end
|
||||||
|
@ -88,7 +82,7 @@ defmodule Shift73kWeb.ShiftAssignLive.Index do
|
||||||
defp init_shift_templates(%{assigns: %{current_user: user}} = socket) do
|
defp init_shift_templates(%{assigns: %{current_user: user}} = socket) do
|
||||||
shift_templates =
|
shift_templates =
|
||||||
Templates.list_shift_templates_by_user_id(user.id)
|
Templates.list_shift_templates_by_user_id(user.id)
|
||||||
|> Enum.map(fn t -> shift_template_option(t, user.fave_shift_template_id) end)
|
|> Stream.map(fn t -> shift_template_option(t, user.fave_shift_template_id) end)
|
||||||
|> Enum.concat([@custom_shift_opt])
|
|> Enum.concat([@custom_shift_opt])
|
||||||
|
|
||||||
assign(socket, :shift_templates, shift_templates)
|
assign(socket, :shift_templates, shift_templates)
|
||||||
|
@ -123,23 +117,31 @@ defmodule Shift73kWeb.ShiftAssignLive.Index do
|
||||||
|> Enum.map(&Timex.day_shortname/1)
|
|> Enum.map(&Timex.day_shortname/1)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp week_rows(cursor_date, week_start_at) do
|
defp date_range(cursor_date, week_start_at) do
|
||||||
first =
|
|
||||||
cursor_date
|
|
||||||
|> Timex.beginning_of_month()
|
|
||||||
|> Timex.beginning_of_week(week_start_at)
|
|
||||||
|
|
||||||
last =
|
last =
|
||||||
cursor_date
|
cursor_date
|
||||||
|> Timex.end_of_month()
|
|> Timex.end_of_month()
|
||||||
|> Timex.end_of_week(week_start_at)
|
|> Timex.end_of_week(week_start_at)
|
||||||
|
|
||||||
week_rows =
|
cursor_date
|
||||||
Interval.new(from: first, until: last, right_open: false)
|
|> Timex.beginning_of_month()
|
||||||
|> Enum.map(&NaiveDateTime.to_date(&1))
|
|> Timex.beginning_of_week(week_start_at)
|
||||||
|> Enum.chunk_every(7)
|
|> Date.range(last)
|
||||||
|
end
|
||||||
|
|
||||||
{first, last, week_rows}
|
defp assign_date_range(%{assigns: %{current_user: user}} = socket) do
|
||||||
|
date_range = date_range(socket.assigns.cursor_date, user.week_start_at)
|
||||||
|
assign(socket, :date_range, date_range)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp week_rows(%Date.Range{} = date_range) do
|
||||||
|
Interval.new(from: date_range.first, until: date_range.last, right_open: false)
|
||||||
|
|> Stream.map(&NaiveDateTime.to_date(&1))
|
||||||
|
|> Enum.chunk_every(7)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp assign_week_rows(%{assigns: %{date_range: date_range}} = socket) do
|
||||||
|
assign(socket, :week_rows, week_rows(date_range))
|
||||||
end
|
end
|
||||||
|
|
||||||
def day_color(day, current_date, cursor_date, selected_days) do
|
def day_color(day, current_date, cursor_date, selected_days) do
|
||||||
|
@ -180,17 +182,11 @@ defmodule Shift73kWeb.ShiftAssignLive.Index do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp set_month(socket, new_cursor_date) do
|
defp update_calendar(socket) do
|
||||||
{first, last, rows} = week_rows(new_cursor_date, socket.assigns.current_user.week_start_at)
|
socket
|
||||||
|
|> assign_date_range()
|
||||||
assigns = [
|
|> assign_week_rows()
|
||||||
cursor_date: new_cursor_date,
|
|> assign_known_shifts()
|
||||||
week_rows: rows,
|
|
||||||
day_first: first,
|
|
||||||
day_last: last
|
|
||||||
]
|
|
||||||
|
|
||||||
assign(socket, assigns) |> assign_known_shifts()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
@ -236,7 +232,10 @@ defmodule Shift73kWeb.ShiftAssignLive.Index do
|
||||||
Timex.shift(socket.assigns.cursor_date, months: months)
|
Timex.shift(socket.assigns.cursor_date, months: months)
|
||||||
end
|
end
|
||||||
|
|
||||||
{:noreply, set_month(socket, new_cursor)}
|
socket
|
||||||
|
|> assign(:cursor_date, new_cursor)
|
||||||
|
|> update_calendar()
|
||||||
|
|> live_noreply()
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
@ -260,9 +259,9 @@ defmodule Shift73kWeb.ShiftAssignLive.Index do
|
||||||
@impl true
|
@impl true
|
||||||
def handle_event("select-day", %{"day" => day}, socket) do
|
def handle_event("select-day", %{"day" => day}, socket) do
|
||||||
selected_days =
|
selected_days =
|
||||||
case day_index = Enum.find_index(socket.assigns.selected_days, fn d -> d == day end) do
|
case Enum.member?(socket.assigns.selected_days, day) do
|
||||||
nil -> [day | socket.assigns.selected_days]
|
false -> [day | socket.assigns.selected_days]
|
||||||
_ -> List.delete_at(socket.assigns.selected_days, day_index)
|
true -> Enum.reject(socket.assigns.selected_days, fn d -> d == day end)
|
||||||
end
|
end
|
||||||
|
|
||||||
{:noreply, assign(socket, :selected_days, selected_days)}
|
{:noreply, assign(socket, :selected_days, selected_days)}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
<h2 class="mb-3 mb-sm-0">
|
<h2 class="mb-3 mb-sm-0">
|
||||||
<%= icon_div @socket, "bi-calendar2-plus", [class: "icon baseline"] %>
|
<%= icon_div @socket, "bi-calendar2-plus", [class: "icon baseline"] %>
|
||||||
Assign Shift To Dates
|
Schedule Shifts
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<div class="row justify-content-center mt-4">
|
<div class="row justify-content-center mt-4">
|
||||||
|
|
|
@ -1,17 +1,44 @@
|
||||||
defmodule Shift73kWeb.ShiftLive.Index do
|
defmodule Shift73kWeb.ShiftLive.Index do
|
||||||
use Shift73kWeb, :live_view
|
use Shift73kWeb, :live_view
|
||||||
|
use Timex
|
||||||
|
|
||||||
alias Shift73k.Shifts
|
alias Shift73k.Shifts
|
||||||
alias Shift73k.Shifts.Shift
|
alias Shift73k.Shifts.Shift
|
||||||
|
alias Shift73kWeb.Roles
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def mount(_params, _session, socket) do
|
def mount(_params, session, socket) do
|
||||||
{:ok, assign(socket, :shifts, list_shifts())}
|
socket
|
||||||
|
|> assign_defaults(session)
|
||||||
|
|> live_okreply()
|
||||||
|
|
||||||
|
# {:ok, assign(socket, :shifts, list_shifts())}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_params(params, _url, socket) do
|
def handle_params(params, _url, socket) do
|
||||||
{:noreply, apply_action(socket, socket.assigns.live_action, params)}
|
current_user = socket.assigns.current_user
|
||||||
|
live_action = socket.assigns.live_action
|
||||||
|
shift = shift_from_params(params)
|
||||||
|
|
||||||
|
if Roles.can?(current_user, shift, live_action) do
|
||||||
|
socket
|
||||||
|
# |> assign_shift_templates()
|
||||||
|
# |> assign_modal_close_handlers()
|
||||||
|
|> init_today(Timex.today())
|
||||||
|
|> assign_date_range()
|
||||||
|
|> assign_known_shifts()
|
||||||
|
|> assign(:delete_shift, nil)
|
||||||
|
|> apply_action(socket.assigns.live_action, params)
|
||||||
|
|> live_noreply()
|
||||||
|
else
|
||||||
|
socket
|
||||||
|
|> put_flash(:error, "Unauthorised")
|
||||||
|
|> redirect(to: "/")
|
||||||
|
|> live_noreply()
|
||||||
|
end
|
||||||
|
|
||||||
|
# {:noreply, apply_action(socket, socket.assigns.live_action, params)}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp apply_action(socket, :edit, %{"id" => id}) do
|
defp apply_action(socket, :edit, %{"id" => id}) do
|
||||||
|
@ -32,15 +59,57 @@ defmodule Shift73kWeb.ShiftLive.Index do
|
||||||
|> assign(:shift, nil)
|
|> assign(:shift, nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp shift_from_params(params)
|
||||||
|
|
||||||
|
defp shift_from_params(%{"id" => id}),
|
||||||
|
do: Shifts.get_shift!(id)
|
||||||
|
|
||||||
|
defp shift_from_params(_params), do: %Shift{}
|
||||||
|
|
||||||
|
defp init_today(socket, today) do
|
||||||
|
assign(socket, current_date: today, cursor_date: today)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp assign_date_range(%{assigns: %{cursor_date: cursor_date}} = socket) do
|
||||||
|
assign(socket, date_range: date_range(cursor_date))
|
||||||
|
end
|
||||||
|
|
||||||
|
defp date_range(cursor_date) do
|
||||||
|
cursor_date
|
||||||
|
|> Timex.beginning_of_month()
|
||||||
|
|> Date.range(Timex.end_of_month(cursor_date))
|
||||||
|
end
|
||||||
|
|
||||||
|
defp assign_known_shifts(socket) do
|
||||||
|
user = socket.assigns.current_user
|
||||||
|
shifts = Shifts.list_shifts_by_user_in_date_range(user.id, socket.assigns.date_range)
|
||||||
|
assign(socket, :shifts, shifts)
|
||||||
|
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)
|
||||||
{:ok, _} = Shifts.delete_shift(shift)
|
{:ok, _} = Shifts.delete_shift(shift)
|
||||||
|
|
||||||
{:noreply, assign(socket, :shifts, list_shifts())}
|
{:noreply, assign_known_shifts(socket)}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp list_shifts do
|
@impl true
|
||||||
Shifts.list_shifts()
|
def handle_event("month-nav", %{"month" => direction}, socket) do
|
||||||
|
new_cursor =
|
||||||
|
cond do
|
||||||
|
direction == "now" ->
|
||||||
|
Timex.today()
|
||||||
|
|
||||||
|
true ->
|
||||||
|
months = (direction == "prev" && -1) || 1
|
||||||
|
Timex.shift(socket.assigns.cursor_date, months: months)
|
||||||
|
end
|
||||||
|
|
||||||
|
socket
|
||||||
|
|> assign(:cursor_date, new_cursor)
|
||||||
|
|> assign_date_range()
|
||||||
|
|> assign_known_shifts()
|
||||||
|
|> live_noreply()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
<h1>Listing Shifts</h1>
|
|
||||||
|
|
||||||
<%= if @live_action in [:new, :edit] do %>
|
<%= if @live_action in [:new, :edit] do %>
|
||||||
<%= live_modal @socket, Shift73kWeb.ShiftLive.FormComponent,
|
<%= live_modal @socket, Shift73kWeb.ShiftLive.FormComponent,
|
||||||
id: @shift.id || :new,
|
id: @shift.id || :new,
|
||||||
|
@ -9,41 +7,87 @@
|
||||||
return_to: Routes.shift_index_path(@socket, :index) %>
|
return_to: Routes.shift_index_path(@socket, :index) %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Subject</th>
|
|
||||||
<th>Location</th>
|
|
||||||
<th>Description</th>
|
|
||||||
<th>Time zone</th>
|
|
||||||
<th>Date</th>
|
|
||||||
<th>Time zone</th>
|
|
||||||
<th>Time start</th>
|
|
||||||
<th>Time end</th>
|
|
||||||
|
|
||||||
<th></th>
|
<div class="row justify-content-start justify-content-sm-center">
|
||||||
</tr>
|
<div class="col-md-10 col-xl-10">
|
||||||
</thead>
|
|
||||||
<tbody id="shifts">
|
<h2 class="mb-3 mb-sm-0">
|
||||||
<%= for shift <- @shifts do %>
|
<%= icon_div @socket, "bi-calendar2-date", [class: "icon baseline"] %>
|
||||||
<tr id="shift-<%= shift.id %>">
|
My Shifts
|
||||||
<td><%= shift.subject %></td>
|
</h2>
|
||||||
<td><%= shift.location %></td>
|
|
||||||
<td><%= shift.description %></td>
|
<%# month navigation %>
|
||||||
<td><%= shift.time_zone %></td>
|
<div class="d-flex justify-content-between align-items-end mt-4">
|
||||||
<td><%= shift.date %></td>
|
<h3 class="text-muted mb-0">
|
||||||
<td><%= shift.time_zone %></td>
|
<%= Timex.format!(@cursor_date, "{Mfull} {YYYY}") %>
|
||||||
<td><%= shift.time_start %></td>
|
</h3>
|
||||||
<td><%= shift.time_end %></td>
|
<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(Timex.today(), :month), do: "disabled" %>>
|
||||||
|
<%= icon_div @socket, "bi-asterisk", [class: "icon baseline"] %>
|
||||||
|
<span class="d-none d-sm-inline">Today</span>
|
||||||
|
</button>
|
||||||
|
<button type="button" phx-click="month-nav" phx-value-month="prev" class="btn btn-primary">
|
||||||
|
<%= icon_div @socket, "bi-chevron-left", [class: "icon baseline"] %>
|
||||||
|
<span class="d-none d-sm-inline">Prev</span>
|
||||||
|
</button>
|
||||||
|
<button type="button" phx-click="month-nav" phx-value-month="next" class="btn btn-primary">
|
||||||
|
<span class="d-none d-sm-inline">Next</span>
|
||||||
|
<%= icon_div @socket, "bi-chevron-right", [class: "icon baseline", style: "margin-left:0.125rem;"] %>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<dl>
|
||||||
|
<%= for day <- Enum.to_list(@date_range) do %>
|
||||||
|
<% Date.day_of_week(day, @current_user.week_start_at) |> IO.inspect(label: "day in date_range") %>
|
||||||
|
<%= if Date.day_of_week(day, @current_user.week_start_at) == 1 do %>
|
||||||
|
<div class="border-top mt-4 mb-4"></div>
|
||||||
|
<% end %>
|
||||||
|
<dt>
|
||||||
|
<%= Timex.format!(day, "{WDfull}, {Mshort} {D}") %>
|
||||||
|
</dt>
|
||||||
|
<% day_shifts = Enum.filter(@shifts, fn s -> s.date == day end) %>
|
||||||
|
<%= if !Enum.empty?(day_shifts) do %>
|
||||||
|
<dd id="day-<%= day.day %>">
|
||||||
|
<%= for shift <- day_shifts do %>
|
||||||
|
<div class="row gx-2" id="shift-<%= shift.id %>">
|
||||||
|
<div class="col-4 col-md-3 col-lg-2 text-end">
|
||||||
|
<div>
|
||||||
|
<%= format_shift_time(shift.time_start) |> String.trim_trailing("m") %>
|
||||||
|
—
|
||||||
|
<%= format_shift_time(shift.time_end) |> String.trim_trailing("m") %>
|
||||||
|
</div>
|
||||||
|
<div style="font-size: smaller;"><%= shift.time_zone %></div>
|
||||||
|
</div>
|
||||||
|
<div class="col-8 col-md-9 col-lg-10">
|
||||||
|
<div>
|
||||||
|
<%= shift.subject %>
|
||||||
|
<%= if shift.location do %>
|
||||||
|
<span class="text-muted">(<%= shift.location %>)</span>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<div style="font-size: smaller;"><%= shift.description %></div>
|
||||||
|
<div style="font-size: smaller;">
|
||||||
|
<span><%= live_redirect "Show", to: Routes.shift_show_path(@socket, :show, shift) %></span>
|
||||||
|
<span><%= live_patch "Edit", to: Routes.shift_index_path(@socket, :edit, shift) %></span>
|
||||||
|
<span><%= link "Delete", to: "#", phx_click: "delete", phx_value_id: shift.id, data: [confirm: "Are you sure?"] %></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<% else %>
|
||||||
|
<dd><em>No shift scheduled</em></dd>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</dl>
|
||||||
|
|
||||||
<td>
|
|
||||||
<span><%= live_redirect "Show", to: Routes.shift_show_path(@socket, :show, shift) %></span>
|
|
||||||
<span><%= live_patch "Edit", to: Routes.shift_index_path(@socket, :edit, shift) %></span>
|
|
||||||
<span><%= link "Delete", to: "#", phx_click: "delete", phx_value_id: shift.id, data: [confirm: "Are you sure?"] %></span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<% end %>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<span><%= live_patch "New Shift", to: Routes.shift_index_path(@socket, :new) %></span>
|
<span><%= live_patch "New Shift", to: Routes.shift_index_path(@socket, :new) %></span>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
|
@ -26,11 +26,6 @@
|
||||||
<%= @shift.description %>
|
<%= @shift.description %>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>
|
|
||||||
<strong>Time zone:</strong>
|
|
||||||
<%= @shift.time_zone %>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<strong>Date:</strong>
|
<strong>Date:</strong>
|
||||||
<%= @shift.date %>
|
<%= @shift.date %>
|
||||||
|
|
|
@ -5,6 +5,7 @@ defmodule Shift73kWeb.Roles do
|
||||||
|
|
||||||
alias Shift73k.Accounts.User
|
alias Shift73k.Accounts.User
|
||||||
alias Shift73k.Shifts.Templates.ShiftTemplate
|
alias Shift73k.Shifts.Templates.ShiftTemplate
|
||||||
|
alias Shift73k.Shifts.Shift
|
||||||
|
|
||||||
@type entity :: struct()
|
@type entity :: struct()
|
||||||
@type action :: :new | :index | :edit | :show | :delete | :edit_role
|
@type action :: :new | :index | :edit | :show | :delete | :edit_role
|
||||||
|
@ -16,11 +17,19 @@ defmodule Shift73kWeb.Roles do
|
||||||
def can?(%User{role: :admin}, %ShiftTemplate{}, _any), do: true
|
def can?(%User{role: :admin}, %ShiftTemplate{}, _any), do: true
|
||||||
def can?(%User{}, %ShiftTemplate{}, :index), do: true
|
def can?(%User{}, %ShiftTemplate{}, :index), do: true
|
||||||
def can?(%User{}, %ShiftTemplate{}, :new), do: true
|
def can?(%User{}, %ShiftTemplate{}, :new), do: true
|
||||||
# def can?(%User{}, %ShiftTemplate{}, :show), do: true
|
# def can?(%User{id: id}, %ShiftTemplate{user_id: id}, :show), do: true
|
||||||
def can?(%User{id: id}, %ShiftTemplate{user_id: id}, :edit), do: true
|
def can?(%User{id: id}, %ShiftTemplate{user_id: id}, :edit), do: true
|
||||||
def can?(%User{id: id}, %ShiftTemplate{user_id: id}, :clone), do: true
|
def can?(%User{id: id}, %ShiftTemplate{user_id: id}, :clone), do: true
|
||||||
def can?(%User{id: id}, %ShiftTemplate{user_id: id}, :delete), do: true
|
def can?(%User{id: id}, %ShiftTemplate{user_id: id}, :delete), do: true
|
||||||
|
|
||||||
|
# Shifts / Shift
|
||||||
|
def can?(%User{role: :admin}, %Shift{}, _any), do: true
|
||||||
|
def can?(%User{}, %Shift{}, :index), do: true
|
||||||
|
def can?(%User{}, %Shift{}, :new), do: true
|
||||||
|
def can?(%User{id: id}, %Shift{user_id: id}, :show), do: true
|
||||||
|
def can?(%User{id: id}, %Shift{user_id: id}, :edit), do: true
|
||||||
|
def can?(%User{id: id}, %Shift{user_id: id}, :delete), do: true
|
||||||
|
|
||||||
# Accounts / User
|
# Accounts / User
|
||||||
def can?(%User{role: :admin}, %User{}, _any), do: true
|
def can?(%User{role: :admin}, %User{}, _any), do: true
|
||||||
def can?(%User{role: :manager}, %User{}, :index), do: true
|
def can?(%User{role: :manager}, %User{}, :index), do: true
|
||||||
|
|
|
@ -10,7 +10,13 @@
|
||||||
<li>
|
<li>
|
||||||
<%= link nav_link_opts(@conn, to: Routes.shift_assign_index_path(@conn, :index), class: "dropdown-item") do %>
|
<%= link nav_link_opts(@conn, to: Routes.shift_assign_index_path(@conn, :index), class: "dropdown-item") do %>
|
||||||
<%= icon_div @conn, "bi-calendar2-plus", [class: "icon baseline me-1"] %>
|
<%= icon_div @conn, "bi-calendar2-plus", [class: "icon baseline me-1"] %>
|
||||||
Assign Shift To Dates
|
Schedule Shifts
|
||||||
|
<% end %>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<%= link nav_link_opts(@conn, to: Routes.shift_index_path(@conn, :index), class: "dropdown-item") do %>
|
||||||
|
<%= icon_div @conn, "bi-card-list", [class: "icon baseline me-1"] %>
|
||||||
|
My Scheduled Shifts
|
||||||
<% end %>
|
<% end %>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
|
|
|
@ -58,7 +58,7 @@ extra_mock_users = ~s([
|
||||||
mock_users =
|
mock_users =
|
||||||
extra_mock_users
|
extra_mock_users
|
||||||
|> Jason.decode!()
|
|> Jason.decode!()
|
||||||
|> Enum.concat(mock_users)
|
|> Stream.concat(mock_users)
|
||||||
|> Enum.map(fn e ->
|
|> Enum.map(fn e ->
|
||||||
add_dt = NaiveDateTime.from_iso8601!(e["inserted_at"])
|
add_dt = NaiveDateTime.from_iso8601!(e["inserted_at"])
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue