refactor: enhance ChunkPreview with form handling and preview functionality

pull/21398/head
twwu 1 year ago
parent 7d65e9980c
commit e3708bfa85

@ -1,5 +1,5 @@
'use client' 'use client'
import { useCallback, useMemo, useState } from 'react' import { useCallback, useMemo, useRef, useState } from 'react'
import DataSourceOptions from './data-source-options' import DataSourceOptions from './data-source-options'
import type { CrawlResultItem, CustomFile as File, FileItem } from '@/models/datasets' import type { CrawlResultItem, CustomFile as File, FileItem } from '@/models/datasets'
import { DataSourceType } from '@/models/datasets' import { DataSourceType } from '@/models/datasets'
@ -30,7 +30,7 @@ import Processing from './processing'
const TestRunPanel = () => { const TestRunPanel = () => {
const { t } = useTranslation() const { t } = useTranslation()
const [currentStep, setCurrentStep] = useState(3) const [currentStep, setCurrentStep] = useState(1)
const [datasource, setDatasource] = useState<Datasource>() const [datasource, setDatasource] = useState<Datasource>()
const [fileList, setFiles] = useState<FileItem[]>([]) const [fileList, setFiles] = useState<FileItem[]>([])
const [notionPages, setNotionPages] = useState<NotionPage[]>([]) const [notionPages, setNotionPages] = useState<NotionPage[]>([])
@ -47,6 +47,9 @@ const TestRunPanel = () => {
const indexingType = useDatasetDetailContextWithSelector(s => s.dataset?.indexing_technique) const indexingType = useDatasetDetailContextWithSelector(s => s.dataset?.indexing_technique)
const retrievalMethod = useDatasetDetailContextWithSelector(s => s.dataset?.retrieval_model_dict.search_method) const retrievalMethod = useDatasetDetailContextWithSelector(s => s.dataset?.retrieval_model_dict.search_method)
const isPreview = useRef(false)
const formRef = useRef<any>(null)
const { data: pipelineInfo, isFetching: isFetchingPipelineInfo } = usePublishedPipelineInfo(pipelineId || '') const { data: pipelineInfo, isFetching: isFetchingPipelineInfo } = usePublishedPipelineInfo(pipelineId || '')
const allFileLoaded = (fileList.length > 0 && fileList.every(file => file.file.id)) const allFileLoaded = (fileList.length > 0 && fileList.every(file => file.file.id))
@ -158,6 +161,24 @@ const TestRunPanel = () => {
handleNextStep() handleNextStep()
}, [datasource, fileList, handleNextStep, notionPages, websiteCrawlJobId, websitePages]) }, [datasource, fileList, handleNextStep, notionPages, websiteCrawlJobId, websitePages])
const onClickProcess = useCallback(() => {
isPreview.current = false
formRef.current?.submit()
}, [])
const onClickPreview = useCallback(() => {
isPreview.current = true
formRef.current?.submit()
}, [])
const onClickReset = useCallback(() => {
formRef.current?.reset()
}, [])
const handleSubmit = useCallback((data: Record<string, any>) => {
isPreview.current ? handlePreviewChunks(data) : handleProcess(data)
}, [handlePreviewChunks, handleProcess])
if (isFetchingPipelineInfo) { if (isFetchingPipelineInfo) {
return ( return (
<Loading type='app' /> <Loading type='app' />
@ -240,9 +261,12 @@ const TestRunPanel = () => {
{ {
currentStep === 2 && ( currentStep === 2 && (
<ProcessDocuments <ProcessDocuments
ref={formRef}
dataSourceNodeId={datasource?.nodeId || ''} dataSourceNodeId={datasource?.nodeId || ''}
onProcess={handleProcess} onProcess={onClickProcess}
onPreview={handlePreviewChunks} onPreview={onClickPreview}
onSubmit={handleSubmit}
onReset={onClickReset}
onBack={handleBackStep} onBack={handleBackStep}
/> />
) )
@ -280,6 +304,7 @@ const TestRunPanel = () => {
isIdle={true} isIdle={true}
isPending={true} isPending={true}
estimateData={undefined} estimateData={undefined}
onPreview={onClickPreview}
/> />
) )
} }

@ -15,6 +15,7 @@ import { PreviewSlice } from '../../../formatted-text/flavours/preview-slice'
import { SkeletonContainer, SkeletonPoint, SkeletonRectangle, SkeletonRow } from '@/app/components/base/skeleton' import { SkeletonContainer, SkeletonPoint, SkeletonRectangle, SkeletonRow } from '@/app/components/base/skeleton'
import { RiSearchEyeLine } from '@remixicon/react' import { RiSearchEyeLine } from '@remixicon/react'
import Badge from '@/app/components/base/badge' import Badge from '@/app/components/base/badge'
import Button from '@/app/components/base/button'
type ChunkPreviewProps = { type ChunkPreviewProps = {
datasource: Datasource datasource: Datasource
@ -24,6 +25,7 @@ type ChunkPreviewProps = {
isIdle: boolean isIdle: boolean
isPending: boolean isPending: boolean
estimateData: FileIndexingEstimateResponse | undefined estimateData: FileIndexingEstimateResponse | undefined
onPreview: () => void
} }
const ChunkPreview = ({ const ChunkPreview = ({
@ -34,6 +36,7 @@ const ChunkPreview = ({
isIdle, isIdle,
isPending, isPending,
estimateData, estimateData,
onPreview,
}: ChunkPreviewProps) => { }: ChunkPreviewProps) => {
const { t } = useTranslation() const { t } = useTranslation()
const currentDocForm = useDatasetDetailContextWithSelector(s => s.dataset?.doc_form) const currentDocForm = useDatasetDetailContextWithSelector(s => s.dataset?.doc_form)
@ -173,11 +176,16 @@ const ChunkPreview = ({
)} )}
{!isIdle && ( {!isIdle && (
<div className='flex h-full w-full items-center justify-center'> <div className='flex h-full w-full items-center justify-center'>
<div className='flex flex-col items-center justify-center gap-3'> <div className='flex flex-col items-center justify-center gap-3 pb-4'>
<RiSearchEyeLine className='size-10 text-text-empty-state-icon' /> <RiSearchEyeLine className='size-10 text-text-empty-state-icon' />
<p className='text-sm text-text-tertiary'> <p className='text-sm text-text-tertiary'>
{t('datasetCreation.stepTwo.previewChunkTip')} {t('datasetCreation.stepTwo.previewChunkTip')}
</p> </p>
<Button
onClick={onPreview}
>
{t('datasetPipeline.addDocuments.stepTwo.previewChunks')}
</Button>
</div> </div>
</div> </div>
)} )}

@ -2,13 +2,15 @@ import { generateZodSchema } from '@/app/components/base/form/form-scenarios/bas
import { useConfigurations } from './hooks' import { useConfigurations } from './hooks'
import Options from './options' import Options from './options'
import Actions from './actions' import Actions from './actions'
import { useCallback, useRef } from 'react'
import Header from './header' import Header from './header'
type ProcessDocumentsProps = { type ProcessDocumentsProps = {
dataSourceNodeId: string dataSourceNodeId: string
onProcess: (data: Record<string, any>) => void ref: React.RefObject<any>
onPreview: (data: Record<string, any>) => void onProcess: () => void
onPreview: () => void
onReset: () => void
onSubmit: (data: Record<string, any>) => void
onBack: () => void onBack: () => void
} }
@ -16,48 +18,31 @@ const ProcessDocuments = ({
dataSourceNodeId, dataSourceNodeId,
onProcess, onProcess,
onPreview, onPreview,
onSubmit,
onReset,
onBack, onBack,
ref,
}: ProcessDocumentsProps) => { }: ProcessDocumentsProps) => {
const formRef = useRef<any>(null)
const isPreview = useRef(false)
const { initialData, configurations } = useConfigurations(dataSourceNodeId) const { initialData, configurations } = useConfigurations(dataSourceNodeId)
const schema = generateZodSchema(configurations) const schema = generateZodSchema(configurations)
const handleProcess = useCallback(() => {
isPreview.current = false
formRef.current?.submit()
}, [])
const handlePreview = useCallback(() => {
isPreview.current = true
formRef.current?.submit()
}, [])
const handleSubmit = useCallback((data: Record<string, any>) => {
isPreview.current ? onPreview(data) : onProcess(data)
}, [onPreview, onProcess])
const handleReset = useCallback(() => {
formRef.current?.reset()
}, [])
return ( return (
<div className='flex flex-col gap-y-4 pt-4'> <div className='flex flex-col gap-y-4 pt-4'>
<div className='flex flex-col rounded-lg border border-components-panel-border bg-components-panel-bg'> <div className='flex flex-col rounded-lg border border-components-panel-border bg-components-panel-bg'>
<Header <Header
onReset={handleReset} onReset={onReset}
disableReset={!formRef.current?.isDirty()} disableReset={!ref.current?.isDirty()}
onPreview={handlePreview} onPreview={onPreview}
/> />
<Options <Options
ref={formRef} ref={ref}
initialData={initialData} initialData={initialData}
configurations={configurations} configurations={configurations}
schema={schema} schema={schema}
onSubmit={handleSubmit} onSubmit={onSubmit}
/> />
</div> </div>
<Actions onBack={onBack} onProcess={handleProcess} /> <Actions onBack={onBack} onProcess={onProcess} />
</div> </div>
) )
} }

Loading…
Cancel
Save