mirror of
https://github.com/OpenHands/OpenHands.git
synced 2025-12-26 05:48:36 +08:00
fix(misc): MCP settings and other UI improvements/fixes (#10141)
This commit is contained in:
parent
e3411f743d
commit
69fa580899
@ -1,8 +1,10 @@
|
||||
import { Lock } from "lucide-react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ContextMenu } from "./context-menu";
|
||||
import { ContextMenuListItem } from "./context-menu-list-item";
|
||||
import { useClickOutsideElement } from "#/hooks/use-click-outside-element";
|
||||
import { I18nKey } from "#/i18n/declaration";
|
||||
import { ContextMenuIconText } from "./context-menu-icon-text";
|
||||
|
||||
interface AccountSettingsContextMenuProps {
|
||||
onLogout: () => void;
|
||||
@ -23,7 +25,10 @@ export function AccountSettingsContextMenu({
|
||||
className="absolute right-full md:left-full -top-1 z-10 w-fit"
|
||||
>
|
||||
<ContextMenuListItem onClick={onLogout} data-testid="logout-button">
|
||||
{t(I18nKey.ACCOUNT_SETTINGS$LOGOUT)}
|
||||
<ContextMenuIconText
|
||||
icon={Lock}
|
||||
text={t(I18nKey.ACCOUNT_SETTINGS$LOGOUT)}
|
||||
/>
|
||||
</ContextMenuListItem>
|
||||
</ContextMenu>
|
||||
);
|
||||
|
||||
@ -13,6 +13,7 @@ export function ConnectToProviderMessage() {
|
||||
<Link
|
||||
data-testid="navigate-to-settings-button"
|
||||
to="/settings/integrations"
|
||||
className="self-start"
|
||||
>
|
||||
<BrandButton type="button" variant="primary" isDisabled={isLoading}>
|
||||
{!isLoading && t("SETTINGS$TITLE")}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useState, useRef, useEffect } from "react";
|
||||
import { useTranslation, Trans } from "react-i18next";
|
||||
import { MCPConfig } from "#/types/settings";
|
||||
import { I18nKey } from "#/i18n/declaration";
|
||||
@ -11,6 +11,11 @@ interface MCPJsonEditorProps {
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
const MCP_DEFAULT_CONFIG: MCPConfig = {
|
||||
sse_servers: [],
|
||||
stdio_servers: [],
|
||||
};
|
||||
|
||||
export function MCPJsonEditor({
|
||||
mcpConfig,
|
||||
onChange,
|
||||
@ -20,10 +25,17 @@ export function MCPJsonEditor({
|
||||
const [configText, setConfigText] = useState(() =>
|
||||
mcpConfig
|
||||
? JSON.stringify(mcpConfig, null, 2)
|
||||
: t(I18nKey.SETTINGS$MCP_DEFAULT_CONFIG),
|
||||
: JSON.stringify(MCP_DEFAULT_CONFIG, null, 2),
|
||||
);
|
||||
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
textareaRef.current?.focus();
|
||||
}, []);
|
||||
|
||||
const handleTextChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||
setConfigText(e.target.value);
|
||||
};
|
||||
@ -89,6 +101,7 @@ export function MCPJsonEditor({
|
||||
/>
|
||||
</p>
|
||||
<textarea
|
||||
ref={textareaRef}
|
||||
className={cn(
|
||||
"w-full h-64 resize-y p-2 rounded-sm text-sm font-mono",
|
||||
"bg-tertiary border border-[#717888]",
|
||||
@ -118,7 +131,7 @@ export function MCPJsonEditor({
|
||||
{t(I18nKey.BUTTON$CANCEL)}
|
||||
</BrandButton>
|
||||
<BrandButton type="button" variant="primary" onClick={handleSave}>
|
||||
{t(I18nKey.SETTINGS$MCP_CONFIRM_CHANGES)}
|
||||
{t(I18nKey.SETTINGS$MCP_PREVIEW_CHANGES)}
|
||||
</BrandButton>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -51,7 +51,7 @@ export enum I18nKey {
|
||||
SETTINGS$NAV_MCP = "SETTINGS$NAV_MCP",
|
||||
SETTINGS$MCP_CONFIGURATION = "SETTINGS$MCP_CONFIGURATION",
|
||||
SETTINGS$MCP_EDIT_CONFIGURATION = "SETTINGS$MCP_EDIT_CONFIGURATION",
|
||||
SETTINGS$MCP_CONFIRM_CHANGES = "SETTINGS$MCP_CONFIRM_CHANGES",
|
||||
SETTINGS$MCP_PREVIEW_CHANGES = "SETTINGS$MCP_PREVIEW_CHANGES",
|
||||
SETTINGS$MCP_CONFIG_DESCRIPTION = "SETTINGS$MCP_CONFIG_DESCRIPTION",
|
||||
SETTINGS$MCP_CONFIG_ERROR = "SETTINGS$MCP_CONFIG_ERROR",
|
||||
SETTINGS$MCP_CONFIG_EXAMPLE = "SETTINGS$MCP_CONFIG_EXAMPLE",
|
||||
@ -71,7 +71,6 @@ export enum I18nKey {
|
||||
SETTINGS$MCP_ERROR_SSE_URL = "SETTINGS$MCP_ERROR_SSE_URL",
|
||||
SETTINGS$MCP_ERROR_STDIO_PROPS = "SETTINGS$MCP_ERROR_STDIO_PROPS",
|
||||
SETTINGS$MCP_ERROR_INVALID_JSON = "SETTINGS$MCP_ERROR_INVALID_JSON",
|
||||
SETTINGS$MCP_DEFAULT_CONFIG = "SETTINGS$MCP_DEFAULT_CONFIG",
|
||||
HOME$CONNECT_PROVIDER_MESSAGE = "HOME$CONNECT_PROVIDER_MESSAGE",
|
||||
HOME$LETS_START_BUILDING = "HOME$LETS_START_BUILDING",
|
||||
HOME$OPENHANDS_DESCRIPTION = "HOME$OPENHANDS_DESCRIPTION",
|
||||
|
||||
@ -815,21 +815,21 @@
|
||||
"de": "Konfiguration bearbeiten",
|
||||
"uk": "Редагувати налаштування"
|
||||
},
|
||||
"SETTINGS$MCP_CONFIRM_CHANGES": {
|
||||
"en": "Confirm Changes",
|
||||
"ja": "変更を確定",
|
||||
"zh-CN": "确认更改",
|
||||
"zh-TW": "確認變更",
|
||||
"ko-KR": "변경 사항 확인",
|
||||
"no": "Bekreft endringer",
|
||||
"it": "Conferma modifiche",
|
||||
"pt": "Confirmar alterações",
|
||||
"es": "Confirmar cambios",
|
||||
"ar": "تأكيد التغييرات",
|
||||
"fr": "Confirmer les modifications",
|
||||
"tr": "Değişiklikleri Onayla",
|
||||
"de": "Änderungen bestätigen",
|
||||
"uk": "Підтвердити зміни"
|
||||
"SETTINGS$MCP_PREVIEW_CHANGES": {
|
||||
"en": "Preview Changes",
|
||||
"ja": "変更内容をプレビュー",
|
||||
"zh-CN": "预览更改",
|
||||
"zh-TW": "預覽變更",
|
||||
"ko-KR": "변경 사항 미리보기",
|
||||
"no": "Forhåndsvis endringer",
|
||||
"it": "Anteprima modifiche",
|
||||
"pt": "Visualizar alterações",
|
||||
"es": "Vista previa de los cambios",
|
||||
"ar": "معاينة التغييرات",
|
||||
"fr": "Aperçu des modifications",
|
||||
"tr": "Değişiklikleri Önizle",
|
||||
"de": "Änderungen anzeigen",
|
||||
"uk": "Переглянути зміни"
|
||||
},
|
||||
"SETTINGS$MCP_CONFIG_DESCRIPTION": {
|
||||
"en": "Edit the JSON configuration for MCP servers below. The configuration must include both sse_servers and stdio_servers arrays. For full configuration details and integration examples, see the <a>documentation</a>.",
|
||||
@ -1135,22 +1135,6 @@
|
||||
"de": "Ungültiges JSON",
|
||||
"uk": "Невірний JSON"
|
||||
},
|
||||
"SETTINGS$MCP_DEFAULT_CONFIG": {
|
||||
"en": "{\n \"sse_servers\": [],\n \"stdio_servers\": []\n}",
|
||||
"ja": "{\n \"sse_servers\": [],\n \"stdio_servers\": []\n}",
|
||||
"zh-CN": "{\n \"sse_servers\": [],\n \"stdio_servers\": []\n}",
|
||||
"zh-TW": "{\n \"sse_servers\": [],\n \"stdio_servers\": []\n}",
|
||||
"ko-KR": "{\n \"sse_servers\": [],\n \"stdio_servers\": []\n}",
|
||||
"no": "{\n \"sse_servers\": [],\n \"stdio_servers\": []\n}",
|
||||
"it": "{\n \"sse_servers\": [],\n \"stdio_servers\": []\n}",
|
||||
"pt": "{\n \"sse_servers\": [],\n \"stdio_servers\": []\n}",
|
||||
"es": "{\n \"sse_servers\": [],\n \"stdio_servers\": []\n}",
|
||||
"ar": "{\n \"sse_servers\": [],\n \"stdio_servers\": []\n}",
|
||||
"fr": "{\n \"sse_servers\": [],\n \"stdio_servers\": []\n}",
|
||||
"tr": "{\n \"sse_servers\": [],\n \"stdio_servers\": []\n}",
|
||||
"de": "{\n \"sse_servers\": [],\n \"stdio_servers\": []\n}",
|
||||
"uk": "{\n \"sse_servers\": [],\n \"stdio_servers\": []\n}"
|
||||
},
|
||||
"HOME$CONNECT_PROVIDER_MESSAGE": {
|
||||
"en": "To get started with suggested tasks, please connect your GitHub, GitLab, or Bitbucket account.",
|
||||
"ja": "提案されたタスクを始めるには、GitHub、GitLab、またはBitbucketアカウントを接続してください。",
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import posthog from "posthog-js";
|
||||
import { useSettings } from "#/hooks/query/use-settings";
|
||||
@ -18,11 +18,15 @@ function MCPSettingsScreen() {
|
||||
const { data: settings, isLoading } = useSettings();
|
||||
const { mutate: saveSettings, isPending } = useSaveSettings();
|
||||
|
||||
const [mcpConfig, setMcpConfig] = useState<MCPConfig | undefined>(
|
||||
settings?.MCP_CONFIG,
|
||||
);
|
||||
const [mcpConfig, setMcpConfig] = useState<MCPConfig | undefined>(undefined);
|
||||
const [isDirty, setIsDirty] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!mcpConfig && settings?.MCP_CONFIG) {
|
||||
setMcpConfig(settings.MCP_CONFIG);
|
||||
}
|
||||
}, [settings, mcpConfig]);
|
||||
|
||||
const handleConfigChange = (config: MCPConfig) => {
|
||||
setMcpConfig(config);
|
||||
setIsDirty(true);
|
||||
|
||||
@ -89,6 +89,7 @@ function SecretsSettingsScreen() {
|
||||
to="/settings/integrations"
|
||||
data-testid="connect-git-button"
|
||||
type="button"
|
||||
className="self-start"
|
||||
>
|
||||
<BrandButton type="button" variant="secondary">
|
||||
{t(I18nKey.SECRETS$CONNECT_GIT_PROVIDER)}
|
||||
|
||||
@ -47,7 +47,8 @@ export function getIndicatorColor(
|
||||
webSocketStatus === "DISCONNECTED" ||
|
||||
conversationStatus === "STOPPED" ||
|
||||
runtimeStatus === "STATUS$STOPPED" ||
|
||||
agentState === AgentState.STOPPED
|
||||
agentState === AgentState.STOPPED ||
|
||||
agentState === AgentState.ERROR
|
||||
) {
|
||||
return IndicatorColor.RED;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user