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
67 lines
2.3 KiB
Text
67 lines
2.3 KiB
Text
<Layouts.authenticated
|
|
flash={@flash}
|
|
current_scope={@current_scope}
|
|
current_organization={@organization}
|
|
>
|
|
<div class="mb-4">
|
|
<.link
|
|
navigate={
|
|
if @live_action == :edit,
|
|
do: ~p"/orgs/#{@organization.slug}/sites/#{@site.id}",
|
|
else: ~p"/orgs/#{@organization.slug}/sites"
|
|
}
|
|
class="inline-flex items-center gap-1 text-sm text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-100"
|
|
>
|
|
<.icon name="hero-arrow-left" class="h-4 w-4" />
|
|
{if @live_action == :edit, do: "Back to Site", else: "Back to Sites"}
|
|
</.link>
|
|
</div>
|
|
|
|
<.header>
|
|
{@page_title}
|
|
<:subtitle>
|
|
{if @live_action == :new,
|
|
do: "Add a new site to your organization",
|
|
else: "Update site details"}
|
|
</:subtitle>
|
|
</.header>
|
|
|
|
<div class="max-w-2xl">
|
|
<.form for={@form} id="site-form" phx-change="validate" phx-submit="save">
|
|
<.input field={@form[:name]} type="text" label="Site Name" required />
|
|
|
|
<.input
|
|
field={@form[:parent_site_id]}
|
|
type="select"
|
|
label="Parent Site (optional)"
|
|
prompt="No parent site"
|
|
options={Enum.map(@available_parent_sites, &{&1.name, &1.id})}
|
|
/>
|
|
|
|
<.input field={@form[:location]} type="text" label="Location" />
|
|
|
|
<.input field={@form[:description]} type="textarea" label="Description" />
|
|
|
|
<div class="flex gap-3 mt-6">
|
|
<.button phx-disable-with="Saving..." variant="primary">Save Site</.button>
|
|
<.button navigate={~p"/orgs/#{@organization.slug}/sites"}>Cancel</.button>
|
|
</div>
|
|
</.form>
|
|
|
|
<%= if @live_action == :edit do %>
|
|
<div class="mt-12 pt-8 border-t border-zinc-200 dark:border-zinc-800">
|
|
<h3 class="text-lg font-semibold text-red-600 dark:text-red-500 mb-4">Danger Zone</h3>
|
|
<p class="text-sm text-zinc-600 dark:text-zinc-400 mb-4">
|
|
Once you delete a site, there is no going back. This will also delete all equipment at this site.
|
|
</p>
|
|
<.button
|
|
phx-click="delete"
|
|
data-confirm="Are you sure you want to delete this site? This will also delete all equipment at this site."
|
|
variant="danger"
|
|
>
|
|
<.icon name="hero-trash" class="h-4 w-4" /> Delete Site
|
|
</.button>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
</Layouts.authenticated>
|