feat(common-config): add guide info and empty state to common config editor

Add an informational alert block at the top of the common config snippet
editor modal (Claude/Codex/Gemini) explaining what the feature is, why
it exists, and how to use it. Also add an empty state prompt when no
snippet has been extracted yet, guiding users to click "Extract from
Editor". Includes i18n support for zh/en/ja.
This commit is contained in:
Jason
2026-04-09 16:20:22 +08:00
parent 521571c4ca
commit ecb1fed5db
6 changed files with 114 additions and 10 deletions
@@ -1,5 +1,5 @@
import React, { useEffect, useState } from "react";
import { Save, Download, Loader2 } from "lucide-react";
import { Save, Download, Loader2, Package } from "lucide-react";
import { useTranslation } from "react-i18next";
import { FullScreenPanel } from "@/components/common/FullScreenPanel";
import { Button } from "@/components/ui/button";
@@ -100,9 +100,35 @@ export const CodexCommonConfigModal: React.FC<CodexCommonConfigModalProps> = ({
}
>
<div className="space-y-4">
<p className="text-sm text-muted-foreground">
<div className="rounded-lg border border-blue-200 dark:border-blue-800 bg-blue-50/50 dark:bg-blue-950/30 p-3 space-y-1.5">
<p className="text-sm font-medium text-blue-800 dark:text-blue-300">
{t("commonConfig.guideTitle")}
</p>
<p className="text-xs text-blue-700/80 dark:text-blue-400/80">
{t("commonConfig.guidePurpose")}
</p>
<p className="text-xs text-blue-700/80 dark:text-blue-400/80">
{t("commonConfig.guideUsage")}
</p>
<p className="text-xs text-blue-700/80 dark:text-blue-400/80">
{t("commonConfig.guideReExtract")}
</p>
<p className="text-xs text-muted-foreground">
{t("commonConfig.guideReassurance")}
</p>
</div>
<p className="text-xs text-muted-foreground">
{t("codexConfig.commonConfigHint")}
</p>
{(!draftValue || draftValue.trim() === "") && (
<div className="flex flex-col items-center justify-center py-6 text-center text-muted-foreground">
<Package className="h-8 w-8 mb-2 opacity-40" />
<p className="text-sm font-medium">
{t("commonConfig.emptyTitle")}
</p>
<p className="text-xs mt-1">{t("commonConfig.emptyHint")}</p>
</div>
)}
<JsonEditor
value={draftValue}
@@ -3,7 +3,7 @@ import { useEffect, useState, useCallback, useMemo } from "react";
import { FullScreenPanel } from "@/components/common/FullScreenPanel";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import { Save, Download, Loader2 } from "lucide-react";
import { Save, Download, Loader2, Package } from "lucide-react";
import JsonEditor from "@/components/JsonEditor";
interface CommonConfigEditorProps {
@@ -298,11 +298,34 @@ export function CommonConfigEditor({
}
>
<div className="space-y-4">
<p className="text-sm text-muted-foreground">
{t("claudeConfig.commonConfigHint", {
defaultValue: "通用配置片段将合并到所有启用它的供应商配置中",
})}
</p>
<div className="rounded-lg border border-blue-200 dark:border-blue-800 bg-blue-50/50 dark:bg-blue-950/30 p-3 space-y-1.5">
<p className="text-sm font-medium text-blue-800 dark:text-blue-300">
{t("commonConfig.guideTitle")}
</p>
<p className="text-xs text-blue-700/80 dark:text-blue-400/80">
{t("commonConfig.guidePurpose")}
</p>
<p className="text-xs text-blue-700/80 dark:text-blue-400/80">
{t("commonConfig.guideUsage")}
</p>
<p className="text-xs text-blue-700/80 dark:text-blue-400/80">
{t("commonConfig.guideReExtract")}
</p>
<p className="text-xs text-muted-foreground">
{t("commonConfig.guideReassurance")}
</p>
</div>
{(!commonConfigSnippet ||
commonConfigSnippet.trim() === "" ||
commonConfigSnippet.trim() === "{}") && (
<div className="flex flex-col items-center justify-center py-6 text-center text-muted-foreground">
<Package className="h-8 w-8 mb-2 opacity-40" />
<p className="text-sm font-medium">
{t("commonConfig.emptyTitle")}
</p>
<p className="text-xs mt-1">{t("commonConfig.emptyHint")}</p>
</div>
)}
<JsonEditor
value={commonConfigSnippet}
onChange={onCommonConfigSnippetChange}
@@ -1,5 +1,5 @@
import React, { useEffect, useState } from "react";
import { Save, Download, Loader2 } from "lucide-react";
import { Save, Download, Loader2, Package } from "lucide-react";
import { useTranslation } from "react-i18next";
import { FullScreenPanel } from "@/components/common/FullScreenPanel";
import { Button } from "@/components/ui/button";
@@ -96,12 +96,40 @@ export const GeminiCommonConfigModal: React.FC<
}
>
<div className="space-y-4">
<p className="text-sm text-muted-foreground">
<div className="rounded-lg border border-blue-200 dark:border-blue-800 bg-blue-50/50 dark:bg-blue-950/30 p-3 space-y-1.5">
<p className="text-sm font-medium text-blue-800 dark:text-blue-300">
{t("commonConfig.guideTitle")}
</p>
<p className="text-xs text-blue-700/80 dark:text-blue-400/80">
{t("commonConfig.guidePurpose")}
</p>
<p className="text-xs text-blue-700/80 dark:text-blue-400/80">
{t("commonConfig.guideUsage")}
</p>
<p className="text-xs text-blue-700/80 dark:text-blue-400/80">
{t("commonConfig.guideReExtract")}
</p>
<p className="text-xs text-muted-foreground">
{t("commonConfig.guideReassurance")}
</p>
</div>
<p className="text-xs text-amber-600 dark:text-amber-400">
{t("geminiConfig.commonConfigHint", {
defaultValue:
"该片段会写入 Gemini 的 .env(不允许包含 GOOGLE_GEMINI_BASE_URL、GEMINI_API_KEY",
})}
</p>
{(!draftValue ||
draftValue.trim() === "" ||
draftValue.trim() === "{}") && (
<div className="flex flex-col items-center justify-center py-6 text-center text-muted-foreground">
<Package className="h-8 w-8 mb-2 opacity-40" />
<p className="text-sm font-medium">
{t("commonConfig.emptyTitle")}
</p>
<p className="text-xs mt-1">{t("commonConfig.emptyHint")}</p>
</div>
)}
<JsonEditor
value={draftValue}