towerops/lib/towerops_web/live/equipment_live/index.html.heex
Graham McIntire 806b293ead
Fix impersonation to show correct user data and banner
Two issues were preventing impersonation from working correctly:

1. Templates were not passing current_scope to Layouts.authenticated,
   so the impersonation banner never displayed.

2. fetch_current_scope_for_user was looking up the user from the
   session token, which always pointed to the superuser. This caused
   the superuser to see their own organizations and equipment instead
   of the impersonated user's data.

Changes:
- Pass current_scope={@current_scope} to all Layouts.authenticated calls
- Store target_user_id in session during impersonation
- Fetch target user directly from database using target_user_id
- Update both fetch_current_scope_for_user (for controllers) and
  mount_current_scope (for LiveViews) to properly handle impersonation
- Clean up target_user_id from session when impersonation ends

Now when a superuser impersonates a user, they correctly see:
- The impersonation banner at the top with exit link
- The target user's organizations and equipment
- All data scoped to the impersonated user
2026-01-06 13:22:13 -06:00

107 lines
3.7 KiB
Text

<Layouts.authenticated
flash={@flash}
current_scope={@current_scope}
current_organization={@current_organization}
active_page="equipment"
>
<.header>
{@page_title}
<:subtitle>Monitor and manage all your network equipment</:subtitle>
<:actions>
<.button
:if={@has_sites}
navigate={~p"/orgs/#{@current_organization.slug}/equipment/new"}
variant="primary"
>
<.icon name="hero-plus" class="h-5 w-5" /> New Equipment
</.button>
</:actions>
</.header>
<%= if !@has_sites do %>
<div class="text-center py-16">
<.icon
name="hero-building-office"
class="mx-auto h-12 w-12 text-zinc-400 dark:text-zinc-600"
/>
<h3 class="mt-4 text-lg font-semibold text-zinc-900 dark:text-zinc-100">
Create a site first
</h3>
<p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
Before adding equipment, you need to create at least one site location.
</p>
<p class="mt-1 text-sm text-zinc-600 dark:text-zinc-400">
Sites help you organize your equipment by physical location.
</p>
<div class="mt-6">
<.button navigate={~p"/orgs/#{@current_organization.slug}/sites/new"} variant="primary">
<.icon name="hero-plus" class="h-5 w-5" /> Create Your First Site
</.button>
</div>
</div>
<% else %>
<%= if @equipment == [] do %>
<div class="text-center py-16">
<.icon name="hero-server" class="mx-auto h-12 w-12 text-zinc-400 dark:text-zinc-600" />
<h3 class="mt-4 text-lg font-semibold text-zinc-900 dark:text-zinc-100">No equipment</h3>
<p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
Get started by adding your first equipment.
</p>
<div class="mt-6">
<.button
navigate={~p"/orgs/#{@current_organization.slug}/equipment/new"}
variant="primary"
>
<.icon name="hero-plus" class="h-5 w-5" /> New Equipment
</.button>
</div>
</div>
<% else %>
<.table
id="equipment"
rows={@equipment}
row_click={
fn eq ->
JS.navigate(~p"/orgs/#{@current_organization.slug}/equipment/#{eq.id}")
end
}
>
<:col :let={eq} label="Name">
<span class="font-medium">{eq.name}</span>
</:col>
<:col :let={eq} label="IP Address">
<span class="font-mono text-sm">{eq.ip_address}</span>
</:col>
<:col :let={eq} label="Site">
<.link
navigate={~p"/orgs/#{@current_organization.slug}/sites/#{eq.site.id}"}
class="text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300"
>
{eq.site.name}
</.link>
</:col>
<:col :let={eq} label="Status">
<span class={[
"inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium",
eq.status == :up &&
"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200",
eq.status == :down && "bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200",
eq.status == :unknown &&
"bg-zinc-100 text-zinc-800 dark:bg-zinc-800 dark:text-zinc-200"
]}>
{eq.status |> to_string() |> String.upcase()}
</span>
</:col>
<:col :let={eq} label="Last Checked">
<span class="text-sm text-zinc-600 dark:text-zinc-400">
<%= if eq.last_checked_at do %>
{Calendar.strftime(eq.last_checked_at, "%Y-%m-%d %H:%M")}
<% else %>
Never
<% end %>
</span>
</:col>
</.table>
<% end %>
<% end %>
</Layouts.authenticated>