feat: default value option for select input fields (#21192)
Co-authored-by: crazywoola <427733928@qq.com> Co-authored-by: GuanMu <ballmanjq@gmail.com>
This commit is contained in:
@@ -20,6 +20,7 @@ import FileUploadSetting from '@/app/components/workflow/nodes/_base/components/
|
||||
import Checkbox from '@/app/components/base/checkbox'
|
||||
import { DEFAULT_FILE_UPLOAD_SETTING } from '@/app/components/workflow/constants'
|
||||
import { DEFAULT_VALUE_MAX_LEN } from '@/config'
|
||||
import { SimpleSelect } from '@/app/components/base/select'
|
||||
|
||||
const TEXT_MAX_LENGTH = 256
|
||||
|
||||
@@ -234,9 +235,30 @@ const ConfigModal: FC<IConfigModalProps> = ({
|
||||
|
||||
)}
|
||||
{type === InputVarType.select && (
|
||||
<>
|
||||
<Field title={t('appDebug.variableConfig.options')}>
|
||||
<ConfigSelect options={options || []} onChange={handlePayloadChange('options')} />
|
||||
</Field>
|
||||
{options && options.length > 0 && (
|
||||
<Field title={t('appDebug.variableConfig.defaultValue')}>
|
||||
<SimpleSelect
|
||||
key={`default-select-${options.join('-')}`}
|
||||
className="w-full"
|
||||
items={[
|
||||
{ value: '', name: t('appDebug.variableConfig.noDefaultValue') },
|
||||
...options.filter(opt => opt.trim() !== '').map(option => ({
|
||||
value: option,
|
||||
name: option,
|
||||
})),
|
||||
]}
|
||||
defaultValue={tempPayload.default || ''}
|
||||
onSelect={item => handlePayloadChange('default')(item.value === '' ? undefined : item.value)}
|
||||
placeholder={t('appDebug.variableConfig.selectDefaultValue')}
|
||||
allowSearch={false}
|
||||
/>
|
||||
</Field>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
{[InputVarType.singleFile, InputVarType.multiFiles].includes(type) && (
|
||||
|
@@ -211,7 +211,7 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
|
||||
const isInputInOptions = item.select.options.includes(initInputs[item.select.variable])
|
||||
return {
|
||||
...item.select,
|
||||
default: (isInputInOptions ? initInputs[item.select.variable] : undefined) || item.default,
|
||||
default: (isInputInOptions ? initInputs[item.select.variable] : undefined) || item.select.default,
|
||||
type: 'select',
|
||||
}
|
||||
}
|
||||
|
@@ -73,7 +73,7 @@ const InputsFormContent = ({ showTip }: Props) => {
|
||||
{form.type === InputVarType.select && (
|
||||
<PortalSelect
|
||||
popupClassName='w-[200px]'
|
||||
value={inputsFormValue?.[form.variable]}
|
||||
value={inputsFormValue?.[form.variable] ?? form.default ?? ''}
|
||||
items={form.options.map((option: string) => ({ value: option, name: option }))}
|
||||
onSelect={item => handleFormChange(form.variable, item.value as string)}
|
||||
placeholder={form.label}
|
||||
|
@@ -199,7 +199,7 @@ export const useEmbeddedChatbot = () => {
|
||||
const isInputInOptions = item.select.options.includes(initInputs[item.select.variable])
|
||||
return {
|
||||
...item.select,
|
||||
default: (isInputInOptions ? initInputs[item.select.variable] : undefined) || item.default,
|
||||
default: (isInputInOptions ? initInputs[item.select.variable] : undefined) || item.select.default,
|
||||
type: 'select',
|
||||
}
|
||||
}
|
||||
|
@@ -73,7 +73,7 @@ const InputsFormContent = ({ showTip }: Props) => {
|
||||
{form.type === InputVarType.select && (
|
||||
<PortalSelect
|
||||
popupClassName='w-[200px]'
|
||||
value={inputsFormValue?.[form.variable]}
|
||||
value={inputsFormValue?.[form.variable] ?? form.default ?? ''}
|
||||
items={form.options.map((option: string) => ({ value: option, name: option }))}
|
||||
onSelect={item => handleFormChange(form.variable, item.value as string)}
|
||||
placeholder={form.label}
|
||||
|
@@ -158,7 +158,7 @@ const FormItem: FC<Props> = ({
|
||||
type === InputVarType.select && (
|
||||
<Select
|
||||
className="w-full"
|
||||
defaultValue={value || ''}
|
||||
defaultValue={value || payload.default || ''}
|
||||
items={payload.options?.map(option => ({ name: option, value: option })) || []}
|
||||
onSelect={i => onChange(i.value)}
|
||||
allowSearch={false}
|
||||
|
@@ -47,7 +47,22 @@ const ChatWrapper = (
|
||||
const startVariables = startNode?.data.variables
|
||||
const appDetail = useAppStore(s => s.appDetail)
|
||||
const workflowStore = useWorkflowStore()
|
||||
const inputs = useStore(s => s.inputs)
|
||||
const { inputs, setInputs } = useStore(s => ({
|
||||
inputs: s.inputs,
|
||||
setInputs: s.setInputs,
|
||||
}))
|
||||
|
||||
const initialInputs = useMemo(() => {
|
||||
const initInputs: Record<string, any> = {}
|
||||
if (startVariables) {
|
||||
startVariables.forEach((variable) => {
|
||||
if (variable.default)
|
||||
initInputs[variable.variable] = variable.default
|
||||
})
|
||||
}
|
||||
return initInputs
|
||||
}, [startVariables])
|
||||
|
||||
const features = useFeatures(s => s.features)
|
||||
const config = useMemo(() => {
|
||||
return {
|
||||
@@ -82,6 +97,11 @@ const ChatWrapper = (
|
||||
taskId => stopChatMessageResponding(appDetail!.id, taskId),
|
||||
)
|
||||
|
||||
const handleRestartChat = useCallback(() => {
|
||||
handleRestart()
|
||||
setInputs(initialInputs)
|
||||
}, [handleRestart, setInputs, initialInputs])
|
||||
|
||||
const doSend: OnSend = useCallback((message, files, isRegenerate = false, parentAnswer: ChatItem | null = null) => {
|
||||
handleSend(
|
||||
{
|
||||
@@ -115,9 +135,18 @@ const ChatWrapper = (
|
||||
|
||||
useImperativeHandle(ref, () => {
|
||||
return {
|
||||
handleRestart,
|
||||
handleRestart: handleRestartChat,
|
||||
}
|
||||
}, [handleRestart])
|
||||
}, [handleRestartChat])
|
||||
|
||||
useEffect(() => {
|
||||
if (Object.keys(initialInputs).length > 0) {
|
||||
setInputs({
|
||||
...initialInputs,
|
||||
...inputs,
|
||||
})
|
||||
}
|
||||
}, [initialInputs])
|
||||
|
||||
useEffect(() => {
|
||||
if (isResponding)
|
||||
|
@@ -261,6 +261,9 @@ const translation = {
|
||||
options: 'Optionen',
|
||||
addOption: 'Option hinzufügen',
|
||||
apiBasedVar: 'API-basierte Variable',
|
||||
defaultValue: 'Standardwert',
|
||||
noDefaultValue: 'Kein Standardwert',
|
||||
selectDefaultValue: 'Standardwert auswählen',
|
||||
},
|
||||
vision: {
|
||||
name: 'Vision',
|
||||
|
@@ -404,6 +404,9 @@ const translation = {
|
||||
atLeastOneOption: 'At least one option is required',
|
||||
optionRepeat: 'Has repeat options',
|
||||
},
|
||||
'defaultValue': 'Default value',
|
||||
'noDefaultValue': 'No default value',
|
||||
'selectDefaultValue': 'Select default value',
|
||||
},
|
||||
vision: {
|
||||
name: 'Vision',
|
||||
|
@@ -288,6 +288,9 @@ const translation = {
|
||||
atLeastOneOption: 'Se requiere al menos una opción',
|
||||
optionRepeat: 'Hay opciones repetidas',
|
||||
},
|
||||
'defaultValue': 'Valor predeterminado',
|
||||
'noDefaultValue': 'Sin valor predeterminado',
|
||||
'selectDefaultValue': 'Seleccionar valor predeterminado',
|
||||
},
|
||||
vision: {
|
||||
name: 'Visión',
|
||||
|
@@ -276,6 +276,9 @@ const translation = {
|
||||
atLeastOneOption: 'At least one option is required',
|
||||
optionRepeat: 'Has repeat options',
|
||||
},
|
||||
'defaultValue': 'Valeur par défaut',
|
||||
'noDefaultValue': 'Aucune valeur par défaut',
|
||||
'selectDefaultValue': 'Sélectionner la valeur par défaut',
|
||||
},
|
||||
vision: {
|
||||
name: 'Vision',
|
||||
|
@@ -320,6 +320,9 @@ const translation = {
|
||||
atLeastOneOption: 'कम से कम एक विकल्प आवश्यक है',
|
||||
optionRepeat: 'विकल्प दोहराए गए हैं',
|
||||
},
|
||||
'defaultValue': 'डिफ़ॉल्ट मान',
|
||||
'noDefaultValue': 'कोई डिफ़ॉल्ट मान नहीं',
|
||||
'selectDefaultValue': 'डिफ़ॉल्ट मान चुनें',
|
||||
},
|
||||
vision: {
|
||||
name: 'विजन',
|
||||
|
@@ -322,6 +322,9 @@ const translation = {
|
||||
atLeastOneOption: 'È richiesta almeno un\'opzione',
|
||||
optionRepeat: 'Ci sono opzioni ripetute',
|
||||
},
|
||||
'defaultValue': 'Valore predefinito',
|
||||
'noDefaultValue': 'Nessun valore predefinito',
|
||||
'selectDefaultValue': 'Seleziona valore predefinito',
|
||||
},
|
||||
vision: {
|
||||
name: 'Visione',
|
||||
|
@@ -392,6 +392,9 @@ const translation = {
|
||||
atLeastOneOption: '少なくとも 1 つのオプションが必要です',
|
||||
optionRepeat: '繰り返しオプションがあります',
|
||||
},
|
||||
'defaultValue': 'デフォルト値',
|
||||
'noDefaultValue': 'デフォルト値なし',
|
||||
'selectDefaultValue': 'デフォルト値を選択',
|
||||
},
|
||||
vision: {
|
||||
name: 'ビジョン',
|
||||
|
@@ -287,6 +287,9 @@ const translation = {
|
||||
atLeastOneOption: '적어도 하나의 옵션이 필요합니다',
|
||||
optionRepeat: '옵션이 중복되어 있습니다',
|
||||
},
|
||||
'defaultValue': '기본값',
|
||||
'noDefaultValue': '기본값 없음',
|
||||
'selectDefaultValue': '기본값 선택',
|
||||
},
|
||||
vision: {
|
||||
name: '비전',
|
||||
|
@@ -317,6 +317,9 @@ const translation = {
|
||||
atLeastOneOption: 'Wymagana jest co najmniej jedna opcja',
|
||||
optionRepeat: 'Powtarzają się opcje',
|
||||
},
|
||||
'defaultValue': 'Wartość domyślna',
|
||||
'noDefaultValue': 'Brak wartości domyślnej',
|
||||
'selectDefaultValue': 'Wybierz wartość domyślną',
|
||||
},
|
||||
vision: {
|
||||
name: 'Wizja',
|
||||
|
@@ -293,6 +293,9 @@ const translation = {
|
||||
atLeastOneOption: 'Pelo menos uma opção é obrigatória',
|
||||
optionRepeat: 'Tem opções repetidas',
|
||||
},
|
||||
'defaultValue': 'Valor padrão',
|
||||
'noDefaultValue': 'Nenhum valor padrão',
|
||||
'selectDefaultValue': 'Selecionar valor padrão',
|
||||
},
|
||||
vision: {
|
||||
name: 'Visão',
|
||||
|
@@ -293,6 +293,9 @@ const translation = {
|
||||
atLeastOneOption: 'Este necesară cel puțin o opțiune',
|
||||
optionRepeat: 'Există opțiuni repetate',
|
||||
},
|
||||
'defaultValue': 'Valoare implicită',
|
||||
'noDefaultValue': 'Fără valoare implicită',
|
||||
'selectDefaultValue': 'Selectați valoarea implicită',
|
||||
},
|
||||
vision: {
|
||||
name: 'Viziune',
|
||||
|
@@ -329,6 +329,9 @@ const translation = {
|
||||
atLeastOneOption: 'Требуется хотя бы один вариант',
|
||||
optionRepeat: 'Есть повторяющиеся варианты',
|
||||
},
|
||||
'defaultValue': 'Значение по умолчанию',
|
||||
'noDefaultValue': 'Без значения по умолчанию',
|
||||
'selectDefaultValue': 'Выберите значение по умолчанию',
|
||||
},
|
||||
vision: {
|
||||
name: 'Зрение',
|
||||
|
@@ -329,6 +329,9 @@ const translation = {
|
||||
atLeastOneOption: 'En az bir seçenek gereklidir',
|
||||
optionRepeat: 'Yinelenen seçenekler var',
|
||||
},
|
||||
defaultValue: 'Varsayılan değer',
|
||||
noDefaultValue: 'Varsayılan değer yok',
|
||||
selectDefaultValue: 'Varsayılan değer seç',
|
||||
},
|
||||
vision: {
|
||||
name: 'Görüş',
|
||||
|
@@ -287,6 +287,9 @@ const translation = {
|
||||
atLeastOneOption: 'Потрібно щонайменше одну опцію',
|
||||
optionRepeat: 'Є повторні опції',
|
||||
},
|
||||
'defaultValue': 'Значення за замовчуванням',
|
||||
'noDefaultValue': 'Без значення за замовчуванням',
|
||||
'selectDefaultValue': 'Обрати значення за замовчуванням',
|
||||
},
|
||||
vision: {
|
||||
name: 'Зображення', // Vision
|
||||
|
@@ -287,6 +287,9 @@ const translation = {
|
||||
atLeastOneOption: 'Cần ít nhất một tùy chọn',
|
||||
optionRepeat: 'Có các tùy chọn trùng lặp',
|
||||
},
|
||||
'defaultValue': 'Giá trị mặc định',
|
||||
'noDefaultValue': 'Không có giá trị mặc định',
|
||||
'selectDefaultValue': 'Chọn giá trị mặc định',
|
||||
},
|
||||
vision: {
|
||||
name: 'Thị giác',
|
||||
|
@@ -394,6 +394,9 @@ const translation = {
|
||||
atLeastOneOption: '至少需要一个选项',
|
||||
optionRepeat: '选项不能重复',
|
||||
},
|
||||
'defaultValue': '默认值',
|
||||
'noDefaultValue': '无默认值',
|
||||
'selectDefaultValue': '选择默认值',
|
||||
},
|
||||
vision: {
|
||||
name: '视觉',
|
||||
|
@@ -272,6 +272,9 @@ const translation = {
|
||||
atLeastOneOption: '至少需要一個選項',
|
||||
optionRepeat: '選項不能重複',
|
||||
},
|
||||
'defaultValue': '預設值',
|
||||
'noDefaultValue': '無預設值',
|
||||
'selectDefaultValue': '選擇預設值',
|
||||
},
|
||||
vision: {
|
||||
name: '視覺',
|
||||
|
Reference in New Issue
Block a user