Packages
livebook
0.19.2
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
Current section
Files
Jump to
Current section
Files
lib/livebook_web/live/hub/secret_form_component.ex
defmodule LivebookWeb.Hub.SecretFormComponent do
use LivebookWeb, :live_component
alias Livebook.Hubs
alias Livebook.Secrets
alias Livebook.Secrets.Secret
@impl true
def mount(socket) do
{:ok, assign(socket, error_message: nil)}
end
@impl true
def update(assigns, socket) do
{:ok,
socket
|> assign(assigns)
|> assign_new(:changeset, fn ->
Secrets.change_secret(%Secret{}, %{
name: assigns.secret_name,
value: assigns.secret_value
})
end)
|> assign(
title: title(socket),
button: button_attrs(socket),
deployment_group_id: assigns[:deployment_group_id]
)}
end
@impl true
def render(assigns) do
~H"""
<div class="flex flex-col space-y-5">
<h3 class="text-2xl font-semibold text-gray-800">
{@title}
</h3>
<p class="text-gray-700">
A notebook can read the secret value as a LB_ prefixed environment variable.
</p>
<div :if={@error_message} class="error-box">
{@error_message}
</div>
<div class="flex flex-columns gap-4">
<.form
:let={f}
id={"#{@id}-form"}
for={@changeset}
phx-target={@myself}
phx-change="validate"
phx-submit="save"
autocomplete="off"
class="basis-1/2 grow"
>
<div class="flex flex-col space-y-4">
<.text_field
field={f[:name]}
label="Name (alphanumeric and underscore)"
outer_prefix="LB_"
autofocus={@secret_name == nil}
spellcheck="false"
autocomplete="off"
readonly={@secret_name != nil}
phx-debounce
help="Name cannot be changed"
class={secret_name_input_class(@secret_name)}
/>
<.password_field
field={f[:value]}
label="Value"
autofocus={@secret_name != nil}
spellcheck="false"
autocomplete="off"
phx-debounce
/>
<.hidden_field field={f[:hub_id]} value={@hub.id} />
<.hidden_field field={f[:deployment_group_id]} value={@deployment_group_id} />
<div class="flex space-x-2">
<.button type="submit" disabled={@disabled or not @changeset.valid?}>
<.remix_icon icon={@button.icon} />
<span class="font-normal">{@button.label}</span>
</.button>
<.button color="gray" outlined patch={@return_to}>
Cancel
</.button>
</div>
</div>
</.form>
</div>
</div>
"""
end
@impl true
def handle_event("save", %{"secret" => attrs}, socket) do
changeset = Secrets.change_secret(%Secret{}, attrs)
with {:ok, secret} <- Ecto.Changeset.apply_action(changeset, :insert),
:ok <- save_secret(socket, secret, changeset) do
message =
if socket.assigns.secret_name,
do: "Secret #{secret.name} updated successfully",
else: "Secret #{secret.name} added successfully"
{:noreply,
socket
|> put_flash(:success, message)
|> push_patch(to: socket.assigns.return_to)}
else
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, changeset: changeset)}
{:transport_error, error} ->
{:noreply, assign(socket, error_message: error)}
end
end
def handle_event("validate", %{"secret" => attrs}, socket) do
changeset =
%Secret{}
|> Secrets.change_secret(attrs)
|> Map.replace!(:action, :validate)
{:noreply, assign(socket, changeset: changeset)}
end
defp title(%{assigns: %{secret_name: nil}}), do: "Add secret"
defp title(_), do: "Edit secret"
defp button_attrs(%{assigns: %{secret_name: nil}}), do: %{icon: "add-line", label: "Add"}
defp button_attrs(_), do: %{icon: "save-line", label: "Save"}
defp save_secret(socket, secret, changeset) do
result =
if socket.assigns.secret_name do
Hubs.update_secret(socket.assigns.hub, secret)
else
Hubs.create_secret(socket.assigns.hub, secret)
end
with {:error, errors} <- result do
{:error,
changeset
|> Livebook.Utils.put_changeset_errors(errors)
|> Map.replace!(:action, :validate)}
end
end
defp secret_name_input_class(nil), do: "uppercase"
defp secret_name_input_class(_), do: "uppercase bg-gray-200/50 border-200/80 cursor-not-allowed"
end