Skip to content

Commit

Permalink
feat(app): deprecate formik, migrate to react-hook-form (#14424)
Browse files Browse the repository at this point in the history
closes RAUT-960
  • Loading branch information
jerader authored and Carlos-fernandez committed May 20, 2024
1 parent 33d9795 commit eb7121a
Show file tree
Hide file tree
Showing 19 changed files with 748 additions and 386 deletions.
2 changes: 1 addition & 1 deletion app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@
"date-fns": "2.25.0",
"events": "3.0.0",
"file-saver": "2.0.1",
"formik": "2.1.4",
"history": "4.7.2",
"i18next": "^19.8.3",
"is-ip": "3.1.0",
"jszip": "3.2.2",
"lodash": "4.17.21",
"mixpanel-browser": "2.22.1",
"netmask": "2.0.2",
"react-hook-form": "7.50.1",
"path-to-regexp": "3.0.0",
"react": "18.2.0",
"react-dom": "18.2.0",
Expand Down
85 changes: 52 additions & 33 deletions app/src/organisms/AppSettings/ManualIpHostnameForm.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react'
import { useDispatch } from 'react-redux'
import { useTranslation } from 'react-i18next'
import { useFormik } from 'formik'
import { useForm } from 'react-hook-form'
import styled from 'styled-components'

import {
Expand All @@ -19,6 +19,7 @@ import { StyledText } from '../../atoms/text'
import { addManualIp } from '../../redux/config'
import { startDiscovery } from '../../redux/discovery'

import type { FieldError, Resolver } from 'react-hook-form'
import type { Dispatch } from '../../redux/types'

const FlexForm = styled.form`
Expand Down Expand Up @@ -56,8 +57,8 @@ const StyledInput = styled.input`
}
`

interface FormikErrors {
ip?: string
interface FormValues {
ip: string
}
interface ManualIpHostnameFormProps {
setMostRecentAddition: (ip: string) => void
Expand All @@ -72,47 +73,65 @@ export function ManualIpHostnameForm({
dispatch(addManualIp(ip))
dispatch(startDiscovery())
}
const formik = useFormik({
initialValues: {

const resolver: Resolver<FormValues> = values => {
let errors = {}
errors = validateForm(values, errors)
return { values, errors }
}
const { formState, handleSubmit, register, reset } = useForm<FormValues>({
defaultValues: {
ip: '',
},
onSubmit: (values, { resetForm }) => {
const ip = values.ip.trim()
const inputForm = document.getElementById('ip')
if (inputForm != null)
inputForm.style.border = `1px solid ${String(COLORS.grey30)}`
addManualIpAndHostname(ip)
resetForm()
setMostRecentAddition(ip)
},
validate: values => {
const errors: FormikErrors = {}
const ip = values.ip.trim()
// ToDo: kj 12/19/2022 for this, the best way is to use the regex because invisible unicode characters
if (!ip) {
errors.ip = t('add_ip_error')
const inputForm = document.getElementById('ip')
if (inputForm != null)
inputForm.style.border = `1px solid ${String(COLORS.red50)}`
}
return errors
},
resolver: resolver,
})

const validateForm = (
data: FormValues,
errors: Record<string, FieldError>
): Record<string, FieldError> => {
const ip = data.ip.trim()
let message: string | undefined
if (!ip) {
message = t('add_ip_error')
}
const updatedErrors =
message != null
? {
...errors,
ip: {
type: 'error',
message: message,
},
}
: errors
return updatedErrors
}

const onSubmit = (data: FormValues): void => {
const trimmedIp = data.ip.trim()
const inputForm = document.getElementById('ip')

if (inputForm !== null) {
inputForm.style.border = `1px solid ${COLORS.grey30}`
}

addManualIpAndHostname(trimmedIp)
reset()
setMostRecentAddition(trimmedIp)
}

return (
<Flex
flexDirection={DIRECTION_COLUMN}
margin={`${SPACING.spacing4} 0`}
height={SPACING.spacing32}
>
<FlexForm onSubmit={formik.handleSubmit}>
<FlexForm onSubmit={handleSubmit(onSubmit)}>
<StyledInput
id="ip"
name="ip"
type="text"
onChange={formik.handleChange}
onBlur={formik.handleBlur}
value={formik.values.ip}
{...register('ip')}
data-testid="manual-ip-hostname-input"
/>
<TertiaryButton
Expand All @@ -125,13 +144,13 @@ export function ManualIpHostnameForm({
{t('add_ip_button')}
</TertiaryButton>
</FlexForm>
{formik.errors.ip != null && (
{formState.errors?.ip != null && (
<StyledText
as="label"
marginTop={SPACING.spacing4}
color={COLORS.red50}
>
{formik.errors.ip}
{formState.errors.ip.message}
</StyledText>
)}
</Flex>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ describe('ConnectRobotSlideout', () => {
it.todo(
'Clicking Add button with an IP address/hostname should display the IP address/hostname and Not Found label'
)
// NOTE: consider mocking formik here?
// NOTE: consider mocking react-hook-form here?
// , async () => {
// mockGetConfig.mockReturnValue({ discovery: { candidates: ['1.1.1.2'] } } as any)
// mockGetViewableRobots.mockReturnValue([] as any[])
Expand Down
Loading

0 comments on commit eb7121a

Please sign in to comment.