From 3b0291b77668be5e2ee3afa787a2d04f3c704c06 Mon Sep 17 00:00:00 2001 From: Tsu-ba-me Date: Thu, 11 Aug 2022 19:11:50 -0400 Subject: [PATCH] fix(striker-ui): add symbols to input messages, migrate to test input onBlur in GeneralInitForm --- striker-ui/components/GeneralInitForm.tsx | 236 +++++++++++++--------- 1 file changed, 146 insertions(+), 90 deletions(-) diff --git a/striker-ui/components/GeneralInitForm.tsx b/striker-ui/components/GeneralInitForm.tsx index 40aea54d..5794c2dd 100644 --- a/striker-ui/components/GeneralInitForm.tsx +++ b/striker-ui/components/GeneralInitForm.tsx @@ -1,5 +1,6 @@ import { Grid as MUIGrid } from '@mui/material'; import { + FC, forwardRef, ReactNode, useCallback, @@ -12,7 +13,7 @@ import { v4 as uuidv4 } from 'uuid'; import INPUT_TYPES from '../lib/consts/INPUT_TYPES'; -import FlexBox from './FlexBox'; +import FlexBox, { FlexBoxProps } from './FlexBox'; import InputWithRef, { InputForwardedRefContent } from './InputWithRef'; import isEmpty from '../lib/isEmpty'; import MessageBox, { Message } from './MessageBox'; @@ -23,6 +24,7 @@ import pad from '../lib/pad'; import SuggestButton from './SuggestButton'; import { testInput, testLength, testNotBlank } from '../lib/test_input'; import { InputTestBatches } from '../types/TestInputFunction'; +import { BodyText } from './Text'; type GeneralInitFormForwardRefContent = { get?: () => { @@ -64,6 +66,11 @@ const INPUT_TEST_MESSAGE_KEYS: string[] = Array.from( () => uuidv4(), ); +const INITIAL_INPUT_MESSAGES = Array.from( + { length: INPUT_COUNT }, + () => undefined, +); + const buildOrganizationPrefix = (organizationName = '') => { const words: string[] = organizationName .split(/\s/) @@ -88,12 +95,29 @@ const buildHostName = ({ ? `${organizationPrefix}-striker${pad(hostNumber)}.${domainName}` : ''; +const ms = (text: ReactNode) => ( + +); + +const MessageChildren: FC = ({ ...flexBoxProps }) => ( + .inline-monospace-text': { + marginTop: '-.2em', + }, + }} + /> +); + const GeneralInitForm = forwardRef( (generalInitFormProps, ref) => { const [helpMessage, setHelpMessage] = useState(); const [inputMessages, setInputMessages] = useState< Array - >([]); + >(INITIAL_INPUT_MESSAGES); const [ isShowOrganizationPrefixSuggest, setIsShowOrganizationPrefixSuggest, @@ -149,28 +173,6 @@ const GeneralInitForm = forwardRef( (message?: Message) => setInputMessage(6, message), [setInputMessage], ); - const createInputTestMessages = useCallback( - () => - inputMessages.map((message, index) => { - let messageElement; - - if (message) { - const { children, type = 'warning' } = message; - - messageElement = ( - - {children} - - ); - } - - return messageElement; - }), - [inputMessages], - ); const populateOrganizationPrefixInput = useCallback( ({ organizationName = organizationNameInputRef.current.getValue?.call( @@ -263,6 +265,28 @@ const GeneralInitForm = forwardRef( [], ); + const inputMessageElements = useMemo( + () => + inputMessages.map((message, index) => { + let messageElement; + + if (message) { + const { children, type = 'warning' } = message; + + messageElement = ( + + {children} + + ); + } + + return messageElement; + }), + [inputMessages], + ); const inputTests: InputTestBatches = useMemo( () => ({ adminPassword: { @@ -275,12 +299,19 @@ const GeneralInitForm = forwardRef( { onFailure: () => { setAdminPasswordInputMessage({ - children: - 'Admin password cannot contain single-quote, double-quote, slash, backslash, angle brackets, and curly brackets.', + children: ( + + Admin password cannot contain single-quote ({ms("'")}), + double-quote ({ms('"')}), slash ({ms('/')}), backslash ( + {ms('\\')}), angle brackets ({ms('<>')}), curly brackets ( + {ms('{}')}). + + ), }); }, test: ({ value }) => !/['"/\\><}{]/g.test(value as string), }, + { test: testNotBlank }, ], }, confirmAdminPassword: { @@ -298,6 +329,7 @@ const GeneralInitForm = forwardRef( }, test: ({ value, compare }) => value === compare, }, + { test: testNotBlank }, ], }, domainName: { @@ -310,12 +342,17 @@ const GeneralInitForm = forwardRef( { onFailure: () => { setDomainNameInputMessage({ - children: - 'Domain name can only contain lowercase alphanumeric, hyphen, and decimal characters.', + children: ( + + Domain name can only contain lowercase alphanumeric, + hyphen ({ms('-')}), and dot ({ms('.')}) characters. + + ), }); }, test: ({ value }) => REP_DN_CHAR.test(value as string), }, + { test: testNotBlank }, ], }, hostName: { @@ -328,12 +365,17 @@ const GeneralInitForm = forwardRef( { onFailure: () => { setHostNameInputMessage({ - children: - 'Host name can only contain lowercase alphanumeric, hyphen, and decimal characters.', + children: ( + + Host name can only contain lowercase alphanumeric, hyphen + ({ms('-')}), and dot ({ms('.')}) characters. + + ), }); }, test: ({ value }) => REP_DN_CHAR.test(value as string), }, + { test: testNotBlank }, ], }, hostNumber: { @@ -351,6 +393,7 @@ const GeneralInitForm = forwardRef( }, test: ({ value }) => /^\d+$/.test(value as string), }, + { test: testNotBlank }, ], }, organizationName: { @@ -380,6 +423,7 @@ const GeneralInitForm = forwardRef( }, test: ({ value }) => /^[a-z0-9]+$/.test(value as string), }, + { test: testNotBlank }, ], }, }), @@ -419,12 +463,6 @@ const GeneralInitForm = forwardRef( }} inputLabelProps={{ isNotifyRequired: true }} label="Organization name" - onChange={({ target: { value } }) => { - testInput({ - inputs: { organizationName: { value } }, - tests: inputTests, - }); - }} onHelp={() => { setHelpMessage( buildHelpMessage( @@ -461,22 +499,28 @@ const GeneralInitForm = forwardRef( minWidth: '2.5em', }, }, - onBlur: populateHostNameInputOnBlur, + onBlur: (event) => { + const { + target: { value }, + } = event; + + testInput({ + inputs: { + organizationPrefix: { + max: MAX_ORGANIZATION_PREFIX_LENGTH, + min: MIN_ORGANIZATION_PREFIX_LENGTH, + value, + }, + }, + tests: inputTests, + }); + + populateHostNameInputOnBlur(event); + }, }} inputLabelProps={{ isNotifyRequired: true }} label="Prefix" - onChange={({ target: { value } }) => { - testInput({ - inputs: { - organizationPrefix: { - max: MAX_ORGANIZATION_PREFIX_LENGTH, - min: MIN_ORGANIZATION_PREFIX_LENGTH, - value, - }, - }, - tests: inputTests, - }); - + onChange={() => { setIsShowOrganizationPrefixSuggest( isOrganizationPrefixPrereqFilled(), ); @@ -503,16 +547,21 @@ const GeneralInitForm = forwardRef( minWidth: '2em', }, }, - onBlur: populateHostNameInputOnBlur, + onBlur: (event) => { + const { + target: { value }, + } = event; + + testInput({ + inputs: { hostNumber: { value } }, + tests: inputTests, + }); + + populateHostNameInputOnBlur(event); + }, }} inputLabelProps={{ isNotifyRequired: true }} label="Striker #" - onChange={({ target: { value } }) => { - testInput({ - inputs: { hostNumber: { value } }, - tests: inputTests, - }); - }} onHelp={() => { setHelpMessage( buildHelpMessage( @@ -535,16 +584,21 @@ const GeneralInitForm = forwardRef( { + const { + target: { value }, + } = event; + + testInput({ + inputs: { domainName: { value } }, + tests: inputTests, + }); + + populateHostNameInputOnBlur(event); + }, }} inputLabelProps={{ isNotifyRequired: true }} label="Domain name" - onChange={({ target: { value } }) => { - testInput({ - inputs: { domainName: { value } }, - tests: inputTests, - }); - }} onHelp={() => { setHelpMessage( buildHelpMessage( @@ -568,15 +622,17 @@ const GeneralInitForm = forwardRef( onClick={handlerHostNameSuggest} /> ), + + onBlur: ({ target: { value } }) => { + testInput({ + inputs: { hostName: { value } }, + tests: inputTests, + }); + }, }} inputLabelProps={{ isNotifyRequired: true }} label="Host name" - onChange={({ target: { value } }) => { - testInput({ - inputs: { hostName: { value } }, - tests: inputTests, - }); - + onChange={() => { setIsShowHostNameSuggest(isHostNamePrereqFilled()); }} onHelp={() => { @@ -612,6 +668,12 @@ const GeneralInitForm = forwardRef( inputProps: { type: INPUT_TYPES.password, }, + onBlur: ({ target: { value } }) => { + testInput({ + inputs: { adminPassword: { value } }, + tests: inputTests, + }); + }, onPasswordVisibilityAppend: (inputType) => { setIsConfirmAdminPassword( inputType === INPUT_TYPES.password, @@ -620,12 +682,6 @@ const GeneralInitForm = forwardRef( }} inputLabelProps={{ isNotifyRequired: true }} label="Admin password" - onChange={({ target: { value } }) => { - testInput({ - inputs: { adminPassword: { value } }, - tests: inputTests, - }); - }} onHelp={() => { setHelpMessage( buildHelpMessage( @@ -648,25 +704,25 @@ const GeneralInitForm = forwardRef( inputProps: { type: INPUT_TYPES.password, }, + onBlur: ({ target: { value } }) => { + testInput({ + inputs: { + confirmAdminPassword: { + value, + compare: + adminPasswordInputRef.current.getValue?.call( + null, + ), + }, + }, + tests: inputTests, + }); + }, }} inputLabelProps={{ isNotifyRequired: isConfirmAdminPassword, }} label="Confirm password" - onChange={({ target: { value } }) => { - testInput({ - inputs: { - confirmAdminPassword: { - value, - compare: - adminPasswordInputRef.current.getValue?.call( - null, - ), - }, - }, - tests: inputTests, - }); - }} /> } ref={confirmAdminPasswordInputRef} @@ -676,7 +732,7 @@ const GeneralInitForm = forwardRef( - {createInputTestMessages()} + {inputMessageElements} {helpMessage && ( {