update table component
This commit is contained in:
parent
e16e127673
commit
bf235b837c
@ -6,7 +6,7 @@ defmodule MemexWeb.Components.TableComponent do
|
|||||||
- `:columns`: An array of maps containing the following keys
|
- `:columns`: An array of maps containing the following keys
|
||||||
- `:label`: A gettext'd or otherwise user-facing string label for the
|
- `:label`: A gettext'd or otherwise user-facing string label for the
|
||||||
column. Can be nil
|
column. Can be nil
|
||||||
- `:key`: A string key used for sorting
|
- `:key`: An atom key used for sorting
|
||||||
- `:class`: Extra classes to be applied to the column element, if desired.
|
- `:class`: Extra classes to be applied to the column element, if desired.
|
||||||
Optional
|
Optional
|
||||||
- `:sortable`: If false, will prevent the user from sorting with it.
|
- `:sortable`: If false, will prevent the user from sorting with it.
|
||||||
@ -21,6 +21,7 @@ defmodule MemexWeb.Components.TableComponent do
|
|||||||
|
|
||||||
use MemexWeb, :live_component
|
use MemexWeb, :live_component
|
||||||
alias Phoenix.LiveView.Socket
|
alias Phoenix.LiveView.Socket
|
||||||
|
require Integer
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
@spec update(
|
@spec update(
|
||||||
@ -28,26 +29,50 @@ defmodule MemexWeb.Components.TableComponent do
|
|||||||
required(:columns) =>
|
required(:columns) =>
|
||||||
list(%{
|
list(%{
|
||||||
required(:label) => String.t() | nil,
|
required(:label) => String.t() | nil,
|
||||||
required(:key) => String.t() | nil,
|
required(:key) => atom() | nil,
|
||||||
optional(:class) => String.t(),
|
optional(:class) => String.t(),
|
||||||
|
optional(:row_class) => String.t(),
|
||||||
|
optional(:alternate_row_class) => String.t(),
|
||||||
optional(:sortable) => false
|
optional(:sortable) => false
|
||||||
}),
|
}),
|
||||||
required(:rows) =>
|
required(:rows) =>
|
||||||
list(%{
|
list(%{
|
||||||
(key :: String.t()) => any() | {custom_sort_value :: String.t(), value :: any()}
|
(key :: atom()) => any() | {custom_sort_value :: String.t(), value :: any()}
|
||||||
}),
|
}),
|
||||||
|
optional(:inital_key) => atom(),
|
||||||
|
optional(:initial_sort_mode) => atom(),
|
||||||
optional(any()) => any()
|
optional(any()) => any()
|
||||||
},
|
},
|
||||||
Socket.t()
|
Socket.t()
|
||||||
) :: {:ok, Socket.t()}
|
) :: {:ok, Socket.t()}
|
||||||
def update(%{columns: columns, rows: rows} = assigns, socket) do
|
def update(%{columns: columns, rows: rows} = assigns, socket) do
|
||||||
initial_key = columns |> List.first() |> Map.get(:key)
|
initial_key =
|
||||||
rows = rows |> Enum.sort_by(fn row -> row |> Map.get(initial_key) end, :asc)
|
if assigns |> Map.has_key?(:initial_key) do
|
||||||
|
assigns.initial_key
|
||||||
|
else
|
||||||
|
columns |> List.first(%{}) |> Map.get(:key)
|
||||||
|
end
|
||||||
|
|
||||||
|
initial_sort_mode =
|
||||||
|
if assigns |> Map.has_key?(:initial_sort_mode) do
|
||||||
|
assigns.initial_sort_mode
|
||||||
|
else
|
||||||
|
:asc
|
||||||
|
end
|
||||||
|
|
||||||
|
rows = rows |> sort_by_custom_sort_value_or_value(initial_key, initial_sort_mode)
|
||||||
|
|
||||||
socket =
|
socket =
|
||||||
socket
|
socket
|
||||||
|> assign(assigns)
|
|> assign(assigns)
|
||||||
|> assign(columns: columns, rows: rows, last_sort_key: initial_key, sort_mode: :asc)
|
|> assign(
|
||||||
|
columns: columns,
|
||||||
|
rows: rows,
|
||||||
|
last_sort_key: initial_key,
|
||||||
|
sort_mode: initial_sort_mode
|
||||||
|
)
|
||||||
|
|> assign_new(:row_class, fn -> "bg-white" end)
|
||||||
|
|> assign_new(:alternate_row_class, fn -> "bg-gray-200" end)
|
||||||
|
|
||||||
{:ok, socket}
|
{:ok, socket}
|
||||||
end
|
end
|
||||||
@ -56,20 +81,19 @@ defmodule MemexWeb.Components.TableComponent do
|
|||||||
def handle_event(
|
def handle_event(
|
||||||
"sort_by",
|
"sort_by",
|
||||||
%{"sort-key" => key},
|
%{"sort-key" => key},
|
||||||
%{assigns: %{rows: rows, last_sort_key: key, sort_mode: sort_mode}} = socket
|
%{assigns: %{rows: rows, last_sort_key: last_sort_key, sort_mode: sort_mode}} = socket
|
||||||
) do
|
) do
|
||||||
sort_mode = if sort_mode == :asc, do: :desc, else: :asc
|
key = key |> String.to_existing_atom()
|
||||||
rows = rows |> sort_by_custom_sort_value_or_value(key, sort_mode)
|
|
||||||
{:noreply, socket |> assign(sort_mode: sort_mode, rows: rows)}
|
sort_mode =
|
||||||
|
case {key, sort_mode} do
|
||||||
|
{^last_sort_key, :asc} -> :desc
|
||||||
|
{^last_sort_key, :desc} -> :asc
|
||||||
|
{_new_sort_key, _last_sort_mode} -> :asc
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_event(
|
rows = rows |> sort_by_custom_sort_value_or_value(key, sort_mode)
|
||||||
"sort_by",
|
{:noreply, socket |> assign(last_sort_key: key, sort_mode: sort_mode, rows: rows)}
|
||||||
%{"sort-key" => key},
|
|
||||||
%{assigns: %{rows: rows}} = socket
|
|
||||||
) do
|
|
||||||
rows = rows |> sort_by_custom_sort_value_or_value(key, :asc)
|
|
||||||
{:noreply, socket |> assign(last_sort_key: key, sort_mode: :asc, rows: rows)}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
defp sort_by_custom_sort_value_or_value(rows, key, sort_mode) do
|
defp sort_by_custom_sort_value_or_value(rows, key, sort_mode) do
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<div class="w-full overflow-x-auto border border-gray-600 rounded-lg shadow-lg bg-black">
|
<div id={@id} class="w-full overflow-x-auto border border-gray-600 rounded-lg shadow-lg bg-black">
|
||||||
<table class="min-w-full table-auto text-center bg-white">
|
<table class="min-w-full table-auto text-center bg-white">
|
||||||
<thead class="border-b border-primary-600">
|
<thead class="border-b border-primary-600">
|
||||||
<tr>
|
<tr>
|
||||||
@ -6,7 +6,7 @@
|
|||||||
<%= if column |> Map.get(:sortable, true) do %>
|
<%= if column |> Map.get(:sortable, true) do %>
|
||||||
<th class={"p-2 #{column[:class]}"}>
|
<th class={"p-2 #{column[:class]}"}>
|
||||||
<span
|
<span
|
||||||
class="cursor-pointer"
|
class="cursor-pointer flex justify-center items-center space-x-2"
|
||||||
phx-click="sort_by"
|
phx-click="sort_by"
|
||||||
phx-value-sort-key={key}
|
phx-value-sort-key={key}
|
||||||
phx-target={@myself}
|
phx-target={@myself}
|
||||||
@ -33,8 +33,8 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<%= for values <- @rows do %>
|
<%= for {values, i} <- @rows |> Enum.with_index() do %>
|
||||||
<tr>
|
<tr class={if i |> Integer.is_even(), do: @row_class, else: @alternate_row_class}>
|
||||||
<%= for %{key: key} = value <- @columns do %>
|
<%= for %{key: key} = value <- @columns do %>
|
||||||
<td class={"p-2 #{value[:class]}"}>
|
<td class={"p-2 #{value[:class]}"}>
|
||||||
<%= case values |> Map.get(key) do %>
|
<%= case values |> Map.get(key) do %>
|
||||||
|
Loading…
Reference in New Issue
Block a user