From 7c3752a8e6e440951d0d54b0eaf0c2e95b289a01 Mon Sep 17 00:00:00 2001 From: suyao Date: Thu, 19 Jun 2025 14:20:20 +0800 Subject: [PATCH] feat(TopicsHistory): integrate assistant information into topic display - Added functionality to map and display assistant details alongside topics in the TopicsHistory component. - Introduced a new AssistantTag styled component for better visual representation of assistants. - Updated the layout of TopicItem to accommodate assistant information. --- .../history/components/TopicsHistory.tsx | 64 +++++++++++++++---- src/renderer/src/store/tabs.ts | 2 +- src/renderer/src/store/topics.ts | 6 +- 3 files changed, 58 insertions(+), 14 deletions(-) diff --git a/src/renderer/src/pages/history/components/TopicsHistory.tsx b/src/renderer/src/pages/history/components/TopicsHistory.tsx index 13738567f9..0a042c54cf 100644 --- a/src/renderer/src/pages/history/components/TopicsHistory.tsx +++ b/src/renderer/src/pages/history/components/TopicsHistory.tsx @@ -3,6 +3,7 @@ import { VStack } from '@renderer/components/Layout' import useScrollPosition from '@renderer/hooks/useScrollPosition' import { getTopicById } from '@renderer/hooks/useTopic' import { useAppSelector } from '@renderer/store' +import { selectActiveAssistants } from '@renderer/store/assistants' import { selectAllTopics } from '@renderer/store/topics' import { Topic } from '@renderer/types' import { Button, Divider, Empty } from 'antd' @@ -19,6 +20,7 @@ type Props = { const TopicsHistory: React.FC = ({ keywords, onClick, onSearch, ...props }) => { const topics = useAppSelector(selectAllTopics) + const assistants = useAppSelector(selectActiveAssistants) const { t } = useTranslation() const { handleScroll, containerRef } = useScrollPosition('TopicsHistory') @@ -32,6 +34,15 @@ const TopicsHistory: React.FC = ({ keywords, onClick, onSearch, ...props return dayjs(topic.createdAt).format('MM/DD') }) + // 创建助手映射表 + const assistantMap = assistants.reduce( + (map, assistant) => { + map[assistant.id] = assistant + return map + }, + {} as Record + ) + if (isEmpty(filteredTopics)) { return ( @@ -52,17 +63,27 @@ const TopicsHistory: React.FC = ({ keywords, onClick, onSearch, ...props {date} - {items.map((topic) => ( - { - const _topic = await getTopicById(topic.id) - onClick(_topic) - }}> - {topic.name.substring(0, 50)} - {dayjs(topic.updatedAt).format('HH:mm')} - - ))} + {items.map((topic) => { + const assistant = assistantMap[topic.assistantId] + return ( + { + const _topic = await getTopicById(topic.id) + onClick(_topic) + }}> + + {topic.name.substring(0, 50)} + {assistant && ( + + {assistant.emoji} {assistant.name} + + )} + + {dayjs(topic.updatedAt).format('HH:mm')} + + ) + })} ))} {keywords.length >= 2 && ( @@ -114,7 +135,15 @@ const TopicItem = styled.div` flex-direction: row; align-items: center; justify-content: space-between; - height: 30px; + min-height: 30px; + padding: 4px 0; +` + +const TopicContent = styled.div` + display: flex; + flex-direction: column; + gap: 4px; + flex: 1; ` const TopicName = styled.div` @@ -122,10 +151,21 @@ const TopicName = styled.div` color: var(--color-text); ` +const AssistantTag = styled.div` + font-size: 12px; + color: var(--color-text-3); + background: var(--color-fill-quaternary); + padding: 2px 6px; + border-radius: 4px; + display: inline-block; + width: fit-content; +` + const TopicDate = styled.div` font-size: 14px; color: var(--color-text-3); margin-left: 10px; + flex-shrink: 0; ` export default TopicsHistory diff --git a/src/renderer/src/store/tabs.ts b/src/renderer/src/store/tabs.ts index 4f90eb4e81..01dc7b1fb3 100644 --- a/src/renderer/src/store/tabs.ts +++ b/src/renderer/src/store/tabs.ts @@ -5,7 +5,7 @@ export interface Tab { path: string } -interface TabsState { +export interface TabsState { tabs: Tab[] activeTabId: string } diff --git a/src/renderer/src/store/topics.ts b/src/renderer/src/store/topics.ts index b8847f3177..f7adec5f82 100644 --- a/src/renderer/src/store/topics.ts +++ b/src/renderer/src/store/topics.ts @@ -129,8 +129,12 @@ const topicsSlice = createSlice({ // Remove topics from redux topicsAdapter.removeMany(state, topicIds) + state.topicIdsByAssistant[assistantId] = [] + // Create default topic - topicsActions.addDefaultTopic({ assistantId }) + const defaultTopic = getDefaultTopic(assistantId) + topicsAdapter.addOne(state, defaultTopic) + state.topicIdsByAssistant[assistantId] = [defaultTopic.id] }, moveTopic(state, action: PayloadAction) { const { fromAssistantId, toAssistantId, topicId } = action.payload