Buckets:
| import { ButtonV2 } from "@opencode-ai/ui/v2/button-v2" | |
| import { Tag } from "@opencode-ai/ui/v2/badge-v2" | |
| import { Icon as IconV2 } from "@opencode-ai/ui/v2/icon" | |
| import { IconButtonV2 } from "@opencode-ai/ui/v2/icon-button-v2" | |
| import { TextInputV2 } from "@opencode-ai/ui/v2/text-input-v2" | |
| import { useDialog } from "@opencode-ai/ui/context/dialog" | |
| import fuzzysort from "fuzzysort" | |
| import { type Component, For, Show, createMemo } from "solid-js" | |
| import { createStore } from "solid-js/store" | |
| import { ServerRowMenu } from "@/components/server/server-row-menu" | |
| import { ServerHealthIndicator } from "@/components/server/server-row" | |
| import { useLanguage } from "@/context/language" | |
| import { ServerConnection, serverName } from "@/context/server" | |
| import { useServerManagementController } from "../dialog-select-server" | |
| import { DialogServerV2 } from "./dialog-server-v2" | |
| import { SettingsListV2 } from "./parts/list" | |
| import { isWslServer, useFilteredWslServers, WslAddServerButton, WslServerSettings } from "@/wsl/settings" | |
| import "./settings-v2.css" | |
| export const SettingsServersV2: Component = () => { | |
| const dialog = useDialog() | |
| const language = useLanguage() | |
| const controller = useServerManagementController() | |
| const [store, setStore] = createStore({ filter: "" }) | |
| const wslServers = useFilteredWslServers(() => store.filter) | |
| const showSearch = createMemo( | |
| () => controller.sortedItems().filter((item) => !isWslServer(item)).length + wslServers().length > 1, | |
| ) | |
| const filtered = createMemo(() => { | |
| const items = controller.sortedItems().filter((item) => !isWslServer(item)) | |
| const query = store.filter.trim() | |
| if (!query) return items | |
| return fuzzysort | |
| .go(query, items, { | |
| keys: [(item) => serverName(item), (item) => item.http.url], | |
| }) | |
| .map((result) => result.obj) | |
| }) | |
| const openAdd = () => { | |
| dialog.push(() => <DialogServerV2 mode="add" />) | |
| } | |
| const openEdit = (server: ServerConnection.Http) => { | |
| dialog.push(() => <DialogServerV2 mode="edit" server={server} />) | |
| } | |
| return ( | |
| <> | |
| <div | |
| class="settings-v2-tab-header settings-v2-servers-header" | |
| classList={{ "settings-v2-tab-header--stacked": showSearch() }} | |
| > | |
| <div class="settings-v2-tab-header-row"> | |
| <h2 class="settings-v2-tab-title">{language.t("status.popover.tab.servers")}</h2> | |
| <ButtonV2 variant="ghost-muted" icon="plus" onClick={openAdd}> | |
| {language.t("dialog.server.add.button")} | |
| </ButtonV2> | |
| <WslAddServerButton /> | |
| </div> | |
| <Show when={showSearch()}> | |
| <div class="settings-v2-tab-search"> | |
| <TextInputV2 | |
| type="search" | |
| appearance="base" | |
| value={store.filter} | |
| onInput={(event) => setStore("filter", event.currentTarget.value)} | |
| placeholder={language.t("dialog.server.search.placeholder")} | |
| spellcheck={false} | |
| autocorrect="off" | |
| autocomplete="off" | |
| autocapitalize="off" | |
| aria-label={language.t("dialog.server.search.placeholder")} | |
| /> | |
| <Show when={store.filter}> | |
| <IconButtonV2 | |
| type="button" | |
| variant="ghost-muted" | |
| size="small" | |
| class="settings-v2-tab-search-clear" | |
| icon={<IconV2 name="close" size="large" class="text-v2-icon-icon-muted" />} | |
| onClick={() => setStore("filter", "")} | |
| /> | |
| </Show> | |
| </div> | |
| </Show> | |
| </div> | |
| <div class="settings-v2-tab-body settings-v2-servers"> | |
| <Show | |
| when={filtered().length > 0 || wslServers().length > 0} | |
| fallback={ | |
| <div class="settings-v2-servers-status"> | |
| <span>{store.filter ? language.t("palette.empty") : language.t("dialog.server.empty")}</span> | |
| <Show when={store.filter}> | |
| <span class="settings-v2-servers-status-filter">"{store.filter}"</span> | |
| </Show> | |
| </div> | |
| } | |
| > | |
| <SettingsListV2> | |
| <WslServerSettings controller={controller} servers={wslServers} /> | |
| <For each={filtered()}> | |
| {(item) => { | |
| const key = ServerConnection.key(item) | |
| const health = () => controller.status()[key] | |
| const isDefault = () => controller.defaultKey() === key | |
| return ( | |
| <div class="settings-v2-servers-row"> | |
| <div class="settings-v2-servers-lead"> | |
| <ServerHealthIndicator health={health()} /> | |
| <div class="settings-v2-servers-copy"> | |
| <span class="settings-v2-servers-name">{serverName(item)}</span> | |
| <span class="settings-v2-servers-meta"> | |
| <Show when={health()?.version}>v{health()?.version}</Show> | |
| <Show when={health()?.version && item.type === "http"}> • </Show> | |
| <Show | |
| when={item.type === "http" && item.http.username} | |
| fallback={<Show when={item.type === "http"}>{language.t("server.row.noUsername")}</Show>} | |
| > | |
| {item.http.username} | |
| </Show> | |
| </span> | |
| </div> | |
| </div> | |
| <div class="settings-v2-servers-actions"> | |
| <Show when={controller.canDefault() && isDefault()}> | |
| <Tag>{language.t("dialog.server.status.default")}</Tag> | |
| </Show> | |
| <ServerRowMenu server={item} controller={controller} onEdit={openEdit} /> | |
| </div> | |
| </div> | |
| ) | |
| }} | |
| </For> | |
| </SettingsListV2> | |
| </Show> | |
| </div> | |
| </> | |
| ) | |
| } | |
Xet Storage Details
- Size:
- 6.02 kB
- Xet hash:
- 414f17714f3e6177e4d22cabda2ee2b599cfae1dfa15f2aeceb473482540ff5c
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.