defmodule CanneryWeb.Components.ContainerTableComponent do @moduledoc """ A component that displays a list of containers """ use CanneryWeb, :live_component alias Cannery.{Accounts.User, Ammo, Containers.Container} alias Ecto.UUID alias Phoenix.LiveView.{Rendered, Socket} @impl true @spec update( %{ required(:id) => UUID.t(), required(:current_user) => User.t(), optional(:containers) => [Container.t()], optional(:tag_actions) => Rendered.t(), optional(:actions) => Rendered.t(), optional(any()) => any() }, Socket.t() ) :: {:ok, Socket.t()} def update(%{id: _id, containers: _containers, current_user: _current_user} = assigns, socket) do socket = socket |> assign(assigns) |> assign_new(:tag_actions, fn -> [] end) |> assign_new(:actions, fn -> [] end) |> display_containers() {:ok, socket} end defp display_containers( %{ assigns: %{ containers: containers, current_user: current_user, tag_actions: tag_actions, actions: actions } } = socket ) do columns = [ %{label: gettext("Name"), key: :name, type: :string}, %{label: gettext("Description"), key: :desc, type: :string}, %{label: gettext("Location"), key: :location, type: :string}, %{label: gettext("Type"), key: :type, type: :string} ] |> Enum.filter(fn %{key: key, type: type} -> # remove columns if all values match defaults default_value = case type do :boolean -> false _other_type -> nil end containers |> Enum.any?(fn container -> type in [:tags, :actions] or not (container |> Map.get(key) == default_value) end) end) |> Enum.concat([ %{label: gettext("Packs"), key: :packs, type: :integer}, %{label: gettext("Rounds"), key: :rounds, type: :integer}, %{label: gettext("Tags"), key: :tags, type: :tags}, %{label: gettext("Actions"), key: :actions, sortable: false, type: :actions} ]) extra_data = %{ current_user: current_user, tag_actions: tag_actions, actions: actions, pack_count: Ammo.get_grouped_packs_count(current_user, containers: containers, group_by: :container_id), round_count: Ammo.get_grouped_round_count(current_user, containers: containers, group_by: :container_id) } rows = containers |> Enum.map(fn container -> container |> get_row_data_for_container(columns, extra_data) end) socket |> assign( columns: columns, rows: rows ) end @impl true def render(assigns) do ~H"""