feat: Implement document processing component with configuration and action handling
parent
8f07e088f5
commit
53f2882077
@ -0,0 +1,25 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import Button from '@/app/components/base/button'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
|
type ActionsProps = {
|
||||||
|
disabled?: boolean
|
||||||
|
handleNextStep: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const Actions = ({
|
||||||
|
disabled,
|
||||||
|
handleNextStep,
|
||||||
|
}: ActionsProps) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='flex justify-end p-4 pt-2'>
|
||||||
|
<Button disabled={disabled} variant='primary' onClick={handleNextStep}>
|
||||||
|
<span className='px-0.5'>{t('datasetCreation.stepOne.button')}</span>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default React.memo(Actions)
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import Button from '@/app/components/base/button'
|
||||||
|
import type { FormType } from '@/app/components/base/form'
|
||||||
|
|
||||||
|
type ActionsProps = {
|
||||||
|
form: FormType
|
||||||
|
onBack: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const Actions = ({
|
||||||
|
form,
|
||||||
|
onBack,
|
||||||
|
}: ActionsProps) => {
|
||||||
|
return (
|
||||||
|
<div className='flex items-center justify-end gap-x-2 p-4 pt-2'>
|
||||||
|
<Button
|
||||||
|
variant='secondary'
|
||||||
|
onClick={onBack}
|
||||||
|
>
|
||||||
|
Back to Data Source
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant='primary'
|
||||||
|
onClick={() => {
|
||||||
|
form.handleSubmit()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Process
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default React.memo(Actions)
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
import type { BaseConfiguration } from '@/app/components/base/form/form-scenarios/base/types'
|
||||||
|
import { BaseFieldType } from '@/app/components/base/form/form-scenarios/base/types'
|
||||||
|
import type { FormData } from './options'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
|
export const useConfigurations = () => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
const maxValue = Number.parseInt(globalThis.document?.body?.getAttribute('data-public-indexing-max-segmentation-tokens-length') || '4000', 10)
|
||||||
|
|
||||||
|
const configurations: BaseConfiguration<FormData>[] = [
|
||||||
|
{
|
||||||
|
type: BaseFieldType.textInput,
|
||||||
|
variable: 'separator',
|
||||||
|
label: t('datasetCreation.stepTwo.separator'),
|
||||||
|
required: false,
|
||||||
|
showConditions: [],
|
||||||
|
placeholder: t('datasetCreation.stepTwo.separatorPlaceholder'),
|
||||||
|
tooltip: t('datasetCreation.stepTwo.separatorTip'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: BaseFieldType.numberInput,
|
||||||
|
variable: 'max_tokens',
|
||||||
|
label: t('datasetCreation.stepTwo.maxLength'),
|
||||||
|
required: false,
|
||||||
|
min: 1,
|
||||||
|
max: maxValue,
|
||||||
|
showConditions: [],
|
||||||
|
placeholder: `≤ ${maxValue}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: BaseFieldType.numberInput,
|
||||||
|
variable: 'chunk_overlap',
|
||||||
|
label: t('datasetCreation.stepTwo.overlap'),
|
||||||
|
required: false,
|
||||||
|
min: 1,
|
||||||
|
showConditions: [],
|
||||||
|
placeholder: t('datasetCreation.stepTwo.overlap') || '',
|
||||||
|
tooltip: t('datasetCreation.stepTwo.overlapTip'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: BaseFieldType.checkbox,
|
||||||
|
variable: 'remove_extra_spaces',
|
||||||
|
label: t('datasetCreation.stepTwo.removeExtraSpaces'),
|
||||||
|
required: false,
|
||||||
|
showConditions: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: BaseFieldType.checkbox,
|
||||||
|
variable: 'remove_urls_emails',
|
||||||
|
label: t('datasetCreation.stepTwo.removeUrlEmails'),
|
||||||
|
required: false,
|
||||||
|
showConditions: [],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
return configurations
|
||||||
|
}
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
import { generateZodSchema } from '@/app/components/base/form/form-scenarios/base/utils'
|
||||||
|
import { useConfigurations } from './hooks'
|
||||||
|
import Options from './options'
|
||||||
|
import Actions from './actions'
|
||||||
|
import type { FormType } from '@/app/components/base/form'
|
||||||
|
import { useCallback } from 'react'
|
||||||
|
|
||||||
|
type DocumentProcessingProps = {
|
||||||
|
payload: any
|
||||||
|
onProcess: (data: any) => void
|
||||||
|
onBack: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const DEFAULT_SEGMENT_IDENTIFIER = '\\n\\n'
|
||||||
|
const DEFAULT_MAXIMUM_CHUNK_LENGTH = 1024
|
||||||
|
const DEFAULT_OVERLAP = 50
|
||||||
|
|
||||||
|
const DocumentProcessing = ({
|
||||||
|
payload,
|
||||||
|
onProcess,
|
||||||
|
onBack,
|
||||||
|
}: DocumentProcessingProps) => {
|
||||||
|
const configurations = useConfigurations()
|
||||||
|
const schema = generateZodSchema(configurations)
|
||||||
|
|
||||||
|
const renderCustomActions = useCallback((form: FormType) => (
|
||||||
|
<Actions form={form} onBack={onBack} />
|
||||||
|
), [onBack])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Options
|
||||||
|
initialData={{
|
||||||
|
separator: DEFAULT_SEGMENT_IDENTIFIER,
|
||||||
|
max_tokens: DEFAULT_MAXIMUM_CHUNK_LENGTH,
|
||||||
|
chunk_overlap: DEFAULT_OVERLAP,
|
||||||
|
remove_extra_spaces: true,
|
||||||
|
remove_urls_emails: false,
|
||||||
|
}}
|
||||||
|
configurations={configurations}
|
||||||
|
schema={schema}
|
||||||
|
onSubmit={(data) => {
|
||||||
|
onProcess(data)
|
||||||
|
}}
|
||||||
|
CustomActions={renderCustomActions}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DocumentProcessing
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
import type { FormType } from '@/app/components/base/form'
|
||||||
|
import { useAppForm } from '@/app/components/base/form'
|
||||||
|
import BaseField from '@/app/components/base/form/form-scenarios/base/field'
|
||||||
|
import type { BaseConfiguration } from '@/app/components/base/form/form-scenarios/base/types'
|
||||||
|
import Toast from '@/app/components/base/toast'
|
||||||
|
import type { ZodSchema } from 'zod'
|
||||||
|
|
||||||
|
export type FormData = {
|
||||||
|
separator: string
|
||||||
|
max_tokens: number
|
||||||
|
chunk_overlap: number
|
||||||
|
remove_extra_spaces: boolean
|
||||||
|
remove_urls_emails: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
type OptionsProps = {
|
||||||
|
initialData: FormData
|
||||||
|
configurations: BaseConfiguration<FormData>[]
|
||||||
|
schema: ZodSchema
|
||||||
|
CustomActions: (form: FormType) => React.JSX.Element
|
||||||
|
onSubmit: (data: FormData) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const Options = ({
|
||||||
|
initialData,
|
||||||
|
configurations,
|
||||||
|
schema,
|
||||||
|
CustomActions,
|
||||||
|
onSubmit,
|
||||||
|
}: OptionsProps) => {
|
||||||
|
const form = useAppForm({
|
||||||
|
defaultValues: initialData,
|
||||||
|
validators: {
|
||||||
|
onSubmit: ({ value }) => {
|
||||||
|
const result = schema.safeParse(value)
|
||||||
|
if (!result.success) {
|
||||||
|
const issues = result.error.issues
|
||||||
|
const firstIssue = issues[0]
|
||||||
|
const errorMessage = `"${firstIssue.path.join('.')}" ${firstIssue.message}`
|
||||||
|
Toast.notify({
|
||||||
|
type: 'error',
|
||||||
|
message: errorMessage,
|
||||||
|
})
|
||||||
|
return errorMessage
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onSubmit: ({ value }) => {
|
||||||
|
onSubmit(value)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form
|
||||||
|
className='w-full'
|
||||||
|
onSubmit={(e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
form.handleSubmit()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className='flex flex-col gap-3 px-4 pb-6 pt-3'>
|
||||||
|
{configurations.map((config, index) => {
|
||||||
|
const FieldComponent = BaseField<FormData>({
|
||||||
|
initialData,
|
||||||
|
config,
|
||||||
|
})
|
||||||
|
return <FieldComponent key={index} form={form} />
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
<form.AppForm>
|
||||||
|
<form.Actions
|
||||||
|
CustomActions={CustomActions}
|
||||||
|
/>
|
||||||
|
</form.AppForm>
|
||||||
|
</form>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Options
|
||||||
Loading…
Reference in New Issue