Always broadcast from update_device_status/2 so the device index LiveView refreshes even when status hasn't changed. Add a 15-second tick timer to keep "Last Checked" timestamps fresh between polls. Scope alert PubSub topics to organization for defense-in-depth.
52 lines
1.8 KiB
Elixir
52 lines
1.8 KiB
Elixir
defmodule ToweropsWeb.DashboardLive do
|
|
@moduledoc false
|
|
use ToweropsWeb, :live_view
|
|
|
|
alias Towerops.Alerts
|
|
alias Towerops.Devices
|
|
alias Towerops.Sites
|
|
|
|
@impl true
|
|
def mount(_params, _session, socket) do
|
|
organization = socket.assigns.current_scope.organization
|
|
|
|
# Subscribe to real-time alert updates
|
|
_ =
|
|
if connected?(socket) do
|
|
_ = Phoenix.PubSub.subscribe(Towerops.PubSub, "alerts:org:#{organization.id}:new")
|
|
Phoenix.PubSub.subscribe(Towerops.PubSub, "alerts:org:#{organization.id}:resolved")
|
|
end
|
|
|
|
{:ok,
|
|
socket
|
|
|> assign(:page_title, organization.name)
|
|
|> load_dashboard_data(organization.id)}
|
|
end
|
|
|
|
@impl true
|
|
def handle_info({:new_alert, _device_id, _alert_type}, socket) do
|
|
{:noreply, load_dashboard_data(socket, socket.assigns.current_scope.organization.id)}
|
|
end
|
|
|
|
@impl true
|
|
def handle_info({:alert_resolved, _device_id, _alert_type}, socket) do
|
|
{:noreply, load_dashboard_data(socket, socket.assigns.current_scope.organization.id)}
|
|
end
|
|
|
|
defp load_dashboard_data(socket, organization_id) do
|
|
organization = socket.assigns.current_scope.organization
|
|
active_alerts = Alerts.list_organization_active_alerts(organization_id)
|
|
sites_count = if organization.use_sites, do: Sites.count_organization_sites(organization_id), else: 0
|
|
status_counts = Devices.get_device_status_counts(organization_id)
|
|
|
|
device_count = status_counts |> Map.values() |> Enum.sum()
|
|
|
|
socket
|
|
|> assign(:active_alerts, active_alerts)
|
|
|> assign(:sites_count, sites_count)
|
|
|> assign(:device_count, device_count)
|
|
|> assign(:device_up, Map.get(status_counts, :up, 0))
|
|
|> assign(:device_down, Map.get(status_counts, :down, 0))
|
|
|> assign(:device_unknown, Map.get(status_counts, :unknown, 0))
|
|
end
|
|
end
|