Packages
livebook
0.9.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>
<.menu_item>
<button
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>Markdown</span>
</button>
</.menu_item>
<.menu_item>
<button
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>Section</span>
</button>
</.menu_item>
<div class="my-2 border-b border-gray-200"></div>
<.menu_item>
<button
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>Diagram</span>
</button>
</.menu_item>
<.menu_item>
<.link
patch={
~p"/sessions/#{@session_id}/cell-upload?section_id=#{@section_id}&cell_id=#{@cell_id || ""}"
}
aria-label="insert image"
role="menuitem"
>
<.remix_icon icon="image-add-line" />
<span>Image</span>
</.link>
</.menu_item>
</.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>
<.menu_item :for={definition <- Enum.sort_by(@smart_cell_definitions, & &1.name)}>
<.smart_cell_insert_button
definition={definition}
section_id={@section_id}
cell_id={@cell_id}
/>
</.menu_item>
</.menu>
<% end %>
</div>
</div>
"""
end
defp smart_cell_insert_button(%{definition: %{requirement: %{variants: [_, _ | _]}}} = assigns) do
~H"""
<.submenu>
<:primary>
<button role="menuitem">
<span><%= @definition.name %></span>
</button>
</:primary>
<.menu_item :for={{variant, idx} <- Enum.with_index(@definition.requirement.variants)}>
<button
role="menuitem"
phx-click={on_smart_cell_click(@definition, idx, @section_id, @cell_id)}
>
<span><%= variant.name %></span>
</button>
</.menu_item>
</.submenu>
"""
end
defp smart_cell_insert_button(assigns) do
~H"""
<button role="menuitem" phx-click={on_smart_cell_click(@definition, 0, @section_id, @cell_id)}>
<span><%= @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