diff --git a/web/src/components/auto-keywords-item.tsx b/web/src/components/auto-keywords-item.tsx deleted file mode 100644 index a18c161e4..000000000 --- a/web/src/components/auto-keywords-item.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { useTranslate } from '@/hooks/common-hooks'; -import { Flex, Form, InputNumber, Slider } from 'antd'; - -export const AutoKeywordsItem = () => { - const { t } = useTranslate('knowledgeDetails'); - - return ( - - - - - - - - - - - - - ); -}; - -export const AutoQuestionsItem = () => { - const { t } = useTranslate('knowledgeDetails'); - - return ( - - - - - - - - - - - - - ); -}; diff --git a/web/src/components/chunk-method-modal/hooks.ts b/web/src/components/chunk-method-modal/hooks.ts deleted file mode 100644 index 635843a38..000000000 --- a/web/src/components/chunk-method-modal/hooks.ts +++ /dev/null @@ -1,161 +0,0 @@ -import { DocumentParserType } from '@/constants/knowledge'; -import { useHandleChunkMethodSelectChange } from '@/hooks/logic-hooks'; -import { useSelectParserList } from '@/hooks/use-user-setting-request'; -import { FormInstance } from 'antd'; -import { useCallback, useEffect, useMemo, useState } from 'react'; - -const ParserListMap = new Map([ - [ - ['pdf'], - [ - DocumentParserType.Naive, - DocumentParserType.Resume, - DocumentParserType.Manual, - DocumentParserType.Paper, - DocumentParserType.Book, - DocumentParserType.Laws, - DocumentParserType.Presentation, - DocumentParserType.One, - DocumentParserType.Qa, - DocumentParserType.KnowledgeGraph, - ], - ], - [ - ['doc', 'docx'], - [ - DocumentParserType.Naive, - DocumentParserType.Resume, - DocumentParserType.Book, - DocumentParserType.Laws, - DocumentParserType.One, - DocumentParserType.Qa, - DocumentParserType.Manual, - DocumentParserType.KnowledgeGraph, - ], - ], - [ - ['xlsx', 'xls'], - [ - DocumentParserType.Naive, - DocumentParserType.Qa, - DocumentParserType.Table, - DocumentParserType.One, - DocumentParserType.KnowledgeGraph, - ], - ], - [['ppt', 'pptx'], [DocumentParserType.Presentation]], - [ - ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tif', 'tiff', 'webp', 'svg', 'ico'], - [DocumentParserType.Picture], - ], - [ - ['txt'], - [ - DocumentParserType.Naive, - DocumentParserType.Resume, - DocumentParserType.Book, - DocumentParserType.Laws, - DocumentParserType.One, - DocumentParserType.Qa, - DocumentParserType.Table, - DocumentParserType.KnowledgeGraph, - ], - ], - [ - ['csv'], - [ - DocumentParserType.Naive, - DocumentParserType.Resume, - DocumentParserType.Book, - DocumentParserType.Laws, - DocumentParserType.One, - DocumentParserType.Qa, - DocumentParserType.Table, - DocumentParserType.KnowledgeGraph, - ], - ], - [ - ['md'], - [ - DocumentParserType.Naive, - DocumentParserType.Qa, - DocumentParserType.KnowledgeGraph, - ], - ], - [['json'], [DocumentParserType.Naive, DocumentParserType.KnowledgeGraph]], - [['eml'], [DocumentParserType.Email]], -]); - -const getParserList = ( - values: string[], - parserList: Array<{ - value: string; - label: string; - }>, -) => { - return parserList.filter((x) => values?.some((y) => y === x.value)); -}; - -export const useFetchParserListOnMount = ( - documentId: string, - parserId: DocumentParserType, - documentExtension: string, - form: FormInstance, -) => { - const [selectedTag, setSelectedTag] = useState(); - const parserList = useSelectParserList(); - const handleChunkMethodSelectChange = useHandleChunkMethodSelectChange(form); - - const nextParserList = useMemo(() => { - const key = [...ParserListMap.keys()].find((x) => - x.some((y) => y === documentExtension), - ); - if (key) { - const values = ParserListMap.get(key); - return getParserList(values ?? [], parserList); - } - - return getParserList( - [ - DocumentParserType.Naive, - DocumentParserType.Resume, - DocumentParserType.Book, - DocumentParserType.Laws, - DocumentParserType.One, - DocumentParserType.Qa, - DocumentParserType.Table, - ], - parserList, - ); - }, [parserList, documentExtension]); - - useEffect(() => { - setSelectedTag(parserId); - }, [parserId, documentId]); - - const handleChange = (tag: string) => { - handleChunkMethodSelectChange(tag); - setSelectedTag(tag as DocumentParserType); - }; - - return { parserList: nextParserList, handleChange, selectedTag }; -}; - -const hideAutoKeywords = [ - DocumentParserType.Qa, - DocumentParserType.Table, - DocumentParserType.Resume, - DocumentParserType.KnowledgeGraph, - DocumentParserType.Tag, -]; - -export const useShowAutoKeywords = () => { - const showAutoKeywords = useCallback( - (selectedTag: DocumentParserType | undefined) => { - return hideAutoKeywords.every((x) => selectedTag !== x); - }, - [], - ); - - return showAutoKeywords; -}; diff --git a/web/src/components/chunk-method-modal/index.less b/web/src/components/chunk-method-modal/index.less deleted file mode 100644 index ec79449bf..000000000 --- a/web/src/components/chunk-method-modal/index.less +++ /dev/null @@ -1,14 +0,0 @@ -.pageInputNumber { - width: 220px; -} - -.questionIcon { - margin-inline-start: 4px; - color: rgba(0, 0, 0, 0.45); - cursor: help; - writing-mode: horizontal-tb; -} - -.chunkMethod { - margin-bottom: 0; -} diff --git a/web/src/components/chunk-method-modal/index.tsx b/web/src/components/chunk-method-modal/index.tsx deleted file mode 100644 index 27106ada5..000000000 --- a/web/src/components/chunk-method-modal/index.tsx +++ /dev/null @@ -1,350 +0,0 @@ -import MaxTokenNumber from '@/components/max-token-number'; -import { IModalManagerChildrenProps } from '@/components/modal-manager'; -import { - MinusCircleOutlined, - PlusOutlined, - QuestionCircleOutlined, -} from '@ant-design/icons'; -import { - Button, - Divider, - Form, - InputNumber, - Modal, - Select, - Space, - Tooltip, -} from 'antd'; -import omit from 'lodash/omit'; -import React, { useEffect, useMemo } from 'react'; -import { useFetchParserListOnMount, useShowAutoKeywords } from './hooks'; - -import { DocumentParserType } from '@/constants/knowledge'; -import { useTranslate } from '@/hooks/common-hooks'; -import { useFetchKnowledgeBaseConfiguration } from '@/hooks/use-knowledge-request'; -import { IParserConfig } from '@/interfaces/database/document'; -import { IChangeParserConfigRequestBody } from '@/interfaces/request/document'; -import { get } from 'lodash'; -import { AutoKeywordsItem, AutoQuestionsItem } from '../auto-keywords-item'; -import { DatasetConfigurationContainer } from '../dataset-configuration-container'; -import Delimiter from '../delimiter'; -import EntityTypesItem from '../entity-types-item'; -import ExcelToHtml from '../excel-to-html'; -import LayoutRecognize from '../layout-recognize'; -import ParseConfiguration, { - showRaptorParseConfiguration, -} from '../parse-configuration'; -import { - UseGraphRagItem, - showGraphRagItems, -} from '../parse-configuration/graph-rag-items'; -import styles from './index.less'; - -interface IProps extends Omit { - loading: boolean; - onOk: ( - parserId: DocumentParserType | undefined, - parserConfig: IChangeParserConfigRequestBody, - ) => void; - showModal?(): void; - parserId: DocumentParserType; - parserConfig: IParserConfig; - documentExtension: string; - documentId: string; -} - -const hidePagesChunkMethods = [ - DocumentParserType.Qa, - DocumentParserType.Table, - DocumentParserType.Picture, - DocumentParserType.Resume, - DocumentParserType.One, - DocumentParserType.KnowledgeGraph, -]; - -const ChunkMethodModal: React.FC = ({ - documentId, - parserId, - onOk, - hideModal, - visible, - documentExtension, - parserConfig, - loading, -}) => { - const [form] = Form.useForm(); - const { parserList, handleChange, selectedTag } = useFetchParserListOnMount( - documentId, - parserId, - documentExtension, - form, - ); - const { t } = useTranslate('knowledgeDetails'); - const { data: knowledgeDetails } = useFetchKnowledgeBaseConfiguration(); - - const useGraphRag = useMemo(() => { - return knowledgeDetails.parser_config?.graphrag?.use_graphrag; - }, [knowledgeDetails.parser_config?.graphrag?.use_graphrag]); - - const handleOk = async () => { - const values = await form.validateFields(); - const parser_config = { - ...values.parser_config, - pages: values.pages?.map((x: any) => [x.from, x.to]) ?? [], - }; - onOk(selectedTag, parser_config); - }; - - const isPdf = documentExtension === 'pdf'; - - const showPages = useMemo(() => { - return isPdf && hidePagesChunkMethods.every((x) => x !== selectedTag); - }, [selectedTag, isPdf]); - - const showOne = useMemo(() => { - return ( - isPdf && - hidePagesChunkMethods - .filter((x) => x !== DocumentParserType.One) - .every((x) => x !== selectedTag) - ); - }, [selectedTag, isPdf]); - - const showMaxTokenNumber = - selectedTag === DocumentParserType.Naive || - selectedTag === DocumentParserType.KnowledgeGraph; - - const showEntityTypes = selectedTag === DocumentParserType.KnowledgeGraph; - - const showExcelToHtml = - selectedTag === DocumentParserType.Naive && documentExtension === 'xlsx'; - - const showAutoKeywords = useShowAutoKeywords(); - - const afterClose = () => { - form.resetFields(); - }; - - useEffect(() => { - if (visible) { - const pages = - parserConfig?.pages?.map((x) => ({ from: x[0], to: x[1] })) ?? []; - form.setFieldsValue({ - pages: pages.length > 0 ? pages : [{ from: 1, to: 1024 }], - parser_config: { - ...omit(parserConfig, 'pages'), - graphrag: { - use_graphrag: get( - parserConfig, - 'graphrag.use_graphrag', - useGraphRag, - ), - }, - }, - }); - } - }, [ - form, - knowledgeDetails.parser_config, - parserConfig, - useGraphRag, - visible, - ]); - - return ( - - - - - ); -}; - -const Delimiter = () => { - const { t } = useTranslation(); - - return ( - - - - ); -}; - -export default Delimiter; diff --git a/web/src/components/entity-types-item.tsx b/web/src/components/entity-types-item.tsx deleted file mode 100644 index 3a6ccb858..000000000 --- a/web/src/components/entity-types-item.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { useTranslate } from '@/hooks/common-hooks'; -import { Form } from 'antd'; -import EditTag from './edit-tag'; - -const initialEntityTypes = [ - 'organization', - 'person', - 'geo', - 'event', - 'category', -]; - -type IProps = { - field?: string[]; -}; - -const EntityTypesItem = ({ - field = ['parser_config', 'entity_types'], -}: IProps) => { - const { t } = useTranslate('knowledgeConfiguration'); - return ( - - - - ); -}; - -export default EntityTypesItem; diff --git a/web/src/components/excel-to-html.tsx b/web/src/components/excel-to-html.tsx deleted file mode 100644 index e236a12f3..000000000 --- a/web/src/components/excel-to-html.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { useTranslate } from '@/hooks/common-hooks'; -import { Form, Switch } from 'antd'; - -const ExcelToHtml = () => { - const { t } = useTranslate('knowledgeDetails'); - return ( - - - - ); -}; - -export default ExcelToHtml; diff --git a/web/src/components/feedback-dialog.tsx b/web/src/components/feedback-dialog.tsx new file mode 100644 index 000000000..7b39dbc48 --- /dev/null +++ b/web/src/components/feedback-dialog.tsx @@ -0,0 +1,77 @@ +import { IModalProps } from '@/interfaces/common'; +import { IFeedbackRequestBody } from '@/interfaces/request/chat'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { useCallback } from 'react'; +import { useForm } from 'react-hook-form'; +import { useTranslation } from 'react-i18next'; +import { z } from 'zod'; +import { RAGFlowFormItem } from './ragflow-form'; +import { ButtonLoading } from './ui/button'; +import { + Dialog, + DialogContent, + DialogFooter, + DialogHeader, + DialogTitle, +} from './ui/dialog'; +import { Form } from './ui/form'; +import { Textarea } from './ui/textarea'; + +const FormId = 'feedback-dialog'; + +const FeedbackDialog = ({ + visible, + hideModal, + onOk, + loading, +}: IModalProps) => { + const { t } = useTranslation(); + const FormSchema = z.object({ + feedback: z + .string() + .min(1, { + message: t('common.namePlaceholder'), + }) + .trim(), + }); + + const form = useForm>({ + resolver: zodResolver(FormSchema), + defaultValues: { feedback: '' }, + }); + + const handleOk = useCallback( + async (data: z.infer) => { + return onOk?.({ thumbup: false, feedback: data.feedback }); + }, + [onOk], + ); + + return ( + + + + Feedback + +
+ + + + +
+ + + + {t('common.save')} + + +
+
+ ); +}; + +export default FeedbackDialog; diff --git a/web/src/components/file-upload-modal/index.less b/web/src/components/file-upload-modal/index.less deleted file mode 100644 index 8472339fe..000000000 --- a/web/src/components/file-upload-modal/index.less +++ /dev/null @@ -1,13 +0,0 @@ -.uploader { - :global { - .ant-upload-list { - max-height: 40vh; - overflow-y: auto; - } - } -} - -.uploadLimit { - color: red; - font-size: 12px; -} diff --git a/web/src/components/file-upload-modal/index.tsx b/web/src/components/file-upload-modal/index.tsx deleted file mode 100644 index cc6b545aa..000000000 --- a/web/src/components/file-upload-modal/index.tsx +++ /dev/null @@ -1,191 +0,0 @@ -import { useTranslate } from '@/hooks/common-hooks'; -import { IModalProps } from '@/interfaces/common'; -import { InboxOutlined } from '@ant-design/icons'; -import { - Checkbox, - Flex, - Modal, - Progress, - Segmented, - Tabs, - TabsProps, - Upload, - UploadFile, - UploadProps, -} from 'antd'; -import { Dispatch, SetStateAction, useState } from 'react'; - -import styles from './index.less'; - -const { Dragger } = Upload; - -const FileUpload = ({ - directory, - fileList, - setFileList, - uploadProgress, -}: { - directory: boolean; - fileList: UploadFile[]; - setFileList: Dispatch>; - uploadProgress?: number; -}) => { - const { t } = useTranslate('fileManager'); - const props: UploadProps = { - multiple: true, - onRemove: (file) => { - const index = fileList.indexOf(file); - const newFileList = fileList.slice(); - newFileList.splice(index, 1); - setFileList(newFileList); - }, - beforeUpload: (file: UploadFile) => { - setFileList((pre) => { - return [...pre, file]; - }); - - return false; - }, - directory, - fileList, - progress: { - strokeWidth: 2, - }, - }; - - return ( - <> - - -

- -

-

{t('uploadTitle')}

-

{t('uploadDescription')}

- {false &&

{t('uploadLimit')}

} -
- - ); -}; - -interface IFileUploadModalProps - extends IModalProps< - { parseOnCreation: boolean; directoryFileList: UploadFile[] } | UploadFile[] - > { - uploadFileList?: UploadFile[]; - setUploadFileList?: Dispatch>; - uploadProgress?: number; - setUploadProgress?: Dispatch>; -} - -const FileUploadModal = ({ - visible, - hideModal, - loading, - onOk: onFileUploadOk, - uploadFileList: fileList, - setUploadFileList: setFileList, - uploadProgress, - setUploadProgress, -}: IFileUploadModalProps) => { - const { t } = useTranslate('fileManager'); - const [value, setValue] = useState('local'); - const [parseOnCreation, setParseOnCreation] = useState(false); - const [currentFileList, setCurrentFileList] = useState([]); - const [directoryFileList, setDirectoryFileList] = useState([]); - - const clearFileList = () => { - if (setFileList) { - setFileList([]); - setUploadProgress?.(0); - } else { - setCurrentFileList([]); - } - setDirectoryFileList([]); - }; - - const onOk = async () => { - if (uploadProgress === 100) { - hideModal?.(); - return; - } - - const ret = await onFileUploadOk?.( - fileList - ? { parseOnCreation, directoryFileList } - : [...currentFileList, ...directoryFileList], - ); - return ret; - }; - - const afterClose = () => { - clearFileList(); - }; - - const items: TabsProps['items'] = [ - { - key: '1', - label: t('file'), - children: ( - - ), - }, - { - key: '2', - label: t('directory'), - children: ( - - ), - }, - ]; - - return ( - <> - - - - {value === 'local' ? ( - <> - setParseOnCreation(e.target.checked)} - > - {t('parseOnCreation')} - - - - ) : ( - t('comingSoon', { keyPrefix: 'common' }) - )} - - - - ); -}; - -export default FileUploadModal; diff --git a/web/src/components/layout-recognize.tsx b/web/src/components/layout-recognize.tsx deleted file mode 100644 index 13ec88e65..000000000 --- a/web/src/components/layout-recognize.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { LlmModelType } from '@/constants/knowledge'; -import { useTranslate } from '@/hooks/common-hooks'; -import { useSelectLlmOptionsByModelType } from '@/hooks/use-llm-request'; -import { Form, Select } from 'antd'; -import { camelCase } from 'lodash'; -import { useMemo } from 'react'; - -const enum DocumentType { - DeepDOC = 'DeepDOC', - PlainText = 'Plain Text', -} - -const LayoutRecognize = () => { - const { t } = useTranslate('knowledgeDetails'); - const allOptions = useSelectLlmOptionsByModelType(); - - const options = useMemo(() => { - const list = [DocumentType.DeepDOC, DocumentType.PlainText].map((x) => ({ - label: x === DocumentType.PlainText ? t(camelCase(x)) : 'DeepDoc', - value: x, - })); - - const image2TextList = allOptions[LlmModelType.Image2text].map((x) => { - return { - ...x, - options: x.options.map((y) => { - return { - ...y, - label: ( -
- {y.label} - Experimental -
- ), - }; - }), - }; - }); - - return [...list, ...image2TextList]; - }, [allOptions, t]); - - return ( - - ( - - {option.label} - {option.data.description} - - )} - onChange={onChange} - value={value} - disabled={disabled} - > - ); -}; - -export default LLMToolsSelect; diff --git a/web/src/components/max-token-number.tsx b/web/src/components/max-token-number.tsx deleted file mode 100644 index c64b40fac..000000000 --- a/web/src/components/max-token-number.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { useTranslate } from '@/hooks/common-hooks'; -import { Flex, Form, InputNumber, Slider } from 'antd'; - -interface IProps { - initialValue?: number; - max?: number; -} - -const MaxTokenNumber = ({ initialValue = 512, max = 2048 }: IProps) => { - const { t } = useTranslate('knowledgeConfiguration'); - - return ( - - - - - - - - - - - - - ); -}; - -export default MaxTokenNumber; diff --git a/web/src/components/message-history-window-size-item.tsx b/web/src/components/message-history-window-size-item.tsx index e717076e5..69df072b1 100644 --- a/web/src/components/message-history-window-size-item.tsx +++ b/web/src/components/message-history-window-size-item.tsx @@ -1,4 +1,3 @@ -import { Form, InputNumber } from 'antd'; import { useFormContext } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import { @@ -10,27 +9,6 @@ import { } from './ui/form'; import { NumberInput } from './ui/input'; -const MessageHistoryWindowSizeItem = ({ - initialValue, -}: { - initialValue: number; -}) => { - const { t } = useTranslation(); - - return ( - - - - ); -}; - -export default MessageHistoryWindowSizeItem; - export function MessageHistoryWindowSizeFormField() { const form = useFormContext(); const { t } = useTranslation(); diff --git a/web/src/components/message-item/feedback-modal.tsx b/web/src/components/message-item/feedback-modal.tsx deleted file mode 100644 index c2a471c7b..000000000 --- a/web/src/components/message-item/feedback-modal.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { Form, Input, Modal } from 'antd'; - -import { IModalProps } from '@/interfaces/common'; -import { IFeedbackRequestBody } from '@/interfaces/request/chat'; -import { useCallback } from 'react'; - -type FieldType = { - feedback?: string; -}; - -const FeedbackModal = ({ - visible, - hideModal, - onOk, - loading, -}: IModalProps) => { - const [form] = Form.useForm(); - - const handleOk = useCallback(async () => { - const ret = await form.validateFields(); - return onOk?.({ thumbup: false, feedback: ret.feedback }); - }, [onOk, form]); - - return ( - -
- - name="feedback" - rules={[{ required: true, message: 'Please input your feedback!' }]} - > - - - -
- ); -}; - -export default FeedbackModal; diff --git a/web/src/components/message-item/group-button.tsx b/web/src/components/message-item/group-button.tsx index 98085b92f..aad19cb40 100644 --- a/web/src/components/message-item/group-button.tsx +++ b/web/src/components/message-item/group-button.tsx @@ -13,9 +13,9 @@ import { import { Radio, Tooltip } from 'antd'; import { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; -import FeedbackModal from './feedback-modal'; +import FeedbackDialog from '../feedback-dialog'; +import { PromptDialog } from '../prompt-dialog'; import { useRemoveMessage, useSendFeedback, useSpeech } from './hooks'; -import PromptModal from './prompt-modal'; interface IProps { messageId: string; @@ -79,19 +79,19 @@ export const AssistantGroupButton = ({ )} {visible && ( - + > )} {promptVisible && ( - + > )} ); diff --git a/web/src/components/message-item/prompt-modal.tsx b/web/src/components/message-item/prompt-modal.tsx deleted file mode 100644 index f5222e59b..000000000 --- a/web/src/components/message-item/prompt-modal.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { IModalProps } from '@/interfaces/common'; -import { IFeedbackRequestBody } from '@/interfaces/request/chat'; -import { Modal, Space } from 'antd'; -import HightLightMarkdown from '../highlight-markdown'; -import SvgIcon from '../svg-icon'; - -const PromptModal = ({ - visible, - hideModal, - prompt, -}: IModalProps & { prompt?: string }) => { - return ( - - - Prompt -
- } - width={'80%'} - open={visible} - onCancel={hideModal} - footer={null} - > - {prompt} -
- ); -}; - -export default PromptModal; diff --git a/web/src/components/next-message-item/feedback-modal.tsx b/web/src/components/next-message-item/feedback-modal.tsx deleted file mode 100644 index c2a471c7b..000000000 --- a/web/src/components/next-message-item/feedback-modal.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { Form, Input, Modal } from 'antd'; - -import { IModalProps } from '@/interfaces/common'; -import { IFeedbackRequestBody } from '@/interfaces/request/chat'; -import { useCallback } from 'react'; - -type FieldType = { - feedback?: string; -}; - -const FeedbackModal = ({ - visible, - hideModal, - onOk, - loading, -}: IModalProps) => { - const [form] = Form.useForm(); - - const handleOk = useCallback(async () => { - const ret = await form.validateFields(); - return onOk?.({ thumbup: false, feedback: ret.feedback }); - }, [onOk, form]); - - return ( - -
- - name="feedback" - rules={[{ required: true, message: 'Please input your feedback!' }]} - > - - - -
- ); -}; - -export default FeedbackModal; diff --git a/web/src/components/next-message-item/group-button.tsx b/web/src/components/next-message-item/group-button.tsx index 5c064239f..1719511de 100644 --- a/web/src/components/next-message-item/group-button.tsx +++ b/web/src/components/next-message-item/group-button.tsx @@ -17,10 +17,10 @@ import { Radio, Tooltip } from 'antd'; import { Download, NotebookText } from 'lucide-react'; import { useCallback, useContext } from 'react'; import { useTranslation } from 'react-i18next'; +import FeedbackDialog from '../feedback-dialog'; +import { PromptDialog } from '../prompt-dialog'; import { ToggleGroup, ToggleGroupItem } from '../ui/toggle-group'; -import FeedbackModal from './feedback-modal'; import { useRemoveMessage, useSendFeedback, useSpeech } from './hooks'; -import PromptModal from './prompt-modal'; interface IProps { messageId: string; @@ -129,19 +129,19 @@ export const AssistantGroupButton = ({ )} {visible && ( - + > )} {promptVisible && ( - + > )} ); diff --git a/web/src/components/next-message-item/prompt-modal.tsx b/web/src/components/next-message-item/prompt-modal.tsx deleted file mode 100644 index f5222e59b..000000000 --- a/web/src/components/next-message-item/prompt-modal.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { IModalProps } from '@/interfaces/common'; -import { IFeedbackRequestBody } from '@/interfaces/request/chat'; -import { Modal, Space } from 'antd'; -import HightLightMarkdown from '../highlight-markdown'; -import SvgIcon from '../svg-icon'; - -const PromptModal = ({ - visible, - hideModal, - prompt, -}: IModalProps & { prompt?: string }) => { - return ( - - - Prompt - - } - width={'80%'} - open={visible} - onCancel={hideModal} - footer={null} - > - {prompt} - - ); -}; - -export default PromptModal; diff --git a/web/src/components/operate-dropdown/index.less b/web/src/components/operate-dropdown/index.less deleted file mode 100644 index 8c3dcd72b..000000000 --- a/web/src/components/operate-dropdown/index.less +++ /dev/null @@ -1,4 +0,0 @@ -.delete { - // height: 24px; - display: inline-block; -} diff --git a/web/src/components/operate-dropdown/index.tsx b/web/src/components/operate-dropdown/index.tsx deleted file mode 100644 index f243ad2b7..000000000 --- a/web/src/components/operate-dropdown/index.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import { useShowDeleteConfirm } from '@/hooks/common-hooks'; -import { DeleteOutlined, MoreOutlined } from '@ant-design/icons'; -import { Dropdown, MenuProps, Space } from 'antd'; -import { useTranslation } from 'react-i18next'; - -import React, { useMemo } from 'react'; -import styles from './index.less'; - -interface IProps { - deleteItem: () => Promise | void; - iconFontSize?: number; - iconFontColor?: string; - items?: MenuProps['items']; - height?: number; - needsDeletionValidation?: boolean; - showDeleteItems?: boolean; -} - -const OperateDropdown = ({ - deleteItem, - children, - iconFontSize = 30, - iconFontColor = 'gray', - items: otherItems = [], - height = 24, - needsDeletionValidation = true, - showDeleteItems = true, -}: React.PropsWithChildren) => { - const { t } = useTranslation(); - const showDeleteConfirm = useShowDeleteConfirm(); - - const handleDelete = () => { - if (needsDeletionValidation) { - showDeleteConfirm({ onOk: deleteItem }); - } else { - deleteItem(); - } - }; - - const handleDropdownMenuClick: MenuProps['onClick'] = ({ domEvent, key }) => { - domEvent.preventDefault(); - domEvent.stopPropagation(); - if (key === '1') { - handleDelete(); - } - }; - - const items: MenuProps['items'] = useMemo(() => { - const items = []; - - if (showDeleteItems) { - items.push({ - key: '1', - label: ( - - {t('common.delete')} - - - ), - }); - } - - return [...items, ...otherItems]; - }, [showDeleteItems, otherItems, t]); - - return ( - - {children || ( - - - - )} - - ); -}; - -export default OperateDropdown; diff --git a/web/src/components/page-rank.tsx b/web/src/components/page-rank.tsx deleted file mode 100644 index 24579d759..000000000 --- a/web/src/components/page-rank.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { useTranslate } from '@/hooks/common-hooks'; -import { Flex, Form, InputNumber, Slider } from 'antd'; - -const PageRank = () => { - const { t } = useTranslate('knowledgeConfiguration'); - - return ( - - - - - - - - - - - - - ); -}; - -export default PageRank; diff --git a/web/src/components/parse-configuration/graph-rag-items.tsx b/web/src/components/parse-configuration/graph-rag-items.tsx deleted file mode 100644 index 04e3f0150..000000000 --- a/web/src/components/parse-configuration/graph-rag-items.tsx +++ /dev/null @@ -1,138 +0,0 @@ -import { DocumentParserType } from '@/constants/knowledge'; -import { useTranslate } from '@/hooks/common-hooks'; -import { cn } from '@/lib/utils'; -import { Form, Select, Switch } from 'antd'; -import { upperFirst } from 'lodash'; -import { useCallback, useMemo } from 'react'; -import { DatasetConfigurationContainer } from '../dataset-configuration-container'; -import EntityTypesItem from '../entity-types-item'; - -const excludedTagParseMethods = [ - DocumentParserType.Table, - DocumentParserType.KnowledgeGraph, - DocumentParserType.Tag, -]; - -export const showTagItems = (parserId: DocumentParserType) => { - return !excludedTagParseMethods.includes(parserId); -}; - -const enum MethodValue { - General = 'general', - Light = 'light', -} - -export const excludedParseMethods = [ - DocumentParserType.Table, - DocumentParserType.Resume, - DocumentParserType.Picture, - DocumentParserType.KnowledgeGraph, - DocumentParserType.Qa, - DocumentParserType.Tag, -]; - -export const showGraphRagItems = (parserId: DocumentParserType | undefined) => { - return !excludedParseMethods.some((x) => x === parserId); -}; - -type GraphRagItemsProps = { - marginBottom?: boolean; -}; - -export function UseGraphRagItem() { - const { t } = useTranslate('knowledgeConfiguration'); - - return ( - - - - ); -} - -// The three types "table", "resume" and "one" do not display this configuration. -const GraphRagItems = ({ marginBottom = false }: GraphRagItemsProps) => { - const { t } = useTranslate('knowledgeConfiguration'); - - const methodOptions = useMemo(() => { - return [MethodValue.Light, MethodValue.General].map((x) => ({ - value: x, - label: upperFirst(x), - })); - }, []); - - const renderWideTooltip = useCallback( - (title: React.ReactNode | string) => { - return { - title: typeof title === 'string' ? t(title) : title, - overlayInnerStyle: { width: '32vw' }, - }; - }, - [t], - ); - - return ( - - - - prevValues.parser_config.graphrag.use_graphrag !== - curValues.parser_config.graphrag.use_graphrag - } - > - {({ getFieldValue }) => { - const useRaptor = getFieldValue([ - 'parser_config', - 'graphrag', - 'use_graphrag', - ]); - - return ( - useRaptor && ( - <> - - , - )} - initialValue={MethodValue.Light} - > - - - - - ); -}; - -export default RenameModal; diff --git a/web/src/components/rerank.tsx b/web/src/components/rerank.tsx index 62ffe01e5..808940bac 100644 --- a/web/src/components/rerank.tsx +++ b/web/src/components/rerank.tsx @@ -1,8 +1,6 @@ import { LlmModelType } from '@/constants/knowledge'; import { useTranslate } from '@/hooks/common-hooks'; import { useSelectLlmOptionsByModelType } from '@/hooks/use-llm-request'; -import { Select as AntSelect, Form, message, Slider } from 'antd'; -import { useCallback } from 'react'; import { useFormContext } from 'react-hook-form'; import { z } from 'zod'; import { SelectWithSearch } from './originui/select-with-search'; @@ -15,47 +13,6 @@ import { FormMessage, } from './ui/form'; -type FieldType = { - rerank_id?: string; - top_k?: number; -}; - -export const RerankItem = () => { - const { t } = useTranslate('knowledgeDetails'); - const allOptions = useSelectLlmOptionsByModelType(); - const [messageApi, contextHolder] = message.useMessage(); - - const handleChange = useCallback( - (val: string) => { - if (val) { - messageApi.open({ - type: 'warning', - content: t('reRankModelWaring'), - }); - } - }, - [messageApi, t], - ); - - return ( - <> - {contextHolder} - - - - - ); -}; - export const topKSchema = { top_k: z.number().optional(), }; @@ -64,35 +21,6 @@ export const initialTopKValue = { top_k: 1024, }; -const Rerank = () => { - const { t } = useTranslate('knowledgeDetails'); - - return ( - <> - - - {({ getFieldValue }) => { - const rerankId = getFieldValue('rerank_id'); - return ( - rerankId && ( - - label={t('topK')} - name={'top_k'} - initialValue={1024} - tooltip={t('topKTip')} - > - - - ) - ); - }} - - - ); -}; - -export default Rerank; - const RerankId = 'rerank_id'; function RerankFormField() { diff --git a/web/src/components/retrieval-documents/index.less b/web/src/components/retrieval-documents/index.less deleted file mode 100644 index 60a5a8f6e..000000000 --- a/web/src/components/retrieval-documents/index.less +++ /dev/null @@ -1,11 +0,0 @@ -.selectFilesCollapse { - :global(.ant-collapse-header) { - padding-left: 22px; - } - margin-bottom: 32px; - overflow-y: auto; -} - -.selectFilesTitle { - padding-right: 10px; -} diff --git a/web/src/components/retrieval-documents/index.tsx b/web/src/components/retrieval-documents/index.tsx deleted file mode 100644 index 88789a85e..000000000 --- a/web/src/components/retrieval-documents/index.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import { ReactComponent as SelectedFilesCollapseIcon } from '@/assets/svg/selected-files-collapse.svg'; -import { Collapse, Flex, Space } from 'antd'; -import SelectFiles from './select-files'; - -import { - useAllTestingResult, - useSelectTestingResult, -} from '@/hooks/use-knowledge-request'; -import { useTranslation } from 'react-i18next'; -import styles from './index.less'; - -interface IProps { - onTesting(documentIds: string[]): void; - setSelectedDocumentIds(documentIds: string[]): void; - selectedDocumentIds: string[]; -} - -const RetrievalDocuments = ({ - onTesting, - selectedDocumentIds, - setSelectedDocumentIds, -}: IProps) => { - const { t } = useTranslation(); - const { documents: documentsAll } = useAllTestingResult(); - const { documents } = useSelectTestingResult(); - const { documents: useDocuments } = { - documents: - documentsAll?.length > documents?.length ? documentsAll : documents, - }; - - return ( - } - className={styles.selectFilesCollapse} - items={[ - { - key: '1', - label: ( - - - - {selectedDocumentIds?.length ?? 0}/{useDocuments?.length ?? 0} - - {t('knowledgeDetails.filesSelected')} - - - ), - children: ( -
- -
- ), - }, - ]} - /> - ); -}; - -export default RetrievalDocuments; diff --git a/web/src/components/retrieval-documents/select-files.tsx b/web/src/components/retrieval-documents/select-files.tsx deleted file mode 100644 index 66afd3d8c..000000000 --- a/web/src/components/retrieval-documents/select-files.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import NewDocumentLink from '@/components/new-document-link'; -import { useTranslate } from '@/hooks/common-hooks'; -import { - useAllTestingResult, - useSelectTestingResult, -} from '@/hooks/use-knowledge-request'; -import { ITestingDocument } from '@/interfaces/database/knowledge'; -import { EyeOutlined } from '@ant-design/icons'; -import { Button, Table, TableProps, Tooltip } from 'antd'; - -interface IProps { - handleTesting: (ids: string[]) => void; - setSelectedDocumentIds: (ids: string[]) => void; -} - -const SelectFiles = ({ setSelectedDocumentIds, handleTesting }: IProps) => { - const { documents } = useSelectTestingResult(); - const { documents: documentsAll } = useAllTestingResult(); - const useDocuments = - documentsAll?.length > documents?.length ? documentsAll : documents; - const { t } = useTranslate('fileManager'); - - const columns: TableProps['columns'] = [ - { - title: 'Name', - dataIndex: 'doc_name', - key: 'doc_name', - render: (text) =>

{text}

, - }, - - { - title: 'Hits', - dataIndex: 'count', - key: 'count', - width: 80, - }, - { - title: 'View', - key: 'view', - width: 50, - render: (_, { doc_id, doc_name }) => ( - - - - - - ), - }, - ]; - - const rowSelection = { - onChange: (selectedRowKeys: React.Key[]) => { - handleTesting(selectedRowKeys as string[]); - setSelectedDocumentIds(selectedRowKeys as string[]); - }, - getCheckboxProps: (record: ITestingDocument) => ({ - disabled: record.doc_name === 'Disabled User', // Column configuration not to be checked - name: record.doc_name, - }), - }; - - return ( - - ); -}; - -export default SelectFiles; diff --git a/web/src/components/similarity-slider/index.tsx b/web/src/components/similarity-slider/index.tsx index d4c07e4d3..c95068886 100644 --- a/web/src/components/similarity-slider/index.tsx +++ b/web/src/components/similarity-slider/index.tsx @@ -1,7 +1,6 @@ import { FormLayout } from '@/constants/form'; import { useTranslate } from '@/hooks/common-hooks'; import { cn } from '@/lib/utils'; -import { Form, Slider } from 'antd'; import { useFormContext } from 'react-hook-form'; import { z } from 'zod'; import { SliderInputFormField } from '../slider-input-form-field'; @@ -15,46 +14,6 @@ import { } from '../ui/form'; import { NumberInput } from '../ui/input'; -type FieldType = { - similarity_threshold?: number; - // vector_similarity_weight?: number; -}; - -interface IProps { - isTooltipShown?: boolean; - vectorSimilarityWeightName?: string; -} - -const SimilaritySlider = ({ - isTooltipShown = false, - vectorSimilarityWeightName = 'vector_similarity_weight', -}: IProps) => { - const { t } = useTranslate('knowledgeDetails'); - - return ( - <> - - label={t('similarityThreshold')} - name={'similarity_threshold'} - tooltip={isTooltipShown && t('similarityThresholdTip')} - initialValue={0.2} - > - - - - - - - ); -}; - -export default SimilaritySlider; - interface SimilaritySliderFormFieldProps { similarityName?: string; vectorSimilarityWeightName?: string; diff --git a/web/src/components/tavily-item.tsx b/web/src/components/tavily-item.tsx deleted file mode 100644 index 6da72126a..000000000 --- a/web/src/components/tavily-item.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { useTranslate } from '@/hooks/common-hooks'; -import { Form, Input, Typography } from 'antd'; - -interface IProps { - name?: string | string[]; -} - -export function TavilyItem({ - name = ['prompt_config', 'tavily_api_key'], -}: IProps) { - const { t } = useTranslate('chat'); - - return ( - -
- - - - - {t('tavilyApiKeyHelp')} - -
-
- ); -} diff --git a/web/src/components/top-n-item.tsx b/web/src/components/top-n-item.tsx index f91140f2d..325019e32 100644 --- a/web/src/components/top-n-item.tsx +++ b/web/src/components/top-n-item.tsx @@ -1,35 +1,8 @@ import { FormLayout } from '@/constants/form'; import { useTranslate } from '@/hooks/common-hooks'; -import { Form, Slider } from 'antd'; import { z } from 'zod'; import { SliderInputFormField } from './slider-input-form-field'; -type FieldType = { - top_n?: number; -}; - -interface IProps { - initialValue?: number; - max?: number; -} - -const TopNItem = ({ initialValue = 8, max = 30 }: IProps) => { - const { t } = useTranslate('chat'); - - return ( - - label={t('topN')} - name={'top_n'} - initialValue={initialValue} - tooltip={t('topNTip')} - > - - - ); -}; - -export default TopNItem; - interface SimilaritySliderFormFieldProps { max?: number; } diff --git a/web/src/components/use-knowledge-graph-item.tsx b/web/src/components/use-knowledge-graph-item.tsx index af05a931b..a24f1ee5e 100644 --- a/web/src/components/use-knowledge-graph-item.tsx +++ b/web/src/components/use-knowledge-graph-item.tsx @@ -1,26 +1,6 @@ -import { Form, Switch } from 'antd'; import { useTranslation } from 'react-i18next'; import { SwitchFormField } from './switch-fom-field'; -type IProps = { - filedName: string[] | string; -}; - -export function UseKnowledgeGraphItem({ filedName }: IProps) { - const { t } = useTranslation(); - - return ( - - - - ); -} - interface UseKnowledgeGraphFormFieldProps { name: string; } diff --git a/web/src/constants/agent.tsx b/web/src/constants/agent.tsx index ee10e3a29..ec42c0f2c 100644 --- a/web/src/constants/agent.tsx +++ b/web/src/constants/agent.tsx @@ -73,7 +73,6 @@ export enum Operator { Retrieval = 'Retrieval', Categorize = 'Categorize', Message = 'Message', - Relevant = 'Relevant', RewriteQuestion = 'RewriteQuestion', DuckDuckGo = 'DuckDuckGo', Wikipedia = 'Wikipedia', diff --git a/web/src/locales/de.ts b/web/src/locales/de.ts index 4036ee0e1..82fc60832 100644 --- a/web/src/locales/de.ts +++ b/web/src/locales/de.ts @@ -856,7 +856,6 @@ export default { generate: 'Generieren', answer: 'Interagieren', categorize: 'Kategorisieren', - relevant: 'Relevant', rewriteQuestion: 'Umschreiben', rewrite: 'Umschreiben', begin: 'Beginn', diff --git a/web/src/locales/en.ts b/web/src/locales/en.ts index b4af29e22..59e85600d 100644 --- a/web/src/locales/en.ts +++ b/web/src/locales/en.ts @@ -1217,7 +1217,6 @@ Example: Virtual Hosted Style`, generate: 'Generate', answer: 'Interact', categorize: 'Categorize', - relevant: 'Relevant', rewriteQuestion: 'Rewrite', rewrite: 'Rewrite', begin: 'Begin', diff --git a/web/src/pages/agent/canvas/index.tsx b/web/src/pages/agent/canvas/index.tsx index 6c088809d..7be70be83 100644 --- a/web/src/pages/agent/canvas/index.tsx +++ b/web/src/pages/agent/canvas/index.tsx @@ -59,7 +59,6 @@ import { NextStepDropdown } from './node/dropdown/next-step-dropdown'; import { ExitLoopNode } from './node/exit-loop-node'; import { ExtractorNode } from './node/extractor-node'; import { FileNode } from './node/file-node'; -import { InvokeNode } from './node/invoke-node'; import { IterationNode, IterationStartNode } from './node/iteration-node'; import { KeywordNode } from './node/keyword-node'; import { ListOperationsNode } from './node/list-operations-node'; @@ -68,12 +67,10 @@ import { MessageNode } from './node/message-node'; import NoteNode from './node/note-node'; import ParserNode from './node/parser-node'; import { PlaceholderNode } from './node/placeholder-node'; -import { RelevantNode } from './node/relevant-node'; import { RetrievalNode } from './node/retrieval-node'; import { RewriteNode } from './node/rewrite-node'; import { SplitterNode } from './node/splitter-node'; import { SwitchNode } from './node/switch-node'; -import { TemplateNode } from './node/template-node'; import TokenizerNode from './node/tokenizer-node'; import { ToolNode } from './node/tool-node'; import { VariableAggregatorNode } from './node/variable-aggregator-node'; @@ -84,15 +81,12 @@ export const nodeTypes: NodeTypes = { categorizeNode: CategorizeNode, beginNode: BeginNode, placeholderNode: PlaceholderNode, - relevantNode: RelevantNode, noteNode: NoteNode, switchNode: SwitchNode, retrievalNode: RetrievalNode, messageNode: MessageNode, rewriteNode: RewriteNode, keywordNode: KeywordNode, - invokeNode: InvokeNode, - templateNode: TemplateNode, // emailNode: EmailNode, group: IterationNode, iterationStartNode: IterationStartNode, diff --git a/web/src/pages/agent/canvas/node/email-node.tsx b/web/src/pages/agent/canvas/node/email-node.tsx deleted file mode 100644 index 9482194f3..000000000 --- a/web/src/pages/agent/canvas/node/email-node.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import { IEmailNode } from '@/interfaces/database/flow'; -import { Handle, NodeProps, Position } from '@xyflow/react'; -import { Flex } from 'antd'; -import classNames from 'classnames'; -import { memo, useState } from 'react'; -import { LeftHandleStyle, RightHandleStyle } from './handle-icon'; -import styles from './index.less'; -import NodeHeader from './node-header'; - -export function InnerEmailNode({ - id, - data, - isConnectable = true, - selected, -}: NodeProps) { - const [showDetails, setShowDetails] = useState(false); - - return ( -
- - - - - -
setShowDetails(!showDetails)} - > -
- SMTP: - {data.form?.smtp_server} -
-
- Port: - {data.form?.smtp_port} -
-
- From: - {data.form?.email} -
-
{showDetails ? 'â–¼' : 'â–¶'}
-
- - {showDetails && ( -
-
Expected Input JSON:
-
-              {`{
-  "to_email": "...",
-  "cc_email": "...", 
-  "subject": "...",
-  "content": "..."
-}`}
-            
-
- )} -
-
- ); -} - -export const EmailNode = memo(InnerEmailNode); diff --git a/web/src/pages/agent/canvas/node/invoke-node.tsx b/web/src/pages/agent/canvas/node/invoke-node.tsx deleted file mode 100644 index cf1e28d02..000000000 --- a/web/src/pages/agent/canvas/node/invoke-node.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { useTheme } from '@/components/theme-provider'; -import { IInvokeNode } from '@/interfaces/database/flow'; -import { Handle, NodeProps, Position } from '@xyflow/react'; -import { Flex } from 'antd'; -import classNames from 'classnames'; -import { get } from 'lodash'; -import { memo } from 'react'; -import { useTranslation } from 'react-i18next'; -import { LeftHandleStyle, RightHandleStyle } from './handle-icon'; -import styles from './index.less'; -import NodeHeader from './node-header'; - -function InnerInvokeNode({ - id, - data, - isConnectable = true, - selected, -}: NodeProps) { - const { t } = useTranslation(); - const { theme } = useTheme(); - const url = get(data, 'form.url'); - return ( -
- - - - -
{t('flow.url')}
-
{url}
-
-
- ); -} - -export const InvokeNode = memo(InnerInvokeNode); diff --git a/web/src/pages/agent/canvas/node/message-node.tsx b/web/src/pages/agent/canvas/node/message-node.tsx index cf6802757..b29a72aa8 100644 --- a/web/src/pages/agent/canvas/node/message-node.tsx +++ b/web/src/pages/agent/canvas/node/message-node.tsx @@ -1,9 +1,11 @@ +import { NodeCollapsible } from '@/components/collapse'; import { IMessageNode } from '@/interfaces/database/flow'; +import { cn } from '@/lib/utils'; import { NodeProps } from '@xyflow/react'; -import { Flex } from 'antd'; import classNames from 'classnames'; import { get } from 'lodash'; import { memo } from 'react'; +import { LabelCard } from './card'; import { LeftEndHandle } from './handle'; import styles from './index.less'; import NodeHeader from './node-header'; @@ -11,20 +13,11 @@ import { NodeWrapper } from './node-wrapper'; import { ToolBar } from './toolbar'; function InnerMessageNode({ id, data, selected }: NodeProps) { - const messages: string[] = get(data, 'form.messages', []); + const messages: string[] = get(data, 'form.content', []); return ( - {/* */} ) { [styles.nodeHeader]: messages.length > 0, })} > - - {messages.map((message, idx) => { - return ( -
- {message} -
- ); - })} -
+
+ + {(x, idx) => ( + + {x} + + )} + +
); diff --git a/web/src/pages/agent/canvas/node/placeholder-node.tsx b/web/src/pages/agent/canvas/node/placeholder-node.tsx index 7dc0d0fbd..e1de79c66 100644 --- a/web/src/pages/agent/canvas/node/placeholder-node.tsx +++ b/web/src/pages/agent/canvas/node/placeholder-node.tsx @@ -1,5 +1,5 @@ +import { Skeleton } from '@/components/ui/skeleton'; import { NodeProps, Position } from '@xyflow/react'; -import { Skeleton } from 'antd'; import { memo } from 'react'; import { NodeHandleId } from '../../constant'; import { CommonHandle } from './handle'; @@ -17,19 +17,10 @@ function InnerPlaceholderNode({ id, selected }: NodeProps) { nodeId={id} id={NodeHandleId.End} > - -
- -
- -
- -
+
+ + +
); } diff --git a/web/src/pages/agent/canvas/node/relevant-node.tsx b/web/src/pages/agent/canvas/node/relevant-node.tsx deleted file mode 100644 index 410a7accd..000000000 --- a/web/src/pages/agent/canvas/node/relevant-node.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import { Handle, NodeProps, Position } from '@xyflow/react'; -import { Flex } from 'antd'; -import classNames from 'classnames'; -import { RightHandleStyle } from './handle-icon'; - -import { useTheme } from '@/components/theme-provider'; -import { IRelevantNode } from '@/interfaces/database/flow'; -import { get } from 'lodash'; -import { memo } from 'react'; -import { useReplaceIdWithName } from '../../hooks'; -import styles from './index.less'; -import NodeHeader from './node-header'; - -function InnerRelevantNode({ id, data, selected }: NodeProps) { - const yes = get(data, 'form.yes'); - const no = get(data, 'form.no'); - const replaceIdWithName = useReplaceIdWithName(); - const { theme } = useTheme(); - return ( -
- - - - - - - -
Yes
-
{replaceIdWithName(yes)}
-
- -
No
-
{replaceIdWithName(no)}
-
-
-
- ); -} - -export const RelevantNode = memo(InnerRelevantNode); diff --git a/web/src/pages/agent/canvas/node/template-node.tsx b/web/src/pages/agent/canvas/node/template-node.tsx deleted file mode 100644 index b204717ab..000000000 --- a/web/src/pages/agent/canvas/node/template-node.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import { useTheme } from '@/components/theme-provider'; -import { Handle, NodeProps, Position } from '@xyflow/react'; -import { Flex } from 'antd'; -import classNames from 'classnames'; -import { get } from 'lodash'; -import { useGetComponentLabelByValue } from '../../hooks/use-get-begin-query'; -import { IGenerateParameter } from '../../interface'; -import { LeftHandleStyle, RightHandleStyle } from './handle-icon'; -import NodeHeader from './node-header'; - -import { ITemplateNode } from '@/interfaces/database/flow'; -import { memo } from 'react'; -import styles from './index.less'; - -function InnerTemplateNode({ - id, - data, - isConnectable = true, - selected, -}: NodeProps) { - const parameters: IGenerateParameter[] = get(data, 'form.parameters', []); - const getLabel = useGetComponentLabelByValue(id); - const { theme } = useTheme(); - return ( -
- - - - - - - {parameters.map((x) => ( - - - - {getLabel(x.component_id)} - - - ))} - -
- ); -} - -export const TemplateNode = memo(InnerTemplateNode); diff --git a/web/src/pages/agent/constant/index.tsx b/web/src/pages/agent/constant/index.tsx index 283a3d718..abef76ab3 100644 --- a/web/src/pages/agent/constant/index.tsx +++ b/web/src/pages/agent/constant/index.tsx @@ -613,7 +613,7 @@ export const CategorizeAnchorPointPositions = [ // key is the source of the edge, value is the target of the edge // no connection lines are allowed between key and value export const RestrictedUpstreamMap = { - [Operator.Begin]: [Operator.Relevant], + [Operator.Begin]: [Operator.Begin], [Operator.Categorize]: [Operator.Begin, Operator.Categorize], [Operator.Retrieval]: [Operator.Begin, Operator.Retrieval], [Operator.Message]: [ @@ -623,12 +623,10 @@ export const RestrictedUpstreamMap = { Operator.RewriteQuestion, Operator.Categorize, ], - [Operator.Relevant]: [Operator.Begin], [Operator.RewriteQuestion]: [ Operator.Begin, Operator.Message, Operator.RewriteQuestion, - Operator.Relevant, ], [Operator.DuckDuckGo]: [Operator.Begin, Operator.Retrieval], [Operator.Wikipedia]: [Operator.Begin, Operator.Retrieval], @@ -678,7 +676,6 @@ export const NodeMap = { [Operator.Categorize]: 'categorizeNode', [Operator.Retrieval]: 'retrievalNode', [Operator.Message]: 'messageNode', - [Operator.Relevant]: 'relevantNode', [Operator.RewriteQuestion]: 'rewriteNode', [Operator.DuckDuckGo]: 'ragNode', [Operator.Wikipedia]: 'ragNode', diff --git a/web/src/pages/agent/form-sheet/form-config-map.tsx b/web/src/pages/agent/form-sheet/form-config-map.tsx index a1a68bb21..9bda1f674 100644 --- a/web/src/pages/agent/form-sheet/form-config-map.tsx +++ b/web/src/pages/agent/form-sheet/form-config-map.tsx @@ -23,7 +23,6 @@ import LoopForm from '../form/loop-form'; import MessageForm from '../form/message-form'; import ParserForm from '../form/parser-form'; import PubMedForm from '../form/pubmed-form'; -import RelevantForm from '../form/relevant-form'; import RetrievalForm from '../form/retrieval-form/next'; import RewriteQuestionForm from '../form/rewrite-question-form'; import SearXNGForm from '../form/searxng-form'; @@ -54,9 +53,6 @@ export const FormConfigMap = { [Operator.Message]: { component: MessageForm, }, - [Operator.Relevant]: { - component: RelevantForm, - }, [Operator.RewriteQuestion]: { component: RewriteQuestionForm, }, diff --git a/web/src/pages/agent/form/relevant-form/hooks.ts b/web/src/pages/agent/form/relevant-form/hooks.ts deleted file mode 100644 index 413a0ac38..000000000 --- a/web/src/pages/agent/form/relevant-form/hooks.ts +++ /dev/null @@ -1,41 +0,0 @@ -import pick from 'lodash/pick'; -import { useCallback, useEffect } from 'react'; -import { IOperatorForm } from '../../interface'; -import useGraphStore from '../../store'; - -export const useBuildRelevantOptions = () => { - const nodes = useGraphStore((state) => state.nodes); - - const buildRelevantOptions = useCallback( - (toList: string[]) => { - return nodes - .filter( - (x) => !toList.some((y) => y === x.id), // filter out selected values ​​in other to fields from the current drop-down box options - ) - .map((x) => ({ label: x.data.name, value: x.id })); - }, - [nodes], - ); - - return buildRelevantOptions; -}; - -/** - * monitor changes in the connection and synchronize the target to the yes and no fields of the form - * similar to the categorize-form's useHandleFormValuesChange method - * @param param0 - */ -export const useWatchConnectionChanges = ({ nodeId, form }: IOperatorForm) => { - const getNode = useGraphStore((state) => state.getNode); - const node = getNode(nodeId); - - const watchFormChanges = useCallback(() => { - if (node) { - form?.setFieldsValue(pick(node, ['yes', 'no'])); - } - }, [node, form]); - - useEffect(() => { - watchFormChanges(); - }, [watchFormChanges]); -}; diff --git a/web/src/pages/agent/form/relevant-form/index.tsx b/web/src/pages/agent/form/relevant-form/index.tsx deleted file mode 100644 index e2366f6f0..000000000 --- a/web/src/pages/agent/form/relevant-form/index.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import LLMSelect from '@/components/llm-select'; -import { useTranslate } from '@/hooks/common-hooks'; -import { Form, Select } from 'antd'; -import { Operator } from '../../constant'; -import { useBuildFormSelectOptions } from '../../form-hooks'; -import { IOperatorForm } from '../../interface'; -import { useWatchConnectionChanges } from './hooks'; - -const RelevantForm = ({ onValuesChange, form, node }: IOperatorForm) => { - const { t } = useTranslate('flow'); - const buildRelevantOptions = useBuildFormSelectOptions( - Operator.Relevant, - node?.id, - ); - useWatchConnectionChanges({ nodeId: node?.id, form }); - - return ( -
- - - - - - - - ); -}; - -export default RelevantForm; diff --git a/web/src/pages/agent/hooks/use-add-node.ts b/web/src/pages/agent/hooks/use-add-node.ts index 36aae5d4f..43db495ee 100644 --- a/web/src/pages/agent/hooks/use-add-node.ts +++ b/web/src/pages/agent/hooks/use-add-node.ts @@ -34,7 +34,6 @@ import { initialNoteValues, initialParserValues, initialPubMedValues, - initialRelevantValues, initialRetrievalValues, initialRewriteQuestionValues, initialSearXNGValues, @@ -129,7 +128,6 @@ export const useInitializeOperatorParams = () => { [Operator.Begin]: initialBeginValues, [Operator.Retrieval]: initialRetrievalValues, [Operator.Categorize]: { ...initialCategorizeValues, llm_id: llmId }, - [Operator.Relevant]: { ...initialRelevantValues, llm_id: llmId }, [Operator.RewriteQuestion]: { ...initialRewriteQuestionValues, llm_id: llmId, diff --git a/web/src/pages/agent/hooks/use-get-begin-query.tsx b/web/src/pages/agent/hooks/use-get-begin-query.tsx index c18a72029..387f59821 100644 --- a/web/src/pages/agent/hooks/use-get-begin-query.tsx +++ b/web/src/pages/agent/hooks/use-get-begin-query.tsx @@ -125,12 +125,7 @@ export function useBuildParentOutputOptions(parentId?: string) { } // exclude nodes with branches -const ExcludedNodes = [ - Operator.Categorize, - Operator.Relevant, - Operator.Begin, - Operator.Note, -]; +const ExcludedNodes = [Operator.Categorize, Operator.Begin, Operator.Note]; const StringList = [ BeginQueryType.Line, diff --git a/web/src/pages/agent/store.ts b/web/src/pages/agent/store.ts index d71bf68c2..42ce97444 100644 --- a/web/src/pages/agent/store.ts +++ b/web/src/pages/agent/store.ts @@ -301,12 +301,7 @@ const useGraphStore = create()( }); }, deleteEdgeById: (id: string) => { - const { - edges, - updateNodeForm, - getOperatorTypeFromId, - updateSwitchFormData, - } = get(); + const { edges, getOperatorTypeFromId, updateSwitchFormData } = get(); const currentEdge = edges.find((x) => x.id === id); if (currentEdge) { @@ -314,11 +309,6 @@ const useGraphStore = create()( const operatorType = getOperatorTypeFromId(source); // After deleting the edge, set the corresponding field in the node's form field to undefined switch (operatorType) { - case Operator.Relevant: - updateNodeForm(source, { - [sourceHandle as string]: undefined, - }); - break; // case Operator.Categorize: // if (sourceHandle) // updateNodeForm(source, undefined, [ diff --git a/web/src/pages/agent/utils.ts b/web/src/pages/agent/utils.ts index da2fbf267..6825dd9f5 100644 --- a/web/src/pages/agent/utils.ts +++ b/web/src/pages/agent/utils.ts @@ -569,12 +569,6 @@ export const duplicateNodeForm = (nodeData?: RAGFlowNodeType['data']) => { }, {}); } - // Delete the downstream nodes corresponding to the yes and no fields of the Relevant operator - if (nodeData?.label === Operator.Relevant) { - form.yes = undefined; - form.no = undefined; - } - return { ...(nodeData ?? { label: '' }), form, diff --git a/web/src/pages/document-viewer/index.tsx b/web/src/pages/document-viewer/index.tsx index a56a2cec2..2e6fbccfd 100644 --- a/web/src/pages/document-viewer/index.tsx +++ b/web/src/pages/document-viewer/index.tsx @@ -1,6 +1,5 @@ import { Images } from '@/constants/common'; import { api_host } from '@/utils/api'; -// import { Flex } from 'antd'; import { useParams, useSearchParams } from 'umi'; // import Docx from './docx'; // import Excel from './excel'; diff --git a/web/src/pages/document-viewer/pdf/index.tsx b/web/src/pages/document-viewer/pdf/index.tsx deleted file mode 100644 index 7e055c410..000000000 --- a/web/src/pages/document-viewer/pdf/index.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { Authorization } from '@/constants/authorization'; -import { getAuthorization } from '@/utils/authorization-util'; -import { Skeleton } from 'antd'; -import { PdfHighlighter, PdfLoader } from 'react-pdf-highlighter'; -import FileError from '../file-error'; -import { useCatchError } from '../hooks'; -type PdfLoaderProps = React.ComponentProps & { - httpHeaders?: Record; -}; - -const Loader = PdfLoader as React.ComponentType; - -interface IProps { - url: string; -} - -const PdfPreviewer = ({ url }: IProps) => { - const { error } = useCatchError(url); - const resetHash = () => {}; - const httpHeaders = { - [Authorization]: getAuthorization(), - }; - return ( -
- } - workerSrc="/pdfjs-dist/pdf.worker.min.js" - errorMessage={{error}} - onError={(e) => { - console.warn(e); - }} - > - {(pdfDocument) => { - return ( - event.altKey} - onScrollChange={resetHash} - scrollRef={() => {}} - onSelectionFinished={() => null} - highlightTransform={() => { - return
; - }} - highlights={[]} - /> - ); - }} -
-
- ); -}; - -export default PdfPreviewer; diff --git a/web/src/pages/next-search/embed-app-modal.tsx b/web/src/pages/next-search/embed-app-modal.tsx index dca773cc7..1d443400e 100644 --- a/web/src/pages/next-search/embed-app-modal.tsx +++ b/web/src/pages/next-search/embed-app-modal.tsx @@ -1,4 +1,5 @@ import HightLightMarkdown from '@/components/highlight-markdown'; +import message from '@/components/ui/message'; import { Modal } from '@/components/ui/modal/modal'; import { RAGFlowSelect } from '@/components/ui/select'; import { Switch } from '@/components/ui/switch'; @@ -7,7 +8,6 @@ import { LanguageAbbreviationMap, } from '@/constants/common'; import { useTranslate } from '@/hooks/common-hooks'; -import { message } from 'antd'; import { useCallback, useMemo, useState } from 'react'; type IEmbedAppModalProps = { diff --git a/web/src/pages/profile-setting/components.tsx b/web/src/pages/profile-setting/components.tsx deleted file mode 100644 index a2ee73acd..000000000 --- a/web/src/pages/profile-setting/components.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { Card, CardContent, CardHeader } from '@/components/ui/card'; -import { PropsWithChildren } from 'react'; - -export function Title({ children }: PropsWithChildren) { - return {children}; -} - -type ProfileSettingWrapperCardProps = { - header: React.ReactNode; -} & PropsWithChildren; - -export function ProfileSettingWrapperCard({ - header, - children, -}: ProfileSettingWrapperCardProps) { - return ( - - - {header} - - {children} - - ); -} diff --git a/web/src/pages/profile-setting/hooks.tsx b/web/src/pages/profile-setting/hooks.tsx deleted file mode 100644 index 364cff2b0..000000000 --- a/web/src/pages/profile-setting/hooks.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { ProfileSettingRouteKey } from '@/constants/setting'; -import { useSecondPathName } from '@/hooks/route-hook'; - -export const useGetPageTitle = (): string => { - const pathName = useSecondPathName(); - - const LabelMap = { - [ProfileSettingRouteKey.Profile]: 'User profile', - [ProfileSettingRouteKey.Plan]: 'Plan & balance', - [ProfileSettingRouteKey.Model]: 'Model management', - [ProfileSettingRouteKey.System]: 'System', - [ProfileSettingRouteKey.Api]: 'Api', - [ProfileSettingRouteKey.Team]: 'Team management', - [ProfileSettingRouteKey.Prompt]: 'Prompt management', - [ProfileSettingRouteKey.Chunk]: 'Chunking method', - [ProfileSettingRouteKey.Logout]: 'Logout', - }; - - return LabelMap[pathName as ProfileSettingRouteKey]; -}; diff --git a/web/src/pages/profile-setting/index.tsx b/web/src/pages/profile-setting/index.tsx deleted file mode 100644 index 88be7acd9..000000000 --- a/web/src/pages/profile-setting/index.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { PageHeader } from '@/components/page-header'; -import { - Breadcrumb, - BreadcrumbItem, - BreadcrumbLink, - BreadcrumbList, - BreadcrumbPage, - BreadcrumbSeparator, -} from '@/components/ui/breadcrumb'; -import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks'; -import { House } from 'lucide-react'; -import { useTranslation } from 'react-i18next'; -import { Outlet } from 'umi'; -import { SideBar } from './sidebar'; - -export default function ProfileSetting() { - const { navigateToHome } = useNavigatePage(); - const { t } = useTranslation(); - - return ( -
- - - - - - - - - - - {t('setting.profile')} - - - - - -
- - -
- -
-
-
- ); -} diff --git a/web/src/pages/profile-setting/mcp/edit-mcp-dialog.tsx b/web/src/pages/profile-setting/mcp/edit-mcp-dialog.tsx deleted file mode 100644 index e62c1007e..000000000 --- a/web/src/pages/profile-setting/mcp/edit-mcp-dialog.tsx +++ /dev/null @@ -1,178 +0,0 @@ -import { Collapse } from '@/components/collapse'; -import { Button, ButtonLoading } from '@/components/ui/button'; -import { Card, CardContent } from '@/components/ui/card'; -import { - Dialog, - DialogClose, - DialogContent, - DialogFooter, - DialogHeader, - DialogTitle, -} from '@/components/ui/dialog'; -import { useGetMcpServer, useTestMcpServer } from '@/hooks/use-mcp-request'; -import { IModalProps } from '@/interfaces/common'; -import { IMCPTool, IMCPToolObject } from '@/interfaces/database/mcp'; -import { cn } from '@/lib/utils'; -import { zodResolver } from '@hookform/resolvers/zod'; -import { isEmpty, omit, pick } from 'lodash'; -import { RefreshCw } from 'lucide-react'; -import { - MouseEventHandler, - useCallback, - useEffect, - useMemo, - useState, -} from 'react'; -import { useForm } from 'react-hook-form'; -import { useTranslation } from 'react-i18next'; -import { z } from 'zod'; -import { - EditMcpForm, - FormId, - ServerType, - useBuildFormSchema, -} from './edit-mcp-form'; -import { McpToolCard } from './tool-card'; - -function transferToolToArray(tools: IMCPToolObject) { - return Object.entries(tools).reduce((pre, [name, tool]) => { - pre.push({ ...tool, name }); - return pre; - }, []); -} - -const DefaultValues = { - name: '', - server_type: ServerType.SSE, - url: '', -}; - -export function EditMcpDialog({ - hideModal, - loading, - onOk, - id, -}: IModalProps & { id: string }) { - const { t } = useTranslation(); - const { - testMcpServer, - data: testData, - loading: testLoading, - } = useTestMcpServer(); - const [isTriggeredBySaving, setIsTriggeredBySaving] = useState(false); - const FormSchema = useBuildFormSchema(); - const [collapseOpen, setCollapseOpen] = useState(true); - const { data } = useGetMcpServer(id); - const [fieldChanged, setFieldChanged] = useState(false); - - const tools = useMemo(() => { - return testData?.data || []; - }, [testData?.data]); - - const form = useForm>({ - resolver: zodResolver(FormSchema), - defaultValues: DefaultValues, - }); - - const handleTest: MouseEventHandler = useCallback((e) => { - e.stopPropagation(); - setIsTriggeredBySaving(false); - }, []); - - const handleSave: MouseEventHandler = useCallback(() => { - setIsTriggeredBySaving(true); - }, []); - - const handleOk = async (values: z.infer) => { - const nextValues = { - ...omit(values, 'authorization_token'), - variables: { authorization_token: values.authorization_token }, - headers: { Authorization: 'Bearer ${authorization_token}' }, - }; - if (isTriggeredBySaving) { - onOk?.(nextValues); - } else { - const ret = await testMcpServer(nextValues); - if (ret.code === 0) { - setFieldChanged(false); - } - } - }; - - useEffect(() => { - if (!isEmpty(data)) { - form.reset(pick(data, ['name', 'server_type', 'url'])); - } - }, [data, form]); - - const nextTools = useMemo(() => { - return isEmpty(tools) - ? transferToolToArray(data.variables?.tools || {}) - : tools; - }, [data.variables?.tools, tools]); - - const disabled = !!!tools?.length || testLoading || fieldChanged; - - return ( - - - - {id ? t('mcp.editMCP') : t('mcp.addMCP')} - - - - - - {nextTools?.length || 0} {t('mcp.toolsAvailable')} - - } - open={collapseOpen} - onOpenChange={setCollapseOpen} - rightContent={ - - } - > -
- {nextTools?.map((x) => ( - - ))} -
-
-
-
- - - - - - {t('common.save')} - - -
-
- ); -} diff --git a/web/src/pages/profile-setting/mcp/edit-mcp-form.tsx b/web/src/pages/profile-setting/mcp/edit-mcp-form.tsx deleted file mode 100644 index d6b49db11..000000000 --- a/web/src/pages/profile-setting/mcp/edit-mcp-form.tsx +++ /dev/null @@ -1,171 +0,0 @@ -'use client'; - -import { UseFormReturn } from 'react-hook-form'; -import { z } from 'zod'; - -import { - Form, - FormControl, - FormField, - FormItem, - FormLabel, - FormMessage, -} from '@/components/ui/form'; -import { Input } from '@/components/ui/input'; -import { RAGFlowSelect } from '@/components/ui/select'; -import { IModalProps } from '@/interfaces/common'; -import { buildOptions } from '@/utils/form'; -import { loader } from '@monaco-editor/react'; -import { Dispatch, SetStateAction } from 'react'; -import { useTranslation } from 'react-i18next'; - -loader.config({ paths: { vs: '/vs' } }); - -export const FormId = 'EditMcpForm'; - -export enum ServerType { - SSE = 'sse', - StreamableHttp = 'streamable-http', -} - -const ServerTypeOptions = buildOptions(ServerType); - -export function useBuildFormSchema() { - const { t } = useTranslation(); - - const FormSchema = z.object({ - name: z - .string() - .min(1, { - message: t('common.mcp.namePlaceholder'), - }) - .regex(/^[a-zA-Z0-9_-]{1,64}$/, { - message: t('common.mcp.nameRequired'), - }) - .trim(), - url: z - .string() - .url() - .min(1, { - message: t('common.mcp.urlPlaceholder'), - }) - .trim(), - server_type: z - .string() - .min(1, { - message: t('common.pleaseSelect'), - }) - .trim(), - authorization_token: z.string().optional(), - }); - - return FormSchema; -} - -export function EditMcpForm({ - form, - onOk, - setFieldChanged, -}: IModalProps & { - form: UseFormReturn; - setFieldChanged: Dispatch>; -}) { - const { t } = useTranslation(); - const FormSchema = useBuildFormSchema(); - - function onSubmit(data: z.infer) { - onOk?.(data); - } - - return ( -
- - ( - - {t('common.name')} - - - - - - )} - /> - ( - - {t('mcp.url')} - - { - field.onChange(e.target.value.trim()); - setFieldChanged(true); - }} - /> - - - - )} - /> - ( - - {t('mcp.serverType')} - - { - field.onChange(value); - setFieldChanged(true); - }} - /> - - - - )} - /> - ( - - Authorization Token - - { - field.onChange(e.target.value.trim()); - setFieldChanged(true); - }} - /> - - - - )} - /> - - - ); -} diff --git a/web/src/pages/profile-setting/mcp/import-mcp-dialog/import-mcp-form.tsx b/web/src/pages/profile-setting/mcp/import-mcp-dialog/import-mcp-form.tsx deleted file mode 100644 index 6408b9e18..000000000 --- a/web/src/pages/profile-setting/mcp/import-mcp-dialog/import-mcp-form.tsx +++ /dev/null @@ -1,72 +0,0 @@ -'use client'; - -import { zodResolver } from '@hookform/resolvers/zod'; -import { useForm } from 'react-hook-form'; -import { z } from 'zod'; - -import { FileUploader } from '@/components/file-uploader'; -import { - Form, - FormControl, - FormField, - FormItem, - FormLabel, - FormMessage, -} from '@/components/ui/form'; -import { FileMimeType, Platform } from '@/constants/common'; -import { TagRenameId } from '@/constants/knowledge'; -import { IModalProps } from '@/interfaces/common'; -import { useTranslation } from 'react-i18next'; - -export function ImportMcpForm({ hideModal, onOk }: IModalProps) { - const { t } = useTranslation(); - const FormSchema = z.object({ - platform: z - .string() - .min(1, { - message: t('common.namePlaceholder'), - }) - .trim(), - fileList: z.array(z.instanceof(File)), - }); - - const form = useForm>({ - resolver: zodResolver(FormSchema), - defaultValues: { platform: Platform.RAGFlow }, - }); - - async function onSubmit(data: z.infer) { - const ret = await onOk?.(data); - if (ret) { - hideModal?.(); - } - } - - return ( -
- - ( - - {t('common.name')} - - - - - - )} - /> - - - ); -} diff --git a/web/src/pages/profile-setting/mcp/import-mcp-dialog/index.tsx b/web/src/pages/profile-setting/mcp/import-mcp-dialog/index.tsx deleted file mode 100644 index 1946523eb..000000000 --- a/web/src/pages/profile-setting/mcp/import-mcp-dialog/index.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { - Dialog, - DialogContent, - DialogFooter, - DialogHeader, - DialogTitle, -} from '@/components/ui/dialog'; -import { LoadingButton } from '@/components/ui/loading-button'; -import { TagRenameId } from '@/constants/knowledge'; -import { IModalProps } from '@/interfaces/common'; -import { useTranslation } from 'react-i18next'; -import { ImportMcpForm } from './import-mcp-form'; - -export function ImportMcpDialog({ - hideModal, - onOk, - loading, -}: IModalProps) { - const { t } = useTranslation(); - - return ( - - - - {t('mcp.import')} - - - - - {t('common.save')} - - - - - ); -} diff --git a/web/src/pages/profile-setting/mcp/index.tsx b/web/src/pages/profile-setting/mcp/index.tsx deleted file mode 100644 index d790ac6d3..000000000 --- a/web/src/pages/profile-setting/mcp/index.tsx +++ /dev/null @@ -1,157 +0,0 @@ -import { CardContainer } from '@/components/card-container'; -import { ConfirmDeleteDialog } from '@/components/confirm-delete-dialog'; -import Spotlight from '@/components/spotlight'; -import { Button } from '@/components/ui/button'; -import { Checkbox } from '@/components/ui/checkbox'; -import { SearchInput } from '@/components/ui/input'; -import { Label } from '@/components/ui/label'; -import { RAGFlowPagination } from '@/components/ui/ragflow-pagination'; -import { useListMcpServer } from '@/hooks/use-mcp-request'; -import { pick } from 'lodash'; -import { - Download, - LayoutList, - ListChecks, - Plus, - Trash2, - Upload, -} from 'lucide-react'; -import { useCallback, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { ProfileSettingWrapperCard } from '../components'; -import { EditMcpDialog } from './edit-mcp-dialog'; -import { ImportMcpDialog } from './import-mcp-dialog'; -import { McpCard } from './mcp-card'; -import { useBulkOperateMCP } from './use-bulk-operate-mcp'; -import { useEditMcp } from './use-edit-mcp'; -import { useImportMcp } from './use-import-mcp'; - -export default function McpServer() { - const { data, setPagination, searchString, handleInputChange, pagination } = - useListMcpServer(); - const { editVisible, showEditModal, hideEditModal, handleOk, id, loading } = - useEditMcp(); - const { - selectedList, - handleSelectChange, - handleDelete, - handleExportMcp, - handleSelectAll, - } = useBulkOperateMCP(data.mcp_servers); - const { t } = useTranslation(); - const { importVisible, showImportModal, hideImportModal, onImportOk } = - useImportMcp(); - - const [isSelectionMode, setSelectionMode] = useState(false); - - const handlePageChange = useCallback( - (page: number, pageSize?: number) => { - setPagination({ page, pageSize }); - }, - [setPagination], - ); - - const switchSelectionMode = useCallback(() => { - setSelectionMode((prev) => !prev); - }, []); - - return ( - -
- {t('mcp.mcpServers')} -
-
-
- {t('mcp.customizeTheListOfMcpServers')} -
-
- - - - -
-
- - } - > - {isSelectionMode && ( -
- - - - {t('mcp.selected')} {selectedList.length} - -
- - - - -
-
- )} - - {data.mcp_servers.map((item) => ( - - ))} - -
- -
- {editVisible && ( - - )} - {importVisible && ( - - )} - -
- ); -} diff --git a/web/src/pages/profile-setting/mcp/mcp-card.tsx b/web/src/pages/profile-setting/mcp/mcp-card.tsx deleted file mode 100644 index b0cfcd162..000000000 --- a/web/src/pages/profile-setting/mcp/mcp-card.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import { Card, CardContent } from '@/components/ui/card'; -import { Checkbox } from '@/components/ui/checkbox'; -import { IMcpServer } from '@/interfaces/database/mcp'; -import { formatDate } from '@/utils/date'; -import { isPlainObject } from 'lodash'; -import { useMemo } from 'react'; -import { useTranslation } from 'react-i18next'; -import { McpOperation } from './mcp-operation'; -import { UseBulkOperateMCPReturnType } from './use-bulk-operate-mcp'; -import { UseEditMcpReturnType } from './use-edit-mcp'; - -export type DatasetCardProps = { - data: IMcpServer; - isSelectionMode: boolean; -} & Pick & - Pick; - -export function McpCard({ - data, - selectedList, - handleSelectChange, - showEditModal, - isSelectionMode, -}: DatasetCardProps) { - const { t } = useTranslation(); - const toolLength = useMemo(() => { - const tools = data.variables?.tools; - if (isPlainObject(tools)) { - return Object.keys(tools || {}).length; - } - return 0; - }, [data.variables?.tools]); - const onCheckedChange = (checked: boolean) => { - if (typeof checked === 'boolean') { - handleSelectChange(data.id, checked); - } - }; - - return ( - - -
-

- {data.name} -

-
- {isSelectionMode ? ( - { - e.stopPropagation(); - }} - /> - ) : ( - - )} -
-
-
-
-
- {toolLength} {t('mcp.cachedTools')} -
-

{formatDate(data.update_date)}

-
-
-
-
- ); -} diff --git a/web/src/pages/profile-setting/mcp/mcp-operation.tsx b/web/src/pages/profile-setting/mcp/mcp-operation.tsx deleted file mode 100644 index 9bbd9e5c8..000000000 --- a/web/src/pages/profile-setting/mcp/mcp-operation.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { ConfirmDeleteDialog } from '@/components/confirm-delete-dialog'; -import { RAGFlowTooltip } from '@/components/ui/tooltip'; -import { useDeleteMcpServer } from '@/hooks/use-mcp-request'; -import { PenLine, Trash2, Upload } from 'lucide-react'; -import { MouseEventHandler, useCallback } from 'react'; -import { useTranslation } from 'react-i18next'; -import { UseEditMcpReturnType } from './use-edit-mcp'; -import { useExportMcp } from './use-export-mcp'; - -export function McpOperation({ - mcpId, - showEditModal, -}: { mcpId: string } & Pick) { - const { t } = useTranslation(); - const { deleteMcpServer } = useDeleteMcpServer(); - const { handleExportMcpJson } = useExportMcp(); - - const handleDelete: MouseEventHandler = useCallback(() => { - deleteMcpServer([mcpId]); - }, [deleteMcpServer, mcpId]); - - return ( -
- - - - - - - - - - - -
- ); -} diff --git a/web/src/pages/profile-setting/mcp/tool-card.tsx b/web/src/pages/profile-setting/mcp/tool-card.tsx deleted file mode 100644 index 123b4a611..000000000 --- a/web/src/pages/profile-setting/mcp/tool-card.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { IMCPTool } from '@/interfaces/database/mcp'; - -export type McpToolCardProps = { - data: IMCPTool; -}; - -export function McpToolCard({ data }: McpToolCardProps) { - return ( -
-

{data.name}

-
- {data.description} -
-
- ); -} diff --git a/web/src/pages/profile-setting/mcp/use-bulk-operate-mcp.tsx b/web/src/pages/profile-setting/mcp/use-bulk-operate-mcp.tsx deleted file mode 100644 index 2afef8347..000000000 --- a/web/src/pages/profile-setting/mcp/use-bulk-operate-mcp.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import { useDeleteMcpServer } from '@/hooks/use-mcp-request'; -import { IMcpServer } from '@/interfaces/database/mcp'; -import { Trash2, Upload } from 'lucide-react'; -import { useCallback, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { useExportMcp } from './use-export-mcp'; - -export function useBulkOperateMCP(mcpList: IMcpServer[]) { - const { t } = useTranslation(); - const [selectedList, setSelectedList] = useState>([]); - const { deleteMcpServer } = useDeleteMcpServer(); - const { handleExportMcpJson } = useExportMcp(); - - const handleDelete = useCallback(() => { - deleteMcpServer(selectedList); - }, [deleteMcpServer, selectedList]); - - const handleSelectChange = useCallback((id: string, checked: boolean) => { - setSelectedList((list) => { - return checked ? [...list, id] : list.filter((item) => item !== id); - }); - }, []); - - const handleSelectAll = useCallback( - (checked: boolean) => { - setSelectedList(() => (checked ? mcpList.map((item) => item.id) : [])); - }, - [mcpList], - ); - - const list = [ - { - id: 'export', - label: t('mcp.export'), - icon: , - onClick: handleExportMcpJson(selectedList), - }, - { - id: 'delete', - label: t('common.delete'), - icon: , - onClick: handleDelete, - }, - ]; - - return { - list, - selectedList, - handleSelectChange, - handleDelete, - handleExportMcp: handleExportMcpJson(selectedList), - handleSelectAll, - }; -} - -export type UseBulkOperateMCPReturnType = ReturnType; diff --git a/web/src/pages/profile-setting/mcp/use-edit-mcp.ts b/web/src/pages/profile-setting/mcp/use-edit-mcp.ts deleted file mode 100644 index 09fc83be5..000000000 --- a/web/src/pages/profile-setting/mcp/use-edit-mcp.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { useSetModalState } from '@/hooks/common-hooks'; -import { - useCreateMcpServer, - useUpdateMcpServer, -} from '@/hooks/use-mcp-request'; -import { useCallback, useState } from 'react'; - -export const useEditMcp = () => { - const { - visible: editVisible, - hideModal: hideEditModal, - showModal: showEditModal, - } = useSetModalState(); - const { createMcpServer, loading } = useCreateMcpServer(); - const [id, setId] = useState(''); - - const { updateMcpServer, loading: updateLoading } = useUpdateMcpServer(); - - const handleShowModal = useCallback( - (id: string) => () => { - setId(id); - showEditModal(); - }, - [setId, showEditModal], - ); - - const handleOk = useCallback( - async (values: any) => { - let code; - if (id) { - code = await updateMcpServer({ ...values, mcp_id: id }); - } else { - code = await createMcpServer(values); - } - if (code === 0) { - hideEditModal(); - } - }, - [createMcpServer, hideEditModal, id, updateMcpServer], - ); - - return { - editVisible, - hideEditModal, - showEditModal: handleShowModal, - loading: loading || updateLoading, - createMcpServer, - handleOk, - id, - }; -}; - -export type UseEditMcpReturnType = ReturnType; diff --git a/web/src/pages/profile-setting/mcp/use-export-mcp.ts b/web/src/pages/profile-setting/mcp/use-export-mcp.ts deleted file mode 100644 index 636290c91..000000000 --- a/web/src/pages/profile-setting/mcp/use-export-mcp.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { useExportMcpServer } from '@/hooks/use-mcp-request'; -import { downloadJsonFile } from '@/utils/file-util'; -import { useCallback } from 'react'; - -export function useExportMcp() { - const { exportMcpServer } = useExportMcpServer(); - - const handleExportMcpJson = useCallback( - (ids: string[]) => async () => { - const data = await exportMcpServer(ids); - if (data.code === 0) { - downloadJsonFile(data.data, `mcp.json`); - } - }, - [exportMcpServer], - ); - - return { - handleExportMcpJson, - }; -} diff --git a/web/src/pages/profile-setting/mcp/use-import-mcp.ts b/web/src/pages/profile-setting/mcp/use-import-mcp.ts deleted file mode 100644 index 33e844191..000000000 --- a/web/src/pages/profile-setting/mcp/use-import-mcp.ts +++ /dev/null @@ -1,73 +0,0 @@ -import message from '@/components/ui/message'; -import { FileMimeType } from '@/constants/common'; -import { useSetModalState } from '@/hooks/common-hooks'; -import { useImportMcpServer } from '@/hooks/use-mcp-request'; -import { isEmpty } from 'lodash'; -import { useCallback } from 'react'; -import { useTranslation } from 'react-i18next'; -import { z } from 'zod'; - -const ServerEntrySchema = z.object({ - authorization_token: z.string().optional(), - name: z.string().optional(), - tool_configuration: z.object({}).passthrough().optional(), - type: z.string(), - url: z.string().url(), -}); - -const McpConfigSchema = z.object({ - mcpServers: z.record(ServerEntrySchema), -}); - -export const useImportMcp = () => { - const { - visible: importVisible, - hideModal: hideImportModal, - showModal: showImportModal, - } = useSetModalState(); - const { t } = useTranslation(); - const { importMcpServer, loading } = useImportMcpServer(); - - const onImportOk = useCallback( - async ({ fileList }: { fileList: File[] }) => { - if (fileList.length > 0) { - const file = fileList[0]; - if (file.type !== FileMimeType.Json) { - message.error(t('flow.jsonUploadTypeErrorMessage')); - return; - } - - const mcpStr = await file.text(); - const errorMessage = t('flow.jsonUploadContentErrorMessage'); - try { - const mcp = JSON.parse(mcpStr); - try { - McpConfigSchema.parse(mcp); - } catch (error) { - message.error('Incorrect data format'); - return; - } - if (mcpStr && !isEmpty(mcp)) { - const ret = await importMcpServer(mcp); - if (ret.code === 0) { - hideImportModal(); - } - } else { - message.error(errorMessage); - } - } catch (error) { - message.error(errorMessage); - } - } - }, - [hideImportModal, importMcpServer, t], - ); - - return { - importVisible, - showImportModal, - hideImportModal, - onImportOk, - loading, - }; -}; diff --git a/web/src/pages/profile-setting/model/index.tsx b/web/src/pages/profile-setting/model/index.tsx deleted file mode 100644 index 3f4457f7a..000000000 --- a/web/src/pages/profile-setting/model/index.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { Button } from '@/components/ui/button'; -import { Input } from '@/components/ui/input'; -import { - AddModelCard, - ModelLibraryCard, - SystemModelSetting, -} from './model-card'; - -const addedModelList = new Array(4).fill(1); - -const modelLibraryList = new Array(4).fill(1); - -export default function ModelManagement() { - return ( -
-
-

Team management

- -
-
- -
-

Added model

-
- {addedModelList.map((x, idx) => ( - - ))} -
-
-
-
-

Model library

- -
-
- {modelLibraryList.map((x, idx) => ( - - ))} -
-
-
-
- ); -} diff --git a/web/src/pages/profile-setting/model/model-card.tsx b/web/src/pages/profile-setting/model/model-card.tsx deleted file mode 100644 index dad059298..000000000 --- a/web/src/pages/profile-setting/model/model-card.tsx +++ /dev/null @@ -1,136 +0,0 @@ -import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'; -import { Button } from '@/components/ui/button'; -import { Card, CardContent } from '@/components/ui/card'; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from '@/components/ui/select'; -import { Key, MoreVertical, Plus, Trash2 } from 'lucide-react'; -import { PropsWithChildren } from 'react'; - -const settings = [ - { - title: 'GPT Model', - description: - 'The default chat LLM all the newly created knowledgebase will use.', - model: 'DeepseekChat', - }, - { - title: 'Embedding Model', - description: - 'The default embedding model all the newly created knowledgebase will use.', - model: 'DeepseekChat', - }, - { - title: 'Image Model', - description: - 'The default multi-capable model all the newly created knowledgebase will use. It can generate a picture or video.', - model: 'DeepseekChat', - }, - { - title: 'Speech2TXT Model', - description: - 'The default ASR model all the newly created knowledgebase will use. Use this model to translate voices to text something text.', - model: 'DeepseekChat', - }, - { - title: 'TTS Model', - description: - 'The default text to speech model all the newly created knowledgebase will use.', - model: 'DeepseekChat', - }, -]; - -function Title({ children }: PropsWithChildren) { - return {children}; -} - -export function SystemModelSetting() { - return ( - - - {settings.map((x, idx) => ( -
-
- {x.title} - - {x.description} - -
-
- -
-
- ))} -
-
- ); -} - -export function AddModelCard() { - return ( - - -
- - - CN - - -
- Deep seek -

LLM,TEXT EMBEDDING, SPEECH2TEXT, MODERATION

- - - - - - -
- - -
-
-
- ); -} - -export function ModelLibraryCard() { - return ( - - - - - CN - - - Deep seek -

LLM,TEXT EMBEDDING, SPEECH2TEXT, MODERATION

- -
- -
-
-
- ); -} diff --git a/web/src/pages/profile-setting/plan/index.tsx b/web/src/pages/profile-setting/plan/index.tsx deleted file mode 100644 index 2da8dad37..000000000 --- a/web/src/pages/profile-setting/plan/index.tsx +++ /dev/null @@ -1,121 +0,0 @@ -import { Button } from '@/components/ui/button'; -import { Card, CardContent } from '@/components/ui/card'; -import { Segmented, SegmentedValue } from '@/components/ui/segmented'; -import { CircleCheckBig, LogOut } from 'lucide-react'; -import { useMemo, useState } from 'react'; -import { PricingCard } from './pricing-card'; - -const pricingData = [ - { - title: 'Free', - price: '$0', - description: 'Meh, just looking', - features: [ - { name: 'Project', value: '1 project' }, - { name: 'Storage', value: '1 Gb' }, - { name: 'Team', value: '2 members' }, - { name: 'Features', value: 'Basic features' }, - ], - buttonText: 'Current plan', - buttonVariant: 'outline' as const, - }, - { - title: 'Pro', - price: '$16.00', - description: 'For professional use.', - features: [ - { name: 'Project', value: 'Unlimited projects' }, - { name: 'Storage', value: '100 Gb' }, - { name: 'Team', value: 'Unlimited members' }, - { name: 'Features', value: 'Basic features All advanced features' }, - ], - buttonText: 'Upgrade', - buttonVariant: 'default' as const, - isPro: true, - }, - { - title: 'Enterprise', - price: 'Customed', - description: - 'Get full capabilities and support for large-scale mission-critical systems.', - features: [ - { name: 'Project', value: 'Unlimited projects' }, - { name: 'Storage', value: '100 Gb' }, - { name: 'Team', value: 'Unlimited members' }, - { name: 'Features', value: 'Basic features All advanced features' }, - ], - buttonText: 'Contact us', - buttonVariant: 'secondary' as const, - isEnterprise: true, - }, -]; - -export default function Plan() { - const [val, setVal] = useState('monthly'); - const options = useMemo(() => { - return [ - { - label: 'Monthly', - value: 'monthly', - }, - { - label: 'Yearly', - value: 'yearly', - }, - ]; - }, []); - - const handleChange = (path: SegmentedValue) => { - setVal(path as string); - }; - - const list = [ - 'Full access to pro features', - 'Exclusive analyze models', - 'Create more teams', - 'Invite more collaborators', - ]; - - return ( -
-

Plan & balance

- -
- Balance - $ 100.00 -
-
- The value equals to 1,000 tokens or 10.00 GBs of storage - -
-
- - -
Upgrade to access
-
- {list.map((x, idx) => ( -
- - {x} -
- ))} -
- -
- {pricingData.map((plan, index) => ( - - ))} -
-
-
-
- ); -} diff --git a/web/src/pages/profile-setting/plan/pricing-card.tsx b/web/src/pages/profile-setting/plan/pricing-card.tsx deleted file mode 100644 index 2f0024cdf..000000000 --- a/web/src/pages/profile-setting/plan/pricing-card.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import { Badge } from '@/components/ui/badge'; -import { Button } from '@/components/ui/button'; -import { Card, CardContent, CardHeader } from '@/components/ui/card'; -import { cn } from '@/lib/utils'; -import { Mail, Zap } from 'lucide-react'; - -interface PricingFeature { - name: string; - value: string; - tooltip?: string; -} - -interface PricingCardProps { - title: string; - price: string; - description: string; - features: PricingFeature[]; - buttonText: string; - buttonVariant?: 'default' | 'outline' | 'secondary'; - badge?: string; - isPro?: boolean; - isEnterprise?: boolean; -} - -export function PricingCard({ - title, - price, - description, - features, - buttonText, - isPro, - isEnterprise, -}: PricingCardProps) { - const isFree = title === 'Free'; - - return ( - - -
-
- - {isPro && } - {isEnterprise && } - {title} - -
-

- {description} -

-
-
-
- {price} - {price !== 'Customed' && ( - /mo - )} -
- -
-
- -
    - {features.map((feature, index) => ( -
  • -
    - {feature.name} -
    - - {feature.value} - -
  • - ))} -
-
-
- ); -} diff --git a/web/src/pages/profile-setting/profile/hooks/use-profile.ts b/web/src/pages/profile-setting/profile/hooks/use-profile.ts deleted file mode 100644 index 5b8bdf7b5..000000000 --- a/web/src/pages/profile-setting/profile/hooks/use-profile.ts +++ /dev/null @@ -1,151 +0,0 @@ -// src/hooks/useProfile.ts -import { - useFetchUserInfo, - useSaveSetting, -} from '@/hooks/use-user-setting-request'; -import { rsaPsw } from '@/utils'; -import { useCallback, useEffect, useState } from 'react'; - -interface ProfileData { - userName: string; - timeZone: string; - currPasswd?: string; - newPasswd?: string; - avatar: string; - email: string; - confirmPasswd?: string; -} - -export const EditType = { - editName: 'editName', - editTimeZone: 'editTimeZone', - editPassword: 'editPassword', -} as const; - -export type IEditType = keyof typeof EditType; - -export const modalTitle = { - [EditType.editName]: 'Edit Name', - [EditType.editTimeZone]: 'Edit Time Zone', - [EditType.editPassword]: 'Edit Password', -} as const; - -export const useProfile = () => { - const { data: userInfo } = useFetchUserInfo(); - const [profile, setProfile] = useState({ - userName: '', - avatar: '', - timeZone: '', - email: '', - currPasswd: '', - }); - - const [editType, setEditType] = useState(EditType.editName); - const [isEditing, setIsEditing] = useState(false); - const [editForm, setEditForm] = useState>({}); - const { - saveSetting, - loading: submitLoading, - data: saveSettingData, - } = useSaveSetting(); - - useEffect(() => { - // form.setValue('currPasswd', ''); // current password - const profile = { - userName: userInfo.nickname, - timeZone: userInfo.timezone, - avatar: userInfo.avatar || '', - email: userInfo.email, - currPasswd: userInfo.password, - }; - setProfile(profile); - }, [userInfo, setProfile]); - - useEffect(() => { - if (saveSettingData === 0) { - setIsEditing(false); - setEditForm({}); - } - }, [saveSettingData]); - const onSubmit = (newProfile: ProfileData) => { - const payload: Partial<{ - nickname: string; - password: string; - new_password: string; - avatar: string; - timezone: string; - }> = { - nickname: newProfile.userName, - avatar: newProfile.avatar, - timezone: newProfile.timeZone, - }; - - if ( - 'currPasswd' in newProfile && - 'newPasswd' in newProfile && - newProfile.currPasswd && - newProfile.newPasswd - ) { - payload.password = rsaPsw(newProfile.currPasswd!) as string; - payload.new_password = rsaPsw(newProfile.newPasswd!) as string; - } - console.log('payload', payload); - if (editType === EditType.editName && payload.nickname) { - saveSetting({ nickname: payload.nickname }); - setProfile(newProfile); - } - if (editType === EditType.editTimeZone && payload.timezone) { - saveSetting({ timezone: payload.timezone }); - setProfile(newProfile); - } - if (editType === EditType.editPassword && payload.password) { - saveSetting({ - password: payload.password, - new_password: payload.new_password, - }); - setProfile(newProfile); - } - // saveSetting(payload); - }; - - const handleEditClick = useCallback( - (type: IEditType) => { - setEditForm(profile); - setEditType(type); - setIsEditing(true); - }, - [profile], - ); - - const handleCancel = useCallback(() => { - setIsEditing(false); - setEditForm({}); - }, []); - - const handleSave = (data: ProfileData) => { - console.log('handleSave', data); - const newProfile = { ...profile, ...data }; - - onSubmit(newProfile); - // setIsEditing(false); - // setEditForm({}); - }; - - const handleAvatarUpload = (avatar: string) => { - setProfile((prev) => ({ ...prev, avatar })); - saveSetting({ avatar }); - }; - - return { - profile, - setProfile, - submitLoading: submitLoading, - isEditing, - editType, - editForm, - handleEditClick, - handleCancel, - handleSave, - handleAvatarUpload, - }; -}; diff --git a/web/src/pages/profile-setting/profile/index.tsx b/web/src/pages/profile-setting/profile/index.tsx deleted file mode 100644 index 7f8cf5676..000000000 --- a/web/src/pages/profile-setting/profile/index.tsx +++ /dev/null @@ -1,412 +0,0 @@ -// src/components/ProfilePage.tsx -import { AvatarUpload } from '@/components/avatar-upload'; -import PasswordInput from '@/components/originui/password-input'; -import { Button } from '@/components/ui/button'; -import { - Form, - FormControl, - FormField, - FormItem, - FormLabel, - FormMessage, -} from '@/components/ui/form'; -import { Input } from '@/components/ui/input'; -import { Modal } from '@/components/ui/modal/modal'; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from '@/components/ui/select'; -import { useTranslate } from '@/hooks/common-hooks'; -import { TimezoneList } from '@/pages/user-setting/constants'; -import { zodResolver } from '@hookform/resolvers/zod'; -import { t } from 'i18next'; -import { Loader2Icon, PenLine } from 'lucide-react'; -import { FC, useEffect } from 'react'; -import { useForm } from 'react-hook-form'; -import { z } from 'zod'; -import { EditType, modalTitle, useProfile } from './hooks/use-profile'; - -const baseSchema = z.object({ - userName: z - .string() - .min(1, { message: t('setting.usernameMessage') }) - .trim(), - timeZone: z - .string() - .trim() - .min(1, { message: t('setting.timezonePlaceholder') }), -}); - -const nameSchema = baseSchema.extend({ - currPasswd: z.string().optional(), - newPasswd: z.string().optional(), - confirmPasswd: z.string().optional(), -}); - -const passwordSchema = baseSchema - .extend({ - currPasswd: z - .string({ - required_error: t('setting.currentPasswordMessage'), - }) - .trim(), - newPasswd: z - .string({ - required_error: t('setting.newPasswordMessage'), - }) - .trim() - .min(8, { message: t('setting.newPasswordDescription') }), - confirmPasswd: z - .string({ - required_error: t('setting.confirmPasswordMessage'), - }) - .trim() - .min(8, { message: t('setting.newPasswordDescription') }), - }) - .superRefine((data, ctx) => { - if ( - data.newPasswd && - data.confirmPasswd && - data.newPasswd !== data.confirmPasswd - ) { - ctx.addIssue({ - path: ['confirmPasswd'], - message: t('setting.confirmPasswordNonMatchMessage'), - code: z.ZodIssueCode.custom, - }); - } - }); -const ProfilePage: FC = () => { - const { t } = useTranslate('setting'); - - const { - profile, - editType, - isEditing, - submitLoading, - editForm, - handleEditClick, - handleCancel, - handleSave, - handleAvatarUpload, - } = useProfile(); - - const form = useForm>({ - resolver: zodResolver( - editType === EditType.editPassword ? passwordSchema : nameSchema, - ), - defaultValues: { - userName: '', - timeZone: '', - }, - // shouldUnregister: true, - }); - useEffect(() => { - form.reset({ ...editForm, currPasswd: undefined }); - }, [editForm, form]); - - // const ModalContent: FC = () => { - // // let content = null; - // // if (editType === EditType.editName) { - // // content = editName(); - // // } - // return ( - // <> - - // - // ); - // }; - - return ( -
- {/* Header */} -
-

{t('profile')}

-
- {t('profileDescription')} -
-
- - {/* Main Content */} -
- {/* Name */} -
- -
-
- {profile.userName} -
- -
-
- - {/* Avatar */} -
- -
- -
-
- - {/* Time Zone */} -
- -
-
- {profile.timeZone} -
- -
-
- - {/* Email Address */} -
- -
-
- {profile.email} -
- - {t('emailDescription')} - -
-
- - {/* Password */} -
- -
-
- {profile.currPasswd ? '********' : ''} -
- -
-
-
- - {editType && ( - { - if (!open) { - handleCancel(); - } - }} - className="!w-[480px]" - > - {/* */} -
- handleSave(data as any))} - className="flex flex-col mt-6 mb-8 ml-2 space-y-6 " - > - {editType === EditType.editName && ( - ( - -
- - {t('username')} - - - - -
-
-
- -
-
- )} - /> - )} - - {editType === EditType.editTimeZone && ( - ( - -
- - {t('timezone')} - - -
-
-
- -
-
- )} - /> - )} - - {editType === EditType.editPassword && ( - <> - ( - -
- - {t('currentPassword')} - - - - -
-
- -
-
- )} - /> - ( - -
- - {t('newPassword')} - - - - -
-
- -
-
- )} - /> - ( - -
- - {t('confirmPassword')} - - - { - form.trigger('confirmPasswd'); - }} - onChange={(ev) => { - form.setValue( - 'confirmPasswd', - ev.target.value.trim(), - ); - }} - /> - -
-
- -
-
- )} - /> - - )} - -
- - -
- - -
- )} -
- ); -}; - -export default ProfilePage; diff --git a/web/src/pages/profile-setting/prompt/index.tsx b/web/src/pages/profile-setting/prompt/index.tsx deleted file mode 100644 index 0c569f01c..000000000 --- a/web/src/pages/profile-setting/prompt/index.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { Button } from '@/components/ui/button'; -import { Card, CardContent } from '@/components/ui/card'; -import { Plus, Trash2 } from 'lucide-react'; -import { Title } from '../components'; - -const text = `You are an intelligent assistant. Please summarize the content of the knowledge base to answer the question. Please list the data in the knowledge base and answer in detail. When all knowledge base content is irrelevant to the question, your answer must include the sentence "The answer you are looking for is not found in the knowledge base!" Answers need to consider chat history. - Here is the knowledge base: - {knowledge} - The above is the knowledge base.`; - -const PromptManagement = () => { - const modelLibraryList = new Array(8).fill(1); - - return ( -
-
-
-

Prompt templates

- -
-
-
- {modelLibraryList.map((x, idx) => ( - - - Prompt name -

{text}

- -
- - -
-
-
- ))} -
-
- ); -}; - -export default PromptManagement; diff --git a/web/src/pages/profile-setting/sidebar/hooks.tsx b/web/src/pages/profile-setting/sidebar/hooks.tsx deleted file mode 100644 index b50d1f52f..000000000 --- a/web/src/pages/profile-setting/sidebar/hooks.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { useLogout } from '@/hooks/use-login-request'; -import { Routes } from '@/routes'; -import { useCallback, useState } from 'react'; -import { useNavigate } from 'umi'; - -export const useHandleMenuClick = () => { - const navigate = useNavigate(); - const [active, setActive] = useState(); - const { logout } = useLogout(); - - const handleMenuClick = useCallback( - (key: Routes) => () => { - if (key === Routes.Logout) { - logout(); - } else { - setActive(key); - navigate(`${Routes.ProfileSetting}${key}`); - } - }, - [logout, navigate], - ); - - return { handleMenuClick, active }; -}; diff --git a/web/src/pages/profile-setting/sidebar/index.tsx b/web/src/pages/profile-setting/sidebar/index.tsx deleted file mode 100644 index 98b62db91..000000000 --- a/web/src/pages/profile-setting/sidebar/index.tsx +++ /dev/null @@ -1,113 +0,0 @@ -import { RAGFlowAvatar } from '@/components/ragflow-avatar'; -import ThemeToggle from '@/components/theme-toggle'; -import { Button } from '@/components/ui/button'; -import { useSecondPathName } from '@/hooks/route-hook'; -import { useLogout } from '@/hooks/use-login-request'; -import { useFetchUserInfo } from '@/hooks/use-user-setting-request'; -import { cn } from '@/lib/utils'; -import { Routes } from '@/routes'; -import { - AlignEndVertical, - Banknote, - Box, - FileCog, - User, - Users, -} from 'lucide-react'; -import { useHandleMenuClick } from './hooks'; - -const menuItems = [ - { - section: 'Account & collaboration', - items: [ - { icon: User, label: 'Profile', key: Routes.Profile }, - { icon: Users, label: 'Team', key: Routes.Team }, - { icon: Banknote, label: 'Plan', key: Routes.Plan }, - { icon: Banknote, label: 'MCP', key: Routes.Mcp }, - ], - }, - { - section: 'System configurations', - items: [ - { - icon: Box, - label: 'Model management', - key: Routes.Model, - }, - { - icon: FileCog, - label: 'Prompt management', - key: Routes.Prompt, - }, - { - icon: AlignEndVertical, - label: 'Chunking method', - key: Routes.Chunk, - }, - ], - }, -]; - -export function SideBar() { - const pathName = useSecondPathName(); - const { data: userInfo } = useFetchUserInfo(); - const { handleMenuClick, active } = useHandleMenuClick(); - - const { logout } = useLogout(); - - return ( - - ); -} diff --git a/web/src/pages/profile-setting/team/index.tsx b/web/src/pages/profile-setting/team/index.tsx deleted file mode 100644 index c04d03b60..000000000 --- a/web/src/pages/profile-setting/team/index.tsx +++ /dev/null @@ -1,107 +0,0 @@ -import { Button } from '@/components/ui/button'; -import { Card } from '@/components/ui/card'; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger, -} from '@/components/ui/dropdown-menu'; -import { Table, TableBody, TableCell, TableRow } from '@/components/ui/table'; -import { ChevronDown, MoreVertical, Plus, UserPlus } from 'lucide-react'; - -interface TeamMember { - email: string; - name: string; - role: string; -} - -const TeamManagement = () => { - const teamMembers: TeamMember[] = [ - { email: 'yifanwu92@gmail.com', name: 'Yifan Wu', role: 'Admin' }, - { email: 'yifanwu92@gmail.com', name: 'Yifan Wu', role: 'Admin' }, - ]; - - const stats = { - project: 1, - token: '1,000', - storage: '1GB', - }; - - return ( -
-
-
-

Team management

- -
- -
-
-

Yifan's team

- -
- - -
-
-

Project

-

{stats.project}

-
-
-

Token

-

{stats.token}

-
-
-

Storage

-

{stats.storage}

-
-
-
- - -
- - {teamMembers.map((member, idx) => ( - - {member.email} - {member.name} - - - {member.role} - - - - - - - Edit - - Remove - - - - - - ))} - -
- - - - - - - ); -}; - -export default TeamManagement; diff --git a/web/src/routes.ts b/web/src/routes.ts index 306a5225f..215eff345 100644 --- a/web/src/routes.ts +++ b/web/src/routes.ts @@ -268,41 +268,41 @@ const routes = [ layout: false, component: `@/pages${Routes.Chunk}`, }, - { - path: Routes.ProfileSetting, - layout: false, - component: `@/pages${Routes.ProfileSetting}`, - routes: [ - { - path: Routes.ProfileSetting, - redirect: `${Routes.ProfileProfile}`, - }, - { - path: `${Routes.ProfileProfile}`, - component: `@/pages${Routes.ProfileProfile}`, - }, - { - path: `${Routes.ProfileTeam}`, - component: `@/pages${Routes.ProfileTeam}`, - }, - { - path: `${Routes.ProfilePlan}`, - component: `@/pages${Routes.ProfilePlan}`, - }, - { - path: `${Routes.ProfileModel}`, - component: `@/pages${Routes.ProfileModel}`, - }, - { - path: `${Routes.ProfilePrompt}`, - component: `@/pages${Routes.ProfilePrompt}`, - }, - { - path: Routes.ProfileMcp, - component: `@/pages${Routes.ProfileMcp}`, - }, - ], - }, + // { + // path: Routes.ProfileSetting, + // layout: false, + // component: `@/pages${Routes.ProfileSetting}`, + // routes: [ + // { + // path: Routes.ProfileSetting, + // redirect: `${Routes.ProfileProfile}`, + // }, + // { + // path: `${Routes.ProfileProfile}`, + // component: `@/pages${Routes.ProfileProfile}`, + // }, + // { + // path: `${Routes.ProfileTeam}`, + // component: `@/pages${Routes.ProfileTeam}`, + // }, + // { + // path: `${Routes.ProfilePlan}`, + // component: `@/pages${Routes.ProfilePlan}`, + // }, + // { + // path: `${Routes.ProfileModel}`, + // component: `@/pages${Routes.ProfileModel}`, + // }, + // { + // path: `${Routes.ProfilePrompt}`, + // component: `@/pages${Routes.ProfilePrompt}`, + // }, + // { + // path: Routes.ProfileMcp, + // component: `@/pages${Routes.ProfileMcp}`, + // }, + // ], + // }, { path: '/user-setting', component: '@/pages/user-setting',