parent
46f299d878
commit
87c8240bf7
4 changed files with 451 additions and 33 deletions
@ -0,0 +1,197 @@ |
||||
import { ReactElement, useMemo, useRef, useState } from 'react'; |
||||
|
||||
import INPUT_TYPES from '../../lib/consts/INPUT_TYPES'; |
||||
|
||||
import Grid from '../Grid'; |
||||
import InputWithRef, { InputForwardedRefContent } from '../InputWithRef'; |
||||
import OutlinedInputWithLabel from '../OutlinedInputWithLabel'; |
||||
import { |
||||
buildPeacefulStringTestBatch, |
||||
testNotBlank, |
||||
} from '../../lib/test_input'; |
||||
|
||||
const INPUT_ID_USER_CONFIRM_PASSWORD = 'common-user-input-confirm-password'; |
||||
const INPUT_ID_USER_NAME = 'common-user-input-name'; |
||||
const INPUT_ID_USER_PASSWORD = 'common-user-input-password'; |
||||
|
||||
const INPUT_LABEL_USER_CONFIRM_PASSWORD = 'Confirm password'; |
||||
const INPUT_LABEL_USER_NAME = 'Username'; |
||||
const INPUT_LABEL_USER_PASSWORD = 'Password'; |
||||
|
||||
const CommonUserInputGroup = < |
||||
M extends { |
||||
[K in |
||||
| typeof INPUT_ID_USER_CONFIRM_PASSWORD |
||||
| typeof INPUT_ID_USER_NAME |
||||
| typeof INPUT_ID_USER_PASSWORD]: string; |
||||
}, |
||||
>({ |
||||
formUtils: { |
||||
buildFinishInputTestBatchFunction, |
||||
buildInputFirstRenderFunction, |
||||
setMessage, |
||||
setValidity, |
||||
}, |
||||
previous: { name: previousName } = {}, |
||||
readOnlyUserName, |
||||
requirePassword = false, |
||||
showPasswordField, |
||||
}: CommonUserInputGroupProps<M>): ReactElement => { |
||||
const userPasswordInputRef = useRef<InputForwardedRefContent<'string'>>({}); |
||||
const userConfirmPasswordInputRef = useRef< |
||||
InputForwardedRefContent<'string'> |
||||
>({}); |
||||
|
||||
const [requireConfirmPassword, setRequireConfirmPassword] = |
||||
useState<boolean>(requirePassword); |
||||
|
||||
const userPasswordInputGroup = useMemo( |
||||
() => |
||||
showPasswordField |
||||
? { |
||||
'common-user-input-cell-password': { |
||||
children: ( |
||||
<InputWithRef |
||||
input={ |
||||
<OutlinedInputWithLabel |
||||
id={INPUT_ID_USER_PASSWORD} |
||||
label={INPUT_LABEL_USER_PASSWORD} |
||||
type={INPUT_TYPES.password} |
||||
/> |
||||
} |
||||
inputTestBatch={buildPeacefulStringTestBatch( |
||||
INPUT_LABEL_USER_PASSWORD, |
||||
() => { |
||||
setMessage(INPUT_ID_USER_PASSWORD); |
||||
}, |
||||
{ |
||||
onFinishBatch: buildFinishInputTestBatchFunction( |
||||
INPUT_ID_USER_PASSWORD, |
||||
), |
||||
}, |
||||
(message) => { |
||||
setMessage(INPUT_ID_USER_PASSWORD, { children: message }); |
||||
}, |
||||
)} |
||||
onBlurAppend={({ target: { value } }) => { |
||||
setRequireConfirmPassword(value.length > 0); |
||||
setValidity( |
||||
INPUT_ID_USER_CONFIRM_PASSWORD, |
||||
value === |
||||
userConfirmPasswordInputRef.current.getValue?.call( |
||||
null, |
||||
), |
||||
); |
||||
}} |
||||
onFirstRender={buildInputFirstRenderFunction( |
||||
INPUT_ID_USER_PASSWORD, |
||||
)} |
||||
ref={userPasswordInputRef} |
||||
required={requirePassword} |
||||
/> |
||||
), |
||||
}, |
||||
'common-user-input-cell-confirm-password': { |
||||
children: ( |
||||
<InputWithRef |
||||
input={ |
||||
<OutlinedInputWithLabel |
||||
id={INPUT_ID_USER_CONFIRM_PASSWORD} |
||||
inputProps={{ readOnly: !requireConfirmPassword }} |
||||
label={INPUT_LABEL_USER_CONFIRM_PASSWORD} |
||||
type={INPUT_TYPES.password} |
||||
/> |
||||
} |
||||
inputTestBatch={{ |
||||
defaults: { |
||||
onSuccess: () => { |
||||
setMessage(INPUT_ID_USER_CONFIRM_PASSWORD); |
||||
}, |
||||
}, |
||||
onFinishBatch: buildFinishInputTestBatchFunction( |
||||
INPUT_ID_USER_CONFIRM_PASSWORD, |
||||
), |
||||
tests: [ |
||||
{ test: testNotBlank }, |
||||
{ |
||||
onFailure: () => { |
||||
setMessage(INPUT_ID_USER_CONFIRM_PASSWORD, { |
||||
children: 'The passwords do not match.', |
||||
}); |
||||
}, |
||||
test: ({ value }) => |
||||
value === |
||||
userPasswordInputRef.current.getValue?.call(null), |
||||
}, |
||||
], |
||||
}} |
||||
onFirstRender={buildInputFirstRenderFunction( |
||||
INPUT_ID_USER_CONFIRM_PASSWORD, |
||||
)} |
||||
ref={userConfirmPasswordInputRef} |
||||
required={requireConfirmPassword} |
||||
/> |
||||
), |
||||
}, |
||||
} |
||||
: undefined, |
||||
[ |
||||
buildFinishInputTestBatchFunction, |
||||
buildInputFirstRenderFunction, |
||||
requireConfirmPassword, |
||||
requirePassword, |
||||
setMessage, |
||||
setValidity, |
||||
showPasswordField, |
||||
], |
||||
); |
||||
|
||||
return ( |
||||
<Grid |
||||
columns={{ xs: 1, sm: 2, md: 3 }} |
||||
layout={{ |
||||
'common-user-input-cell-name': { |
||||
children: ( |
||||
<InputWithRef |
||||
input={ |
||||
<OutlinedInputWithLabel |
||||
id={INPUT_ID_USER_NAME} |
||||
inputProps={{ readOnly: readOnlyUserName }} |
||||
label={INPUT_LABEL_USER_NAME} |
||||
value={previousName} |
||||
/> |
||||
} |
||||
inputTestBatch={buildPeacefulStringTestBatch( |
||||
INPUT_LABEL_USER_NAME, |
||||
() => { |
||||
setMessage(INPUT_ID_USER_NAME); |
||||
}, |
||||
{ |
||||
onFinishBatch: |
||||
buildFinishInputTestBatchFunction(INPUT_ID_USER_NAME), |
||||
}, |
||||
(message) => { |
||||
setMessage(INPUT_ID_USER_NAME, { children: message }); |
||||
}, |
||||
)} |
||||
onFirstRender={buildInputFirstRenderFunction(INPUT_ID_USER_NAME)} |
||||
required |
||||
/> |
||||
), |
||||
md: 1, |
||||
sm: 2, |
||||
}, |
||||
...userPasswordInputGroup, |
||||
}} |
||||
spacing="1em" |
||||
/> |
||||
); |
||||
}; |
||||
|
||||
export { |
||||
INPUT_ID_USER_CONFIRM_PASSWORD, |
||||
INPUT_ID_USER_NAME, |
||||
INPUT_ID_USER_PASSWORD, |
||||
}; |
||||
|
||||
export default CommonUserInputGroup; |
@ -0,0 +1,11 @@ |
||||
type CommonUserInputGroupOptionalProps = { |
||||
previous?: { name?: string; password?: string }; |
||||
readOnlyUserName?: boolean; |
||||
requirePassword?: boolean; |
||||
showPasswordField?: boolean; |
||||
}; |
||||
|
||||
type CommonUserInputGroupProps<M extends MapToInputTestID> = |
||||
CommonUserInputGroupOptionalProps & { |
||||
formUtils: FormUtils<M>; |
||||
}; |
Loading…
Reference in new issue