mirror of
https://github.com/langgenius/dify.git
synced 2025-07-24 01:50:21 +00:00
184 lines
6.2 KiB
TypeScript
184 lines
6.2 KiB
TypeScript
import { useCallback, useMemo, useRef, useState } from 'react'
|
|
import type { CrawlResultItem, CustomFile, FileIndexingEstimateResponse } from '@/models/datasets'
|
|
import type { NotionPage } from '@/models/common'
|
|
import { useTranslation } from 'react-i18next'
|
|
import AppUnavailable from '@/app/components/base/app-unavailable'
|
|
import ChunkPreview from '../../../create-from-pipeline/preview/chunk-preview'
|
|
import Loading from '@/app/components/base/loading'
|
|
import ProcessDocuments from './process-documents'
|
|
import LeftHeader from './left-header'
|
|
import { usePipelineExecutionLog, useRunPublishedPipeline } from '@/service/use-pipeline'
|
|
import type { PublishedPipelineRunPreviewResponse } from '@/models/pipeline'
|
|
import { DatasourceType } from '@/models/pipeline'
|
|
import { noop } from 'lodash-es'
|
|
import { useDatasetDetailContextWithSelector } from '@/context/dataset-detail'
|
|
import { useRouter } from 'next/navigation'
|
|
import { useInvalidDocumentList } from '@/service/knowledge/use-document'
|
|
|
|
type PipelineSettingsProps = {
|
|
datasetId: string
|
|
documentId: string
|
|
}
|
|
|
|
const PipelineSettings = ({
|
|
datasetId,
|
|
documentId,
|
|
}: PipelineSettingsProps) => {
|
|
const { t } = useTranslation()
|
|
const { push } = useRouter()
|
|
const [estimateData, setEstimateData] = useState<FileIndexingEstimateResponse | undefined>(undefined)
|
|
const pipelineId = useDatasetDetailContextWithSelector(state => state.dataset?.pipeline_id)
|
|
|
|
const isPreview = useRef(false)
|
|
const formRef = useRef<any>(null)
|
|
|
|
const { data: lastRunData, isFetching: isFetchingLastRunData, isError } = usePipelineExecutionLog({
|
|
dataset_id: datasetId,
|
|
document_id: documentId,
|
|
})
|
|
|
|
const files = useMemo(() => {
|
|
const files: CustomFile[] = []
|
|
if (lastRunData?.datasource_type === DatasourceType.localFile) {
|
|
const { related_id, name, extension } = lastRunData.datasource_info
|
|
files.push({
|
|
id: related_id,
|
|
name,
|
|
extension,
|
|
} as CustomFile)
|
|
}
|
|
return files
|
|
}, [lastRunData])
|
|
|
|
const websitePages = useMemo(() => {
|
|
const websitePages: CrawlResultItem[] = []
|
|
if (lastRunData?.datasource_type === DatasourceType.websiteCrawl) {
|
|
const { content, description, source_url, title } = lastRunData.datasource_info
|
|
websitePages.push({
|
|
markdown: content,
|
|
description,
|
|
source_url,
|
|
title,
|
|
})
|
|
}
|
|
return websitePages
|
|
}, [lastRunData])
|
|
|
|
const onlineDocuments = useMemo(() => {
|
|
const onlineDocuments: NotionPage[] = []
|
|
if (lastRunData?.datasource_type === DatasourceType.onlineDocument) {
|
|
const { workspace_id, page } = lastRunData.datasource_info
|
|
onlineDocuments.push({
|
|
workspace_id,
|
|
...page,
|
|
})
|
|
}
|
|
return onlineDocuments
|
|
}, [lastRunData])
|
|
|
|
const { mutateAsync: runPublishedPipeline, isIdle, isPending } = useRunPublishedPipeline()
|
|
|
|
const handlePreviewChunks = useCallback(async (data: Record<string, any>) => {
|
|
if (!lastRunData)
|
|
return
|
|
const datasourceInfoList: Record<string, any>[] = []
|
|
const documentInfo = lastRunData.datasource_info
|
|
datasourceInfoList.push(documentInfo)
|
|
await runPublishedPipeline({
|
|
pipeline_id: pipelineId!,
|
|
inputs: data,
|
|
start_node_id: lastRunData.datasource_node_id,
|
|
datasource_type: lastRunData.datasource_type,
|
|
datasource_info_list: datasourceInfoList,
|
|
is_preview: true,
|
|
}, {
|
|
onSuccess: (res) => {
|
|
setEstimateData((res as PublishedPipelineRunPreviewResponse).data.outputs)
|
|
},
|
|
})
|
|
}, [lastRunData, pipelineId, runPublishedPipeline])
|
|
|
|
const invalidDocumentList = useInvalidDocumentList(datasetId)
|
|
const handleProcess = useCallback(async (data: Record<string, any>) => {
|
|
if (!lastRunData)
|
|
return
|
|
const datasourceInfoList: Record<string, any>[] = []
|
|
const documentInfo = lastRunData.datasource_info
|
|
datasourceInfoList.push(documentInfo)
|
|
await runPublishedPipeline({
|
|
pipeline_id: pipelineId!,
|
|
inputs: data,
|
|
start_node_id: lastRunData.datasource_node_id,
|
|
datasource_type: lastRunData.datasource_type,
|
|
datasource_info_list: datasourceInfoList,
|
|
is_preview: false,
|
|
}, {
|
|
onSuccess: () => {
|
|
invalidDocumentList()
|
|
push(`/datasets/${datasetId}/documents/${documentId}`)
|
|
},
|
|
})
|
|
}, [datasetId, documentId, invalidDocumentList, lastRunData, pipelineId, push, runPublishedPipeline])
|
|
|
|
const onClickProcess = useCallback(() => {
|
|
isPreview.current = false
|
|
formRef.current?.submit()
|
|
}, [])
|
|
|
|
const onClickPreview = useCallback(() => {
|
|
isPreview.current = true
|
|
formRef.current?.submit()
|
|
}, [])
|
|
|
|
const handleSubmit = useCallback((data: Record<string, any>) => {
|
|
isPreview.current ? handlePreviewChunks(data) : handleProcess(data)
|
|
}, [handlePreviewChunks, handleProcess])
|
|
|
|
if (isFetchingLastRunData) {
|
|
return (
|
|
<Loading type='app' />
|
|
)
|
|
}
|
|
|
|
if (isError)
|
|
return <AppUnavailable code={500} unknownReason={t('datasetCreation.error.unavailable') as string} />
|
|
|
|
return (
|
|
<div
|
|
className='relative flex h-[calc(100vh-56px)] min-w-[1024px] overflow-x-auto rounded-t-2xl border-t border-effects-highlight bg-background-default-subtle'
|
|
>
|
|
<div className='flex h-full flex-1 flex-col px-14'>
|
|
<LeftHeader title={t('datasetPipeline.documentSettings.title')} />
|
|
<div className='grow overflow-y-auto'>
|
|
<ProcessDocuments
|
|
ref={formRef}
|
|
lastRunInputData={lastRunData!.input_data}
|
|
datasourceNodeId={lastRunData!.datasource_node_id}
|
|
onProcess={onClickProcess}
|
|
onPreview={onClickPreview}
|
|
onSubmit={handleSubmit}
|
|
/>
|
|
</div>
|
|
</div>
|
|
{/* Preview */}
|
|
<div className='flex h-full flex-1 pl-2 pt-2'>
|
|
<ChunkPreview
|
|
dataSourceType={lastRunData!.datasource_type}
|
|
files={files}
|
|
onlineDocuments={onlineDocuments}
|
|
websitePages={websitePages}
|
|
isIdle={isIdle}
|
|
isPending={isPending && isPreview.current}
|
|
estimateData={estimateData}
|
|
onPreview={onClickPreview}
|
|
handlePreviewFileChange={noop}
|
|
handlePreviewOnlineDocumentChange={noop}
|
|
handlePreviewWebsitePageChange={noop}
|
|
/>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default PipelineSettings
|