mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-28 08:44:41 +08:00
155532ea8c
* feat(prompts): add prompt management across Tauri service and React UI
- backend: add commands/prompt.rs, services/prompt.rs, register in commands/mod.rs and lib.rs, refine app_config.rs
- frontend: add PromptPanel, PromptFormModal, PromptListItem, MarkdownEditor, usePromptActions, integrate in App.tsx
- api: add src/lib/api/prompts.ts
- i18n: update src/i18n/locales/{en,zh}.json
- build: update package.json and pnpm-lock.yaml
* feat(i18n): improve i18n for prompts and Markdown editor
- update src/i18n/locales/{en,zh}.json keys and strings
- apply i18n in PromptFormModal, PromptPanel, and MarkdownEditor
- align prompt text with src-tauri/src/services/prompt.rs
* feat(prompts): add enable/disable toggle and simplify panel UI
- Add PromptToggle component and integrate in prompt list items
- Implement toggleEnabled with optimistic update; enable via API, disable via upsert with enabled=false;
reload after success
- Simplify PromptPanel: remove file import and current-file preview to keep CRUD flow focused
- Tweak header controls style (use mcp variant) and minor copy: rename “Prompt Management” to “Prompts”
- i18n: add disableSuccess/disableFailed messages
- Backend (Tauri): prevent duplicate backups when importing original prompt content
* style: unify code formatting with trailing commas
* feat(prompts): add Gemini filename support to PromptFormModal
Update filename mapping to use Record<AppId, string> pattern, supporting
GEMINI.md alongside CLAUDE.md and AGENTS.md.
* fix(prompts): sync enabled prompt to file when updating
When updating a prompt that is currently enabled, automatically sync
the updated content to the corresponding live file (CLAUDE.md/AGENTS.md/GEMINI.md).
This ensures the active prompt file always reflects the latest content
when editing enabled prompts.
76 lines
2.1 KiB
TypeScript
76 lines
2.1 KiB
TypeScript
import React from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import { Edit3, Trash2 } from "lucide-react";
|
|
import { Button } from "@/components/ui/button";
|
|
import type { Prompt } from "@/lib/api";
|
|
import PromptToggle from "./PromptToggle";
|
|
|
|
interface PromptListItemProps {
|
|
id: string;
|
|
prompt: Prompt;
|
|
onToggle: (id: string, enabled: boolean) => void;
|
|
onEdit: (id: string) => void;
|
|
onDelete: (id: string) => void;
|
|
}
|
|
|
|
const PromptListItem: React.FC<PromptListItemProps> = ({
|
|
id,
|
|
prompt,
|
|
onToggle,
|
|
onEdit,
|
|
onDelete,
|
|
}) => {
|
|
const { t } = useTranslation();
|
|
|
|
const enabled = prompt.enabled === true;
|
|
|
|
return (
|
|
<div className="h-16 rounded-lg border border-border-default bg-card p-4 transition-[border-color,box-shadow] duration-200 hover:border-border-hover hover:shadow-sm">
|
|
<div className="flex items-center gap-4 h-full">
|
|
{/* Toggle 开关 */}
|
|
<div className="flex-shrink-0">
|
|
<PromptToggle
|
|
enabled={enabled}
|
|
onChange={(newEnabled) => onToggle(id, newEnabled)}
|
|
/>
|
|
</div>
|
|
|
|
<div className="flex-1 min-w-0">
|
|
<h3 className="font-medium text-gray-900 dark:text-gray-100 mb-1">
|
|
{prompt.name}
|
|
</h3>
|
|
{prompt.description && (
|
|
<p className="text-sm text-gray-500 dark:text-gray-400 truncate">
|
|
{prompt.description}
|
|
</p>
|
|
)}
|
|
</div>
|
|
|
|
<div className="flex items-center gap-2 flex-shrink-0">
|
|
<Button
|
|
type="button"
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={() => onEdit(id)}
|
|
title={t("common.edit")}
|
|
>
|
|
<Edit3 size={16} />
|
|
</Button>
|
|
<Button
|
|
type="button"
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={() => onDelete(id)}
|
|
className="hover:text-red-500 hover:bg-red-100 dark:hover:text-red-400 dark:hover:bg-red-500/10"
|
|
title={t("common.delete")}
|
|
>
|
|
<Trash2 size={16} />
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default PromptListItem;
|