- <.header>
- {gettext("Listing Users")}
- <:actions>
- <.button variant="primary" navigate={~p"/users/new"}>
- <.icon name="hero-plus" /> {gettext("New User")}
-
-
-
-
- <.table
- id="users"
- rows={@streams.users}
- row_click={fn {_id, user} -> JS.navigate(~p"/users/#{user}") end}
- >
- <:col :let={{_id, user}} label={gettext("Email")}>{user.email}
- <:col :let={{_id, user}} label={gettext("OIDC ID")}>{user.oidc_id}
-
- <:action :let={{_id, user}}>
-
- <.link navigate={~p"/users/#{user}"}>{gettext("Show")}
-
-
- <.link navigate={~p"/users/#{user}/edit"}>{gettext("Edit")}
-
-
- <:action :let={{id, user}}>
- <.link
- phx-click={JS.push("delete", value: %{id: user.id}) |> hide("##{id}")}
- data-confirm={gettext("Are you sure?")}
- >
- {gettext("Delete")}
-
-
-
-
- """
- end
+ import MvWeb.TableComponents
@impl true
def mount(_params, _session, socket) do
+ users = Ash.read!(Mv.Accounts.User, domain: Mv.Accounts)
+ sorted = Enum.sort_by(users, & &1.email)
+
{:ok,
socket
|> assign(:page_title, gettext("Listing Users"))
- |> stream(:users, Ash.read!(Mv.Accounts.User, domain: Mv.Accounts))}
+ |> assign(:sort_field, :email)
+ |> assign(:sort_order, :asc)
+ |> assign(:users, sorted)
+ |> assign(:selected_users, [])}
end
@impl true
@@ -56,6 +21,66 @@ defmodule MvWeb.UserLive.Index do
user = Ash.get!(Mv.Accounts.User, id, domain: Mv.Accounts)
Ash.destroy!(user, domain: Mv.Accounts)
- {:noreply, stream_delete(socket, :users, user)}
+ updated_users = Enum.reject(socket.assigns.users, &(&1.id == id))
+ {:noreply, assign(socket, :users, updated_users)}
end
+
+ # Selects one user in the list of users
+ @impl true
+ def handle_event("select_user", %{"id" => id}, socket) do
+ selected =
+ if id in socket.assigns.selected_users do
+ List.delete(socket.assigns.selected_users, id)
+ else
+ [id | socket.assigns.selected_users]
+ end
+
+ {:noreply, assign(socket, :selected_users, selected)}
+ end
+
+ # Sorts the list of users according to a field, when you click on the column header
+ @impl true
+ def handle_event("sort", %{"field" => field_str}, socket) do
+ users = socket.assigns.users
+ field = String.to_existing_atom(field_str)
+
+ new_order =
+ if socket.assigns.sort_field == field do
+ toggle_order(socket.assigns.sort_order)
+ else
+ :asc
+ end
+
+ sorted_users =
+ users
+ |> Enum.sort_by(&Map.get(&1, field), sort_fun(new_order))
+
+ {:noreply,
+ socket
+ |> assign(:sort_field, field)
+ |> assign(:sort_order, new_order)
+ |> assign(:users, sorted_users)}
+ end
+
+ # Selects all users in the list of users
+ @impl true
+ def handle_event("select_all", _params, socket) do
+ users = socket.assigns.users
+
+ all_ids = Enum.map(users, & &1.id)
+
+ selected =
+ if Enum.sort(socket.assigns.selected_users) == Enum.sort(all_ids) do
+ []
+ else
+ all_ids
+ end
+
+ {:noreply, assign(socket, :selected_users, selected)}
+ end
+
+ defp toggle_order(:asc), do: :desc
+ defp toggle_order(:desc), do: :asc
+ defp sort_fun(:asc), do: &<=/2
+ defp sort_fun(:desc), do: &>=/2
end
diff --git a/lib/mv_web/live/user_live/index.html.heex b/lib/mv_web/live/user_live/index.html.heex
new file mode 100644
index 0000000..5b313f0
--- /dev/null
+++ b/lib/mv_web/live/user_live/index.html.heex
@@ -0,0 +1,75 @@
+