feat: 工作台对话列表添加删除功能

- 对话卡片 Hover 时显示删除按钮
- 点击删除按钮显示确认弹窗
- 删除按钮垂直居中对齐
This commit is contained in:
2026-03-28 18:04:21 +08:00
parent fb9833663c
commit f46f26fe27
3 changed files with 119 additions and 6 deletions

View File

@@ -1,25 +1,40 @@
import { useState } from 'react';
import { Outlet, useLocation, useNavigate } from 'react-router-dom';
import { FiPlus, FiClock, FiList, FiUsers, FiBox } from 'react-icons/fi';
import { FiTrash2 } from 'react-icons/fi';
import { FaPuzzlePiece } from 'react-icons/fa';
import Layout from '../Layout.jsx';
import SidebarNavItem from './SidebarNavItem.jsx';
import Modal from '../common/Modal.jsx';
import api from '../../services/api.js';
function ConsoleLayout() {
const location = useLocation();
const navigate = useNavigate();
const [deleteTarget, setDeleteTarget] = useState(null);
// 从 URL 提取当前 scene
const sceneMatch = location.pathname.match(/\/console\/chat\/(.+)$/);
const currentScene = sceneMatch ? sceneMatch[1] : null;
// 判断是否在 chat 页面(需要全宽布局)
const isChatPage = location.pathname === '/console/chat' ||
location.pathname.startsWith('/console/chat/');
// sidebar 高亮判断
const isPathActive = (basePath) => location.pathname.startsWith(basePath);
const handleDeleteClick = (e, conv) => {
e.stopPropagation();
setDeleteTarget(conv);
};
const handleDeleteConfirm = () => {
console.log('删除对话:', deleteTarget?.id);
setDeleteTarget(null);
};
const handleDeleteCancel = () => {
setDeleteTarget(null);
};
const sidebar = (
<>
<div className="chat-sidebar-header">
@@ -35,10 +50,21 @@ function ConsoleLayout() {
<div
key={conv.id}
className={`conversation-item ${conv.scene === currentScene ? 'active' : ''}`}
onClick={() => navigate(`/console/chat/${conv.scene}`)}
>
<div className="conversation-title">{conv.title}</div>
<div className="conversation-time">{conv.time}</div>
<div
className="conversation-item__content"
onClick={() => navigate(`/console/chat/${conv.scene}`)}
>
<div className="conversation-title">{conv.title}</div>
<div className="conversation-time">{conv.time}</div>
</div>
<button
className="conversation-item__delete"
onClick={(e) => handleDeleteClick(e, conv)}
title="删除对话"
>
<FiTrash2 size={14} />
</button>
</div>
))}
</div>
@@ -82,6 +108,14 @@ function ConsoleLayout() {
onClick={() => navigate('/console/projects')}
/>
</div>
<Modal
visible={!!deleteTarget}
title="确认删除"
onConfirm={handleDeleteConfirm}
onCancel={handleDeleteCancel}
>
确定要删除对话{deleteTarget?.title}
</Modal>
</>
);

View File

@@ -143,6 +143,9 @@
}
.conversation-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 14px;
border-radius: var(--radius-md);
cursor: pointer;
@@ -153,6 +156,10 @@
&:hover {
background: var(--color-bg-1);
border-color: var(--color-border-2);
.conversation-item__delete {
opacity: 1;
}
}
&.active {
@@ -162,6 +169,30 @@
}
}
.conversation-item__content {
flex: 1;
min-width: 0;
}
.conversation-item__delete {
flex-shrink: 0;
padding: 4px;
margin-left: 8px;
background: transparent;
border: none;
color: var(--color-text-3);
cursor: pointer;
opacity: 0;
transition: all var(--transition);
display: flex;
align-items: center;
justify-content: center;
&:hover {
color: var(--color-danger);
}
}
.conversation-title {
font-size: 14px;
margin-bottom: 4px;