2021-03-12 12:47:06 -05:00
|
|
|
defmodule Shift73kWeb.ShiftAssignLive.Index do
|
|
|
|
use Shift73kWeb, :live_view
|
2021-03-12 17:26:37 -05:00
|
|
|
use Timex
|
|
|
|
|
|
|
|
alias Shift73k.EctoEnums.WeekdayEnum
|
2021-03-15 15:46:59 -04:00
|
|
|
alias Shift73k.Shifts.Templates
|
|
|
|
alias Shift73k.Shifts.Templates.ShiftTemplate
|
|
|
|
|
|
|
|
@custom_shift %ShiftTemplate{subject: "Custom shift", id: "custom-shift"}
|
|
|
|
@custom_shift_opt {@custom_shift.subject, @custom_shift.id}
|
2021-03-12 12:47:06 -05:00
|
|
|
|
|
|
|
@impl true
|
|
|
|
def mount(_params, session, socket) do
|
|
|
|
socket
|
|
|
|
|> assign_defaults(session)
|
2021-03-15 15:46:59 -04:00
|
|
|
|> assign(:custom_shift, @custom_shift)
|
|
|
|
|> assign(:show_template_btn_active, :false)
|
|
|
|
|> assign(:show_template_details, :false)
|
|
|
|
|> assign(:selected_days, [])
|
2021-03-12 12:47:06 -05:00
|
|
|
|> live_okreply()
|
|
|
|
end
|
2021-03-12 17:26:37 -05:00
|
|
|
|
2021-03-15 15:46:59 -04:00
|
|
|
@impl true
|
|
|
|
def handle_params(_params, _url, socket) do
|
|
|
|
socket
|
|
|
|
|> init_shift_templates()
|
|
|
|
|> init_shift_template()
|
|
|
|
|> show_details_if_custom()
|
|
|
|
|> assign_shift_length()
|
|
|
|
|> assign_shift_template_changeset()
|
|
|
|
|> init_today(Timex.today())
|
|
|
|
|> init_calendar()
|
|
|
|
|> init_known_shifts()
|
|
|
|
|> live_noreply()
|
|
|
|
end
|
|
|
|
|
|
|
|
defp get_shift_template("custom-shift"), do: @custom_shift
|
|
|
|
defp get_shift_template(template_id), do: Templates.get_shift_template(template_id)
|
|
|
|
|
|
|
|
defp assign_shift_length(%{assigns: %{shift_template: shift}} = socket) do
|
|
|
|
assign(socket, :shift_length, format_shift_length(shift))
|
|
|
|
end
|
|
|
|
|
|
|
|
defp init_known_shifts(%{assigns: %{current_user: user, week_rows: weeks}} = socket) do
|
|
|
|
days = weeks |> List.flatten()
|
|
|
|
first = weeks |> List.flatten() |> List.first()
|
|
|
|
socket
|
|
|
|
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
|
|
|
|
assign(socket, [current_date: today, cursor_date: today])
|
|
|
|
end
|
|
|
|
|
|
|
|
defp assign_shift_template_changeset(%{assigns: %{shift_template: shift}} = socket) do
|
|
|
|
cs = Templates.change_shift_template(shift)
|
|
|
|
assign(socket, :shift_template_changeset, cs)
|
|
|
|
end
|
|
|
|
|
|
|
|
defp init_shift_template(socket) do
|
|
|
|
first_list_id = socket.assigns.shift_templates |> hd() |> elem(1)
|
|
|
|
fave_id = socket.assigns.current_user.fave_shift_template_id
|
|
|
|
assign_shift_template(socket, (fave_id || first_list_id))
|
|
|
|
end
|
|
|
|
|
|
|
|
defp assign_shift_template(socket, template_id) do
|
|
|
|
assign(socket, :shift_template, get_shift_template(template_id))
|
|
|
|
end
|
|
|
|
|
|
|
|
defp init_shift_templates(%{assigns: %{current_user: user}} = socket) do
|
|
|
|
shift_templates =
|
|
|
|
Templates.list_shift_templates_by_user_id(user.id)
|
|
|
|
|> Enum.map(fn t -> shift_template_option(t, user.fave_shift_template_id) end)
|
|
|
|
|> Enum.concat([@custom_shift_opt])
|
|
|
|
assign(socket, :shift_templates, shift_templates)
|
|
|
|
end
|
|
|
|
|
|
|
|
defp shift_template_option(template, fave_id) do
|
|
|
|
label =
|
|
|
|
template.subject <> " (" <>
|
|
|
|
format_shift_time(template.time_start) <> "—" <>
|
|
|
|
format_shift_time(template.time_end) <> ")"
|
|
|
|
|
|
|
|
label =
|
|
|
|
case fave_id == template.id do
|
|
|
|
true -> label <> " ★"
|
|
|
|
false -> label
|
|
|
|
end
|
|
|
|
|
|
|
|
{label, template.id}
|
|
|
|
end
|
|
|
|
|
2021-03-12 17:26:37 -05:00
|
|
|
defp rotate_week(week_start_at) do
|
|
|
|
{a, b} = Enum.split_while(WeekdayEnum.__enum_map__(), fn {k, _v} -> k != week_start_at end)
|
|
|
|
b ++ a
|
|
|
|
end
|
|
|
|
|
|
|
|
defp day_names(week_start_at) do
|
|
|
|
week_start_at
|
|
|
|
|> rotate_week()
|
|
|
|
|> Keyword.values()
|
|
|
|
|> Enum.map(&Timex.day_shortname/1)
|
|
|
|
end
|
|
|
|
|
|
|
|
defp week_rows(cursor_date, week_start_at) do
|
|
|
|
first =
|
|
|
|
cursor_date
|
|
|
|
|> Timex.beginning_of_month()
|
|
|
|
|> Timex.beginning_of_week(week_start_at)
|
|
|
|
|
|
|
|
last =
|
|
|
|
cursor_date
|
|
|
|
|> Timex.end_of_month()
|
|
|
|
|> Timex.end_of_week(week_start_at)
|
|
|
|
|
2021-03-15 15:46:59 -04:00
|
|
|
week_rows =
|
|
|
|
Interval.new(from: first, until: last, right_open: false)
|
|
|
|
|> Enum.map(& NaiveDateTime.to_date(&1))
|
|
|
|
|> Enum.chunk_every(7)
|
2021-03-12 17:26:37 -05:00
|
|
|
|
2021-03-15 15:46:59 -04:00
|
|
|
{first, last, week_rows}
|
2021-03-12 17:26:37 -05:00
|
|
|
end
|
|
|
|
|
2021-03-15 15:46:59 -04:00
|
|
|
def day_color(day, current_date, cursor_date, selected_days) do
|
|
|
|
cond do
|
|
|
|
Enum.member?(selected_days, Date.to_string(day)) ->
|
|
|
|
cond do
|
|
|
|
Timex.compare(day, current_date, :days) == 0 -> "bg-triangle-info text-white"
|
|
|
|
day.month != cursor_date.month -> "bg-triangle-light text-gray"
|
|
|
|
true -> "bg-triangle-white"
|
|
|
|
end
|
|
|
|
|
|
|
|
Timex.compare(day, current_date, :days) == 0 -> "bg-info text-white"
|
|
|
|
|
|
|
|
day.month != cursor_date.month -> "bg-light text-gray"
|
|
|
|
|
|
|
|
true -> ""
|
|
|
|
end
|
2021-03-12 17:26:37 -05:00
|
|
|
end
|
|
|
|
|
2021-03-15 15:46:59 -04:00
|
|
|
defp prep_template_params(params, current_user) do
|
|
|
|
params
|
|
|
|
|> Map.put("time_start", Time.from_iso8601!("T#{params["time_start"]}:00"))
|
|
|
|
|> Map.put("time_end", Time.from_iso8601!("T#{params["time_end"]}:00"))
|
|
|
|
|> Map.put("user_id", current_user.id)
|
|
|
|
end
|
2021-03-12 17:26:37 -05:00
|
|
|
|
2021-03-15 15:46:59 -04:00
|
|
|
defp show_details_if_custom(socket) do
|
|
|
|
if (socket.assigns.shift_template.id != @custom_shift.id) || socket.assigns.show_template_details do
|
|
|
|
socket
|
|
|
|
else
|
|
|
|
socket
|
|
|
|
|> assign(:show_template_btn_active, :true)
|
|
|
|
|> push_event("toggle-template-details", %{targetId: "#templateDetailsCol"})
|
|
|
|
end
|
2021-03-12 17:26:37 -05:00
|
|
|
end
|
|
|
|
|
2021-03-15 15:46:59 -04:00
|
|
|
defp set_month(socket, new_cursor_date) do
|
|
|
|
{first, last, rows} = week_rows(new_cursor_date, socket.assigns.current_user.week_start_at)
|
2021-03-12 18:44:25 -05:00
|
|
|
|
|
|
|
assigns = [
|
2021-03-15 15:46:59 -04:00
|
|
|
cursor_date: new_cursor_date,
|
|
|
|
week_rows: rows,
|
|
|
|
day_first: first,
|
|
|
|
day_last: last
|
2021-03-12 18:44:25 -05:00
|
|
|
]
|
|
|
|
|
2021-03-15 15:46:59 -04:00
|
|
|
assign(socket, assigns)
|
2021-03-12 18:44:25 -05:00
|
|
|
end
|
|
|
|
|
2021-03-15 15:46:59 -04:00
|
|
|
@impl true
|
|
|
|
def handle_event("validate-shift-template", %{"shift_template" => params}, socket) do
|
|
|
|
params = prep_template_params(params, socket.assigns.current_user)
|
|
|
|
shift_template = socket.assigns.shift_template
|
2021-03-12 18:44:25 -05:00
|
|
|
|
2021-03-15 15:46:59 -04:00
|
|
|
cs =
|
|
|
|
shift_template
|
|
|
|
|> Templates.change_shift_template(params)
|
|
|
|
|> Map.put(:action, :validate)
|
|
|
|
|
|
|
|
socket
|
|
|
|
|> assign(:shift_template_changeset, cs)
|
|
|
|
|> assign(:shift_template, Map.merge(shift_template, cs.changes))
|
|
|
|
|> assign_shift_length()
|
|
|
|
|> live_noreply()
|
|
|
|
end
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
def handle_event("change-selected-template", %{"template_select" => %{"template" => template_id}}, socket) do
|
|
|
|
socket
|
|
|
|
|> assign_shift_template(template_id)
|
|
|
|
|> show_details_if_custom()
|
|
|
|
|> assign_shift_length()
|
|
|
|
|> assign_shift_template_changeset()
|
|
|
|
|> live_noreply()
|
|
|
|
end
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
def handle_event("month-nav", %{"month" => direction}, socket) do
|
|
|
|
new_cursor =
|
|
|
|
cond do
|
|
|
|
direction == "now" -> Timex.today()
|
|
|
|
true ->
|
|
|
|
months = m = direction == "prev" && -1 || 1
|
|
|
|
Timex.shift(socket.assigns.cursor_date, months: months)
|
|
|
|
end
|
|
|
|
|
|
|
|
{:noreply, set_month(socket, new_cursor)}
|
|
|
|
end
|
|
|
|
|
|
|
|
# @impl true
|
|
|
|
# def handle_event("prev-month", _, socket) do
|
|
|
|
# cursor_date = Timex.shift(socket.assigns.cursor_date, months: -1)
|
|
|
|
# {first, last, rows} = week_rows(cursor_date, socket.assigns.current_user.week_start_at)
|
|
|
|
|
|
|
|
# assigns = [
|
|
|
|
# cursor_date: cursor_date,
|
|
|
|
# week_rows: week_rows(cursor_date, socket.assigns.current_user.week_start_at)
|
|
|
|
# ]
|
|
|
|
|
|
|
|
# {:noreply, assign(socket, assigns)}
|
|
|
|
# end
|
|
|
|
|
|
|
|
# @impl true
|
|
|
|
# def handle_event("next-month", _, socket) do
|
|
|
|
# cursor_date = Timex.shift(socket.assigns.cursor_date, months: 1)
|
|
|
|
# {first, last, rows} = week_rows(cursor_date, socket.assigns.current_user.week_start_at)
|
2021-03-12 18:44:25 -05:00
|
|
|
|
2021-03-15 15:46:59 -04:00
|
|
|
# assigns = [
|
|
|
|
# cursor_date: cursor_date,
|
|
|
|
# week_rows: rows,
|
|
|
|
# day_first: first,
|
|
|
|
# day_last: last
|
|
|
|
# ]
|
|
|
|
|
|
|
|
# {:noreply, assign(socket, assigns)}
|
|
|
|
# end
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
def handle_event("toggle-template-details", %{"target_id" => target_id}, socket) do
|
|
|
|
socket
|
|
|
|
|> assign(:show_template_btn_active, !socket.assigns.show_template_btn_active)
|
|
|
|
|> push_event("toggle-template-details", %{targetId: target_id})
|
|
|
|
|> live_noreply()
|
|
|
|
end
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
def handle_event("collapse-shown", %{"target_id" => _target_id}, socket) do
|
|
|
|
{:noreply, assign(socket, :show_template_details, :true)}
|
|
|
|
end
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
def handle_event("collapse-hidden", %{"target_id" => _target_id}, socket) do
|
|
|
|
{:noreply, assign(socket, :show_template_details, :false)}
|
|
|
|
end
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
def handle_event("select-day", %{"day" => day}, socket) do
|
|
|
|
selected_days =
|
|
|
|
case day_index = Enum.find_index(socket.assigns.selected_days, fn d -> d == day end) do
|
|
|
|
nil -> [day | socket.assigns.selected_days]
|
|
|
|
_ -> List.delete_at(socket.assigns.selected_days, day_index)
|
|
|
|
end
|
|
|
|
|
|
|
|
{:noreply, assign(socket, :selected_days, selected_days)}
|
|
|
|
end
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
def handle_event("clear-days", _params, socket) do
|
|
|
|
{:noreply, assign(socket, :selected_days, [])}
|
2021-03-12 18:44:25 -05:00
|
|
|
end
|
2021-03-12 12:47:06 -05:00
|
|
|
end
|