@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.
- package/.babelrc +12 -0
- package/.eslintrc.json +36 -0
- package/.releaserc.json +25 -0
- package/README.md +251 -0
- package/jest.config.ts +11 -0
- package/package.json +17 -0
- package/project.json +55 -0
- package/rollup.config.js +14 -0
- package/src/index.ts +166 -0
- package/src/lib/Additional/HelpContent.tsx +95 -0
- package/src/lib/Additional/index.ts +1 -0
- package/src/lib/Additional/styled-components.ts +27 -0
- package/src/lib/Cells/DateCell.tsx +10 -0
- package/src/lib/Cells/IntegerCell.tsx +10 -0
- package/src/lib/Cells/NumberCell.tsx +10 -0
- package/src/lib/Cells/TextCell.tsx +10 -0
- package/src/lib/Cells/TimeCell.tsx +10 -0
- package/src/lib/Cells/index.tsx +14 -0
- package/src/lib/Context/index.tsx +172 -0
- package/src/lib/Controls/FileUploader/ContextMenu.tsx +50 -0
- package/src/lib/Controls/FileUploader/FileUploaderControl.tsx +131 -0
- package/src/lib/Controls/FileUploader/FileUploaderTester.tsx +3 -0
- package/src/lib/Controls/FileUploader/index.tsx +2 -0
- package/src/lib/Controls/FileUploader/styled-components.tsx +10 -0
- package/src/lib/Controls/FormStepper/FormStepperControl.tsx +269 -0
- package/src/lib/Controls/FormStepper/FormStepperTester.tsx +22 -0
- package/src/lib/Controls/FormStepper/index.tsx +2 -0
- package/src/lib/Controls/FormStepper/styled-components.tsx +17 -0
- package/src/lib/Controls/Inputs/InputBaseControl.tsx +52 -0
- package/src/lib/Controls/Inputs/InputBooleanControl.tsx +67 -0
- package/src/lib/Controls/Inputs/InputBooleanRadioControl.tsx +74 -0
- package/src/lib/Controls/Inputs/InputDateControl.tsx +90 -0
- package/src/lib/Controls/Inputs/InputDateTimeControl.tsx +46 -0
- package/src/lib/Controls/Inputs/InputEnum.tsx +74 -0
- package/src/lib/Controls/Inputs/InputEnumAutoComplete.tsx +73 -0
- package/src/lib/Controls/Inputs/InputEnumRadios.tsx +43 -0
- package/src/lib/Controls/Inputs/InputIntegerControl.tsx +63 -0
- package/src/lib/Controls/Inputs/InputMultiLineTextControl.tsx +63 -0
- package/src/lib/Controls/Inputs/InputNumberControl.tsx +63 -0
- package/src/lib/Controls/Inputs/InputTextControl.tsx +62 -0
- package/src/lib/Controls/Inputs/InputTimeControl.tsx +46 -0
- package/src/lib/Controls/Inputs/index.tsx +13 -0
- package/src/lib/Controls/Inputs/inputControl.spec.ts +84 -0
- package/src/lib/Controls/Inputs/type.ts +3 -0
- package/src/lib/Controls/ObjectArray/DeleteDialog.tsx +49 -0
- package/src/lib/Controls/ObjectArray/ObjectArray.tsx +59 -0
- package/src/lib/Controls/ObjectArray/ObjectArrayToolBar.tsx +51 -0
- package/src/lib/Controls/ObjectArray/ObjectListControl.tsx +368 -0
- package/src/lib/Controls/ObjectArray/index.tsx +1 -0
- package/src/lib/Controls/ObjectArray/styled-components.tsx +13 -0
- package/src/lib/Controls/index.tsx +4 -0
- package/src/lib/ErrorHandling/GoAErrorControl.tsx +53 -0
- package/src/lib/ErrorHandling/MessageControl.tsx +19 -0
- package/src/lib/ErrorHandling/categorizationValidation.spec.ts +98 -0
- package/src/lib/ErrorHandling/controlValildation.spec.ts +57 -0
- package/src/lib/ErrorHandling/errorCheck.spec.ts +185 -0
- package/src/lib/ErrorHandling/errorCheck.tsx +86 -0
- package/src/lib/ErrorHandling/layoutValildation.spec.ts +47 -0
- package/src/lib/ErrorHandling/otherValildation.spec.ts +74 -0
- package/src/lib/ErrorHandling/schemaValidation.ts +115 -0
- package/src/lib/common/Grid.tsx +55 -0
- package/src/lib/jsonforms-components.module.scss +7 -0
- package/src/lib/jsonforms-components.spec.tsx +10 -0
- package/src/lib/jsonforms-components.tsx +14 -0
- package/src/lib/layouts/GroupControl.tsx +25 -0
- package/src/lib/layouts/HorizontalLayoutControl.tsx +30 -0
- package/src/lib/layouts/VerticalLayoutControl.tsx +28 -0
- package/src/lib/layouts/index.ts +3 -0
- package/src/lib/util/layout.tsx +68 -0
- package/src/lib/util/schemaUtils.ts +9 -0
- package/src/lib/util/stringUtils.ts +98 -0
- package/src/lib/util/style-component.ts +8 -0
- package/tsconfig.json +20 -0
- package/tsconfig.lib.json +19 -0
- package/tsconfig.spec.json +20 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { LayoutProps, RankedTester, rankWith, uiTypeIs, HorizontalLayout } from '@jsonforms/core';
|
|
3
|
+
import { LayoutRenderer, LayoutRendererProps } from '../util/layout';
|
|
4
|
+
import { withJsonFormsLayoutProps } from '@jsonforms/react';
|
|
5
|
+
|
|
6
|
+
export const materialHorizontalLayoutTester: RankedTester = rankWith(2, uiTypeIs('HorizontalLayout'));
|
|
7
|
+
|
|
8
|
+
export const GoAHorizontalLayoutComponent = ({
|
|
9
|
+
uischema,
|
|
10
|
+
renderers,
|
|
11
|
+
cells,
|
|
12
|
+
schema,
|
|
13
|
+
path,
|
|
14
|
+
enabled,
|
|
15
|
+
visible,
|
|
16
|
+
}: LayoutProps) => {
|
|
17
|
+
const layout = uischema as HorizontalLayout;
|
|
18
|
+
const childProps: LayoutRendererProps = {
|
|
19
|
+
elements: layout.elements,
|
|
20
|
+
schema,
|
|
21
|
+
path,
|
|
22
|
+
enabled,
|
|
23
|
+
direction: 'row',
|
|
24
|
+
visible,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
return <LayoutRenderer {...childProps} renderers={renderers} cells={cells} />;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const GoAHorizontalLayout = withJsonFormsLayoutProps(GoAHorizontalLayoutComponent, true);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { LayoutProps, VerticalLayout } from '@jsonforms/core';
|
|
3
|
+
import { LayoutRenderer, LayoutRendererProps } from '../util/layout';
|
|
4
|
+
import { withJsonFormsLayoutProps } from '@jsonforms/react';
|
|
5
|
+
|
|
6
|
+
export const GoAVerticalLayoutComponent = ({
|
|
7
|
+
uischema,
|
|
8
|
+
schema,
|
|
9
|
+
path,
|
|
10
|
+
enabled,
|
|
11
|
+
renderers,
|
|
12
|
+
cells,
|
|
13
|
+
visible,
|
|
14
|
+
}: LayoutProps) => {
|
|
15
|
+
const verticalLayout = uischema as VerticalLayout;
|
|
16
|
+
const childProps: LayoutRendererProps = {
|
|
17
|
+
elements: verticalLayout.elements,
|
|
18
|
+
schema,
|
|
19
|
+
path,
|
|
20
|
+
enabled,
|
|
21
|
+
direction: 'column',
|
|
22
|
+
visible,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
return <LayoutRenderer {...childProps} renderers={renderers} cells={cells} />;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const GoAVerticalLayout = withJsonFormsLayoutProps(GoAVerticalLayoutComponent, true);
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import isEmpty from 'lodash/isEmpty';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import type { UISchemaElement } from '@jsonforms/core';
|
|
5
|
+
import {
|
|
6
|
+
JsonFormsCellRendererRegistryEntry,
|
|
7
|
+
JsonFormsRendererRegistryEntry,
|
|
8
|
+
JsonSchema,
|
|
9
|
+
OwnPropsOfRenderer,
|
|
10
|
+
} from '@jsonforms/core';
|
|
11
|
+
import { JsonFormsDispatch } from '@jsonforms/react';
|
|
12
|
+
import { GoAGrid } from '@abgov/react-components-new';
|
|
13
|
+
import { Hidden } from '@mui/material';
|
|
14
|
+
|
|
15
|
+
export const renderLayoutElements = (
|
|
16
|
+
elements: UISchemaElement[],
|
|
17
|
+
schema?: JsonSchema,
|
|
18
|
+
path?: string,
|
|
19
|
+
enabled?: boolean,
|
|
20
|
+
renderers?: JsonFormsRendererRegistryEntry[],
|
|
21
|
+
cells?: JsonFormsCellRendererRegistryEntry[]
|
|
22
|
+
) => {
|
|
23
|
+
return elements.map((child, index) => (
|
|
24
|
+
<div key={index}>
|
|
25
|
+
<JsonFormsDispatch
|
|
26
|
+
uischema={child}
|
|
27
|
+
schema={schema}
|
|
28
|
+
key={path}
|
|
29
|
+
path={path}
|
|
30
|
+
enabled={enabled}
|
|
31
|
+
renderers={renderers}
|
|
32
|
+
cells={cells}
|
|
33
|
+
/>
|
|
34
|
+
</div>
|
|
35
|
+
));
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export interface LayoutRendererProps extends OwnPropsOfRenderer {
|
|
39
|
+
elements: UISchemaElement[];
|
|
40
|
+
direction: 'row' | 'column';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export const LayoutRenderer = ({
|
|
44
|
+
elements,
|
|
45
|
+
schema,
|
|
46
|
+
path,
|
|
47
|
+
enabled,
|
|
48
|
+
direction,
|
|
49
|
+
renderers,
|
|
50
|
+
cells,
|
|
51
|
+
visible,
|
|
52
|
+
}: LayoutRendererProps) => {
|
|
53
|
+
if (isEmpty(elements)) {
|
|
54
|
+
return null;
|
|
55
|
+
} else {
|
|
56
|
+
if (direction === 'row') {
|
|
57
|
+
return (
|
|
58
|
+
<Hidden xsUp={!visible}>
|
|
59
|
+
<GoAGrid minChildWidth="10ch">
|
|
60
|
+
{renderLayoutElements(elements, schema, path, enabled, renderers, cells)}
|
|
61
|
+
</GoAGrid>
|
|
62
|
+
</Hidden>
|
|
63
|
+
);
|
|
64
|
+
} else {
|
|
65
|
+
return <Hidden xsUp={!visible}>{renderLayoutElements(elements, schema, path, enabled, renderers, cells)}</Hidden>;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { ControlProps, JsonSchema } from '@jsonforms/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Sets the first word to be capitalized so that it is sentence cased.
|
|
5
|
+
* @param words
|
|
6
|
+
* @returns sentence word string.
|
|
7
|
+
*/
|
|
8
|
+
export const capitalizeFirstLetter = (words: string) => {
|
|
9
|
+
const value = words.charAt(0).toUpperCase() + words.slice(1).toLowerCase();
|
|
10
|
+
return value;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Compares the scope name and the label to determine if it matches so that it can be sentence case.
|
|
15
|
+
* @param scope - format eg: '#/properties/firstName'
|
|
16
|
+
* @param label - The label text
|
|
17
|
+
* @returns true if the scope and label matches, otherwise false
|
|
18
|
+
*/
|
|
19
|
+
export const controlScopeMatchesLabel = (scope: string, label: string) => {
|
|
20
|
+
// Get the property name in the string from the scope
|
|
21
|
+
const splitIdName = scope.replace(' ', '').split('/')?.at(-1)?.toLowerCase() ?? '';
|
|
22
|
+
const labelWithNoSpaces = label.replace(' ', '').toLowerCase();
|
|
23
|
+
if (splitIdName === labelWithNoSpaces) {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
return false;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Gets the label text in sentence case
|
|
31
|
+
* @param scope
|
|
32
|
+
* @param label
|
|
33
|
+
* @returns
|
|
34
|
+
*/
|
|
35
|
+
export const getLabelText = (scope: string, label: string): string => {
|
|
36
|
+
let labelToUpdate: string = '';
|
|
37
|
+
|
|
38
|
+
if (controlScopeMatchesLabel(scope, label || '')) {
|
|
39
|
+
labelToUpdate = capitalizeFirstLetter(label || '');
|
|
40
|
+
} else {
|
|
41
|
+
labelToUpdate = label || '';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return labelToUpdate;
|
|
45
|
+
};
|
|
46
|
+
// This message is thrown when the isNotEmpty is triggered by Ajv checkInput.ts configuration
|
|
47
|
+
export const FIELD_REQUIRED = 'data should pass "isNotEmpty" keyword validation';
|
|
48
|
+
|
|
49
|
+
const isEmptyBoolean = (schema: JsonSchema, data: unknown): boolean => {
|
|
50
|
+
return schema.type !== undefined && schema.type === 'boolean' && (data === null || data === undefined);
|
|
51
|
+
};
|
|
52
|
+
const isEmptyNumber = (schema: JsonSchema, data: unknown): boolean => {
|
|
53
|
+
return (
|
|
54
|
+
data === '' ||
|
|
55
|
+
data === undefined ||
|
|
56
|
+
data === null ||
|
|
57
|
+
((schema.type === 'number' || schema.type === 'integer') && isNaN(+data))
|
|
58
|
+
);
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Check if a required, defined input value is valid. Returns an appropriate
|
|
62
|
+
* error message if not.
|
|
63
|
+
* @param props
|
|
64
|
+
* @returns error message
|
|
65
|
+
*/
|
|
66
|
+
export const checkFieldValidity = (props: ControlProps): string => {
|
|
67
|
+
const { data, errors: ajvErrors, required, label, uischema, schema } = props;
|
|
68
|
+
const labelToUpdate = getLabelText(uischema.scope, label);
|
|
69
|
+
|
|
70
|
+
if (required) {
|
|
71
|
+
if (data === undefined) return '';
|
|
72
|
+
|
|
73
|
+
if (schema) {
|
|
74
|
+
if (isEmptyBoolean(schema, data)) {
|
|
75
|
+
return `${labelToUpdate} is required`;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (isEmptyNumber(schema, data)) {
|
|
79
|
+
return `${labelToUpdate} is required`;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return ajvErrors;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Check if the date is a valid date/time
|
|
89
|
+
*/
|
|
90
|
+
export const isValidDate = function (date: Date | string) {
|
|
91
|
+
if (date instanceof Date && isFinite(date.getTime())) {
|
|
92
|
+
return true;
|
|
93
|
+
} else if (typeof date === 'string' && date.length > 0) {
|
|
94
|
+
return true;
|
|
95
|
+
} else {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
};
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"jsx": "react-jsx",
|
|
4
|
+
"allowJs": false,
|
|
5
|
+
"esModuleInterop": false,
|
|
6
|
+
"allowSyntheticDefaultImports": true,
|
|
7
|
+
"strict": true
|
|
8
|
+
},
|
|
9
|
+
"files": [],
|
|
10
|
+
"include": [],
|
|
11
|
+
"references": [
|
|
12
|
+
{
|
|
13
|
+
"path": "./tsconfig.lib.json"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"path": "./tsconfig.spec.json"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"extends": "../../tsconfig.base.json"
|
|
20
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "../../dist/out-tsc",
|
|
5
|
+
"types": ["node", "../../node_modules/@nx/react/typings/cssmodule.d.ts", "../../node_modules/@nx/react/typings/image.d.ts"]
|
|
6
|
+
},
|
|
7
|
+
"exclude": [
|
|
8
|
+
"jest.config.ts",
|
|
9
|
+
"src/**/*.spec.ts",
|
|
10
|
+
"src/**/*.test.ts",
|
|
11
|
+
"src/**/*.spec.tsx",
|
|
12
|
+
"src/**/*.test.tsx",
|
|
13
|
+
"src/**/*.spec.js",
|
|
14
|
+
"src/**/*.test.js",
|
|
15
|
+
"src/**/*.spec.jsx",
|
|
16
|
+
"src/**/*.test.jsx"
|
|
17
|
+
],
|
|
18
|
+
"include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]
|
|
19
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "../../dist/out-tsc",
|
|
5
|
+
"module": "commonjs",
|
|
6
|
+
"types": ["jest", "node"]
|
|
7
|
+
},
|
|
8
|
+
"include": [
|
|
9
|
+
"jest.config.ts",
|
|
10
|
+
"src/**/*.test.ts",
|
|
11
|
+
"src/**/*.spec.ts",
|
|
12
|
+
"src/**/*.test.tsx",
|
|
13
|
+
"src/**/*.spec.tsx",
|
|
14
|
+
"src/**/*.test.js",
|
|
15
|
+
"src/**/*.spec.js",
|
|
16
|
+
"src/**/*.test.jsx",
|
|
17
|
+
"src/**/*.spec.jsx",
|
|
18
|
+
"src/**/*.d.ts"
|
|
19
|
+
]
|
|
20
|
+
}
|