feat: restore risk assessment workspace and improve page scrolling
This commit is contained in:
@@ -18,6 +18,13 @@ import {
|
||||
Wrench,
|
||||
Loader2,
|
||||
Database,
|
||||
Building2,
|
||||
Target,
|
||||
Search,
|
||||
Shield,
|
||||
FileText,
|
||||
Users,
|
||||
Bot,
|
||||
} from "lucide-react";
|
||||
import { useApp } from "@/lib/store";
|
||||
import { getSessionTokenCount } from "@/lib/api";
|
||||
@@ -93,6 +100,46 @@ export default function Sidebar() {
|
||||
{/* Divider */}
|
||||
<div className="mx-3 h-px bg-black/[0.04]" />
|
||||
|
||||
{/* Xingbang Assistants section */}
|
||||
<div className="shrink-0 px-1.5 py-2">
|
||||
<p className="px-3 pt-1 pb-2 text-[10px] font-semibold text-gray-400 uppercase tracking-widest">
|
||||
兴邦助手
|
||||
</p>
|
||||
<div className="space-y-0.5">
|
||||
<a
|
||||
href="/risk-assess"
|
||||
className="w-full flex items-center gap-2 px-3 py-2 text-[13px] text-gray-600 hover:bg-white/40 hover:text-gray-800 rounded-lg transition-all"
|
||||
>
|
||||
<Shield className="w-3.5 h-3.5" />
|
||||
<span>风险研判</span>
|
||||
</a>
|
||||
<a
|
||||
href="/rule-engine"
|
||||
className="w-full flex items-center gap-2 px-3 py-2 text-[13px] text-gray-600 hover:bg-white/40 hover:text-gray-800 rounded-lg transition-all"
|
||||
>
|
||||
<FileText className="w-3.5 h-3.5" />
|
||||
<span>规则引擎管理</span>
|
||||
</a>
|
||||
<a
|
||||
href="/historical-data"
|
||||
className="w-full flex items-center gap-2 px-3 py-2 text-[13px] text-gray-600 hover:bg-white/40 hover:text-gray-800 rounded-lg transition-all"
|
||||
>
|
||||
<Database className="w-3.5 h-3.5" />
|
||||
<span>历史数据分析</span>
|
||||
</a>
|
||||
<a
|
||||
href="/xingbang"
|
||||
className="w-full flex items-center gap-2 px-3 py-2 text-[13px] text-gray-600 hover:bg-white/40 hover:text-gray-800 rounded-lg transition-all"
|
||||
>
|
||||
<Bot className="w-3.5 h-3.5" />
|
||||
<span>五Agent流水线</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Divider */}
|
||||
<div className="mx-3 h-px bg-black/[0.04]" />
|
||||
|
||||
{/* Raw Messages section */}
|
||||
<div className="shrink-0">
|
||||
<div className="flex items-center">
|
||||
@@ -254,23 +301,9 @@ function SessionItem({
|
||||
onRename: (title: string) => void;
|
||||
onDelete: () => void;
|
||||
}) {
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
const [renaming, setRenaming] = useState(false);
|
||||
const [renameValue, setRenameValue] = useState(title);
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const menuRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// Close menu on outside click
|
||||
useEffect(() => {
|
||||
if (!menuOpen) return;
|
||||
const handler = (e: MouseEvent) => {
|
||||
if (menuRef.current && !menuRef.current.contains(e.target as Node)) {
|
||||
setMenuOpen(false);
|
||||
}
|
||||
};
|
||||
document.addEventListener("mousedown", handler);
|
||||
return () => document.removeEventListener("mousedown", handler);
|
||||
}, [menuOpen]);
|
||||
|
||||
// Focus input when renaming
|
||||
useEffect(() => {
|
||||
@@ -289,8 +322,7 @@ function SessionItem({
|
||||
}, [renameValue, title, onRename]);
|
||||
|
||||
const handleDelete = useCallback(() => {
|
||||
setMenuOpen(false);
|
||||
if (confirm("Delete this session?")) {
|
||||
if (confirm("删除该会话?此操作不可恢复。")) {
|
||||
onDelete();
|
||||
}
|
||||
}, [onDelete]);
|
||||
@@ -329,7 +361,7 @@ function SessionItem({
|
||||
<div className="relative group">
|
||||
<button
|
||||
onClick={onSelect}
|
||||
className={`w-full flex items-center gap-2 px-3 py-2 text-[13px] rounded-lg transition-all text-left relative pr-8 ${
|
||||
className={`w-full flex items-center gap-2 px-3 py-2 text-[13px] rounded-lg transition-all text-left relative pr-16 ${
|
||||
isActive
|
||||
? "bg-white/70 text-gray-800 font-medium shadow-sm"
|
||||
: "text-gray-500 hover:bg-white/40"
|
||||
@@ -342,40 +374,29 @@ function SessionItem({
|
||||
<span className="truncate">{title}</span>
|
||||
</button>
|
||||
|
||||
{/* More button */}
|
||||
<div className="absolute right-1 top-1/2 -translate-y-1/2" ref={menuRef}>
|
||||
{/* Action buttons: Rename and Delete */}
|
||||
<div className="absolute right-1 top-1/2 -translate-y-1/2 flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity">
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setMenuOpen((v) => !v);
|
||||
setRenameValue(title);
|
||||
setRenaming(true);
|
||||
}}
|
||||
className="p-1 rounded-md text-gray-300 opacity-0 group-hover:opacity-100 hover:text-gray-600 hover:bg-black/[0.04] transition-all"
|
||||
className="p-1 rounded-md text-gray-400 hover:text-gray-700 hover:bg-gray-100 transition-colors"
|
||||
title="重命名"
|
||||
>
|
||||
<MoreHorizontal className="w-3.5 h-3.5" />
|
||||
<Pencil className="w-3.5 h-3.5" />
|
||||
</button>
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleDelete();
|
||||
}}
|
||||
className="p-1 rounded-md text-gray-400 hover:text-red-600 hover:bg-red-50 transition-colors"
|
||||
title="删除会话"
|
||||
>
|
||||
<Trash2 className="w-3.5 h-3.5" />
|
||||
</button>
|
||||
|
||||
{menuOpen && (
|
||||
<div className="absolute right-0 top-full mt-1 w-32 bg-white rounded-lg shadow-lg border border-black/[0.06] py-1 z-50 animate-fade-in-scale">
|
||||
<button
|
||||
onClick={() => {
|
||||
setMenuOpen(false);
|
||||
setRenameValue(title);
|
||||
setRenaming(true);
|
||||
}}
|
||||
className="w-full flex items-center gap-2 px-3 py-1.5 text-[12px] text-gray-600 hover:bg-gray-50 transition-colors"
|
||||
>
|
||||
<Pencil className="w-3 h-3" />
|
||||
Rename
|
||||
</button>
|
||||
<button
|
||||
onClick={handleDelete}
|
||||
className="w-full flex items-center gap-2 px-3 py-1.5 text-[12px] text-red-500 hover:bg-red-50 transition-colors"
|
||||
>
|
||||
<Trash2 className="w-3 h-3" />
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user