'use client' import type { FC } from 'react' import React, { useCallback, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import { useBoolean } from 'ahooks' import { useContext } from 'use-context-selector' import QueryInput from './components/query-input' 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 { ExternalKnowledgeBaseHitTesting, ExternalKnowledgeBaseHitTestingResponse, HitTesting, HitTestingRecord, HitTestingResponse, Query, } from '@/models/datasets' import Loading from '@/app/components/base/loading' import Drawer from '@/app/components/base/drawer' import Pagination from '@/app/components/base/pagination' import FloatRightContainer from '@/app/components/base/float-right-container' import DatasetDetailContext from '@/context/dataset-detail' import type { RetrievalConfig } from '@/types/app' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' import docStyle from '@/app/components/datasets/documents/detail/completed/style.module.css' import { CardSkelton } from '../documents/detail/completed/skeleton/general-list-skeleton' import EmptyRecords from './components/empty-records' import Records from './components/records' import { useExternalKnowledgeBaseHitTesting, useHitTesting, } from '@/service/knowledge/use-hit-testing' import { useDatasetTestingRecords } from '@/service/knowledge/use-dataset' const limit = 10 type Props = { datasetId: string } const HitTestingPage: FC = ({ datasetId }: Props) => { const { t } = useTranslation() const media = useBreakpoints() const isMobile = media === MediaType.mobile const [hitResult, setHitResult] = useState() const [externalHitResult, setExternalHitResult] = useState() const [queries, setQueries] = useState([]) const [queryInputKey, setQueryInputKey] = useState(Date.now()) const [currPage, setCurrPage] = useState(0) const { data: recordsRes, refetch: recordsRefetch, isLoading: isRecordsLoading } = useDatasetTestingRecords(datasetId, { limit, page: currPage + 1 }) const total = recordsRes?.total || 0 const { dataset: currentDataset } = useContext(DatasetDetailContext) const isExternal = currentDataset?.provider === 'external' 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 { mutateAsync: hitTestingMutation, isPending: isHitTestingPending } = useHitTesting(datasetId) const { mutateAsync: externalKnowledgeBaseHitTestingMutation, isPending: isExternalKnowledgeBaseHitTestingPending, } = useExternalKnowledgeBaseHitTesting(datasetId) const isRetrievalLoading = isHitTestingPending || isExternalKnowledgeBaseHitTestingPending const renderHitResults = (results: HitTesting[] | ExternalKnowledgeBaseHitTesting[]) => (
{t('datasetHitTesting.hit.title', { num: results.length })}
{results.map((record, idx) => isExternal ? ( ) : ( ), )}
) const renderEmptyState = () => (
{t('datasetHitTesting.hit.emptyTip')}
) const handleClickRecord = useCallback((record: HitTestingRecord) => { setQueries(record.queries) setQueryInputKey(Date.now()) }, []) useEffect(() => { setShowRightPanel(!isMobile) }, [isMobile, setShowRightPanel]) return (

{t('datasetHitTesting.title')}

{t('datasetHitTesting.desc')}

setIsShowModifyRetrievalModal(true)} retrievalConfig={retrievalConfig} isEconomy={currentDataset?.indexing_technique === 'economy'} hitTestingMutation={hitTestingMutation} externalKnowledgeBaseHitTestingMutation={externalKnowledgeBaseHitTestingMutation} />
{t('datasetHitTesting.records')}
{isRecordsLoading && (
)} {!isRecordsLoading && recordsRes?.data && recordsRes.data.length > 0 && ( <> {(total && total > limit) ? : null} )} {!isRecordsLoading && !recordsRes?.data?.length && ( )}
{isRetrievalLoading ?
: ( (() => { if (!hitResult?.records.length && !externalHitResult?.records.length) return renderEmptyState() if (hitResult?.records.length) return renderHitResults(hitResult.records) return renderHitResults(externalHitResult?.records || []) })() ) }
setIsShowModifyRetrievalModal(false)} footer={null} mask={isMobile} panelClassName='mt-16 mx-2 sm:mr-2 mb-3 !p-0 !max-w-[640px] rounded-xl' > setIsShowModifyRetrievalModal(false)} onSave={(value) => { setRetrievalConfig(value) setIsShowModifyRetrievalModal(false) }} />
) } export default HitTestingPage