Backend: - Migration: beacon_monitors table (binary_id PK, org/user FK, check_type, target_url, config, monitoring fields) - Schema: BeaconMonitor with changeset (pattern-matched port validation, check_type inclusion) - Query: BeaconMonitorQuery — composable scopes (by org, by user, by type, enabled, ordered, preloaded) - Context: Towerops.Beacons — CRUD, toggle, record_check_result (36/36 tests pass) Frontend: - User LiveView: /beacons — stream-based list, create/edit modals, toggle/delete actions - Admin LiveView: /admin/beacons — cross-org view with preloads (20/20 tests pass) - Form component: LiveComponent modal with validation - Helpers: check_type badges, status indicators, response time formatting - Router: user routes + admin route configured - Nav: sidebar + mobile links added - 30+ gettext translations Verification: compile ✓, format ✓, credo ✓, 56/56 new tests pass
86 lines
3.1 KiB
Elixir
86 lines
3.1 KiB
Elixir
defmodule ToweropsWeb.BeaconMonitorLive.Helpers do
|
|
@moduledoc """
|
|
Helper functions for Beacon Monitor LiveViews.
|
|
"""
|
|
|
|
use Gettext, backend: ToweropsWeb.Gettext
|
|
|
|
import ToweropsWeb.GettextHelpers
|
|
|
|
@doc """
|
|
Returns CSS classes for the check type badge based on check type.
|
|
"""
|
|
def check_type_badge_class("http"),
|
|
do: "bg-blue-50 text-blue-700 ring-blue-600/20 dark:bg-blue-900/30 dark:text-blue-300 dark:ring-blue-400/30"
|
|
|
|
def check_type_badge_class("tcp"),
|
|
do: "bg-green-50 text-green-700 ring-green-600/20 dark:bg-green-900/30 dark:text-green-300 dark:ring-green-400/30"
|
|
|
|
def check_type_badge_class("dns"),
|
|
do:
|
|
"bg-purple-50 text-purple-700 ring-purple-600/20 dark:bg-purple-900/30 dark:text-purple-300 dark:ring-purple-400/30"
|
|
|
|
def check_type_badge_class("ssl"),
|
|
do: "bg-amber-50 text-amber-700 ring-amber-600/20 dark:bg-amber-900/30 dark:text-amber-300 dark:ring-amber-400/30"
|
|
|
|
def check_type_badge_class("icmp"),
|
|
do: "bg-rose-50 text-rose-700 ring-rose-600/20 dark:bg-rose-900/30 dark:text-rose-300 dark:ring-rose-400/30"
|
|
|
|
def check_type_badge_class(_unknown),
|
|
do: "bg-gray-50 text-gray-700 ring-gray-600/20 dark:bg-gray-900/30 dark:text-gray-300 dark:ring-gray-400/30"
|
|
|
|
@doc """
|
|
Returns the human-readable label for a check type.
|
|
"""
|
|
def check_type_label("http"), do: "HTTP"
|
|
def check_type_label("tcp"), do: "TCP"
|
|
def check_type_label("dns"), do: "DNS"
|
|
def check_type_label("ssl"), do: "SSL"
|
|
def check_type_label("icmp"), do: "ICMP"
|
|
def check_type_label(_unknown), do: t_equipment("Unknown")
|
|
|
|
@doc """
|
|
Returns CSS classes for the status badge based on last status.
|
|
"""
|
|
def status_badge_class(nil),
|
|
do: "bg-gray-50 text-gray-600 ring-gray-500/10 dark:bg-gray-400/10 dark:text-gray-400 dark:ring-gray-400/20"
|
|
|
|
def status_badge_class("up"),
|
|
do: "bg-green-50 text-green-700 ring-green-600/20 dark:bg-green-900/30 dark:text-green-300 dark:ring-green-400/30"
|
|
|
|
def status_badge_class("down"),
|
|
do: "bg-red-50 text-red-700 ring-red-600/20 dark:bg-red-900/30 dark:text-red-300 dark:ring-red-400/30"
|
|
|
|
def status_badge_class(_unknown),
|
|
do:
|
|
"bg-yellow-50 text-yellow-700 ring-yellow-600/20 dark:bg-yellow-900/30 dark:text-yellow-300 dark:ring-yellow-400/30"
|
|
|
|
@doc """
|
|
Returns CSS classes for the status dot (a small colored circle).
|
|
"""
|
|
def status_dot_class(nil), do: "bg-gray-400"
|
|
def status_dot_class("up"), do: "bg-green-500"
|
|
def status_dot_class("down"), do: "bg-red-500"
|
|
def status_dot_class(_unknown), do: "bg-yellow-500"
|
|
|
|
@doc """
|
|
Returns the human-readable label for a beacon status.
|
|
"""
|
|
def status_label(nil), do: t_equipment("Never checked")
|
|
def status_label("up"), do: t_equipment("Up")
|
|
def status_label("down"), do: t_equipment("Down")
|
|
def status_label(unknown), do: unknown
|
|
|
|
@doc """
|
|
Formats a response time in milliseconds to a human-readable string.
|
|
"""
|
|
def format_response_time(nil), do: "—"
|
|
|
|
def format_response_time(ms) when ms < 1_000 do
|
|
"#{Float.round(ms, 0)}ms"
|
|
end
|
|
|
|
def format_response_time(ms) when ms >= 1_000 do
|
|
"#{Float.round(ms / 1000, 2)}s"
|
|
end
|
|
end
|