initial shift template live view progress
This commit is contained in:
parent
73c97f194b
commit
57c8b5b322
9 changed files with 98 additions and 39 deletions
4
.iex.exs
4
.iex.exs
|
@ -3,5 +3,5 @@ import Ecto.Query
|
||||||
alias Shift73k.Repo
|
alias Shift73k.Repo
|
||||||
alias Shift73k.Accounts
|
alias Shift73k.Accounts
|
||||||
alias Shift73k.Accounts.User
|
alias Shift73k.Accounts.User
|
||||||
alias Shift73k.ShiftTemplates, as: STemplates
|
alias Shift73k.ShiftTemplates
|
||||||
alias Shift73k.ShiftTemplates.ShiftTemplate, as: STemplate
|
alias Shift73k.ShiftTemplates.ShiftTemplate
|
||||||
|
|
|
@ -5,7 +5,7 @@ import "../css/app.scss";
|
||||||
|
|
||||||
// Import icons for sprite-loader
|
// Import icons for sprite-loader
|
||||||
// navbar brand icon
|
// navbar brand icon
|
||||||
import "../node_modules/@mdi/svg/svg/skull-crossbones.svg"; // brand
|
import "../node_modules/bootstrap-icons/icons/calendar3-week.svg"; // brand
|
||||||
// menus etc
|
// menus etc
|
||||||
import "../node_modules/bootstrap-icons/icons/person-circle.svg"; // accounts menu
|
import "../node_modules/bootstrap-icons/icons/person-circle.svg"; // accounts menu
|
||||||
import "../node_modules/bootstrap-icons/icons/person-plus.svg"; // new user / register
|
import "../node_modules/bootstrap-icons/icons/person-plus.svg"; // new user / register
|
||||||
|
@ -35,6 +35,9 @@ import "../node_modules/bootstrap-icons/icons/arrow-repeat.svg"; // resend confi
|
||||||
import "../node_modules/bootstrap-icons/icons/door-open.svg"; // log in header
|
import "../node_modules/bootstrap-icons/icons/door-open.svg"; // log in header
|
||||||
import "../node_modules/@mdi/svg/svg/head-question-outline.svg"; // forgot password
|
import "../node_modules/@mdi/svg/svg/head-question-outline.svg"; // forgot password
|
||||||
import "../node_modules/bootstrap-icons/icons/people.svg"; // users management
|
import "../node_modules/bootstrap-icons/icons/people.svg"; // users management
|
||||||
|
// calendar/event icons
|
||||||
|
import "../node_modules/bootstrap-icons/icons/calendar3-event.svg"; // brand
|
||||||
|
import "../node_modules/bootstrap-icons/icons/clock-history.svg"; // brand
|
||||||
|
|
||||||
// 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
|
||||||
|
|
|
@ -21,6 +21,11 @@ defmodule Shift73k.ShiftTemplates do
|
||||||
Repo.all(ShiftTemplate)
|
Repo.all(ShiftTemplate)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def list_shift_templates_by_user_id(user_id) do
|
||||||
|
(from s in ShiftTemplate, where: s.user_id == ^user_id)
|
||||||
|
|> Repo.all()
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Gets a single shift_template.
|
Gets a single shift_template.
|
||||||
|
|
||||||
|
|
|
@ -2,17 +2,20 @@ defmodule Shift73k.ShiftTemplates.ShiftTemplate do
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
|
|
||||||
|
@app_vars Application.get_env(:shift73k, :app_global_vars, time_zone: "America/New_York")
|
||||||
|
@time_zone @app_vars[:time_zone]
|
||||||
|
|
||||||
@primary_key {:id, :binary_id, autogenerate: true}
|
@primary_key {:id, :binary_id, autogenerate: true}
|
||||||
@foreign_key_type :binary_id
|
@foreign_key_type :binary_id
|
||||||
schema "shift_templates" do
|
schema "shift_templates" do
|
||||||
field :label, :string
|
field :label, :string
|
||||||
field :subject, :string
|
field :subject, :string, default: "My Work Shift"
|
||||||
field :description, :string
|
field :description, :string
|
||||||
field :location, :string
|
field :location, :string
|
||||||
field :timezone, :string
|
field :timezone, :string, default: @time_zone
|
||||||
field :start_time, :time
|
field :start_time, :time, default: ~T[09:00:00]
|
||||||
field :length_hours, :integer
|
field :length_hours, :integer, default: 8
|
||||||
field :length_minutes, :integer
|
field :length_minutes, :integer, default: 0
|
||||||
|
|
||||||
belongs_to(:user, Shift73k.Accounts.User)
|
belongs_to(:user, Shift73k.Accounts.User)
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,36 @@ defmodule Shift73kWeb.ShiftTemplateLive.Index do
|
||||||
|
|
||||||
alias Shift73k.ShiftTemplates
|
alias Shift73k.ShiftTemplates
|
||||||
alias Shift73k.ShiftTemplates.ShiftTemplate
|
alias Shift73k.ShiftTemplates.ShiftTemplate
|
||||||
|
alias Shift73kWeb.Roles
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def mount(_params, _session, socket) do
|
def mount(_params, session, socket) do
|
||||||
{:ok, assign(socket, :shift_templates, list_shift_templates())}
|
# {:ok, assign(socket, :shift_templates, list_shift_templates())}
|
||||||
|
socket
|
||||||
|
|> assign_defaults(session)
|
||||||
|
|> live_okreply()
|
||||||
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_template = shift_template_from_params(params)
|
||||||
|
|
||||||
|
|
||||||
|
if Roles.can?(current_user, shift_template, live_action) do
|
||||||
|
socket
|
||||||
|
|> assign_shift_templates()
|
||||||
|
|> assign(:modal_return_to, Routes.shift_template_index_path(socket, :index))
|
||||||
|
|> assign(:delete_shift_template, nil)
|
||||||
|
|> apply_action(socket.assigns.live_action, params)
|
||||||
|
|> live_noreply()
|
||||||
|
else
|
||||||
|
socket
|
||||||
|
|> put_flash(:error, "Unauthorised")
|
||||||
|
|> redirect(to: "/")
|
||||||
|
|> live_noreply()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp apply_action(socket, :edit, %{"id" => id}) do
|
defp apply_action(socket, :edit, %{"id" => id}) do
|
||||||
|
@ -32,15 +53,36 @@ defmodule Shift73kWeb.ShiftTemplateLive.Index do
|
||||||
|> assign(:shift_template, nil)
|
|> assign(:shift_template, nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp assign_shift_templates(socket) do
|
||||||
|
%User{id: uid} = socket.assigns.current_user
|
||||||
|
user_shifts = ShiftTemplates.list_shift_templates_by_user_id(uid)
|
||||||
|
assign(socket, :shift_templates, user_shifts)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp shift_template_from_params(params)
|
||||||
|
|
||||||
|
defp shift_template_from_params(%{"id" => id}),
|
||||||
|
do: ShiftTemplates.get_shift_template!(id)
|
||||||
|
|
||||||
|
defp shift_template_from_params(_params), do: %ShiftTemplate{}
|
||||||
|
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_event("delete", %{"id" => id}, socket) do
|
def handle_event("delete", %{"id" => id}, socket) do
|
||||||
shift_template = ShiftTemplates.get_shift_template!(id)
|
shift_template = ShiftTemplates.get_shift_template!(id)
|
||||||
{:ok, _} = ShiftTemplates.delete_shift_template(shift_template)
|
{:ok, _} = ShiftTemplates.delete_shift_template(shift_template)
|
||||||
|
|
||||||
{:noreply, assign(socket, :shift_templates, list_shift_templates())}
|
{:noreply, assign_shift_templates(socket)}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp list_shift_templates do
|
@impl true
|
||||||
ShiftTemplates.list_shift_templates()
|
def handle_info({:close_modal, _}, %{assigns: %{modal_return_to: to}} = socket) do
|
||||||
|
socket |> copy_flash() |> push_patch(to: to) |> live_noreply()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_info({:put_flash_message, {flash_type, msg}}, socket) do
|
||||||
|
socket |> put_flash(flash_type, msg) |> live_noreply()
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,15 +1,24 @@
|
||||||
<h1>Listing Shift templates</h1>
|
|
||||||
|
|
||||||
<%= if @live_action in [:new, :edit] do %>
|
<%= if @live_action in [:new, :edit] do %>
|
||||||
<%= live_modal @socket, Shift73kWeb.ShiftTemplateLive.FormComponent,
|
<%= live_modal @socket, Shift73kWeb.ShiftTemplateLive.FormComponent,
|
||||||
id: @shift_template.id || :new,
|
id: @shift_template.id || :new,
|
||||||
title: @page_title,
|
title: @page_title,
|
||||||
action: @live_action,
|
action: @live_action,
|
||||||
shift_template: @shift_template,
|
shift_template: @shift_template,
|
||||||
return_to: Routes.shift_template_index_path(@socket, :index) %>
|
current_user: @current_user %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<table>
|
|
||||||
|
<div class="d-flex justify-content-between d-flex align-items-center">
|
||||||
|
<h2>
|
||||||
|
<%= icon_div @socket, "bi-clock-history", [class: "icon baseline"] %>
|
||||||
|
My Shift Templates
|
||||||
|
</h2>
|
||||||
|
<%= live_patch "New Shift Template", to: Routes.shift_template_index_path(@socket, :new), class: "btn btn-primary" %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Label</th>
|
<th>Label</th>
|
||||||
|
@ -18,8 +27,7 @@
|
||||||
<th>Location</th>
|
<th>Location</th>
|
||||||
<th>Timezone</th>
|
<th>Timezone</th>
|
||||||
<th>Start time</th>
|
<th>Start time</th>
|
||||||
<th>Length hours</th>
|
<th>Length</th>
|
||||||
<th>Length minutes</th>
|
|
||||||
|
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -32,9 +40,8 @@
|
||||||
<td><%= shift_template.description %></td>
|
<td><%= shift_template.description %></td>
|
||||||
<td><%= shift_template.location %></td>
|
<td><%= shift_template.location %></td>
|
||||||
<td><%= shift_template.timezone %></td>
|
<td><%= shift_template.timezone %></td>
|
||||||
<td><%= shift_template.start_time %></td>
|
<td><%= shift_template.start_time |> Calendar.strftime("%I:%M %p") %></td>
|
||||||
<td><%= shift_template.length_hours %></td>
|
<td><%= shift_template.length_hours %>h <%= shift_template.length_minutes || 0 %>m</td>
|
||||||
<td><%= shift_template.length_minutes %></td>
|
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<span><%= live_redirect "Show", to: Routes.shift_template_show_path(@socket, :show, shift_template) %></span>
|
<span><%= live_redirect "Show", to: Routes.shift_template_show_path(@socket, :show, shift_template) %></span>
|
||||||
|
@ -45,5 +52,4 @@
|
||||||
<% end %>
|
<% end %>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
<span><%= live_patch "New Shift template", to: Routes.shift_template_index_path(@socket, :new) %></span>
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ defmodule Shift73kWeb.Roles do
|
||||||
"""
|
"""
|
||||||
|
|
||||||
alias Shift73k.Accounts.User
|
alias Shift73k.Accounts.User
|
||||||
# alias Shift73k.Properties.Property
|
alias Shift73k.ShiftTemplates.ShiftTemplate
|
||||||
|
|
||||||
@type entity :: struct()
|
@type entity :: struct()
|
||||||
@type action :: :new | :index | :edit | :show | :delete | :edit_role
|
@type action :: :new | :index | :edit | :show | :delete | :edit_role
|
||||||
|
@ -12,13 +12,13 @@ defmodule Shift73kWeb.Roles do
|
||||||
|
|
||||||
def can?(user, entity, action)
|
def can?(user, entity, action)
|
||||||
|
|
||||||
# # Properties / Property
|
# ShiftTemplates / ShiftTemplate
|
||||||
# def can?(%User{role: :admin}, %Property{}, _any), do: true
|
def can?(%User{role: :admin}, %ShiftTemplate{}, _any), do: true
|
||||||
# def can?(%User{}, %Property{}, :index), do: true
|
def can?(%User{}, %ShiftTemplate{}, :index), do: true
|
||||||
# def can?(%User{}, %Property{}, :new), do: true
|
def can?(%User{}, %ShiftTemplate{}, :new), do: true
|
||||||
# def can?(%User{}, %Property{}, :show), do: true
|
def can?(%User{}, %ShiftTemplate{}, :show), do: true
|
||||||
# def can?(%User{id: id}, %Property{user_id: id}, :edit), do: true
|
def can?(%User{id: id}, %ShiftTemplate{user_id: id}, :edit), do: true
|
||||||
# def can?(%User{id: id}, %Property{user_id: id}, :delete), do: true
|
def can?(%User{id: id}, %ShiftTemplate{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
|
||||||
|
|
|
@ -91,12 +91,12 @@ defmodule Shift73kWeb.Router do
|
||||||
scope "/", Shift73kWeb do
|
scope "/", Shift73kWeb do
|
||||||
pipe_through([:browser, :require_authenticated_user, :user])
|
pipe_through([:browser, :require_authenticated_user, :user])
|
||||||
|
|
||||||
live "/shift_templates", ShiftTemplateLive.Index, :index
|
live "/my_shifts", ShiftTemplateLive.Index, :index
|
||||||
live "/shift_templates/new", ShiftTemplateLive.Index, :new
|
live "/my_shifts/new", ShiftTemplateLive.Index, :new
|
||||||
live "/shift_templates/:id/edit", ShiftTemplateLive.Index, :edit
|
live "/my_shifts/:id/edit", ShiftTemplateLive.Index, :edit
|
||||||
|
|
||||||
live "/shift_templates/:id", ShiftTemplateLive.Show, :show
|
live "/my_shifts/:id", ShiftTemplateLive.Show, :show
|
||||||
live "/shift_templates/:id/show/edit", ShiftTemplateLive.Show, :edit
|
live "/my_shifts/:id/show/edit", ShiftTemplateLive.Show, :edit
|
||||||
end
|
end
|
||||||
|
|
||||||
# scope "/", Shift73kWeb do
|
# scope "/", Shift73kWeb do
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
<h1 class="fs-4 my-0 py-0 lh-base">
|
<h1 class="fs-4 my-0 py-0 lh-base">
|
||||||
<%= link to: Routes.page_path(@conn, :index), class: "navbar-brand fs-4" do %>
|
<%= link to: Routes.page_path(@conn, :index), class: "navbar-brand fs-4" do %>
|
||||||
<%= icon_div @conn, "mdi-skull-crossbones", [class: "icon baseline fs-3"] %>
|
<%= icon_div @conn, "bi-calendar3-week", [class: "icon baseline me-1"] %>
|
||||||
<span class="fw-light">Shift73k</span>
|
<span class="fw-light">Shift73k</span>
|
||||||
<% end %>
|
<% end %>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
Loading…
Reference in a new issue