defmodule Paleta.Components.Table do use Phoenix.Component alias Paleta.Components.Card alias Phoenix.LiveView.JS attr(:id, :string, default: "p-table") attr(:rows, :list, doc: "Data you want to list", required: true) attr(:row_id, :any, default: nil, doc: "the function for generating the row id") attr(:search, :boolean, doc: "Show or hide search bar", default: false) attr(:pagination, :map, doc: "Show or hide pagination", default: nil) slot :col, doc: "Describe one of your table columns" do attr(:label, :string, doc: "Column label", required: true) attr(:position, :string, doc: "Column position: :left or :center") end slot(:adv_search, doc: "Describe advance inputs") slot(:actions, doc: "Describe one of your table columns") def table(%{actions: actions, pagination: pagination} = assigns) do {first_column, cols} = assigns[:col] |> List.pop_at(0) assigns = with %{rows: %Phoenix.LiveView.LiveStream{}} <- assigns do assign(assigns, row_id: assigns.row_id || fn {id, _item} -> id end) end assigns = assigns |> assign(:first_column, first_column) |> assign(:show_actions, length(actions) > 0) |> assign(:col, cols) |> assign(:pages, build_pages(pagination)) ~H"""

<%= @first_column.label %> <%= col.label %> Actions
<%= render_slot(@first_column, row) %> <%= render_slot(col, row) %>
<%= render_slot(@actions, row) %>
Show entries
  1. <%= page[:label] %>
<%= @pagination.current_page * @pagination.per_page + 1 %> - <%= current_page( @pagination.current_page ) * @pagination.per_page %> of <%= @pagination.total %> entries
""" end defp disable_next_page(%{current_page: current_page, pages: pages}) when current_page == pages - 1, do: true defp disable_next_page(_), do: false defp disable_prev_page(%{current_page: 0}), do: true defp disable_prev_page(_), do: false defp next_page(%{current_page: current_page, pages: pages}) when current_page < pages, do: current_page + 1 defp next_page(%{current_page: current_page}), do: current_page defp prev_page(%{current_page: 0}), do: 0 defp prev_page(%{current_page: current_page}) when current_page > 0, do: current_page - 1 defp current_page(page), do: page + 1 defp build_pages(nil), do: nil defp build_pages(pagination) do pagination |> Paleta.Components.Table.Pagination.pagination() end defp page_class(%{active: false}), do: "flex h-8 min-w-[2rem] items-center justify-center rounded-lg px-3 leading-tight transition-colors hover:bg-slate-300 focus:bg-slate-300 active:bg-slate-300/80 dark:hover:bg-navy-450 dark:focus:bg-navy-450 dark:active:bg-navy-450/90" defp page_class(%{active: true}), do: "flex h-8 min-w-[2rem] items-center justify-center rounded-lg bg-primary px-3 leading-tight text-white transition-colors hover:bg-primary-focus focus:bg-primary-focus active:bg-primary-focus/90 dark:bg-accent dark:hover:bg-accent-focus dark:focus:bg-accent-focus dark:active:bg-accent/90" end