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
54 lines
2 KiB
Text
54 lines
2 KiB
Text
<Layouts.authenticated
|
|
flash={@flash}
|
|
current_scope={@current_scope}
|
|
current_organization={@current_organization}
|
|
active_page="sites"
|
|
>
|
|
<.header>
|
|
{@page_title}
|
|
<:subtitle>Manage your site locations and hierarchy</:subtitle>
|
|
<:actions>
|
|
<.button navigate={~p"/orgs/#{@current_organization.slug}/sites/new"} variant="primary">
|
|
<.icon name="hero-plus" class="h-5 w-5" /> New Site
|
|
</.button>
|
|
</:actions>
|
|
</.header>
|
|
|
|
<%= if @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">No sites</h3>
|
|
<p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
|
|
Get started by creating your first site.
|
|
</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" /> New Site
|
|
</.button>
|
|
</div>
|
|
</div>
|
|
<% else %>
|
|
<div class="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
|
|
<.link
|
|
:for={site <- @sites}
|
|
navigate={~p"/orgs/#{@current_organization.slug}/sites/#{site.id}"}
|
|
class="relative overflow-hidden rounded-lg border border-zinc-200 bg-white p-6 shadow-sm hover:shadow-md transition-shadow dark:border-zinc-800 dark:bg-zinc-900 cursor-pointer"
|
|
>
|
|
<h3 class="text-xl font-semibold text-zinc-900 dark:text-zinc-100">{site.name}</h3>
|
|
<%= if site.location do %>
|
|
<p class="mt-2 flex items-center gap-1.5 text-sm text-zinc-600 dark:text-zinc-400">
|
|
<.icon name="hero-map-pin" class="h-4 w-4" /> {site.location}
|
|
</p>
|
|
<% end %>
|
|
<%= if site.parent_site do %>
|
|
<p class="mt-2 text-xs text-zinc-500 dark:text-zinc-500">
|
|
Parent: {site.parent_site.name}
|
|
</p>
|
|
<% end %>
|
|
</.link>
|
|
</div>
|
|
<% end %>
|
|
</Layouts.authenticated>
|