| import type { FC } from 'react' | import type { FC } from 'react' | ||||
| import React, { useCallback, useEffect, useMemo } from 'react' | |||||
| import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' | |||||
| import useSWR from 'swr' | import useSWR from 'swr' | ||||
| import { useRouter } from 'next/navigation' | import { useRouter } from 'next/navigation' | ||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import { omit } from 'lodash-es' | import { omit } from 'lodash-es' | ||||
| import { ArrowRightIcon } from '@heroicons/react/24/solid' | import { ArrowRightIcon } from '@heroicons/react/24/solid' | ||||
| import { useGetState } from 'ahooks' | |||||
| import cn from 'classnames' | import cn from 'classnames' | ||||
| import s from './index.module.css' | import s from './index.module.css' | ||||
| import { FieldInfo } from '@/app/components/datasets/documents/detail/metadata' | import { FieldInfo } from '@/app/components/datasets/documents/detail/metadata' | ||||
| const getFirstDocument = documents[0] | const getFirstDocument = documents[0] | ||||
| const [indexingStatusBatchDetail, setIndexingStatusDetail, getIndexingStatusDetail] = useGetState<IndexingStatusResponse[]>([]) | |||||
| const [indexingStatusBatchDetail, setIndexingStatusDetail] = useState<IndexingStatusResponse[]>([]) | |||||
| const fetchIndexingStatus = async () => { | const fetchIndexingStatus = async () => { | ||||
| const status = await doFetchIndexingStatus({ datasetId, batchId }) | const status = await doFetchIndexingStatus({ datasetId, batchId }) | ||||
| setIndexingStatusDetail(status.data) | setIndexingStatusDetail(status.data) | ||||
| return status.data | |||||
| } | } | ||||
| const [_, setRunId, getRunId] = useGetState<ReturnType<typeof setInterval>>() | |||||
| // const [_, setRunId, getRunId] = useGetState<ReturnType<typeof setInterval>>() | |||||
| const [runId, setRunId] = useState<ReturnType<typeof setInterval>>() | |||||
| const runIdRef = useRef(runId) | |||||
| const getRunId = () => runIdRef.current | |||||
| useEffect(() => { | |||||
| runIdRef.current = runId | |||||
| }, [runId]) | |||||
| const stopQueryStatus = () => { | const stopQueryStatus = () => { | ||||
| clearInterval(getRunId()) | clearInterval(getRunId()) | ||||
| setRunId(undefined) | |||||
| } | } | ||||
| const startQueryStatus = () => { | const startQueryStatus = () => { | ||||
| const runId = setInterval(() => { | |||||
| const indexingStatusBatchDetail = getIndexingStatusDetail() | |||||
| const runId = setInterval(async () => { | |||||
| // It's so strange that the interval can't be cleared after the clearInterval called. And the runId is current. | |||||
| if (!getRunId()) | |||||
| return | |||||
| const indexingStatusBatchDetail = await fetchIndexingStatus() | |||||
| const isCompleted = indexingStatusBatchDetail.every(indexingStatusDetail => ['completed', 'error'].includes(indexingStatusDetail.indexing_status)) | const isCompleted = indexingStatusBatchDetail.every(indexingStatusDetail => ['completed', 'error'].includes(indexingStatusDetail.indexing_status)) | ||||
| if (isCompleted) { | |||||
| if (isCompleted) | |||||
| stopQueryStatus() | stopQueryStatus() | ||||
| return | |||||
| } | |||||
| fetchIndexingStatus() | |||||
| }, 2500) | }, 2500) | ||||
| setRunId(runId) | setRunId(runId) | ||||
| } | } | ||||
| indexingStatusDetail.indexing_status === 'completed' && s.success, | indexingStatusDetail.indexing_status === 'completed' && s.success, | ||||
| )}> | )}> | ||||
| {isSourceEmbedding(indexingStatusDetail) && ( | {isSourceEmbedding(indexingStatusDetail) && ( | ||||
| <div className={s.progressbar} style={{ width: `${getSourcePercent(indexingStatusDetail)}%` }}/> | |||||
| <div className={s.progressbar} style={{ width: `${getSourcePercent(indexingStatusDetail)}%` }} /> | |||||
| )} | )} | ||||
| <div className={`${s.info} grow`}> | <div className={`${s.info} grow`}> | ||||
| {getSourceType(indexingStatusDetail.id) === DataSourceType.FILE && ( | {getSourceType(indexingStatusDetail.id) === DataSourceType.FILE && ( | ||||
| <div className={cn(s.fileIcon, s[getFileType(getSourceName(indexingStatusDetail.id))])}/> | |||||
| <div className={cn(s.fileIcon, s[getFileType(getSourceName(indexingStatusDetail.id))])} /> | |||||
| )} | )} | ||||
| {getSourceType(indexingStatusDetail.id) === DataSourceType.NOTION && ( | {getSourceType(indexingStatusDetail.id) === DataSourceType.NOTION && ( | ||||
| <NotionIcon | <NotionIcon |