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"""
<.form :let={f} for={%{}} as={:adv_filter} phx-submit="adv-search" role="form text-left">
<%= render_slot(@adv_search, f) %>
Show
entries
<%= @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