defmodule CanneryWeb.Components.PackTableComponent do @moduledoc """ A component that displays a list of packs """ use CanneryWeb, :live_component alias Cannery.{Accounts.User, Ammo.Pack, ComparableDate} alias Cannery.{ActivityLog, Ammo, Containers} alias CanneryWeb.Components.TableComponent alias Ecto.UUID alias Phoenix.LiveView.{Rendered, Socket} @impl true @spec update( %{ required(:id) => UUID.t(), required(:current_user) => User.t(), required(:packs) => [Pack.t()], required(:show_used) => boolean(), optional(:type) => Rendered.t(), optional(:range) => Rendered.t(), optional(:container) => Rendered.t(), optional(:actions) => Rendered.t(), optional(any()) => any() }, Socket.t() ) :: {:ok, Socket.t()} def update( %{id: _id, packs: _pack, current_user: _current_user, show_used: _show_used} = assigns, socket ) do socket = socket |> assign(assigns) |> assign_new(:type, fn -> [] end) |> assign_new(:range, fn -> [] end) |> assign_new(:container, fn -> [] end) |> assign_new(:actions, fn -> [] end) |> display_packs() {:ok, socket} end defp display_packs( %{ assigns: %{ packs: packs, current_user: current_user, type: type, range: range, container: container, actions: actions, show_used: show_used } } = socket ) do lot_number_used = packs |> Enum.any?(fn %{lot_number: lot_number} -> !!lot_number end) price_paid_used = packs |> Enum.any?(fn %{price_paid: price_paid} -> !!price_paid end) columns = [] |> TableComponent.maybe_compose_columns( %{label: gettext("Actions"), key: :actions, sortable: false}, actions != [] ) |> TableComponent.maybe_compose_columns(%{ label: gettext("Last used on"), key: :used_up_on, type: ComparableDate }) |> TableComponent.maybe_compose_columns(%{ label: gettext("Purchased on"), key: :purchased_on, type: ComparableDate }) |> TableComponent.maybe_compose_columns( %{label: gettext("Container"), key: :container}, container != [] ) |> TableComponent.maybe_compose_columns( %{label: gettext("Range"), key: :range}, range != [] ) |> TableComponent.maybe_compose_columns( %{label: gettext("Lot number"), key: :lot_number}, lot_number_used ) |> TableComponent.maybe_compose_columns( %{label: gettext("CPR"), key: :cpr}, price_paid_used ) |> TableComponent.maybe_compose_columns( %{label: gettext("Price paid"), key: :price_paid}, price_paid_used ) |> TableComponent.maybe_compose_columns( %{label: gettext("% left"), key: :remaining}, show_used ) |> TableComponent.maybe_compose_columns( %{label: gettext("Original Count"), key: :original_count}, show_used ) |> TableComponent.maybe_compose_columns(%{ label: if(show_used, do: gettext("Current Count"), else: gettext("Count")), key: :count }) |> TableComponent.maybe_compose_columns( %{label: gettext("Type"), key: :type}, type != [] ) containers = packs |> Enum.map(fn %{container_id: container_id} -> container_id end) |> Containers.get_containers(current_user) extra_data = %{ current_user: current_user, type: type, columns: columns, container: container, containers: containers, original_counts: Ammo.get_original_counts(packs, current_user), cprs: Ammo.get_cprs(packs, current_user), last_used_dates: ActivityLog.get_last_used_dates(packs, current_user), percentages_remaining: Ammo.get_percentages_remaining(packs, current_user), actions: actions, range: range } rows = packs |> Enum.map(fn pack -> pack |> get_row_data_for_pack(extra_data) end) socket |> assign(columns: columns, rows: rows) end @impl true def render(assigns) do ~H"""