defmodule MemexWeb.Components.PipelinesTableComponent do @moduledoc """ A component that displays a list of pipelines """ use MemexWeb, :live_component alias Ecto.UUID alias Memex.{Accounts.User, Pipelines.Pipeline} alias Phoenix.LiveView.{Rendered, Socket} @impl true @spec update( %{ required(:id) => UUID.t(), required(:current_user) => User.t(), required(:pipelines) => [Pipeline.t()], optional(any()) => any() }, Socket.t() ) :: {:ok, Socket.t()} def update(%{id: _id, pipelines: _pipelines, current_user: _current_user} = assigns, socket) do socket = socket |> assign(assigns) |> assign_new(:actions, fn -> [] end) |> display_pipelines() {:ok, socket} end defp display_pipelines( %{ assigns: %{ pipelines: pipelines, current_user: current_user, actions: actions } } = socket ) do columns = if actions == [] or current_user |> is_nil() do [] else [%{label: gettext("actions"), key: :actions, sortable: false}] end columns = [ %{label: gettext("slug"), key: :slug}, %{label: gettext("description"), key: :description}, %{label: gettext("tags"), key: :tags}, %{label: gettext("visibility"), key: :visibility} | columns ] rows = pipelines |> Enum.map(fn pipeline -> pipeline |> get_row_data_for_pipeline(%{ columns: columns, current_user: current_user, actions: actions }) end) socket |> assign(columns: columns, rows: rows) end @impl true def render(assigns) do ~H"""
<.live_component module={MemexWeb.Components.TableComponent} id={@id} columns={@columns} rows={@rows} />
""" end @spec get_row_data_for_pipeline(Pipeline.t(), additional_data :: map()) :: map() defp get_row_data_for_pipeline(pipeline, %{columns: columns} = additional_data) do columns |> Map.new(fn %{key: key} -> {key, get_value_for_key(key, pipeline, additional_data)} end) end @spec get_value_for_key(atom(), Pipeline.t(), additional_data :: map()) :: any() | {any(), Rendered.t()} defp get_value_for_key(:slug, %{slug: slug} = assigns, _additional_data) do slug_block = ~H""" <.link navigate={~p"/pipeline/#{@slug}"} class="link"> <%= @slug %> """ {slug, slug_block} end defp get_value_for_key(:description, %{description: description} = assigns, _additional_data) do description_block = ~H"""
<%= @description %>
""" {description, description_block} end defp get_value_for_key(:tags, assigns, _additional_data) do ~H"""
<.link :for={tag <- @tags} patch={~p"/pipelines/#{tag}"} class="link"> <%= tag %>
""" end defp get_value_for_key(:actions, pipeline, %{actions: actions}) do assigns = %{actions: actions, pipeline: pipeline} ~H"""
<%= render_slot(@actions, @pipeline) %>
""" end defp get_value_for_key(key, pipeline, _additional_data), do: pipeline |> Map.get(key) end