summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/components/server
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-02-06 10:02:31 -0600
committerGitHub <[email protected]>2026-02-06 10:02:31 -0600
commit2c58dd6203df7806f57ef6b29672091cb764e871 (patch)
tree10fca96d3098465b497f78e29de8d0a585c4dac3 /packages/app/src/components/server
parenta4bc883595df9ea0f752079519081bc602408553 (diff)
downloadopencode-2c58dd6203df7806f57ef6b29672091cb764e871.tar.gz
opencode-2c58dd6203df7806f57ef6b29672091cb764e871.zip
chore: refactoring and tests, splitting up files (#12495)
Diffstat (limited to 'packages/app/src/components/server')
-rw-r--r--packages/app/src/components/server/server-row.tsx77
1 files changed, 77 insertions, 0 deletions
diff --git a/packages/app/src/components/server/server-row.tsx b/packages/app/src/components/server/server-row.tsx
new file mode 100644
index 000000000..b43c07882
--- /dev/null
+++ b/packages/app/src/components/server/server-row.tsx
@@ -0,0 +1,77 @@
+import { Tooltip } from "@opencode-ai/ui/tooltip"
+import { JSXElement, ParentProps, Show, createEffect, createSignal, onCleanup, onMount } from "solid-js"
+import { serverDisplayName } from "@/context/server"
+import type { ServerHealth } from "@/utils/server-health"
+
+interface ServerRowProps extends ParentProps {
+ url: string
+ status?: ServerHealth
+ class?: string
+ nameClass?: string
+ versionClass?: string
+ dimmed?: boolean
+ badge?: JSXElement
+}
+
+export function ServerRow(props: ServerRowProps) {
+ const [truncated, setTruncated] = createSignal(false)
+ let nameRef: HTMLSpanElement | undefined
+ let versionRef: HTMLSpanElement | undefined
+
+ const check = () => {
+ const nameTruncated = nameRef ? nameRef.scrollWidth > nameRef.clientWidth : false
+ const versionTruncated = versionRef ? versionRef.scrollWidth > versionRef.clientWidth : false
+ setTruncated(nameTruncated || versionTruncated)
+ }
+
+ createEffect(() => {
+ props.url
+ props.status?.version
+ if (typeof requestAnimationFrame === "function") {
+ requestAnimationFrame(check)
+ return
+ }
+ check()
+ })
+
+ onMount(() => {
+ check()
+ if (typeof window === "undefined") return
+ window.addEventListener("resize", check)
+ onCleanup(() => window.removeEventListener("resize", check))
+ })
+
+ const tooltipValue = () => (
+ <span class="flex items-center gap-2">
+ <span>{serverDisplayName(props.url)}</span>
+ <Show when={props.status?.version}>
+ <span class="text-text-invert-base">{props.status?.version}</span>
+ </Show>
+ </span>
+ )
+
+ return (
+ <Tooltip value={tooltipValue()} placement="top" inactive={!truncated()}>
+ <div class={props.class} classList={{ "opacity-50": props.dimmed }}>
+ <div
+ classList={{
+ "size-1.5 rounded-full shrink-0": true,
+ "bg-icon-success-base": props.status?.healthy === true,
+ "bg-icon-critical-base": props.status?.healthy === false,
+ "bg-border-weak-base": props.status === undefined,
+ }}
+ />
+ <span ref={nameRef} class={props.nameClass ?? "truncate"}>
+ {serverDisplayName(props.url)}
+ </span>
+ <Show when={props.status?.version}>
+ <span ref={versionRef} class={props.versionClass ?? "text-text-weak text-14-regular truncate"}>
+ {props.status?.version}
+ </span>
+ </Show>
+ {props.badge}
+ {props.children}
+ </div>
+ </Tooltip>
+ )
+}