From ecd4d83e3f58ca881b3a1063e8fcc5f8fb6289d7 Mon Sep 17 00:00:00 2001 From: Adam Piontek Date: Tue, 16 Mar 2021 11:00:33 -0400 Subject: [PATCH] saving shifts working --- assets/css/_bs-load.scss | 2 +- assets/css/app.scss | 27 ++++- lib/shift73k/shifts.ex | 10 ++ lib/shift73k/shifts/templates.ex | 2 +- .../live/shift_assign_live/index.ex | 99 ++++++++++++------- .../live/shift_assign_live/index.html.leex | 48 ++++++--- .../live/shift_template_live/index.html.leex | 8 +- .../live/user_management/index.html.leex | 8 +- .../templates/layout/_navbar.html.eex | 4 +- 9 files changed, 141 insertions(+), 67 deletions(-) diff --git a/assets/css/_bs-load.scss b/assets/css/_bs-load.scss index b7c2aa2f..50153ea3 100644 --- a/assets/css/_bs-load.scss +++ b/assets/css/_bs-load.scss @@ -31,7 +31,7 @@ @import "../node_modules/bootstrap/scss/accordion"; // @import "../node_modules/bootstrap/scss/breadcrumb"; @import "../node_modules/bootstrap/scss/pagination"; -// @import "../node_modules/bootstrap/scss/badge"; +@import "../node_modules/bootstrap/scss/badge"; @import "../node_modules/bootstrap/scss/alert"; @import "../node_modules/bootstrap/scss/progress"; // @import "../node_modules/bootstrap/scss/list-group"; diff --git a/assets/css/app.scss b/assets/css/app.scss index 722c55f2..6bed80f0 100644 --- a/assets/css/app.scss +++ b/assets/css/app.scss @@ -63,16 +63,32 @@ } /* calendar table rounded */ +table.table.table-calendar span.badge { + width: 100%; + max-width: 100%; + overflow: hidden; + text-overflow: clip; + white-space: nowrap; + padding-right: 0.7em; + border-right: 0.7em solid transparent; + margin-bottom: 0.1em; +} table.table.table-calendar thead tr th, table.table.table-calendar tbody tr td { - width: 14%; + width: 2.5rem; + max-width: 2.5rem; + white-space: nowrap; } table.table.table-calendar tbody tr td { font-size: $font-size-sm; - height: 3.5rem; + height: 4.1rem; padding: 0.2rem 0.4rem; + @include media-breakpoint-up(sm) { + height: 4.3rem; + padding: 0.2rem 0.5rem; + } @include media-breakpoint-up(md) { - height: 4.5rem; + height: 4.7rem; padding: 0.2rem 0.5rem; } @include media-breakpoint-up(lg) { @@ -90,6 +106,9 @@ table.table.table-calendar tbody tr td { } } +table.table.table-rounded > :not(:last-child) > :last-child > * { + border-bottom-color: $dark; +} table.table.table-rounded { border-collapse: separate; border-spacing: 0; @@ -103,7 +122,7 @@ table.table.table-rounded { th { border-top: 1px solid $table-border-color; border-right: 1px solid $table-border-color; - border-bottom: 2px solid $black !important; + // border-bottom: 2px solid $dark !important; border-left: none; &:first-child { border-top-left-radius: $border-radius; diff --git a/lib/shift73k/shifts.ex b/lib/shift73k/shifts.ex index d1902b86..93078c87 100644 --- a/lib/shift73k/shifts.ex +++ b/lib/shift73k/shifts.ex @@ -21,6 +21,16 @@ defmodule Shift73k.Shifts do Repo.all(Shift) end + def list_shifts_by_user_between_dates(user_id, start_date, end_date) do + q = from( + s in Shift, + select: %{date: s.date, subject: s.subject, time_start: s.time_start, time_end: s.time_end}, + where: s.user_id == ^user_id and s.date >= ^start_date and s.date < ^end_date, + order_by: [s.date, s.time_start] + ) + Repo.all(q) + end + @doc """ Gets a single shift. diff --git a/lib/shift73k/shifts/templates.ex b/lib/shift73k/shifts/templates.ex index 993f73a7..286f555d 100644 --- a/lib/shift73k/shifts/templates.ex +++ b/lib/shift73k/shifts/templates.ex @@ -22,7 +22,7 @@ defmodule Shift73k.Shifts.Templates do end def list_shift_templates_by_user_id(user_id) do - q = from s in ShiftTemplate, where: s.user_id == ^user_id, order_by: s.subject + q = from s in ShiftTemplate, where: s.user_id == ^user_id, order_by: [s.subject, s.time_start] Repo.all(q) end diff --git a/lib/shift73k_web/live/shift_assign_live/index.ex b/lib/shift73k_web/live/shift_assign_live/index.ex index 01e7326c..60535bbd 100644 --- a/lib/shift73k_web/live/shift_assign_live/index.ex +++ b/lib/shift73k_web/live/shift_assign_live/index.ex @@ -2,7 +2,11 @@ defmodule Shift73kWeb.ShiftAssignLive.Index do use Shift73kWeb, :live_view use Timex + alias Ecto.Multi + alias Shift73k.Repo alias Shift73k.EctoEnums.WeekdayEnum + alias Shift73k.Shifts + alias Shift73k.Shifts.Shift alias Shift73k.Shifts.Templates alias Shift73k.Shifts.Templates.ShiftTemplate @@ -30,7 +34,7 @@ defmodule Shift73kWeb.ShiftAssignLive.Index do |> assign_shift_template_changeset() |> init_today(Timex.today()) |> init_calendar() - |> init_known_shifts() + |> assign_known_shifts() |> live_noreply() end @@ -41,10 +45,12 @@ defmodule Shift73kWeb.ShiftAssignLive.Index 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 + defp assign_known_shifts(socket) do + user = socket.assigns.current_user + first = socket.assigns.day_first + last = socket.assigns.day_last + known_shifts = Shifts.list_shifts_by_user_between_dates(user.id, first, last) + assign(socket, :known_shifts, known_shifts) end defp init_calendar(%{assigns: %{current_user: user}} = socket) do @@ -170,7 +176,7 @@ defmodule Shift73kWeb.ShiftAssignLive.Index do day_last: last ] - assign(socket, assigns) + assign(socket, assigns) |> assign_known_shifts() end @impl true @@ -206,41 +212,13 @@ defmodule Shift73kWeb.ShiftAssignLive.Index do cond do direction == "now" -> Timex.today() true -> - months = m = direction == "prev" && -1 || 1 + months = 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) - - # 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 @@ -274,4 +252,55 @@ defmodule Shift73kWeb.ShiftAssignLive.Index do def handle_event("clear-days", _params, socket) do {:noreply, assign(socket, :selected_days, [])} end + + @impl true + def handle_event("save-days", _params, socket) do + # 1. collect attrs from loaded shift template + shift_data = shift_data_from_template(socket.assigns.shift_template) + + # 2. create list of shift attrs to insert + to_insert = Enum.map(socket.assigns.selected_days, &shift_from_day_and_shift_data(&1, shift_data)) + + # 3. insert the data + {status, msg} = insert_shifts(to_insert, length(socket.assigns.selected_days)) + + socket + |> put_flash(status, msg) + |> assign(:selected_days, []) + |> assign_known_shifts() + |> live_noreply() + end + + defp shift_data_from_template(shift_template) do + shift_template + |> Map.from_struct() + |> Map.drop([:__meta__, :id, :inserted_at, :updated_at, :user]) + end + + defp shift_from_day_and_shift_data(day, shift_data) do + now = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second) + date_data = %{date: Date.from_iso8601!(day), inserted_at: now, updated_at: now} + Map.merge(shift_data, date_data) + end + + defp insert_shifts(to_insert, day_count) do + Multi.new() + |> Multi.insert_all(:insert_all, Shift, to_insert) + |> Repo.transaction() + |> case do + {:ok, %{insert_all: {n, _}}} -> + if n == day_count do + {:success, "Successfully assigned shift to #{n} day(s)"} + else + {:warning, "Some error, only #{n} day(s) inserted but #{day_count} were selected"} + end + _ -> {:error, "Ope, unknown error inserting shifts, page the dev"} + end + end + + def shifts_to_show(day_shifts) do + if length(day_shifts) == 1 || length(day_shifts) > 2, + do: Enum.take(day_shifts, 1), + else: day_shifts + end end diff --git a/lib/shift73k_web/live/shift_assign_live/index.html.leex b/lib/shift73k_web/live/shift_assign_live/index.html.leex index 6fe3c5f8..c5136885 100644 --- a/lib/shift73k_web/live/shift_assign_live/index.html.leex +++ b/lib/shift73k_web/live/shift_assign_live/index.html.leex @@ -4,7 +4,7 @@
-
+
<%= form_for :template_select, "#", [phx_change: "change-selected-template"], fn sts -> %> <%= label sts, :template, "Select shift template to assign to dates", class: "form-label" %> @@ -15,8 +15,8 @@ <% end %>
@@ -137,8 +137,6 @@
- - <% end %>
@@ -167,15 +165,15 @@
@@ -196,9 +194,27 @@ <%= for week <- @week_rows do %> <%= for day <- week do %> - <%# day |> NaiveDateTime.to_date() |> IO.inspect() %> + <%= Timex.format!(day, "{0D}") %><%= if day.month != @cursor_date.month, do: "-#{Timex.format!(day, "{Mshort}")}" %> + + <% day_shifts = Enum.filter(@known_shifts, fn s -> s.date == day end) %> + <% shifts_to_show = shifts_to_show(day_shifts) %> + + <%= for shift <- shifts_to_show do %> + + + <%= shift.time_start |> Timex.format!("{h12}:{m}{am}") |> String.trim_trailing("m") %> + <%= shift.subject %> + + + <% end %> + + <%= if length(day_shifts) > 2 do %> + <%= length(day_shifts) - 1 %> more… + <% end %> + + <% end %> @@ -207,16 +223,16 @@ -
+
- - diff --git a/lib/shift73k_web/live/shift_template_live/index.html.leex b/lib/shift73k_web/live/shift_template_live/index.html.leex index 75e40f00..bb9bcd30 100644 --- a/lib/shift73k_web/live/shift_template_live/index.html.leex +++ b/lib/shift73k_web/live/shift_template_live/index.html.leex @@ -25,7 +25,7 @@ My Shift Templates <%= live_patch to: Routes.shift_template_index_path(@socket, :new), class: "btn btn-primary" do %> - <%= icon_div @socket, "bi-plus-circle-dotted", [class: "icon baseline", style: "margin-right:0.125rem;"] %> + <%= icon_div @socket, "bi-plus-circle-dotted", [class: "icon baseline"] %> New Shift Template <% end %>
@@ -100,14 +100,14 @@ <%= if Roles.can?(@current_user, template, :edit) do %> <%= live_patch to: Routes.shift_template_index_path(@socket, :edit, template), class: "btn btn-primary btn-sm text-nowrap" do %> - <%= icon_div @socket, "bi-pencil", [class: "icon baseline", style: "margin-right:0.125rem;"] %> + <%= icon_div @socket, "bi-pencil", [class: "icon baseline"] %> Edit <% end %> <% end %> <%= if Roles.can?(@current_user, template, :clone) do %> <%= live_patch to: Routes.shift_template_index_path(@socket, :clone, template), class: "btn btn-outline-primary btn-sm text-nowrap" do %> - <%= icon_div @socket, "bi-clipboard-plus", [class: "icon baseline", style: "margin-right:0.125rem;"] %> + <%= icon_div @socket, "bi-clipboard-plus", [class: "icon baseline"] %> Clone <% end %> <% end %> @@ -116,7 +116,7 @@ <%= if Roles.can?(@current_user, template, :delete) do %> <% end %> diff --git a/lib/shift73k_web/live/user_management/index.html.leex b/lib/shift73k_web/live/user_management/index.html.leex index d4f539ac..0279f882 100644 --- a/lib/shift73k_web/live/user_management/index.html.leex +++ b/lib/shift73k_web/live/user_management/index.html.leex @@ -98,14 +98,14 @@ <%= if Roles.can?(@current_user, user, :edit) do %> <%= live_patch to: Routes.user_management_index_path(@socket, :edit, user.id, Enum.into(@query, [])), class: "btn btn-primary btn-sm text-nowrap" do %> - <%= icon_div @socket, "bi-pencil", [class: "icon baseline", style: "margin-right:0.125rem;"] %> + <%= icon_div @socket, "bi-pencil", [class: "icon baseline"] %> Edit <% end %> <% end %> <%= if Roles.can?(@current_user, user, :delete) do %> <% end %> @@ -180,14 +180,14 @@ <%= if Roles.can?(@current_user, user, :edit) do %> <%= live_patch to: Routes.user_management_index_path(@socket, :edit, user.id, Enum.into(@query, [])), class: "btn btn-outline-primary btn-sm text-nowrap" do %> - <%= icon_div @socket, "bi-pencil", [class: "icon baseline", style: "margin-right:0.125rem;"] %> + <%= icon_div @socket, "bi-pencil", [class: "icon baseline"] %> Edit <% end %> <% end %> <%= if Roles.can?(@current_user, user, :delete) do %> <% end %> diff --git a/lib/shift73k_web/templates/layout/_navbar.html.eex b/lib/shift73k_web/templates/layout/_navbar.html.eex index e4dff3bf..ccf4a72a 100644 --- a/lib/shift73k_web/templates/layout/_navbar.html.eex +++ b/lib/shift73k_web/templates/layout/_navbar.html.eex @@ -16,7 +16,7 @@ <% else %> <%= link nav_link_opts(@conn, to: Routes.user_session_path(@conn, :new), class: "btn btn-outline-light d-block d-lg-none") do %> - <%= icon_div @conn, "bi-door-open", [class: "icon baseline", style: "margin-right:0.125rem;"] %> + <%= icon_div @conn, "bi-door-open", [class: "icon baseline"] %> Log in <% end %> <% end %> @@ -70,7 +70,7 @@ <%= if !@current_user do %> <%= link nav_link_opts(@conn, to: Routes.user_session_path(@conn, :new), class: "btn btn-outline-light d-none d-lg-block") do %> - <%= icon_div @conn, "bi-door-open", [class: "icon baseline", style: "margin-right:0.125rem;"] %> + <%= icon_div @conn, "bi-door-open", [class: "icon baseline"] %> Log in <% end %> <% end %>