Add the search for Users Index LiveView.

This commit is contained in:
2025-04-17 12:18:15 +03:00
parent 1f895f7ef5
commit a3b5155337
4 changed files with 135 additions and 21 deletions
@@ -11,35 +11,64 @@ defmodule DecentralisedBookIndexWeb.UserLive.Index do
</.header>
<div class="pt-2">
<.table
id="users"
rows={@users}
row_click={fn {_id, user} -> JS.navigate(~p"/users/#{user}") end}
>
<:col :let={{_id, user}} label="Email">{user.email}</:col>
<:col :let={{_id, user}} label="Role">{user.role}</:col>
<:action :let={{_id, user}}>
<div class="sr-only">
<.link navigate={~p"/users/#{user}"}>Show</.link>
</div>
<.link patch={~p"/users/#{user}/edit"}>Edit Role</.link>
</:action>
</.table>
<.just_search_resources
search_query={@search_query}
select_options={@select_options}
selected_option={@sort_by}
current_user={@current_user}
search_placeholder="Search by email"
/>
</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 Users
</p>
</div>
</div>
<% else %>
<div class="pt-2 flex flex-col gap-2">
<.table
id="users"
rows={@users}
row_click={fn user -> JS.navigate(~p"/users/#{user}") end}
>
<:col :let={user} label="Email">{user.email}</:col>
<:col :let={user} label="Role">{user.role}</:col>
<:action :let={user}>
<div class="sr-only">
<.link navigate={~p"/users/#{user}"}>Show</.link>
</div>
<.link patch={~p"/users/#{user}/edit"}>Edit Role</.link>
</:action>
</.table>
<.pagination
endpoint={~p"/servers"}
page={@page}
page_params={@page_params}
params={@params}
/>
</div>
<% end %>
"""
end
@impl true
def mount(params, _session, socket) do
search_query = Map.get(params, "query", "")
sort_by = Map.get(params, "sort_by", "name")
sort_by = Map.get(params, "sort_by", "name") |> validate_sort_by()
page_params = AshPhoenix.LiveView.page_from_params(params, 10)
page = User.search!(
search_query,
query: [sort_input: sort_by],
page: page_params ++ [count: true],
actor: socket.assigns.current_user
)
@@ -48,9 +77,10 @@ defmodule DecentralisedBookIndexWeb.UserLive.Index do
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(:users, user_row(page.results))
|> assign(:users, page.results)
|> assign(:params, params)
|> apply_action(socket.assigns.live_action, params)
@@ -67,7 +97,39 @@ defmodule DecentralisedBookIndexWeb.UserLive.Index do
|> assign(:page_title, "Listing Users")
end
defp user_row(users) do
Enum.map(users, fn user -> {user.id, user} end)
defp sort_options do
[
{"Sort by email", "email"},
{"Sort by role", "role"},
{"Sort by role desc", "-role"},
]
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"/users?#{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"/users?#{params}")}
end
end