add device count to superadmin
This commit is contained in:
parent
8044a6d140
commit
20952a781f
4 changed files with 114 additions and 1 deletions
|
|
@ -33,6 +33,7 @@ defmodule Towerops.Accounts.User do
|
|||
field :privacy_policy_consent, :boolean, virtual: true
|
||||
field :terms_of_service_consent, :boolean, virtual: true
|
||||
field :password_breach_count, :integer, virtual: true
|
||||
field :device_count, :integer, virtual: true
|
||||
field :last_sudo_at, :utc_datetime
|
||||
|
||||
has_many :memberships, Membership
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ defmodule Towerops.Admin do
|
|||
## User Management
|
||||
|
||||
@doc """
|
||||
Lists all users in the system with their organizations.
|
||||
Lists all users in the system with their organizations and device counts.
|
||||
|
||||
## Options
|
||||
|
||||
|
|
@ -34,7 +34,17 @@ defmodule Towerops.Admin do
|
|||
limit = Keyword.get(opts, :limit, 100)
|
||||
offset = Keyword.get(opts, :offset, 0)
|
||||
|
||||
# Subquery to count devices across all user's organizations
|
||||
device_count_query =
|
||||
from d in "devices",
|
||||
join: m in "organization_memberships",
|
||||
on: d.organization_id == m.organization_id,
|
||||
where: m.user_id == parent_as(:user).id,
|
||||
select: count(d.id)
|
||||
|
||||
User
|
||||
|> from(as: :user)
|
||||
|> select_merge([u], %{device_count: subquery(device_count_query)})
|
||||
|> order_by([u], desc: u.inserted_at)
|
||||
|> limit(^limit)
|
||||
|> offset(^offset)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
<:col :let={user} label="Email">{user.email}</:col>
|
||||
<:col :let={user} label="Superuser">{if user.is_superuser, do: "Yes", else: "No"}</:col>
|
||||
<:col :let={user} label="Organizations">{length(user.organizations)}</:col>
|
||||
<:col :let={user} label="Devices">{user.device_count || 0}</:col>
|
||||
<:col :let={user} label="Joined">
|
||||
{ToweropsWeb.TimeHelpers.format_date(user.inserted_at, @timezone)}
|
||||
</:col>
|
||||
|
|
|
|||
101
test/towerops_web/live/admin/user_live_test.exs
Normal file
101
test/towerops_web/live/admin/user_live_test.exs
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
defmodule ToweropsWeb.Admin.UserLiveTest do
|
||||
use ToweropsWeb.ConnCase
|
||||
|
||||
import Phoenix.LiveViewTest
|
||||
import Towerops.AccountsFixtures
|
||||
import Towerops.DevicesFixtures
|
||||
import Towerops.OrganizationsFixtures
|
||||
|
||||
describe "Index" do
|
||||
setup do
|
||||
superuser =
|
||||
user_fixture()
|
||||
|> Ecto.Changeset.change(%{is_superuser: true})
|
||||
|> Towerops.Repo.update!()
|
||||
|
||||
%{superuser: superuser}
|
||||
end
|
||||
|
||||
test "displays device count for users", %{conn: conn, superuser: superuser} do
|
||||
# Create a regular user
|
||||
user = user_fixture()
|
||||
|
||||
# Create organizations with user as owner
|
||||
org1 = organization_fixture(user.id)
|
||||
org2 = organization_fixture(user.id)
|
||||
|
||||
# Create devices in different organizations (device_fixture auto-creates sites)
|
||||
device_fixture(%{organization_id: org1.id})
|
||||
device_fixture(%{organization_id: org1.id})
|
||||
device_fixture(%{organization_id: org2.id})
|
||||
|
||||
# Log in as superuser
|
||||
conn = log_in_user(conn, superuser)
|
||||
|
||||
# Visit the admin users page
|
||||
{:ok, view, html} = live(conn, ~p"/admin/users")
|
||||
|
||||
# Check that the device count column header is displayed
|
||||
assert html =~ "Devices"
|
||||
|
||||
# Verify device count is in the assigns
|
||||
users = :sys.get_state(view.pid).socket.assigns.users
|
||||
test_user = Enum.find(users, &(&1.id == user.id))
|
||||
assert test_user.device_count == 3
|
||||
end
|
||||
|
||||
test "displays 0 devices for users with no organizations", %{conn: conn, superuser: superuser} do
|
||||
# Create a user with no organizations
|
||||
user = user_fixture()
|
||||
|
||||
# Log in as superuser
|
||||
conn = log_in_user(conn, superuser)
|
||||
|
||||
# Visit the admin users page
|
||||
{:ok, view, html} = live(conn, ~p"/admin/users")
|
||||
|
||||
# Check that the device count column header is displayed
|
||||
assert html =~ "Devices"
|
||||
|
||||
# Verify device count is 0 in the assigns
|
||||
users = :sys.get_state(view.pid).socket.assigns.users
|
||||
test_user = Enum.find(users, &(&1.id == user.id))
|
||||
assert test_user.device_count == 0
|
||||
end
|
||||
|
||||
test "device count only includes devices from user's organizations", %{
|
||||
conn: conn,
|
||||
superuser: superuser
|
||||
} do
|
||||
# Create two users
|
||||
user1 = user_fixture()
|
||||
user2 = user_fixture()
|
||||
|
||||
# Create organizations (user1 belongs to org1, user2 to org2)
|
||||
org1 = organization_fixture(user1.id)
|
||||
org2 = organization_fixture(user2.id)
|
||||
|
||||
# Create devices (user1 should only see devices from org1)
|
||||
device_fixture(%{organization_id: org1.id})
|
||||
device_fixture(%{organization_id: org1.id})
|
||||
device_fixture(%{organization_id: org2.id})
|
||||
|
||||
# Log in as superuser
|
||||
conn = log_in_user(conn, superuser)
|
||||
|
||||
# Visit the admin users page
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/users")
|
||||
|
||||
# Get all users from the assigns
|
||||
users = :sys.get_state(view.pid).socket.assigns.users
|
||||
|
||||
# Find user1 and verify device count
|
||||
user1_with_count = Enum.find(users, &(&1.id == user1.id))
|
||||
assert user1_with_count.device_count == 2
|
||||
|
||||
# Find user2 and verify device count
|
||||
user2_with_count = Enum.find(users, &(&1.id == user2.id))
|
||||
assert user2_with_count.device_count == 1
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue