defmodule LivebookWeb.AppComponents do use LivebookWeb, :html alias Livebook.Hubs @doc """ Renders page placeholder on unauthenticated dead render. """ def auth_placeholder(assigns) do ~H"""
livebook
""" end @doc """ Renders app status with indicator. """ attr :status, :map, required: true attr :show_label, :boolean, default: true def app_status(%{status: %{lifecycle: :shutting_down}} = assigns) do ~H""" <.app_status_indicator text={@show_label && "Shutting down"} variant={:inactive} /> """ end def app_status(%{status: %{lifecycle: :deactivated}} = assigns) do ~H""" <.app_status_indicator text={@show_label && "Deactivated"} variant={:inactive} /> """ end def app_status(%{status: %{execution: :executing}} = assigns) do ~H""" <.app_status_indicator text={@show_label && "Executing"} variant={:progressing} /> """ end def app_status(%{status: %{execution: :executed}} = assigns) do ~H""" <.app_status_indicator text={@show_label && "Executed"} variant={:success} /> """ end def app_status(%{status: %{execution: :error}} = assigns) do ~H""" <.app_status_indicator text={@show_label && "Error"} variant={:error} /> """ end def app_status(%{status: %{execution: :interrupted}} = assigns) do ~H""" <.app_status_indicator text={@show_label && "Interrupted"} variant={:waiting} /> """ end defp app_status_indicator(assigns) do ~H""" <.status_indicator variant={@variant} /> <%= @text %> """ end @doc """ Shows a confirmation modal and closes the app on confirm. """ def confirm_app_termination(socket, app_pid) do on_confirm = fn socket -> Livebook.App.close(app_pid) socket end confirm(socket, on_confirm, title: "Terminate app", description: "All app sessions will be immediately terminated.", confirm_text: "Terminate", confirm_icon: "delete-bin-6-line" ) end @doc """ Renders form fields for Dockerfile configuration. """ attr :form, Phoenix.HTML.Form, required: true attr :hub, :map, required: true attr :show_deploy_all, :boolean, default: true def docker_config_form_content(assigns) do ~H"""
<.radio_field :if={@show_deploy_all} label="Deploy" field={@form[:deploy_all]} options={[ {"false", "Only this notebook"}, {"true", "All notebooks in the current directory"} ]} /> <.radio_field label="Base image" field={@form[:docker_tag]} options={docker_tag_options()} />
""" end @doc """ Renders form fields for Deployment Group. """ attr :form, Phoenix.HTML.Form, required: true attr :hub, :map, required: true attr :disabled, :boolean, default: false def deployment_group_form_content(assigns) do ~H"""
<.select_field label="Clustering" help={ ~S''' When running multiple instances of Livebook, they need to be connected into a single cluster. You must either deploy it as a single instance or choose a platform to enable clustering on. ''' } field={@form[:clustering]} options={[ {"Single instance", ""}, {"Fly.io", "fly_io"} ]} disabled={@disabled} />
<%= if Hubs.Provider.type(@hub) == "team" do %>
<.select_field label="Zero Trust Authentication provider" field={@form[:zta_provider]} help={ ~S''' Enable this option if you want to deploy your notebooks behind an authentication proxy ''' } prompt="None" options={zta_options()} disabled={@disabled} /> <.text_field :if={zta_metadata = zta_metadata(@form[:zta_provider].value)} field={@form[:zta_key]} label={zta_metadata.value} placeholder={zta_placeholder(zta_metadata)} phx-debounce disabled={@disabled} />
See the Authentication with <%= zta_metadata.name %> docs for more information.
<% end %> """ end @zta_options for provider <- Livebook.Config.identity_providers(), do: {provider.name, provider.type} defp zta_options(), do: @zta_options @docker_tag_options for image <- Livebook.Config.docker_images(), do: {image.tag, image.name} defp docker_tag_options(), do: @docker_tag_options @doc """ Renders Docker deployment instruction for an app. """ attr :hub, :map, required: true attr :dockerfile, :string, required: true attr :dockerfile_config, :map, required: true slot :dockerfile_actions, default: nil def docker_instructions(assigns) do ~H"""
Dockerfile
<%= render_slot(@dockerfile_actions) %>
<.code_preview source_id="dockerfile-source" source={@dockerfile} language="dockerfile" />
To test the deployment locally, go the the notebook directory, save the Dockerfile, then run:
<.code_preview source_id="dockerfile-cmd" source={ ~s''' docker build -t my-app . docker run --rm -p 8080:8080 -p 8081:8081 my-app ''' } language="text" />

You may additionally perform the following optional steps:

""" end defp zta_metadata(nil), do: nil defp zta_metadata(zta_provider) do Enum.find(Livebook.Config.identity_providers(), &(&1.type == zta_provider)) end @doc """ Updates app list with the given apps event. """ def update_app_list(apps, event) def update_app_list(apps, {:app_created, app}) do if app in apps, do: apps, else: [app | apps] end def update_app_list(apps, {:app_updated, app}) do Enum.map(apps, fn other -> if other.slug == app.slug, do: app, else: other end) end def update_app_list(apps, {:app_closed, app}) do Enum.reject(apps, &(&1.slug == app.slug)) end defp zta_placeholder(%{placeholder: placeholder}), do: placeholder defp zta_placeholder(_), do: nil end