删除无用文件
This commit is contained in:
15
src/App.tsx
15
src/App.tsx
@@ -30,7 +30,6 @@ import { PromptFilesManager } from "@/components";
|
||||
import i18n from "@/lib/i18n";
|
||||
|
||||
// Lazy load these components to match TabContent's dynamic imports
|
||||
const MarkdownEditor = lazy(() => import('@/components/MarkdownEditor').then(m => ({ default: m.MarkdownEditor })));
|
||||
const Settings = lazy(() => import('@/components/Settings').then(m => ({ default: m.Settings })));
|
||||
const UsageDashboard = lazy(() => import('@/components/UsageDashboard').then(m => ({ default: m.UsageDashboard })));
|
||||
const MCPManager = lazy(() => import('@/components/MCPManager').then(m => ({ default: m.MCPManager })));
|
||||
@@ -38,7 +37,6 @@ const MCPManager = lazy(() => import('@/components/MCPManager').then(m => ({ def
|
||||
type View =
|
||||
| "welcome"
|
||||
| "projects"
|
||||
| "editor"
|
||||
| "claude-file-editor"
|
||||
| "settings"
|
||||
| "cc-agents"
|
||||
@@ -61,7 +59,6 @@ function AppContent() {
|
||||
const { t } = useTranslation();
|
||||
const [view, setView] = useState<View>("welcome");
|
||||
const {
|
||||
createClaudeMdTab,
|
||||
createSettingsTab,
|
||||
createUsageTab,
|
||||
createMCPTab,
|
||||
@@ -457,14 +454,7 @@ function AppContent() {
|
||||
</div>
|
||||
);
|
||||
|
||||
case "editor":
|
||||
return (
|
||||
<div className="h-full overflow-hidden">
|
||||
<Suspense fallback={<div className="flex items-center justify-center h-full"><Loader2 className="h-6 w-6 animate-spin" /></div>}>
|
||||
<MarkdownEditor onBack={() => handleViewChange("welcome")} />
|
||||
</Suspense>
|
||||
</div>
|
||||
);
|
||||
// Removed old direct CLAUDE.md editor view
|
||||
|
||||
case "prompt-files":
|
||||
return (
|
||||
@@ -613,7 +603,7 @@ function AppContent() {
|
||||
<TabContent />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
|
||||
case "usage-dashboard":
|
||||
return (
|
||||
@@ -658,7 +648,6 @@ function AppContent() {
|
||||
<div className="h-screen bg-background flex flex-col">
|
||||
{/* Topbar */}
|
||||
<Topbar
|
||||
onClaudeClick={() => view === 'tabs' ? createClaudeMdTab() : handleViewChange('editor')}
|
||||
onSettingsClick={() => view === 'tabs' ? createSettingsTab() : handleViewChange('settings')}
|
||||
onUsageClick={() => view === 'tabs' ? createUsageTab() : handleViewChange('usage-dashboard')}
|
||||
onMCPClick={() => view === 'tabs' ? createMCPTab() : handleViewChange('mcp')}
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import MDEditor from "@uiw/react-md-editor";
|
||||
import { motion } from "framer-motion";
|
||||
import { ArrowLeft, Save, Loader2 } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Toast, ToastContainer } from "@/components/ui/toast";
|
||||
import { api } from "@/lib/api";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useTranslation } from "@/hooks/useTranslation";
|
||||
|
||||
interface MarkdownEditorProps {
|
||||
/**
|
||||
* Callback to go back to the main view
|
||||
*/
|
||||
onBack: () => void;
|
||||
/**
|
||||
* Optional className for styling
|
||||
*/
|
||||
className?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* MarkdownEditor component for editing the CLAUDE.md system prompt
|
||||
*
|
||||
* @example
|
||||
* <MarkdownEditor onBack={() => setView('main')} />
|
||||
*/
|
||||
export const MarkdownEditor: React.FC<MarkdownEditorProps> = ({
|
||||
onBack,
|
||||
className,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const [content, setContent] = useState<string>("");
|
||||
const [originalContent, setOriginalContent] = useState<string>("");
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [toast, setToast] = useState<{ message: string; type: "success" | "error" } | null>(null);
|
||||
|
||||
const hasChanges = content !== originalContent;
|
||||
|
||||
// Load the system prompt on mount
|
||||
useEffect(() => {
|
||||
loadSystemPrompt();
|
||||
}, []);
|
||||
|
||||
const loadSystemPrompt = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
const prompt = await api.getSystemPrompt();
|
||||
setContent(prompt);
|
||||
setOriginalContent(prompt);
|
||||
} catch (err) {
|
||||
console.error("Failed to load system prompt:", err);
|
||||
setError(t('usage.loadClaudemdFailed'));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSave = async () => {
|
||||
try {
|
||||
setSaving(true);
|
||||
setError(null);
|
||||
setToast(null);
|
||||
await api.saveSystemPrompt(content);
|
||||
setOriginalContent(content);
|
||||
setToast({ message: t('usage.claudemdSavedSuccess'), type: "success" });
|
||||
} catch (err) {
|
||||
console.error("Failed to save system prompt:", err);
|
||||
setError(t('usage.saveClaudemdFailed'));
|
||||
setToast({ message: t('usage.saveClaudemdFailed'), type: "error" });
|
||||
} finally {
|
||||
setSaving(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleBack = () => {
|
||||
if (hasChanges) {
|
||||
const confirmLeave = window.confirm(
|
||||
t('usage.unsavedChangesConfirm')
|
||||
);
|
||||
if (!confirmLeave) return;
|
||||
}
|
||||
onBack();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={cn("flex flex-col h-full bg-background", className)}>
|
||||
<div className="w-full max-w-5xl mx-auto flex flex-col h-full">
|
||||
{/* Header */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: -20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
className="flex items-center justify-between p-4 border-b border-border"
|
||||
>
|
||||
<div className="flex items-center space-x-3">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={handleBack}
|
||||
className="h-8 w-8"
|
||||
>
|
||||
<ArrowLeft className="h-4 w-4" />
|
||||
</Button>
|
||||
<div>
|
||||
<h2 className="text-lg font-semibold">CLAUDE.md</h2>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{t('usage.editSystemPrompt')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
onClick={handleSave}
|
||||
disabled={!hasChanges || saving}
|
||||
size="sm"
|
||||
>
|
||||
{saving ? (
|
||||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||
) : (
|
||||
<Save className="mr-2 h-4 w-4" />
|
||||
)}
|
||||
{saving ? t('app.saving') : t('app.save')}
|
||||
</Button>
|
||||
</motion.div>
|
||||
|
||||
{/* Error display */}
|
||||
{error && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
className="mx-4 mt-4 rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-xs text-destructive"
|
||||
>
|
||||
{error}
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
{/* Editor */}
|
||||
<div className="flex-1 p-4 overflow-hidden">
|
||||
{loading ? (
|
||||
<div className="flex items-center justify-center h-full">
|
||||
<Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
|
||||
</div>
|
||||
) : (
|
||||
<div className="h-full rounded-lg border border-border overflow-hidden shadow-sm" data-color-mode="dark">
|
||||
<MDEditor
|
||||
value={content}
|
||||
onChange={(val) => setContent(val || "")}
|
||||
preview="edit"
|
||||
height="100%"
|
||||
visibleDragbar={false}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Toast Notification */}
|
||||
<ToastContainer>
|
||||
{toast && (
|
||||
<Toast
|
||||
message={toast.message}
|
||||
type={toast.type}
|
||||
onDismiss={() => setToast(null)}
|
||||
/>
|
||||
)}
|
||||
</ToastContainer>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -18,7 +18,7 @@ const CreateAgent = lazy(() => import('@/components/CreateAgent').then(m => ({ d
|
||||
const UsageDashboard = lazy(() => import('@/components/UsageDashboard').then(m => ({ default: m.UsageDashboard })));
|
||||
const MCPManager = lazy(() => import('@/components/MCPManager').then(m => ({ default: m.MCPManager })));
|
||||
const Settings = lazy(() => import('@/components/Settings').then(m => ({ default: m.Settings })));
|
||||
const MarkdownEditor = lazy(() => import('@/components/MarkdownEditor').then(m => ({ default: m.MarkdownEditor })));
|
||||
// Removed MarkdownEditor (direct CLAUDE.md editor)
|
||||
// const ClaudeFileEditor = lazy(() => import('@/components/ClaudeFileEditor').then(m => ({ default: m.ClaudeFileEditor })));
|
||||
|
||||
// Import non-lazy components for projects view
|
||||
@@ -234,8 +234,7 @@ const TabPanel: React.FC<TabPanelProps> = ({ tab, isActive }) => {
|
||||
case 'settings':
|
||||
return <Settings onBack={() => {}} />;
|
||||
|
||||
case 'claude-md':
|
||||
return <MarkdownEditor onBack={() => {}} />;
|
||||
// Removed 'claude-md' tab type
|
||||
|
||||
case 'claude-file':
|
||||
if (!tab.claudeFileId) {
|
||||
|
||||
@@ -34,7 +34,6 @@ const TabItem: React.FC<TabItemProps> = ({ tab, isActive, onClose, onClick, isDr
|
||||
return Server;
|
||||
case 'settings':
|
||||
return Settings;
|
||||
case 'claude-md':
|
||||
case 'claude-file':
|
||||
return FileText;
|
||||
case 'agent-execution':
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import { Circle, FileText, Settings, ExternalLink, BarChart3, Network, Info, Bot, Files } from "lucide-react";
|
||||
import { Circle, Settings, ExternalLink, BarChart3, Network, Info, Bot, Files } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Popover } from "@/components/ui/popover";
|
||||
import { LanguageSwitcher } from "@/components/LanguageSwitcher";
|
||||
@@ -10,10 +10,7 @@ import { api, type ClaudeVersionStatus } from "@/lib/api";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface TopbarProps {
|
||||
/**
|
||||
* Callback when CLAUDE.md is clicked
|
||||
*/
|
||||
onClaudeClick: () => void;
|
||||
// Removed direct CLAUDE.md editor entry to avoid duplication
|
||||
/**
|
||||
* Callback when Settings is clicked
|
||||
*/
|
||||
@@ -49,14 +46,13 @@ interface TopbarProps {
|
||||
*
|
||||
* @example
|
||||
* <Topbar
|
||||
* onClaudeClick={() => setView('editor')}
|
||||
* // CLAUDE.md direct editor removed; use Prompt Files manager instead
|
||||
* onSettingsClick={() => setView('settings')}
|
||||
* onUsageClick={() => setView('usage-dashboard')}
|
||||
* onMCPClick={() => setView('mcp')}
|
||||
* />
|
||||
*/
|
||||
export const Topbar: React.FC<TopbarProps> = ({
|
||||
onClaudeClick,
|
||||
onSettingsClick,
|
||||
onUsageClick,
|
||||
onMCPClick,
|
||||
@@ -213,15 +209,7 @@ export const Topbar: React.FC<TopbarProps> = ({
|
||||
{t('navigation.usage')}
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={onClaudeClick}
|
||||
className="text-xs"
|
||||
>
|
||||
<FileText className="mr-2 h-3 w-3" />
|
||||
CLAUDE.md
|
||||
</Button>
|
||||
{/* Removed old direct CLAUDE.md editor button */}
|
||||
|
||||
{onPromptFilesClick && (
|
||||
<Button
|
||||
@@ -273,4 +261,4 @@ export const Topbar: React.FC<TopbarProps> = ({
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useTranslation } from '@/hooks/useTranslation';
|
||||
|
||||
export interface Tab {
|
||||
id: string;
|
||||
type: 'chat' | 'agent' | 'projects' | 'usage' | 'mcp' | 'settings' | 'claude-md' | 'claude-file' | 'agent-execution' | 'create-agent' | 'import-agent';
|
||||
type: 'chat' | 'agent' | 'projects' | 'usage' | 'mcp' | 'settings' | 'claude-file' | 'agent-execution' | 'create-agent' | 'import-agent';
|
||||
title: string;
|
||||
sessionId?: string; // for chat tabs
|
||||
sessionData?: any; // for chat tabs - stores full session object
|
||||
|
||||
@@ -10,7 +10,6 @@ const TAB_SCREEN_NAMES: Record<string, string> = {
|
||||
'usage': 'usage_dashboard',
|
||||
'mcp': 'mcp_manager',
|
||||
'settings': 'settings',
|
||||
'claude-md': 'markdown_editor',
|
||||
'claude-file': 'file_editor',
|
||||
'agent-execution': 'agent_execution',
|
||||
'create-agent': 'create_agent',
|
||||
|
||||
@@ -20,7 +20,6 @@ interface UseTabStateReturn {
|
||||
createUsageTab: () => string | null;
|
||||
createMCPTab: () => string | null;
|
||||
createSettingsTab: () => string | null;
|
||||
createClaudeMdTab: () => string | null;
|
||||
createClaudeFileTab: (fileId: string, fileName: string) => string;
|
||||
createCreateAgentTab: () => string;
|
||||
createImportAgentTab: () => string;
|
||||
@@ -161,22 +160,7 @@ export const useTabState = (): UseTabStateReturn => {
|
||||
});
|
||||
}, [addTab, tabs, setActiveTab, t]);
|
||||
|
||||
const createClaudeMdTab = useCallback((): string | null => {
|
||||
// Check if claude-md tab already exists (singleton)
|
||||
const existingTab = tabs.find(tab => tab.type === 'claude-md');
|
||||
if (existingTab) {
|
||||
setActiveTab(existingTab.id);
|
||||
return existingTab.id;
|
||||
}
|
||||
|
||||
return addTab({
|
||||
type: 'claude-md',
|
||||
title: t('messages.claudemdTitle'),
|
||||
status: 'idle',
|
||||
hasUnsavedChanges: false,
|
||||
icon: 'file-text'
|
||||
});
|
||||
}, [addTab, tabs, setActiveTab, t]);
|
||||
// Removed createClaudeMdTab: using Prompt Files manager instead
|
||||
|
||||
const createClaudeFileTab = useCallback((fileId: string, fileName: string): string => {
|
||||
// Check if tab already exists for this file
|
||||
@@ -328,7 +312,6 @@ export const useTabState = (): UseTabStateReturn => {
|
||||
createUsageTab,
|
||||
createMCPTab,
|
||||
createSettingsTab,
|
||||
createClaudeMdTab,
|
||||
createClaudeFileTab,
|
||||
createCreateAgentTab,
|
||||
createImportAgentTab,
|
||||
|
||||
Reference in New Issue
Block a user