update table component
This commit is contained in:
		| @@ -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)} |  | ||||||
|   end |  | ||||||
|  |  | ||||||
|   def handle_event( |     sort_mode = | ||||||
|         "sort_by", |       case {key, sort_mode} do | ||||||
|         %{"sort-key" => key}, |         {^last_sort_key, :asc} -> :desc | ||||||
|         %{assigns: %{rows: rows}} = socket |         {^last_sort_key, :desc} -> :asc | ||||||
|       ) do |         {_new_sort_key, _last_sort_mode} -> :asc | ||||||
|     rows = rows |> sort_by_custom_sort_value_or_value(key, :asc) |       end | ||||||
|     {:noreply, socket |> assign(last_sort_key: key, sort_mode: :asc, rows: rows)} |  | ||||||
|  |     rows = rows |> sort_by_custom_sort_value_or_value(key, sort_mode) | ||||||
|  |     {:noreply, socket |> assign(last_sort_key: key, sort_mode: sort_mode, 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 %> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user