initial shift template live view progress

This commit is contained in:
Adam Piontek 2021-03-06 20:16:56 -05:00
parent 73c97f194b
commit 57c8b5b322
9 changed files with 98 additions and 39 deletions

View file

@ -3,5 +3,5 @@ import Ecto.Query
alias Shift73k.Repo
alias Shift73k.Accounts
alias Shift73k.Accounts.User
alias Shift73k.ShiftTemplates, as: STemplates
alias Shift73k.ShiftTemplates.ShiftTemplate, as: STemplate
alias Shift73k.ShiftTemplates
alias Shift73k.ShiftTemplates.ShiftTemplate

View file

@ -5,7 +5,7 @@ import "../css/app.scss";
// Import icons for sprite-loader
// 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
import "../node_modules/bootstrap-icons/icons/person-circle.svg"; // accounts menu
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/@mdi/svg/svg/head-question-outline.svg"; // forgot password
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
// entry points. Those entry points can be configured

View file

@ -21,6 +21,11 @@ defmodule Shift73k.ShiftTemplates do
Repo.all(ShiftTemplate)
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 """
Gets a single shift_template.

View file

@ -2,17 +2,20 @@ defmodule Shift73k.ShiftTemplates.ShiftTemplate do
use Ecto.Schema
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}
@foreign_key_type :binary_id
schema "shift_templates" do
field :label, :string
field :subject, :string
field :subject, :string, default: "My Work Shift"
field :description, :string
field :location, :string
field :timezone, :string
field :start_time, :time
field :length_hours, :integer
field :length_minutes, :integer
field :timezone, :string, default: @time_zone
field :start_time, :time, default: ~T[09:00:00]
field :length_hours, :integer, default: 8
field :length_minutes, :integer, default: 0
belongs_to(:user, Shift73k.Accounts.User)

View file

@ -3,15 +3,36 @@ defmodule Shift73kWeb.ShiftTemplateLive.Index do
alias Shift73k.ShiftTemplates
alias Shift73k.ShiftTemplates.ShiftTemplate
alias Shift73kWeb.Roles
@impl true
def mount(_params, _session, socket) do
{:ok, assign(socket, :shift_templates, list_shift_templates())}
def mount(_params, session, socket) do
# {:ok, assign(socket, :shift_templates, list_shift_templates())}
socket
|> assign_defaults(session)
|> live_okreply()
end
@impl true
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
defp apply_action(socket, :edit, %{"id" => id}) do
@ -32,15 +53,36 @@ defmodule Shift73kWeb.ShiftTemplateLive.Index do
|> assign(:shift_template, nil)
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
def handle_event("delete", %{"id" => id}, socket) do
shift_template = ShiftTemplates.get_shift_template!(id)
{:ok, _} = ShiftTemplates.delete_shift_template(shift_template)
{:noreply, assign(socket, :shift_templates, list_shift_templates())}
{:noreply, assign_shift_templates(socket)}
end
defp list_shift_templates do
ShiftTemplates.list_shift_templates()
@impl true
def handle_info({:close_modal, _}, %{assigns: %{modal_return_to: to}} = socket) do
socket |> copy_flash() |> push_patch(to: to) |> live_noreply()
end
@impl true
def handle_info({:put_flash_message, {flash_type, msg}}, socket) do
socket |> put_flash(flash_type, msg) |> live_noreply()
end
end

View file

@ -1,15 +1,24 @@
<h1>Listing Shift templates</h1>
<%= if @live_action in [:new, :edit] do %>
<%= live_modal @socket, Shift73kWeb.ShiftTemplateLive.FormComponent,
id: @shift_template.id || :new,
title: @page_title,
action: @live_action,
shift_template: @shift_template,
return_to: Routes.shift_template_index_path(@socket, :index) %>
current_user: @current_user %>
<% 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>
<tr>
<th>Label</th>
@ -18,8 +27,7 @@
<th>Location</th>
<th>Timezone</th>
<th>Start time</th>
<th>Length hours</th>
<th>Length minutes</th>
<th>Length</th>
<th></th>
</tr>
@ -32,9 +40,8 @@
<td><%= shift_template.description %></td>
<td><%= shift_template.location %></td>
<td><%= shift_template.timezone %></td>
<td><%= shift_template.start_time %></td>
<td><%= shift_template.length_hours %></td>
<td><%= shift_template.length_minutes %></td>
<td><%= shift_template.start_time |> Calendar.strftime("%I:%M %p") %></td>
<td><%= shift_template.length_hours %>h <%= shift_template.length_minutes || 0 %>m</td>
<td>
<span><%= live_redirect "Show", to: Routes.shift_template_show_path(@socket, :show, shift_template) %></span>
@ -45,5 +52,4 @@
<% end %>
</tbody>
</table>
<span><%= live_patch "New Shift template", to: Routes.shift_template_index_path(@socket, :new) %></span>
</div>

View file

@ -4,7 +4,7 @@ defmodule Shift73kWeb.Roles do
"""
alias Shift73k.Accounts.User
# alias Shift73k.Properties.Property
alias Shift73k.ShiftTemplates.ShiftTemplate
@type entity :: struct()
@type action :: :new | :index | :edit | :show | :delete | :edit_role
@ -12,13 +12,13 @@ defmodule Shift73kWeb.Roles do
def can?(user, entity, action)
# # Properties / Property
# def can?(%User{role: :admin}, %Property{}, _any), do: true
# def can?(%User{}, %Property{}, :index), do: true
# def can?(%User{}, %Property{}, :new), do: true
# def can?(%User{}, %Property{}, :show), do: true
# def can?(%User{id: id}, %Property{user_id: id}, :edit), do: true
# def can?(%User{id: id}, %Property{user_id: id}, :delete), do: true
# ShiftTemplates / ShiftTemplate
def can?(%User{role: :admin}, %ShiftTemplate{}, _any), do: true
def can?(%User{}, %ShiftTemplate{}, :index), 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}, :edit), do: true
def can?(%User{id: id}, %ShiftTemplate{user_id: id}, :delete), do: true
# Accounts / User
def can?(%User{role: :admin}, %User{}, _any), do: true

View file

@ -91,12 +91,12 @@ defmodule Shift73kWeb.Router do
scope "/", Shift73kWeb do
pipe_through([:browser, :require_authenticated_user, :user])
live "/shift_templates", ShiftTemplateLive.Index, :index
live "/shift_templates/new", ShiftTemplateLive.Index, :new
live "/shift_templates/:id/edit", ShiftTemplateLive.Index, :edit
live "/my_shifts", ShiftTemplateLive.Index, :index
live "/my_shifts/new", ShiftTemplateLive.Index, :new
live "/my_shifts/:id/edit", ShiftTemplateLive.Index, :edit
live "/shift_templates/:id", ShiftTemplateLive.Show, :show
live "/shift_templates/:id/show/edit", ShiftTemplateLive.Show, :edit
live "/my_shifts/:id", ShiftTemplateLive.Show, :show
live "/my_shifts/:id/show/edit", ShiftTemplateLive.Show, :edit
end
# scope "/", Shift73kWeb do

View file

@ -3,7 +3,7 @@
<h1 class="fs-4 my-0 py-0 lh-base">
<%= 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>
<% end %>
</h1>