Skip to content

Commit

Permalink
Merge pull request #58 from jtomasek/proxy-toggle
Browse files Browse the repository at this point in the history
Add checkbox to enable proxy configuration on discovery ISO dialog
  • Loading branch information
rawagner authored Jul 2, 2020
2 parents 0da346e + ecdcf23 commit 585f519
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 19 deletions.
26 changes: 11 additions & 15 deletions src/components/clusterConfiguration/DiscoveryImageForm.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import * as Yup from 'yup';
import _ from 'lodash';
import {
Button,
ButtonVariant,
Expand All @@ -13,14 +14,16 @@ import {
AlertActionCloseButton,
} from '@patternfly/react-core';
import Axios, { CancelTokenSource } from 'axios';
import { InputField, TextAreaField } from '../ui/formik';
import { TextAreaField } from '../ui/formik';
import { Formik, FormikHelpers } from 'formik';
import { createClusterDownloadsImage } from '../../api/clusters';
import { LoadingState } from '../ui/uiState';
import { handleApiError, getErrorMessage } from '../../api/utils';
import { ImageCreateParams, ImageInfo, Cluster } from '../../api/types';
import { sshPublicKeyValidationSchema } from '../ui/formik/validationSchemas';
import GridGap from '../ui/GridGap';
import DiscoveryProxyFields from './DiscoveryProxyFields';
import { DiscoveryImageFormValues } from './types';

const validationSchema = Yup.object().shape({
proxyUrl: Yup.string().url('Provide a valid URL.'),
Expand Down Expand Up @@ -51,12 +54,13 @@ const DiscoveryImageForm: React.FC<DiscoveryImageFormProps> = ({
}, []);

const handleSubmit = async (
values: ImageCreateParams,
formikActions: FormikHelpers<ImageCreateParams>,
values: DiscoveryImageFormValues,
formikActions: FormikHelpers<DiscoveryImageFormValues>,
) => {
if (clusterId) {
try {
const { data: cluster } = await createClusterDownloadsImage(clusterId, values, {
const params = _.omit(values, ['enableProxy']);
const { data: cluster } = await createClusterDownloadsImage(clusterId, params, {
cancelToken: cancelSourceRef.current?.token,
});
onSuccess(cluster.imageInfo);
Expand All @@ -74,13 +78,14 @@ const DiscoveryImageForm: React.FC<DiscoveryImageFormProps> = ({
};

const initialValues = {
enableProxy: !!proxyUrl,
proxyUrl: proxyUrl || '',
sshPublicKey: sshPublicKey || '',
};

return (
<Formik
initialValues={initialValues as ImageCreateParams}
initialValues={initialValues as DiscoveryImageFormValues}
initialStatus={{ error: null }}
validationSchema={validationSchema}
onSubmit={handleSubmit}
Expand Down Expand Up @@ -114,10 +119,6 @@ const DiscoveryImageForm: React.FC<DiscoveryImageFormProps> = ({
<TextContent>
<Text component="p">
Hosts must be connected to the internet to form a cluster using this installer.
If hosts are behind a firewall that requires the use of a proxy, provide the
proxy URL below.
</Text>
<Text component="p">
Each host will need a valid IP address assigned by a DHCP server with DNS
records that fully resolve.
</Text>
Expand All @@ -128,12 +129,7 @@ const DiscoveryImageForm: React.FC<DiscoveryImageFormProps> = ({
during the installation.
</Text>
</TextContent>
<InputField
label="HTTP Proxy URL"
name="proxyUrl"
placeholder="http://<user>:<password>@<ipaddr>:<port>"
helperText="HTTP proxy URL that agents should use to access the discovery service"
/>
<DiscoveryProxyFields />
<TextAreaField
label="SSH public key"
name="sshPublicKey"
Expand Down
29 changes: 29 additions & 0 deletions src/components/clusterConfiguration/DiscoveryProxyFields.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
import { useFormikContext } from 'formik';
import { InputField, CheckboxField } from '../ui/formik';
import { DiscoveryImageFormValues } from './types';

const DiscoveryProxyFields: React.FC = () => {
const { setFieldValue, values } = useFormikContext<DiscoveryImageFormValues>();
const resetProxy = () => setFieldValue('proxyUrl', '');
return (
<>
<CheckboxField
label="Configure HTTP Proxy"
name="enableProxy"
helperText="If hosts are behind a firewall that requires the use of a proxy, provide additional information about the proxy."
onChange={(value: boolean) => !value && resetProxy()}
/>
{values.enableProxy && (
<InputField
label="HTTP Proxy URL"
name="proxyUrl"
placeholder="http://<user>:<password>@<ipaddr>:<port>"
helperText="HTTP proxy URL that agents should use to access the discovery service"
/>
)}
</>
);
};

export default DiscoveryProxyFields;
5 changes: 5 additions & 0 deletions src/components/clusterConfiguration/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { ImageCreateParams } from '../../api/types';

export type DiscoveryImageFormValues = ImageCreateParams & {
enableProxy: boolean;
};
40 changes: 40 additions & 0 deletions src/components/ui/formik/CheckboxField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as React from 'react';
import { useField } from 'formik';
import { Checkbox } from '@patternfly/react-core';
import { CheckboxFieldProps } from './types';
import { getFieldId } from './utils';
import HelperText from './HelperText';

const CheckboxField: React.FC<CheckboxFieldProps> = ({
label,
helperText,
onChange,
validate,
...props
}) => {
const [field] = useField({ name: props.name, validate });
const fieldId = getFieldId(props.name, 'input');
return (
<Checkbox
{...field}
{...props}
id={fieldId}
label={label}
aria-describedby={`${fieldId}-helper`}
description={
typeof helperText === 'string' ? (
helperText
) : (
<HelperText fieldId={fieldId}>{helperText}</HelperText>
)
}
isChecked={field.value}
onChange={(value, event) => {
field.onChange(event);
onChange && onChange(value, event);
}}
/>
);
};

export default CheckboxField;
18 changes: 18 additions & 0 deletions src/components/ui/formik/HelperText.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';
import { css } from '@patternfly/react-styles';

type HelperTextProps = {
fieldId: string;
};

/**
* HelperText component standardizes the format of non string helperText prop on FormGroup
* which is otherwise rendered 'as is' in FormGroup
*/
const HelperText: React.FC<HelperTextProps> = ({ fieldId, children }) => (
<div className={css('pf-c-form__helper-text')} id={`${fieldId}-helper`} aria-live="polite">
{children}
</div>
);

export default HelperText;
9 changes: 8 additions & 1 deletion src/components/ui/formik/InputField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useField } from 'formik';
import { FormGroup, TextInput } from '@patternfly/react-core';
import { InputFieldProps } from './types';
import { getFieldId } from './utils';
import HelperText from './HelperText';

const InputField: React.FC<InputFieldProps> = ({
label,
Expand All @@ -20,7 +21,13 @@ const InputField: React.FC<InputFieldProps> = ({
<FormGroup
fieldId={fieldId}
label={label}
helperText={helperText}
helperText={
typeof helperText === 'string' ? (
helperText
) : (
<HelperText fieldId={fieldId}>{helperText}</HelperText>
)
}
helperTextInvalid={errorMessage}
validated={isValid ? 'default' : 'error'}
isRequired={isRequired}
Expand Down
9 changes: 8 additions & 1 deletion src/components/ui/formik/TextAreaField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useField } from 'formik';
import { FormGroup, TextArea } from '@patternfly/react-core';
import { TextAreaProps } from './types';
import { getFieldId } from './utils';
import HelperText from './HelperText';

const TextAreaField: React.FC<TextAreaProps> = ({
label,
Expand All @@ -20,7 +21,13 @@ const TextAreaField: React.FC<TextAreaProps> = ({
<FormGroup
fieldId={fieldId}
label={label}
helperText={helperText}
helperText={
typeof helperText === 'string' ? (
helperText
) : (
<HelperText fieldId={fieldId}>{helperText}</HelperText>
)
}
helperTextInvalid={errorMessage}
validated={isValid ? 'default' : 'error'}
isRequired={isRequired}
Expand Down
1 change: 1 addition & 0 deletions src/components/ui/formik/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { default as InputField } from './InputField';
export { default as CheckboxField } from './CheckboxField';
export { default as TextAreaField } from './TextAreaField';
export { default as SelectField } from './SelectField';
export { default as TextAreaSecretField } from './TextAreaSecretField';
3 changes: 1 addition & 2 deletions src/components/ui/formik/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ export interface TextAreaSecretProps extends TextAreaProps {
}

export interface CheckboxFieldProps extends FieldProps {
formLabel?: string;
value?: string;
onChange?: (value: boolean, event: React.FormEvent<HTMLInputElement>) => void;
}

export interface SearchInputFieldProps extends InputFieldProps {
Expand Down

0 comments on commit 585f519

Please sign in to comment.