| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- import { TextAttributes } from "@opentui/core"
- import { useTheme } from "../context/theme"
- import { useSync } from "@tui/context/sync"
- import { For, Match, Switch, Show, createMemo } from "solid-js"
- export type DialogStatusProps = {}
- export function DialogStatus() {
- const sync = useSync()
- const { theme } = useTheme()
- const enabledFormatters = createMemo(() => sync.data.formatter.filter((f) => f.enabled))
- return (
- <box paddingLeft={2} paddingRight={2} gap={1} paddingBottom={1}>
- <box flexDirection="row" justifyContent="space-between">
- <text fg={theme.text} attributes={TextAttributes.BOLD}>
- Status
- </text>
- <text fg={theme.textMuted}>esc</text>
- </box>
- <Show when={Object.keys(sync.data.mcp).length > 0} fallback={<text fg={theme.text}>No MCP Servers</text>}>
- <box>
- <text fg={theme.text}>{Object.keys(sync.data.mcp).length} MCP Servers</text>
- <For each={Object.entries(sync.data.mcp)}>
- {([key, item]) => (
- <box flexDirection="row" gap={1}>
- <text
- flexShrink={0}
- style={{
- fg: (
- {
- connected: theme.success,
- failed: theme.error,
- disabled: theme.textMuted,
- needs_auth: theme.warning,
- needs_client_registration: theme.error,
- } as Record<string, typeof theme.success>
- )[item.status],
- }}
- >
- •
- </text>
- <text fg={theme.text} wrapMode="word">
- <b>{key}</b>{" "}
- <span style={{ fg: theme.textMuted }}>
- <Switch fallback={item.status}>
- <Match when={item.status === "connected"}>Connected</Match>
- <Match when={item.status === "failed" && item}>{(val) => val().error}</Match>
- <Match when={item.status === "disabled"}>Disabled in configuration</Match>
- <Match when={(item.status as string) === "needs_auth"}>
- Needs authentication (run: opencode mcp auth {key})
- </Match>
- <Match when={(item.status as string) === "needs_client_registration" && item}>
- {(val) => (val() as { error: string }).error}
- </Match>
- </Switch>
- </span>
- </text>
- </box>
- )}
- </For>
- </box>
- </Show>
- {sync.data.lsp.length > 0 && (
- <box>
- <text fg={theme.text}>{sync.data.lsp.length} LSP Servers</text>
- <For each={sync.data.lsp}>
- {(item) => (
- <box flexDirection="row" gap={1}>
- <text
- flexShrink={0}
- style={{
- fg: {
- connected: theme.success,
- error: theme.error,
- }[item.status],
- }}
- >
- •
- </text>
- <text fg={theme.text} wrapMode="word">
- <b>{item.id}</b> <span style={{ fg: theme.textMuted }}>{item.root}</span>
- </text>
- </box>
- )}
- </For>
- </box>
- )}
- <Show when={enabledFormatters().length > 0} fallback={<text fg={theme.text}>No Formatters</text>}>
- <box>
- <text fg={theme.text}>{enabledFormatters().length} Formatters</text>
- <For each={enabledFormatters()}>
- {(item) => (
- <box flexDirection="row" gap={1}>
- <text
- flexShrink={0}
- style={{
- fg: theme.success,
- }}
- >
- •
- </text>
- <text wrapMode="word" fg={theme.text}>
- <b>{item.name}</b>
- </text>
- </box>
- )}
- </For>
- </box>
- </Show>
- </box>
- )
- }
|