Move helpers to components (#2448)

This commit is contained in:
Jonatan Kłosko 2024-01-26 05:47:56 +01:00 committed by GitHub
parent 365cbe7101
commit 501a98d7c6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 202 additions and 184 deletions

View file

@ -300,7 +300,7 @@ defmodule Livebook.Hubs.Dockerfile do
end,
if used_hub_file_systems != [] do
%module{} = hd(used_hub_file_systems)
name = LivebookWeb.FileSystemHelpers.file_system_name(module)
name = LivebookWeb.FileSystemComponents.file_system_name(module)
"The #{name} file storage, defined in your personal hub, will not be available in the Docker image." <>
" You must either download all references as attachments or use Livebook Teams to automatically" <>

View file

@ -1,4 +1,4 @@
defmodule LivebookWeb.AppHelpers do
defmodule LivebookWeb.AppComponents do
use LivebookWeb, :html
alias Livebook.Hubs

View file

@ -1,4 +1,4 @@
defmodule LivebookWeb.FileSystemHelpers do
defmodule LivebookWeb.FileSystemComponents do
use LivebookWeb, :html
alias Livebook.FileSystem

View file

@ -1,7 +1,7 @@
defmodule LivebookWeb.LayoutHelpers do
defmodule LivebookWeb.LayoutComponents do
use LivebookWeb, :html
import LivebookWeb.UserHelpers
import LivebookWeb.UserComponents
alias Livebook.Hubs.Provider

View file

@ -0,0 +1,100 @@
defmodule LivebookWeb.NotebookComponents do
use LivebookWeb, :html
@doc """
Renders an learn notebook card.
"""
attr :notebook_info, :map, required: true
def learn_notebook_card(assigns) do
~H"""
<.link
navigate={~p"/learn/notebooks/#{@notebook_info.slug}"}
class="flex flex-col border-2 border-gray-100 hover:border-gray-200 rounded-2xl"
>
<div class="flex items-center justify-center p-6 border-b-2 border-gray-100 rounded-t-2xl h-[150px]">
<img
src={learn_img_src(@notebook_info.details.cover)}
class="max-h-full max-w-[75%]"
alt={"#{@notebook_info.title} logo"}
/>
</div>
<div class="px-6 py-4 bg-gray-100 rounded-b-2xl grow">
<span class="text-gray-800 font-semibold"><%= @notebook_info.title %></span>
<p class="mt-2 text-sm text-gray-600">
<%= @notebook_info.details.description %>
</p>
</div>
</.link>
"""
end
@doc """
Resolves the given image source into a URL.
"""
@spec learn_img_src(Livebook.Notebook.Learn.image_source()) :: String.t()
def learn_img_src({:url, url}), do: url
def learn_img_src({:static, filename}), do: ~p"/images/#{filename}"
@doc """
Renders an icon for the given cell.
"""
attr :cell_type, :atom, required: true
attr :language, :atom, default: nil
def cell_icon(assigns)
def cell_icon(%{cell_type: :code, language: :elixir} = assigns) do
~H"""
<div class="flex w-6 h-6 bg-purple-100 rounded items-center justify-center">
<svg width="11" height="15" viewBox="0 0 11 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M5.7784 3.58083C7.4569 5.87527 9.67878 5.70652 10.0618 9.04833C10.1147 12.9425 8.03684
14.27 6.55353 14.6441C4.02227 15.3635 1.7644 14.2813 0.875648 11.8316C-0.83154 7.89408 2.36684
1.41746 4.42502 0.0668945C4.60193 1.32119 5.05745 2.51995 5.75815 3.57521L5.7784 3.58083Z"
fill="#663299"
/>
</svg>
</div>
"""
end
def cell_icon(%{cell_type: :code, language: :erlang} = assigns) do
~H"""
<div class="flex w-6 h-6 bg-red-100 rounded items-center justify-center">
<svg width="18" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15 10">
<g fill="#a90533">
<path d="M2.4 10A7.7 7.7 0 0 1 .5 4.8c0-2 .6-3.6 1.6-4.8H0v10ZM13 10c.5-.6 1-1.2 1.4-2l-2.3-1.2c-.8 1.4-2 2.6-3.6 2.6-2.3 0-3.2-2-3.2-4.8H14V4c0-1.6-.3-3-1-4H15v10h-2Zm0 0" />
<path d="M5.5 2.3c.1-1.2 1-2 2.1-2s1.9.8 2 2Zm0 0" />
</g>
</svg>
</div>
"""
end
def cell_icon(%{cell_type: :markdown} = assigns) do
~H"""
<div class="flex w-6 h-6 bg-blue-100 rounded items-center justify-center">
<svg width="16" height="14" viewBox="0 0 16 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M1.25 0.25H14.75C14.9489 0.25 15.1397 0.329018 15.2803 0.46967C15.421 0.610322 15.5 0.801088
15.5 1V13C15.5 13.1989 15.421 13.3897 15.2803 13.5303C15.1397 13.671 14.9489 13.75 14.75 13.75H1.25C1.05109
13.75 0.860322 13.671 0.71967 13.5303C0.579018 13.3897 0.5 13.1989 0.5 13V1C0.5 0.801088 0.579018 0.610322
0.71967 0.46967C0.860322 0.329018 1.05109 0.25 1.25 0.25ZM4.25 9.625V6.625L5.75 8.125L7.25
6.625V9.625H8.75V4.375H7.25L5.75 5.875L4.25 4.375H2.75V9.625H4.25ZM12.5 7.375V4.375H11V7.375H9.5L11.75
9.625L14 7.375H12.5Z"
fill="#3E64FF"
/>
</svg>
</div>
"""
end
def cell_icon(%{cell_type: :smart} = assigns) do
~H"""
<div class="flex w-6 h-6 bg-red-100 rounded items-center justify-center">
<.remix_icon icon="flashlight-line text-red-900" />
</div>
"""
end
end

View file

@ -1,7 +1,7 @@
defmodule LivebookWeb.TeamsComponents do
use Phoenix.Component
alias LivebookWeb.LayoutHelpers
alias LivebookWeb.LayoutComponents
@doc """
Renders the teams header with the badges.
@ -12,7 +12,7 @@ defmodule LivebookWeb.TeamsComponents do
def header(assigns) do
~H"""
<LayoutHelpers.title>
<LayoutComponents.title>
<div class="flex gap-2 items-center">
<div class="flex justify-center">
<span class="relative">
@ -33,7 +33,7 @@ defmodule LivebookWeb.TeamsComponents do
</span>
<% end %>
</div>
</LayoutHelpers.title>
</LayoutComponents.title>
"""
end
end

View file

@ -1,4 +1,4 @@
defmodule LivebookWeb.UserHelpers do
defmodule LivebookWeb.UserComponents do
use LivebookWeb, :html
@doc """

View file

@ -1,7 +1,7 @@
defmodule LivebookWeb.AppLive do
use LivebookWeb, :live_view
import LivebookWeb.AppHelpers
import LivebookWeb.AppComponents
@impl true
def mount(%{"slug" => slug}, _session, socket) when socket.assigns.app_authenticated? do

View file

@ -1,7 +1,7 @@
defmodule LivebookWeb.AppSessionLive do
use LivebookWeb, :live_view
import LivebookWeb.AppHelpers
import LivebookWeb.AppComponents
alias Livebook.Session
alias Livebook.Notebook

View file

@ -1,9 +1,9 @@
defmodule LivebookWeb.AppsDashboardLive do
use LivebookWeb, :live_view
import LivebookWeb.AppHelpers
import LivebookWeb.AppComponents
alias LivebookWeb.LayoutHelpers
alias LivebookWeb.LayoutComponents
on_mount LivebookWeb.SidebarHook
@ -21,14 +21,14 @@ defmodule LivebookWeb.AppsDashboardLive do
@impl true
def render(assigns) do
~H"""
<LayoutHelpers.layout
<LayoutComponents.layout
current_page={~p"/apps-dashboard"}
current_user={@current_user}
saved_hubs={@saved_hubs}
>
<div class="p-4 md:px-12 md:py-7 max-w-screen-lg mx-auto">
<div class="flex items-center justify-between">
<LayoutHelpers.title text="Apps" />
<LayoutComponents.title text="Apps" />
<.link navigate={~p"/apps"} class="flex items-center text-blue-600">
<span class="font-semibold">Listing</span>
<.remix_icon icon="arrow-right-line" class="align-middle ml-1" />
@ -38,7 +38,7 @@ defmodule LivebookWeb.AppsDashboardLive do
<.app_list apps={@apps} />
</div>
</div>
</LayoutHelpers.layout>
</LayoutComponents.layout>
"""
end

View file

@ -86,7 +86,7 @@ defmodule LivebookWeb.AppsLive do
@impl true
def handle_info({type, _app} = event, socket)
when type in [:app_created, :app_updated, :app_closed] do
{:noreply, update(socket, :apps, &LivebookWeb.AppHelpers.update_app_list(&1, event))}
{:noreply, update(socket, :apps, &LivebookWeb.AppComponents.update_app_list(&1, event))}
end
def handle_info(_message, socket), do: {:noreply, socket}

View file

@ -28,7 +28,7 @@ defmodule LivebookWeb.FileSelectComponent do
# To force the component to refetch the displayed files you can
# `send_update` with `force_reload: true` to the component.
import LivebookWeb.FileSystemHelpers
import LivebookWeb.FileSystemComponents
alias Livebook.FileSystem

View file

@ -3,7 +3,7 @@ defmodule LivebookWeb.HomeLive do
import LivebookWeb.SessionHelpers
alias LivebookWeb.{LearnHelpers, LayoutHelpers}
alias LivebookWeb.LayoutComponents
alias Livebook.{Sessions, Notebook}
on_mount LivebookWeb.SidebarHook
@ -38,7 +38,7 @@ defmodule LivebookWeb.HomeLive do
@impl true
def render(assigns) do
~H"""
<LayoutHelpers.layout
<LayoutComponents.layout
current_page={@self_path}
current_user={@current_user}
saved_hubs={@saved_hubs}
@ -63,7 +63,7 @@ defmodule LivebookWeb.HomeLive do
<div class="p-4 md:px-12 md:py-6 max-w-screen-lg mx-auto">
<div class="flex flex-row space-y-0 items-center pb-4 justify-between">
<LayoutHelpers.title text="Home" />
<LayoutComponents.title text="Home" />
<div class="hidden md:flex space-x-2" role="navigation" aria-label="new notebook">
<.link
navigate={~p"/open/storage"}
@ -107,9 +107,14 @@ defmodule LivebookWeb.HomeLive do
</:actions>
</.no_entries>
<div class="mt-4 grid grid-cols-1 md:grid-cols-3 gap-4">
<% # Note: it's fine to use stateless components in this comprehension,
# because @notebook_infos never change %>
<LearnHelpers.notebook_card :for={info <- @notebook_infos} notebook_info={info} />
<%!--
Note: it's fine to use stateless components in this comprehension,
because @notebook_infos never change
--%>
<LivebookWeb.NotebookComponents.learn_notebook_card
:for={info <- @notebook_infos}
notebook_info={info}
/>
</div>
<% else %>
<.live_component
@ -143,7 +148,7 @@ defmodule LivebookWeb.HomeLive do
/>
</div>
</div>
</LayoutHelpers.layout>
</LayoutComponents.layout>
<.modal :if={@live_action == :import} id="import-modal" show width={:big} patch={@self_path}>
<.live_component
@ -160,7 +165,7 @@ defmodule LivebookWeb.HomeLive do
defp update_notification(assigns) do
~H"""
<LayoutHelpers.topbar>
<LayoutComponents.topbar>
<span>
Livebook v<%= @version %> available!
<%= if @instructions_url do %>
@ -192,13 +197,13 @@ defmodule LivebookWeb.HomeLive do
<% end %>
🚀
</span>
</LayoutHelpers.topbar>
</LayoutComponents.topbar>
"""
end
defp memory_notification(assigns) do
~H"""
<LayoutHelpers.topbar :if={@app_service_url && @memory.free < 30_000_000} variant={:error}>
<LayoutComponents.topbar :if={@app_service_url && @memory.free < 30_000_000} variant={:error}>
<.remix_icon icon="alarm-warning-line" class="align-text-bottom mr-0.5" />
Less than 30 MB of memory left, consider
<a
@ -215,7 +220,7 @@ defmodule LivebookWeb.HomeLive do
>
running sessions
</a>
</LayoutHelpers.topbar>
</LayoutComponents.topbar>
"""
end

View file

@ -3,7 +3,7 @@ defmodule LivebookWeb.Hub.Edit.PersonalComponent do
alias Livebook.Hubs
alias Livebook.Hubs.Personal
alias LivebookWeb.LayoutHelpers
alias LivebookWeb.LayoutComponents
alias LivebookWeb.NotFoundError
@impl true
@ -47,7 +47,7 @@ defmodule LivebookWeb.Hub.Edit.PersonalComponent do
<div id={"#{@id}-component"}>
<div class="mb-8 flex flex-col space-y-10">
<div class="flex flex-col space-y-2">
<LayoutHelpers.title text={"#{@hub.hub_emoji} #{@hub.hub_name}"} />
<LayoutComponents.title text={"#{@hub.hub_emoji} #{@hub.hub_name}"} />
<p class="text-gray-700 text-sm">
Your personal hub. All data is stored on your machine and only you can access it.

View file

@ -4,7 +4,7 @@ defmodule LivebookWeb.Hub.Edit.TeamComponent do
alias Livebook.Hubs
alias Livebook.Hubs.Provider
alias Livebook.Teams
alias LivebookWeb.LayoutHelpers
alias LivebookWeb.LayoutComponents
alias LivebookWeb.TeamsComponents
alias LivebookWeb.NotFoundError
@ -65,9 +65,9 @@ defmodule LivebookWeb.Hub.Edit.TeamComponent do
def render(assigns) do
~H"""
<div>
<LayoutHelpers.topbar :if={Provider.connection_status(@hub)} variant={:warning}>
<LayoutComponents.topbar :if={Provider.connection_status(@hub)} variant={:warning}>
<%= Provider.connection_status(@hub) %>
</LayoutHelpers.topbar>
</LayoutComponents.topbar>
<div class="p-4 md:px-12 md:py-7 max-w-screen-md mx-auto">
<div id={"#{@id}-component"}>

View file

@ -1,7 +1,7 @@
defmodule LivebookWeb.Hub.EditLive do
use LivebookWeb, :live_view
alias LivebookWeb.LayoutHelpers
alias LivebookWeb.LayoutComponents
alias Livebook.Hubs
alias Livebook.Hubs.Provider
@ -39,7 +39,7 @@ defmodule LivebookWeb.Hub.EditLive do
@impl true
def render(assigns) do
~H"""
<LayoutHelpers.layout
<LayoutComponents.layout
current_page={~p"/hub/#{@hub.id}"}
current_user={@current_user}
saved_hubs={@saved_hubs}
@ -51,7 +51,7 @@ defmodule LivebookWeb.Hub.EditLive do
live_action={@live_action}
params={@params}
/>
</LayoutHelpers.layout>
</LayoutComponents.layout>
"""
end

View file

@ -3,7 +3,7 @@ defmodule LivebookWeb.Hub.NewLive do
alias Livebook.Teams
alias Livebook.Teams.Org
alias LivebookWeb.LayoutHelpers
alias LivebookWeb.LayoutComponents
on_mount LivebookWeb.SidebarHook
@ -35,15 +35,15 @@ defmodule LivebookWeb.Hub.NewLive do
@impl true
def render(assigns) do
~H"""
<LayoutHelpers.layout current_page="/hub" current_user={@current_user} saved_hubs={@saved_hubs}>
<LayoutHelpers.topbar :if={Livebook.Config.warn_on_live_teams_server?()} variant={:warning}>
<LayoutComponents.layout current_page="/hub" current_user={@current_user} saved_hubs={@saved_hubs}>
<LayoutComponents.topbar :if={Livebook.Config.warn_on_live_teams_server?()} variant={:warning}>
<strong>Beware!</strong>
You are running Livebook in development but this page communicates with production servers.
</LayoutHelpers.topbar>
</LayoutComponents.topbar>
<div class="flex flex-col p-4 md:px-12 md:py-7 max-w-screen-md mx-auto space-y-8">
<div>
<LayoutHelpers.title text="Add organization" />
<LayoutComponents.title text="Add organization" />
<p class="mt-4 text-gray-700">
<a
class="font-medium underline text-gray-900 hover:no-underline"
@ -145,7 +145,7 @@ defmodule LivebookWeb.Hub.NewLive do
</.form>
</div>
</div>
</LayoutHelpers.layout>
</LayoutComponents.layout>
"""
end

View file

@ -70,7 +70,7 @@ defmodule LivebookWeb.Hub.Teams.DeploymentGroupFormComponent do
{"Online", "online"}
]}
/>
<LivebookWeb.AppHelpers.deployment_group_form_content hub={@hub} form={f} />
<LivebookWeb.AppComponents.deployment_group_form_content hub={@hub} form={f} />
<div class="flex space-x-2">
<button class="button-base button-blue" type="submit" disabled={not @changeset.valid?}>
<.remix_icon icon={@button.icon} class="align-middle mr-1" />

View file

@ -1,7 +1,7 @@
defmodule LivebookWeb.Hub.Teams.DeploymentGroupLive do
use LivebookWeb, :live_view
alias LivebookWeb.LayoutHelpers
alias LivebookWeb.LayoutComponents
alias LivebookWeb.TeamsComponents
alias Livebook.Hubs
alias Livebook.Teams
@ -58,15 +58,15 @@ defmodule LivebookWeb.Hub.Teams.DeploymentGroupLive do
@impl true
def render(assigns) do
~H"""
<LayoutHelpers.layout
<LayoutComponents.layout
current_page={~p"/hub/#{@hub.id}"}
current_user={@current_user}
saved_hubs={@saved_hubs}
>
<div>
<LayoutHelpers.topbar :if={Provider.connection_status(@hub)} variant={:warning}>
<LayoutComponents.topbar :if={Provider.connection_status(@hub)} variant={:warning}>
<%= Provider.connection_status(@hub) %>
</LayoutHelpers.topbar>
</LayoutComponents.topbar>
<div class="p-4 md:px-12 md:py-7 max-w-screen-md mx-auto">
<div id={"#{@hub.id}-component"}>
@ -127,14 +127,14 @@ defmodule LivebookWeb.Hub.Teams.DeploymentGroupLive do
</p>
<.form :let={f} for={@config_changeset} as={:data} phx-change="validate_dockerfile">
<LivebookWeb.AppHelpers.docker_config_form_content
<LivebookWeb.AppComponents.docker_config_form_content
hub={@hub}
form={f}
show_deploy_all={false}
/>
</.form>
<LivebookWeb.AppHelpers.docker_instructions
<LivebookWeb.AppComponents.docker_instructions
hub={@hub}
dockerfile={@dockerfile}
dockerfile_config={Ecto.Changeset.apply_changes(@config_changeset)}
@ -162,7 +162,7 @@ defmodule LivebookWeb.Hub.Teams.DeploymentGroupLive do
return_to={~p"/hub/#{@hub.id}/deployment-groups/edit/#{@deployment_group.id}"}
/>
</.modal>
</LayoutHelpers.layout>
</LayoutComponents.layout>
"""
end

View file

@ -1,40 +0,0 @@
defmodule LivebookWeb.LearnHelpers do
use Phoenix.Component
use LivebookWeb, :verified_routes
@doc """
Renders an learn notebook card.
"""
attr :notebook_info, :map, required: true
def notebook_card(assigns) do
~H"""
<.link
navigate={~p"/learn/notebooks/#{@notebook_info.slug}"}
class="flex flex-col border-2 border-gray-100 hover:border-gray-200 rounded-2xl"
>
<div class="flex items-center justify-center p-6 border-b-2 border-gray-100 rounded-t-2xl h-[150px]">
<img
src={learn_img_src(@notebook_info.details.cover)}
class="max-h-full max-w-[75%]"
alt={"#{@notebook_info.title} logo"}
/>
</div>
<div class="px-6 py-4 bg-gray-100 rounded-b-2xl grow">
<span class="text-gray-800 font-semibold"><%= @notebook_info.title %></span>
<p class="mt-2 text-sm text-gray-600">
<%= @notebook_info.details.description %>
</p>
</div>
</.link>
"""
end
@doc """
Resolves the given image source into a URL.
"""
@spec learn_img_src(Livebook.Notebook.Learn.image_source()) :: String.t()
def learn_img_src({:url, url}), do: url
def learn_img_src({:static, filename}), do: ~p"/images/#{filename}"
end

View file

@ -2,8 +2,9 @@ defmodule LivebookWeb.LearnLive do
use LivebookWeb, :live_view
import LivebookWeb.SessionHelpers
import LivebookWeb.NotebookComponents
alias LivebookWeb.{LayoutHelpers, LearnHelpers}
alias LivebookWeb.LayoutComponents
alias Livebook.Notebook.Learn
on_mount LivebookWeb.SidebarHook
@ -23,14 +24,14 @@ defmodule LivebookWeb.LearnLive do
@impl true
def render(assigns) do
~H"""
<LayoutHelpers.layout
<LayoutComponents.layout
current_page={~p"/learn"}
current_user={@current_user}
saved_hubs={@saved_hubs}
>
<div class="p-4 md:px-12 md:py-7 max-w-screen-lg mx-auto space-y-4">
<div>
<LayoutHelpers.title text="Learn" />
<LayoutComponents.title text="Learn" />
<p class="mt-4 mb-8 text-gray-700">
Check out a number of examples showcasing various parts of the Elixir ecosystem.<br />
Click on any notebook you like and start playing around with it!
@ -40,11 +41,7 @@ defmodule LivebookWeb.LearnLive do
id="welcome-to-livebook"
class="p-8 bg-gray-900 rounded-2xl flex flex-col sm:flex-row space-y-8 sm:space-y-0 space-x-0 sm:space-x-8 items-center"
>
<img
src={LearnHelpers.learn_img_src(@lead_notebook_info.details.cover)}
width="100"
alt="livebook"
/>
<img src={learn_img_src(@lead_notebook_info.details.cover)} width="100" alt="livebook" />
<div>
<h3 class="text-xl text-gray-50 font-semibold">
<%= @lead_notebook_info.title %>
@ -63,13 +60,15 @@ defmodule LivebookWeb.LearnLive do
</div>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-4">
<% # Note: it's fine to use stateless components in this comprehension,
# because @notebook_infos never change %>
<LearnHelpers.notebook_card :for={info <- @notebook_infos} notebook_info={info} />
<%!--
Note: it's fine to use stateless components in this comprehension,
because @notebook_infos never change
--%>
<.learn_notebook_card :for={info <- @notebook_infos} notebook_info={info} />
</div>
<.notebook_group :for={group_info <- Learn.group_infos()} group_info={group_info} />
</div>
</LayoutHelpers.layout>
</LayoutComponents.layout>
"""
end
@ -77,7 +76,7 @@ defmodule LivebookWeb.LearnLive do
~H"""
<div>
<div class="p-8 mt-16 rounded-2xl border border-gray-300 flex flex-col sm:flex-row space-y-8 sm:space-y-0 space-x-0 sm:space-x-8 items-center">
<img src={LearnHelpers.learn_img_src(@group_info.cover)} width="100" />
<img src={learn_img_src(@group_info.cover)} width="100" />
<div>
<div class="inline-flex px-2 py-0.5 bg-gray-200 rounded-3xl text-gray-700 text-xs font-medium">
<%= length(@group_info.notebook_infos) %> notebooks

View file

@ -3,7 +3,7 @@ defmodule LivebookWeb.OpenLive do
import LivebookWeb.SessionHelpers
alias LivebookWeb.LayoutHelpers
alias LivebookWeb.LayoutComponents
alias Livebook.{Sessions, Notebook, FileSystem}
on_mount LivebookWeb.SidebarHook
@ -32,7 +32,11 @@ defmodule LivebookWeb.OpenLive do
@impl true
def render(assigns) do
~H"""
<LayoutHelpers.layout current_page={~p"/"} current_user={@current_user} saved_hubs={@saved_hubs}>
<LayoutComponents.layout
current_page={~p"/"}
current_user={@current_user}
saved_hubs={@saved_hubs}
>
<:topbar_action>
<.link class="button-base button-blue" navigate={~p"/new"}>
<.remix_icon icon="add-line" class="align-middle mr-1" />
@ -41,7 +45,7 @@ defmodule LivebookWeb.OpenLive do
</:topbar_action>
<div class="p-4 md:px-12 md:py-6 max-w-screen-lg mx-auto space-y-4">
<div class="flex flex-row space-y-0 items-center pb-4 justify-between">
<LayoutHelpers.title text="Open notebook" back_navigate={~p"/"} />
<LayoutComponents.title text="Open notebook" back_navigate={~p"/"} />
<div class="hidden md:flex" role="navigation" aria-label="new notebook">
<.link class="button-base button-blue" navigate={~p"/new"}>
<.remix_icon icon="add-line" class="align-middle mr-1" />
@ -135,7 +139,7 @@ defmodule LivebookWeb.OpenLive do
</div>
</div>
</div>
</LayoutHelpers.layout>
</LayoutComponents.layout>
"""
end

View file

@ -58,8 +58,10 @@ defmodule LivebookWeb.Output.TerminalTextComponent do
data-p-max-lines={hook_prop(Livebook.Notebook.max_terminal_lines())}
data-p-ignore-trailing-empty-line={hook_prop(true)}
>
<% # Note 1: We add a newline to each element, so that multiple lines can be copied properly as element.textContent %>
<% # Note 2: We glue the tags together to avoid inserting unintended whitespace %>
<%!--
Note 1: We add a newline to each element, so that multiple lines can be copied properly as element.textContent
Note 2: We glue the tags together to avoid inserting unintended whitespace
--%>
<div data-template class="hidden" id={"#{@id}-template"} phx-no-format><div
id={"#{@id}-template-append"}
phx-update="stream"

View file

@ -154,60 +154,6 @@ defmodule LivebookWeb.SessionHelpers do
end
end
def cell_icon(%{cell_type: :code, language: :elixir} = assigns) do
~H"""
<div class="flex w-6 h-6 bg-purple-100 rounded items-center justify-center">
<svg width="11" height="15" viewBox="0 0 11 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M5.7784 3.58083C7.4569 5.87527 9.67878 5.70652 10.0618 9.04833C10.1147 12.9425 8.03684
14.27 6.55353 14.6441C4.02227 15.3635 1.7644 14.2813 0.875648 11.8316C-0.83154 7.89408 2.36684
1.41746 4.42502 0.0668945C4.60193 1.32119 5.05745 2.51995 5.75815 3.57521L5.7784 3.58083Z"
fill="#663299"
/>
</svg>
</div>
"""
end
def cell_icon(%{cell_type: :code, language: :erlang} = assigns) do
~H"""
<div class="flex w-6 h-6 bg-red-100 rounded items-center justify-center">
<svg width="18" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15 10">
<g fill="#a90533">
<path d="M2.4 10A7.7 7.7 0 0 1 .5 4.8c0-2 .6-3.6 1.6-4.8H0v10ZM13 10c.5-.6 1-1.2 1.4-2l-2.3-1.2c-.8 1.4-2 2.6-3.6 2.6-2.3 0-3.2-2-3.2-4.8H14V4c0-1.6-.3-3-1-4H15v10h-2Zm0 0" />
<path d="M5.5 2.3c.1-1.2 1-2 2.1-2s1.9.8 2 2Zm0 0" />
</g>
</svg>
</div>
"""
end
def cell_icon(%{cell_type: :markdown} = assigns) do
~H"""
<div class="flex w-6 h-6 bg-blue-100 rounded items-center justify-center">
<svg width="16" height="14" viewBox="0 0 16 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M1.25 0.25H14.75C14.9489 0.25 15.1397 0.329018 15.2803 0.46967C15.421 0.610322 15.5 0.801088
15.5 1V13C15.5 13.1989 15.421 13.3897 15.2803 13.5303C15.1397 13.671 14.9489 13.75 14.75 13.75H1.25C1.05109
13.75 0.860322 13.671 0.71967 13.5303C0.579018 13.3897 0.5 13.1989 0.5 13V1C0.5 0.801088 0.579018 0.610322
0.71967 0.46967C0.860322 0.329018 1.05109 0.25 1.25 0.25ZM4.25 9.625V6.625L5.75 8.125L7.25
6.625V9.625H8.75V4.375H7.25L5.75 5.875L4.25 4.375H2.75V9.625H4.25ZM12.5 7.375V4.375H11V7.375H9.5L11.75
9.625L14 7.375H12.5Z"
fill="#3E64FF"
/>
</svg>
</div>
"""
end
def cell_icon(%{cell_type: :smart} = assigns) do
~H"""
<div class="flex w-6 h-6 bg-red-100 rounded items-center justify-center">
<.remix_icon icon="flashlight-line text-red-900" />
</div>
"""
end
@doc """
Shows a confirmation modal to delete the given session.

View file

@ -1,9 +1,9 @@
defmodule LivebookWeb.SessionLive do
use LivebookWeb, :live_view
import LivebookWeb.UserHelpers
import LivebookWeb.UserComponents
import LivebookWeb.SessionHelpers
import LivebookWeb.FileSystemHelpers
import LivebookWeb.FileSystemComponents
import Livebook.Utils, only: [format_bytes: 1]
alias Livebook.{Sessions, Session, Text, Notebook, Runtime, LiveMarkdown}
@ -715,8 +715,10 @@ defmodule LivebookWeb.SessionLive do
>
<span class="flex items-center space-x-1">
<span><%= section_item.name %></span>
<% # 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 %>
<%!--
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
:if={section_item.parent}
{branching_tooltip_attrs(section_item.name, section_item.parent.name)}

View file

@ -5,7 +5,7 @@ defmodule LivebookWeb.SessionLive.AppDockerComponent do
alias Livebook.Hubs
alias Livebook.FileSystem
alias LivebookWeb.AppHelpers
alias LivebookWeb.AppComponents
alias Livebook.Hubs.Provider
@impl true
@ -136,14 +136,14 @@ defmodule LivebookWeb.SessionLive.AppDockerComponent do
phx-target={@myself}
>
<div class="flex flex-col space-y-4">
<AppHelpers.deployment_group_form_content hub={@hub} form={f} />
<AppComponents.deployment_group_form_content hub={@hub} form={f} />
</div>
</.form>
<.form :let={f} for={@changeset} as={:data} phx-change="validate" phx-target={@myself}>
<AppHelpers.docker_config_form_content hub={@hub} form={f} />
<AppComponents.docker_config_form_content hub={@hub} form={f} />
</.form>
<.save_result :if={@save_result} save_result={@save_result} />
<AppHelpers.docker_instructions
<AppComponents.docker_instructions
hub={@hub}
dockerfile={@dockerfile}
dockerfile_config={apply_changes(@changeset)}
@ -160,7 +160,7 @@ defmodule LivebookWeb.SessionLive.AppDockerComponent do
<span class="font-normal text-xs">Save alongside notebook</span>
</button>
</:dockerfile_actions>
</AppHelpers.docker_instructions>
</AppComponents.docker_instructions>
</div>
"""
end

View file

@ -1,7 +1,7 @@
defmodule LivebookWeb.SessionLive.AppInfoComponent do
use LivebookWeb, :live_component
import LivebookWeb.AppHelpers
import LivebookWeb.AppComponents
@impl true
def render(assigns) do

View file

@ -1,7 +1,7 @@
defmodule LivebookWeb.SessionLive.BinComponent do
use LivebookWeb, :live_component
import LivebookWeb.SessionHelpers
import LivebookWeb.NotebookComponents
alias Livebook.Notebook.Cell

View file

@ -1,7 +1,7 @@
defmodule LivebookWeb.SessionLive.CellComponent do
use LivebookWeb, :live_component
import LivebookWeb.SessionHelpers
import LivebookWeb.NotebookComponents
@impl true
def mount(socket) do

View file

@ -261,7 +261,7 @@ defmodule LivebookWeb.SessionLive.IndicatorsComponent do
defp insert_mode_indicator(assigns) do
~H"""
<% # Note: this indicator is shown/hidden using CSS based on the current mode %>
<%!-- Note: this indicator is shown/hidden using CSS based on the current mode --%>
<span class="tooltip left" data-tooltip="Insert mode" data-el-insert-mode-indicator>
<span class="text-sm font-medium text-gray-400 cursor-default">
ins

View file

@ -1,7 +1,7 @@
defmodule LivebookWeb.SessionLive.InsertButtonsComponent do
use LivebookWeb, :live_component
import LivebookWeb.SessionHelpers
import LivebookWeb.NotebookComponents
defguardp is_many(list) when tl(list) != []

View file

@ -1,7 +1,7 @@
defmodule LivebookWeb.SettingsLive do
use LivebookWeb, :live_view
alias LivebookWeb.LayoutHelpers
alias LivebookWeb.LayoutComponents
on_mount LivebookWeb.SidebarHook
@ -27,7 +27,7 @@ defmodule LivebookWeb.SettingsLive do
@impl true
def render(assigns) do
~H"""
<LayoutHelpers.layout
<LayoutComponents.layout
current_page={~p"/settings"}
current_user={@current_user}
saved_hubs={@saved_hubs}
@ -36,7 +36,7 @@ defmodule LivebookWeb.SettingsLive do
<!-- System settings section -->
<div class="flex flex-col space-y-10">
<div>
<LayoutHelpers.title text="System settings" />
<LayoutComponents.title text="System settings" />
<p class="mt-4 text-gray-700">
Here you can change global Livebook configuration. Keep in mind
that this configuration gets persisted and will be restored on application
@ -121,7 +121,7 @@ defmodule LivebookWeb.SettingsLive do
<!-- User settings section -->
<div class="flex flex-col space-y-10 pb-8">
<div>
<LayoutHelpers.title text="User settings" />
<LayoutComponents.title text="User settings" />
<p class="mt-4 text-gray-700">
The configuration in this section changes only your Livebook
experience and is saved in your browser.
@ -175,7 +175,7 @@ defmodule LivebookWeb.SettingsLive do
</div>
</div>
</div>
</LayoutHelpers.layout>
</LayoutComponents.layout>
<.modal
:if={@live_action in [:add_env_var, :edit_env_var]}

View file

@ -1,7 +1,7 @@
defmodule LivebookWeb.UserComponent do
use LivebookWeb, :live_component
import LivebookWeb.UserHelpers
import LivebookWeb.UserComponents
alias Livebook.EctoTypes.HexColor
alias Livebook.Users