Introduit SmallDropdown comme composant partagé et le fait adopter par AgentsPanel, ModelServerSelect, OpenCodeModeFields, TemplateEditor et TicketViewportSelect, pour que toutes les listes déroulantes dynamiques (agent, modèle, template, viewport) partagent la même apparence que le sélecteur d'agent de la création de ticket. Refs #114 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
54 lines
1.7 KiB
TypeScript
54 lines
1.7 KiB
TypeScript
/**
|
|
* `ModelServerSelect` (F35.2) — a dropdown to bind an OpenCode profile to one of
|
|
* the declared local model servers, or to none ("external endpoint"). Replaces
|
|
* the free-text `localModelServerId` input posed in F36. Presentational: the
|
|
* server list and the current value are passed in.
|
|
*/
|
|
|
|
import type { LocalModelServerConfig } from "@/domain";
|
|
import { SmallDropdown } from "@/shared";
|
|
|
|
/** The sentinel option value standing for "no managed server". */
|
|
const NONE = "";
|
|
|
|
export interface ModelServerSelectProps {
|
|
/** The declared servers to choose from. */
|
|
servers: LocalModelServerConfig[];
|
|
/** The currently-bound server id, or `undefined` for none. */
|
|
value?: string;
|
|
/** Called with the new server id, or `undefined` when "none" is chosen. */
|
|
onChange: (serverId: string | undefined) => void;
|
|
/** Accessible label (defaults to a generic one). */
|
|
ariaLabel?: string;
|
|
}
|
|
|
|
export function ModelServerSelect({
|
|
servers,
|
|
value,
|
|
onChange,
|
|
ariaLabel = "local model server",
|
|
}: ModelServerSelectProps) {
|
|
// A previously-bound server that no longer exists (deleted): keep it visible
|
|
// so the binding isn't silently dropped from the UI.
|
|
const missing =
|
|
value !== undefined && !servers.some((s) => s.id === value);
|
|
|
|
return (
|
|
<SmallDropdown
|
|
aria-label={ariaLabel}
|
|
value={value ?? NONE}
|
|
onChange={(next) => onChange(next === NONE ? undefined : next)}
|
|
options={[
|
|
{ value: NONE, label: "None (external endpoint)" },
|
|
...servers.map((s) => ({
|
|
value: s.id,
|
|
label: `${s.name} — ${s.servedModelName}`,
|
|
})),
|
|
...(missing && value !== undefined
|
|
? [{ value, label: `${value} (unknown / removed)` }]
|
|
: []),
|
|
]}
|
|
/>
|
|
);
|
|
}
|