ui: add validation to provider form (#1932)
This commit is contained in:
@@ -21,6 +21,7 @@ const customFormsMap = {
|
|||||||
|
|
||||||
export default function ProviderConfigurationModal() {
|
export default function ProviderConfigurationModal() {
|
||||||
const { upsert } = useConfig();
|
const { upsert } = useConfig();
|
||||||
|
const [validationErrors, setValidationErrors] = useState({});
|
||||||
const { isOpen, currentProvider, modalProps, closeModal } = useProviderModal();
|
const { isOpen, currentProvider, modalProps, closeModal } = useProviderModal();
|
||||||
const [configValues, setConfigValues] = useState({});
|
const [configValues, setConfigValues] = useState({});
|
||||||
|
|
||||||
@@ -36,6 +37,31 @@ export default function ProviderConfigurationModal() {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
console.log('Form submitted for:', currentProvider.name);
|
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 {
|
try {
|
||||||
// Wait for the submission to complete
|
// Wait for the submission to complete
|
||||||
await SubmitHandler(upsert, currentProvider, configValues);
|
await SubmitHandler(upsert, currentProvider, configValues);
|
||||||
@@ -79,6 +105,7 @@ export default function ProviderConfigurationModal() {
|
|||||||
configValues={configValues}
|
configValues={configValues}
|
||||||
setConfigValues={setConfigValues}
|
setConfigValues={setConfigValues}
|
||||||
provider={currentProvider}
|
provider={currentProvider}
|
||||||
|
validationErrors={validationErrors}
|
||||||
{...(modalProps.formProps || {})} // Spread any custom form props
|
{...(modalProps.formProps || {})} // Spread any custom form props
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
+5
-1
@@ -6,12 +6,14 @@ interface DefaultProviderSetupFormProps {
|
|||||||
configValues: Record<string, any>;
|
configValues: Record<string, any>;
|
||||||
setConfigValues: React.Dispatch<React.SetStateAction<Record<string, any>>>;
|
setConfigValues: React.Dispatch<React.SetStateAction<Record<string, any>>>;
|
||||||
provider: any;
|
provider: any;
|
||||||
|
validationErrors: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function DefaultProviderSetupForm({
|
export default function DefaultProviderSetupForm({
|
||||||
configValues,
|
configValues,
|
||||||
setConfigValues,
|
setConfigValues,
|
||||||
provider,
|
provider,
|
||||||
|
validationErrors,
|
||||||
}: DefaultProviderSetupFormProps) {
|
}: DefaultProviderSetupFormProps) {
|
||||||
const parameters = provider.metadata.config_keys || [];
|
const parameters = provider.metadata.config_keys || [];
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
@@ -107,7 +109,9 @@ export default function DefaultProviderSetupForm({
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
placeholder={getPlaceholder(parameter)}
|
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}
|
required={true}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
-78
@@ -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
|
* Standalone function to submit provider configuration
|
||||||
* Useful for components that don't want to use the hook
|
* Useful for components that don't want to use the hook
|
||||||
|
|||||||
Reference in New Issue
Block a user