defmodule PhoenixKitWeb.Live.Activity.Show do @moduledoc """ Admin LiveView for viewing a single activity entry. Provides a shareable URL for individual activity entries with full detail. """ use PhoenixKitWeb, :live_view alias PhoenixKit.Activity alias PhoenixKit.Settings alias PhoenixKit.Users.Auth.Scope alias PhoenixKit.Utils.Routes @impl true def mount(%{"uuid" => uuid}, _session, socket) do scope = socket.assigns[:phoenix_kit_current_scope] if scope && Scope.has_module_access?(scope, "dashboard") do case Activity.get_entry(uuid) do nil -> {:ok, socket |> put_flash(:error, gettext("Activity not found")) |> push_navigate(to: Routes.path("/admin/activity"))} entry -> project_title = Settings.get_project_title() resource_user = resolve_resource_user(entry) # Resolve deep-links for the resource AND the actor/target (both users), # so the who-did-it / who-it's-for identities are clickable too. links = [entry] |> Enum.concat(user_items(entry)) |> PhoenixKit.ResourceLinks.resolve() socket = socket |> assign(:page_title, gettext("Activity Detail")) |> assign(:project_title, project_title) |> assign(:entry, entry) |> assign(:resource_user, resource_user) |> assign(:resource_link, links[{entry.resource_type, entry.resource_uuid}]) |> assign(:actor_link, links[{"user", entry.actor_uuid}]) |> assign(:target_link, links[{"user", entry.target_uuid}]) {:ok, socket} end else {:ok, socket |> put_flash(:error, gettext("Access denied")) |> push_navigate(to: Routes.path("/admin"))} end end @impl true def handle_params(_params, url, socket) do {:noreply, assign(socket, :url_path, URI.parse(url).path)} end # Synthetic `"user"` items for the actor + target uuids, so ResourceLinks can # resolve them alongside the entry's own resource in one pass. defp user_items(entry) do [entry.actor_uuid, entry.target_uuid] |> Enum.filter(&is_binary/1) |> Enum.uniq() |> Enum.map(&%{resource_type: "user", resource_uuid: &1}) end defp resolve_resource_user(entry) do if entry.resource_type == "user" && entry.resource_uuid do resource_users = Activity.resolve_resource_users([entry]) Map.get(resource_users, entry.resource_uuid) else nil end end defp mode_badge_color(mode), do: Activity.mode_badge_color(mode) defp action_badge_color(action), do: Activity.action_badge_color(action) end