返回 DeepSeek-Reasonix
DraftTopicbarActions.tsx
根目录 / desktop / frontend / src / app-shell / DraftTopicbarActions.tsx
1 import { Plug, Trash2 } from "lucide-react";
2
3 import { draftSubmissionLocksEditing, type SessionDraftSurface } from "../app-runtime/useSessionDraftSurface";
4 import { Tooltip } from "../components/Tooltip";
5 import type { Translator } from "../lib/i18n";
6
7 /** Keeps optional draft controls available without turning the landing surface
8 * into a management page. */
9 export function DraftTopicbarActions(props: {
10 t: Translator;
11 draft: SessionDraftSurface;
12 onSetMCPEnabled(server: SessionDraftSurface["servers"][number], enabled: boolean): void;
13 onDiscard(): void;
14 }) {
15 const { draft, t } = props;
16 const editingLocked = draft.preparingSubmission || draftSubmissionLocksEditing(draft.operation);
17 const discardLabel = t(draft.discarding ? "draft.discarding" : editingLocked ? "draft.discardBlocked" : "draft.discard");
18 const enabledServers = draft.servers.filter((server) => server.enabled && !draft.settings.disabledMcp[server.name]).length;
19 return <div className="topicbar__actions draft-topicbar-actions">
20 {draft.servers.length > 0 ? <details className="draft-topicbar-mcp">
21 <summary className="topicbar__action-btn topicbar__action-btn--utility" aria-label={t("draft.mcpTitle")}>
22 <Plug size={15} aria-hidden="true" />
23 <span>{enabledServers}/{draft.servers.length}</span>
24 </summary>
25 <div className="draft-topicbar-mcp__menu" role="group" aria-label={t("draft.mcpTitle")}>
26 {draft.servers.map((server) => {
27 const available = server.enabled;
28 const selected = available && !draft.settings.disabledMcp[server.name];
29 return <label key={server.name}>
30 <input type="checkbox" checked={selected} disabled={!available || editingLocked}
31 onChange={(event) => props.onSetMCPEnabled(server, event.currentTarget.checked)} />
32 <span>{server.name}</span>
33 <small>{available ? t(selected ? "draft.mcpEnabled" : "draft.mcpDisabled") : t("draft.mcpUnavailable")}</small>
34 </label>;
35 })}
36 </div>
37 </details> : null}
38 <Tooltip label={discardLabel}>
39 <button className="topicbar__action-btn topicbar__action-btn--icon topicbar__action-btn--utility" type="button"
40 aria-label={discardLabel} aria-busy={Boolean(draft.discarding)} disabled={editingLocked} onClick={props.onDiscard}>
41 <Trash2 size={15} aria-hidden="true" />
42 </button>
43 </Tooltip>
44 </div>;
45 }
46
46 lines Plain Text