import { useMemo, useState } from "react"; import { Link } from "react-router"; import { ChevronDownIcon } from "@heroicons/react/16/solid"; import { ComputerDesktopIcon } from "@heroicons/react/24/outline"; import type { ServerSandboxProvidersSettings } from "@qltysh/fabro-api-client"; import { useServerSettings } from "../lib/queries"; import { Dot, Panel, PanelSkeleton, Row, SettingsPageIntro, } from "../components/settings-panel"; import { plural } from "../lib/plural"; export function meta() { return [{ title: "Sandboxes — Fabro" }]; } type SandboxProviderId = "local" | "docker" | "daytona"; type SandboxProvider = { id: SandboxProviderId; name: string; description: string; enabled: boolean; secretName?: string; }; const DESCRIPTION = "Runtime environments where workflow stages execute. Configured via settings.toml."; export default function SettingsSandboxes() { const query = useServerSettings(); const settings = query.data; return (
{settings ? : }
); } function ProvidersPanel({ settings }: { settings: ServerSandboxProvidersSettings }) { const providers: SandboxProvider[] = useMemo( () => [ { id: "local", name: "Local", description: "Run stages directly on the Fabro host.", enabled: settings.local.enabled, }, { id: "docker", name: "Docker", description: "Run stages in isolated Docker containers on the host daemon.", enabled: settings.docker.enabled, }, { id: "daytona", name: "Daytona", description: "Run stages in cloud sandboxes managed by Daytona.", enabled: settings.daytona.enabled, secretName: "DAYTONA_API_KEY", }, ], [settings], ); const { enabled, disabled } = useMemo(() => { const enabled: SandboxProvider[] = []; const disabled: SandboxProvider[] = []; for (const provider of providers) { if (provider.enabled) { enabled.push(provider); } else { disabled.push(provider); } } return { enabled, disabled }; }, [providers]); const [showDisabled, setShowDisabled] = useState(false); const showDisabledRows = enabled.length === 0 || showDisabled; return ( {enabled.map((provider) => ( ))} {showDisabledRows ? disabled.map((provider) => ( )) : null} {enabled.length > 0 && disabled.length > 0 ? ( ) : null} ); } function ProviderRow({ provider }: { provider: SandboxProvider }) { return ( {provider.name} {provider.description} } > ); } function ProviderLogo({ provider }: { provider: SandboxProvider }) { const [failed, setFailed] = useState(false); const chip = "grid size-10 shrink-0 place-items-center rounded-md bg-ice-50 ring-1 ring-line-strong"; const dim = provider.enabled ? "" : "opacity-60"; if (provider.id === "local") { return ( ); } if (failed) { return ( {provider.name.charAt(0)} ); } return ( setFailed(true)} className="size-7" /> ); } function ProviderStatus({ provider }: { provider: SandboxProvider }) { return ( {provider.enabled ? "Enabled" : "Disabled"} {!provider.enabled && provider.secretName ? ( Add secret → ) : null} ); }