mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-09-07 13:34:55 +08:00
Add runtime info panel (#692)
* Add runtime info panel * Remove intro from the runtime modal * Show default runtime in the panel if no runtime is set
This commit is contained in:
parent
1842c203ab
commit
d8d52c9e89
10 changed files with 202 additions and 161 deletions
|
@ -109,6 +109,11 @@ solely client-side operations.
|
|||
@apply hidden;
|
||||
}
|
||||
|
||||
[data-element="session"]:not([data-js-side-panel-content="runtime-info"])
|
||||
[data-element="runtime-info"] {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
[data-element="session"][data-js-side-panel-content="sections-list"]
|
||||
[data-element="sections-list-toggle"] {
|
||||
@apply text-gray-50 bg-gray-700;
|
||||
|
@ -119,6 +124,11 @@ solely client-side operations.
|
|||
@apply text-gray-50 bg-gray-700;
|
||||
}
|
||||
|
||||
[data-element="session"][data-js-side-panel-content="runtime-info"]
|
||||
[data-element="runtime-info-toggle"] {
|
||||
@apply text-gray-50 bg-gray-700;
|
||||
}
|
||||
|
||||
[data-element="section-headline"]:not(:hover)
|
||||
[data-element="section-name"]:not(:focus)
|
||||
+ [data-element="section-actions"]:not(:focus-within) {
|
||||
|
|
|
@ -32,13 +32,13 @@ Example usage:
|
|||
white-space: pre;
|
||||
text-align: center;
|
||||
display: block;
|
||||
z-index: 100;
|
||||
background-color: #1c273c;
|
||||
color: #f0f5f9;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
border-radius: 4px;
|
||||
padding: 3px 12px;
|
||||
z-index: 100;
|
||||
visibility: hidden;
|
||||
transition-property: visibility;
|
||||
transition-duration: 0s;
|
||||
|
@ -50,6 +50,7 @@ Example usage:
|
|||
content: "";
|
||||
position: absolute;
|
||||
display: block;
|
||||
z-index: 100;
|
||||
/* For the arrow we use the triangle trick: https://css-tricks.com/snippets/css/css-triangle/ */
|
||||
border-width: var(--arrow-size);
|
||||
border-style: solid;
|
||||
|
|
|
@ -119,6 +119,10 @@ const Session = {
|
|||
toggleClientsList(this);
|
||||
});
|
||||
|
||||
getRuntimeInfoToggle().addEventListener("click", (event) => {
|
||||
toggleRuntimeInfo(this);
|
||||
});
|
||||
|
||||
getNotebook().addEventListener("scroll", (event) => {
|
||||
updateSectionListHighlight();
|
||||
});
|
||||
|
@ -335,7 +339,7 @@ function handleDocumentKeyDown(hook, event) {
|
|||
} else if (keyBuffer.tryMatch(["s", "u"])) {
|
||||
toggleClientsList(hook);
|
||||
} else if (keyBuffer.tryMatch(["s", "r"])) {
|
||||
showNotebookRuntimeSettings(hook);
|
||||
toggleRuntimeInfo(hook);
|
||||
} else if (keyBuffer.tryMatch(["s", "b"])) {
|
||||
showBin(hook);
|
||||
} else if (keyBuffer.tryMatch(["e", "x"])) {
|
||||
|
@ -581,23 +585,23 @@ function updateSectionListHighlight() {
|
|||
// User action handlers (mostly keybindings)
|
||||
|
||||
function toggleSectionsList(hook) {
|
||||
if (hook.el.getAttribute("data-js-side-panel-content") === "sections-list") {
|
||||
hook.el.removeAttribute("data-js-side-panel-content");
|
||||
} else {
|
||||
hook.el.setAttribute("data-js-side-panel-content", "sections-list");
|
||||
}
|
||||
toggleSidePanelContent(hook, "sections-list");
|
||||
}
|
||||
|
||||
function toggleClientsList(hook) {
|
||||
if (hook.el.getAttribute("data-js-side-panel-content") === "clients-list") {
|
||||
hook.el.removeAttribute("data-js-side-panel-content");
|
||||
} else {
|
||||
hook.el.setAttribute("data-js-side-panel-content", "clients-list");
|
||||
}
|
||||
toggleSidePanelContent(hook, "clients-list");
|
||||
}
|
||||
|
||||
function showNotebookRuntimeSettings(hook) {
|
||||
hook.pushEvent("show_runtime_settings", {});
|
||||
function toggleRuntimeInfo(hook) {
|
||||
toggleSidePanelContent(hook, "runtime-info");
|
||||
}
|
||||
|
||||
function toggleSidePanelContent(hook, name) {
|
||||
if (hook.el.getAttribute("data-js-side-panel-content") === name) {
|
||||
hook.el.removeAttribute("data-js-side-panel-content");
|
||||
} else {
|
||||
hook.el.setAttribute("data-js-side-panel-content", name);
|
||||
}
|
||||
}
|
||||
|
||||
function showBin(hook) {
|
||||
|
@ -1024,6 +1028,10 @@ function getClientsListToggle() {
|
|||
return document.querySelector(`[data-element="clients-list-toggle"]`);
|
||||
}
|
||||
|
||||
function getRuntimeInfoToggle() {
|
||||
return document.querySelector(`[data-element="runtime-info-toggle"]`);
|
||||
}
|
||||
|
||||
function cancelEvent(event) {
|
||||
// Cancel any default browser behavior.
|
||||
event.preventDefault();
|
||||
|
|
|
@ -37,7 +37,8 @@ defmodule LivebookWeb.SessionLive do
|
|||
platform: platform,
|
||||
self: self(),
|
||||
data_view: data_to_view(data),
|
||||
autofocus_cell_id: autofocus_cell_id(data.notebook)
|
||||
autofocus_cell_id: autofocus_cell_id(data.notebook),
|
||||
empty_default_runtime: Livebook.Config.default_runtime() |> elem(0) |> struct()
|
||||
)
|
||||
|> assign_private(data: data)
|
||||
|> allow_upload(:cell_image,
|
||||
|
@ -87,11 +88,10 @@ defmodule LivebookWeb.SessionLive do
|
|||
icon="group-fill"
|
||||
label="Connected users (su)"
|
||||
data_element="clients-list-toggle" />
|
||||
<SidebarHelpers.link_item
|
||||
<SidebarHelpers.button_item
|
||||
icon="cpu-line"
|
||||
label="Runtime settings (sr)"
|
||||
path={Routes.session_path(@socket, :runtime_settings, @session.id)}
|
||||
active={@live_action == :runtime_settings} />
|
||||
data_element="runtime-info-toggle" />
|
||||
<SidebarHelpers.link_item
|
||||
icon="delete-bin-6-fill"
|
||||
label="Bin (sb)"
|
||||
|
@ -110,81 +110,13 @@ defmodule LivebookWeb.SessionLive do
|
|||
<div class="flex flex-col h-full w-full max-w-xs absolute z-30 top-0 left-[64px] overflow-y-auto shadow-xl md:static md:shadow-none bg-gray-50 border-r border-gray-100 px-6 py-10"
|
||||
data-element="side-panel">
|
||||
<div data-element="sections-list">
|
||||
<div class="flex flex-col flex-grow">
|
||||
<h3 class="text-lg font-semibold text-gray-800">
|
||||
Sections
|
||||
</h3>
|
||||
<div class="flex flex-col mt-4 space-y-4">
|
||||
<%= for section_item <- @data_view.sections_items do %>
|
||||
<div class="flex items-center">
|
||||
<button class="flex-grow flex items-center text-gray-500 hover:text-gray-900"
|
||||
data-element="sections-list-item"
|
||||
data-section-id={section_item.id}>
|
||||
<span class="flex items-center space-x-1">
|
||||
<span><%= section_item.name %></span>
|
||||
<%= if section_item.parent do %>
|
||||
<%# Note: the container has overflow-y auto, so we cannot set overflow-x visible,
|
||||
consequently we show the tooltip wrapped to a fixed number of characters %>
|
||||
<span {branching_tooltip_attrs(section_item.name, section_item.parent.name)}>
|
||||
<.remix_icon icon="git-branch-line" class="text-lg font-normal leading-none flip-horizontally" />
|
||||
</span>
|
||||
<% end %>
|
||||
</span>
|
||||
</button>
|
||||
<.session_status status={elem(section_item.status, 0)} cell_id={elem(section_item.status, 1)} />
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<button class="inline-flex items-center justify-center p-8 py-1 mt-8 space-x-2 text-sm font-medium text-gray-500 border border-gray-400 border-dashed rounded-xl hover:bg-gray-100"
|
||||
phx-click="append_section">
|
||||
<.remix_icon icon="add-line" class="text-lg align-center" />
|
||||
<span>New section</span>
|
||||
</button>
|
||||
</div>
|
||||
<.sections_list data_view={@data_view} />
|
||||
</div>
|
||||
<div data-element="clients-list">
|
||||
<div class="flex flex-col flex-grow">
|
||||
<div class="flex items-center justify-between space-x-4">
|
||||
<h3 class="text-lg font-semibold text-gray-800 flex-lg">
|
||||
Users
|
||||
</h3>
|
||||
<span class="flex items-center p-2 space-x-2 text-sm bg-gray-200 rounded-lg">
|
||||
<span class="inline-flex w-3 h-3 bg-green-600 rounded-full"></span>
|
||||
<span><%= length(@data_view.clients) %> connected</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col mt-4 space-y-4">
|
||||
<%= for {client_pid, user} <- @data_view.clients do %>
|
||||
<div class="flex items-center justify-between space-x-2"
|
||||
id={"clients-list-item-#{inspect(client_pid)}"}
|
||||
data-element="clients-list-item"
|
||||
data-client-pid={inspect(client_pid)}>
|
||||
<button class="flex items-center space-x-2 text-gray-500 hover:text-gray-900 disabled:pointer-events-none"
|
||||
disabled={client_pid == @self}
|
||||
data-element="client-link">
|
||||
<.user_avatar user={user} class="flex-shrink-0 h-7 w-7" text_class="text-xs" />
|
||||
<span><%= user.name || "Anonymous" %></span>
|
||||
</button>
|
||||
<%= if client_pid != @self do %>
|
||||
<span class="tooltip left" data-tooltip="Follow this user"
|
||||
data-element="client-follow-toggle"
|
||||
data-meta="follow">
|
||||
<button class="icon-button" aria-label="follow this user">
|
||||
<.remix_icon icon="pushpin-line" class="text-lg" />
|
||||
</button>
|
||||
</span>
|
||||
<span class="tooltip left" data-tooltip="Unfollow this user"
|
||||
data-element="client-follow-toggle"
|
||||
data-meta="unfollow">
|
||||
<button class="icon-button" aria-label="unfollow this user">
|
||||
<.remix_icon icon="pushpin-fill" class="text-lg" />
|
||||
</button>
|
||||
</span>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<.clients_list data_view={@data_view} self={@self} />
|
||||
</div>
|
||||
<div data-element="runtime-info">
|
||||
<.runtime_info data_view={@data_view} session={@session} socket={@socket} empty_default_runtime={@empty_default_runtime} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow overflow-y-auto scroll-smooth" data-element="notebook">
|
||||
|
@ -355,6 +287,143 @@ defmodule LivebookWeb.SessionLive do
|
|||
"""
|
||||
end
|
||||
|
||||
defp sections_list(assigns) do
|
||||
~H"""
|
||||
<div class="flex flex-col flex-grow">
|
||||
<h3 class="text-lg font-semibold text-gray-800">
|
||||
Sections
|
||||
</h3>
|
||||
<div class="flex flex-col mt-4 space-y-4">
|
||||
<%= for section_item <- @data_view.sections_items do %>
|
||||
<div class="flex items-center">
|
||||
<button class="flex-grow flex items-center text-gray-500 hover:text-gray-900"
|
||||
data-element="sections-list-item"
|
||||
data-section-id={section_item.id}>
|
||||
<span class="flex items-center space-x-1">
|
||||
<span><%= section_item.name %></span>
|
||||
<%= if section_item.parent do %>
|
||||
<%# Note: the container has overflow-y auto, so we cannot set overflow-x visible,
|
||||
consequently we show the tooltip wrapped to a fixed number of characters %>
|
||||
<span {branching_tooltip_attrs(section_item.name, section_item.parent.name)}>
|
||||
<.remix_icon icon="git-branch-line" class="text-lg font-normal leading-none flip-horizontally" />
|
||||
</span>
|
||||
<% end %>
|
||||
</span>
|
||||
</button>
|
||||
<.session_status status={elem(section_item.status, 0)} cell_id={elem(section_item.status, 1)} />
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<button class="inline-flex items-center justify-center p-8 py-1 mt-8 space-x-2 text-sm font-medium text-gray-500 border border-gray-400 border-dashed rounded-xl hover:bg-gray-100"
|
||||
phx-click="append_section">
|
||||
<.remix_icon icon="add-line" class="text-lg align-center" />
|
||||
<span>New section</span>
|
||||
</button>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
defp clients_list(assigns) do
|
||||
~H"""
|
||||
<div class="flex flex-col flex-grow">
|
||||
<div class="flex items-center justify-between space-x-4">
|
||||
<h3 class="text-lg font-semibold text-gray-800 flex-lg">
|
||||
Users
|
||||
</h3>
|
||||
<span class="flex items-center p-2 space-x-2 text-sm bg-gray-200 rounded-lg">
|
||||
<span class="inline-flex w-3 h-3 bg-green-600 rounded-full"></span>
|
||||
<span><%= length(@data_view.clients) %> connected</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col mt-4 space-y-4">
|
||||
<%= for {client_pid, user} <- @data_view.clients do %>
|
||||
<div class="flex items-center justify-between space-x-2"
|
||||
id={"clients-list-item-#{inspect(client_pid)}"}
|
||||
data-element="clients-list-item"
|
||||
data-client-pid={inspect(client_pid)}>
|
||||
<button class="flex items-center space-x-2 text-gray-500 hover:text-gray-900 disabled:pointer-events-none"
|
||||
disabled={client_pid == @self}
|
||||
data-element="client-link">
|
||||
<.user_avatar user={user} class="flex-shrink-0 h-7 w-7" text_class="text-xs" />
|
||||
<span><%= user.name || "Anonymous" %></span>
|
||||
</button>
|
||||
<%= if client_pid != @self do %>
|
||||
<span class="tooltip left" data-tooltip="Follow this user"
|
||||
data-element="client-follow-toggle"
|
||||
data-meta="follow">
|
||||
<button class="icon-button" aria-label="follow this user">
|
||||
<.remix_icon icon="pushpin-line" class="text-lg" />
|
||||
</button>
|
||||
</span>
|
||||
<span class="tooltip left" data-tooltip="Unfollow this user"
|
||||
data-element="client-follow-toggle"
|
||||
data-meta="unfollow">
|
||||
<button class="icon-button" aria-label="unfollow this user">
|
||||
<.remix_icon icon="pushpin-fill" class="text-lg" />
|
||||
</button>
|
||||
</span>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
defp runtime_info(assigns) do
|
||||
~H"""
|
||||
<div class="flex flex-col flex-grow">
|
||||
<h3 class="text-lg font-semibold text-gray-800">
|
||||
Runtime
|
||||
</h3>
|
||||
<div class="flex flex-col mt-4 space-y-4">
|
||||
<%= if @data_view.runtime do %>
|
||||
<div class="flex flex-col space-y-3">
|
||||
<.labeled_text label="Type" text={runtime_type_label(@data_view.runtime)} />
|
||||
<.labeled_text label="Node name" text={@data_view.runtime.node} />
|
||||
</div>
|
||||
<div class="flex flex-col space-y-3">
|
||||
<div class="flex space-x-2">
|
||||
<button class="button button-outlined-blue w-full" phx-click="restart_runtime">
|
||||
Reconnect
|
||||
</button>
|
||||
<button class="button button-outlined-red w-full"
|
||||
type="button"
|
||||
phx-click="disconnect_runtime">
|
||||
Disconnect
|
||||
</button>
|
||||
</div>
|
||||
<%= live_patch to: Routes.session_path(@socket, :runtime_settings, @session.id),
|
||||
class: "button button-gray button-square-icon",
|
||||
type: "button" do %>
|
||||
<.remix_icon icon="settings-3-line" />
|
||||
<% end %>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="flex flex-col space-y-3">
|
||||
<.labeled_text label="Type" text={runtime_type_label(@empty_default_runtime)} />
|
||||
</div>
|
||||
<div class="flex space-x-2">
|
||||
<button class="button button-blue" phx-click="connect_default_runtime">
|
||||
Connect
|
||||
</button>
|
||||
<%= live_patch to: Routes.session_path(@socket, :runtime_settings, @session.id),
|
||||
class: "button button-gray button-square-icon",
|
||||
type: "button" do %>
|
||||
<.remix_icon icon="settings-3-line" />
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
defp runtime_type_label(%Runtime.ElixirStandalone{}), do: "Elixir standalone"
|
||||
defp runtime_type_label(%Runtime.MixStandalone{}), do: "Mix standalone"
|
||||
defp runtime_type_label(%Runtime.Attached{}), do: "Attached"
|
||||
defp runtime_type_label(%Runtime.Embedded{}), do: "Embedded"
|
||||
|
||||
defp session_status(%{status: :evaluating} = assigns) do
|
||||
~H"""
|
||||
<button data-element="focus-cell-button" data-target={@cell_id}>
|
||||
|
@ -660,13 +729,6 @@ defmodule LivebookWeb.SessionLive do
|
|||
push_patch(socket, to: Routes.session_path(socket, :shortcuts, socket.assigns.session.id))}
|
||||
end
|
||||
|
||||
def handle_event("show_runtime_settings", %{}, socket) do
|
||||
{:noreply,
|
||||
push_patch(socket,
|
||||
to: Routes.session_path(socket, :runtime_settings, socket.assigns.session.id)
|
||||
)}
|
||||
end
|
||||
|
||||
def handle_event("show_bin", %{}, socket) do
|
||||
{:noreply,
|
||||
push_patch(socket, to: Routes.session_path(socket, :bin, socket.assigns.session.id))}
|
||||
|
@ -690,6 +752,27 @@ defmodule LivebookWeb.SessionLive do
|
|||
{:noreply, socket}
|
||||
end
|
||||
|
||||
def handle_event("connect_default_runtime", %{}, socket) do
|
||||
{runtime_module, args} = Livebook.Config.default_runtime()
|
||||
|
||||
socket =
|
||||
case apply(runtime_module, :init, args) do
|
||||
{:ok, runtime} ->
|
||||
Session.connect_runtime(socket.assigns.session.pid, runtime)
|
||||
socket
|
||||
|
||||
{:error, message} ->
|
||||
put_flash(socket, :error, "Failed to setup runtime - #{message}")
|
||||
end
|
||||
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
def handle_event("disconnect_runtime", %{}, socket) do
|
||||
Session.disconnect_runtime(socket.assigns.session.pid)
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
def handle_event("intellisense_request", %{"cell_id" => cell_id} = params, socket) do
|
||||
request =
|
||||
case params do
|
||||
|
|
|
@ -2,7 +2,6 @@ defmodule LivebookWeb.SessionLive.AttachedLive do
|
|||
use LivebookWeb, :live_view
|
||||
|
||||
alias Livebook.{Session, Runtime, Utils}
|
||||
alias LivebookWeb.SessionLive.RuntimeHelpers
|
||||
|
||||
@impl true
|
||||
def mount(_params, %{"session" => session, "current_runtime" => current_runtime}, socket) do
|
||||
|
@ -28,7 +27,6 @@ defmodule LivebookWeb.SessionLive.AttachedLive do
|
|||
<%= @error_message %>
|
||||
</div>
|
||||
<% end %>
|
||||
<RuntimeHelpers.default_runtime_note module={Runtime.Attached} />
|
||||
<p class="text-gray-700">
|
||||
Connect the session to an already running node
|
||||
and evaluate code in the context of that node.
|
||||
|
|
|
@ -2,7 +2,6 @@ defmodule LivebookWeb.SessionLive.ElixirStandaloneLive do
|
|||
use LivebookWeb, :live_view
|
||||
|
||||
alias Livebook.{Session, Runtime}
|
||||
alias LivebookWeb.SessionLive.RuntimeHelpers
|
||||
|
||||
@impl true
|
||||
def mount(_params, %{"session" => session, "current_runtime" => current_runtime}, socket) do
|
||||
|
@ -22,7 +21,6 @@ defmodule LivebookWeb.SessionLive.ElixirStandaloneLive do
|
|||
<%= @error_message %>
|
||||
</div>
|
||||
<% end %>
|
||||
<RuntimeHelpers.default_runtime_note module={Runtime.ElixirStandalone} />
|
||||
<p class="text-gray-700">
|
||||
Start a new local node to handle code evaluation.
|
||||
</p>
|
||||
|
|
|
@ -2,7 +2,6 @@ defmodule LivebookWeb.SessionLive.EmbeddedLive do
|
|||
use LivebookWeb, :live_view
|
||||
|
||||
alias Livebook.{Session, Runtime}
|
||||
alias LivebookWeb.SessionLive.RuntimeHelpers
|
||||
|
||||
@impl true
|
||||
def mount(_params, %{"session" => session, "current_runtime" => current_runtime}, socket) do
|
||||
|
@ -17,7 +16,6 @@ defmodule LivebookWeb.SessionLive.EmbeddedLive do
|
|||
def render(assigns) do
|
||||
~H"""
|
||||
<div class="flex-col space-y-5">
|
||||
<RuntimeHelpers.default_runtime_note module={Runtime.Embedded} />
|
||||
<p class="text-gray-700">
|
||||
Run the notebook code within the Livebook node itself.
|
||||
This is reserved for specific cases where there is no option
|
||||
|
|
|
@ -2,7 +2,6 @@ defmodule LivebookWeb.SessionLive.MixStandaloneLive do
|
|||
use LivebookWeb, :live_view
|
||||
|
||||
alias Livebook.{Session, Runtime, Utils, FileSystem}
|
||||
alias LivebookWeb.SessionLive.RuntimeHelpers
|
||||
|
||||
@type status :: :initial | :initializing | :finished
|
||||
|
||||
|
@ -27,7 +26,6 @@ defmodule LivebookWeb.SessionLive.MixStandaloneLive do
|
|||
def render(assigns) do
|
||||
~H"""
|
||||
<div class="flex-col space-y-5">
|
||||
<RuntimeHelpers.default_runtime_note module={Runtime.MixStandalone} />
|
||||
<p class="text-gray-700">
|
||||
Start a new local node in the context of a Mix project.
|
||||
This way all your code and dependencies will be available
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
defmodule LivebookWeb.SessionLive.RuntimeComponent do
|
||||
use LivebookWeb, :live_component
|
||||
|
||||
alias Livebook.{Session, Runtime}
|
||||
alias Livebook.Runtime
|
||||
|
||||
@impl true
|
||||
def mount(socket) do
|
||||
|
@ -31,31 +31,11 @@ defmodule LivebookWeb.SessionLive.RuntimeComponent do
|
|||
@impl true
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<div class="p-6 pb-4 max-w-4xl flex flex-col space-y-3">
|
||||
<div class="p-6 pb-4 max-w-4xl flex flex-col space-y-5">
|
||||
<h3 class="text-2xl font-semibold text-gray-800">
|
||||
Runtime
|
||||
</h3>
|
||||
<div class="w-full flex-col space-y-5">
|
||||
<p class="text-gray-700">
|
||||
The code is evaluated in a separate Elixir runtime (node),
|
||||
which you can configure yourself here.
|
||||
</p>
|
||||
<div class="flex items-center justify-between border border-gray-200 rounded-lg p-4">
|
||||
<%= if @runtime do %>
|
||||
<.labeled_text label="Type" text={runtime_type_label(@runtime)} />
|
||||
<.labeled_text label="Node name" text={@runtime.node} />
|
||||
<button class="button button-outlined-red"
|
||||
type="button"
|
||||
phx-click="disconnect"
|
||||
phx-target={@myself}>
|
||||
Disconnect
|
||||
</button>
|
||||
<% else %>
|
||||
<p class="text-sm text-gray-700">
|
||||
No connected node
|
||||
</p>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="flex space-x-4">
|
||||
<.choice_button
|
||||
active={@type == "elixir_standalone"}
|
||||
|
@ -96,11 +76,6 @@ defmodule LivebookWeb.SessionLive.RuntimeComponent do
|
|||
"""
|
||||
end
|
||||
|
||||
defp runtime_type_label(%Runtime.ElixirStandalone{}), do: "Elixir standalone"
|
||||
defp runtime_type_label(%Runtime.MixStandalone{}), do: "Mix standalone"
|
||||
defp runtime_type_label(%Runtime.Attached{}), do: "Attached"
|
||||
defp runtime_type_label(%Runtime.Embedded{}), do: "Embedded"
|
||||
|
||||
defp runtime_type(%Runtime.ElixirStandalone{}), do: "elixir_standalone"
|
||||
defp runtime_type(%Runtime.MixStandalone{}), do: "mix_standalone"
|
||||
defp runtime_type(%Runtime.Attached{}), do: "attached"
|
||||
|
@ -115,10 +90,4 @@ defmodule LivebookWeb.SessionLive.RuntimeComponent do
|
|||
def handle_event("set_runtime_type", %{"type" => type}, socket) do
|
||||
{:noreply, assign(socket, type: type)}
|
||||
end
|
||||
|
||||
def handle_event("disconnect", _params, socket) do
|
||||
Session.disconnect_runtime(socket.assigns.session.pid)
|
||||
|
||||
{:noreply, socket}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
defmodule LivebookWeb.SessionLive.RuntimeHelpers do
|
||||
use Phoenix.Component
|
||||
|
||||
@doc """
|
||||
Displays an info text if `@module` is the default runtime.
|
||||
"""
|
||||
def default_runtime_note(assigns) do
|
||||
~H"""
|
||||
<%= if default_runtime_module?(@module) do %>
|
||||
<p class="text-gray-600 text-sm">
|
||||
Note: This is the <span class="font-semibold">default runtime</span> and starts
|
||||
automatically as soon as you evaluate the first cell.
|
||||
</p>
|
||||
<% end %>
|
||||
"""
|
||||
end
|
||||
|
||||
defp default_runtime_module?(module) do
|
||||
{default_module, _args} = Livebook.Config.default_runtime()
|
||||
default_module == module
|
||||
end
|
||||
end
|
Loading…
Add table
Reference in a new issue