- Replace gray->cool-steel, blue/indigo->cerulean, red->sweet-salmon, yellow/amber->wheat - Dark sidebar: sidebar/footer use cool-steel-800 bg, text lightened for contrast - ~11,600 color replacements across ~99 files - Update tests for new color class names
135 lines
4 KiB
Elixir
135 lines
4 KiB
Elixir
defmodule ToweropsWeb.AgentLive.Helpers do
|
|
@moduledoc """
|
|
Shared helper functions for agent LiveView modules.
|
|
"""
|
|
|
|
@doc """
|
|
Determines the agent's status based on last_seen_at timestamp.
|
|
|
|
Returns a tuple of {status_atom, status_label} where status_atom is:
|
|
- :online - Last seen within 2 minutes
|
|
- :warning - Last seen between 2-5 minutes
|
|
- :offline - Last seen more than 5 minutes ago
|
|
- :never - Never connected
|
|
"""
|
|
def agent_status(agent_token) do
|
|
case agent_token.last_seen_at do
|
|
nil ->
|
|
{:never, "Never connected"}
|
|
|
|
last_seen ->
|
|
seconds_ago = DateTime.diff(DateTime.utc_now(), last_seen, :second)
|
|
|
|
cond do
|
|
seconds_ago < 120 -> {:online, "Online"}
|
|
seconds_ago < 300 -> {:warning, "Warning"}
|
|
true -> {:offline, "Offline"}
|
|
end
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Returns Tailwind CSS classes for status badge background and text colors.
|
|
"""
|
|
def status_badge_class(status) do
|
|
case status do
|
|
:online -> "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300"
|
|
:warning -> "bg-wheat-100 text-wheat-800 dark:bg-wheat-900 dark:text-wheat-300"
|
|
:offline -> "bg-sweet-salmon-100 text-sweet-salmon-800 dark:bg-sweet-salmon-900 dark:text-sweet-salmon-300"
|
|
:never -> "bg-cool-steel-100 text-cool-steel-800 dark:bg-cool-steel-800 dark:text-cool-steel-300"
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Returns Tailwind CSS classes for status indicator dot.
|
|
Online status includes animation.
|
|
"""
|
|
def status_dot_class(status) do
|
|
case status do
|
|
:online -> "bg-green-600 dark:bg-green-400 animate-pulse"
|
|
:warning -> "bg-wheat-600 dark:bg-wheat-400"
|
|
:offline -> "bg-sweet-salmon-600 dark:bg-sweet-salmon-400"
|
|
:never -> "bg-cool-steel-400 dark:bg-cool-steel-600"
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Formats a DateTime into a human-readable "time ago" string.
|
|
|
|
Returns strings like "5s ago", "3m ago", "2h ago", or "5d ago".
|
|
|
|
Delegates to ToweropsWeb.TimeHelpers.format_time_ago/1.
|
|
"""
|
|
defdelegate format_last_seen(datetime), to: ToweropsWeb.TimeHelpers, as: :format_time_ago
|
|
|
|
@doc """
|
|
Formats uptime in seconds to a human-readable string.
|
|
|
|
Returns strings like "2h 34m" or "5d 3h".
|
|
"""
|
|
def format_uptime(uptime_seconds) when is_integer(uptime_seconds) do
|
|
days = div(uptime_seconds, 86_400)
|
|
hours = div(rem(uptime_seconds, 86_400), 3600)
|
|
minutes = div(rem(uptime_seconds, 3600), 60)
|
|
|
|
cond do
|
|
days > 0 -> "#{days}d #{hours}h"
|
|
hours > 0 -> "#{hours}h #{minutes}m"
|
|
true -> "#{minutes}m"
|
|
end
|
|
end
|
|
|
|
def format_uptime(_), do: "Unknown"
|
|
|
|
@doc """
|
|
Formats a DateTime into a full date and time string.
|
|
|
|
Returns strings like "Jan 15, 2026 at 2:34 PM EST".
|
|
|
|
Delegates to ToweropsWeb.TimeHelpers.format_datetime/2.
|
|
"""
|
|
def format_datetime(datetime, timezone \\ "UTC") do
|
|
ToweropsWeb.TimeHelpers.format_datetime(datetime, timezone)
|
|
end
|
|
|
|
@doc """
|
|
Formats a DateTime into a short date string.
|
|
|
|
Returns strings like "Jan 15, 2026".
|
|
|
|
Delegates to ToweropsWeb.TimeHelpers.format_date/2.
|
|
"""
|
|
def format_date(datetime, timezone \\ "UTC") do
|
|
ToweropsWeb.TimeHelpers.format_date(datetime, timezone)
|
|
end
|
|
|
|
@doc """
|
|
Formats a DateTime into a relative time with full datetime in parentheses.
|
|
|
|
Returns strings like "5m ago (Jan 15, 2026 at 2:34 PM EST)".
|
|
"""
|
|
def format_last_seen_with_date(datetime, timezone \\ "UTC")
|
|
def format_last_seen_with_date(nil, _timezone), do: "Never"
|
|
|
|
def format_last_seen_with_date(datetime, timezone) do
|
|
relative = format_last_seen(datetime)
|
|
full = format_datetime(datetime, timezone)
|
|
"#{relative} (#{full})"
|
|
end
|
|
|
|
@doc """
|
|
Formats agent version for display.
|
|
|
|
Handles both legacy semver ("1.2.3") and RFC 3339 timestamp ("2026-02-09T14:30:00Z") formats.
|
|
Timestamps show the full value with a human-readable date, e.g. "2026-02-09T14:30:00Z (Feb 9, 2026)".
|
|
"""
|
|
def format_agent_version(version) when is_binary(version) do
|
|
if String.match?(version, ~r/^\d{4}-\d{2}-\d{2}T/) do
|
|
version
|
|
else
|
|
"v#{version}"
|
|
end
|
|
end
|
|
|
|
def format_agent_version(_), do: nil
|
|
end
|