progress switching to Timex and allowing user to set week_start_at in settings
This commit is contained in:
parent
4031640e1d
commit
235bcc5af3
17 changed files with 130 additions and 17 deletions
|
@ -35,6 +35,7 @@ import "../node_modules/@mdi/svg/svg/head-question-outline.svg"; // forgot passw
|
||||||
import "../node_modules/bootstrap-icons/icons/people.svg"; // users management
|
import "../node_modules/bootstrap-icons/icons/people.svg"; // users management
|
||||||
// calendar/event icons
|
// calendar/event icons
|
||||||
import "../node_modules/bootstrap-icons/icons/calendar3-event.svg";
|
import "../node_modules/bootstrap-icons/icons/calendar3-event.svg";
|
||||||
|
import "../node_modules/bootstrap-icons/icons/calendar3-range.svg";
|
||||||
import "../node_modules/bootstrap-icons/icons/clock-history.svg"; // shift template
|
import "../node_modules/bootstrap-icons/icons/clock-history.svg"; // shift template
|
||||||
import "../node_modules/bootstrap-icons/icons/tag.svg";
|
import "../node_modules/bootstrap-icons/icons/tag.svg";
|
||||||
import "../node_modules/bootstrap-icons/icons/hourglass.svg";
|
import "../node_modules/bootstrap-icons/icons/hourglass.svg";
|
||||||
|
|
|
@ -462,4 +462,15 @@ defmodule Shift73k.Accounts do
|
||||||
|> where(id: ^user_id)
|
|> where(id: ^user_id)
|
||||||
|> Repo.update_all(set: [fave_shift_template_id: nil])
|
|> Repo.update_all(set: [fave_shift_template_id: nil])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
## Week Start at
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Sets the "week start at" day for user
|
||||||
|
"""
|
||||||
|
def set_user_week_start_at(user_id, day) do
|
||||||
|
User
|
||||||
|
|> where(id: ^user_id)
|
||||||
|
|> Repo.update_all(set: [week_start_at: day])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
defmodule Shift73k.Util.Dt do
|
defmodule Shift73k.Util.Dt do
|
||||||
@app_vars Application.get_env(:shift73k, :app_global_vars, time_zone: "America/New_York")
|
@app_vars Application.get_env(:shift73k, :app_global_vars, time_zone: "America/New_York")
|
||||||
@time_zone @app_vars[:time_zone]
|
@app_time_zone @app_vars[:time_zone]
|
||||||
|
|
||||||
def ndt_to_local(%NaiveDateTime{} = ndt), do: DateTime.from_naive(ndt, @time_zone)
|
def app_time_zone, do: @app_time_zone
|
||||||
|
|
||||||
def format_dt_local({:ok, dt_local}, fstr), do: Calendar.strftime(dt_local, fstr)
|
|
||||||
|
|
||||||
def format_ndt(%NaiveDateTime{} = ndt, fstr), do: ndt |> ndt_to_local() |> format_dt_local(fstr)
|
|
||||||
end
|
end
|
||||||
|
|
10
lib/shift73k_web/live/shift_assign_live/index.ex
Normal file
10
lib/shift73k_web/live/shift_assign_live/index.ex
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
defmodule Shift73kWeb.ShiftAssignLive.Index do
|
||||||
|
use Shift73kWeb, :live_view
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def mount(_params, session, socket) do
|
||||||
|
socket
|
||||||
|
|> assign_defaults(session)
|
||||||
|
|> live_okreply()
|
||||||
|
end
|
||||||
|
end
|
4
lib/shift73k_web/live/shift_assign_live/index.html.leex
Normal file
4
lib/shift73k_web/live/shift_assign_live/index.html.leex
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<h2 class="mb-3 mb-sm-0">
|
||||||
|
<%= icon_div @socket, "bi-clock-history", [class: "icon baseline"] %>
|
||||||
|
Assign Shift To Dates
|
||||||
|
</h2>
|
|
@ -1,5 +1,6 @@
|
||||||
defmodule Shift73kWeb.ShiftTemplateLive.DeleteComponent do
|
defmodule Shift73kWeb.ShiftTemplateLive.DeleteComponent do
|
||||||
use Shift73kWeb, :live_component
|
use Shift73kWeb, :live_component
|
||||||
|
use Timex
|
||||||
|
|
||||||
alias Shift73k.Shifts.Templates
|
alias Shift73k.Shifts.Templates
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
Are you sure you want to delete "<%= @delete_shift_template.subject %>
|
Are you sure you want to delete "<%= @delete_shift_template.subject %>
|
||||||
(<%= @delete_shift_template.time_start |> Calendar.strftime("%I:%M%P") %>
|
(<%= @delete_shift_template.time_start |> Timex.format!("{h12}:{m}{am}") %>
|
||||||
—
|
—
|
||||||
<%= @delete_shift_template.time_end |> Calendar.strftime("%I:%M%P") %>)"?
|
<%= @delete_shift_template.time_end |> Timex.format!("{h12}:{m}{am}") %>)"?
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
defmodule Shift73kWeb.ShiftTemplateLive.FormComponent do
|
defmodule Shift73kWeb.ShiftTemplateLive.FormComponent do
|
||||||
use Shift73kWeb, :live_component
|
use Shift73kWeb, :live_component
|
||||||
|
|
||||||
|
import Shift73kWeb.ShiftTemplateLive.Index, only: [format_shift_length: 1]
|
||||||
|
|
||||||
alias Shift73k.Shifts.Templates
|
alias Shift73k.Shifts.Templates
|
||||||
alias Shift73k.Shifts.Templates.ShiftTemplate
|
alias Shift73k.Shifts.Templates.ShiftTemplate
|
||||||
|
|
||||||
|
@ -16,8 +18,7 @@ defmodule Shift73kWeb.ShiftTemplateLive.FormComponent do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp assign_shift_length(socket, shift_template) do
|
defp assign_shift_length(socket, shift_template) do
|
||||||
shift_length = ShiftTemplate.shift_length_h_m(shift_template)
|
assign(socket, :shift_length, format_shift_length(shift_template))
|
||||||
assign(socket, :shift_length, shift_length)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
defp prep_template_params(params, current_user) do
|
defp prep_template_params(params, current_user) do
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="valid-feedback d-block text-primary">Shift length: <%= @shift_length |> elem(0) %>h <%= @shift_length |> elem(1) %>m</div>
|
<div class="valid-feedback d-block text-primary">Shift length: <%= @shift_length %></div>
|
||||||
|
|
||||||
<div class="phx-orphaned-feedback" phx-feedback-for="<%= input_id(f, :time_start) %>">
|
<div class="phx-orphaned-feedback" phx-feedback-for="<%= input_id(f, :time_start) %>">
|
||||||
<%= error_tag f, :time_start %>
|
<%= error_tag f, :time_start %>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
defmodule Shift73kWeb.ShiftTemplateLive.Index do
|
defmodule Shift73kWeb.ShiftTemplateLive.Index do
|
||||||
use Shift73kWeb, :live_view
|
use Shift73kWeb, :live_view
|
||||||
|
use Timex
|
||||||
|
|
||||||
alias Shift73k.Accounts
|
alias Shift73k.Accounts
|
||||||
alias Shift73k.Shifts.Templates
|
alias Shift73k.Shifts.Templates
|
||||||
|
@ -105,4 +106,15 @@ defmodule Shift73kWeb.ShiftTemplateLive.Index do
|
||||||
def handle_info({:put_flash_message, {flash_type, msg}}, socket) do
|
def handle_info({:put_flash_message, {flash_type, msg}}, socket) do
|
||||||
socket |> put_flash(flash_type, msg) |> live_noreply()
|
socket |> put_flash(flash_type, msg) |> live_noreply()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def format_shift_length(shift_template) do
|
||||||
|
shift_template
|
||||||
|
|> ShiftTemplate.shift_length()
|
||||||
|
|> Timex.Duration.from_minutes()
|
||||||
|
|> Timex.format_duration()
|
||||||
|
|> String.replace("PT", "")
|
||||||
|
|> String.replace("H", "h ")
|
||||||
|
|> String.replace("M", "m")
|
||||||
|
|> String.trim()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -57,13 +57,12 @@
|
||||||
<span class="visually-hidden">Hours:</span>
|
<span class="visually-hidden">Hours:</span>
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<%= template.time_start |> Calendar.strftime("%I:%M%P") %>
|
<%= template.time_start |> Timex.format!("{h12}:{m}{am}") %>
|
||||||
—
|
—
|
||||||
<%= template.time_end |> Calendar.strftime("%I:%M%P") %>
|
<%= template.time_end |> Timex.format!("{h12}:{m}{am}") %>
|
||||||
<span class="text-muted">
|
<span class="text-muted">
|
||||||
<span class="visually-hidden">Shift length:</span>
|
<span class="visually-hidden">Shift length:</span>
|
||||||
<% shift_len = ShiftTemplate.shift_length_h_m(template) %>
|
(<%= format_shift_length(template) %>)
|
||||||
(<%= shift_len |> elem(0) %>h <%= shift_len |> elem(1) %>m)
|
|
||||||
</span>
|
</span>
|
||||||
<span class="valid-feedback d-block text-muted mt-n1">TZ: <%= template.time_zone %></span>
|
<span class="valid-feedback d-block text-muted mt-n1">TZ: <%= template.time_zone %></span>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
defmodule Shift73kWeb.UserLive.Settings do
|
defmodule Shift73kWeb.UserLive.Settings do
|
||||||
use Shift73kWeb, :live_view
|
use Shift73kWeb, :live_view
|
||||||
|
|
||||||
|
alias Shift73k.Accounts
|
||||||
alias Shift73k.Accounts.User
|
alias Shift73k.Accounts.User
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
@ -36,4 +37,11 @@ defmodule Shift73kWeb.UserLive.Settings do
|
||||||
def handle_info({:clear_flash_message, flash_type}, socket) do
|
def handle_info({:clear_flash_message, flash_type}, socket) do
|
||||||
socket |> clear_flash(flash_type) |> live_noreply()
|
socket |> clear_flash(flash_type) |> live_noreply()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_info({:reload_current_user, _}, socket) do
|
||||||
|
socket
|
||||||
|
|> assign(:current_user, Accounts.get_user!(socket.assigns.current_user.id))
|
||||||
|
|> live_noreply()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
<div class="row justify-content-center justify-content-md-start">
|
<div class="row justify-content-center justify-content-md-start">
|
||||||
<%= live_component @socket, Shift73kWeb.UserLive.Settings.Email, id: "email-#{@current_user.id}", current_user: @current_user %>
|
<%= live_component @socket, Shift73kWeb.UserLive.Settings.Email, id: "email-#{@current_user.id}", current_user: @current_user %>
|
||||||
<%= live_component @socket, Shift73kWeb.UserLive.Settings.Password, id: "password-#{@current_user.id}", current_user: @current_user %>
|
<%= live_component @socket, Shift73kWeb.UserLive.Settings.Password, id: "password-#{@current_user.id}", current_user: @current_user %>
|
||||||
|
<%= live_component @socket, Shift73kWeb.UserLive.Settings.WeekStart, id: "week_start-#{@current_user.id}", current_user: @current_user %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
35
lib/shift73k_web/live/user/settings/week_start.ex
Normal file
35
lib/shift73k_web/live/user/settings/week_start.ex
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
defmodule Shift73kWeb.UserLive.Settings.WeekStart do
|
||||||
|
use Shift73kWeb, :live_component
|
||||||
|
|
||||||
|
alias Shift73k.EctoEnums.WeekdayEnum
|
||||||
|
alias Shift73k.Accounts
|
||||||
|
# alias Shift73k.Accounts.User
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def update(%{current_user: user} = assigns, socket) do
|
||||||
|
socket
|
||||||
|
|> assign(id: assigns.id)
|
||||||
|
|> assign(current_user: user)
|
||||||
|
|> assign(form_week_start_at: user.week_start_at)
|
||||||
|
|> live_okreply()
|
||||||
|
end
|
||||||
|
|
||||||
|
def week_start_options do
|
||||||
|
WeekdayEnum.__enum_map__() |> Enum.map(fn {d, n} -> {Timex.day_name(n), d} end)
|
||||||
|
end
|
||||||
|
|
||||||
|
@iml true
|
||||||
|
def handle_event("changed", %{"calendar_view" => %{"week_start_at" => day}}, socket) do
|
||||||
|
{:noreply, assign(socket, form_week_start_at: String.to_existing_atom(day))}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_event("save", %{"calendar_view" => %{"week_start_at" => day}}, socket) do
|
||||||
|
Accounts.set_user_week_start_at(socket.assigns.current_user.id, day)
|
||||||
|
flash_msg = {:info, "Calendar view settings updated."}
|
||||||
|
send(self(), {:clear_flash_message, :error})
|
||||||
|
send(self(), {:put_flash_message, flash_msg})
|
||||||
|
send(self(), {:reload_current_user, true})
|
||||||
|
{:noreply, socket}
|
||||||
|
end
|
||||||
|
end
|
27
lib/shift73k_web/live/user/settings/week_start.html.leex
Normal file
27
lib/shift73k_web/live/user/settings/week_start.html.leex
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<div id="<%= @id %>" class="col-12 col-sm-10 col-md-6 col-lg-5 col-xl-4 col-xxl-3 mt-1">
|
||||||
|
|
||||||
|
<h3>Calendar view</h3>
|
||||||
|
|
||||||
|
<%= form_for :calendar_view, "#", [phx_change: :changed, phx_submit: :save, phx_target: @myself], fn cvf -> %>
|
||||||
|
|
||||||
|
<%= label cvf, :week_start_at, class: "form-label" %>
|
||||||
|
<div class="inner-addon left-addon mb-3">
|
||||||
|
<%= icon_div @socket, "bi-calendar3-range", [class: "icon is-left text-muted fs-5"] %>
|
||||||
|
<%= select cvf, :week_start_at, week_start_options(),
|
||||||
|
value: @current_user.week_start_at,
|
||||||
|
class: "form-select"
|
||||||
|
%>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<%= submit "Save",
|
||||||
|
class: "btn btn-primary",
|
||||||
|
disabled: @form_week_start_at == @current_user.week_start_at,
|
||||||
|
aria_disabled: (@form_week_start_at == @current_user.week_start_at) && "true" || false,
|
||||||
|
phx_disable_with: "Saving..."
|
||||||
|
%>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
</div>
|
|
@ -1,9 +1,10 @@
|
||||||
defmodule Shift73kWeb.UserManagementLive.Index do
|
defmodule Shift73kWeb.UserManagementLive.Index do
|
||||||
use Shift73kWeb, :live_view
|
use Shift73kWeb, :live_view
|
||||||
|
use Timex
|
||||||
|
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
import Shift73kWeb.Pagination
|
|
||||||
import Shift73k.Util.Dt
|
import Shift73k.Util.Dt
|
||||||
|
import Shift73kWeb.Pagination
|
||||||
|
|
||||||
alias Shift73k.Repo
|
alias Shift73k.Repo
|
||||||
alias Shift73k.Accounts
|
alias Shift73k.Accounts
|
||||||
|
@ -187,5 +188,9 @@ defmodule Shift73kWeb.UserManagementLive.Index do
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
def dt_out(ndt), do: format_ndt(ndt, "%Y %b %d, %I:%M %p")
|
def dt_out(ndt) do
|
||||||
|
ndt
|
||||||
|
|> Timex.to_datetime(app_time_zone())
|
||||||
|
|> Timex.format!("{YYYY} {Mshort} {D}, {h12}:{m} {AM}")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -96,6 +96,8 @@ defmodule Shift73kWeb.Router do
|
||||||
live "/templates/:id/edit", ShiftTemplateLive.Index, :edit
|
live "/templates/:id/edit", ShiftTemplateLive.Index, :edit
|
||||||
live "/templates/:id/clone", ShiftTemplateLive.Index, :clone
|
live "/templates/:id/clone", ShiftTemplateLive.Index, :clone
|
||||||
|
|
||||||
|
live "/assign", ShiftAssignLive.Index, :index
|
||||||
|
|
||||||
live "/shifts", ShiftLive.Index, :index
|
live "/shifts", ShiftLive.Index, :index
|
||||||
live "/shifts/new", ShiftLive.Index, :new
|
live "/shifts/new", ShiftLive.Index, :new
|
||||||
live "/shifts/:id/edit", ShiftLive.Index, :edit
|
live "/shifts/:id/edit", ShiftLive.Index, :edit
|
||||||
|
|
Loading…
Reference in a new issue