diff --git a/web/app/components/datasets/hit-testing/components/result-item-external.tsx b/web/app/components/datasets/hit-testing/components/result-item-external.tsx new file mode 100644 index 0000000000..000b56d914 --- /dev/null +++ b/web/app/components/datasets/hit-testing/components/result-item-external.tsx @@ -0,0 +1,60 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import { useTranslation } from 'react-i18next' +import { useBoolean } from 'ahooks' +import ResultItemMeta from './result-item-meta' +import ResultItemFooter from './result-item-footer' +import type { ExternalKnowledgeBaseHitTesting } from '@/models/datasets' +import cn from '@/utils/classnames' +import Modal from '@/app/components/base/modal' +import { FileAppearanceTypeEnum } from '@/app/components/base/file-uploader/types' + +const i18nPrefix = 'datasetHitTesting' +type Props = { + payload: ExternalKnowledgeBaseHitTesting + positionId: number +} + +const ResultItemExternal: FC = ({ payload, positionId }) => { + const { t } = useTranslation() + const { content, title, score } = payload + const [ + isShowDetailModal, + { setTrue: showDetailModal, setFalse: hideDetailModal }, + ] = useBoolean(false) + + return ( +
+ {/* Meta info */} + + + {/* Main */} +
+
{content}
+
+ + {/* Foot */} + + + {isShowDetailModal && ( + +
+ +
+ {content} +
+
+
+ )} +
+ ) +} + +export default React.memo(ResultItemExternal) diff --git a/web/app/components/datasets/hit-testing/components/result-item-footer.tsx b/web/app/components/datasets/hit-testing/components/result-item-footer.tsx new file mode 100644 index 0000000000..66b053ba0b --- /dev/null +++ b/web/app/components/datasets/hit-testing/components/result-item-footer.tsx @@ -0,0 +1,42 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import { useTranslation } from 'react-i18next' +import { RiArrowRightUpLine } from '@remixicon/react' +import FileIcon from '@/app/components/base/file-uploader/file-type-icon' +import type { FileAppearanceTypeEnum } from '@/app/components/base/file-uploader/types' + +type Props = { + docType: FileAppearanceTypeEnum + docTitle: string + showDetailModal: () => void +} +const i18nPrefix = 'datasetHitTesting' + +const ResultItemFooter: FC = ({ + docType, + docTitle, + showDetailModal, +}) => { + const { t } = useTranslation() + + return ( +
+
+ + + {docTitle} + +
+
+
{t(`${i18nPrefix}.open`)}
+ +
+
+ ) +} + +export default React.memo(ResultItemFooter) diff --git a/web/app/components/datasets/hit-testing/components/result-item-meta.tsx b/web/app/components/datasets/hit-testing/components/result-item-meta.tsx new file mode 100644 index 0000000000..87267aa8b8 --- /dev/null +++ b/web/app/components/datasets/hit-testing/components/result-item-meta.tsx @@ -0,0 +1,45 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import { useTranslation } from 'react-i18next' +import { SegmentIndexTag } from '../../documents/detail/completed/common/segment-index-tag' +import Dot from '../../documents/detail/completed/common/dot' +import Score from './score' +import cn from '@/utils/classnames' + +type Props = { + labelPrefix: string + positionId: number + wordCount: number + score: number + className?: string +} + +const ResultItemMeta: FC = ({ + labelPrefix, + positionId, + wordCount, + score, + className, +}) => { + const { t } = useTranslation() + + return ( +
+
+ + +
+ {wordCount} {t('datasetDocuments.segment.characters', { count: wordCount })} +
+
+ +
+ ) +} + +export default React.memo(ResultItemMeta) diff --git a/web/app/components/datasets/hit-testing/components/result-item.tsx b/web/app/components/datasets/hit-testing/components/result-item.tsx index 3c8c146d53..16bc40f67c 100644 --- a/web/app/components/datasets/hit-testing/components/result-item.tsx +++ b/web/app/components/datasets/hit-testing/components/result-item.tsx @@ -2,33 +2,29 @@ import type { FC } from 'react' import React from 'react' import { useTranslation } from 'react-i18next' -import { RiArrowDownSLine, RiArrowRightSLine, RiArrowRightUpLine } from '@remixicon/react' +import { RiArrowDownSLine, RiArrowRightSLine } from '@remixicon/react' import { useBoolean } from 'ahooks' -import { SegmentIndexTag } from '../../documents/detail/completed/common/segment-index-tag' -import Dot from '../../documents/detail/completed/common/dot' -import Score from './score' import ChildChunkItem from './child-chunks-item' import ChunkDetailModal from './chunk-detail-modal' +import ResultItemMeta from './result-item-meta' +import ResultItemFooter from './result-item-footer' import type { HitTesting } from '@/models/datasets' import cn from '@/utils/classnames' -import FileIcon from '@/app/components/base/file-uploader/file-type-icon' import type { FileAppearanceTypeEnum } from '@/app/components/base/file-uploader/types' import Tag from '@/app/components/datasets/documents/detail/completed/common/tag' import { extensionToFileType } from '@/app/components/datasets/hit-testing/utils/extension-to-file-type' const i18nPrefix = 'datasetHitTesting' type Props = { - isExternal: boolean payload: HitTesting } const ResultItem: FC = ({ - isExternal, payload, }) => { const { t } = useTranslation() - const { segment, content: externalContent, score, child_chunks } = payload - const data = isExternal ? externalContent : segment + const { segment, score, child_chunks } = payload + const data = segment const { position, word_count, content, keywords, document } = data const isParentChildRetrieval = !!(child_chunks && child_chunks.length > 0) const extension = document.name.split('.').slice(-1)[0] as FileAppearanceTypeEnum @@ -46,18 +42,7 @@ const ResultItem: FC = ({ return (
{/* Meta info */} -
-
- - -
{word_count} {t('datasetDocuments.segment.characters', { count: word_count })}
-
- -
+ {/* Main */}
@@ -88,19 +73,7 @@ const ResultItem: FC = ({ )}
{/* Foot */} -
-
- - {document.name} -
-
-
{t(`${i18nPrefix}.open`)}
- -
-
+ { isShowDetailModal && ( diff --git a/web/app/components/datasets/hit-testing/index.tsx b/web/app/components/datasets/hit-testing/index.tsx index ccc200bbe6..33f2acc65b 100644 --- a/web/app/components/datasets/hit-testing/index.tsx +++ b/web/app/components/datasets/hit-testing/index.tsx @@ -12,8 +12,9 @@ import Textarea from './textarea' import s from './style.module.css' import ModifyRetrievalModal from './modify-retrieval-modal' import ResultItem from './components/result-item' +import ResultItemExternal from './components/result-item-external' import cn from '@/utils/classnames' -import type { ExternalKnowledgeBaseHitTestingResponse, HitTestingResponse } from '@/models/datasets' +import type { ExternalKnowledgeBaseHitTesting, ExternalKnowledgeBaseHitTestingResponse, HitTesting, HitTestingResponse } from '@/models/datasets' import Loading from '@/app/components/base/loading' import Drawer from '@/app/components/base/drawer' import Pagination from '@/app/components/base/pagination' @@ -41,7 +42,7 @@ const RecordsEmpty: FC = () => {
} -const HitTesting: FC = ({ datasetId }: Props) => { +const HitTestingPage: FC = ({ datasetId }: Props) => { const { t } = useTranslation() const { formatTime } = useTimestamp() @@ -68,19 +69,25 @@ const HitTesting: FC = ({ datasetId }: Props) => { const [retrievalConfig, setRetrievalConfig] = useState(currentDataset?.retrieval_model_dict as RetrievalConfig) const [isShowModifyRetrievalModal, setIsShowModifyRetrievalModal] = useState(false) const [isShowRightPanel, { setTrue: showRightPanel, setFalse: hideRightPanel, set: setShowRightPanel }] = useBoolean(!isMobile) - const renderHitResults = (results: any[]) => ( + const renderHitResults = (results: HitTesting[] | ExternalKnowledgeBaseHitTesting[]) => (
{t('datasetHitTesting.hit.title', { num: results.length })}
- {results.map((record, idx) => ( - - ))} + {results.map((record, idx) => + isExternal + ? ( + + ) + : ( + + ), + )}
) @@ -130,7 +137,7 @@ const HitTesting: FC = ({ datasetId }: Props) => { <>
- + @@ -208,4 +215,4 @@ const HitTesting: FC = ({ datasetId }: Props) => { ) } -export default HitTesting +export default HitTestingPage diff --git a/web/app/components/datasets/hit-testing/textarea.tsx b/web/app/components/datasets/hit-testing/textarea.tsx index fcd72a2f1b..43366754fe 100644 --- a/web/app/components/datasets/hit-testing/textarea.tsx +++ b/web/app/components/datasets/hit-testing/textarea.tsx @@ -84,6 +84,7 @@ const TextAreaWithButton = ({ } const externalRetrievalTestingOnSubmit = async () => { + setLoading(true) const [e, res] = await asyncRunSafe( externalKnowledgeBaseHitTesting({ datasetId,
{t('datasetHitTesting.table.header.source')} {t('datasetHitTesting.table.header.text')}