mirror of
https://github.com/langgenius/dify.git
synced 2025-11-01 19:32:58 +00:00
refactor: update input variable types to use PipelineInputVarType and simplify form data handling
This commit is contained in:
parent
8d4ced227e
commit
bd1073ff1a
@ -1,12 +1,11 @@
|
||||
import React from 'react'
|
||||
import { withForm } from '@/app/components/base/form'
|
||||
import type { FormData } from './types'
|
||||
import InputField from '@/app/components/base/form/form-scenarios/input-field/field'
|
||||
import { useStore } from '@tanstack/react-form'
|
||||
import { useHiddenConfigurations } from './hooks'
|
||||
|
||||
type HiddenFieldsProps = {
|
||||
initialData?: FormData
|
||||
initialData?: Record<string, any>
|
||||
}
|
||||
|
||||
const HiddenFields = ({
|
||||
@ -25,10 +24,10 @@ const HiddenFields = ({
|
||||
return (
|
||||
<>
|
||||
{hiddenConfigurations.map((config, index) => {
|
||||
const FieldComponent = InputField<FormData>({
|
||||
initialData,
|
||||
config,
|
||||
})
|
||||
const FieldComponent = InputField({
|
||||
initialData,
|
||||
config,
|
||||
})
|
||||
return <FieldComponent key={index} form={form} />
|
||||
})}
|
||||
</>
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { InputVarType } from '@/app/components/workflow/types'
|
||||
import { useCallback, useMemo } from 'react'
|
||||
import type { InputFieldConfiguration } from '@/app/components/base/form/form-scenarios/input-field/types'
|
||||
import { InputFieldType } from '@/app/components/base/form/form-scenarios/input-field/types'
|
||||
@ -11,21 +10,22 @@ import { DEFAULT_FILE_UPLOAD_SETTING } from '@/app/components/workflow/constants
|
||||
import { DEFAULT_VALUE_MAX_LEN } from '@/config'
|
||||
import type { FormData } from './types'
|
||||
import { TEXT_MAX_LENGTH } from './schema'
|
||||
import { PipelineInputVarType } from '@/models/pipeline'
|
||||
|
||||
export const useHiddenFieldNames = (type: InputVarType) => {
|
||||
export const useHiddenFieldNames = (type: PipelineInputVarType) => {
|
||||
const { t } = useTranslation()
|
||||
const hiddenFieldNames = useMemo(() => {
|
||||
let fieldNames = []
|
||||
switch (type) {
|
||||
case InputVarType.textInput:
|
||||
case InputVarType.paragraph:
|
||||
case PipelineInputVarType.textInput:
|
||||
case PipelineInputVarType.paragraph:
|
||||
fieldNames = [
|
||||
t('appDebug.variableConfig.defaultValue'),
|
||||
t('appDebug.variableConfig.placeholder'),
|
||||
t('appDebug.variableConfig.tooltips'),
|
||||
]
|
||||
break
|
||||
case InputVarType.number:
|
||||
case PipelineInputVarType.number:
|
||||
fieldNames = [
|
||||
t('appDebug.variableConfig.defaultValue'),
|
||||
t('appDebug.variableConfig.unit'),
|
||||
@ -33,19 +33,19 @@ export const useHiddenFieldNames = (type: InputVarType) => {
|
||||
t('appDebug.variableConfig.tooltips'),
|
||||
]
|
||||
break
|
||||
case InputVarType.select:
|
||||
case PipelineInputVarType.select:
|
||||
fieldNames = [
|
||||
t('appDebug.variableConfig.defaultValue'),
|
||||
t('appDebug.variableConfig.tooltips'),
|
||||
]
|
||||
break
|
||||
case InputVarType.singleFile:
|
||||
case PipelineInputVarType.singleFile:
|
||||
fieldNames = [
|
||||
t('appDebug.variableConfig.uploadMethod'),
|
||||
t('appDebug.variableConfig.tooltips'),
|
||||
]
|
||||
break
|
||||
case InputVarType.multiFiles:
|
||||
case PipelineInputVarType.multiFiles:
|
||||
fieldNames = [
|
||||
t('appDebug.variableConfig.uploadMethod'),
|
||||
t('appDebug.variableConfig.maxNumberOfUploads'),
|
||||
@ -71,20 +71,20 @@ export const useConfigurations = (props: {
|
||||
const { setFieldValue, supportFile } = props
|
||||
|
||||
const handleTypeChange = useCallback((type: string) => {
|
||||
if ([InputVarType.singleFile, InputVarType.multiFiles].includes(type as InputVarType)) {
|
||||
if ([PipelineInputVarType.singleFile, PipelineInputVarType.multiFiles].includes(type as PipelineInputVarType)) {
|
||||
setFieldValue('allowedFileUploadMethods', DEFAULT_FILE_UPLOAD_SETTING.allowed_file_upload_methods)
|
||||
setFieldValue('allowedTypesAndExtensions', {
|
||||
allowedFileTypes: DEFAULT_FILE_UPLOAD_SETTING.allowed_file_types,
|
||||
allowedFileExtensions: DEFAULT_FILE_UPLOAD_SETTING.allowed_file_extensions,
|
||||
})
|
||||
if (type === InputVarType.multiFiles)
|
||||
if (type === PipelineInputVarType.multiFiles)
|
||||
setFieldValue('maxLength', DEFAULT_FILE_UPLOAD_SETTING.max_length)
|
||||
}
|
||||
if (type === InputVarType.paragraph)
|
||||
if (type === PipelineInputVarType.paragraph)
|
||||
setFieldValue('maxLength', DEFAULT_VALUE_MAX_LEN)
|
||||
}, [setFieldValue])
|
||||
|
||||
const initialConfigurations = useMemo((): InputFieldConfiguration<FormData>[] => {
|
||||
const initialConfigurations = useMemo((): InputFieldConfiguration[] => {
|
||||
return [{
|
||||
type: InputFieldType.inputTypeSelect,
|
||||
label: t('appDebug.variableConfig.fieldType'),
|
||||
@ -117,7 +117,7 @@ export const useConfigurations = (props: {
|
||||
required: true,
|
||||
showConditions: [{
|
||||
variable: 'type',
|
||||
value: InputVarType.textInput,
|
||||
value: PipelineInputVarType.textInput,
|
||||
}],
|
||||
min: 1,
|
||||
max: TEXT_MAX_LENGTH,
|
||||
@ -128,7 +128,7 @@ export const useConfigurations = (props: {
|
||||
required: true,
|
||||
showConditions: [{
|
||||
variable: 'type',
|
||||
value: InputVarType.select,
|
||||
value: PipelineInputVarType.select,
|
||||
}],
|
||||
}, {
|
||||
type: InputFieldType.fileTypes,
|
||||
@ -137,7 +137,7 @@ export const useConfigurations = (props: {
|
||||
required: true,
|
||||
showConditions: [{
|
||||
variable: 'type',
|
||||
value: InputVarType.singleFile,
|
||||
value: PipelineInputVarType.singleFile,
|
||||
}],
|
||||
}, {
|
||||
type: InputFieldType.fileTypes,
|
||||
@ -146,7 +146,7 @@ export const useConfigurations = (props: {
|
||||
required: true,
|
||||
showConditions: [{
|
||||
variable: 'type',
|
||||
value: InputVarType.multiFiles,
|
||||
value: PipelineInputVarType.multiFiles,
|
||||
}],
|
||||
}, {
|
||||
type: InputFieldType.checkbox,
|
||||
@ -157,7 +157,7 @@ export const useConfigurations = (props: {
|
||||
}]
|
||||
}, [handleTypeChange, supportFile, t])
|
||||
|
||||
return initialConfigurations
|
||||
return initialConfigurations
|
||||
}
|
||||
|
||||
export const useHiddenConfigurations = (props: {
|
||||
@ -192,7 +192,7 @@ export const useHiddenConfigurations = (props: {
|
||||
return []
|
||||
}, [options, t])
|
||||
|
||||
const hiddenConfigurations = useMemo((): InputFieldConfiguration<FormData>[] => {
|
||||
const hiddenConfigurations = useMemo((): InputFieldConfiguration[] => {
|
||||
return [{
|
||||
type: InputFieldType.textInput,
|
||||
label: t('appDebug.variableConfig.defaultValue'),
|
||||
@ -201,20 +201,20 @@ export const useHiddenConfigurations = (props: {
|
||||
required: false,
|
||||
showConditions: [{
|
||||
variable: 'type',
|
||||
value: InputVarType.textInput,
|
||||
value: PipelineInputVarType.textInput,
|
||||
}],
|
||||
showOptional: true,
|
||||
}, {
|
||||
type: InputFieldType.textInput,
|
||||
label: t('appDebug.variableConfig.defaultValue'),
|
||||
variable: 'default',
|
||||
placeholder: t('appDebug.variableConfig.defaultValuePlaceholder'),
|
||||
required: false,
|
||||
showConditions: [{
|
||||
variable: 'type',
|
||||
value: InputVarType.paragraph,
|
||||
}],
|
||||
showOptional: true,
|
||||
type: InputFieldType.textInput,
|
||||
label: t('appDebug.variableConfig.defaultValue'),
|
||||
variable: 'default',
|
||||
placeholder: t('appDebug.variableConfig.defaultValuePlaceholder'),
|
||||
required: false,
|
||||
showConditions: [{
|
||||
variable: 'type',
|
||||
value: PipelineInputVarType.paragraph,
|
||||
}],
|
||||
showOptional: true,
|
||||
}, {
|
||||
type: InputFieldType.numberInput,
|
||||
label: t('appDebug.variableConfig.defaultValue'),
|
||||
@ -223,7 +223,7 @@ export const useHiddenConfigurations = (props: {
|
||||
required: false,
|
||||
showConditions: [{
|
||||
variable: 'type',
|
||||
value: InputVarType.number,
|
||||
value: PipelineInputVarType.number,
|
||||
}],
|
||||
showOptional: true,
|
||||
}, {
|
||||
@ -233,7 +233,7 @@ export const useHiddenConfigurations = (props: {
|
||||
required: false,
|
||||
showConditions: [{
|
||||
variable: 'type',
|
||||
value: InputVarType.select,
|
||||
value: PipelineInputVarType.select,
|
||||
}],
|
||||
showOptional: true,
|
||||
options: defaultSelectOptions,
|
||||
@ -248,7 +248,7 @@ export const useHiddenConfigurations = (props: {
|
||||
required: false,
|
||||
showConditions: [{
|
||||
variable: 'type',
|
||||
value: InputVarType.textInput,
|
||||
value: PipelineInputVarType.textInput,
|
||||
}],
|
||||
showOptional: true,
|
||||
}, {
|
||||
@ -259,7 +259,7 @@ export const useHiddenConfigurations = (props: {
|
||||
required: false,
|
||||
showConditions: [{
|
||||
variable: 'type',
|
||||
value: InputVarType.paragraph,
|
||||
value: PipelineInputVarType.paragraph,
|
||||
}],
|
||||
showOptional: true,
|
||||
}, {
|
||||
@ -270,7 +270,7 @@ export const useHiddenConfigurations = (props: {
|
||||
required: false,
|
||||
showConditions: [{
|
||||
variable: 'type',
|
||||
value: InputVarType.number,
|
||||
value: PipelineInputVarType.number,
|
||||
}],
|
||||
showOptional: true,
|
||||
}, {
|
||||
@ -281,7 +281,7 @@ export const useHiddenConfigurations = (props: {
|
||||
required: false,
|
||||
showConditions: [{
|
||||
variable: 'type',
|
||||
value: InputVarType.number,
|
||||
value: PipelineInputVarType.number,
|
||||
}],
|
||||
showOptional: true,
|
||||
}, {
|
||||
@ -291,7 +291,7 @@ export const useHiddenConfigurations = (props: {
|
||||
required: false,
|
||||
showConditions: [{
|
||||
variable: 'type',
|
||||
value: InputVarType.singleFile,
|
||||
value: PipelineInputVarType.singleFile,
|
||||
}],
|
||||
}, {
|
||||
type: InputFieldType.uploadMethod,
|
||||
@ -300,7 +300,7 @@ export const useHiddenConfigurations = (props: {
|
||||
required: false,
|
||||
showConditions: [{
|
||||
variable: 'type',
|
||||
value: InputVarType.multiFiles,
|
||||
value: PipelineInputVarType.multiFiles,
|
||||
}],
|
||||
}, {
|
||||
type: InputFieldType.numberSlider,
|
||||
@ -309,7 +309,7 @@ export const useHiddenConfigurations = (props: {
|
||||
required: false,
|
||||
showConditions: [{
|
||||
variable: 'type',
|
||||
value: InputVarType.multiFiles,
|
||||
value: PipelineInputVarType.multiFiles,
|
||||
}],
|
||||
description: t('appDebug.variableConfig.maxNumberTip', {
|
||||
imgLimit: formatFileSize(imgSizeLimit),
|
||||
|
||||
@ -2,7 +2,7 @@ import { useTranslation } from 'react-i18next'
|
||||
import { useCallback, useState } from 'react'
|
||||
import { ChangeType } from '@/app/components/workflow/types'
|
||||
import { useFileUploadConfig } from '@/service/use-common'
|
||||
import type { InputFieldFormProps } from './types'
|
||||
import type { FormData, InputFieldFormProps } from './types'
|
||||
import { useAppForm } from '@/app/components/base/form'
|
||||
import { createInputFieldSchema } from './schema'
|
||||
import Toast from '@/app/components/base/toast'
|
||||
@ -53,7 +53,7 @@ const InputFieldForm = ({
|
||||
type: ChangeType.changeVarName,
|
||||
payload: { beforeKey: initialData?.variable || '', afterKey: value.variable },
|
||||
}
|
||||
onSubmit(value, moreInfo)
|
||||
onSubmit(value as FormData, moreInfo)
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@ -1,12 +1,10 @@
|
||||
import React, { useCallback } from 'react'
|
||||
import { withForm } from '@/app/components/base/form'
|
||||
import type { FormData } from './types'
|
||||
import InputField from '@/app/components/base/form/form-scenarios/input-field/field'
|
||||
import type { DeepKeys } from '@tanstack/react-form'
|
||||
import { useConfigurations } from './hooks'
|
||||
|
||||
type InitialFieldsProps = {
|
||||
initialData?: FormData
|
||||
initialData?: Record<string, any>
|
||||
supportFile: boolean
|
||||
}
|
||||
|
||||
@ -18,7 +16,7 @@ const InitialFields = ({
|
||||
render: function Render({
|
||||
form,
|
||||
}) {
|
||||
const setFieldValue = useCallback((fieldName: DeepKeys<FormData>, value: any) => {
|
||||
const setFieldValue = useCallback((fieldName: string, value: any) => {
|
||||
form.setFieldValue(fieldName, value)
|
||||
}, [form])
|
||||
|
||||
@ -30,10 +28,10 @@ const InitialFields = ({
|
||||
return (
|
||||
<>
|
||||
{initialConfigurations.map((config, index) => {
|
||||
const FieldComponent = InputField<FormData>({
|
||||
initialData,
|
||||
config,
|
||||
})
|
||||
const FieldComponent = InputField({
|
||||
initialData,
|
||||
config,
|
||||
})
|
||||
return <FieldComponent key={index} form={form} />
|
||||
})}
|
||||
</>
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { InputVarType } from '@/app/components/workflow/types'
|
||||
import { MAX_VAR_KEY_LENGTH } from '@/config'
|
||||
import type { TFunction } from 'i18next'
|
||||
import { z } from 'zod'
|
||||
import type { SchemaOptions } from './types'
|
||||
import { PipelineInputVarType } from '@/models/pipeline'
|
||||
|
||||
export const TEXT_MAX_LENGTH = 256
|
||||
|
||||
@ -30,7 +30,7 @@ export const SupportedFileTypes = z.enum([
|
||||
'custom',
|
||||
])
|
||||
|
||||
export const createInputFieldSchema = (type: InputVarType, t: TFunction, options: SchemaOptions) => {
|
||||
export const createInputFieldSchema = (type: PipelineInputVarType, t: TFunction, options: SchemaOptions) => {
|
||||
const { maxFileUploadLimit } = options
|
||||
const commonSchema = z.object({
|
||||
type: InputType,
|
||||
@ -47,22 +47,22 @@ export const createInputFieldSchema = (type: InputVarType, t: TFunction, options
|
||||
message: t('appDebug.variableConfig.errorMsg.labelNameRequired'),
|
||||
}),
|
||||
required: z.boolean(),
|
||||
hint: z.string().optional(),
|
||||
tooltips: z.string().optional(),
|
||||
})
|
||||
if (type === InputVarType.textInput || type === InputVarType.paragraph) {
|
||||
if (type === PipelineInputVarType.textInput || type === PipelineInputVarType.paragraph) {
|
||||
return z.object({
|
||||
maxLength: z.number().min(1).max(TEXT_MAX_LENGTH),
|
||||
default: z.string().optional(),
|
||||
}).merge(commonSchema).passthrough()
|
||||
}
|
||||
if (type === InputVarType.number) {
|
||||
if (type === PipelineInputVarType.number) {
|
||||
return z.object({
|
||||
default: z.number().optional(),
|
||||
unit: z.string().optional(),
|
||||
placeholder: z.string().optional(),
|
||||
}).merge(commonSchema).passthrough()
|
||||
}
|
||||
if (type === InputVarType.select) {
|
||||
if (type === PipelineInputVarType.select) {
|
||||
return z.object({
|
||||
options: z.array(z.string()).nonempty({
|
||||
message: t('appDebug.variableConfig.errorMsg.atLeastOneOption'),
|
||||
@ -75,7 +75,7 @@ export const createInputFieldSchema = (type: InputVarType, t: TFunction, options
|
||||
default: z.string().optional(),
|
||||
}).merge(commonSchema).passthrough()
|
||||
}
|
||||
if (type === InputVarType.singleFile) {
|
||||
if (type === PipelineInputVarType.singleFile) {
|
||||
return z.object({
|
||||
allowedFileUploadMethods: z.array(TransferMethod),
|
||||
allowedTypesAndExtensions: z.object({
|
||||
@ -84,7 +84,7 @@ export const createInputFieldSchema = (type: InputVarType, t: TFunction, options
|
||||
}),
|
||||
}).merge(commonSchema).passthrough()
|
||||
}
|
||||
if (type === InputVarType.multiFiles) {
|
||||
if (type === PipelineInputVarType.multiFiles) {
|
||||
return z.object({
|
||||
allowedFileUploadMethods: z.array(TransferMethod),
|
||||
allowedTypesAndExtensions: z.object({
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
import React from 'react'
|
||||
import { withForm } from '@/app/components/base/form'
|
||||
import type { FormData } from './types'
|
||||
import { useStore } from '@tanstack/react-form'
|
||||
import { useHiddenFieldNames } from './hooks'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { RiArrowRightSLine } from '@remixicon/react'
|
||||
|
||||
type ShowAllSettingsProps = {
|
||||
initialData?: FormData
|
||||
initialData?: Record<string, any>
|
||||
handleShowAllSettings: () => void
|
||||
}
|
||||
|
||||
|
||||
@ -1,14 +1,15 @@
|
||||
import type { InputVarType, MoreInfo, SupportUploadFileTypes } from '@/app/components/workflow/types'
|
||||
import type { MoreInfo, SupportUploadFileTypes } from '@/app/components/workflow/types'
|
||||
import type { PipelineInputVarType } from '@/models/pipeline'
|
||||
import type { TransferMethod } from '@/types/app'
|
||||
|
||||
export type FormData = {
|
||||
type: InputVarType
|
||||
type: PipelineInputVarType
|
||||
label: string
|
||||
variable: string
|
||||
maxLength?: number
|
||||
default?: string | number
|
||||
default?: string
|
||||
required: boolean
|
||||
hint?: string
|
||||
tooltips?: string
|
||||
options?: string[]
|
||||
placeholder?: string
|
||||
unit?: string
|
||||
@ -20,7 +21,7 @@ export type FormData = {
|
||||
}
|
||||
|
||||
export type InputFieldFormProps = {
|
||||
initialData: FormData
|
||||
initialData: Record<string, any>
|
||||
supportFile?: boolean
|
||||
onCancel: () => void
|
||||
onSubmit: (value: FormData, moreInfo?: MoreInfo) => void
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
import { RiCloseLine } from '@remixicon/react'
|
||||
import DialogWrapper from '../dialog-wrapper'
|
||||
import type { InputVar } from '@/app/components/workflow/types'
|
||||
import InputFieldForm from './form'
|
||||
import { convertToInputFieldFormData } from './utils'
|
||||
import { useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import type { InputVar } from '@/models/pipeline'
|
||||
import type { FormData } from './form/types'
|
||||
|
||||
type InputFieldEditorProps = {
|
||||
show: boolean
|
||||
@ -22,8 +23,36 @@ const InputFieldEditor = ({
|
||||
const { t } = useTranslation()
|
||||
const formData = convertToInputFieldFormData(initialData)
|
||||
|
||||
const handleSubmit = useCallback((value: InputVar) => {
|
||||
onSubmit(value)
|
||||
const handleSubmit = useCallback((value: FormData) => {
|
||||
const {
|
||||
type,
|
||||
label,
|
||||
variable,
|
||||
maxLength,
|
||||
required,
|
||||
tooltips,
|
||||
options,
|
||||
placeholder,
|
||||
unit,
|
||||
default: defaultValue,
|
||||
allowedFileUploadMethods,
|
||||
allowedTypesAndExtensions,
|
||||
} = value
|
||||
onSubmit({
|
||||
type,
|
||||
label,
|
||||
variable,
|
||||
max_length: maxLength,
|
||||
required,
|
||||
tooltips,
|
||||
options,
|
||||
placeholder,
|
||||
unit,
|
||||
default: defaultValue,
|
||||
allowed_file_upload_methods: allowedFileUploadMethods,
|
||||
allowed_file_types: allowedTypesAndExtensions.allowedFileTypes,
|
||||
allowed_file_extensions: allowedTypesAndExtensions.allowedFileExtensions,
|
||||
})
|
||||
onClose()
|
||||
}, [onSubmit, onClose])
|
||||
|
||||
|
||||
@ -1,6 +1,12 @@
|
||||
import type { InputVar } from '@/app/components/workflow/types'
|
||||
import type { InputVar } from '@/models/pipeline'
|
||||
import type { FormData } from './form/types'
|
||||
import { getNewVarInWorkflow } from '@/utils/var'
|
||||
import { VAR_ITEM_TEMPLATE_IN_PIPELINE } from '@/config'
|
||||
|
||||
const getNewInputVarInRagPipeline = (): InputVar => {
|
||||
return {
|
||||
...VAR_ITEM_TEMPLATE_IN_PIPELINE,
|
||||
}
|
||||
}
|
||||
|
||||
export const convertToInputFieldFormData = (data?: InputVar): FormData => {
|
||||
const {
|
||||
@ -10,23 +16,23 @@ export const convertToInputFieldFormData = (data?: InputVar): FormData => {
|
||||
max_length,
|
||||
'default': defaultValue,
|
||||
required,
|
||||
hint,
|
||||
tooltips,
|
||||
options,
|
||||
placeholder,
|
||||
unit,
|
||||
allowed_file_upload_methods,
|
||||
allowed_file_types,
|
||||
allowed_file_extensions,
|
||||
} = data || getNewVarInWorkflow('')
|
||||
} = data || getNewInputVarInRagPipeline()
|
||||
|
||||
return {
|
||||
type,
|
||||
label: label as string,
|
||||
label,
|
||||
variable,
|
||||
maxLength: max_length,
|
||||
default: defaultValue,
|
||||
required,
|
||||
hint,
|
||||
tooltips,
|
||||
options,
|
||||
placeholder,
|
||||
unit,
|
||||
|
||||
@ -7,11 +7,12 @@ import {
|
||||
RiDraggable,
|
||||
RiEditLine,
|
||||
} from '@remixicon/react'
|
||||
import type { InputVar } from '@/app/components/workflow/types'
|
||||
import { InputField } from '@/app/components/base/icons/src/vender/pipeline'
|
||||
import InputVarTypeIcon from '@/app/components/workflow/nodes/_base/components/input-var-type-icon'
|
||||
import cn from '@/utils/classnames'
|
||||
import Badge from '@/app/components/base/badge'
|
||||
import type { InputVar } from '@/models/pipeline'
|
||||
import type { InputVarType } from '@/app/components/workflow/types'
|
||||
|
||||
type FieldItemProps = {
|
||||
readonly?: boolean
|
||||
@ -33,7 +34,7 @@ const FieldItem = ({
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
// ref={ref}
|
||||
className={cn(
|
||||
'flex h-8 cursor-pointer items-center justify-between gap-x-1 rounded-lg border border-components-panel-border-subtle bg-components-panel-on-panel-item-bg py-1 pl-2 shadow-xs hover:shadow-sm',
|
||||
(!isHovering || readonly) ? 'pr-2.5' : !readonly && 'pr-1',
|
||||
@ -69,7 +70,7 @@ const FieldItem = ({
|
||||
{payload.required && (
|
||||
<Badge>{t('workflow.nodes.start.required')}</Badge>
|
||||
)}
|
||||
<InputVarTypeIcon type={payload.type} className='h-3 w-3 text-text-tertiary' />
|
||||
<InputVarTypeIcon type={payload.type as unknown as InputVarType} className='h-3 w-3 text-text-tertiary' />
|
||||
</div>
|
||||
)
|
||||
: (!readonly && (
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import type { InputVar } from '@/app/components/workflow/types'
|
||||
import { RiAddLine } from '@remixicon/react'
|
||||
import FieldItem from './field-item'
|
||||
import cn from '@/utils/classnames'
|
||||
@ -6,6 +5,7 @@ import { useCallback, useMemo, useState } from 'react'
|
||||
import InputFieldEditor from '../editor'
|
||||
import { ReactSortable } from 'react-sortablejs'
|
||||
import produce from 'immer'
|
||||
import type { InputVar } from '@/models/pipeline'
|
||||
|
||||
type FieldListProps = {
|
||||
LabelRightContent: React.ReactNode
|
||||
@ -48,7 +48,7 @@ const FieldList = ({
|
||||
}, [handleInputFieldsChange, inputFields])
|
||||
|
||||
const handleAddField = () => {
|
||||
setCurrentIndex(-1)
|
||||
setCurrentIndex(-1) // -1 means add new field
|
||||
setCurrentInputField(undefined)
|
||||
setShowInputFieldEditor(true)
|
||||
}
|
||||
@ -61,6 +61,10 @@ const FieldList = ({
|
||||
|
||||
const handleSubmitChange = useCallback((data: InputVar) => {
|
||||
const newInputFields = produce(inputFields, (draft) => {
|
||||
if (currentIndex === -1) {
|
||||
draft.push(data)
|
||||
return
|
||||
}
|
||||
draft[currentIndex] = data
|
||||
})
|
||||
handleInputFieldsChange(newInputFields)
|
||||
@ -91,7 +95,7 @@ const FieldList = ({
|
||||
list={optionList}
|
||||
setList={list => handleListSortChange(list)}
|
||||
handle='.handle'
|
||||
ghostClass="opacity-50"
|
||||
ghostClass='opacity-50'
|
||||
animation={150}
|
||||
disabled={readonly}
|
||||
>
|
||||
|
||||
@ -5,7 +5,7 @@ import {
|
||||
} from 'react'
|
||||
import { useStore } from '@/app/components/workflow/store'
|
||||
import { RiCloseLine } from '@remixicon/react'
|
||||
import { BlockEnum, type InputVar } from '@/app/components/workflow/types'
|
||||
import { BlockEnum } from '@/app/components/workflow/types'
|
||||
import DialogWrapper from './dialog-wrapper'
|
||||
import FieldList from './field-list'
|
||||
import FooterTip from './footer-tip'
|
||||
@ -15,6 +15,8 @@ import { useNodes } from 'reactflow'
|
||||
import type { DataSourceNodeType } from '@/app/components/workflow/nodes/data-source/types'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import produce from 'immer'
|
||||
import { useNodesSyncDraft } from '../../hooks'
|
||||
import type { InputVar, RAGPipelineVariables } from '@/models/pipeline'
|
||||
|
||||
type InputFieldDialogProps = {
|
||||
readonly?: boolean
|
||||
@ -29,6 +31,7 @@ const InputFieldDialog = ({
|
||||
const setShowInputFieldDialog = useStore(state => state.setShowInputFieldDialog)
|
||||
const ragPipelineVariables = useStore(state => state.ragPipelineVariables)
|
||||
const setRagPipelineVariables = useStore(state => state.setRagPipelineVariables)
|
||||
const { doSyncWorkflowDraft } = useNodesSyncDraft()
|
||||
|
||||
const datasourceTitleMap = useMemo(() => {
|
||||
const datasourceNameMap: Record<string, string> = {}
|
||||
@ -44,11 +47,11 @@ const InputFieldDialog = ({
|
||||
const inputFieldsMap = useMemo(() => {
|
||||
const inputFieldsMap: Record<string, InputVar[]> = {}
|
||||
ragPipelineVariables?.forEach((variable) => {
|
||||
const { nodeId, variables } = variable
|
||||
if (nodeId)
|
||||
inputFieldsMap[nodeId] = variables
|
||||
const { belong_to_node_id: nodeId, ...varConfig } = variable
|
||||
if (inputFieldsMap[nodeId])
|
||||
inputFieldsMap[nodeId].push(varConfig)
|
||||
else
|
||||
inputFieldsMap.shared = variables
|
||||
inputFieldsMap[nodeId] = [varConfig]
|
||||
})
|
||||
return inputFieldsMap
|
||||
}, [ragPipelineVariables])
|
||||
@ -57,13 +60,23 @@ const InputFieldDialog = ({
|
||||
return Object.keys(inputFieldsMap).filter(key => key !== 'shared')
|
||||
}, [inputFieldsMap])
|
||||
|
||||
const updateInputFields = useCallback((key: string, value: InputVar[]) => {
|
||||
const newRagPipelineVariables = produce(ragPipelineVariables!, (draft) => {
|
||||
const index = draft.findIndex(variable => variable.nodeId === key)
|
||||
draft[index].variables = value
|
||||
const updateInputFields = useCallback(async (key: string, value: InputVar[]) => {
|
||||
const NewInputFieldsMap = produce(inputFieldsMap, (draft) => {
|
||||
draft[key] = value
|
||||
})
|
||||
const newRagPipelineVariables: RAGPipelineVariables = []
|
||||
Object.keys(NewInputFieldsMap).forEach((key) => {
|
||||
const inputFields = NewInputFieldsMap[key]
|
||||
inputFields.forEach((inputField) => {
|
||||
newRagPipelineVariables.push({
|
||||
...inputField,
|
||||
belong_to_node_id: key,
|
||||
})
|
||||
})
|
||||
})
|
||||
setRagPipelineVariables?.(newRagPipelineVariables)
|
||||
}, [ragPipelineVariables, setRagPipelineVariables])
|
||||
await doSyncWorkflowDraft()
|
||||
}, [doSyncWorkflowDraft, inputFieldsMap, setRagPipelineVariables])
|
||||
|
||||
const closePanel = useCallback(() => {
|
||||
setShowInputFieldDialog?.(false)
|
||||
@ -99,6 +112,7 @@ const InputFieldDialog = ({
|
||||
return null
|
||||
return (
|
||||
<FieldList
|
||||
key={key}
|
||||
LabelRightContent={<Datasource title={datasourceTitleMap[key]} />}
|
||||
inputFields={inputFields}
|
||||
readonly={readonly}
|
||||
@ -109,15 +123,13 @@ const InputFieldDialog = ({
|
||||
})
|
||||
}
|
||||
{/* Shared Inputs */}
|
||||
{inputFieldsMap.shared?.length > 0 && (
|
||||
<FieldList
|
||||
LabelRightContent={<SharedInputs />}
|
||||
inputFields={inputFieldsMap.shared}
|
||||
readonly={readonly}
|
||||
labelClassName='pt-1 pb-2'
|
||||
handleInputFieldsChange={updateInputFields.bind(null, '')}
|
||||
/>
|
||||
)}
|
||||
<FieldList
|
||||
LabelRightContent={<SharedInputs />}
|
||||
inputFields={inputFieldsMap.shared || []}
|
||||
readonly={readonly}
|
||||
labelClassName='pt-1 pb-2'
|
||||
handleInputFieldsChange={updateInputFields.bind(null, 'shared')}
|
||||
/>
|
||||
</div>
|
||||
<FooterTip />
|
||||
</div>
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import type { RAGPipelineVariables } from '@/models/pipeline'
|
||||
import type { StateCreator } from 'zustand'
|
||||
import { InputVarType } from '../../workflow/types'
|
||||
|
||||
export type RagPipelineSliceShape = {
|
||||
pipelineId: string
|
||||
@ -19,35 +18,6 @@ export const createRagPipelineSliceSlice: StateCreator<RagPipelineSliceShape> =
|
||||
setShowInputFieldDialog: showInputFieldDialog => set(() => ({ showInputFieldDialog })),
|
||||
nodesDefaultConfigs: {},
|
||||
setNodesDefaultConfigs: nodesDefaultConfigs => set(() => ({ nodesDefaultConfigs })),
|
||||
ragPipelineVariables: [{
|
||||
// TODO: delete mock data
|
||||
nodeId: '123',
|
||||
variables: [{
|
||||
variable: 'name',
|
||||
label: 'name',
|
||||
type: InputVarType.textInput,
|
||||
required: true,
|
||||
max_length: 12,
|
||||
}, {
|
||||
variable: 'num',
|
||||
label: 'num',
|
||||
type: InputVarType.number,
|
||||
required: true,
|
||||
}],
|
||||
}, {
|
||||
nodeId: '',
|
||||
variables: [{
|
||||
variable: 'name',
|
||||
label: 'name',
|
||||
type: InputVarType.textInput,
|
||||
required: true,
|
||||
max_length: 12,
|
||||
}, {
|
||||
variable: 'num',
|
||||
label: 'num',
|
||||
type: InputVarType.number,
|
||||
required: true,
|
||||
}],
|
||||
}],
|
||||
ragPipelineVariables: [],
|
||||
setRagPipelineVariables: (ragPipelineVariables: RAGPipelineVariables) => set(() => ({ ragPipelineVariables })),
|
||||
})
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { InputVarType } from '@/app/components/workflow/types'
|
||||
import { AgentStrategy } from '@/types/app'
|
||||
import { PromptRole } from '@/models/debug'
|
||||
import { PipelineInputVarType } from '@/models/pipeline'
|
||||
|
||||
export let apiPrefix = ''
|
||||
export let webPrefix = ''
|
||||
@ -162,6 +163,15 @@ export const VAR_ITEM_TEMPLATE_IN_WORKFLOW = {
|
||||
options: [],
|
||||
}
|
||||
|
||||
export const VAR_ITEM_TEMPLATE_IN_PIPELINE = {
|
||||
variable: '',
|
||||
label: '',
|
||||
type: PipelineInputVarType.textInput,
|
||||
max_length: DEFAULT_VALUE_MAX_LEN,
|
||||
required: true,
|
||||
options: [],
|
||||
}
|
||||
|
||||
export const appDefaultIconBackground = '#D5F5F6'
|
||||
|
||||
export const NEED_REFRESH_APP_LIST_KEY = 'needRefreshAppList'
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
import type { Edge, InputVar, InputVarType, Node } from '@/app/components/workflow/types'
|
||||
import type { Edge, Node, SupportUploadFileTypes } from '@/app/components/workflow/types'
|
||||
import type { DSLImportMode, DSLImportStatus } from './app'
|
||||
import type { ChunkingMode, DatasetPermission, IconInfo } from './datasets'
|
||||
import type { Dependency } from '@/app/components/plugins/types'
|
||||
import type { AppIconSelection } from '@/app/components/base/app-icon-picker'
|
||||
import type { Viewport } from 'reactflow'
|
||||
import type { TransferMethod } from '@/types/app'
|
||||
|
||||
export type PipelineTemplateListParams = {
|
||||
type: 'built-in' | 'customized'
|
||||
@ -96,24 +97,37 @@ export type PipelineCheckDependenciesResponse = {
|
||||
leaked_dependencies: Dependency[]
|
||||
}
|
||||
|
||||
export type Variables = {
|
||||
type: InputVarType
|
||||
label: string
|
||||
description: string
|
||||
variable: string
|
||||
max_length: number
|
||||
required: boolean
|
||||
options?: string[]
|
||||
default: string | number | boolean
|
||||
export enum PipelineInputVarType {
|
||||
textInput = 'text-input',
|
||||
paragraph = 'paragraph',
|
||||
select = 'select',
|
||||
number = 'number',
|
||||
singleFile = 'file',
|
||||
multiFiles = 'file-list',
|
||||
checkbox = 'checkbox',
|
||||
}
|
||||
|
||||
export type RAGPipelineVariable = {
|
||||
belong_to_node_id: string // indicates belong to which node or 'shared'
|
||||
type: PipelineInputVarType
|
||||
label: string
|
||||
variable: string
|
||||
max_length?: number
|
||||
default?: string
|
||||
placeholder?: string
|
||||
unit?: string
|
||||
required: boolean
|
||||
tooltips?: string
|
||||
options?: string[]
|
||||
allowed_file_upload_methods?: TransferMethod[]
|
||||
allowed_file_types?: SupportUploadFileTypes[]
|
||||
allowed_file_extensions?: string[]
|
||||
}
|
||||
|
||||
export type InputVar = Omit<RAGPipelineVariable, 'belong_to_node_id'>
|
||||
|
||||
export type PipelineProcessingParamsResponse = {
|
||||
variables: Variables[]
|
||||
variables: RAGPipelineVariable[]
|
||||
}
|
||||
|
||||
export type RAGPipelineVariable = InputVar
|
||||
|
||||
export type RAGPipelineVariables = Array<{
|
||||
nodeId: string
|
||||
variables: RAGPipelineVariable[]
|
||||
}>
|
||||
export type RAGPipelineVariables = RAGPipelineVariable[]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user