import { useDialog } from "@opencode-ai/ui/context/dialog" import { Tag } from "@opencode-ai/ui/v2/badge-v2" import { ButtonV2 } from "@opencode-ai/ui/v2/button-v2" import { Icon as IconV2 } from "@opencode-ai/ui/v2/icon" import { IconButtonV2 } from "@opencode-ai/ui/v2/icon-button-v2" import { MenuV2 } from "@opencode-ai/ui/v2/menu-v2" import { useMutation } from "@tanstack/solid-query" import fuzzysort from "fuzzysort" import { type Accessor, For, Show, createMemo } from "solid-js" import type { useServerManagementController } from "@/components/dialog-select-server" import { ServerHealthIndicator } from "@/components/server/server-row" import { useLanguage } from "@/context/language" import { usePlatform } from "@/context/platform" import { ServerConnection } from "@/context/server" import { showToast } from "@/utils/toast" import { DialogAddWslServer } from "./dialog-add-server" import { useWslServers } from "./context" import { wslOpencodeAction, wslRuntimeRetryable } from "./settings-model" type Controller = ReturnType export function isWslServer(server: ServerConnection.Any) { return server.type === "sidecar" && server.variant === "wsl" } export function AddServerMenu(props: { onAddServer: () => void }) { const platform = usePlatform() const dialog = useDialog() const language = useLanguage() const openAddWsl = () => { dialog.push(() => ) } return ( {language.t("dialog.server.add.button")} } > {language.t("dialog.server.add.button")} {language.t("dialog.server.add.button")} {language.t("wsl.server.add")} ) } export function useFilteredWslServers(filter: Accessor) { const wsl = useWslServers() return createMemo(() => { const servers = wsl.data?.servers ?? [] const query = filter().trim() if (!query) return servers return fuzzysort .go(query, servers, { keys: [(item) => item.config.distro, (item) => item.config.id] }) .map((x) => x.obj) }) } export function WslServerSettings(props: { controller: Controller servers: ReturnType }) { const platform = usePlatform() const language = useLanguage() const wsl = useWslServers() const api = platform.wslServers const request = useMutation(() => ({ mutationFn: (action: () => Promise) => action(), onError: (error) => showToast({ variant: "error", title: language.t("common.requestFailed"), description: error instanceof Error ? error.message : String(error), }), })) const remove = (key: ServerConnection.Key) => { request.mutate(() => props.controller.handleRemove(key)) } return ( {(item) => { const key = ServerConnection.Key.make(item.config.id) const check = () => wsl.data?.opencodeChecks[item.config.distro] const opencodeAction = () => wslOpencodeAction(check()) const busy = () => wsl.data?.job?.kind === "install-opencode" && wsl.data.job.distro === item.config.distro return (
{item.config.distro} {language.t("wsl.server.label")} {(version) => `v${version()}`}
{language.t("dialog.server.status.default")} {(label) => ( api && request.mutate(() => api.installOpencode(item.config.distro))} > {busy() ? language.t("wsl.server.updating") : label()} )} } aria-label={language.t("common.moreOptions")} /> {language.t("wsl.server.menu.label")} api && request.mutate(() => api.startServer(key))}> {language.t("wsl.server.retryStart")} props.controller.setDefault(key)}> {language.t("dialog.server.menu.default")} props.controller.setDefault(null)}> {language.t("dialog.server.menu.defaultRemove")} remove(key)}> {language.t("dialog.server.menu.delete")}
) }}
) }