Packages
livebook
0.8.0
0.19.8
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.3
0.17.2
0.17.1
0.17.0
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.14.0-rc.1
0.14.0-rc.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
Automate code & data workflows with interactive notebooks
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/livebook_web/live/session_live/insert_buttons_component.ex
defmodule LivebookWeb.SessionLive.InsertButtonsComponent do
use LivebookWeb, :live_component
def render(assigns) do
~H"""
<div
class="relative top-0.5 m-0 flex justify-center"
role="toolbar"
aria-label="insert new"
data-el-insert-buttons
>
<div class={
"w-full absolute z-10 hover:z-[11] #{if(@persistent, do: "opacity-100", else: "opacity-0")} hover:opacity-100 focus-within:opacity-100 flex space-x-2 justify-center items-center"
}>
<button
class="button-base button-small"
phx-click="insert_cell_below"
phx-value-type="code"
phx-value-section_id={@section_id}
phx-value-cell_id={@cell_id}
>
+ Code
</button>
<.menu id={"#{@id}-block-menu"} position="bottom-left">
<:toggle>
<button class="button-base button-small">+ Block</button>
</:toggle>
<:content>
<button
class="menu-item text-gray-500"
role="menuitem"
phx-click="insert_cell_below"
phx-value-type="markdown"
phx-value-section_id={@section_id}
phx-value-cell_id={@cell_id}
>
<.remix_icon icon="markdown-fill" />
<span class="font-medium">Markdown</span>
</button>
<button
class="menu-item text-gray-500"
role="menuitem"
phx-click="insert_section_below"
phx-value-section_id={@section_id}
phx-value-cell_id={@cell_id}
>
<.remix_icon icon="h-2" />
<span class="font-medium">Section</span>
</button>
<div class="my-2 border-b border-gray-200"></div>
<button
class="menu-item text-gray-500"
role="menuitem"
phx-click="insert_cell_below"
phx-value-type="diagram"
phx-value-section_id={@section_id}
phx-value-cell_id={@cell_id}
>
<.remix_icon icon="organization-chart" />
<span class="font-medium">Diagram</span>
</button>
</:content>
</.menu>
<%= cond do %>
<% not Livebook.Runtime.connected?(@runtime) -> %>
<button
class="button-base button-small"
phx-click={
with_confirm(
JS.push("setup_default_runtime"),
title: "Setup runtime",
description: ~s'''
To see the available smart cells, you need a connected runtime.
Do you want to connect and setup the default one?
''',
confirm_text: "Setup runtime",
confirm_icon: "play-line",
danger: false
)
}
>
+ Smart
</button>
<% @smart_cell_definitions == [] -> %>
<span class="tooltip right" data-tooltip="No smart cells available">
<button class="button-base button-small" disabled>+ Smart</button>
</span>
<% true -> %>
<.menu id={"#{@id}-smart-menu"} position="bottom-left">
<:toggle>
<button class="button-base button-small">+ Smart</button>
</:toggle>
<:content>
<%= for definition <- Enum.sort_by(@smart_cell_definitions, & &1.name) do %>
<.smart_cell_insert_button
definition={definition}
section_id={@section_id}
cell_id={@cell_id}
/>
<% end %>
</:content>
</.menu>
<% end %>
</div>
</div>
"""
end
defp smart_cell_insert_button(%{definition: %{requirement: %{variants: [_, _ | _]}}} = assigns) do
~H"""
<.submenu>
<button class="menu-item text-gray-500" role="menuitem">
<span class="font-medium"><%= @definition.name %></span>
</button>
<:content>
<%= for {variant, idx} <- Enum.with_index(@definition.requirement.variants) do %>
<button
class="menu-item text-gray-500"
role="menuitem"
phx-click={on_smart_cell_click(@definition, idx, @section_id, @cell_id)}
>
<span class="font-medium"><%= variant.name %></span>
</button>
<% end %>
</:content>
</.submenu>
"""
end
defp smart_cell_insert_button(assigns) do
~H"""
<button
class="menu-item text-gray-500"
role="menuitem"
phx-click={on_smart_cell_click(@definition, 0, @section_id, @cell_id)}
>
<span class="font-medium"><%= @definition.name %></span>
</button>
"""
end
defp on_smart_cell_click(%{requirement: nil} = definition, _variant_idx, section_id, cell_id) do
insert_smart_cell(definition, section_id, cell_id)
end
defp on_smart_cell_click(%{requirement: %{}} = definition, variant_idx, section_id, cell_id) do
variant = Enum.fetch!(definition.requirement.variants, variant_idx)
with_confirm(
JS.push("add_smart_cell_dependencies",
value: %{kind: definition.kind, variant_idx: variant_idx}
)
|> insert_smart_cell(definition, section_id, cell_id)
|> JS.push("queue_cells_reevaluation"),
title: "Add packages",
description:
case variant.packages do
[%{name: name}] ->
~s'''
The <span class="font-semibold">“#{definition.name}“</span>
smart cell requires the #{code_tag(name)} package. Do you want to add
it as a dependency and restart?
'''
packages ->
~s'''
The <span class="font-semibold">“#{definition.name}“</span>
smart cell requires the #{packages |> Enum.map(&code_tag(&1.name)) |> format_items()}
packages. Do you want to add them as dependencies and restart?
'''
end,
confirm_text: "Add and restart",
confirm_icon: "add-line",
danger: false,
html: true
)
end
defp code_tag(text), do: "<code>#{text}</code>"
defp insert_smart_cell(js \\ %JS{}, definition, section_id, cell_id) do
JS.push(js, "insert_cell_below",
value: %{
type: "smart",
kind: definition.kind,
section_id: section_id,
cell_id: cell_id
}
)
end
end