feat: new var input editor

This commit is contained in:
Joel 2024-02-22 18:49:21 +08:00
parent ee616ee6dd
commit 235bec6481
13 changed files with 250 additions and 134 deletions

View File

@ -0,0 +1,21 @@
'use client'
import type { FC } from 'react'
import React from 'react'
type Props = {
title: string
children: JSX.Element
}
const Field: FC<Props> = ({
title,
children,
}) => {
return (
<div>
<div className='leading-8 text-[13px] font-medium text-gray-700'>{title}</div>
<div>{children}</div>
</div>
)
}
export default React.memo(Field)

View File

@ -1,30 +1,35 @@
'use client'
import type { FC } from 'react'
import React, { useEffect, useState } from 'react'
import React, { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import ModalFoot from '../modal-foot'
import type { Options } from '../config-select'
import ConfigSelect from '../config-select'
import ConfigString from '../config-string'
import SelectTypeItem from '../select-type-item'
import s from './style.module.css'
import Field from './field'
import Toast from '@/app/components/base/toast'
import type { PromptVariable } from '@/models/debug'
import { getNewVar } from '@/utils/var'
import { getNewVarInWorkflow } from '@/utils/var'
import ConfigContext from '@/context/debug-configuration'
import { type InputVar, InputVarType } from '@/app/components/workflow/types'
import Modal from '@/app/components/base/modal'
import Switch from '@/app/components/base/switch'
export type IConfigModalProps = {
payload: PromptVariable
isCreate?: boolean
payload?: InputVar
type?: string
isShow: boolean
onClose: () => void
onConfirm: (newValue: { type: string; value: any }) => void
// onConfirm: (newValue: { type: string; value: any }) => void
onConfirm: (newValue: InputVar) => void
}
const inputClassName = 'w-full px-3 text-sm leading-9 text-gray-900 border-0 rounded-lg grow h-9 bg-gray-50 focus:outline-none focus:ring-1 focus:ring-inset focus:ring-gray-200'
const ConfigModal: FC<IConfigModalProps> = ({
isCreate,
payload,
isShow,
onClose,
@ -32,45 +37,36 @@ const ConfigModal: FC<IConfigModalProps> = ({
}) => {
const { modelConfig } = useContext(ConfigContext)
const { t } = useTranslation()
const { type, name, key, options, max_length } = payload || getNewVar('')
const [tempPayload, setTempPayload] = useState<InputVar>(payload || getNewVarInWorkflow('') as any)
// const { type, name, key, options, max_length } = tempPayload; name => label; variable => key
const { type, label, variable, options, max_length } = tempPayload
const [tempType, setTempType] = useState(type)
useEffect(() => {
setTempType(type)
}, [type])
const handleTypeChange = (type: string) => {
return () => {
setTempType(type)
const isStringInput = type === InputVarType.textInput || type === InputVarType.paragraph
const handlePayloadChange = useCallback((key: string) => {
return (value: any) => {
setTempPayload((prev) => {
return {
...prev,
[key]: value,
}
})
}
}
const isStringInput = tempType === 'string' || tempType === 'paragraph'
const title = isStringInput ? t('appDebug.variableConig.maxLength') : t('appDebug.variableConig.options')
// string type
const [tempMaxLength, setTempMaxValue] = useState(max_length)
useEffect(() => {
setTempMaxValue(max_length)
}, [max_length])
// select type
const [tempOptions, setTempOptions] = useState<Options>(options || [])
useEffect(() => {
setTempOptions(options || [])
}, [options])
}, [])
const handleConfirm = () => {
if (isStringInput) {
onConfirm({ type: tempType, value: tempMaxLength })
onConfirm(tempPayload)
// onConfirm({ type: type, value: tempMaxLength })
}
else {
if (tempOptions.length === 0) {
if (options?.length === 0) {
Toast.notify({ type: 'error', message: 'At least one option requied' })
return
}
const obj: Record<string, boolean> = {}
let hasRepeatedItem = false
tempOptions.forEach((o) => {
options?.forEach((o) => {
if (obj[o]) {
hasRepeatedItem = true
return
@ -81,39 +77,62 @@ const ConfigModal: FC<IConfigModalProps> = ({
Toast.notify({ type: 'error', message: 'Has repeat items' })
return
}
onConfirm({ type: tempType, value: tempOptions })
onConfirm(tempPayload)
}
}
return (
<Modal
title={t('appDebug.variableConig.modalTitle')}
title={t(`appDebug.variableConig.${isCreate ? 'addModalTitle' : 'editModalTitle'}`)}
isShow={isShow}
onClose={onClose}
wrapperClassName='!z-[100]'
>
<div className='mb-8'>
<div className='mt-2 mb-8 text-sm text-gray-500'>{t('appDebug.variableConig.description', { varName: `{{${name || key}}}` })}</div>
<div className='mb-2'>
<div className={s.title}>{t('appDebug.variableConig.fieldType')}</div>
<div className='flex space-x-2'>
<SelectTypeItem type='string' selected={tempType === 'string'} onClick={handleTypeChange('string')} />
<SelectTypeItem type='paragraph' selected={tempType === 'paragraph'} onClick={handleTypeChange('paragraph')} />
<SelectTypeItem type='select' selected={tempType === 'select'} onClick={handleTypeChange('select')} />
</div>
</div>
<div className='space-y-2'>
{tempType !== 'paragraph' && (
<div className='mt-6'>
<div className={s.title}>{title}</div>
{isStringInput
? (
<ConfigString modelId={modelConfig.model_id} value={tempMaxLength} onChange={setTempMaxValue} />
)
: (
<ConfigSelect options={tempOptions} onChange={setTempOptions} />
)}
</div>
)}
<Field title={t('appDebug.variableConig.fieldType')}>
<div className='flex space-x-2'>
{/* TODO handlePayloadChange(string) */}
<SelectTypeItem type={InputVarType.textInput} selected={type === InputVarType.textInput} onClick={() => handlePayloadChange('type')(InputVarType.textInput)} />
<SelectTypeItem type={InputVarType.paragraph} selected={type === InputVarType.paragraph} onClick={() => handlePayloadChange('type')(InputVarType.paragraph)} />
<SelectTypeItem type={InputVarType.select} selected={type === InputVarType.select} onClick={() => handlePayloadChange('type')(InputVarType.select)} />
</div>
</Field>
<Field title={t('appDebug.variableConig.varName')}>
<input
type='text'
className={inputClassName}
value={variable}
onChange={e => handlePayloadChange('variable')(e.target.value)}
/>
</Field>
<Field title={t('appDebug.variableConig.labelName')}>
<input
type='text'
className={inputClassName}
value={label}
onChange={e => handlePayloadChange('label')(e.target.value)}
/>
</Field>
{isStringInput && (
<Field title={t('appDebug.variableConig.maxLength')}>
<ConfigString modelId={modelConfig.model_id} value={max_length} onChange={handlePayloadChange('max_length')} />
</Field>
)}
{type === InputVarType.select && (
<Field title={t('appDebug.variableConig.options')}>
<ConfigSelect options={options!} onChange={handlePayloadChange('options')} />
</Field>
)}
<Field title={t('appDebug.variableConig.required')}>
<Switch defaultValue={tempPayload.required} onChange={handlePayloadChange('required')} />
</Field>
</div>
</div>
<ModalFoot
onConfirm={handleConfirm}

View File

@ -1,8 +0,0 @@
.title {
margin-bottom: 8px;
font-size: 13px;
line-height: 18px;
font-weight: 500;
color: #101828;
text-transform: capitalize;
}

View File

@ -25,6 +25,8 @@ import { AppType } from '@/types/app'
import type { ExternalDataTool } from '@/models/common'
import { useModalContext } from '@/context/modal-context'
import { useEventEmitterContextContext } from '@/context/event-emitter'
import type { InputVar } from '@/app/components/workflow/types'
import { InputVarType } from '@/app/components/workflow/types'
export const ADD_EXTERNAL_DATA_TOOL = 'ADD_EXTERNAL_DATA_TOOL'
@ -71,6 +73,7 @@ const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVar
}
const batchUpdatePromptVariable = (key: string, updateKeys: string[], newValues: any[], isParagraph?: boolean) => {
console.log(key)
const newPromptVariables = promptVariables.map((item) => {
if (item.key === key) {
const newItem: any = { ...item }
@ -111,7 +114,7 @@ const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVar
})
conflictTimer = setTimeout(() => {
const isKeyExists = promptVariables.some(item => item.key.trim() === newKey.trim())
const isKeyExists = promptVariables.some(item => item.key?.trim() === newKey.trim())
if (isKeyExists) {
Toast.notify({
type: 'error',
@ -242,6 +245,17 @@ const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVar
const [currKey, setCurrKey] = useState<string | null>(null)
const currItem = currKey ? promptVariables.find(item => item.key === currKey) : null
const currItemToEdit: InputVar | null = (() => {
if (!currItem)
return null
return {
...currItem,
label: currItem.name,
variable: currItem.key,
type: currItem.type === 'string' ? InputVarType.textInput : currItem.type,
} as InputVar
})()
const [isShowEditModal, { setTrue: showEditModal, setFalse: hideEditModal }] = useBoolean(false)
const handleConfig = ({ key, type, index, name, config, icon, icon_background }: ExternalDataToolParams) => {
@ -297,6 +311,7 @@ const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVar
<tr key={index} className="h-9 leading-9">
<td className="w-[160px] border-b border-gray-100 pl-3">
<div className='flex items-center space-x-1'>
{type}
<IconTypeIcon type={type as IInputTypeIconProps['type']} className='text-gray-400' />
{!readonly
? (
@ -358,14 +373,17 @@ const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVar
{isShowEditModal && (
<EditModal
payload={currItem as PromptVariable}
payload={currItemToEdit!}
isShow={isShowEditModal}
onClose={hideEditModal}
onConfirm={({ type, value }) => {
if (type === 'string')
batchUpdatePromptVariable(currKey as string, ['type', 'max_length'], [type, value || DEFAULT_VALUE_MAX_LEN])
onConfirm={(item) => {
const { type, max_length, options } = item
if (type === InputVarType.textInput)
batchUpdatePromptVariable(currKey as string, ['type', 'max_length'], ['string', max_length || DEFAULT_VALUE_MAX_LEN])
if (type === InputVarType.paragraph)
batchUpdatePromptVariable(currKey as string, ['type', 'max_length'], [InputVarType.paragraph, max_length || DEFAULT_VALUE_MAX_LEN], true)
else
batchUpdatePromptVariable(currKey as string, ['type', 'options'], [type, value || []], type === 'paragraph')
batchUpdatePromptVariable(currKey as string, ['type', 'options'], [type, options || []], false)
hideEditModal()
}}

View File

@ -3,18 +3,18 @@ import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import cn from 'classnames'
import s from './style.module.css'
import { InputVarType } from '@/app/components/workflow/types'
export type ISelectTypeItemProps = {
type: string
type: InputVarType
selected: boolean
onClick: () => void
}
const Icon = ({ type, selected }: Partial<ISelectTypeItemProps>) => {
switch (type) {
case 'select':
case InputVarType.select:
return selected
? (
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
@ -28,16 +28,16 @@ const Icon = ({ type, selected }: Partial<ISelectTypeItemProps>) => {
<path d="M12.8923 0.666672H7.77427C7.42285 0.666661 7.11966 0.666651 6.86995 0.687053C6.60639 0.708587 6.34424 0.756131 6.09199 0.884661C5.71567 1.07641 5.40971 1.38237 5.21796 1.75869C5.08943 2.01095 5.04188 2.27309 5.02035 2.53665C5.00206 2.76051 5.00018 3.02733 4.99999 3.33336L8.92055 3.33335C9.2463 3.33327 9.59951 3.33319 9.90523 3.35816C10.2512 3.38644 10.7084 3.4564 11.1799 3.69667C11.8071 4.01625 12.3171 4.52618 12.6367 5.15339C12.8769 5.62493 12.9469 6.08208 12.9752 6.42809C13.0001 6.73382 13.0001 7.08702 13 7.41279L13 11.3333C13.306 11.3331 13.5728 11.3313 13.7967 11.313C14.0602 11.2914 14.3224 11.2439 14.5746 11.1154C14.9509 10.9236 15.2569 10.6176 15.4487 10.2413C15.5772 9.98907 15.6247 9.72692 15.6463 9.46336C15.6667 9.21366 15.6666 8.91051 15.6666 8.5591V3.44099C15.6666 3.08959 15.6667 2.78635 15.6463 2.53665C15.6247 2.27309 15.5772 2.01095 15.4487 1.75869C15.2569 1.38237 14.9509 1.07641 14.5746 0.884661C14.3224 0.756131 14.0602 0.708587 13.7967 0.687053C13.5469 0.666651 13.2438 0.666661 12.8923 0.666672Z" fill="#667085" />
</svg>
)
case 'paragraph':
case InputVarType.paragraph:
return selected
? (
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="align-left">
<g id="Solid">
<path fillRule="evenodd" clipRule="evenodd" d="M1.33334 6.66665C1.33334 6.29846 1.63182 5.99998 2.00001 5.99998H10.6667C11.0349 5.99998 11.3333 6.29846 11.3333 6.66665C11.3333 7.03484 11.0349 7.33331 10.6667 7.33331H2.00001C1.63182 7.33331 1.33334 7.03484 1.33334 6.66665Z" fill="#155EEF"/>
<path fillRule="evenodd" clipRule="evenodd" d="M1.33334 3.99998C1.33334 3.63179 1.63182 3.33331 2.00001 3.33331H13.3333C13.7015 3.33331 14 3.63179 14 3.99998C14 4.36817 13.7015 4.66665 13.3333 4.66665H2.00001C1.63182 4.66665 1.33334 4.36817 1.33334 3.99998Z" fill="#155EEF"/>
<path fillRule="evenodd" clipRule="evenodd" d="M1.33334 9.33331C1.33334 8.96512 1.63182 8.66665 2.00001 8.66665H13.3333C13.7015 8.66665 14 8.96512 14 9.33331C14 9.7015 13.7015 9.99998 13.3333 9.99998H2.00001C1.63182 9.99998 1.33334 9.7015 1.33334 9.33331Z" fill="#155EEF"/>
<path fillRule="evenodd" clipRule="evenodd" d="M1.33334 12C1.33334 11.6318 1.63182 11.3333 2.00001 11.3333H10.6667C11.0349 11.3333 11.3333 11.6318 11.3333 12C11.3333 12.3682 11.0349 12.6666 10.6667 12.6666H2.00001C1.63182 12.6666 1.33334 12.3682 1.33334 12Z" fill="#155EEF"/>
<path fillRule="evenodd" clipRule="evenodd" d="M1.33334 6.66665C1.33334 6.29846 1.63182 5.99998 2.00001 5.99998H10.6667C11.0349 5.99998 11.3333 6.29846 11.3333 6.66665C11.3333 7.03484 11.0349 7.33331 10.6667 7.33331H2.00001C1.63182 7.33331 1.33334 7.03484 1.33334 6.66665Z" fill="#155EEF" />
<path fillRule="evenodd" clipRule="evenodd" d="M1.33334 3.99998C1.33334 3.63179 1.63182 3.33331 2.00001 3.33331H13.3333C13.7015 3.33331 14 3.63179 14 3.99998C14 4.36817 13.7015 4.66665 13.3333 4.66665H2.00001C1.63182 4.66665 1.33334 4.36817 1.33334 3.99998Z" fill="#155EEF" />
<path fillRule="evenodd" clipRule="evenodd" d="M1.33334 9.33331C1.33334 8.96512 1.63182 8.66665 2.00001 8.66665H13.3333C13.7015 8.66665 14 8.96512 14 9.33331C14 9.7015 13.7015 9.99998 13.3333 9.99998H2.00001C1.63182 9.99998 1.33334 9.7015 1.33334 9.33331Z" fill="#155EEF" />
<path fillRule="evenodd" clipRule="evenodd" d="M1.33334 12C1.33334 11.6318 1.63182 11.3333 2.00001 11.3333H10.6667C11.0349 11.3333 11.3333 11.6318 11.3333 12C11.3333 12.3682 11.0349 12.6666 10.6667 12.6666H2.00001C1.63182 12.6666 1.33334 12.3682 1.33334 12Z" fill="#155EEF" />
</g>
</g>
</svg>
@ -46,15 +46,15 @@ const Icon = ({ type, selected }: Partial<ISelectTypeItemProps>) => {
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="align-left">
<g id="Solid">
<path fillRule="evenodd" clipRule="evenodd" d="M1.33334 6.66666C1.33334 6.29847 1.63182 5.99999 2.00001 5.99999H10.6667C11.0349 5.99999 11.3333 6.29847 11.3333 6.66666C11.3333 7.03485 11.0349 7.33333 10.6667 7.33333H2.00001C1.63182 7.33333 1.33334 7.03485 1.33334 6.66666Z" fill="#667085"/>
<path fillRule="evenodd" clipRule="evenodd" d="M1.33334 3.99999C1.33334 3.63181 1.63182 3.33333 2.00001 3.33333H13.3333C13.7015 3.33333 14 3.63181 14 3.99999C14 4.36818 13.7015 4.66666 13.3333 4.66666H2.00001C1.63182 4.66666 1.33334 4.36818 1.33334 3.99999Z" fill="#667085"/>
<path fillRule="evenodd" clipRule="evenodd" d="M1.33334 9.33333C1.33334 8.96514 1.63182 8.66666 2.00001 8.66666H13.3333C13.7015 8.66666 14 8.96514 14 9.33333C14 9.70152 13.7015 10 13.3333 10H2.00001C1.63182 10 1.33334 9.70152 1.33334 9.33333Z" fill="#667085"/>
<path fillRule="evenodd" clipRule="evenodd" d="M1.33334 12C1.33334 11.6318 1.63182 11.3333 2.00001 11.3333H10.6667C11.0349 11.3333 11.3333 11.6318 11.3333 12C11.3333 12.3682 11.0349 12.6667 10.6667 12.6667H2.00001C1.63182 12.6667 1.33334 12.3682 1.33334 12Z" fill="#667085"/>
<path fillRule="evenodd" clipRule="evenodd" d="M1.33334 6.66666C1.33334 6.29847 1.63182 5.99999 2.00001 5.99999H10.6667C11.0349 5.99999 11.3333 6.29847 11.3333 6.66666C11.3333 7.03485 11.0349 7.33333 10.6667 7.33333H2.00001C1.63182 7.33333 1.33334 7.03485 1.33334 6.66666Z" fill="#667085" />
<path fillRule="evenodd" clipRule="evenodd" d="M1.33334 3.99999C1.33334 3.63181 1.63182 3.33333 2.00001 3.33333H13.3333C13.7015 3.33333 14 3.63181 14 3.99999C14 4.36818 13.7015 4.66666 13.3333 4.66666H2.00001C1.63182 4.66666 1.33334 4.36818 1.33334 3.99999Z" fill="#667085" />
<path fillRule="evenodd" clipRule="evenodd" d="M1.33334 9.33333C1.33334 8.96514 1.63182 8.66666 2.00001 8.66666H13.3333C13.7015 8.66666 14 8.96514 14 9.33333C14 9.70152 13.7015 10 13.3333 10H2.00001C1.63182 10 1.33334 9.70152 1.33334 9.33333Z" fill="#667085" />
<path fillRule="evenodd" clipRule="evenodd" d="M1.33334 12C1.33334 11.6318 1.63182 11.3333 2.00001 11.3333H10.6667C11.0349 11.3333 11.3333 11.6318 11.3333 12C11.3333 12.3682 11.0349 12.6667 10.6667 12.6667H2.00001C1.63182 12.6667 1.33334 12.3682 1.33334 12Z" fill="#667085" />
</g>
</g>
</svg>
)
case 'string':
case InputVarType.textInput:
default:
return selected
? (

View File

@ -7,6 +7,7 @@ import Split from '@/app/components/workflow/nodes/_base/components/split'
import Field from '@/app/components/workflow/nodes/_base/components/field'
import OutputVars, { VarItem } from '@/app/components/workflow/nodes/_base/components/output-vars'
import AddButton from '@/app/components/base/button/add-button'
import ConfigVarModal from '@/app/components/app/configuration/config-var/config-modal'
const i18nPrefix = 'workflow.nodes.start'
@ -15,6 +16,10 @@ const Panel: FC = () => {
const readOnly = false
const {
inputs,
isShowAddVarModal,
showAddVarModal,
handleAddVariable,
hideAddVarModal,
handleVarListChange,
} = useConfig(mockData)
@ -24,7 +29,7 @@ const Panel: FC = () => {
<Field
title={t(`${i18nPrefix}.inputField`)}
operations={
<AddButton onClick={() => { }} />
<AddButton onClick={showAddVarModal} />
}
>
<VarList
@ -69,6 +74,17 @@ const Panel: FC = () => {
</>
</OutputVars>
</div>
{isShowAddVarModal && (
<ConfigVarModal
isCreate
isShow={isShowAddVarModal}
onClose={hideAddVarModal}
onConfirm={(payload) => {
handleAddVariable(payload)
hideAddVarModal()
}}
/>
)}
</div>
)
}

View File

@ -1,11 +1,17 @@
import { useCallback, useState } from 'react'
import produce from 'immer'
import { useBoolean } from 'ahooks'
import type { StartNodeType } from './types'
import type { InputVar } from '@/app/components/workflow/types'
const useConfig = (initInputs: StartNodeType) => {
const [inputs, setInputs] = useState<StartNodeType>(initInputs)
const [isShowAddVarModal, {
setTrue: showAddVarModal,
setFalse: hideAddVarModal,
}] = useBoolean(true)
const handleVarListChange = useCallback((newList: InputVar[]) => {
const newInputs = produce(inputs, (draft: any) => {
draft.variables = newList
@ -21,6 +27,9 @@ const useConfig = (initInputs: StartNodeType) => {
}, [inputs, setInputs])
return {
inputs,
isShowAddVarModal,
showAddVarModal,
hideAddVarModal,
handleVarListChange,
handleAddVariable,
}

View File

@ -1,4 +1,5 @@
/* eslint-disable import/no-mutable-exports */
import { InputVarType } from '@/app/components/workflow/types'
import { AgentStrategy } from '@/types/app'
export let apiPrefix = ''
@ -115,6 +116,15 @@ export const VAR_ITEM_TEMPLATE = {
required: true,
}
export const VAR_ITEM_TEMPLATE_IN_WORKFLOW = {
variable: '',
label: '',
type: InputVarType.textInput,
max_length: DEFAULT_VALUE_MAX_LEN,
required: true,
options: [],
}
export const appDefaultIconBackground = '#D5F5F6'
export const NEED_REFRESH_APP_LIST_KEY = 'needRefreshAppList'

View File

@ -266,18 +266,23 @@ const translation = {
queryNoBeEmpty: 'Query must be set in the prompt',
},
variableConig: {
modalTitle: 'Field settings',
description: 'Setting for variable {{varName}}',
fieldType: 'Field type',
string: 'Short Text',
paragraph: 'Paragraph',
select: 'Select',
notSet: 'Not set, try typing {{input}} in the prefix prompt',
stringTitle: 'Form text box options',
maxLength: 'Max length',
options: 'Options',
addOption: 'Add option',
apiBasedVar: 'API-based Variable',
'addModalTitle': 'Add Input Field',
'editModalTitle': 'Edit Input Field',
'description': 'Setting for variable {{varName}}',
'fieldType': 'Field type',
'string': 'Short Text',
'text-input': 'Short Text',
'paragraph': 'Paragraph',
'select': 'Select',
'notSet': 'Not set, try typing {{input}} in the prefix prompt',
'stringTitle': 'Form text box options',
'maxLength': 'Max length',
'options': 'Options',
'addOption': 'Add option',
'apiBasedVar': 'API-based Variable',
'varName': 'Variable Name',
'labelName': 'Label Name',
'required': 'Required',
},
vision: {
name: 'Vision',

View File

@ -266,18 +266,19 @@ const translation = {
queryNoBeEmpty: 'A consulta deve ser definida na solicitação',
},
variableConig: {
modalTitle: 'Configurações do Campo',
description: 'Configuração para a variável {{varName}}',
fieldType: 'Tipo de Campo',
string: 'Texto Curto',
paragraph: 'Parágrafo',
select: 'Selecionar',
notSet: 'Não definido, tente digitar {{input}} na solicitação',
stringTitle: 'Opções da Caixa de Texto do Formulário',
maxLength: 'Comprimento Máximo',
options: 'Opções',
addOption: 'Adicionar opção',
apiBasedVar: 'Variável Baseada em API',
'addModalTitle': 'Configurações do Campo',
'description': 'Configuração para a variável {{varName}}',
'fieldType': 'Tipo de Campo',
'string': 'Texto Curto',
'text-input': 'Texto Curto',
'paragraph': 'Parágrafo',
'select': 'Selecionar',
'notSet': 'Não definido, tente digitar {{input}} na solicitação',
'stringTitle': 'Opções da Caixa de Texto do Formulário',
'maxLength': 'Comprimento Máximo',
'options': 'Opções',
'addOption': 'Adicionar opção',
'apiBasedVar': 'Variável Baseada em API',
},
vision: {
name: 'Visão',

View File

@ -260,18 +260,19 @@ const translation = {
queryNoBeEmpty: 'Запит має бути встановлений у підказці', // Query must be set in the prompt
},
variableConig: {
modalTitle: 'Налаштування поля', // Field settings
description: 'Налаштування для змінної {{varName}}', // Setting for variable {{varName}}
fieldType: 'Тип поля', // Field type
string: 'Короткий текст', // Short Text
paragraph: 'Абзац', // Paragraph
select: 'Вибрати', // Select
notSet: 'Не налаштовано, спробуйте ввести {{input}} у префіксну підказку', // Not set, try typing {{input}} in the prefix prompt
stringTitle: 'Опції текстового поля форми', // Form text box options
maxLength: 'Максимальна довжина', // Max length
options: 'Опції', // Options
addOption: 'Додати опцію', // Add option
apiBasedVar: 'Змінна на основі API', // API-based Variable
'addModalTitle': 'Налаштування поля', // Field settings
'description': 'Налаштування для змінної {{varName}}', // Setting for variable {{varName}}
'fieldType': 'Тип поля', // Field type
'string': 'Короткий текст', // Short Text
'text-input': 'Короткий текст', // Short Text
'paragraph': 'Абзац', // Paragraph
'select': 'Вибрати', // Select
'notSet': 'Не налаштовано, спробуйте ввести {{input}} у префіксну підказку', // Not set, try typing {{input}} in the prefix prompt
'stringTitle': 'Опції текстового поля форми', // Form text box options
'maxLength': 'Максимальна довжина', // Max length
'options': 'Опції', // Options
'addOption': 'Додати опцію', // Add option
'apiBasedVar': 'Змінна на основі API', // API-based Variable
},
vision: {
name: 'Зображення', // Vision

View File

@ -248,6 +248,9 @@ const translation = {
action: '操作',
typeString: '文本',
typeSelect: '下拉选项',
varName: '变量名称',
labelName: '显示名称',
required: '必填',
},
varKeyError: {
canNoBeEmpty: '变量不能为空',
@ -262,18 +265,20 @@ const translation = {
queryNoBeEmpty: '提示词中必须设置查询内容',
},
variableConig: {
modalTitle: '变量设置',
description: '设置变量 {{varName}}',
fieldType: '字段类型',
string: '文本',
paragraph: '段落',
select: '下拉选项',
notSet: '未设置,在 Prompt 中输入 {{input}} 试试',
stringTitle: '文本框设置',
maxLength: '最大长度',
options: '选项',
addOption: '添加选项',
apiBasedVar: '基于 API 的变量',
'addModalTitle': '添加变量',
'editModalTitle': '编辑变量',
'description': '设置变量 {{varName}}',
'fieldType': '字段类型',
'string': '文本',
'text-input': '文本',
'paragraph': '段落',
'select': '下拉选项',
'notSet': '未设置,在 Prompt 中输入 {{input}} 试试',
'stringTitle': '文本框设置',
'maxLength': '最大长度',
'options': '选项',
'addOption': '添加选项',
'apiBasedVar': '基于 API 的变量',
},
vision: {
name: '视觉',

View File

@ -1,5 +1,6 @@
import { MAX_VAR_KEY_LENGHT, VAR_ITEM_TEMPLATE, getMaxVarNameLength } from '@/config'
import { MAX_VAR_KEY_LENGHT, VAR_ITEM_TEMPLATE, VAR_ITEM_TEMPLATE_IN_WORKFLOW, getMaxVarNameLength } from '@/config'
import { CONTEXT_PLACEHOLDER_TEXT, HISTORY_PLACEHOLDER_TEXT, PRE_PROMPT_PLACEHOLDER_TEXT, QUERY_PLACEHOLDER_TEXT } from '@/app/components/base/prompt-editor/constants'
import { InputVarType } from '@/app/components/workflow/types'
const otherAllowedRegex = /^[a-zA-Z0-9_]+$/
@ -21,6 +22,24 @@ export const getNewVar = (key: string, type: string) => {
}
}
export const getNewVarInWorkflow = (key: string, type = InputVarType.textInput) => {
const { max_length, ...rest } = VAR_ITEM_TEMPLATE_IN_WORKFLOW
if (type !== InputVarType.textInput) {
return {
...rest,
type,
variable: key,
label: key.slice(0, getMaxVarNameLength(key)),
}
}
return {
...VAR_ITEM_TEMPLATE_IN_WORKFLOW,
type,
variable: key,
label: key.slice(0, getMaxVarNameLength(key)),
}
}
const checkKey = (key: string, canBeEmpty?: boolean) => {
if (key.length === 0 && !canBeEmpty)
return 'canNoBeEmpty'