fix(striker-ui): add symbols to input messages, migrate to test input onBlur in GeneralInitForm

main
Tsu-ba-me 2 years ago
parent d082d6d3f6
commit 3b0291b776
  1. 236
      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) => (
<BodyText className="inline-monospace-text" monospaced text={text} />
);
const MessageChildren: FC<FlexBoxProps> = ({ ...flexBoxProps }) => (
<FlexBox
{...flexBoxProps}
row
spacing={0}
sx={{
'& > .inline-monospace-text': {
marginTop: '-.2em',
},
}}
/>
);
const GeneralInitForm = forwardRef<GeneralInitFormForwardRefContent>(
(generalInitFormProps, ref) => {
const [helpMessage, setHelpMessage] = useState<ReactNode | undefined>();
const [inputMessages, setInputMessages] = useState<
Array<Message | undefined>
>([]);
>(INITIAL_INPUT_MESSAGES);
const [
isShowOrganizationPrefixSuggest,
setIsShowOrganizationPrefixSuggest,
@ -149,28 +173,6 @@ const GeneralInitForm = forwardRef<GeneralInitFormForwardRefContent>(
(message?: Message) => setInputMessage(6, message),
[setInputMessage],
);
const createInputTestMessages = useCallback(
() =>
inputMessages.map((message, index) => {
let messageElement;
if (message) {
const { children, type = 'warning' } = message;
messageElement = (
<MessageBox
key={`input-test-message-${INPUT_TEST_MESSAGE_KEYS[index]}`}
type={type}
>
{children}
</MessageBox>
);
}
return messageElement;
}),
[inputMessages],
);
const populateOrganizationPrefixInput = useCallback(
({
organizationName = organizationNameInputRef.current.getValue?.call(
@ -263,6 +265,28 @@ const GeneralInitForm = forwardRef<GeneralInitFormForwardRefContent>(
[],
);
const inputMessageElements = useMemo(
() =>
inputMessages.map((message, index) => {
let messageElement;
if (message) {
const { children, type = 'warning' } = message;
messageElement = (
<MessageBox
key={`input-test-message-${INPUT_TEST_MESSAGE_KEYS[index]}`}
type={type}
>
{children}
</MessageBox>
);
}
return messageElement;
}),
[inputMessages],
);
const inputTests: InputTestBatches = useMemo(
() => ({
adminPassword: {
@ -275,12 +299,19 @@ const GeneralInitForm = forwardRef<GeneralInitFormForwardRefContent>(
{
onFailure: () => {
setAdminPasswordInputMessage({
children:
'Admin password cannot contain single-quote, double-quote, slash, backslash, angle brackets, and curly brackets.',
children: (
<MessageChildren>
Admin password cannot contain single-quote ({ms("'")}),
double-quote ({ms('"')}), slash ({ms('/')}), backslash (
{ms('\\')}), angle brackets ({ms('<>')}), curly brackets (
{ms('{}')}).
</MessageChildren>
),
});
},
test: ({ value }) => !/['"/\\><}{]/g.test(value as string),
},
{ test: testNotBlank },
],
},
confirmAdminPassword: {
@ -298,6 +329,7 @@ const GeneralInitForm = forwardRef<GeneralInitFormForwardRefContent>(
},
test: ({ value, compare }) => value === compare,
},
{ test: testNotBlank },
],
},
domainName: {
@ -310,12 +342,17 @@ const GeneralInitForm = forwardRef<GeneralInitFormForwardRefContent>(
{
onFailure: () => {
setDomainNameInputMessage({
children:
'Domain name can only contain lowercase alphanumeric, hyphen, and decimal characters.',
children: (
<MessageChildren>
Domain name can only contain lowercase alphanumeric,
hyphen ({ms('-')}), and dot ({ms('.')}) characters.
</MessageChildren>
),
});
},
test: ({ value }) => REP_DN_CHAR.test(value as string),
},
{ test: testNotBlank },
],
},
hostName: {
@ -328,12 +365,17 @@ const GeneralInitForm = forwardRef<GeneralInitFormForwardRefContent>(
{
onFailure: () => {
setHostNameInputMessage({
children:
'Host name can only contain lowercase alphanumeric, hyphen, and decimal characters.',
children: (
<MessageChildren>
Host name can only contain lowercase alphanumeric, hyphen
({ms('-')}), and dot ({ms('.')}) characters.
</MessageChildren>
),
});
},
test: ({ value }) => REP_DN_CHAR.test(value as string),
},
{ test: testNotBlank },
],
},
hostNumber: {
@ -351,6 +393,7 @@ const GeneralInitForm = forwardRef<GeneralInitFormForwardRefContent>(
},
test: ({ value }) => /^\d+$/.test(value as string),
},
{ test: testNotBlank },
],
},
organizationName: {
@ -380,6 +423,7 @@ const GeneralInitForm = forwardRef<GeneralInitFormForwardRefContent>(
},
test: ({ value }) => /^[a-z0-9]+$/.test(value as string),
},
{ test: testNotBlank },
],
},
}),
@ -419,12 +463,6 @@ const GeneralInitForm = forwardRef<GeneralInitFormForwardRefContent>(
}}
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<GeneralInitFormForwardRefContent>(
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<GeneralInitFormForwardRefContent>(
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<GeneralInitFormForwardRefContent>(
<OutlinedInputWithLabel
id="striker-init-general-domain-name"
inputProps={{
onBlur: populateHostNameInputOnBlur,
onBlur: (event) => {
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<GeneralInitFormForwardRefContent>(
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<GeneralInitFormForwardRefContent>(
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<GeneralInitFormForwardRefContent>(
}}
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<GeneralInitFormForwardRefContent>(
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<GeneralInitFormForwardRefContent>(
</MUIGrid>
</MUIGrid>
</MUIGrid>
{createInputTestMessages()}
{inputMessageElements}
{helpMessage && (
<MessageBox
onClose={() => {

Loading…
Cancel
Save