@abgov/jsonforms-components 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/.babelrc +12 -0
  2. package/.eslintrc.json +36 -0
  3. package/.releaserc.json +25 -0
  4. package/README.md +251 -0
  5. package/jest.config.ts +11 -0
  6. package/package.json +17 -0
  7. package/project.json +55 -0
  8. package/rollup.config.js +14 -0
  9. package/src/index.ts +166 -0
  10. package/src/lib/Additional/HelpContent.tsx +95 -0
  11. package/src/lib/Additional/index.ts +1 -0
  12. package/src/lib/Additional/styled-components.ts +27 -0
  13. package/src/lib/Cells/DateCell.tsx +10 -0
  14. package/src/lib/Cells/IntegerCell.tsx +10 -0
  15. package/src/lib/Cells/NumberCell.tsx +10 -0
  16. package/src/lib/Cells/TextCell.tsx +10 -0
  17. package/src/lib/Cells/TimeCell.tsx +10 -0
  18. package/src/lib/Cells/index.tsx +14 -0
  19. package/src/lib/Context/index.tsx +172 -0
  20. package/src/lib/Controls/FileUploader/ContextMenu.tsx +50 -0
  21. package/src/lib/Controls/FileUploader/FileUploaderControl.tsx +131 -0
  22. package/src/lib/Controls/FileUploader/FileUploaderTester.tsx +3 -0
  23. package/src/lib/Controls/FileUploader/index.tsx +2 -0
  24. package/src/lib/Controls/FileUploader/styled-components.tsx +10 -0
  25. package/src/lib/Controls/FormStepper/FormStepperControl.tsx +269 -0
  26. package/src/lib/Controls/FormStepper/FormStepperTester.tsx +22 -0
  27. package/src/lib/Controls/FormStepper/index.tsx +2 -0
  28. package/src/lib/Controls/FormStepper/styled-components.tsx +17 -0
  29. package/src/lib/Controls/Inputs/InputBaseControl.tsx +52 -0
  30. package/src/lib/Controls/Inputs/InputBooleanControl.tsx +67 -0
  31. package/src/lib/Controls/Inputs/InputBooleanRadioControl.tsx +74 -0
  32. package/src/lib/Controls/Inputs/InputDateControl.tsx +90 -0
  33. package/src/lib/Controls/Inputs/InputDateTimeControl.tsx +46 -0
  34. package/src/lib/Controls/Inputs/InputEnum.tsx +74 -0
  35. package/src/lib/Controls/Inputs/InputEnumAutoComplete.tsx +73 -0
  36. package/src/lib/Controls/Inputs/InputEnumRadios.tsx +43 -0
  37. package/src/lib/Controls/Inputs/InputIntegerControl.tsx +63 -0
  38. package/src/lib/Controls/Inputs/InputMultiLineTextControl.tsx +63 -0
  39. package/src/lib/Controls/Inputs/InputNumberControl.tsx +63 -0
  40. package/src/lib/Controls/Inputs/InputTextControl.tsx +62 -0
  41. package/src/lib/Controls/Inputs/InputTimeControl.tsx +46 -0
  42. package/src/lib/Controls/Inputs/index.tsx +13 -0
  43. package/src/lib/Controls/Inputs/inputControl.spec.ts +84 -0
  44. package/src/lib/Controls/Inputs/type.ts +3 -0
  45. package/src/lib/Controls/ObjectArray/DeleteDialog.tsx +49 -0
  46. package/src/lib/Controls/ObjectArray/ObjectArray.tsx +59 -0
  47. package/src/lib/Controls/ObjectArray/ObjectArrayToolBar.tsx +51 -0
  48. package/src/lib/Controls/ObjectArray/ObjectListControl.tsx +368 -0
  49. package/src/lib/Controls/ObjectArray/index.tsx +1 -0
  50. package/src/lib/Controls/ObjectArray/styled-components.tsx +13 -0
  51. package/src/lib/Controls/index.tsx +4 -0
  52. package/src/lib/ErrorHandling/GoAErrorControl.tsx +53 -0
  53. package/src/lib/ErrorHandling/MessageControl.tsx +19 -0
  54. package/src/lib/ErrorHandling/categorizationValidation.spec.ts +98 -0
  55. package/src/lib/ErrorHandling/controlValildation.spec.ts +57 -0
  56. package/src/lib/ErrorHandling/errorCheck.spec.ts +185 -0
  57. package/src/lib/ErrorHandling/errorCheck.tsx +86 -0
  58. package/src/lib/ErrorHandling/layoutValildation.spec.ts +47 -0
  59. package/src/lib/ErrorHandling/otherValildation.spec.ts +74 -0
  60. package/src/lib/ErrorHandling/schemaValidation.ts +115 -0
  61. package/src/lib/common/Grid.tsx +55 -0
  62. package/src/lib/jsonforms-components.module.scss +7 -0
  63. package/src/lib/jsonforms-components.spec.tsx +10 -0
  64. package/src/lib/jsonforms-components.tsx +14 -0
  65. package/src/lib/layouts/GroupControl.tsx +25 -0
  66. package/src/lib/layouts/HorizontalLayoutControl.tsx +30 -0
  67. package/src/lib/layouts/VerticalLayoutControl.tsx +28 -0
  68. package/src/lib/layouts/index.ts +3 -0
  69. package/src/lib/util/layout.tsx +68 -0
  70. package/src/lib/util/schemaUtils.ts +9 -0
  71. package/src/lib/util/stringUtils.ts +98 -0
  72. package/src/lib/util/style-component.ts +8 -0
  73. package/tsconfig.json +20 -0
  74. package/tsconfig.lib.json +19 -0
  75. package/tsconfig.spec.json +20 -0
@@ -0,0 +1,74 @@
1
+ import React, { useEffect } from 'react';
2
+ import { ControlProps, isEnumControl, OwnPropsOfEnum, RankedTester, rankWith } from '@jsonforms/core';
3
+ import { TranslateProps, withJsonFormsEnumProps, withTranslateProps } from '@jsonforms/react';
4
+ import { WithInputProps } from './type';
5
+ import merge from 'lodash/merge';
6
+ import { GoAInputBaseControl } from './InputBaseControl';
7
+ import { WithOptionLabel } from '@jsonforms/material-renderers';
8
+ import { GoADropdown, GoADropdownItem } from '@abgov/react-components-new';
9
+ import { EnumCellProps, WithClassname } from '@jsonforms/core';
10
+
11
+ import { addDataByOptions, getData } from '../../Context';
12
+ import { checkFieldValidity } from '../../util/stringUtils';
13
+
14
+ type EnumSelectProp = EnumCellProps & WithClassname & TranslateProps & WithInputProps;
15
+
16
+ export const EnumSelect = (props: EnumSelectProp): JSX.Element => {
17
+ const { data, id, enabled, errors, schema, path, handleChange, options, config, label, uischema } = props;
18
+ const { required } = props as ControlProps;
19
+
20
+ let enumData: unknown[] = schema?.enum || [];
21
+
22
+ const appliedUiSchemaOptions = merge({}, config, props.uischema.options, options);
23
+
24
+ const dataKey = uischema?.options?.enumContext?.key;
25
+
26
+ const url = uischema?.options?.enumContext?.url;
27
+ const location = uischema?.options?.enumContext?.location;
28
+ const type = uischema?.options?.enumContext?.type;
29
+ const values = uischema?.options?.enumContext?.values;
30
+
31
+ const errorsFormInput = checkFieldValidity(props as ControlProps);
32
+
33
+ useEffect(() => {
34
+ if (dataKey && url) {
35
+ addDataByOptions(dataKey, url, location, type, values);
36
+ }
37
+ }, [url, location, type, values, dataKey]);
38
+
39
+ if (dataKey && getData(dataKey)) {
40
+ const newData = getData(dataKey) as unknown[];
41
+
42
+ enumData = newData;
43
+ }
44
+
45
+ return (
46
+ <GoADropdown
47
+ error={errorsFormInput.length > 0}
48
+ name={`${label}`}
49
+ value={data}
50
+ disabled={!enabled}
51
+ relative={true}
52
+ key={`${id}-jsonform-key`}
53
+ testId={`${id || label}-jsonform`}
54
+ {...appliedUiSchemaOptions}
55
+ onChange={(name, value) => {
56
+ handleChange(path, value);
57
+ }}
58
+ {...uischema?.options?.componentProps}
59
+ >
60
+ {enumData?.map((item) => {
61
+ return <GoADropdownItem key={`json-form-dropdown-${item}`} value={`${item}`} label={`${item}`} />;
62
+ })}
63
+ </GoADropdown>
64
+ );
65
+ };
66
+
67
+ export const numControl = (props: ControlProps & OwnPropsOfEnum & WithOptionLabel & TranslateProps) => {
68
+ return <GoAInputBaseControl {...props} input={EnumSelect} />;
69
+ };
70
+
71
+ export const GoAEnumControlTester: RankedTester = rankWith(2, isEnumControl);
72
+
73
+ // HOC order can be reversed with https://github.com/eclipsesource/jsonforms/issues/1987
74
+ export const GoAEnumControl = withJsonFormsEnumProps(withTranslateProps(numControl), true);
@@ -0,0 +1,73 @@
1
+ import React, { useEffect } from 'react';
2
+ import { ControlProps, isEnumControl, and, optionIs, OwnPropsOfEnum, RankedTester, rankWith } from '@jsonforms/core';
3
+ import { TranslateProps, withJsonFormsEnumProps, withTranslateProps } from '@jsonforms/react';
4
+ import { WithInputProps } from './type';
5
+ import { GoAInputBaseControl } from './InputBaseControl';
6
+ import { WithOptionLabel } from '@jsonforms/material-renderers';
7
+ import { EnumCellProps, WithClassname } from '@jsonforms/core';
8
+ import TextField from '@mui/material/TextField';
9
+ import Autocomplete from '@mui/material/Autocomplete';
10
+
11
+ import { addDataByOptions, getData } from '../../Context';
12
+
13
+ type EnumSelectAutoCompleteProp = EnumCellProps & WithClassname & TranslateProps & WithInputProps;
14
+
15
+ export const EnumSelectAutoComplete = (props: EnumSelectAutoCompleteProp): JSX.Element => {
16
+ const { data, schema, path, handleChange, uischema } = props;
17
+ let enumData = schema?.enum || [];
18
+
19
+ const dataKey = uischema?.options?.enumContext?.key;
20
+
21
+ const url = uischema?.options?.enumContext?.url;
22
+ const location = uischema?.options?.enumContext?.location;
23
+ const type = uischema?.options?.enumContext?.type;
24
+ const values = uischema?.options?.enumContext?.values;
25
+
26
+ const defaultProps = {
27
+ options: enumData,
28
+ getOptionLabel: (option: Array<string>) => option,
29
+ };
30
+
31
+ const [inputValue, setInputValue] = React.useState('');
32
+
33
+ useEffect(() => {
34
+ if (dataKey && url) {
35
+ addDataByOptions(dataKey, url, location, type, values);
36
+ }
37
+ }, [url, location, type, values, dataKey]);
38
+
39
+ if (dataKey && getData(dataKey)) {
40
+ const newData = getData(dataKey);
41
+ // eslint-disable-next-line
42
+ enumData = newData as any[];
43
+ defaultProps.options = enumData;
44
+ }
45
+
46
+ return (
47
+ <Autocomplete
48
+ {...defaultProps}
49
+ id="autocomplete"
50
+ getOptionLabel={(option) => option}
51
+ isOptionEqualToValue={(option, value) => option.id === value.id}
52
+ value={data || null}
53
+ onChange={(name, value) => {
54
+ handleChange(path, value);
55
+ setInputValue(value);
56
+ }}
57
+ renderInput={(params) => {
58
+ return <TextField {...params} variant="outlined" size="small" placeholder={schema?.description} />;
59
+ }}
60
+ />
61
+ );
62
+ };
63
+
64
+ const numControlAutoComplete = (props: ControlProps & OwnPropsOfEnum & WithOptionLabel & TranslateProps) => {
65
+ return <GoAInputBaseControl {...props} input={EnumSelectAutoComplete} />;
66
+ };
67
+
68
+ export const GoAEnumControlAutoCompleteTester: RankedTester = rankWith(
69
+ 3,
70
+ and(isEnumControl, optionIs('autocomplete', true))
71
+ );
72
+
73
+ export const GoAEnumAutoCompleteControl = withJsonFormsEnumProps(withTranslateProps(numControlAutoComplete), true);
@@ -0,0 +1,43 @@
1
+ import React from 'react';
2
+ import { ControlProps, isEnumControl, OwnPropsOfEnum, RankedTester, rankWith, optionIs, and } from '@jsonforms/core';
3
+ import { TranslateProps, withJsonFormsEnumProps, withTranslateProps } from '@jsonforms/react';
4
+ import { WithInputProps } from './type';
5
+ import merge from 'lodash/merge';
6
+ import { GoAInputBaseControl } from './InputBaseControl';
7
+ import { WithOptionLabel } from '@jsonforms/material-renderers';
8
+ import { GoARadioGroup, GoARadioItem } from '@abgov/react-components-new';
9
+ import { EnumCellProps, WithClassname } from '@jsonforms/core';
10
+ import { checkFieldValidity } from '../../util/stringUtils';
11
+
12
+ type RadioGroupProp = EnumCellProps & WithClassname & TranslateProps & WithInputProps;
13
+
14
+ export const RadioGroup = (props: RadioGroupProp): JSX.Element => {
15
+ const { data, className, id, enabled, schema, uischema, path, handleChange, options, config, label, t } = props;
16
+ const enumData = schema?.enum || [];
17
+ const appliedUiSchemaOptions = merge({}, config, props.uischema.options, uischema, options);
18
+ const errorsFormInput = checkFieldValidity(props as ControlProps);
19
+
20
+ return (
21
+ <GoARadioGroup
22
+ error={errorsFormInput.length > 0}
23
+ name={`${options || appliedUiSchemaOptions.label}`}
24
+ testId={`${id || label}-jsonform-dropdown`}
25
+ value={data}
26
+ disabled={!enabled}
27
+ {...appliedUiSchemaOptions}
28
+ onChange={(name: string, value: string) => handleChange(path, value)}
29
+ {...uischema?.options?.componentProps}
30
+ >
31
+ {enumData.map((value) => {
32
+ return <GoARadioItem name={value} value={`${value}`} label={value} {...appliedUiSchemaOptions} />;
33
+ })}
34
+ </GoARadioGroup>
35
+ );
36
+ };
37
+
38
+ export const EnumRadioControl = (props: ControlProps & OwnPropsOfEnum & WithOptionLabel & TranslateProps) => {
39
+ return <GoAInputBaseControl {...props} input={RadioGroup} />;
40
+ };
41
+
42
+ export const GoAEnumRadioGroupControl = withJsonFormsEnumProps(withTranslateProps(EnumRadioControl), true);
43
+ export const GoARadioGroupControlTester: RankedTester = rankWith(20, and(isEnumControl, optionIs('format', 'radio')));
@@ -0,0 +1,63 @@
1
+ import React from 'react';
2
+ import { CellProps, WithClassname, ControlProps, isIntegerControl, RankedTester, rankWith } from '@jsonforms/core';
3
+ import { GoAInput, GoAInputNumber } from '@abgov/react-components-new';
4
+ import { WithInputProps } from './type';
5
+ import { withJsonFormsControlProps } from '@jsonforms/react';
6
+ import { GoAInputBaseControl } from './InputBaseControl';
7
+ import { checkFieldValidity, isValidDate } from '../../util/stringUtils';
8
+ type GoAInputIntegerProps = CellProps & WithClassname & WithInputProps;
9
+
10
+ export const GoAInputInteger = (props: GoAInputIntegerProps): JSX.Element => {
11
+ // eslint-disable-next-line
12
+ const { data, config, id, enabled, uischema, isValid, path, handleChange, schema, label } = props;
13
+ const appliedUiSchemaOptions = { ...config, ...uischema?.options };
14
+ const placeholder = appliedUiSchemaOptions?.placeholder || schema?.description || '';
15
+ const InputValue = data && data !== undefined ? data : '';
16
+ const clonedSchema = JSON.parse(JSON.stringify(schema));
17
+ const StepValue = clonedSchema.multipleOf ? clonedSchema.multipleOf : 0;
18
+ const MinValue = clonedSchema.minimum ? clonedSchema.minimum : '';
19
+ const MaxValue = clonedSchema.exclusiveMaximum ? clonedSchema.exclusiveMaximum : '';
20
+ const errorsFormInput = checkFieldValidity(props as ControlProps);
21
+
22
+ return (
23
+ <GoAInput
24
+ type="number"
25
+ error={errorsFormInput.length > 0}
26
+ width="100%"
27
+ disabled={!enabled}
28
+ value={InputValue}
29
+ step={StepValue}
30
+ min={MinValue}
31
+ max={MaxValue}
32
+ placeholder={placeholder}
33
+ name={appliedUiSchemaOptions?.name || `${id || label}-input`}
34
+ testId={appliedUiSchemaOptions?.testId || `${id}-input`}
35
+ onKeyPress={(name: string, value: string, key: string) => {
36
+ if (!(key === 'Tab' || key === 'Shift')) {
37
+ let newValue: string | number = '';
38
+ if (value !== '') {
39
+ newValue = +value;
40
+ }
41
+
42
+ handleChange(path, newValue);
43
+ }
44
+ }}
45
+ onBlur={(name: string, value: string) => {
46
+ let newValue: string | number = '';
47
+ if (value !== '') {
48
+ newValue = +value;
49
+ }
50
+ handleChange(path, newValue);
51
+ }}
52
+ //Dont trigger the handleChange event on the onChange event as it will cause
53
+ //issue with the error message from displaying, use keyPress or the onBlur event instead
54
+ onChange={(name: string, value: string) => {}}
55
+ {...uischema?.options?.componentProps}
56
+ />
57
+ );
58
+ };
59
+
60
+ export const GoAIntegerControl = (props: ControlProps) => <GoAInputBaseControl {...props} input={GoAInputInteger} />;
61
+
62
+ export const GoAIntegerControlTester: RankedTester = rankWith(2, isIntegerControl);
63
+ export const GoAInputIntegerControl = withJsonFormsControlProps(GoAIntegerControl);
@@ -0,0 +1,63 @@
1
+ import React from 'react';
2
+ import {
3
+ CellProps,
4
+ WithClassname,
5
+ ControlProps,
6
+ isStringControl,
7
+ RankedTester,
8
+ rankWith,
9
+ and,
10
+ optionIs,
11
+ } from '@jsonforms/core';
12
+ import { GoATextArea } from '@abgov/react-components-new';
13
+ import { WithInputProps } from './type';
14
+ import { withJsonFormsControlProps } from '@jsonforms/react';
15
+ import { GoAInputBaseControl } from './InputBaseControl';
16
+ import { checkFieldValidity } from '../../util/stringUtils';
17
+ type GoAInputTextProps = CellProps & WithClassname & WithInputProps;
18
+
19
+ export const MultiLineText = (props: GoAInputTextProps): JSX.Element => {
20
+ // eslint-disable-next-line
21
+ const { data, config, id, enabled, uischema, path, handleChange, schema, label } = props;
22
+
23
+ const appliedUiSchemaOptions = { ...config, ...uischema?.options };
24
+ const placeholder = appliedUiSchemaOptions?.placeholder || schema?.description || '';
25
+ const errorsFormInput = checkFieldValidity(props as ControlProps);
26
+ const autoCapitalize =
27
+ uischema?.options?.componentProps?.autoCapitalize === true || uischema?.options?.autoCapitalize === true;
28
+
29
+ return (
30
+ <GoATextArea
31
+ error={errorsFormInput.length > 0}
32
+ value={data}
33
+ disabled={!enabled}
34
+ placeholder={placeholder}
35
+ testId={appliedUiSchemaOptions?.testId || `${id}-input`}
36
+ name={`${label || path}-text-area`}
37
+ width={'100%'}
38
+ // Note: Paul Jan-09-2023. The latest ui-component come with the maxCount. We need to uncomment the following line when the component is updated
39
+ // maxCount={schema.maxLength || 256}
40
+ onKeyPress={(name: string, value: string, key: string) => {
41
+ if (!(key === 'Tab' || key === 'Shift')) {
42
+ if (autoCapitalize === true) {
43
+ handleChange(path, value.toUpperCase());
44
+ } else {
45
+ handleChange(path, value);
46
+ }
47
+ }
48
+ }}
49
+ // Dont use handleChange in the onChange event, use the keyPress or onBlur.
50
+ // If you use it onChange along with keyPress event it will cause a
51
+ // side effect that causes the validation to render when it shouldnt.
52
+ onChange={() => {}}
53
+ {...uischema?.options?.componentProps}
54
+ />
55
+ );
56
+ };
57
+
58
+ export const MultiLineTextControlInput = (props: ControlProps) => (
59
+ <GoAInputBaseControl {...props} input={MultiLineText} />
60
+ );
61
+
62
+ export const MultiLineTextControlTester: RankedTester = rankWith(3, and(isStringControl, optionIs('multi', true)));
63
+ export const MultiLineTextControl = withJsonFormsControlProps(MultiLineTextControlInput);
@@ -0,0 +1,63 @@
1
+ import React from 'react';
2
+ import { CellProps, WithClassname, ControlProps, isNumberControl, RankedTester, rankWith } from '@jsonforms/core';
3
+ import { GoAInput } from '@abgov/react-components-new';
4
+ import { WithInputProps } from './type';
5
+ import { withJsonFormsControlProps } from '@jsonforms/react';
6
+ import { GoAInputBaseControl } from './InputBaseControl';
7
+ import { checkFieldValidity } from '../../util/stringUtils';
8
+ type GoAInputNumberProps = CellProps & WithClassname & WithInputProps;
9
+
10
+ export const GoANumberInput = (props: GoAInputNumberProps): JSX.Element => {
11
+ // eslint-disable-next-line
12
+ const { data, config, id, enabled, uischema, isValid, path, handleChange, schema, label } = props;
13
+
14
+ const appliedUiSchemaOptions = { ...config, ...uischema?.options };
15
+ const placeholder = appliedUiSchemaOptions?.placeholder || schema?.description || '';
16
+ const InputValue = data && data !== undefined ? data : '';
17
+ const clonedSchema = JSON.parse(JSON.stringify(schema));
18
+ const StepValue = clonedSchema.multipleOf ? clonedSchema.multipleOf : 0.01;
19
+ const MinValue = clonedSchema.minimum ? clonedSchema.minimum : '';
20
+ const MaxValue = clonedSchema.exclusiveMaximum ? clonedSchema.exclusiveMaximum : '';
21
+ const errorsFormInput = checkFieldValidity(props as ControlProps);
22
+
23
+ return (
24
+ <GoAInput
25
+ type="number"
26
+ error={errorsFormInput.length > 0}
27
+ disabled={!enabled}
28
+ value={InputValue}
29
+ placeholder={placeholder}
30
+ step={StepValue}
31
+ min={MinValue}
32
+ max={MaxValue}
33
+ width="100%"
34
+ name={appliedUiSchemaOptions?.name || `${id || label}-input`}
35
+ testId={appliedUiSchemaOptions?.testId || `${id}-input`}
36
+ onKeyPress={(name: string, value: string, key: string) => {
37
+ if (!(key === 'Tab' || key === 'Shift')) {
38
+ let newValue: string | number = '';
39
+ if (value !== '') {
40
+ newValue = +value;
41
+ }
42
+ handleChange(path, newValue);
43
+ }
44
+ }}
45
+ onBlur={(name: string, value: string) => {
46
+ let newValue: string | number = '';
47
+ if (value !== '') {
48
+ newValue = +value;
49
+ }
50
+ handleChange(path, newValue);
51
+ }}
52
+ //Dont trigger the handleChange event on the onChange event as it will cause
53
+ //issue with the error message from displaying, use keyPress or the onBlur event instead
54
+ onChange={(name: string, value: string) => {}}
55
+ {...uischema?.options?.componentProps}
56
+ />
57
+ );
58
+ };
59
+
60
+ export const GoANumberControl = (props: ControlProps) => <GoAInputBaseControl {...props} input={GoANumberInput} />;
61
+
62
+ export const GoANumberControlTester: RankedTester = rankWith(2, isNumberControl);
63
+ export const GoAInputNumberControl = withJsonFormsControlProps(GoANumberControl);
@@ -0,0 +1,62 @@
1
+ import React from 'react';
2
+ import { CellProps, WithClassname, ControlProps, isStringControl, RankedTester, rankWith } from '@jsonforms/core';
3
+ import { withJsonFormsControlProps } from '@jsonforms/react';
4
+ import { GoAInput, GoAFormItem } from '@abgov/react-components-new';
5
+ import { WithInputProps } from './type';
6
+ import { GoAInputBaseControl } from './InputBaseControl';
7
+ import { checkFieldValidity, getLabelText } from '../../util/stringUtils';
8
+
9
+ type GoAInputTextProps = CellProps & WithClassname & WithInputProps;
10
+
11
+ export const GoAInputText = (props: GoAInputTextProps): JSX.Element => {
12
+ // eslint-disable-next-line
13
+ const { data, config, id, enabled, uischema, isValid, errors, path, handleChange, schema, label } = props;
14
+
15
+ const appliedUiSchemaOptions = { ...config, ...uischema?.options };
16
+ const placeholder = appliedUiSchemaOptions?.placeholder || schema?.description || '';
17
+
18
+ const errorsFormInput = checkFieldValidity(props as ControlProps);
19
+
20
+ const autoCapitalize =
21
+ uischema?.options?.componentProps?.autoCapitalize === true || uischema?.options?.autoCapitalize === true;
22
+
23
+ return (
24
+ <GoAInput
25
+ error={errorsFormInput.length > 0}
26
+ type={appliedUiSchemaOptions.format === 'password' ? 'password' : 'text'}
27
+ disabled={!enabled}
28
+ value={data}
29
+ width={'100%'}
30
+ placeholder={placeholder}
31
+ // maxLength={appliedUiSchemaOptions?.maxLength}
32
+ name={appliedUiSchemaOptions?.name || `${id || label}-input`}
33
+ testId={appliedUiSchemaOptions?.testId || `${id}-input`}
34
+ // Dont use handleChange in the onChange event, use the keyPress or onBlur.
35
+ // If you use it onChange along with keyPress event it will cause a
36
+ // side effect that causes the validation to render when it shouldnt.
37
+ onChange={(name: string, value: string) => {}}
38
+ onKeyPress={(name: string, value: string, key: string) => {
39
+ if (!(key === 'Tab' || key === 'Shift')) {
40
+ if (autoCapitalize === true) {
41
+ handleChange(path, value.toUpperCase());
42
+ } else {
43
+ handleChange(path, value);
44
+ }
45
+ }
46
+ }}
47
+ onBlur={(name: string, value: string) => {
48
+ if (autoCapitalize === true) {
49
+ handleChange(path, value.toUpperCase());
50
+ } else {
51
+ handleChange(path, value);
52
+ }
53
+ }}
54
+ {...uischema?.options?.componentProps}
55
+ />
56
+ );
57
+ };
58
+
59
+ export const GoATextControl = (props: ControlProps) => <GoAInputBaseControl {...props} input={GoAInputText} />;
60
+
61
+ export const GoATextControlTester: RankedTester = rankWith(1, isStringControl);
62
+ export const GoAInputTextControl = withJsonFormsControlProps(GoATextControl);
@@ -0,0 +1,46 @@
1
+ import React from 'react';
2
+ import { CellProps, WithClassname, ControlProps, isTimeControl, RankedTester, rankWith } from '@jsonforms/core';
3
+ import { GoAInputTime } from '@abgov/react-components-new';
4
+ import { WithInputProps } from './type';
5
+ import { withJsonFormsControlProps } from '@jsonforms/react';
6
+ import { GoAInputBaseControl } from './InputBaseControl';
7
+ import { checkFieldValidity, isValidDate } from '../../util/stringUtils';
8
+ type GoAInputTimeProps = CellProps & WithClassname & WithInputProps;
9
+
10
+ export const GoATimeInput = (props: GoAInputTimeProps): JSX.Element => {
11
+ // eslint-disable-next-line
12
+ const { data, config, id, enabled, uischema, isValid, path, handleChange, schema, label } = props;
13
+ const appliedUiSchemaOptions = { ...config, ...uischema?.options };
14
+ const placeholder = appliedUiSchemaOptions?.placeholder || schema?.description || '';
15
+ const errorsFormInput = checkFieldValidity(props as ControlProps);
16
+
17
+ return (
18
+ <GoAInputTime
19
+ error={errorsFormInput.length > 0}
20
+ name={appliedUiSchemaOptions?.name || `${id || label}-input`}
21
+ value={data}
22
+ step={1}
23
+ width="100%"
24
+ disabled={!enabled}
25
+ testId={appliedUiSchemaOptions?.testId || `${id}-input`}
26
+ onBlur={(name: string, value: string) => {
27
+ handleChange(path, value);
28
+ }}
29
+ // Dont use handleChange in the onChange event, use the keyPress or onBlur.
30
+ // If you use it onChange along with keyPress event it will cause a
31
+ // side effect that causes the validation to render when it shouldnt.
32
+ onChange={(name, value) => {}}
33
+ onKeyPress={(name: string, value: string, key: string) => {
34
+ if (!(key === 'Tab' || key === 'Shift')) {
35
+ handleChange(path, value);
36
+ }
37
+ }}
38
+ {...uischema?.options?.componentProps}
39
+ />
40
+ );
41
+ };
42
+
43
+ export const GoATimeControl = (props: ControlProps) => <GoAInputBaseControl {...props} input={GoATimeInput} />;
44
+
45
+ export const GoATimeControlTester: RankedTester = rankWith(4, isTimeControl);
46
+ export const GoAInputTimeControl = withJsonFormsControlProps(GoATimeControl);
@@ -0,0 +1,13 @@
1
+ export * from './InputBaseControl';
2
+ export * from './InputTextControl';
3
+ export * from './InputMultiLineTextControl';
4
+ export * from './InputDateControl';
5
+ export * from './InputNumberControl';
6
+ export * from './InputIntegerControl';
7
+ export * from './InputDateTimeControl';
8
+ export * from './InputTimeControl';
9
+ export * from './InputEnum';
10
+ export * from './InputEnumAutoComplete';
11
+ export * from './InputEnumRadios';
12
+ export * from './InputBooleanControl';
13
+ export * from './InputBooleanRadioControl';
@@ -0,0 +1,84 @@
1
+ import React from 'react';
2
+ import { render } from '@testing-library/react';
3
+ import '@testing-library/jest-dom';
4
+ import { GoADateInput, errMalformedDate } from './InputDateControl';
5
+ import { GoAInputDateProps } from './InputDateControl';
6
+ import { ControlElement } from '@jsonforms/core';
7
+
8
+ const theDate = {
9
+ theDate: '',
10
+ };
11
+
12
+ const dateSchema = {
13
+ type: 'object',
14
+ properties: {
15
+ theDate: {
16
+ type: 'string',
17
+ format: 'date',
18
+ },
19
+ },
20
+ };
21
+
22
+ const uiSchema = (min: string, max: string): ControlElement => {
23
+ return {
24
+ type: 'Control',
25
+ scope: '#/properties/theDate',
26
+ label: 'Date control test',
27
+ options: {
28
+ componentProps: {
29
+ min: min,
30
+ max: max,
31
+ },
32
+ },
33
+ };
34
+ };
35
+
36
+ const staticProps: GoAInputDateProps = {
37
+ uischema: uiSchema('2023-02-01', '2025-02-01'),
38
+ schema: dateSchema,
39
+ rootSchema: dateSchema,
40
+ handleChange: () => {},
41
+ enabled: true,
42
+ label: 'Date control test',
43
+ id: 'My ID',
44
+ config: {},
45
+ path: '',
46
+ errors: '',
47
+ data: theDate.theDate,
48
+ visible: true,
49
+ isValid: true,
50
+ };
51
+
52
+ describe('input control tests', () => {
53
+ describe('input date control tests', () => {
54
+ it('can render valid date', () => {
55
+ const props = { ...staticProps, uischema: uiSchema('2023-02-01', '2025-02-01') };
56
+ const component = render(GoADateInput(props));
57
+ expect(component.getByTestId('My ID-input')).toBeInTheDocument();
58
+ });
59
+
60
+ it('can detect malformed max dates in schema', () => {
61
+ const props = { ...staticProps, uischema: uiSchema('2023-02-01', '2025a/02-01') };
62
+ const component = render(GoADateInput(props));
63
+ expect(component.getByText(errMalformedDate(props.uischema.scope, 'Max'))).toBeInTheDocument();
64
+ });
65
+
66
+ it('can detect malformed min dates in schema', () => {
67
+ const props = { ...staticProps, uischema: uiSchema('2023b/02-01', '2025-02-01') };
68
+ const component = render(GoADateInput(props));
69
+ expect(component.getByText(errMalformedDate(props.uischema.scope, 'Min'))).toBeInTheDocument();
70
+ });
71
+
72
+ it('will reformat non-standard min dates', () => {
73
+ const props = { ...staticProps, uischema: uiSchema('2023/02-01', '2025-02-01') };
74
+ const component = render(GoADateInput(props));
75
+ expect(component.getByTestId('My ID-input')).toBeInTheDocument();
76
+ });
77
+
78
+ it('will reformat non-standard max', () => {
79
+ const props = { ...staticProps, uischema: uiSchema('2023-02-01', '2025/02-01') };
80
+ const component = render(GoADateInput(props));
81
+ expect(component.getByTestId('My ID-input')).toBeInTheDocument();
82
+ });
83
+ });
84
+ });
@@ -0,0 +1,3 @@
1
+ export interface WithInputProps {
2
+ label?: string;
3
+ }
@@ -0,0 +1,49 @@
1
+ import React from 'react';
2
+ import { GoAButton, GoAModal, GoAButtonGroup } from '@abgov/react-components-new';
3
+ import { DeleteDialogContent } from './styled-components';
4
+
5
+ export interface DeleteDialogProps {
6
+ open: boolean;
7
+ onConfirm(): void;
8
+ onCancel(): void;
9
+ title: string;
10
+ message: string;
11
+ }
12
+
13
+ export interface WithDeleteDialogSupport {
14
+ openDeleteDialog(path: string, data: number): void;
15
+ }
16
+
17
+ export const DeleteDialog = React.memo(function DeleteDialog({
18
+ open,
19
+ onConfirm,
20
+ onCancel,
21
+ title,
22
+ message,
23
+ }: DeleteDialogProps) {
24
+ return (
25
+ <GoAModal open={open} key={1} testId="object-array-modal" heading={title}>
26
+ <DeleteDialogContent data-testid="object-array-modal-content">{message}</DeleteDialogContent>
27
+ <GoAButtonGroup alignment="end">
28
+ <GoAButton
29
+ type="secondary"
30
+ testId="object-array-modal-button"
31
+ onClick={() => {
32
+ onCancel();
33
+ }}
34
+ >
35
+ Cancel
36
+ </GoAButton>
37
+ <GoAButton
38
+ type="primary"
39
+ testId="object-array-confirm-button"
40
+ onClick={() => {
41
+ onConfirm();
42
+ }}
43
+ >
44
+ Delete
45
+ </GoAButton>
46
+ </GoAButtonGroup>
47
+ </GoAModal>
48
+ );
49
+ });