defmodule ExESDBDashboard.ClusterStatus do @moduledoc """ Standalone cluster status component that can be embedded in other LiveViews. Displays a compact overview of cluster health and key metrics. Automatically updates in real-time via PubSub. ## Usage In your LiveView template: <.live_component module={ExESDBDashboard.ClusterStatus} id="cluster-status" /> Or use the helper from the main Dashboard module: <.live_component module={ExESDBDashboard.cluster_status_component()} id="cluster-status" /> """ use Phoenix.LiveComponent alias ExESDBDashboard @impl true def mount(socket) do {:ok, socket} end @impl true def update(assigns, socket) do # Load cluster data on first render or when explicitly requested cluster_data = ExESDBDashboard.get_cluster_data() socket = socket |> assign(assigns) |> assign(:cluster_data, cluster_data) |> assign(:last_updated, DateTime.utc_now()) {:ok, socket} end @impl true def handle_event("refresh", _params, socket) do cluster_data = ExESDBDashboard.get_cluster_data() socket = socket |> assign(:cluster_data, cluster_data) |> assign(:last_updated, DateTime.utc_now()) {:noreply, socket} end # LiveComponents don't receive handle_info messages directly from PubSub. # The parent LiveView should forward cluster updates to this component # by calling send_update/3 when it receives PubSub messages. # # For manual refresh, users can click the refresh button which triggers # the "refresh" event handled above. @impl true def render(assigns) do ~H"""
""" end # Component helpers defp health_indicator(assigns) do health_class = health_to_class(assigns.health) health_emoji = health_to_emoji(assigns.health) health_text = health_to_text(assigns.health) assigns = assign(assigns, :health_class, health_class) assigns = assign(assigns, :health_emoji, health_emoji) assigns = assign(assigns, :health_text, health_text) ~H"""<%= @summary %>
""" end # Helper functions defp health_to_class(:healthy), do: "healthy" defp health_to_class(:degraded), do: "degraded" defp health_to_class(:unhealthy), do: "unhealthy" defp health_to_class(:no_cluster), do: "no-cluster" defp health_to_class(:no_stores), do: "no-stores" defp health_to_class(_), do: "unknown" defp health_to_emoji(:healthy), do: "✅" defp health_to_emoji(:degraded), do: "⚠️" defp health_to_emoji(:unhealthy), do: "❌" defp health_to_emoji(:no_cluster), do: "🚫" defp health_to_emoji(:no_stores), do: "📭" defp health_to_emoji(_), do: "❓" defp health_to_text(:healthy), do: "Healthy" defp health_to_text(:degraded), do: "Degraded" defp health_to_text(:unhealthy), do: "Unhealthy" defp health_to_text(:no_cluster), do: "No Cluster" defp health_to_text(:no_stores), do: "No Stores" defp health_to_text(_), do: "Unknown" end