Reviewed-on: https://git.nikos.gg/prymn/prymn/pulls/9 Co-authored-by: Nikos Papadakis <nikos@papadakis.xyz> Co-committed-by: Nikos Papadakis <nikos@papadakis.xyz>
132 lines
3.8 KiB
Elixir
132 lines
3.8 KiB
Elixir
defmodule PrymnWeb.ServerLive.Index do
|
|
require Logger
|
|
|
|
alias Prymn.{Agents, Servers}
|
|
|
|
use PrymnWeb, :live_view
|
|
|
|
@impl true
|
|
def mount(_params, _session, socket) do
|
|
servers = Servers.list_servers()
|
|
|
|
healths =
|
|
if connected?(socket) do
|
|
for %Servers.Server{status: :registered, public_ip: ip} = server <- servers, into: %{} do
|
|
Agents.from_server(server)
|
|
|> Agents.subscribe_to_health()
|
|
|
|
{ip, Agents.get_health(ip)}
|
|
end
|
|
else
|
|
%{}
|
|
end
|
|
|
|
{:ok,
|
|
socket
|
|
|> assign(:servers, servers)
|
|
|> assign(:healths, healths)}
|
|
end
|
|
|
|
@impl true
|
|
def render(assigns) do
|
|
~H"""
|
|
<div class="mx-auto max-w-2xl">
|
|
<.header>
|
|
Your servers
|
|
<small class="block">
|
|
<%= "#{Enum.count(@servers)} servers" %>
|
|
</small>
|
|
<:actions>
|
|
<Button.primary patch={~p"/servers/new"}>Connect a Server</Button.primary>
|
|
</:actions>
|
|
</.header>
|
|
<div class="space-y-5" phx-update="replace" id="servers">
|
|
<.link
|
|
:for={server <- @servers}
|
|
navigate={~p"/servers/#{server}"}
|
|
class="group block rounded-lg bg-gray-100 p-5 shadow-sm shadow-gray-300 hover:bg-black hover:text-white"
|
|
>
|
|
<div class="flex flex-row flex-wrap justify-between">
|
|
<h2 class="text-xl"><%= server.name %></h2>
|
|
<.server_status status={server.status} health={@healths[server.public_ip]} />
|
|
</div>
|
|
<div class="flex flex-row flex-wrap justify-between lg:text-sm">
|
|
<span>IP: <%= server.public_ip || "N/A" %></span>
|
|
<%= if @healths[server.public_ip] do %>
|
|
<span
|
|
:for={{name, task} <- @healths[server.public_ip].tasks || []}
|
|
class="text-right text-xs text-slate-700"
|
|
>
|
|
<div>In progress: <%= name %></div>
|
|
<div><%= task.progress %></div>
|
|
</span>
|
|
<% end %>
|
|
</div>
|
|
</.link>
|
|
</div>
|
|
<.modal :if={@live_action == :new} id="server-modal" show on_cancel={JS.patch(~p"/servers")}>
|
|
<.live_component module={PrymnWeb.ServerLive.NewServer} id={:new} patch={~p"/servers"} />
|
|
</.modal>
|
|
</div>
|
|
"""
|
|
end
|
|
|
|
@impl true
|
|
def handle_params(_params, _url, socket) do
|
|
socket =
|
|
case socket.assigns.live_action do
|
|
:new -> assign(socket, :page_title, gettext("Connect a Server"))
|
|
:index -> assign(socket, :page_title, gettext("Listing Servers"))
|
|
end
|
|
|
|
{:noreply, socket}
|
|
end
|
|
|
|
@impl true
|
|
def handle_info({:connect, %Servers.Server{} = server}, socket) do
|
|
{:noreply,
|
|
socket
|
|
|> update(:servers, fn servers -> [server | servers] end)}
|
|
end
|
|
|
|
def handle_info(%Agents.Health{} = health, socket) do
|
|
healths = Map.put(socket.assigns.healths, health.host, health)
|
|
{:noreply, assign(socket, :healths, healths)}
|
|
end
|
|
|
|
def handle_info(msg, state) do
|
|
Logger.debug("received unexpected message #{inspect(msg)}")
|
|
{:noreply, state}
|
|
end
|
|
|
|
defp server_status(assigns) do
|
|
case {assigns.status, assigns.health} do
|
|
{:unregistered, _} ->
|
|
~H"""
|
|
<span class="self-center text-sm text-gray-500">Needs registration</span>
|
|
"""
|
|
|
|
{:registered, nil} ->
|
|
~H"""
|
|
<.spinner size="md" />
|
|
"""
|
|
|
|
{:registered, %Agents.Health{status: :connected}} ->
|
|
~H"""
|
|
<span class="self-center text-sm text-green-600">Connected</span>
|
|
"""
|
|
|
|
{:registered, %Agents.Health{status: :disconnected}} ->
|
|
~H"""
|
|
<span class="self-center text-sm text-red-600">Disconnected</span>
|
|
"""
|
|
|
|
{:registered, %Agents.Health{message: message}} ->
|
|
assigns = assign(assigns, :message, message)
|
|
|
|
~H"""
|
|
<span class="self-center text-sm text-yellow-900"><%= @message %></span>
|
|
"""
|
|
end
|
|
end
|
|
end
|