From 0dc0490f20429480278ca6f082de560416089598 Mon Sep 17 00:00:00 2001 From: Katie Adee Date: Fri, 26 Oct 2018 12:50:54 -0400 Subject: [PATCH] refactor(app): Add validation to network auth forms (#2559) closes #2416 --- .../SelectNetwork/ConnectForm.js | 56 ++++++++++++++++--- .../SelectNetwork/ConnectFormField.js | 22 +++++++- 2 files changed, 67 insertions(+), 11 deletions(-) diff --git a/app/src/components/RobotSettings/SelectNetwork/ConnectForm.js b/app/src/components/RobotSettings/SelectNetwork/ConnectForm.js index b503d53d24d..3245317588f 100644 --- a/app/src/components/RobotSettings/SelectNetwork/ConnectForm.js +++ b/app/src/components/RobotSettings/SelectNetwork/ConnectForm.js @@ -4,6 +4,7 @@ import {Formik} from 'formik' import get from 'lodash/get' import find from 'lodash/find' import set from 'lodash/set' +import isEmpty from 'lodash/isEmpty' import {WPA_PSK_SECURITY, WPA_EAP_SECURITY} from '../../../http-api-client' @@ -62,6 +63,34 @@ export default class ConnectForm extends React.Component { }) } + getEapFields = (eapMethod: ?WifiEapOption): Array => { + return get(eapMethod, 'options', []).map(field => ({ + ...field, + name: `eapConfig.${field.name}`, + })) + } + + getValidationSchema = (values: any) => { + let fields = [] + const errors = {} + if (this.props.securityType === WPA_PSK_SECURITY) { + fields = WIFI_PSK_FIELDS + } else { + const selectedEapMethod = find(this.props.eapOptions, { + name: values.eapConfig.eapType, + }) + fields = this.getEapFields(selectedEapMethod) + } + fields.forEach(f => { + if (f.required && !get(values, f.name)) { + set(errors, f.name, `${f.displayName} is required`) + } else if (f.name === 'psk' && get(values, f.name).length < 8) { + set(errors, f.name, 'Password must be at least 8 characters') + } + }) + return errors + } + render () { const {showPassword} = this.state const {securityType, eapOptions, close} = this.props @@ -70,12 +99,24 @@ export default class ConnectForm extends React.Component { ? `${CONNECT_FIELD_ID_PREFIX}${eapMethodField}` : '' - // TODO(mc, 2018-10-18): form validation return ( { - const {handleChange, handleSubmit, values, setValues} = formProps + const { + handleChange, + handleSubmit, + values, + setValues, + handleBlur, + errors, + touched, + } = formProps + + // disable submit if form is pristine or errors present + const disabled = isEmpty(touched) || !isEmpty(errors) + const eapMethod = get(values, eapMethodField) let fields: Array = [] @@ -83,12 +124,8 @@ export default class ConnectForm extends React.Component { fields = WIFI_PSK_FIELDS } else if (securityType === WPA_EAP_SECURITY) { const selectedEapMethod = find(eapOptions, {name: eapMethod}) - fields = get(selectedEapMethod, 'options', []).map(field => ({ - ...field, - name: `eapConfig.${field.name}`, - })) + fields = this.getEapFields(selectedEapMethod) } - return (
@@ -121,13 +158,16 @@ export default class ConnectForm extends React.Component { showPassword={!!showPassword[field.name]} onChange={handleChange} toggleShowPassword={this.toggleShowPassword} + onBlur={handleBlur} + errors={errors} + touched={touched} /> ))} diff --git a/app/src/components/RobotSettings/SelectNetwork/ConnectFormField.js b/app/src/components/RobotSettings/SelectNetwork/ConnectFormField.js index 746ce7e0d8c..6355758e9e8 100644 --- a/app/src/components/RobotSettings/SelectNetwork/ConnectFormField.js +++ b/app/src/components/RobotSettings/SelectNetwork/ConnectFormField.js @@ -1,6 +1,6 @@ // @flow import * as React from 'react' - +import get from 'lodash/get' import {InputField, CheckboxField, DropdownField} from '@opentrons/components' import {FormTableRow} from './FormTable' @@ -12,12 +12,27 @@ type Props = { showPassword: boolean, onChange: (*) => mixed, toggleShowPassword: (name: string) => mixed, + errors: { + [string]: string, + }, + touched: { + [string]: boolean, + }, + onBlur: (SyntheticFocusEvent<*>) => mixed, } export const CONNECT_FIELD_ID_PREFIX = '__ConnectForm__' export default function ConnectFormField (props: Props) { - const {value, showPassword, onChange, toggleShowPassword} = props + const { + value, + showPassword, + onChange, + toggleShowPassword, + onBlur, + touched, + errors, + } = props const {name, displayName, type, required} = props.field const id = `${CONNECT_FIELD_ID_PREFIX}${name}` const label = required ? `* ${displayName}:` : `${displayName}:` @@ -25,7 +40,6 @@ export default function ConnectFormField (props: Props) { if (type === 'string' || type === 'password') { const inputType = type === 'string' || showPassword ? 'text' : 'password' - input = ( ) } else if (type === 'file') {