205 lines
5.9 KiB
Elixir
205 lines
5.9 KiB
Elixir
|
defmodule Bones73kWeb.UserManagementLive.Index do
|
||
|
use Bones73kWeb, :live_view
|
||
|
|
||
|
import Ecto.Query
|
||
|
import Bones73kWeb.Pagination
|
||
|
import Bones73k.Util.Dt
|
||
|
|
||
|
alias Bones73k.Repo
|
||
|
alias Bones73k.Accounts
|
||
|
alias Bones73k.Accounts.User
|
||
|
alias Bones73kWeb.Roles
|
||
|
|
||
|
@impl true
|
||
|
def mount(_params, session, socket) do
|
||
|
socket
|
||
|
|> assign_defaults(session)
|
||
|
|> live_okreply()
|
||
|
end
|
||
|
|
||
|
@impl true
|
||
|
def handle_params(params, _url, socket) do
|
||
|
current_user = socket.assigns.current_user
|
||
|
live_action = socket.assigns.live_action
|
||
|
user = user_from_params(params)
|
||
|
|
||
|
if Roles.can?(current_user, user, live_action) do
|
||
|
socket
|
||
|
|> assign(:query, query_map(params))
|
||
|
|> assign_modal_return_to()
|
||
|
|> page_query()
|
||
|
|> apply_action(socket.assigns.live_action, params)
|
||
|
|> live_noreply()
|
||
|
else
|
||
|
socket
|
||
|
|> put_flash(:error, "Unauthorised")
|
||
|
|> redirect(to: "/")
|
||
|
|> live_noreply()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
defp apply_action(socket, :index, _params) do
|
||
|
socket
|
||
|
|> assign(:page_title, "Listing Users")
|
||
|
|> assign(:user, nil)
|
||
|
end
|
||
|
|
||
|
defp apply_action(socket, :new, _params) do
|
||
|
socket
|
||
|
|> assign(:page_title, "New User")
|
||
|
|> assign(:user, %User{})
|
||
|
end
|
||
|
|
||
|
defp apply_action(socket, :edit, %{"id" => id}) do
|
||
|
socket
|
||
|
|> assign(:page_title, "Edit User")
|
||
|
|> assign(:user, Accounts.get_user!(id))
|
||
|
end
|
||
|
|
||
|
def assign_modal_return_to(%{assigns: %{query: query}} = socket) do
|
||
|
to = Routes.user_management_index_path(socket, :index, Enum.into(query, []))
|
||
|
assign(socket, :modal_return_to, to)
|
||
|
end
|
||
|
|
||
|
defp user_from_params(params)
|
||
|
|
||
|
defp user_from_params(%{"id" => id}),
|
||
|
do: Accounts.get_user!(id)
|
||
|
|
||
|
defp user_from_params(_params), do: %User{}
|
||
|
|
||
|
def query_map(params) do
|
||
|
%{
|
||
|
filter: params["filter"] || "",
|
||
|
sort_by: (params["sort_by"] in ~w(email inserted_at role) && params["sort_by"]) || "email",
|
||
|
sort_order: (params["sort_order"] == "desc" && "desc") || "asc",
|
||
|
page_number: String.to_integer(params["page_number"] || "1"),
|
||
|
page_size: String.to_integer(params["page_size"] || "10")
|
||
|
}
|
||
|
end
|
||
|
|
||
|
defp page_query(%{assigns: %{query: query}} = socket) do
|
||
|
result_page =
|
||
|
from(u in User)
|
||
|
|> or_where([u], ilike(u.email, ^"%#{query.filter}%"))
|
||
|
# |> or_where([u], ilike(u.singer_name, ^"%#{query.filter}%"))
|
||
|
|> order_by([u], [
|
||
|
{^String.to_existing_atom(query.sort_order), ^String.to_existing_atom(query.sort_by)}
|
||
|
])
|
||
|
|> Repo.paginate(page: query.page_number, page_size: query.page_size)
|
||
|
|
||
|
socket
|
||
|
|> assign(:page, result_page)
|
||
|
|> assign(:table_loading, false)
|
||
|
end
|
||
|
|
||
|
@impl true
|
||
|
def handle_event("delete", %{"id" => id, "email" => email}, socket) do
|
||
|
id
|
||
|
|> Accounts.get_user()
|
||
|
|> Accounts.delete_user()
|
||
|
|> case do
|
||
|
{:ok, _} ->
|
||
|
socket
|
||
|
|> put_flash(:success, "User deleted successfully: \"#{email}\"")
|
||
|
|> assign(:table_loading, true)
|
||
|
|> page_query()
|
||
|
|> live_noreply()
|
||
|
|
||
|
{:error, _} ->
|
||
|
socket
|
||
|
|> put_flash(
|
||
|
:error,
|
||
|
"Something went wrong attempting to delete user \"#{email}\". Possibly already deleted? Reloading list..."
|
||
|
)
|
||
|
|> assign(:table_loading, true)
|
||
|
|> page_query()
|
||
|
|> live_noreply()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
@impl true
|
||
|
def handle_event("filter-change", params, socket) do
|
||
|
send(self(), {:query_update, Map.put(params, "page_number", "1")})
|
||
|
{:noreply, assign(socket, :table_loading, true)}
|
||
|
end
|
||
|
|
||
|
@impl true
|
||
|
def handle_event("filter-clear", _params, socket) do
|
||
|
send(self(), {:query_update, %{"filter" => "", "page_number" => "1"}})
|
||
|
{:noreply, assign(socket, :table_loading, true)}
|
||
|
end
|
||
|
|
||
|
@impl true
|
||
|
def handle_event(
|
||
|
"sort-change",
|
||
|
%{"sort_by" => column} = params,
|
||
|
%{assigns: %{query: query}} = socket
|
||
|
) do
|
||
|
(column == query.sort_by &&
|
||
|
send(
|
||
|
self(),
|
||
|
{:query_update, %{"sort_order" => (query.sort_order == "asc" && "desc") || "asc"}}
|
||
|
)) ||
|
||
|
send(self(), {:query_update, Map.put(params, "sort_order", "asc")})
|
||
|
|
||
|
{:noreply, assign(socket, :table_loading, true)}
|
||
|
end
|
||
|
|
||
|
@impl true
|
||
|
def handle_event("sort-by-change", %{"sort" => params}, socket) do
|
||
|
send(self(), {:query_update, params})
|
||
|
{:noreply, assign(socket, :table_loading, true)}
|
||
|
end
|
||
|
|
||
|
@impl true
|
||
|
def handle_event("sort-order-change", _params, socket) do
|
||
|
new_sort_order = (socket.assigns.query.sort_order == "asc" && "desc") || "asc"
|
||
|
send(self(), {:query_update, %{"sort_order" => new_sort_order}})
|
||
|
{:noreply, assign(socket, :table_loading, true)}
|
||
|
end
|
||
|
|
||
|
@impl true
|
||
|
def handle_event("page-change", params, socket) do
|
||
|
send(self(), {:query_update, params})
|
||
|
{:noreply, assign(socket, :table_loading, true)}
|
||
|
end
|
||
|
|
||
|
@impl true
|
||
|
def handle_event("page-size-change", params, socket) do
|
||
|
send(self(), {:query_update, Map.put(params, "page_number", "1")})
|
||
|
{:noreply, assign(socket, :table_loading, true)}
|
||
|
end
|
||
|
|
||
|
@impl true
|
||
|
def handle_info({:query_update, params}, %{assigns: %{query: q}} = socket) do
|
||
|
{:noreply,
|
||
|
push_patch(socket,
|
||
|
to: Routes.user_management_index_path(socket, :index, get_new_params(params, q)),
|
||
|
replace: true
|
||
|
)}
|
||
|
end
|
||
|
|
||
|
@impl true
|
||
|
def handle_info({:close_modal, _}, %{assigns: %{modal_return_to: to}} = socket) do
|
||
|
socket |> copy_flash() |> push_patch(to: to) |> live_noreply()
|
||
|
end
|
||
|
|
||
|
@impl true
|
||
|
def handle_info({:put_flash_message, {flash_type, msg}}, socket) do
|
||
|
socket |> put_flash(flash_type, msg) |> live_noreply()
|
||
|
end
|
||
|
|
||
|
defp get_new_params(params, query) do
|
||
|
[
|
||
|
{:filter, Map.get(params, "filter") || query.filter},
|
||
|
{:sort_by, Map.get(params, "sort_by") || query.sort_by},
|
||
|
{:sort_order, Map.get(params, "sort_order") || query.sort_order},
|
||
|
{:page_number, Map.get(params, "page_number") || query.page_number},
|
||
|
{:page_size, Map.get(params, "page_size") || query.page_size}
|
||
|
]
|
||
|
end
|
||
|
|
||
|
def dt_out(ndt), do: format_ndt(ndt, "{YYYY} {Mshort} {0D}, {h12}:{0m} {am}")
|
||
|
end
|