From 599fa2e69ec9b9a7c4c8274890707df7c989df32 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Wed, 14 Jan 2026 09:12:59 -0600 Subject: [PATCH] Integrate agent health statistics into agent UI - Added Stats module to agent LiveView index - Load organization-wide health statistics on mount - Display agent health, equipment counts, and assignment breakdown - Refresh stats after agent creation/revocation - All 10 agent LiveView tests passing --- lib/towerops_web/live/agent_live/index.ex | 25 ++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/towerops_web/live/agent_live/index.ex b/lib/towerops_web/live/agent_live/index.ex index 6724bbb0..ff71cee0 100644 --- a/lib/towerops_web/live/agent_live/index.ex +++ b/lib/towerops_web/live/agent_live/index.ex @@ -3,23 +3,32 @@ defmodule ToweropsWeb.AgentLive.Index do use ToweropsWeb, :live_view alias Towerops.Agents + alias Towerops.Agents.Stats @impl true def mount(_params, _session, socket) do organization = socket.assigns.current_organization agent_tokens = Agents.list_organization_agent_tokens(organization.id) - # Get equipment counts for each agent + # Get equipment counts for each agent (directly assigned) equipment_counts = Map.new(agent_tokens, fn token -> {token.id, Agents.count_assigned_equipment(token.id)} end) + # Get organization-wide agent health statistics + agent_health_stats = Stats.get_organization_agent_health(organization.id) + assignment_breakdown = Stats.get_equipment_assignment_breakdown(organization.id) + offline_agents = Stats.get_offline_agents(organization.id) + {:ok, socket |> assign(:page_title, "Remote Agents") |> assign(:agent_tokens, agent_tokens) |> assign(:equipment_counts, equipment_counts) + |> assign(:agent_health_stats, agent_health_stats) + |> assign(:assignment_breakdown, assignment_breakdown) + |> assign(:offline_agents, offline_agents) |> assign(:new_token, nil) |> assign(:show_token_modal, false) |> assign(:agent_form, to_form(%{"name" => ""}))} @@ -50,10 +59,18 @@ defmodule ToweropsWeb.AgentLive.Index do {t.id, Agents.count_assigned_equipment(t.id)} end) + # Refresh health statistics + agent_health_stats = Stats.get_organization_agent_health(organization.id) + assignment_breakdown = Stats.get_equipment_assignment_breakdown(organization.id) + offline_agents = Stats.get_offline_agents(organization.id) + {:noreply, socket |> assign(:agent_tokens, agent_tokens) |> assign(:equipment_counts, equipment_counts) + |> assign(:agent_health_stats, agent_health_stats) + |> assign(:assignment_breakdown, assignment_breakdown) + |> assign(:offline_agents, offline_agents) |> assign(:new_token, %{agent_token: agent_token, token: token}) |> assign(:show_token_modal, true) |> assign(:agent_form, to_form(%{"name" => ""})) @@ -117,9 +134,15 @@ defmodule ToweropsWeb.AgentLive.Index do organization = socket.assigns.current_organization agent_tokens = Agents.list_organization_agent_tokens(organization.id) + # Refresh health statistics + agent_health_stats = Stats.get_organization_agent_health(organization.id) + offline_agents = Stats.get_offline_agents(organization.id) + {:noreply, socket |> assign(:agent_tokens, agent_tokens) + |> assign(:agent_health_stats, agent_health_stats) + |> assign(:offline_agents, offline_agents) |> put_flash(:info, "Agent revoked successfully")} {:error, _} ->