cloudConfig: toggle aws config

This is still a wip since the form fields aren't yet disabled when the
config toggle is set to off.
This commit is contained in:
Gianluca Zuccarelli 2025-04-16 10:56:15 +00:00 committed by Sanne Raymaekers
parent 73ffb97414
commit afcc0126e4
2 changed files with 112 additions and 19 deletions

View file

@ -1,69 +1,153 @@
import React from 'react';
import React, { useState } from 'react';
import { Form, FormGroup } from '@patternfly/react-core';
import { Form, FormGroup, Switch, TextInput } from '@patternfly/react-core';
import { isAwsBucketValid, isAwsCredsPathValid } from './validators';
import {
changeAWSBucketName,
changeAWSCredsPath,
reinitializeAWSConfig,
selectAWSBucketName,
selectAWSCredsPath,
} from '../../store/cloudProviderConfigSlice';
import {
AWSWorkerConfig,
WorkerConfigResponse,
} from '../../store/cockpit/types';
import { useAppDispatch, useAppSelector } from '../../store/hooks';
import { ValidatedInput } from '../CreateImageWizard/ValidatedInput';
type FormGroupProps = {
value: string | undefined;
setValue: (value: string) => void;
type FormGroupProps<T> = {
value: T | undefined;
onChange: (value: T) => void;
isDisabled?: boolean;
};
const AWSBucket = ({ value, setValue }: FormGroupProps) => {
type ToggleGroupProps = Omit<FormGroupProps<boolean>, 'isDisabled'>;
const AWSConfigToggle = ({ value, onChange }: ToggleGroupProps) => {
const handleChange = (
_event: React.FormEvent<HTMLInputElement>,
checked: boolean
) => {
onChange(checked);
};
return (
<FormGroup label="AWS Bucket">
<FormGroup label="Configure AWS Uploads">
<Switch
id="aws-config-switch"
ouiaId="aws-config-switch"
aria-label="aws-config-switch"
// empty label so there is no icon
label=""
isChecked={value}
onChange={handleChange}
/>
</FormGroup>
);
};
const DisabledInputGroup = ({
value,
label,
}: {
value: string | undefined;
label: string;
}) => {
return (
<FormGroup label={label}>
<TextInput aria-label={label} value={value || ''} isDisabled />
</FormGroup>
);
};
const AWSBucket = ({ value, onChange, isDisabled }: FormGroupProps<string>) => {
const label = 'AWS Bucket';
if (isDisabled) {
return <DisabledInputGroup label={label} value={value} />;
}
return (
<FormGroup label={label}>
<ValidatedInput
ariaLabel="aws-bucket"
value={value || ''}
validator={isAwsBucketValid}
onChange={(_event, value) => setValue(value)}
onChange={(_event, value) => onChange(value)}
helperText="Invalid AWS bucket name"
/>
</FormGroup>
);
};
const AWSCredsPath = ({ value, setValue }: FormGroupProps) => {
const AWSCredsPath = ({
value,
onChange,
isDisabled,
}: FormGroupProps<string>) => {
const label = 'AWS Credentials Filepath';
if (isDisabled) {
return <DisabledInputGroup value={value} label={label} />;
}
return (
<FormGroup label="AWS Credentials Filepath">
<FormGroup label={label}>
<ValidatedInput
ariaLabel="aws-creds-path"
value={value || ''}
validator={isAwsCredsPathValid}
onChange={(_event, value) => setValue(value)}
onChange={(_event, value) => onChange(value)}
helperText="Invalid filepath for AWS credentials"
/>
</FormGroup>
);
};
export const AWSConfig = () => {
type AWSConfigProps = {
isEnabled: boolean;
reinit: (config: AWSWorkerConfig | undefined) => void;
refetch: () => Promise<{
data?: WorkerConfigResponse | undefined;
}>;
};
export const AWSConfig = ({ isEnabled, refetch, reinit }: AWSConfigProps) => {
const dispatch = useAppDispatch();
const bucket = useAppSelector(selectAWSBucketName);
const credentials = useAppSelector(selectAWSCredsPath);
const [enabled, setEnabled] = useState<boolean>(isEnabled);
// TODO: maybe add a radio button to toggle AWS configuration
// on or off - this might simplify validation & the overall
// experience
const onToggle = async (v: boolean) => {
if (v) {
try {
const { data } = await refetch();
reinit(data?.aws);
setEnabled(v);
return;
} catch {
return;
}
}
dispatch(reinitializeAWSConfig());
setEnabled(v);
};
return (
<Form>
<AWSConfigToggle value={enabled} onChange={onToggle} />
<AWSBucket
value={bucket}
setValue={(v) => dispatch(changeAWSBucketName(v))}
onChange={(v) => dispatch(changeAWSBucketName(v))}
isDisabled={!enabled}
/>
<AWSCredsPath
value={credentials}
setValue={(v) => dispatch(changeAWSCredsPath(v))}
onChange={(v) => dispatch(changeAWSCredsPath(v))}
isDisabled={!enabled}
/>
</Form>
);

View file

@ -8,6 +8,7 @@ import {
EmptyStateFooter,
EmptyStateVariant,
PageSection,
Skeleton,
Title,
Wizard,
WizardStep,
@ -63,7 +64,7 @@ export const CloudProviderConfig = () => {
const dispatch = useAppDispatch();
const handleClose = () => navigate(resolveRelPath(''));
const { data, error } = useGetWorkerConfigQuery({});
const { data, error, refetch, isLoading } = useGetWorkerConfigQuery({});
const initAWSConfig = useCallback(
(config: AWSWorkerConfig | undefined) => {
@ -88,6 +89,10 @@ export const CloudProviderConfig = () => {
initAWSConfig(data?.aws);
}, [data, initAWSConfig]);
if (isLoading) {
return <Skeleton />;
}
if (error) {
return <ConfigError onClose={handleClose} />;
}
@ -106,7 +111,11 @@ export const CloudProviderConfig = () => {
isBackDisabled: true,
}}
>
<AWSConfig />
<AWSConfig
refetch={refetch}
reinit={initAWSConfig}
isEnabled={!!(data?.aws && Object.keys(data.aws).length > 0)}
/>
</WizardStep>
</Wizard>
</PageSection>