diff --git a/lib/decentralised_book_index/metadata.ex b/lib/decentralised_book_index/metadata.ex index f1cef6e..494bf7e 100644 --- a/lib/decentralised_book_index/metadata.ex +++ b/lib/decentralised_book_index/metadata.ex @@ -141,6 +141,7 @@ defmodule DecentralisedBookIndex.Metadata do define :create_publisher, action: :create, args: [:name] define :list_publishers, action: :read define :get_publisher_by_id, args: [:id], action: :by_id + define :search_publisher, action: :search, args: [:name] define :update_publisher, action: :update define :destroy_publisher, action: :destroy end diff --git a/lib/decentralised_book_index_web/live/publisher_live/index.ex b/lib/decentralised_book_index_web/live/publisher_live/index.ex index 340b27d..a0f365f 100644 --- a/lib/decentralised_book_index_web/live/publisher_live/index.ex +++ b/lib/decentralised_book_index_web/live/publisher_live/index.ex @@ -1,36 +1,61 @@ defmodule DecentralisedBookIndexWeb.PublisherLive.Index do use DecentralisedBookIndexWeb, :live_view + alias DecentralisedBookIndex.Metadata + @impl true def render(assigns) do ~H""" <.header> Listing Publishers - <:actions> - <.link patch={~p"/publishers/new"}> - <.button>New Publisher - -
- <.table - id="publishers" - rows={@streams.publishers} - row_click={fn {_id, publisher} -> JS.navigate(~p"/publishers/#{publisher}") end} - > - <:col :let={{_id, publisher}} label="Name">{publisher.name} - - <:action :let={{_id, publisher}}> -
- <.link navigate={~p"/publishers/#{publisher}"}>Show -
- - <.link patch={~p"/publishers/#{publisher}/edit"}>Edit - - + <.search_resources + search_query={@search_query} + select_options={@select_options} + selected_option={@sort_by} + current_user={@current_user} + resource_type="publisher" + resource_new_url={~p"/publishers/new"} + />
+ <%= if Enum.empty?(@page.results) do %> +
+
+

+ No Publisher +

+
+
+ <% else %> +
+ <.table + id="publishers" + rows={@page.results} + row_click={fn publisher -> JS.navigate(~p"/publishers/#{publisher}") end} + > + <:col :let={publisher} label="Name">{publisher.name} + + <:action :let={publisher}> +
+ <.link navigate={~p"/publishers/#{publisher}"}>Show +
+ + <.link patch={~p"/publishers/#{publisher}/edit"}>Edit + + + + <.pagination + endpoint={~p"/publishers"} + page={@page} + page_params={@page_params} + params={@params} + /> +
+ <% end %> + <.modal :if={@live_action in [:new, :edit]} id="publisher-modal" @@ -54,16 +79,33 @@ defmodule DecentralisedBookIndexWeb.PublisherLive.Index do def mount(_params, _session, socket) do {:ok, socket - |> stream( - :publishers, - Ash.read!(DecentralisedBookIndex.Metadata.Publisher, actor: socket.assigns[:current_user]) - ) |> assign_new(:current_user, fn -> nil end)} end @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_publisher!( + search_query, + query: [sort_input: sort_by], + page: page_params ++ [count: true], + ) + + 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} + #apply_action(socket, socket.assigns.live_action, params)} end defp apply_action(socket, :edit, %{"id" => id}) do @@ -104,4 +146,40 @@ defmodule DecentralisedBookIndexWeb.PublisherLive.Index do {:noreply, stream_delete(socket, :publishers, publisher)} 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"/publishers?#{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"/publishers?#{params}")} + end end