Co-authored-by: crazywoola <427733928@qq.com> Co-authored-by: GuanMu <ballmanjq@gmail.com>tags/1.7.1
| @@ -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> | |||
| <> | |||
| <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, | |||
| } | |||
| }, [handleRestartChat]) | |||
| useEffect(() => { | |||
| if (Object.keys(initialInputs).length > 0) { | |||
| setInputs({ | |||
| ...initialInputs, | |||
| ...inputs, | |||
| }) | |||
| } | |||
| }, [handleRestart]) | |||
| }, [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: '視覺', | |||