defmodule PrymnWeb.ServerLive.Show do
use PrymnWeb, :live_view
require Logger
alias Prymn.{Agents, Servers, Messaging}
@impl true
def mount(_params, _session, socket) do
# TODO: A more lightweight call instead of listing all data?
servers = Servers.list_servers()
{:ok, assign(socket, :servers, servers)}
end
@impl true
def render(assigns) do
~H"""
<.dropdown title="Select a different server">
<:button variant="tertiary">Server <%= @server.name %>
<:item
:for={server <- Enum.filter(@servers, &(&1.id != @server.id))}
patch={~p"/servers/#{server}"}
>
<%= server.name %>
<.icon class="h-4 w-4" name="hero-pencil-solid" />
<.indicator message="test" />
<.dropdown>
<:button variant="tertiary" size="sm">Quick actions
<:item>
Test
New App
<%= @server.public_ip %>
Connect to your server using root credentials and execute the following command:
#
<%= @registration_command %>
<.icon
name="hero-document-duplicate-solid"
class="invisible ml-4 animate-bounce text-gray-500 group-hover:visible"
/>
<.live_component
id={"system_info-#{@server.name}"}
module={PrymnWeb.SystemInfo}
agent={assigns[:agent]}
/>
System
Updates: <%= 0 %> pending updates.
Update now
<%= output %>
Terminal
<.live_component id="terminal" module={PrymnWeb.Terminal} agent={@agent} />
<.back navigate={~p"/servers"}>Back to servers
"""
end
@impl true
def handle_params(%{"id" => id}, _, socket) do
server = Servers.get_server!(id)
agent = Agents.from_server(server)
{:noreply,
socket
|> assign(:page_title, server.name)
|> assign(:server, server)
|> assign(:agent, agent)
|> assign(:dry_run, false)
|> assign(:update_output, [])
# TODO: Do not assign this to the socket - instead generate it in the HTML
|> assign(:registration_command, Servers.create_setup_command(server))}
end
@impl true
def handle_info(%Agents.Agent{} = agent, socket) do
{:noreply, assign(socket, :agent, agent)}
end
def handle_info(%Messaging.Messages.TerminalOutput{output: output}, socket) do
send_update(PrymnWeb.Terminal, id: "terminal", data: output)
{:noreply, socket}
end
# @impl true
# def handle_info(%PrymnProto.Prymn.SysUpdateResponse{} = response, socket) do
# output = String.split(response.output, "\n")
# socket = assign(socket, :update_output, output)
# {:noreply, socket}
# end
# def handle_info(%Agents.Health{host: host} = health, socket) do
# socket =
# if host == socket.assigns.server.public_ip,
# do: assign(socket, :health, health),
# else: socket
# {:noreply, socket}
# end
@impl true
def handle_event("system_update", _params, socket) do
# server_name = get_in(socket.assigns, [:server, Access.key(:name)])
# pid = self()
# if agent = socket.assigns[:agent] do
# # TODO: This is ugly
# Task.start_link(fn ->
# Agents.sys_update(agent, %{dry_run: socket.assigns.dry_run})
# |> Stream.each(fn
# {:ok, msg} -> send(pid, msg)
# {:error, error} -> Logger.error("error during system update call: #{inspect(error)}")
# end)
# |> Enum.to_list()
# end)
# put_flash(socket, :info, "Started a system update on server #{server_name}.")
# else
# put_flash(socket, :error, "Could not perform the update.")
# end
{:noreply, socket}
end
def handle_event("edit_server_name", %{"name" => name}, socket) do
server =
socket.assigns.server
|> Servers.update_server(%{"name" => name})
|> case do
{:ok, server} -> server
{:error, _} -> raise "Oops"
end
{:noreply, assign(socket, :server, server)}
end
def handle_event("change_dry_run", %{"dry_run" => enabled}, socket) do
enabled = (enabled == "true" && true) || false
{:noreply, assign(socket, :dry_run, enabled)}
end
defp show_edit_server_name() do
JS.hide(to: "#server-name")
|> JS.show(to: "#server-name-edit", display: "flex")
|> JS.focus_first(to: "#server-name-edit")
end
defp submit_edit_server_name() do
JS.push("edit_server_name")
|> JS.hide()
|> JS.show(to: "#server-name", display: "flex")
end
defp indicator(assigns) do
~H"""
<%= case @message do %>
<% "Connected" -> %>
<% "Disconnected" -> %>
<% _ -> %>
<% end %>
"""
end
end