defmodule LivebookWeb.Hub.Edit.FlyComponent do use LivebookWeb, :live_component alias Livebook.Hubs.{Fly, FlyClient} alias LivebookWeb.LayoutHelpers @impl true def update(assigns, socket) do changeset = Fly.change_hub(assigns.hub) {:ok, app} = FlyClient.fetch_app(assigns.hub) env_vars = env_vars_from_secrets(app["secrets"]) env_var = if name = assigns.env_var_id do Enum.find(env_vars, &(&1.name == name)) end {:ok, socket |> assign(assigns) |> assign( app_url: "https://fly.io/apps/#{app["name"]}", changeset: changeset, env_vars: env_vars, env_var: env_var )} end defp env_vars_from_secrets(secrets) do for secret <- secrets do %Livebook.Settings.EnvVar{name: secret["name"]} end end @impl true def render(assigns) do ~H"""
<.labeled_text label="Application ID"> <%= @hub.application_id %> <.labeled_text label="Type"> Fly
<.remix_icon icon="dashboard-2-line" class="align-middle mr-1" /> Manage app on Fly

General

<.form :let={f} id={@id} class="flex flex-col mt-4 space-y-4" for={@changeset} phx-submit="save" phx-change="validate" phx-target={@myself} >
<.text_field field={f[:hub_name]} label="Name" /> <.emoji_field field={f[:hub_emoji]} label="Emoji" />

Environment Variables

<.live_component module={LivebookWeb.EnvVarsComponent} id="env-vars" env_vars={@env_vars} return_to={~p"/hub/#{@hub.id}"} add_env_var_path={~p"/hub/#{@hub.id}/env-var/new"} edit_label="Replace" target={@myself} />
<.modal :if={@live_action in [:add_env_var, :edit_env_var]} id="env-var-modal" show width={:medium} target={@myself} patch={~p"/hub/#{@hub.id}"} > <.live_component module={LivebookWeb.EnvVarComponent} id="env-var" on_save={JS.push("save_env_var", target: @myself)} env_var={@env_var} headline="Configute your Fly application system environment variables" return_to={~p"/hub/#{@hub.id}"} />
""" end @impl true def handle_event("save", %{"fly" => params}, socket) do case Fly.update_hub(socket.assigns.hub, params) do {:ok, hub} -> {:noreply, socket |> put_flash(:success, "Hub updated successfully") |> push_navigate(to: ~p"/hub/#{hub.id}")} {:error, changeset} -> {:noreply, assign(socket, changeset: changeset)} end end def handle_event("validate", %{"fly" => attrs}, socket) do {:noreply, assign(socket, changeset: Fly.validate_hub(socket.assigns.hub, attrs))} end # EnvVar component callbacks def handle_event("save_env_var", %{"env_var" => attrs}, socket) do env_operation = attrs["operation"] attrs = %{"key" => attrs["name"], "value" => attrs["value"]} case FlyClient.set_secrets(socket.assigns.hub, [attrs]) do {:ok, _} -> message = if env_operation == "new", do: "Environment variable added", else: "Environment variable updated" {:noreply, socket |> put_flash(:success, message) |> push_navigate(to: ~p"/hub/#{socket.assigns.hub.id}")} {:error, _} -> message = if env_operation == "new", do: "Failed to add environment variable", else: "Failed to update environment variable" {:noreply, socket |> put_flash(:error, message) |> push_navigate(to: ~p"/hub/#{socket.assigns.hub.id}")} end end def handle_event("edit_env_var", %{"env_var" => key}, socket) do {:noreply, push_patch(socket, to: ~p"/hub/#{socket.assigns.hub.id}/env-var/edit/#{key}")} end def handle_event("delete_env_var", %{"env_var" => key}, socket) do case FlyClient.unset_secrets(socket.assigns.hub, [key]) do {:ok, _} -> {:noreply, socket |> put_flash(:success, "Environment variable deleted") |> push_navigate(to: ~p"/hub/#{socket.assigns.hub.id}")} {:error, _} -> {:noreply, socket |> put_flash(:error, "Failed to delete environment variable") |> push_navigate(to: ~p"/hub/#{socket.assigns.hub.id}")} end end end