feat(侧边栏): 集成标签筛选功能
- 集成 TagFilter 组件实现标签筛选 - 根据选中标签过滤对话列表 - 在对话项中显示标签(极简 # 文字样式) - 优化对话列表布局适应标签显示
This commit is contained in:
parent
c2b97f0f2d
commit
bbe07e203e
@ -6,11 +6,13 @@ import { Plus, PanelLeft, Trash2, MoreHorizontal, Loader2, Pencil, Check, X, Bot
|
||||
import { UserMenu } from '@/components/ui/UserMenu';
|
||||
import { NewChatModal } from '@/components/features/NewChatModal';
|
||||
import { SearchModal } from '@/components/features/SearchModal';
|
||||
import { TagFilter } from '@/components/features/Tags';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { useConversations } from '@/hooks/useConversations';
|
||||
import { useTagFilter } from '@/hooks/useTags';
|
||||
import { useAuth } from '@/providers/AuthProvider';
|
||||
import type { Conversation } from '@/drizzle/schema';
|
||||
import { useState, useRef, useEffect, useCallback } from 'react';
|
||||
import { useState, useRef, useEffect, useCallback, useMemo } from 'react';
|
||||
import { useHotkeys } from '@/hooks/useHotkeys';
|
||||
|
||||
interface SidebarProps {
|
||||
@ -22,6 +24,7 @@ export function Sidebar({ isOpen = true }: SidebarProps) {
|
||||
const pathname = usePathname();
|
||||
const router = useRouter();
|
||||
const { conversations, loading, deleteConversation, updateConversation } = useConversations();
|
||||
const { selectedTags, selectTag, clearFilter, matchesFilter } = useTagFilter();
|
||||
const { user } = useAuth();
|
||||
const [menuOpen, setMenuOpen] = useState<string | null>(null);
|
||||
const [editingId, setEditingId] = useState<string | null>(null);
|
||||
@ -32,6 +35,12 @@ export function Sidebar({ isOpen = true }: SidebarProps) {
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const menuRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// 根据标签筛选对话
|
||||
const filteredConversations = useMemo(() => {
|
||||
if (selectedTags.length === 0) return conversations;
|
||||
return conversations.filter((conv) => matchesFilter(conv.tags as string[] | null));
|
||||
}, [conversations, selectedTags, matchesFilter]);
|
||||
|
||||
// 聚焦输入框
|
||||
useEffect(() => {
|
||||
if (editingId && inputRef.current) {
|
||||
@ -157,8 +166,8 @@ export function Sidebar({ isOpen = true }: SidebarProps) {
|
||||
}
|
||||
};
|
||||
|
||||
// 按时间分组对话
|
||||
const groupedConversations = groupConversationsByTime(conversations);
|
||||
// 按时间分组对话(使用筛选后的列表)
|
||||
const groupedConversations = groupConversationsByTime(filteredConversations);
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -200,6 +209,17 @@ export function Sidebar({ isOpen = true }: SidebarProps) {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* 标签筛选 */}
|
||||
<TagFilter
|
||||
onFilterChange={(tags) => {
|
||||
if (tags.length > 0) {
|
||||
selectTag(tags[0]);
|
||||
} else {
|
||||
clearFilter();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* 助手库入口 */}
|
||||
<div className="px-4 pb-2">
|
||||
<Link
|
||||
@ -301,13 +321,23 @@ export function Sidebar({ isOpen = true }: SidebarProps) {
|
||||
<Link
|
||||
href={`/chat/${conversation.conversationId}`}
|
||||
className={cn(
|
||||
'block px-3 py-2 rounded-lg text-sm cursor-pointer transition-colors truncate pr-8',
|
||||
'block px-3 py-2 rounded-lg text-sm cursor-pointer transition-colors pr-8',
|
||||
isActive
|
||||
? 'bg-[var(--color-bg-tertiary)] text-[var(--color-text-primary)]'
|
||||
: 'text-[var(--color-text-secondary)] hover:bg-[var(--color-bg-hover)]'
|
||||
)}
|
||||
>
|
||||
{conversation.title}
|
||||
<div className="truncate">{conversation.title}</div>
|
||||
{/* 标签 - 极简文字式 */}
|
||||
{conversation.tags && (conversation.tags as string[]).length > 0 && (
|
||||
<div className="mt-1 text-[10px] text-[var(--color-text-muted)] truncate">
|
||||
{(conversation.tags as string[]).slice(0, 3).map((tag, index) => (
|
||||
<span key={tag} className="text-[var(--color-text-tertiary)]">
|
||||
<span className="opacity-50">#</span>{tag}{index < Math.min((conversation.tags as string[]).length, 3) - 1 ? ' ' : ''}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</Link>
|
||||
)}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user