feat: 添加聊天助手功能,创建 ChatDev 页面及相关状态管理;更新路由配置,支持聊天助手的路径
This commit is contained in:
@@ -53,6 +53,7 @@
|
|||||||
"sigma": "^3.0.2",
|
"sigma": "^3.0.2",
|
||||||
"sonner": "^2.0.7",
|
"sonner": "^2.0.7",
|
||||||
"three": "^0.183.2",
|
"three": "^0.183.2",
|
||||||
|
"three-spritetext": "^1.10.0",
|
||||||
"zustand": "^5.0.11"
|
"zustand": "^5.0.11"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
|
|||||||
65
src/pages/code-graph/components/Graph3DConfigDialog.tsx
Normal file
65
src/pages/code-graph/components/Graph3DConfigDialog.tsx
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import { SlidersHorizontalIcon } from 'lucide-react';
|
||||||
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '@/components/ui/dialog';
|
||||||
|
import { Checkbox } from '@/components/ui/checkbox';
|
||||||
|
import { Button } from '@/components/ui/button';
|
||||||
|
import { Graph3DConfig } from '../modules/graph3d-config';
|
||||||
|
|
||||||
|
interface Graph3DConfigDialogProps {
|
||||||
|
open: boolean;
|
||||||
|
onOpenChange: (open: boolean) => void;
|
||||||
|
config: Graph3DConfig;
|
||||||
|
onUpdate: (patch: Partial<Graph3DConfig>) => void;
|
||||||
|
onReset: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Graph3DConfigDialog({ open, onOpenChange, config, onUpdate, onReset }: Graph3DConfigDialogProps) {
|
||||||
|
return (
|
||||||
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||||
|
<DialogContent className='max-w-md'>
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle className='flex items-center gap-2'>
|
||||||
|
<SlidersHorizontalIcon className='w-4 h-4' />
|
||||||
|
3D 图谱配置
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogDescription>配置 3D 力导向图的显示效果,设置自动保存到本地。</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
|
||||||
|
<div className='py-2 space-y-5'>
|
||||||
|
{/* ── 显示 ── */}
|
||||||
|
<section>
|
||||||
|
<p className='text-xs font-semibold text-slate-400 uppercase tracking-wider mb-3'>显示</p>
|
||||||
|
<div className='space-y-3'>
|
||||||
|
<label className='flex items-center gap-3 cursor-pointer select-none group'>
|
||||||
|
<Checkbox
|
||||||
|
checked={config.showLabels}
|
||||||
|
onCheckedChange={(checked) => onUpdate({ showLabels: !!checked })}
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
<p className='text-sm font-medium text-slate-100'>显示节点文字标签</p>
|
||||||
|
<p className='text-xs text-slate-400'>在节点旁以 3D 精灵字体显示名称</p>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── 其他配置暂留 ── */}
|
||||||
|
<section>
|
||||||
|
<p className='text-xs font-semibold text-slate-400 uppercase tracking-wider mb-3'>其他(暂留)</p>
|
||||||
|
<div className='rounded-md border border-dashed border-white/10 px-4 py-3 text-xs text-slate-500'>
|
||||||
|
更多配置项开发中…
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='flex justify-between pt-2'>
|
||||||
|
<Button variant='ghost' size='sm' className='text-slate-400 hover:text-slate-200' onClick={onReset}>
|
||||||
|
恢复默认
|
||||||
|
</Button>
|
||||||
|
<Button size='sm' onClick={() => onOpenChange(false)}>
|
||||||
|
完成
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
50
src/pages/code-graph/modules/graph3d-config.ts
Normal file
50
src/pages/code-graph/modules/graph3d-config.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import { useState, useCallback } from 'react';
|
||||||
|
|
||||||
|
const STORAGE_KEY = 'code-graph-3d-config';
|
||||||
|
|
||||||
|
export interface Graph3DConfig {
|
||||||
|
/** 是否默认显示文字标签(SpriteText) */
|
||||||
|
showLabels: boolean;
|
||||||
|
// 其他配置项暂留
|
||||||
|
}
|
||||||
|
|
||||||
|
const DEFAULT_CONFIG: Graph3DConfig = {
|
||||||
|
showLabels: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
function loadConfig(): Graph3DConfig {
|
||||||
|
try {
|
||||||
|
const raw = localStorage.getItem(STORAGE_KEY);
|
||||||
|
if (!raw) return { ...DEFAULT_CONFIG };
|
||||||
|
return { ...DEFAULT_CONFIG, ...JSON.parse(raw) };
|
||||||
|
} catch {
|
||||||
|
return { ...DEFAULT_CONFIG };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveConfig(config: Graph3DConfig): void {
|
||||||
|
try {
|
||||||
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(config));
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useGraph3DConfig() {
|
||||||
|
const [config, setConfigState] = useState<Graph3DConfig>(() => loadConfig());
|
||||||
|
|
||||||
|
const updateConfig = useCallback((patch: Partial<Graph3DConfig>) => {
|
||||||
|
setConfigState((prev) => {
|
||||||
|
const next = { ...prev, ...patch };
|
||||||
|
saveConfig(next);
|
||||||
|
return next;
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const resetConfig = useCallback(() => {
|
||||||
|
saveConfig(DEFAULT_CONFIG);
|
||||||
|
setConfigState({ ...DEFAULT_CONFIG });
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return { config, updateConfig, resetConfig };
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user