diff --git a/web/app/components/base/chat/chat-with-history/memory/card.tsx b/web/app/components/base/chat/chat-with-history/memory/card/index.tsx similarity index 57% rename from web/app/components/base/chat/chat-with-history/memory/card.tsx rename to web/app/components/base/chat/chat-with-history/memory/card/index.tsx index cda0902c2e..395a654df1 100644 --- a/web/app/components/base/chat/chat-with-history/memory/card.tsx +++ b/web/app/components/base/chat/chat-with-history/memory/card/index.tsx @@ -1,9 +1,15 @@ import React from 'react' import { useTranslation } from 'react-i18next' +import { + RiArrowDownSLine, + RiArrowUpSLine, +} from '@remixicon/react' import { Memory } from '@/app/components/base/icons/src/vender/line/others' +import ActionButton from '@/app/components/base/action-button' import Badge from '@/app/components/base/badge' import Indicator from '@/app/components/header/indicator' -import type { MemoryItem } from './type' +import Operation from './operation' +import type { MemoryItem } from '../type' import cn from '@/utils/classnames' type Props = { @@ -12,25 +18,37 @@ type Props = { const MemoryCard: React.FC = ({ memory }) => { const { t } = useTranslation() + const [isHovering, setIsHovering] = React.useState(false) return ( -
+
setIsHovering(true)} + onMouseLeave={() => setIsHovering(false)} + >
-
+
{memory.name}
+ {isHovering && ( +
+ + + +
+ )}
{memory.content}
{memory.status === 'latest' && ( -
+
{t('share.chat.memory.latestVersion')}
)} {memory.status === 'needUpdate' && ( -
+
{t('share.chat.memory.notLatestVersion', { num: memory.mergeCount })}
diff --git a/web/app/components/base/chat/chat-with-history/memory/card/operation.tsx b/web/app/components/base/chat/chat-with-history/memory/card/operation.tsx new file mode 100644 index 0000000000..4b59129e65 --- /dev/null +++ b/web/app/components/base/chat/chat-with-history/memory/card/operation.tsx @@ -0,0 +1,77 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback, useRef, useState } from 'react' +import { useTranslation } from 'react-i18next' +import { RiCheckLine, RiMoreFill } from '@remixicon/react' +import ActionButton from '@/app/components/base/action-button' +import { + PortalToFollowElem, + PortalToFollowElemContent, + PortalToFollowElemTrigger, +} from '@/app/components/base/portal-to-follow-elem' +import Divider from '@/app/components/base/divider' +import cn from '@/utils/classnames' + +type Props = { +} + +const OperationDropdown: FC = ({ +}) => { + const { t } = useTranslation() + const [open, doSetOpen] = useState(false) + const openRef = useRef(open) + const setOpen = useCallback((v: boolean) => { + doSetOpen(v) + openRef.current = v + }, [doSetOpen]) + + const handleTrigger = useCallback(() => { + setOpen(!openRef.current) + }, [setOpen]) + + return ( + + +
+ + + +
+
+ +
+
+
{t('share.chat.memory.operations.edit')}
+
{t('share.chat.memory.operations.reset')}
+
{t('share.chat.memory.operations.clear')}
+
+ +
+
{t('share.chat.memory.updateVersion.title')}
+
+ {t('share.chat.memory.operations.edit')} + +
+
+ {t('share.chat.memory.operations.edit')} + +
+
+ {t('share.chat.memory.operations.edit')} + +
+
+
+
+
+ ) +} +export default React.memo(OperationDropdown) diff --git a/web/app/components/base/chat/chat-with-history/memory/mock.ts b/web/app/components/base/chat/chat-with-history/memory/mock.ts index b78f95cc25..278da9ee07 100644 --- a/web/app/components/base/chat/chat-with-history/memory/mock.ts +++ b/web/app/components/base/chat/chat-with-history/memory/mock.ts @@ -2,16 +2,27 @@ import type { MemoryItem } from './type' export const mockMemoryList: MemoryItem[] = [ { name: 'learning_companion', - content: 'Learning Goal: [What you\'re studying] \\n Current Level: [Beginner/Intermediate/Advanced] \\n Learning Style: [Visual, hands-on, theoretical, etc.] \\n Progress: [Topics mastered, current focus] \\n Preferred Pace: [Fast/moderate/slow explanations] \\n Background: [Relevant experience or education] \\n Time Constraints: [Available study time]', + content: `Learning Goal: [What you\'re studying] + Current Level: [Beginner/Intermediate/Advanced] + Learning Style: [Visual, hands-on, theoretical, etc.] + Progress: [Topics mastered, current focus] + Preferred Pace: [Fast/moderate/slow explanations] + Background: [Relevant experience or education] + Time Constraints: [Available study time]`, }, { name: 'research_partner', - content: 'Research Topic: [Your research topic] \\n Current Progress: [Literature review, experiments, etc.] \\n Challenges: [What you\'re struggling with] \\n Goals: [Short-term and long-term research goals]', + content: `Research Topic: [Your research topic] + Current Progress: [Literature review, experiments, etc.] + Challenges: [What you\'re struggling with] + Goals: [Short-term and long-term research goals]`, status: 'latest', }, { name: 'code_partner', - content: 'Code Context: [Brief description of the codebase] \\n Current Issues: [Bugs, technical debt, etc.] \\n Goals: [Features to implement, improvements to make]', + content: `Code Context: [Brief description of the codebase] + Current Issues: [Bugs, technical debt, etc.] + Goals: [Features to implement, improvements to make]`, status: 'needUpdate', mergeCount: 5, },