mirror of
https://github.com/aljazceru/goose.git
synced 2026-01-02 22:14:26 +01:00
ui: add validation to provider form (#1932)
This commit is contained in:
@@ -21,6 +21,7 @@ const customFormsMap = {
|
||||
|
||||
export default function ProviderConfigurationModal() {
|
||||
const { upsert } = useConfig();
|
||||
const [validationErrors, setValidationErrors] = useState({});
|
||||
const { isOpen, currentProvider, modalProps, closeModal } = useProviderModal();
|
||||
const [configValues, setConfigValues] = useState({});
|
||||
|
||||
@@ -36,6 +37,31 @@ export default function ProviderConfigurationModal() {
|
||||
e.preventDefault();
|
||||
console.log('Form submitted for:', currentProvider.name);
|
||||
|
||||
// Reset previous validation errors
|
||||
setValidationErrors({});
|
||||
|
||||
// Validation logic
|
||||
const parameters = currentProvider.metadata.config_keys || [];
|
||||
const errors = {};
|
||||
|
||||
// Check required fields
|
||||
parameters.forEach((parameter) => {
|
||||
if (
|
||||
parameter.required &&
|
||||
(configValues[parameter.name] === undefined ||
|
||||
configValues[parameter.name] === null ||
|
||||
configValues[parameter.name] === '')
|
||||
) {
|
||||
errors[parameter.name] = `${parameter.name} is required`;
|
||||
}
|
||||
});
|
||||
|
||||
// If there are validation errors, stop the submission
|
||||
if (Object.keys(errors).length > 0) {
|
||||
setValidationErrors(errors);
|
||||
return; // Stop the submission process
|
||||
}
|
||||
|
||||
try {
|
||||
// Wait for the submission to complete
|
||||
await SubmitHandler(upsert, currentProvider, configValues);
|
||||
@@ -79,6 +105,7 @@ export default function ProviderConfigurationModal() {
|
||||
configValues={configValues}
|
||||
setConfigValues={setConfigValues}
|
||||
provider={currentProvider}
|
||||
validationErrors={validationErrors}
|
||||
{...(modalProps.formProps || {})} // Spread any custom form props
|
||||
/>
|
||||
|
||||
|
||||
@@ -6,12 +6,14 @@ interface DefaultProviderSetupFormProps {
|
||||
configValues: Record<string, any>;
|
||||
setConfigValues: React.Dispatch<React.SetStateAction<Record<string, any>>>;
|
||||
provider: any;
|
||||
validationErrors: any;
|
||||
}
|
||||
|
||||
export default function DefaultProviderSetupForm({
|
||||
configValues,
|
||||
setConfigValues,
|
||||
provider,
|
||||
validationErrors,
|
||||
}: DefaultProviderSetupFormProps) {
|
||||
const parameters = provider.metadata.config_keys || [];
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
@@ -107,7 +109,9 @@ export default function DefaultProviderSetupForm({
|
||||
}))
|
||||
}
|
||||
placeholder={getPlaceholder(parameter)}
|
||||
className="w-full h-14 px-4 font-regular rounded-lg border shadow-none border-gray-300 bg-white text-lg placeholder:text-gray-400 font-regular text-gray-900"
|
||||
className={`w-full h-14 px-4 font-regular rounded-lg border shadow-none ${
|
||||
validationErrors[parameter.name] ? 'border-red-500' : 'border-gray-300'
|
||||
} bg-white text-lg placeholder:text-gray-400 font-regular text-gray-900`}
|
||||
required={true}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1,81 +1,3 @@
|
||||
import { useConfig } from '../../../../../ConfigContext';
|
||||
import React from 'react';
|
||||
|
||||
/**
|
||||
* Custom hook for provider configuration submission
|
||||
* Returns a submit handler function and submission state
|
||||
*/
|
||||
export const useDefaultSubmit = () => {
|
||||
const { upsert } = useConfig();
|
||||
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
||||
const [error, setError] = React.useState(null);
|
||||
const [isSuccess, setIsSuccess] = React.useState(false);
|
||||
|
||||
/**
|
||||
* Submit handler for provider configuration
|
||||
* @param {Object} provider - The provider object with metadata
|
||||
* @param {Object} configValues - The form values to be submitted
|
||||
* @param {Function} onSuccess - Optional callback for successful submission
|
||||
*/
|
||||
const handleSubmit = async (provider, configValues, onSuccess) => {
|
||||
setIsSubmitting(true);
|
||||
setError(null);
|
||||
setIsSuccess(false);
|
||||
|
||||
try {
|
||||
const parameters = provider.metadata.config_keys || [];
|
||||
|
||||
// Create an array of promises for all the upsert operations
|
||||
const upsertPromises = parameters.map((parameter) => {
|
||||
// Skip parameters that don't have a value and aren't required
|
||||
if (!configValues[parameter.name] && !parameter.required) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// For required parameters with no value, use the default if available
|
||||
const value =
|
||||
configValues[parameter.name] !== undefined
|
||||
? configValues[parameter.name]
|
||||
: parameter.default;
|
||||
|
||||
// Skip if there's still no value
|
||||
if (value === undefined || value === null) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// Create the provider-specific config key
|
||||
// Format: provider.{provider_name}.{parameter_name}
|
||||
const configKey = `provider.${provider.name}.${parameter.name}`;
|
||||
|
||||
// Pass the is_secret flag from the parameter definition
|
||||
return upsert(configKey, value, parameter.secret || false);
|
||||
});
|
||||
|
||||
// Wait for all upsert operations to complete
|
||||
await Promise.all(upsertPromises);
|
||||
|
||||
setIsSuccess(true);
|
||||
|
||||
// Call the success callback if provided
|
||||
if (onSuccess) {
|
||||
onSuccess();
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to save provider configuration:', err);
|
||||
setError('Failed to save configuration. Please try again.');
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
handleSubmit,
|
||||
isSubmitting,
|
||||
error,
|
||||
isSuccess,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Standalone function to submit provider configuration
|
||||
* Useful for components that don't want to use the hook
|
||||
|
||||
Reference in New Issue
Block a user