import React, { useId, useState, useEffect } from 'react'; import { Parameter } from '../recipe'; import { Button } from './ui/button'; import { defineMessages, useIntl } from '../i18n'; const i18n = defineMessages({ cancelRecipeSetup: { id: 'parameterInputModal.cancelRecipeSetup', defaultMessage: 'Cancel Recipe Setup', }, whatToDo: { id: 'parameterInputModal.whatToDo', defaultMessage: 'What would you like to do?', }, backToForm: { id: 'parameterInputModal.backToForm', defaultMessage: 'Back to Parameter Form', }, startNewChat: { id: 'parameterInputModal.startNewChat', defaultMessage: 'Start New Chat (No Recipe)', }, recipeParameters: { id: 'parameterInputModal.recipeParameters', defaultMessage: 'Recipe Parameters', }, selectOption: { id: 'parameterInputModal.selectOption', defaultMessage: 'Select an option...', }, select: { id: 'parameterInputModal.select', defaultMessage: 'Select...', }, true: { id: 'parameterInputModal.true', defaultMessage: 'True', }, false: { id: 'parameterInputModal.false', defaultMessage: 'False', }, enterValue: { id: 'parameterInputModal.enterValue', defaultMessage: 'Enter value for {key}...', }, cancel: { id: 'parameterInputModal.cancel', defaultMessage: 'Cancel', }, startRecipe: { id: 'parameterInputModal.startRecipe', defaultMessage: 'Start Recipe', }, }); interface ParameterInputModalProps { parameters: Parameter[]; onSubmit: (values: Record) => void; onClose: () => void; initialValues?: Record; } function needsUserValue(param: Parameter): boolean { return param.requirement === 'required' || param.requirement === 'user_prompt'; } const ParameterInputModal: React.FC = ({ parameters, onSubmit, onClose, initialValues, }) => { const intl = useIntl(); const fieldIdPrefix = useId(); const fieldId = (key: string): string => `${fieldIdPrefix}-${key}`; const [inputValues, setInputValues] = useState>({}); const [validationErrors, setValidationErrors] = useState>({}); const [showCancelOptions, setShowCancelOptions] = useState(false); useEffect(() => { const defaultValues: Record = {}; parameters.forEach((param) => { if (param.requirement === 'optional' && param.default) { defaultValues[param.key] = param.input_type === 'boolean' ? param.default.toLowerCase() : param.default; } }); setInputValues({ ...defaultValues, ...initialValues }); }, [parameters, initialValues]); const handleChange = (name: string, value: string): void => { setInputValues((prevValues: Record) => ({ ...prevValues, [name]: value })); }; const handleSubmit = (): void => { setValidationErrors({}); const requiredParams: Parameter[] = parameters.filter(needsUserValue); const errors: Record = {}; requiredParams.forEach((param) => { const value = inputValues[param.key]?.trim(); if (!value) { errors[param.key] = `${param.description || param.key} is required`; } }); if (Object.keys(errors).length > 0) { setValidationErrors(errors); return; } onSubmit(inputValues); }; const handleCancel = (): void => { const hasAnyParams = parameters.length > 0; if (hasAnyParams) { setShowCancelOptions(true); } else { onClose(); } }; return (
{showCancelOptions ? (

{intl.formatMessage(i18n.cancelRecipeSetup)}

{intl.formatMessage(i18n.whatToDo)}

) : (

{intl.formatMessage(i18n.recipeParameters)}

{parameters.map((param) => (
{param.input_type === 'select' && param.options ? ( ) : param.input_type === 'boolean' ? ( ) : ( handleChange(param.key, e.target.value)} className={`w-full p-3 border rounded-lg bg-background-secondary text-text-primary focus:outline-none focus:ring-2 ${ validationErrors[param.key] ? 'border-red-500 focus:ring-red-500' : 'border-border-primary focus:ring-border-secondary' }`} placeholder={ param.default || intl.formatMessage(i18n.enterValue, { key: param.key }) } /> )} {validationErrors[param.key] && (

{validationErrors[param.key]}

)}
))}
)}
); }; export default ParameterInputModal;