forked from shibao/cannery
use shot group table component instead
This commit is contained in:
117
lib/cannery_web/components/shot_group_table_component.ex
Normal file
117
lib/cannery_web/components/shot_group_table_component.ex
Normal file
@ -0,0 +1,117 @@
|
||||
defmodule CanneryWeb.Components.ShotGroupTableComponent do
|
||||
@moduledoc """
|
||||
A component that displays a list of shot groups
|
||||
"""
|
||||
use CanneryWeb, :live_component
|
||||
alias Cannery.{Accounts.User, ActivityLog.ShotGroup, Repo}
|
||||
alias Ecto.UUID
|
||||
alias Phoenix.LiveView.{Rendered, Socket}
|
||||
|
||||
@impl true
|
||||
@spec update(
|
||||
%{
|
||||
required(:id) => UUID.t(),
|
||||
required(:current_user) => User.t(),
|
||||
optional(:shot_groups) => [ShotGroup.t()],
|
||||
optional(:actions) => Rendered.t(),
|
||||
optional(any()) => any()
|
||||
},
|
||||
Socket.t()
|
||||
) :: {:ok, Socket.t()}
|
||||
def update(%{id: _id, shot_groups: _shot_groups, current_user: _current_user} = assigns, socket) do
|
||||
socket =
|
||||
socket
|
||||
|> assign(assigns)
|
||||
|> assign_new(:actions, fn -> [] end)
|
||||
|> display_shot_groups()
|
||||
|
||||
{:ok, socket}
|
||||
end
|
||||
|
||||
defp display_shot_groups(
|
||||
%{
|
||||
assigns: %{
|
||||
shot_groups: shot_groups,
|
||||
current_user: current_user,
|
||||
actions: actions
|
||||
}
|
||||
} = socket
|
||||
) do
|
||||
columns = [
|
||||
%{label: gettext("Ammo"), key: :name},
|
||||
%{label: gettext("Rounds shot"), key: :count},
|
||||
%{label: gettext("Notes"), key: :notes},
|
||||
%{label: gettext("Date"), key: :date},
|
||||
%{label: nil, key: :actions, sortable: false}
|
||||
]
|
||||
|
||||
extra_data = %{current_user: current_user, actions: actions}
|
||||
|
||||
rows =
|
||||
shot_groups
|
||||
|> Enum.map(fn shot_group ->
|
||||
shot_group |> get_row_data_for_shot_group(columns, extra_data)
|
||||
end)
|
||||
|
||||
socket
|
||||
|> assign(
|
||||
columns: columns,
|
||||
rows: rows
|
||||
)
|
||||
end
|
||||
|
||||
@impl true
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<div id={@id} class="w-full">
|
||||
<.live_component
|
||||
module={CanneryWeb.Components.TableComponent}
|
||||
id={"table-#{@id}"}
|
||||
columns={@columns}
|
||||
rows={@rows}
|
||||
initial_key={:date}
|
||||
initial_sort_mode={:desc}
|
||||
/>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
@spec get_row_data_for_shot_group(ShotGroup.t(), columns :: [map()], extra_data :: map()) ::
|
||||
map()
|
||||
defp get_row_data_for_shot_group(shot_group, columns, extra_data) do
|
||||
shot_group = shot_group |> Repo.preload(ammo_group: :ammo_type)
|
||||
|
||||
columns
|
||||
|> Map.new(fn %{key: key} ->
|
||||
{key, get_row_value(key, shot_group, extra_data)}
|
||||
end)
|
||||
end
|
||||
|
||||
defp get_row_value(
|
||||
:name,
|
||||
%{ammo_group: %{ammo_type: %{name: ammo_type_name} = ammo_group}},
|
||||
_extra_data
|
||||
) do
|
||||
assigns = %{ammo_group: ammo_group, ammo_type_name: ammo_type_name}
|
||||
|
||||
name_block = ~H"""
|
||||
<.link navigate={Routes.ammo_group_show_path(Endpoint, :show, @ammo_group)} class="link">
|
||||
<%= @ammo_type_name %>
|
||||
</.link>
|
||||
"""
|
||||
|
||||
{ammo_type_name, name_block}
|
||||
end
|
||||
|
||||
defp get_row_value(:date, %{date: date}, _extra_data), do: date |> display_date()
|
||||
|
||||
defp get_row_value(:actions, shot_group, %{actions: actions}) do
|
||||
assigns = %{actions: actions, shot_group: shot_group}
|
||||
|
||||
~H"""
|
||||
<%= render_slot(@actions, @shot_group) %>
|
||||
"""
|
||||
end
|
||||
|
||||
defp get_row_value(key, shot_group, _extra_data), do: shot_group |> Map.get(key)
|
||||
end
|
@ -112,26 +112,11 @@ defmodule CanneryWeb.RangeLive.Index do
|
||||
|> Repo.preload(ammo_group: :ammo_type)
|
||||
|
||||
ammo_groups = Ammo.list_staged_ammo_groups(current_user)
|
||||
|
||||
columns = [
|
||||
%{label: gettext("Ammo"), key: :name},
|
||||
%{label: gettext("Rounds shot"), key: :count},
|
||||
%{label: gettext("Notes"), key: :notes},
|
||||
%{label: gettext("Date"), key: :date},
|
||||
%{label: nil, key: :actions, sortable: false}
|
||||
]
|
||||
|
||||
rows =
|
||||
shot_groups
|
||||
|> Enum.map(fn shot_group -> shot_group |> get_row_data_for_shot_group(columns) end)
|
||||
|
||||
chart_data = shot_groups |> get_chart_data_for_shot_group()
|
||||
|
||||
socket
|
||||
|> assign(
|
||||
ammo_groups: ammo_groups,
|
||||
columns: columns,
|
||||
rows: rows,
|
||||
chart_data: chart_data,
|
||||
shot_groups: shot_groups
|
||||
)
|
||||
@ -153,59 +138,4 @@ defmodule CanneryWeb.RangeLive.Index do
|
||||
end)
|
||||
|> Enum.sort_by(fn %{date: date} -> date end, Date)
|
||||
end
|
||||
|
||||
@spec get_row_data_for_shot_group(ShotGroup.t(), [map()]) :: map()
|
||||
defp get_row_data_for_shot_group(%{date: date} = shot_group, columns) do
|
||||
shot_group = shot_group |> Repo.preload(ammo_group: :ammo_type)
|
||||
assigns = %{shot_group: shot_group}
|
||||
|
||||
columns
|
||||
|> Map.new(fn %{key: key} ->
|
||||
value =
|
||||
case key do
|
||||
:name ->
|
||||
{shot_group.ammo_group.ammo_type.name,
|
||||
~H"""
|
||||
<.link
|
||||
navigate={Routes.ammo_group_show_path(Endpoint, :show, @shot_group.ammo_group)}
|
||||
class="link"
|
||||
>
|
||||
<%= @shot_group.ammo_group.ammo_type.name %>
|
||||
</.link>
|
||||
"""}
|
||||
|
||||
:date ->
|
||||
date |> display_date()
|
||||
|
||||
:actions ->
|
||||
~H"""
|
||||
<div class="px-4 py-2 space-x-4 flex justify-center items-center">
|
||||
<.link
|
||||
patch={Routes.range_index_path(Endpoint, :edit, @shot_group)}
|
||||
class="text-primary-600 link"
|
||||
data-qa={"edit-#{@shot_group.id}"}
|
||||
>
|
||||
<i class="fa-fw fa-lg fas fa-edit"></i>
|
||||
</.link>
|
||||
|
||||
<.link
|
||||
href="#"
|
||||
class="text-primary-600 link"
|
||||
phx-click="delete"
|
||||
phx-value-id={@shot_group.id}
|
||||
data-confirm={dgettext("prompts", "Are you sure you want to delete this shot record?")}
|
||||
data-qa={"delete-#{@shot_group.id}"}
|
||||
>
|
||||
<i class="fa-fw fa-lg fas fa-trash"></i>
|
||||
</.link>
|
||||
</div>
|
||||
"""
|
||||
|
||||
key ->
|
||||
shot_group |> Map.get(key)
|
||||
end
|
||||
|
||||
{key, value}
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
@ -92,13 +92,36 @@
|
||||
</h1>
|
||||
<% else %>
|
||||
<.live_component
|
||||
module={CanneryWeb.Components.TableComponent}
|
||||
module={CanneryWeb.Components.ShotGroupTableComponent}
|
||||
id="shot_groups_index_table"
|
||||
columns={@columns}
|
||||
rows={@rows}
|
||||
initial_key={:date}
|
||||
initial_sort_mode={:desc}
|
||||
/>
|
||||
shot_groups={@shot_groups}
|
||||
current_user={@current_user}
|
||||
>
|
||||
<:actions :let={shot_group}>
|
||||
<div class="px-4 py-2 space-x-4 flex justify-center items-center">
|
||||
<.link
|
||||
patch={Routes.range_index_path(Endpoint, :edit, shot_group)}
|
||||
class="text-primary-600 link"
|
||||
data-qa={"edit-#{shot_group.id}"}
|
||||
>
|
||||
<i class="fa-fw fa-lg fas fa-edit"></i>
|
||||
</.link>
|
||||
|
||||
<.link
|
||||
href="#"
|
||||
class="text-primary-600 link"
|
||||
phx-click="delete"
|
||||
phx-value-id={shot_group.id}
|
||||
data-confirm={
|
||||
dgettext("prompts", "Are you sure you want to delete this shot record?")
|
||||
}
|
||||
data-qa={"delete-#{shot_group.id}"}
|
||||
>
|
||||
<i class="fa-fw fa-lg fas fa-trash"></i>
|
||||
</.link>
|
||||
</div>
|
||||
</:actions>
|
||||
</.live_component>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
Reference in New Issue
Block a user