Update the Publisher Index LiveView to search and sort data.
continuous-integration/drone/push Build is passing Details

dev
KKlochko 2 months ago
parent 291fbfbdf4
commit 33a70a023f

@ -141,6 +141,7 @@ defmodule DecentralisedBookIndex.Metadata do
define :create_publisher, action: :create, args: [:name] define :create_publisher, action: :create, args: [:name]
define :list_publishers, action: :read define :list_publishers, action: :read
define :get_publisher_by_id, args: [:id], action: :by_id define :get_publisher_by_id, args: [:id], action: :by_id
define :search_publisher, action: :search, args: [:name]
define :update_publisher, action: :update define :update_publisher, action: :update
define :destroy_publisher, action: :destroy define :destroy_publisher, action: :destroy
end end

@ -1,36 +1,61 @@
defmodule DecentralisedBookIndexWeb.PublisherLive.Index do defmodule DecentralisedBookIndexWeb.PublisherLive.Index do
use DecentralisedBookIndexWeb, :live_view use DecentralisedBookIndexWeb, :live_view
alias DecentralisedBookIndex.Metadata
@impl true @impl true
def render(assigns) do def render(assigns) do
~H""" ~H"""
<.header> <.header>
Listing Publishers Listing Publishers
<:actions>
<.link patch={~p"/publishers/new"}>
<.button>New Publisher</.button>
</.link>
</:actions>
</.header> </.header>
<div class="pt-2"> <div class="pt-2">
<.table <.search_resources
id="publishers" search_query={@search_query}
rows={@streams.publishers} select_options={@select_options}
row_click={fn {_id, publisher} -> JS.navigate(~p"/publishers/#{publisher}") end} selected_option={@sort_by}
> current_user={@current_user}
<:col :let={{_id, publisher}} label="Name">{publisher.name}</:col> resource_type="publisher"
resource_new_url={~p"/publishers/new"}
<:action :let={{_id, publisher}}> />
<div class="sr-only">
<.link navigate={~p"/publishers/#{publisher}"}>Show</.link>
</div>
<.link patch={~p"/publishers/#{publisher}/edit"}>Edit</.link>
</:action>
</.table>
</div> </div>
<%= if Enum.empty?(@page.results) do %>
<div class="flex justify-center ">
<div>
<p class="text-xl font-semibold py-5 dark:text-white">
No Publisher
</p>
</div>
</div>
<% else %>
<div class="pt-2 flex flex-col gap-2">
<.table
id="publishers"
rows={@page.results}
row_click={fn publisher -> JS.navigate(~p"/publishers/#{publisher}") end}
>
<:col :let={publisher} label="Name">{publisher.name}</:col>
<:action :let={publisher}>
<div class="sr-only">
<.link navigate={~p"/publishers/#{publisher}"}>Show</.link>
</div>
<.link patch={~p"/publishers/#{publisher}/edit"}>Edit</.link>
</:action>
</.table>
<.pagination
endpoint={~p"/publishers"}
page={@page}
page_params={@page_params}
params={@params}
/>
</div>
<% end %>
<.modal <.modal
:if={@live_action in [:new, :edit]} :if={@live_action in [:new, :edit]}
id="publisher-modal" id="publisher-modal"
@ -54,16 +79,33 @@ defmodule DecentralisedBookIndexWeb.PublisherLive.Index do
def mount(_params, _session, socket) do def mount(_params, _session, socket) do
{:ok, {:ok,
socket socket
|> stream(
:publishers,
Ash.read!(DecentralisedBookIndex.Metadata.Publisher, actor: socket.assigns[:current_user])
)
|> assign_new(:current_user, fn -> nil end)} |> assign_new(:current_user, fn -> nil end)}
end end
@impl true @impl true
def handle_params(params, _url, socket) do 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 end
defp apply_action(socket, :edit, %{"id" => id}) do defp apply_action(socket, :edit, %{"id" => id}) do
@ -104,4 +146,40 @@ defmodule DecentralisedBookIndexWeb.PublisherLive.Index do
{:noreply, stream_delete(socket, :publishers, publisher)} {:noreply, stream_delete(socket, :publishers, publisher)}
end 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 end

Loading…
Cancel
Save