From 4967e2ec47fd8f6e56f328bd5b61ff3bb0f673b6 Mon Sep 17 00:00:00 2001 From: Jiri Tomasek Date: Thu, 2 Jul 2020 12:38:00 +0200 Subject: [PATCH] Add checkbox to enable proxy configuration on discovery ISO dialog --- .../DiscoveryImageForm.tsx | 26 +++++------- .../DiscoveryProxyFields.tsx | 29 ++++++++++++++ src/components/clusterConfiguration/types.ts | 5 +++ src/components/ui/formik/CheckboxField.tsx | 40 +++++++++++++++++++ src/components/ui/formik/HelperText.tsx | 18 +++++++++ src/components/ui/formik/InputField.tsx | 9 ++++- src/components/ui/formik/TextAreaField.tsx | 9 ++++- src/components/ui/formik/index.tsx | 1 + src/components/ui/formik/types.ts | 3 +- 9 files changed, 121 insertions(+), 19 deletions(-) create mode 100644 src/components/clusterConfiguration/DiscoveryProxyFields.tsx create mode 100644 src/components/clusterConfiguration/types.ts create mode 100644 src/components/ui/formik/CheckboxField.tsx create mode 100644 src/components/ui/formik/HelperText.tsx diff --git a/src/components/clusterConfiguration/DiscoveryImageForm.tsx b/src/components/clusterConfiguration/DiscoveryImageForm.tsx index 6df6a45d03..fcd29f9839 100644 --- a/src/components/clusterConfiguration/DiscoveryImageForm.tsx +++ b/src/components/clusterConfiguration/DiscoveryImageForm.tsx @@ -1,5 +1,6 @@ import React from 'react'; import * as Yup from 'yup'; +import _ from 'lodash'; import { Button, ButtonVariant, @@ -13,7 +14,7 @@ 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'; @@ -21,6 +22,8 @@ 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.'), @@ -51,12 +54,13 @@ const DiscoveryImageForm: React.FC = ({ }, []); const handleSubmit = async ( - values: ImageCreateParams, - formikActions: FormikHelpers, + values: DiscoveryImageFormValues, + formikActions: FormikHelpers, ) => { 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); @@ -74,13 +78,14 @@ const DiscoveryImageForm: React.FC = ({ }; const initialValues = { + enableProxy: !!proxyUrl, proxyUrl: proxyUrl || '', sshPublicKey: sshPublicKey || '', }; return ( = ({ 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. - - Each host will need a valid IP address assigned by a DHCP server with DNS records that fully resolve. @@ -128,12 +129,7 @@ const DiscoveryImageForm: React.FC = ({ during the installation. - + { + const { setFieldValue, values } = useFormikContext(); + const resetProxy = () => setFieldValue('proxyUrl', ''); + return ( + <> + !value && resetProxy()} + /> + {values.enableProxy && ( + + )} + + ); +}; + +export default DiscoveryProxyFields; diff --git a/src/components/clusterConfiguration/types.ts b/src/components/clusterConfiguration/types.ts new file mode 100644 index 0000000000..6bba09d07f --- /dev/null +++ b/src/components/clusterConfiguration/types.ts @@ -0,0 +1,5 @@ +import { ImageCreateParams } from '../../api/types'; + +export type DiscoveryImageFormValues = ImageCreateParams & { + enableProxy: boolean; +}; diff --git a/src/components/ui/formik/CheckboxField.tsx b/src/components/ui/formik/CheckboxField.tsx new file mode 100644 index 0000000000..f127124cda --- /dev/null +++ b/src/components/ui/formik/CheckboxField.tsx @@ -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 = ({ + label, + helperText, + onChange, + validate, + ...props +}) => { + const [field] = useField({ name: props.name, validate }); + const fieldId = getFieldId(props.name, 'input'); + return ( + {helperText} + ) + } + isChecked={field.value} + onChange={(value, event) => { + field.onChange(event); + onChange && onChange(value, event); + }} + /> + ); +}; + +export default CheckboxField; diff --git a/src/components/ui/formik/HelperText.tsx b/src/components/ui/formik/HelperText.tsx new file mode 100644 index 0000000000..c928066c51 --- /dev/null +++ b/src/components/ui/formik/HelperText.tsx @@ -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 = ({ fieldId, children }) => ( +
+ {children} +
+); + +export default HelperText; diff --git a/src/components/ui/formik/InputField.tsx b/src/components/ui/formik/InputField.tsx index a2796d6477..a51e25e2c8 100644 --- a/src/components/ui/formik/InputField.tsx +++ b/src/components/ui/formik/InputField.tsx @@ -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 = ({ label, @@ -20,7 +21,13 @@ const InputField: React.FC = ({ {helperText} + ) + } helperTextInvalid={errorMessage} validated={isValid ? 'default' : 'error'} isRequired={isRequired} diff --git a/src/components/ui/formik/TextAreaField.tsx b/src/components/ui/formik/TextAreaField.tsx index 220a883d7c..247b8aed9d 100644 --- a/src/components/ui/formik/TextAreaField.tsx +++ b/src/components/ui/formik/TextAreaField.tsx @@ -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 = ({ label, @@ -20,7 +21,13 @@ const TextAreaField: React.FC = ({ {helperText} + ) + } helperTextInvalid={errorMessage} validated={isValid ? 'default' : 'error'} isRequired={isRequired} diff --git a/src/components/ui/formik/index.tsx b/src/components/ui/formik/index.tsx index f7305a673a..3d5e39338b 100644 --- a/src/components/ui/formik/index.tsx +++ b/src/components/ui/formik/index.tsx @@ -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'; diff --git a/src/components/ui/formik/types.ts b/src/components/ui/formik/types.ts index caa5aca26a..0c44c65b1a 100644 --- a/src/components/ui/formik/types.ts +++ b/src/components/ui/formik/types.ts @@ -48,8 +48,7 @@ export interface TextAreaSecretProps extends TextAreaProps { } export interface CheckboxFieldProps extends FieldProps { - formLabel?: string; - value?: string; + onChange?: (value: boolean, event: React.FormEvent) => void; } export interface SearchInputFieldProps extends InputFieldProps {