defmodule LivebookWeb.AppsLive do use LivebookWeb, :live_view import LivebookWeb.AppHelpers import LivebookWeb.SessionHelpers alias LivebookWeb.LayoutHelpers alias Livebook.Sessions on_mount LivebookWeb.SidebarHook @impl true def mount(_params, _session, socket) do if connected?(socket) do Livebook.Sessions.subscribe() end sessions = Sessions.list_sessions() |> Enum.filter(&(&1.mode == :app)) |> Enum.sort_by(& &1.created_at, {:desc, DateTime}) {:ok, assign(socket, sessions: sessions, page_title: "Livebook - Apps")} end @impl true def render(assigns) do ~H"""

<%= if @sessions == [] do %> No apps currently running. <% else %> These apps are currently running. <% end %>

<%= "/" <> slug %>
<%= for {session, idx} <- Enum.with_index(sessions) do %>
0} class="ml-4 border-l-2 border-gray-300 border-dashed h-6">
<.app_box session={session} /> <% end %>
""" end defp app_box(assigns) do ~H"""
<.labeled_text label="Status"> <.app_status status={@session.app_info.status} />
<.labeled_text label="Name"> <%= @session.notebook_name %>
<.labeled_text label="URL"> <%= if @session.app_info.registered do %> <%= url(~p"/apps/#{@session.app_info.slug}") %> <% else %> - <% end %>
<.remix_icon icon="terminal-line" class="text-lg" /> <%= if @session.app_info.registered do %> <% else %> <% end %>
""" end @impl true def handle_info({type, session} = event, socket) when type in [:session_created, :session_updated, :session_closed] and session.mode == :app do {:noreply, update(socket, :sessions, &update_session_list(&1, event))} end def handle_info(_message, socket), do: {:noreply, socket} @impl true def handle_event("terminate_app", %{"session_id" => session_id}, socket) do session = Enum.find(socket.assigns.sessions, &(&1.id == session_id)) Livebook.Session.close(session.pid) {:noreply, socket} end def handle_event("stop_app", %{"session_id" => session_id}, socket) do session = Enum.find(socket.assigns.sessions, &(&1.id == session_id)) Livebook.Session.app_stop(session.pid) {:noreply, socket} end defp group_apps(sessions) do sessions |> Enum.group_by(& &1.app_info.slug) |> Enum.sort_by(&elem(&1, 0)) end end