From 403d037b553986784720ce9ed97e97a72d9f3c42 Mon Sep 17 00:00:00 2001 From: KKlochko Date: Thu, 17 Apr 2025 11:47:55 +0300 Subject: [PATCH] Add the search and pagination for Server Index LiveView. --- .../live/dbi_server_live/index.ex | 150 ++++++++++++++---- 1 file changed, 118 insertions(+), 32 deletions(-) diff --git a/lib/decentralised_book_index_web/live/dbi_server_live/index.ex b/lib/decentralised_book_index_web/live/dbi_server_live/index.ex index ece065b..f2a232b 100644 --- a/lib/decentralised_book_index_web/live/dbi_server_live/index.ex +++ b/lib/decentralised_book_index_web/live/dbi_server_live/index.ex @@ -1,45 +1,73 @@ defmodule DecentralisedBookIndexWeb.DbiServerLive.Index do use DecentralisedBookIndexWeb, :live_view + alias DecentralisedBookIndex.Metadata + @impl true def render(assigns) do ~H""" <.header> Listing servers - <:actions> - <.link patch={~p"/servers/new"}> - <.button>New server - -
- <.table - id="dbi_servers" - rows={@streams.dbi_servers} - row_click={fn {_id, dbi_server} -> JS.navigate(~p"/servers/#{dbi_server}") end} - > - <:col :let={{_id, dbi_server}} label="Name">{dbi_server.name} - - <:col :let={{_id, dbi_server}} label="Url">{dbi_server.url} - - <:action :let={{_id, dbi_server}}> -
- <.link navigate={~p"/servers/#{dbi_server}"}>Show -
- - <.link patch={~p"/servers/#{dbi_server}/edit"}>Edit - - - <:action :let={{id, dbi_server}}> - <.link - phx-click={JS.push("delete", value: %{id: dbi_server.id}) |> hide("##{id}")} - data-confirm="Are you sure?" - > - Delete - - - + <.search_resources + search_query={@search_query} + select_options={@select_options} + selected_option={@sort_by} + current_user={@current_user} + resource_type="server" + resource_new_url={~p"/servers/new"} + /> +
+ + <%= if Enum.empty?(@page.results) do %> +
+
+

+ No Servers +

+
+
+ <% else %> +
+ <.table + id="dbi_servers" + rows={@page.results} + row_click={fn dbi_server -> JS.navigate(~p"/servers/#{dbi_server}") end} + > + <:col :let={dbi_server} label="Name">{dbi_server.name} + + <:col :let={dbi_server} label="Url">{dbi_server.url} + + <:action :let={dbi_server}> +
+ <.link navigate={~p"/servers/#{dbi_server}"}>Show +
+ + <.link patch={~p"/servers/#{dbi_server}/edit"}>Edit + + + <:action :let={dbi_server}> + <.link + phx-click={JS.push("delete", value: %{id: dbi_server.id}) |> hide("##{dbi_server.id}")} + data-confirm="Are you sure?" + > + Delete + + + + + <.pagination + endpoint={~p"/servers"} + page={@page} + page_params={@page_params} + params={@params} + /> +
+ <% end %> + +
<.modal @@ -74,7 +102,29 @@ defmodule DecentralisedBookIndexWeb.DbiServerLive.Index do @impl true def handle_params(params, _url, socket) do - {:noreply, apply_action(socket, socket.assigns.live_action, params)} + search_query = Map.get(params, "query", "") + sort_by = Map.get(params, "sort_by", "name") |> validate_sort_by() + page_params = AshPhoenix.LiveView.page_from_params(params, 10) + + page = Metadata.search_dbi_server!( + search_query, + query: [sort_input: sort_by], + page: page_params ++ [count: true], + actor: socket.assigns.current_user + ) + + socket = + socket + |> assign(:sort_by, sort_by) + |> assign(:search_query, search_query) + |> assign(:select_options, sort_options()) + |> assign(:page_params, page_params) + |> assign(:page, page) + |> assign(:params, params) + |> apply_action(socket.assigns.live_action, params) + + {:noreply, socket} + # {:noreply, apply_action(socket, socket.assigns.live_action, params)} end defp apply_action(socket, :edit, %{"id" => id}) do @@ -115,4 +165,40 @@ defmodule DecentralisedBookIndexWeb.DbiServerLive.Index do {:noreply, stream_delete(socket, :dbi_servers, dbi_server)} end + + defp sort_options do + [ + {"Sort by name", "name"}, + {"Sort by recently updated", "-updated_at"}, + {"Sort by recently added", "-inserted_at"}, + ] + end + + def validate_sort_by(key) do + valid_keys = Enum.map(sort_options(), &elem(&1, 1)) + + if key in valid_keys do + key + else + List.first(valid_keys) + end + end + + @impl true + def handle_event("change-sort", %{"sort_by" => sort_by}, socket) do + params = + socket.assigns.params + |> Map.put("sort_by", sort_by) + + {:noreply, push_patch(socket, to: ~p"/servers?#{params}")} + end + + @impl true + def handle_event("search", %{"query" => query}, socket) do + params = + socket.assigns.params + |> Map.put("query", query) + + {:noreply, push_patch(socket, to: ~p"/servers?#{params}")} + end end