mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-11-08 05:04:46 +08:00
Improvements to Hubs pages
This commit is contained in:
parent
926a359245
commit
4a54762889
3 changed files with 289 additions and 285 deletions
|
|
@ -180,9 +180,9 @@ defmodule Livebook.Config do
|
|||
@doc """
|
||||
Returns the configured URL for the Livebook Teams endpoint.
|
||||
"""
|
||||
@spec teams_url() :: String.t() | nil
|
||||
@spec teams_url() :: String.t()
|
||||
def teams_url() do
|
||||
Application.get_env(:livebook, :teams_url)
|
||||
Application.fetch_env!(:livebook, :teams_url)
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
|
|
|||
|
|
@ -34,141 +34,139 @@ defmodule LivebookWeb.Hub.Edit.PersonalComponent do
|
|||
~H"""
|
||||
<div class="p-4 md:px-12 md:py-7 max-w-screen-md mx-auto">
|
||||
<div id={"#{@id}-component"}>
|
||||
<div class="mb-8">
|
||||
<div class="space-y-8">
|
||||
<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}"} />
|
||||
|
||||
<p class="text-gray-700">
|
||||
<p class="text-gray-700 text-sm">
|
||||
Your personal hub. All data is stored on your machine and only you can access it.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col space-y-10">
|
||||
<div class="flex flex-col space-y-2">
|
||||
<h2 class="text-xl text-gray-800 font-medium pb-2 border-b border-gray-200">
|
||||
General
|
||||
</h2>
|
||||
<div class="flex flex-col space-y-4">
|
||||
<h2 class="text-xl text-gray-800 font-medium pb-2 border-b border-gray-200">
|
||||
General
|
||||
</h2>
|
||||
|
||||
<.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}
|
||||
<.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}
|
||||
>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||
<.text_field field={f[:hub_name]} label="Name" />
|
||||
<.emoji_field field={f[:hub_emoji]} label="Emoji" />
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
class="button-base button-blue"
|
||||
type="submit"
|
||||
phx-disable-with="Updating..."
|
||||
disabled={not @changeset.valid?}
|
||||
>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||
<.text_field field={f[:hub_name]} label="Name" />
|
||||
<.emoji_field field={f[:hub_emoji]} label="Emoji" />
|
||||
</div>
|
||||
<div>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</.form>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col space-y-4">
|
||||
<h2 class="text-xl text-gray-800 font-medium pb-2 border-b border-gray-200">
|
||||
Secrets
|
||||
</h2>
|
||||
|
||||
<p class="text-gray-700">
|
||||
Secrets are a safe way to share credentials and tokens with notebooks.
|
||||
They are often used by Smart cells and can be read as
|
||||
environment variables using the <code>LB_</code> prefix.
|
||||
</p>
|
||||
|
||||
<.live_component
|
||||
module={LivebookWeb.Hub.SecretListComponent}
|
||||
id="hub-secrets-list"
|
||||
hub={@hub}
|
||||
secrets={@secrets}
|
||||
target={@myself}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col space-y-4">
|
||||
<h2 class="text-xl text-gray-800 font-medium pb-2 border-b border-gray-200">
|
||||
Stamping
|
||||
</h2>
|
||||
|
||||
<p class="text-gray-700">
|
||||
Notebooks may be stamped using your <span class="font-medium text-gray-800">secret key</span>.
|
||||
A stamp allows to securely store information such as the names of the secrets that you granted access to.
|
||||
You must not share your secret key with others. But you may copy the secret key between
|
||||
different machines you own.
|
||||
</p>
|
||||
<p class="text-gray-700">
|
||||
If you change the <span class="font-medium text-gray-800">secret key</span>, you will need
|
||||
to grant access to secrets once again in previously stamped notebooks.
|
||||
</p>
|
||||
|
||||
<.form
|
||||
:let={f}
|
||||
id={"#{@id}-stamp"}
|
||||
class="flex flex-col mt-4 space-y-4"
|
||||
for={@stamp_changeset}
|
||||
phx-submit="stamp_save"
|
||||
phx-change="stamp_validate"
|
||||
phx-target={@myself}
|
||||
>
|
||||
<div class="flex space-x-2">
|
||||
<div class="grow">
|
||||
<.password_field field={f[:secret_key]} label="Secret key" />
|
||||
</div>
|
||||
<div class="mt-6">
|
||||
<span class="tooltip top" data-tooltip="Generate">
|
||||
<button
|
||||
class="button-base button-blue"
|
||||
type="submit"
|
||||
phx-disable-with="Updating..."
|
||||
disabled={not @changeset.valid?}
|
||||
class="button-base button-outlined-gray button-square-icon"
|
||||
type="button"
|
||||
phx-click="generate_secret_key"
|
||||
phx-target={@myself}
|
||||
>
|
||||
Save
|
||||
<.remix_icon icon="refresh-line" class="text-xl" />
|
||||
</button>
|
||||
</div>
|
||||
</.form>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col space-y-4">
|
||||
<h2 class="text-xl text-gray-800 font-medium pb-2 border-b border-gray-200">
|
||||
Secrets
|
||||
</h2>
|
||||
|
||||
<p class="text-gray-700">
|
||||
Secrets are a safe way to share credentials and tokens with notebooks.
|
||||
They are often shared with Smart cells and can be read as
|
||||
environment variables using the <code>LB_</code> prefix.
|
||||
</p>
|
||||
|
||||
<.live_component
|
||||
module={LivebookWeb.Hub.SecretListComponent}
|
||||
id="hub-secrets-list"
|
||||
hub={@hub}
|
||||
secrets={@secrets}
|
||||
target={@myself}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col space-y-4">
|
||||
<h2 class="text-xl text-gray-800 font-medium pb-2 border-b border-gray-200">
|
||||
Stamping
|
||||
</h2>
|
||||
|
||||
<p class="text-gray-700">
|
||||
Notebooks may be stamped using your <span class="font-medium text-gray-800">secret key</span>.
|
||||
A stamp allows to securely store information such as the names of the secrets that you granted access to.
|
||||
You must not share your secret key with others. But you may copy the secret key between
|
||||
different machines you own.
|
||||
</p>
|
||||
<p class="text-gray-700">
|
||||
If you change the <span class="font-medium text-gray-800">secret key</span>, you will need
|
||||
to grant access to secrets once again in previously stamped notebooks.
|
||||
</p>
|
||||
|
||||
<.form
|
||||
:let={f}
|
||||
id={"#{@id}-stamp"}
|
||||
class="flex flex-col mt-4 space-y-4"
|
||||
for={@stamp_changeset}
|
||||
phx-submit="stamp_save"
|
||||
phx-change="stamp_validate"
|
||||
phx-target={@myself}
|
||||
<div>
|
||||
<button
|
||||
class="button-base button-blue"
|
||||
type="submit"
|
||||
phx-disable-with="Updating..."
|
||||
disabled={not @stamp_changeset.valid?}
|
||||
>
|
||||
<div class="flex space-x-2">
|
||||
<div class="grow">
|
||||
<.password_field field={f[:secret_key]} label="Secret key" />
|
||||
</div>
|
||||
<div class="mt-6">
|
||||
<span class="tooltip top" data-tooltip="Generate">
|
||||
<button
|
||||
class="button-base button-outlined-gray button-square-icon"
|
||||
type="button"
|
||||
phx-click="generate_secret_key"
|
||||
phx-target={@myself}
|
||||
>
|
||||
<.remix_icon icon="refresh-line" class="text-xl" />
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
class="button-base button-blue"
|
||||
type="submit"
|
||||
phx-disable-with="Updating..."
|
||||
disabled={not @stamp_changeset.valid?}
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</.form>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</.form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<.modal
|
||||
:if={@live_action in [:new_secret, :edit_secret]}
|
||||
id="secrets-modal"
|
||||
show
|
||||
width={:medium}
|
||||
patch={~p"/hub/#{@hub.id}"}
|
||||
>
|
||||
<.live_component
|
||||
module={LivebookWeb.Hub.SecretFormComponent}
|
||||
id="secrets"
|
||||
hub={@hub}
|
||||
secret_name={@secret_name}
|
||||
secret_value={@secret_value}
|
||||
return_to={~p"/hub/#{@hub.id}"}
|
||||
/>
|
||||
</.modal>
|
||||
</div>
|
||||
|
||||
<.modal
|
||||
:if={@live_action in [:new_secret, :edit_secret]}
|
||||
id="secrets-modal"
|
||||
show
|
||||
width={:medium}
|
||||
patch={~p"/hub/#{@hub.id}"}
|
||||
>
|
||||
<.live_component
|
||||
module={LivebookWeb.Hub.SecretFormComponent}
|
||||
id="secrets"
|
||||
hub={@hub}
|
||||
secret_name={@secret_name}
|
||||
secret_value={@secret_value}
|
||||
return_to={~p"/hub/#{@hub.id}"}
|
||||
/>
|
||||
</.modal>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
|
|
|||
|
|
@ -43,189 +43,191 @@ defmodule LivebookWeb.Hub.Edit.TeamComponent do
|
|||
|
||||
<div class="p-4 md:px-12 md:py-7 max-w-screen-md mx-auto">
|
||||
<div id={"#{@id}-component"}>
|
||||
<div class="mb-8 flex flex-col space-y-8">
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex items-center justify-between">
|
||||
<LayoutHelpers.title>
|
||||
<div class="flex gap-2">
|
||||
<div class="flex justify-center">
|
||||
<span class="relative">
|
||||
<%= @hub.hub_emoji %>
|
||||
<div class="mb-8 flex flex-col space-y-10">
|
||||
<div class="flex flex-col space-y-2">
|
||||
<LayoutHelpers.title>
|
||||
<div class="flex gap-2 items-center">
|
||||
<div class="flex justify-center">
|
||||
<span class="relative">
|
||||
<%= @hub.hub_emoji %>
|
||||
|
||||
<div class={[
|
||||
"absolute w-[10px] h-[10px] border-gray-900 border-2 rounded-full right-0 bottom-1",
|
||||
if(@hub_metadata.connected?, do: "bg-green-400", else: "bg-red-400")
|
||||
]} />
|
||||
</span>
|
||||
</div>
|
||||
<%= @hub.hub_name %>
|
||||
<div class={[
|
||||
"absolute w-[10px] h-[10px] border-white border-2 rounded-full right-0 bottom-1",
|
||||
if(@hub_metadata.connected?, do: "bg-green-400", else: "bg-red-400")
|
||||
]} />
|
||||
</span>
|
||||
</div>
|
||||
</LayoutHelpers.title>
|
||||
|
||||
<div class="flex justify-end gap-2">
|
||||
<button
|
||||
phx-click={show_modal("show-key-modal")}
|
||||
phx-target={@myself}
|
||||
class="button-base button-outlined-gray"
|
||||
>
|
||||
<span class="hidden sm:block">Teams key</span>
|
||||
<.remix_icon icon="key-2-fill" class="text-xl sm:hidden" />
|
||||
</button>
|
||||
<%= @hub.hub_name %>
|
||||
<span class="bg-green-100 text-green-800 text-xs px-2.5 py-0.5 rounded cursor-default">
|
||||
Livebook Teams
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</LayoutHelpers.title>
|
||||
|
||||
<div>
|
||||
<p class="text-gray-700">
|
||||
A shared Teams hub. All resources here are shared with your team. Manage users and billing on livebook.dev.
|
||||
<p class="text-sm flex flex-row space-x-6 text-gray-700">
|
||||
<a href={org_url(@hub, "/")} class="hover:text-blue-600">
|
||||
<.remix_icon icon="mail-line" /> Invite users
|
||||
</a>
|
||||
|
||||
<a href={org_url(@hub, "/")} class="hover:text-blue-600">
|
||||
<.remix_icon icon="settings-line" /> Manage organization
|
||||
</a>
|
||||
|
||||
<a
|
||||
phx-click={show_modal("show-key-modal")}
|
||||
phx-target={@myself}
|
||||
class="hover:text-blue-600 cursor-pointer"
|
||||
>
|
||||
<.remix_icon icon="key-2-fill" /> Display Teams key
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col space-y-10">
|
||||
<div class="flex flex-col space-y-2">
|
||||
<h2 class="text-xl text-gray-800 font-medium pb-2 border-b border-gray-200">
|
||||
General
|
||||
</h2>
|
||||
<div class="flex flex-col space-y-4">
|
||||
<h2 class="text-xl text-gray-800 font-medium pb-2 border-b border-gray-200">
|
||||
General
|
||||
</h2>
|
||||
|
||||
<.form
|
||||
:let={f}
|
||||
id={@id}
|
||||
class="flex flex-col mt-4 space-y-4"
|
||||
for={@form}
|
||||
phx-submit="save"
|
||||
phx-change="validate"
|
||||
phx-target={@myself}
|
||||
>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-3 mt-2">
|
||||
<.text_field
|
||||
field={f[:hub_name]}
|
||||
label="Name"
|
||||
disabled
|
||||
help="Name cannot be changed"
|
||||
class="bg-gray-200/50 border-200/80 cursor-not-allowed"
|
||||
/>
|
||||
<.emoji_field field={f[:hub_emoji]} label="Emoji" />
|
||||
</div>
|
||||
<.form
|
||||
:let={f}
|
||||
id={@id}
|
||||
class="flex flex-col mt-4 space-y-4"
|
||||
for={@form}
|
||||
phx-submit="save"
|
||||
phx-change="validate"
|
||||
phx-target={@myself}
|
||||
>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||
<.text_field
|
||||
field={f[:hub_name]}
|
||||
label="Name"
|
||||
disabled
|
||||
help="Name cannot be changed"
|
||||
class="bg-gray-200/50 border-200/80 cursor-not-allowed"
|
||||
/>
|
||||
<.emoji_field field={f[:hub_emoji]} label="Emoji" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button
|
||||
class="button-base button-blue"
|
||||
type="submit"
|
||||
phx-disable-with="Updating..."
|
||||
>
|
||||
Update Hub
|
||||
</button>
|
||||
</div>
|
||||
</.form>
|
||||
</div>
|
||||
<div>
|
||||
<button class="button-base button-blue" type="submit" phx-disable-with="Updating...">
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</.form>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col space-y-4">
|
||||
<h2 class="text-xl text-gray-800 font-medium pb-2 border-b border-gray-200">
|
||||
Secrets
|
||||
</h2>
|
||||
<div class="flex flex-col space-y-4">
|
||||
<h2 class="text-xl text-gray-800 font-medium pb-2 border-b border-gray-200">
|
||||
Secrets
|
||||
</h2>
|
||||
|
||||
<p class="text-gray-700">
|
||||
Secrets are a safe way to share credentials and tokens with notebooks.
|
||||
They are often shared with Smart cells and can be read as
|
||||
environment variables using the <code>LB_</code> prefix.
|
||||
</p>
|
||||
<p class="text-gray-700">
|
||||
Secrets are a safe way to share credentials and tokens with notebooks.
|
||||
They are often used by Smart cells and can be read as
|
||||
environment variables using the <code>LB_</code> prefix.
|
||||
</p>
|
||||
|
||||
<.live_component
|
||||
module={LivebookWeb.Hub.SecretListComponent}
|
||||
id="hub-secrets-list"
|
||||
hub={@hub}
|
||||
secrets={@secrets}
|
||||
target={@myself}
|
||||
<.live_component
|
||||
module={LivebookWeb.Hub.SecretListComponent}
|
||||
id="hub-secrets-list"
|
||||
hub={@hub}
|
||||
secrets={@secrets}
|
||||
target={@myself}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col space-y-4">
|
||||
<h2 class="text-xl text-gray-800 font-medium pb-2 border-b border-gray-200">
|
||||
Airgapped Deployment
|
||||
</h2>
|
||||
|
||||
<p class="text-gray-700">
|
||||
It is possible to deploy notebooks that belong to this Hub in an airgapped
|
||||
deployment, without connecting back to Livebook Teams server. This is done
|
||||
using the Docker image template below, which encrypts all of your Hub metadata,
|
||||
and taking some additional steps.
|
||||
</p>
|
||||
|
||||
<div id="env-code">
|
||||
<div class="flex justify-between items-end">
|
||||
<span class="text-sm text-gray-700 font-semibold">Dockerfile</span>
|
||||
<button
|
||||
class="button-base button-gray whitespace-nowrap py-1 px-2"
|
||||
data-copy
|
||||
data-tooltip="Copied to clipboard"
|
||||
type="button"
|
||||
aria-label="copy to clipboard"
|
||||
phx-click={
|
||||
JS.dispatch("lb:clipcopy", to: "#offline-deployment-#{@hub.id}-source")
|
||||
|> JS.add_class(
|
||||
"tooltip top",
|
||||
to: "#env-code [data-copy]",
|
||||
transition: {"ease-out duration-200", "opacity-0", "opacity-100"}
|
||||
)
|
||||
|> JS.remove_class(
|
||||
"tooltip top",
|
||||
to: "#env-code [data-copy]",
|
||||
transition: {"ease-out duration-200", "opacity-0", "opacity-100"},
|
||||
time: 2000
|
||||
)
|
||||
}
|
||||
>
|
||||
<.remix_icon icon="clipboard-line" class="align-middle mr-1 text-xs" />
|
||||
<span class="font-normal text-xs">Copy source</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<.code_preview
|
||||
source_id={"offline-deployment-#{@hub.id}-source"}
|
||||
source={@dockerfile}
|
||||
language="dockerfile"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col space-y-4">
|
||||
<h2 class="text-xl text-gray-800 font-medium pb-2 border-b border-gray-200">
|
||||
Airgapped Deployment
|
||||
</h2>
|
||||
<p class="text-gray-700 py-2">
|
||||
Before deployment, you must perform the following manual steps:
|
||||
</p>
|
||||
|
||||
<p class="text-gray-700">
|
||||
It is possible to deploy notebooks that belong to this Hub in an airgapped
|
||||
deployment, without connecting back to Livebook Teams server. This is done
|
||||
using the Docker image template below, which encrypts all of your Hub metadata,
|
||||
and taking some additional steps.
|
||||
</p>
|
||||
<ol class="text-gray-700 space-y-3 list-disc list-inside">
|
||||
<li>
|
||||
You must change <code>/path/to/my/notebooks</code> in the template above
|
||||
to point to a directory with the <code>.livemd</code> files you want to deploy
|
||||
</li>
|
||||
<li>
|
||||
You must set the <code>LIVEBOOK_TEAMS_KEY</code> environment variable
|
||||
directly on your deployment platform, with the value you can find at the
|
||||
top of this page
|
||||
</li>
|
||||
<li>
|
||||
You may set the <code>LIVEBOOK_PASSWORD</code> environment variable to any
|
||||
value of your choice, if you want to access and debug your deployed notebooks
|
||||
in production
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<div id="env-code">
|
||||
<div class="flex justify-between items-end mb-1">
|
||||
<span class="text-sm text-gray-700 font-semibold"> Dockerfile </span>
|
||||
<button
|
||||
class="button-base button-gray whitespace-nowrap py-1 px-2"
|
||||
data-copy
|
||||
data-tooltip="Copied to clipboard"
|
||||
type="button"
|
||||
aria-label="copy to clipboard"
|
||||
phx-click={
|
||||
JS.dispatch("lb:clipcopy", to: "#offline-deployment-#{@hub.id}-source")
|
||||
|> JS.add_class(
|
||||
"tooltip top",
|
||||
to: "#env-code [data-copy]",
|
||||
transition: {"ease-out duration-200", "opacity-0", "opacity-100"}
|
||||
)
|
||||
|> JS.remove_class(
|
||||
"tooltip top",
|
||||
to: "#env-code [data-copy]",
|
||||
transition: {"ease-out duration-200", "opacity-0", "opacity-100"},
|
||||
time: 2000
|
||||
)
|
||||
}
|
||||
>
|
||||
<.remix_icon icon="clipboard-line" class="align-middle mr-1 text-xs" />
|
||||
<span class="font-normal text-xs">Copy source</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex flex-col space-y-4">
|
||||
<h2 class="text-xl text-gray-800 font-medium pb-2 border-b border-gray-200">
|
||||
Danger Zone
|
||||
</h2>
|
||||
|
||||
<.code_preview
|
||||
source_id={"offline-deployment-#{@hub.id}-source"}
|
||||
source={@dockerfile}
|
||||
language="dockerfile"
|
||||
/>
|
||||
|
||||
<ol class="text-gray-700 mt-4 space-y-2 list-disc list-inside">
|
||||
<li>
|
||||
You must change <code>/path/to/my/notebooks</code> in the template above
|
||||
to point to a directory with the `.livemd` files you want to deploy
|
||||
</li>
|
||||
<li>
|
||||
You must set the <code>LIVEBOOK_TEAMS_KEY</code> environment variable
|
||||
directly on your deployment platform, with the value you can find at the
|
||||
top of this page
|
||||
</li>
|
||||
<li>
|
||||
You may set the <code>LIVEBOOK_PASSWORD</code> environment variable to any
|
||||
value of your choice, if you want to access and debug your deployed notebooks
|
||||
in production
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col space-y-4">
|
||||
<h2 class="text-xl text-gray-800 font-medium pb-2 border-b border-gray-200">
|
||||
Danger Zone
|
||||
</h2>
|
||||
|
||||
<div class="flex items-center justify-between gap-4 text-gray-700">
|
||||
<div class="flex flex-col">
|
||||
<h3 class="font-semibold">
|
||||
Delete this hub
|
||||
</h3>
|
||||
<p>Once deleted, you won’t be able to access its features unless you rejoin.</p>
|
||||
</div>
|
||||
<button
|
||||
id="delete-hub"
|
||||
phx-click={JS.push("delete_hub", value: %{id: @hub.id})}
|
||||
class="button-base button-outlined-red"
|
||||
>
|
||||
<span class="hidden sm:block">Delete hub</span>
|
||||
<.remix_icon icon="delete-bin-line" class="text-lg sm:hidden" />
|
||||
</button>
|
||||
<div class="flex items-center justify-between gap-4 text-gray-700">
|
||||
<div class="flex flex-col">
|
||||
<h3 class="font-semibold">
|
||||
Delete this hub
|
||||
</h3>
|
||||
<p class="text-sm">
|
||||
This only removes the hub from this machine. You must rejoin to access its features once again.
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
id="delete-hub"
|
||||
phx-click={JS.push("delete_hub", value: %{id: @hub.id})}
|
||||
class="button-base button-outlined-red"
|
||||
>
|
||||
<span class="hidden sm:block">Delete hub</span>
|
||||
<.remix_icon icon="delete-bin-line" class="text-lg sm:hidden" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -256,6 +258,10 @@ defmodule LivebookWeb.Hub.Edit.TeamComponent do
|
|||
"""
|
||||
end
|
||||
|
||||
defp org_url(hub, path) do
|
||||
Livebook.Config.teams_url() <> "/orgs/#{hub.org_id}" <> path
|
||||
end
|
||||
|
||||
defp teams_key_modal(assigns) do
|
||||
~H"""
|
||||
<div class="p-6 flex flex-col space-y-5">
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue