Migrates all equipment-related flash messages to gettext for internationalization: - DeviceLive.Index: device discovery, reordering, error messages - DeviceLive.Show: backup messages, permission errors - DeviceLive.Form: device CRUD operations - AlertLive.Index: alert acknowledgment messages - SiteLive.Show: site discovery messages - SiteLive.Form: site CRUD and SNMP/agent propagation Fixes sudo mode test suite issues: - Updates Accounts.sudo_mode?/2 test to check last_sudo_at instead of authenticated_at - Adds register_and_log_in_user_with_sudo/1 helper to ConnCase - Fixes UserAuth sudo mode tests to use session-based authentication - Updates MyData tests to use sudo mode (now required per router config) - Removes obsolete UserSettingsLive "without sudo mode" test - Fixes grant_sudo_mode/1 DateTime truncation to seconds All equipment module tests passing. Ready for Phase 3 (Admin Features).
92 lines
2.6 KiB
Elixir
92 lines
2.6 KiB
Elixir
defmodule ToweropsWeb.AlertLive.Index do
|
|
@moduledoc false
|
|
use ToweropsWeb, :live_view
|
|
|
|
alias Towerops.Alerts
|
|
alias Towerops.Repo
|
|
|
|
@impl true
|
|
def mount(_params, _session, socket) do
|
|
organization = socket.assigns.current_scope.organization
|
|
|
|
# Subscribe to alert events
|
|
_ =
|
|
if connected?(socket) do
|
|
_ = Phoenix.PubSub.subscribe(Towerops.PubSub, "alerts:new")
|
|
Phoenix.PubSub.subscribe(Towerops.PubSub, "alerts:resolved")
|
|
end
|
|
|
|
{:ok,
|
|
socket
|
|
|> assign(:page_title, "Alerts")
|
|
|> assign(:filter, "active")
|
|
|> load_alerts(organization.id)}
|
|
end
|
|
|
|
@impl true
|
|
def handle_params(params, _url, socket) do
|
|
filter = Map.get(params, "filter", "active")
|
|
|
|
{:noreply,
|
|
socket
|
|
|> assign(:filter, filter)
|
|
|> load_alerts(socket.assigns.current_scope.organization.id)}
|
|
end
|
|
|
|
@impl true
|
|
def handle_event("acknowledge", %{"id" => id}, socket) do
|
|
organization = socket.assigns.current_scope.organization
|
|
user_id = socket.assigns.current_scope.user.id
|
|
|
|
case Alerts.get_alert(id) do
|
|
nil ->
|
|
{:noreply, put_flash(socket, :error, t_equipment("Alert not found"))}
|
|
|
|
alert ->
|
|
# Preload device and site to check organization access
|
|
alert = Repo.preload(alert, device: [site: :organization])
|
|
|
|
if alert.device.site.organization_id == organization.id do
|
|
perform_acknowledge_alert(socket, alert, user_id, organization.id)
|
|
else
|
|
{:noreply, put_flash(socket, :error, t_equipment("You don't have access to this alert"))}
|
|
end
|
|
end
|
|
end
|
|
|
|
defp perform_acknowledge_alert(socket, alert, user_id, organization_id) do
|
|
case Alerts.acknowledge_alert(alert, user_id) do
|
|
{:ok, _alert} ->
|
|
{:noreply,
|
|
socket
|
|
|> put_flash(:info, t_equipment("Alert acknowledged"))
|
|
|> load_alerts(organization_id)}
|
|
|
|
{:error, _changeset} ->
|
|
{:noreply, put_flash(socket, :error, t_equipment("Unable to acknowledge alert"))}
|
|
end
|
|
end
|
|
|
|
@impl true
|
|
def handle_info({:new_alert, _device_id, _alert_type}, socket) do
|
|
{:noreply, load_alerts(socket, socket.assigns.current_scope.organization.id)}
|
|
end
|
|
|
|
@impl true
|
|
def handle_info({:alert_resolved, _device_id, _alert_type}, socket) do
|
|
{:noreply, load_alerts(socket, socket.assigns.current_scope.organization.id)}
|
|
end
|
|
|
|
defp load_alerts(socket, organization_id) do
|
|
alerts =
|
|
case socket.assigns.filter do
|
|
"active" ->
|
|
Alerts.list_organization_active_alerts(organization_id)
|
|
|
|
_ ->
|
|
Alerts.list_organization_alerts(organization_id, 100)
|
|
end
|
|
|
|
assign(socket, :alerts, alerts)
|
|
end
|
|
end
|