mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-24 12:44:18 +08:00
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:
@@ -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}
|
||||
|
||||
@@ -57,6 +57,15 @@
|
||||
"mustBeObject": "Configuration must be a JSON object, not an array or other type",
|
||||
"invalidJson": "Invalid JSON format"
|
||||
},
|
||||
"commonConfig": {
|
||||
"guideTitle": "What is a Common Config Snippet?",
|
||||
"guidePurpose": "It lets you share non-sensitive settings (plugins, environment variables, etc.) across different providers. These settings won't be lost when you switch providers.",
|
||||
"guideUsage": "How to use: ① Click \"Extract from Editor\" to save the common parts ② Check \"Write Common Config\" when creating a new provider",
|
||||
"guideReExtract": "If you've newly installed plugins or hooks, re-extract the common config so they sync to other providers.",
|
||||
"guideReassurance": "Don't worry — your original configuration is safely stored in the default provider and won't be lost.",
|
||||
"emptyTitle": "No common config snippet yet",
|
||||
"emptyHint": "Click \"Extract from Editor\" below to extract reusable parts from your current configuration"
|
||||
},
|
||||
"claudeConfig": {
|
||||
"configLabel": "Claude Code settings.json (JSON) *",
|
||||
"writeCommonConfig": "Write Common Config",
|
||||
|
||||
@@ -57,6 +57,15 @@
|
||||
"mustBeObject": "設定はオブジェクト形式の JSON で入力してください(配列や他の型は不可)",
|
||||
"invalidJson": "JSON 形式が正しくありません"
|
||||
},
|
||||
"commonConfig": {
|
||||
"guideTitle": "共通設定スニペットとは?",
|
||||
"guidePurpose": "異なるプロバイダー間でプラグインや環境変数などの非機密設定を共有するための機能です。プロバイダーを切り替えてもこれらの設定は失われません。",
|
||||
"guideUsage": "使い方:① 「編集内容から抽出」をクリックして共通部分を保存 ② 新規プロバイダー作成時に「共通設定を書き込む」をチェック",
|
||||
"guideReExtract": "新しいプラグインや Hook をインストールした場合は、共通設定を再抽出して他のプロバイダーに同期してください。",
|
||||
"guideReassurance": "ご安心ください:元の設定はデフォルトプロバイダーに安全に保存されており、失われることはありません。",
|
||||
"emptyTitle": "共通設定スニペットがまだありません",
|
||||
"emptyHint": "下の「編集内容から抽出」ボタンをクリックして、現在の設定から再利用可能な部分を抽出してください"
|
||||
},
|
||||
"claudeConfig": {
|
||||
"configLabel": "Claude Code settings.json (JSON) *",
|
||||
"writeCommonConfig": "共通設定を書き込む",
|
||||
|
||||
@@ -57,6 +57,15 @@
|
||||
"mustBeObject": "配置必须是JSON对象,不能是数组或其他类型",
|
||||
"invalidJson": "JSON格式错误"
|
||||
},
|
||||
"commonConfig": {
|
||||
"guideTitle": "什么是通用配置片段?",
|
||||
"guidePurpose": "用来在不同供应商之间共享插件、环境变量等非敏感配置。切换供应商时不会丢失这些设置。",
|
||||
"guideUsage": "用法:① 点击「从编辑内容提取」保存通用部分 ② 新建供应商时勾选「写入通用配置」",
|
||||
"guideReExtract": "如果您新安装了插件或 Hook,请重新提取一次通用配置,以便同步到其他供应商。",
|
||||
"guideReassurance": "放心:您的原始配置已保存在默认供应商中,不会丢失。",
|
||||
"emptyTitle": "还没有通用配置片段",
|
||||
"emptyHint": "点击下方「从编辑内容提取」按钮,从当前配置中提取可复用的部分"
|
||||
},
|
||||
"claudeConfig": {
|
||||
"configLabel": "Claude Code 配置 (JSON) *",
|
||||
"writeCommonConfig": "写入通用配置",
|
||||
|
||||
Reference in New Issue
Block a user