mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 20:42:30 +08:00
### 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:
@ -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}
|
||||||
|
|||||||
@ -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.referenceChunkImage}
|
||||||
|
></Image>
|
||||||
|
</HoverCardTrigger>
|
||||||
|
<HoverCardContent>
|
||||||
<Image
|
<Image
|
||||||
id={imageId}
|
id={imageId}
|
||||||
className={styles.referenceImagePreview}
|
className={styles.referenceImagePreview}
|
||||||
></Image>
|
></Image>
|
||||||
}
|
</HoverCardContent>
|
||||||
>
|
</HoverCard>
|
||||||
<Image
|
|
||||||
id={imageId}
|
|
||||||
className={styles.referenceChunkImage}
|
|
||||||
></Image>
|
|
||||||
</Popover>
|
|
||||||
)}
|
)}
|
||||||
<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>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -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,40 +98,43 @@ 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
|
|
||||||
messageId={item.id}
|
|
||||||
content={item.content}
|
|
||||||
prompt={item.prompt}
|
|
||||||
showLikeButton={showLikeButton}
|
|
||||||
audioBinary={item.audio_binary}
|
|
||||||
showLoudspeaker={showLoudspeaker}
|
|
||||||
></AssistantGroupButton>
|
|
||||||
)
|
|
||||||
) : (
|
|
||||||
<UserGroupButton
|
|
||||||
content={item.content}
|
|
||||||
messageId={item.id}
|
messageId={item.id}
|
||||||
removeMessageById={removeMessageById}
|
content={item.content}
|
||||||
regenerateMessage={
|
prompt={item.prompt}
|
||||||
regenerateMessage && handleRegenerateMessage
|
showLikeButton={showLikeButton}
|
||||||
}
|
audioBinary={item.audio_binary}
|
||||||
sendLoading={sendLoading}
|
showLoudspeaker={showLoudspeaker}
|
||||||
></UserGroupButton>
|
></AssistantGroupButton>
|
||||||
)}
|
)
|
||||||
|
) : (
|
||||||
|
<UserGroupButton
|
||||||
|
content={item.content}
|
||||||
|
messageId={item.id}
|
||||||
|
removeMessageById={removeMessageById}
|
||||||
|
regenerateMessage={regenerateMessage && handleRegenerateMessage}
|
||||||
|
sendLoading={sendLoading}
|
||||||
|
></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>
|
||||||
|
|||||||
@ -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,
|
||||||
>
|
}}
|
||||||
<DocumentPreviewer
|
>
|
||||||
documentId={documentId}
|
<SheetHeader>
|
||||||
chunk={chunk}
|
<SheetTitle>Document Previewer</SheetTitle>
|
||||||
visible={visible}
|
</SheetHeader>
|
||||||
></DocumentPreviewer>
|
<DocumentPreviewer
|
||||||
</Drawer>
|
documentId={documentId}
|
||||||
|
chunk={chunk}
|
||||||
|
visible={visible}
|
||||||
|
></DocumentPreviewer>
|
||||||
|
</SheetContent>
|
||||||
|
</Sheet>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default PdfDrawer;
|
export default PdfSheet;
|
||||||
|
|||||||
@ -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>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -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>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user