ui: setting configuration (#1597)
This commit is contained in:
@@ -71,13 +71,13 @@ export const ConfigProvider: React.FC<ConfigProviderProps> = ({ children }) => {
|
||||
setConfig(response.data.config || {});
|
||||
};
|
||||
|
||||
const upsert = async (key: string, value: unknown, isSecret?: boolean) => {
|
||||
const upsert = async (key: string, value: unknown, isSecret: boolean = false) => {
|
||||
console.log('trying to upsert', key, value, isSecret);
|
||||
const query: UpsertConfigQuery = {
|
||||
key,
|
||||
value,
|
||||
is_secret: isSecret || null,
|
||||
key: key,
|
||||
value: value,
|
||||
is_secret: isSecret,
|
||||
};
|
||||
|
||||
await upsertConfig({
|
||||
body: query,
|
||||
});
|
||||
|
||||
+8
-22
@@ -6,51 +6,37 @@ import ProviderSetupActions from './subcomponents/ProviderSetupActions';
|
||||
import ProviderLogo from './subcomponents/ProviderLogo';
|
||||
import { useProviderModal } from './ProviderModalProvider';
|
||||
import { SecureStorageNotice } from './subcomponents/SecureStorageNotice';
|
||||
import DefaultSubmitHandler from './subcomponents/handlers/DefaultSubmitHandler';
|
||||
import { DefaultSubmitHandler } from './subcomponents/handlers/DefaultSubmitHandler';
|
||||
import OllamaSubmitHandler from './subcomponents/handlers/OllamaSubmitHandler';
|
||||
import OllamaForm from './subcomponents/forms/OllamaForm';
|
||||
import { useConfig } from '../../../ConfigContext';
|
||||
|
||||
const customSubmitHandler = {
|
||||
const customSubmitHandlerMap = {
|
||||
provider_name: OllamaSubmitHandler, // example
|
||||
};
|
||||
|
||||
const customForms = {
|
||||
const customFormsMap = {
|
||||
provider_name: OllamaForm, // example
|
||||
};
|
||||
|
||||
export default function ProviderConfigurationModal() {
|
||||
const { upsert } = useConfig();
|
||||
const { isOpen, currentProvider, modalProps, closeModal } = useProviderModal();
|
||||
const [configValues, setConfigValues] = useState({});
|
||||
|
||||
useEffect(() => {
|
||||
if (currentProvider) {
|
||||
// Initialize form with default values
|
||||
const initialValues = {};
|
||||
// FIXME
|
||||
// if (currentProvider.parameters) {
|
||||
// currentProvider.parameters.forEach((param) => {
|
||||
// initialValues[param.name] = param.default || '';
|
||||
// });
|
||||
// }
|
||||
setConfigValues(initialValues);
|
||||
} else {
|
||||
setConfigValues({});
|
||||
}
|
||||
}, [currentProvider]);
|
||||
|
||||
if (!isOpen || !currentProvider) return null;
|
||||
|
||||
const headerText = `Configure ${currentProvider.metadata.display_name}`;
|
||||
const descriptionText = `Add your API key(s) for this provider to integrate into Goose`;
|
||||
|
||||
const SubmitHandler = customSubmitHandler[currentProvider.name] || DefaultSubmitHandler;
|
||||
const FormComponent = customForms[currentProvider.name] || DefaultProviderSetupForm;
|
||||
const SubmitHandler = customSubmitHandlerMap[currentProvider.name] || DefaultSubmitHandler;
|
||||
const FormComponent = customFormsMap[currentProvider.name] || DefaultProviderSetupForm;
|
||||
|
||||
const handleSubmitForm = (e) => {
|
||||
e.preventDefault();
|
||||
console.log('Form submitted for:', currentProvider.name);
|
||||
|
||||
SubmitHandler(configValues);
|
||||
SubmitHandler(upsert, currentProvider, configValues);
|
||||
|
||||
// Close the modal unless the custom handler explicitly returns false
|
||||
// This gives custom handlers the ability to keep the modal open if needed
|
||||
|
||||
+1
-4
@@ -62,10 +62,7 @@ export default function DefaultProviderSetupForm({
|
||||
) : (
|
||||
requiredParameters.map((parameter) => (
|
||||
<div key={parameter.name}>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
{parameter.name}
|
||||
<span className="text-red-500 ml-1">*</span>
|
||||
</label>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">{parameter.name}</label>
|
||||
<Input
|
||||
type={parameter.secret ? 'password' : 'text'}
|
||||
value={configValues[parameter.name] || ''}
|
||||
|
||||
+113
-6
@@ -1,7 +1,114 @@
|
||||
export default function DefaultSubmitHandler(configValues) {
|
||||
// Log each field value individually for clarity
|
||||
console.log('Field values:');
|
||||
Object.entries(configValues).forEach(([key, value]) => {
|
||||
console.log(`${key}: ${value}`);
|
||||
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
|
||||
*/
|
||||
export const DefaultSubmitHandler = async (upsertFn, provider, configValues) => {
|
||||
const parameters = provider.metadata.config_keys || [];
|
||||
|
||||
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
|
||||
const configKey = `${parameter.name}`;
|
||||
|
||||
// Explicitly define is_secret as a boolean (true/false) or null
|
||||
// This is critical for Rust's Option<bool> type
|
||||
const isSecret = parameter.secret === true;
|
||||
|
||||
// Pass the is_secret flag from the parameter definition
|
||||
return upsertFn(configKey, value, isSecret);
|
||||
});
|
||||
}
|
||||
|
||||
// Wait for all upsert operations to complete
|
||||
return Promise.all(upsertPromises);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user