Feat: Replace antd in the chat message with shadcn. #10427 (#11590)

### What problem does this PR solve?

Feat: Replace antd in the chat message with shadcn. #10427

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu
2025-11-28 17:15:01 +08:00
committed by GitHub
parent 3d2e0f1a1b
commit ccce8beeeb
9 changed files with 101 additions and 83 deletions

View File

@ -1,4 +1,4 @@
import PdfDrawer from '@/components/pdf-drawer'; import PdfSheet from '@/components/pdf-drawer';
import { useClickDrawer } from '@/components/pdf-drawer/hooks'; import { useClickDrawer } from '@/components/pdf-drawer/hooks';
import { MessageType } from '@/constants/chat'; import { MessageType } from '@/constants/chat';
import { useFetchExternalChatInfo } from '@/hooks/use-chat-request'; import { useFetchExternalChatInfo } from '@/hooks/use-chat-request';
@ -494,7 +494,7 @@ const FloatingChatWidget = () => {
</div> </div>
</div> </div>
</div> </div>
<PdfDrawer <PdfSheet
visible={visible} visible={visible}
hideModal={hideModal} hideModal={hideModal}
documentId={documentId} documentId={documentId}
@ -695,7 +695,7 @@ const FloatingChatWidget = () => {
</div> </div>
)} )}
</div> </div>
<PdfDrawer <PdfSheet
visible={visible} visible={visible}
hideModal={hideModal} hideModal={hideModal}
documentId={documentId} documentId={documentId}

View File

@ -2,8 +2,6 @@ import Image from '@/components/image';
import SvgIcon from '@/components/svg-icon'; import SvgIcon from '@/components/svg-icon';
import { IReference, IReferenceChunk } from '@/interfaces/database/chat'; import { IReference, IReferenceChunk } from '@/interfaces/database/chat';
import { getExtension } from '@/utils/document-util'; import { getExtension } from '@/utils/document-util';
import { InfoCircleOutlined } from '@ant-design/icons';
import { Button, Flex, Popover } from 'antd';
import DOMPurify from 'dompurify'; import DOMPurify from 'dompurify';
import { useCallback, useEffect, useMemo } from 'react'; import { useCallback, useEffect, useMemo } from 'react';
import Markdown from 'react-markdown'; import Markdown from 'react-markdown';
@ -27,10 +25,16 @@ import {
replaceThinkToSection, replaceThinkToSection,
showImage, showImage,
} from '@/utils/chat'; } from '@/utils/chat';
import classNames from 'classnames'; import classNames from 'classnames';
import { omit } from 'lodash'; import { omit } from 'lodash';
import { pipe } from 'lodash/fp'; import { pipe } from 'lodash/fp';
import { CircleAlert } from 'lucide-react';
import { Button } from '../ui/button';
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from '../ui/hover-card';
import styles from './index.less'; import styles from './index.less';
const getChunkIndex = (match: string) => Number(match); const getChunkIndex = (match: string) => Number(match);
@ -145,20 +149,20 @@ const MarkdownContent = ({
return ( return (
<div key={chunkItem?.id} className="flex gap-2"> <div key={chunkItem?.id} className="flex gap-2">
{imageId && ( {imageId && (
<Popover <HoverCard>
placement="left" <HoverCardTrigger>
content={
<Image
id={imageId}
className={styles.referenceImagePreview}
></Image>
}
>
<Image <Image
id={imageId} id={imageId}
className={styles.referenceChunkImage} className={styles.referenceChunkImage}
></Image> ></Image>
</Popover> </HoverCardTrigger>
<HoverCardContent>
<Image
id={imageId}
className={styles.referenceImagePreview}
></Image>
</HoverCardContent>
</HoverCard>
)} )}
<div className={'space-y-2 max-w-[40vw]'}> <div className={'space-y-2 max-w-[40vw]'}>
<div <div
@ -168,7 +172,7 @@ const MarkdownContent = ({
className={classNames(styles.chunkContentText)} className={classNames(styles.chunkContentText)}
></div> ></div>
{documentId && ( {documentId && (
<Flex gap={'small'}> <section className="flex gap-1">
{fileThumbnail ? ( {fileThumbnail ? (
<img <img
src={fileThumbnail} src={fileThumbnail}
@ -182,8 +186,8 @@ const MarkdownContent = ({
></SvgIcon> ></SvgIcon>
)} )}
<Button <Button
type="link" variant="link"
className={classNames(styles.documentLink, 'text-wrap')} className={'text-wrap p-0'}
onClick={handleDocumentButtonClick( onClick={handleDocumentButtonClick(
documentId, documentId,
chunkItem, chunkItem,
@ -193,7 +197,7 @@ const MarkdownContent = ({
> >
{document?.doc_name} {document?.doc_name}
</Button> </Button>
</Flex> </section>
)} )}
</div> </div>
</div> </div>
@ -228,9 +232,14 @@ const MarkdownContent = ({
} }
></Image> ></Image>
) : ( ) : (
<Popover content={getPopoverContent(chunkIndex)} key={i}> <HoverCard key={i}>
<InfoCircleOutlined className={styles.referenceIcon} /> <HoverCardTrigger>
</Popover> <CircleAlert className="size-4 inline-block" />
</HoverCardTrigger>
<HoverCardContent className="max-w-3xl">
{getPopoverContent(chunkIndex)}
</HoverCardContent>
</HoverCard>
); );
}); });

View File

@ -14,10 +14,10 @@ import {
} from '@/hooks/document-hooks'; } from '@/hooks/document-hooks';
import { IRegenerateMessage, IRemoveMessageById } from '@/hooks/logic-hooks'; import { IRegenerateMessage, IRemoveMessageById } from '@/hooks/logic-hooks';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
import { Avatar, Flex, Space } from 'antd';
import MarkdownContent from '../markdown-content'; import MarkdownContent from '../markdown-content';
import { ReferenceDocumentList } from '../next-message-item/reference-document-list'; import { ReferenceDocumentList } from '../next-message-item/reference-document-list';
import { InnerUploadedMessageFiles } from '../next-message-item/uploaded-message-files'; import { InnerUploadedMessageFiles } from '../next-message-item/uploaded-message-files';
import { RAGFlowAvatar } from '../ragflow-avatar';
import { useTheme } from '../theme-provider'; import { useTheme } from '../theme-provider';
import { AssistantGroupButton, UserGroupButton } from './group-button'; import { AssistantGroupButton, UserGroupButton } from './group-button';
import styles from './index.less'; import styles from './index.less';
@ -98,15 +98,22 @@ const MessageItem = ({
> >
{visibleAvatar && {visibleAvatar &&
(item.role === MessageType.User ? ( (item.role === MessageType.User ? (
<Avatar size={40} src={avatar ?? '/logo.svg'} /> <RAGFlowAvatar
className="size-10"
avatar={avatar ?? '/logo.svg'}
isPerson
/>
) : avatarDialog ? ( ) : avatarDialog ? (
<Avatar size={40} src={avatarDialog} /> <RAGFlowAvatar
className="size-10"
avatar={avatarDialog}
isPerson
/>
) : ( ) : (
<AssistantIcon /> <AssistantIcon />
))} ))}
<Flex vertical gap={8} flex={1}> <section className="flex gap-2 flex-1 flex-col">
<Space>
{isAssistant ? ( {isAssistant ? (
index !== 0 && ( index !== 0 && (
<AssistantGroupButton <AssistantGroupButton
@ -123,15 +130,11 @@ const MessageItem = ({
content={item.content} content={item.content}
messageId={item.id} messageId={item.id}
removeMessageById={removeMessageById} removeMessageById={removeMessageById}
regenerateMessage={ regenerateMessage={regenerateMessage && handleRegenerateMessage}
regenerateMessage && handleRegenerateMessage
}
sendLoading={sendLoading} sendLoading={sendLoading}
></UserGroupButton> ></UserGroupButton>
)} )}
{/* <b>{isAssistant ? '' : nickname}</b> */}
</Space>
<div <div
className={cn( className={cn(
isAssistant isAssistant
@ -159,7 +162,7 @@ const MessageItem = ({
files={documentList} files={documentList}
></InnerUploadedMessageFiles> ></InnerUploadedMessageFiles>
)} )}
</Flex> </section>
</div> </div>
</section> </section>
</div> </div>

View File

@ -1,8 +1,9 @@
import { IModalProps } from '@/interfaces/common'; import { IModalProps } from '@/interfaces/common';
import { IReferenceChunk } from '@/interfaces/database/chat'; import { IReferenceChunk } from '@/interfaces/database/chat';
import { IChunk } from '@/interfaces/database/knowledge'; import { IChunk } from '@/interfaces/database/knowledge';
import { Drawer } from 'antd'; import { cn } from '@/lib/utils';
import DocumentPreviewer from '../pdf-previewer'; import DocumentPreviewer from '../pdf-previewer';
import { Sheet, SheetContent, SheetHeader, SheetTitle } from '../ui/sheet';
interface IProps extends IModalProps<any> { interface IProps extends IModalProps<any> {
documentId: string; documentId: string;
@ -11,7 +12,7 @@ interface IProps extends IModalProps<any> {
height?: string | number; height?: string | number;
} }
export const PdfDrawer = ({ export const PdfSheet = ({
visible = false, visible = false,
hideModal, hideModal,
documentId, documentId,
@ -20,20 +21,25 @@ export const PdfDrawer = ({
height, height,
}: IProps) => { }: IProps) => {
return ( return (
<Drawer <Sheet open onOpenChange={hideModal}>
title="Document Previewer" <SheetContent
onClose={hideModal} className={cn(`max-w-full`)}
open={visible} style={{
width={width} width: width,
height={height} height: height ? height : undefined,
}}
> >
<SheetHeader>
<SheetTitle>Document Previewer</SheetTitle>
</SheetHeader>
<DocumentPreviewer <DocumentPreviewer
documentId={documentId} documentId={documentId}
chunk={chunk} chunk={chunk}
visible={visible} visible={visible}
></DocumentPreviewer> ></DocumentPreviewer>
</Drawer> </SheetContent>
</Sheet>
); );
}; };
export default PdfDrawer; export default PdfSheet;

View File

@ -5,7 +5,7 @@ import { useSendAgentMessage } from './use-send-agent-message';
import { FileUploadProps } from '@/components/file-upload'; import { FileUploadProps } from '@/components/file-upload';
import { NextMessageInput } from '@/components/message-input/next'; import { NextMessageInput } from '@/components/message-input/next';
import MessageItem from '@/components/next-message-item'; import MessageItem from '@/components/next-message-item';
import PdfDrawer from '@/components/pdf-drawer'; import PdfSheet from '@/components/pdf-drawer';
import { useClickDrawer } from '@/components/pdf-drawer/hooks'; import { useClickDrawer } from '@/components/pdf-drawer/hooks';
import { import {
useFetchAgent, useFetchAgent,
@ -127,12 +127,12 @@ function AgentChatBox() {
/> />
)} )}
</section> </section>
<PdfDrawer <PdfSheet
visible={visible} visible={visible}
hideModal={hideModal} hideModal={hideModal}
documentId={documentId} documentId={documentId}
chunk={selectedChunk} chunk={selectedChunk}
></PdfDrawer> ></PdfSheet>
</> </>
); );
} }

View File

@ -2,7 +2,7 @@ import { EmbedContainer } from '@/components/embed-container';
import { FileUploadProps } from '@/components/file-upload'; import { FileUploadProps } from '@/components/file-upload';
import { NextMessageInput } from '@/components/message-input/next'; import { NextMessageInput } from '@/components/message-input/next';
import MessageItem from '@/components/next-message-item'; import MessageItem from '@/components/next-message-item';
import PdfDrawer from '@/components/pdf-drawer'; import PdfSheet from '@/components/pdf-drawer';
import { useClickDrawer } from '@/components/pdf-drawer/hooks'; import { useClickDrawer } from '@/components/pdf-drawer/hooks';
import { MessageType } from '@/constants/chat'; import { MessageType } from '@/constants/chat';
import { useUploadCanvasFileWithProgress } from '@/hooks/use-agent-request'; import { useUploadCanvasFileWithProgress } from '@/hooks/use-agent-request';
@ -204,12 +204,12 @@ const ChatContainer = () => {
</div> </div>
</EmbedContainer> </EmbedContainer>
{visible && ( {visible && (
<PdfDrawer <PdfSheet
visible={visible} visible={visible}
hideModal={hideModal} hideModal={hideModal}
documentId={documentId} documentId={documentId}
chunk={selectedChunk} chunk={selectedChunk}
></PdfDrawer> ></PdfSheet>
)} )}
{parameterDialogVisible && ( {parameterDialogVisible && (
<ParameterDialog <ParameterDialog

View File

@ -2,7 +2,7 @@ import { LargeModelFormFieldWithoutFilter } from '@/components/large-model-form-
import { LlmSettingSchema } from '@/components/llm-setting-items/next'; import { LlmSettingSchema } from '@/components/llm-setting-items/next';
import { NextMessageInput } from '@/components/message-input/next'; import { NextMessageInput } from '@/components/message-input/next';
import MessageItem from '@/components/message-item'; import MessageItem from '@/components/message-item';
import PdfDrawer from '@/components/pdf-drawer'; import PdfSheet from '@/components/pdf-drawer';
import { useClickDrawer } from '@/components/pdf-drawer/hooks'; import { useClickDrawer } from '@/components/pdf-drawer/hooks';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
@ -257,12 +257,12 @@ export function MultipleChatBox({
/> />
</div> </div>
{visible && ( {visible && (
<PdfDrawer <PdfSheet
visible={visible} visible={visible}
hideModal={hideModal} hideModal={hideModal}
documentId={documentId} documentId={documentId}
chunk={selectedChunk} chunk={selectedChunk}
></PdfDrawer> ></PdfSheet>
)} )}
</section> </section>
); );

View File

@ -1,6 +1,6 @@
import { NextMessageInput } from '@/components/message-input/next'; import { NextMessageInput } from '@/components/message-input/next';
import MessageItem from '@/components/message-item'; import MessageItem from '@/components/message-item';
import PdfDrawer from '@/components/pdf-drawer'; import PdfSheet from '@/components/pdf-drawer';
import { useClickDrawer } from '@/components/pdf-drawer/hooks'; import { useClickDrawer } from '@/components/pdf-drawer/hooks';
import { MessageType } from '@/constants/chat'; import { MessageType } from '@/constants/chat';
import { import {
@ -101,12 +101,12 @@ export function SingleChatBox({ controller, stopOutputMessage }: IProps) {
removeFile={removeFile} removeFile={removeFile}
/> />
{visible && ( {visible && (
<PdfDrawer <PdfSheet
visible={visible} visible={visible}
hideModal={hideModal} hideModal={hideModal}
documentId={documentId} documentId={documentId}
chunk={selectedChunk} chunk={selectedChunk}
></PdfDrawer> ></PdfSheet>
)} )}
</section> </section>
); );

View File

@ -1,7 +1,7 @@
import { EmbedContainer } from '@/components/embed-container'; import { EmbedContainer } from '@/components/embed-container';
import { NextMessageInput } from '@/components/message-input/next'; import { NextMessageInput } from '@/components/message-input/next';
import MessageItem from '@/components/message-item'; import MessageItem from '@/components/message-item';
import PdfDrawer from '@/components/pdf-drawer'; import PdfSheet from '@/components/pdf-drawer';
import { useClickDrawer } from '@/components/pdf-drawer/hooks'; import { useClickDrawer } from '@/components/pdf-drawer/hooks';
import { MessageType, SharedFrom } from '@/constants/chat'; import { MessageType, SharedFrom } from '@/constants/chat';
import { useFetchNextConversationSSE } from '@/hooks/chat-hooks'; import { useFetchNextConversationSSE } from '@/hooks/chat-hooks';
@ -123,12 +123,12 @@ const ChatContainer = () => {
</div> </div>
</EmbedContainer> </EmbedContainer>
{visible && ( {visible && (
<PdfDrawer <PdfSheet
visible={visible} visible={visible}
hideModal={hideModal} hideModal={hideModal}
documentId={documentId} documentId={documentId}
chunk={selectedChunk} chunk={selectedChunk}
></PdfDrawer> ></PdfSheet>
)} )}
</> </>
); );