diff --git a/lib/towerops_web/live/admin/agent_live/index.ex b/lib/towerops_web/live/admin/agent_live/index.ex index 43a6dc67..eb7c8ff0 100644 --- a/lib/towerops_web/live/admin/agent_live/index.ex +++ b/lib/towerops_web/live/admin/agent_live/index.ex @@ -14,13 +14,17 @@ defmodule ToweropsWeb.Admin.AgentLive.Index do end agent_tokens = Agents.list_all_agent_tokens() + {cloud_pollers, org_agents} = Enum.split_with(agent_tokens, & &1.is_cloud_poller) device_counts = calculate_device_counts(agent_tokens) {:ok, socket |> assign(:page_title, "All Agents") |> assign(:timezone, socket.assigns.current_scope.timezone) - |> stream(:agent_tokens, agent_tokens) + |> stream(:cloud_pollers, cloud_pollers) + |> stream(:org_agents, org_agents) + |> assign(:has_cloud_pollers, cloud_pollers != []) + |> assign(:has_org_agents, org_agents != []) |> assign(:device_counts, device_counts) |> assign(:now, DateTime.utc_now())} end @@ -56,8 +60,10 @@ defmodule ToweropsWeb.Admin.AgentLive.Index do direct = Agents.count_assigned_devices(agent_token_id) total = length(Agents.list_agent_polling_targets(agent_token_id)) + stream_name = if agent_token.is_cloud_poller, do: :cloud_pollers, else: :org_agents + socket - |> stream_insert(:agent_tokens, agent_token) + |> stream_insert(stream_name, agent_token) |> assign(:device_counts, Map.put(socket.assigns.device_counts, agent_token_id, %{direct: direct, total: total})) rescue Ecto.NoResultsError -> socket @@ -65,10 +71,14 @@ defmodule ToweropsWeb.Admin.AgentLive.Index do defp reload_all(socket) do agent_tokens = Agents.list_all_agent_tokens() + {cloud_pollers, org_agents} = Enum.split_with(agent_tokens, & &1.is_cloud_poller) device_counts = calculate_device_counts(agent_tokens) socket - |> stream(:agent_tokens, agent_tokens, reset: true) + |> stream(:cloud_pollers, cloud_pollers, reset: true) + |> stream(:org_agents, org_agents, reset: true) + |> assign(:has_cloud_pollers, cloud_pollers != []) + |> assign(:has_org_agents, org_agents != []) |> assign(:device_counts, device_counts) end diff --git a/lib/towerops_web/live/admin/agent_live/index.html.heex b/lib/towerops_web/live/admin/agent_live/index.html.heex index 87fd34f1..1b6120dc 100644 --- a/lib/towerops_web/live/admin/agent_live/index.html.heex +++ b/lib/towerops_web/live/admin/agent_live/index.html.heex @@ -7,77 +7,149 @@

- <.table id="admin-agents-table" rows={@streams.agent_tokens}> - <:col :let={{_id, agent}} label="Name"> -
- <.link - navigate={~p"/agents/#{agent.id}"} - class="font-medium text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300" - > - {agent.name} - - <%= if agent.is_cloud_poller do %> - - <.icon name="hero-cloud" class="h-3 w-3" /> Cloud + <%!-- Cloud Pollers --%> + <%= if @has_cloud_pollers do %> +
+

+ <.icon name="hero-cloud" class="w-5 h-5 inline mr-1" /> Cloud Pollers +

+ <.table id="cloud-pollers-table" rows={@streams.cloud_pollers}> + <:col :let={{_id, agent}} label="Name"> +
+ <.link + navigate={~p"/agents/#{agent.id}"} + class="font-medium text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300" + > + {agent.name} + + <%= if agent.allow_remote_debug do %> + + <.icon name="hero-bug-ant" class="h-3 w-3" /> Debug + + <% end %> +
+ + + <:col :let={{_id, agent}} label="Status"> + <% {status, label} = agent_status(agent) %> + + + {label} - <% end %> - <%= if agent.allow_remote_debug do %> - - <.icon name="hero-bug-ant" class="h-3 w-3" /> Debug + + + <:col :let={{_id, agent}} label="Devices"> + <% counts = Map.get(@device_counts, agent.id, %{direct: 0, total: 0}) %> +
+ {counts.total} total +
+
+ {counts.direct} direct + <%= if counts.total > counts.direct do %> + · {counts.total - counts.direct} inherited + <% end %> +
+ + + <:col :let={{_id, agent}} label="Last Seen"> +
+ <.timestamp datetime={agent.last_seen_at} timezone={@timezone} now={@now} /> +
+ <%= if agent.last_seen_at do %> +
+ <.timestamp + datetime={agent.last_seen_at} + timezone={@timezone} + format="absolute" + /> +
+ <% end %> + + + <:col :let={{_id, agent}} label="Version"> + <%= if agent.metadata["version"] do %> +
+ {format_agent_version(agent.metadata["version"])} +
+ <% end %> + + +
+ <% end %> + + <%!-- Organization Agents --%> + <%= if @has_org_agents do %> +
+

+ <.icon name="hero-server" class="w-5 h-5 inline mr-1" /> Organization Agents +

+ <.table id="org-agents-table" rows={@streams.org_agents}> + <:col :let={{_id, agent}} label="Name"> +
+
+ <.link + navigate={~p"/agents/#{agent.id}"} + class="font-medium text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300" + > + {agent.name} + + <%= if agent.allow_remote_debug do %> + + <.icon name="hero-bug-ant" class="h-3 w-3" /> Debug + + <% end %> +
+
+ {agent.organization && agent.organization.name} +
+
+ + + <:col :let={{_id, agent}} label="Status"> + <% {status, label} = agent_status(agent) %> + + + {label} - <% end %> -
- + - <:col :let={{_id, agent}} label="Organization"> - <%= if agent.is_cloud_poller do %> - Cloud Poller - <% else %> - - {agent.organization && agent.organization.name} - - <% end %> - + <:col :let={{_id, agent}} label="Devices"> + <% counts = Map.get(@device_counts, agent.id, %{direct: 0, total: 0}) %> +
+ {counts.total} total +
+
+ {counts.direct} direct + <%= if counts.total > counts.direct do %> + · {counts.total - counts.direct} inherited + <% end %> +
+ - <:col :let={{_id, agent}} label="Status"> - <% {status, label} = agent_status(agent) %> - - - {label} - - + <:col :let={{_id, agent}} label="Last Seen"> +
+ <.timestamp datetime={agent.last_seen_at} timezone={@timezone} now={@now} /> +
+ <%= if agent.last_seen_at do %> +
+ <.timestamp + datetime={agent.last_seen_at} + timezone={@timezone} + format="absolute" + /> +
+ <% end %> + - <:col :let={{_id, agent}} label="Devices"> - <% counts = Map.get(@device_counts, agent.id, %{direct: 0, total: 0}) %> -
- {counts.total} total -
-
- {counts.direct} direct - <%= if counts.total > counts.direct do %> - · {counts.total - counts.direct} inherited - <% end %> -
- - - <:col :let={{_id, agent}} label="Last Seen"> -
- <.timestamp datetime={agent.last_seen_at} timezone={@timezone} now={@now} /> -
- <%= if agent.last_seen_at do %> -
- <.timestamp datetime={agent.last_seen_at} timezone={@timezone} format="absolute" /> -
- <% end %> - - - <:col :let={{_id, agent}} label="Version"> - <%= if agent.metadata["version"] do %> -
- {format_agent_version(agent.metadata["version"])} -
- <% end %> - - + <:col :let={{_id, agent}} label="Version"> + <%= if agent.metadata["version"] do %> +
+ {format_agent_version(agent.metadata["version"])} +
+ <% end %> + + +
+ <% end %>