mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-10-30 23:36:39 +08:00
Move helpers to components (#2448)
This commit is contained in:
parent
365cbe7101
commit
501a98d7c6
33 changed files with 202 additions and 184 deletions
|
|
@ -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" <>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
defmodule LivebookWeb.AppHelpers do
|
||||
defmodule LivebookWeb.AppComponents do
|
||||
use LivebookWeb, :html
|
||||
|
||||
alias Livebook.Hubs
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
defmodule LivebookWeb.FileSystemHelpers do
|
||||
defmodule LivebookWeb.FileSystemComponents do
|
||||
use LivebookWeb, :html
|
||||
|
||||
alias Livebook.FileSystem
|
||||
|
|
@ -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
|
||||
|
||||
100
lib/livebook_web/components/notebook_components.ex
Normal file
100
lib/livebook_web/components/notebook_components.ex
Normal 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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
defmodule LivebookWeb.UserHelpers do
|
||||
defmodule LivebookWeb.UserComponents do
|
||||
use LivebookWeb, :html
|
||||
|
||||
@doc """
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
defmodule LivebookWeb.AppSessionLive do
|
||||
use LivebookWeb, :live_view
|
||||
|
||||
import LivebookWeb.AppHelpers
|
||||
import LivebookWeb.AppComponents
|
||||
|
||||
alias Livebook.Session
|
||||
alias Livebook.Notebook
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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"}>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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)}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
defmodule LivebookWeb.SessionLive.BinComponent do
|
||||
use LivebookWeb, :live_component
|
||||
|
||||
import LivebookWeb.SessionHelpers
|
||||
import LivebookWeb.NotebookComponents
|
||||
|
||||
alias Livebook.Notebook.Cell
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) != []
|
||||
|
||||
|
|
|
|||
|
|
@ -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]}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue