@abgov/jsonforms-components 0.0.1 → 1.2.0
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/index.esm.d.ts +1 -0
- package/index.esm.js +4831 -0
- package/package.json +8 -2
- package/src/index.d.ts +5 -0
- package/src/lib/Additional/HelpContent.d.ts +21 -0
- package/src/lib/Additional/styled-components.d.ts +1 -0
- package/src/lib/Cells/DateCell.d.ts +6 -0
- package/src/lib/Cells/IntegerCell.d.ts +6 -0
- package/src/lib/Cells/NumberCell.d.ts +6 -0
- package/src/lib/Cells/TextCell.d.ts +6 -0
- package/src/lib/Cells/TimeCell.d.ts +6 -0
- package/src/lib/Cells/index.d.ts +2 -0
- package/src/lib/Context/index.d.ts +39 -0
- package/src/lib/Controls/FileUploader/ContextMenu.d.ts +18 -0
- package/src/lib/Controls/FileUploader/FileUploaderControl.d.ts +4 -0
- package/src/lib/Controls/FileUploader/FileUploaderTester.d.ts +2 -0
- package/src/lib/Controls/FileUploader/styled-components.d.ts +1 -0
- package/src/lib/Controls/FormStepper/FormStepperControl.d.ts +14 -0
- package/src/lib/Controls/FormStepper/FormStepperTester.d.ts +2 -0
- package/src/lib/Controls/FormStepper/styled-components.d.ts +7 -0
- package/src/lib/Controls/Inputs/InputBaseControl.d.ts +7 -0
- package/src/lib/Controls/Inputs/InputBooleanControl.d.ts +6 -0
- package/src/lib/Controls/Inputs/InputBooleanRadioControl.d.ts +6 -0
- package/src/lib/Controls/Inputs/InputDateControl.d.ts +9 -0
- package/src/lib/Controls/Inputs/InputDateTimeControl.d.ts +9 -0
- package/src/lib/Controls/Inputs/InputEnum.d.ts +12 -0
- package/src/lib/Controls/Inputs/InputEnumAutoComplete.d.ts +10 -0
- package/src/lib/Controls/Inputs/InputEnumRadios.d.ts +12 -0
- package/src/lib/Controls/Inputs/InputIntegerControl.d.ts +9 -0
- package/src/lib/Controls/Inputs/InputMultiLineTextControl.d.ts +9 -0
- package/src/lib/Controls/Inputs/InputNumberControl.d.ts +9 -0
- package/src/lib/Controls/Inputs/InputTextControl.d.ts +9 -0
- package/src/lib/Controls/Inputs/InputTimeControl.d.ts +9 -0
- package/src/lib/Controls/Inputs/{type.ts → type.d.ts} +1 -1
- package/src/lib/Controls/ObjectArray/DeleteDialog.d.ts +12 -0
- package/src/lib/Controls/ObjectArray/ObjectArray.d.ts +6 -0
- package/src/lib/Controls/ObjectArray/ObjectArrayToolBar.d.ts +16 -0
- package/src/lib/Controls/ObjectArray/ObjectListControl.d.ts +24 -0
- package/src/lib/Controls/ObjectArray/styled-components.d.ts +3 -0
- package/src/lib/ErrorHandling/GoAErrorControl.d.ts +15 -0
- package/src/lib/ErrorHandling/{MessageControl.tsx → MessageControl.d.ts} +1 -8
- package/src/lib/ErrorHandling/errorCheck.d.ts +14 -0
- package/src/lib/ErrorHandling/schemaValidation.d.ts +11 -0
- package/src/lib/common/Grid.d.ts +11 -0
- package/src/lib/jsonforms-components.d.ts +4 -0
- package/src/lib/layouts/GroupControl.d.ts +5 -0
- package/src/lib/layouts/HorizontalLayoutControl.d.ts +5 -0
- package/src/lib/layouts/VerticalLayoutControl.d.ts +4 -0
- package/src/lib/util/layout.d.ts +8 -0
- package/src/lib/util/schemaUtils.d.ts +1 -0
- package/src/lib/util/stringUtils.d.ts +33 -0
- package/src/lib/util/style-component.d.ts +1 -0
- package/.babelrc +0 -12
- package/.eslintrc.json +0 -36
- package/.releaserc.json +0 -25
- package/jest.config.ts +0 -11
- package/project.json +0 -55
- package/rollup.config.js +0 -14
- package/src/index.ts +0 -166
- package/src/lib/Additional/HelpContent.tsx +0 -95
- package/src/lib/Additional/styled-components.ts +0 -27
- package/src/lib/Cells/DateCell.tsx +0 -10
- package/src/lib/Cells/IntegerCell.tsx +0 -10
- package/src/lib/Cells/NumberCell.tsx +0 -10
- package/src/lib/Cells/TextCell.tsx +0 -10
- package/src/lib/Cells/TimeCell.tsx +0 -10
- package/src/lib/Cells/index.tsx +0 -14
- package/src/lib/Context/index.tsx +0 -172
- package/src/lib/Controls/FileUploader/ContextMenu.tsx +0 -50
- package/src/lib/Controls/FileUploader/FileUploaderControl.tsx +0 -131
- package/src/lib/Controls/FileUploader/FileUploaderTester.tsx +0 -3
- package/src/lib/Controls/FileUploader/styled-components.tsx +0 -10
- package/src/lib/Controls/FormStepper/FormStepperControl.tsx +0 -269
- package/src/lib/Controls/FormStepper/FormStepperTester.tsx +0 -22
- package/src/lib/Controls/FormStepper/styled-components.tsx +0 -17
- package/src/lib/Controls/Inputs/InputBaseControl.tsx +0 -52
- package/src/lib/Controls/Inputs/InputBooleanControl.tsx +0 -67
- package/src/lib/Controls/Inputs/InputBooleanRadioControl.tsx +0 -74
- package/src/lib/Controls/Inputs/InputDateControl.tsx +0 -90
- package/src/lib/Controls/Inputs/InputDateTimeControl.tsx +0 -46
- package/src/lib/Controls/Inputs/InputEnum.tsx +0 -74
- package/src/lib/Controls/Inputs/InputEnumAutoComplete.tsx +0 -73
- package/src/lib/Controls/Inputs/InputEnumRadios.tsx +0 -43
- package/src/lib/Controls/Inputs/InputIntegerControl.tsx +0 -63
- package/src/lib/Controls/Inputs/InputMultiLineTextControl.tsx +0 -63
- package/src/lib/Controls/Inputs/InputNumberControl.tsx +0 -63
- package/src/lib/Controls/Inputs/InputTextControl.tsx +0 -62
- package/src/lib/Controls/Inputs/InputTimeControl.tsx +0 -46
- package/src/lib/Controls/Inputs/inputControl.spec.ts +0 -84
- package/src/lib/Controls/ObjectArray/DeleteDialog.tsx +0 -49
- package/src/lib/Controls/ObjectArray/ObjectArray.tsx +0 -59
- package/src/lib/Controls/ObjectArray/ObjectArrayToolBar.tsx +0 -51
- package/src/lib/Controls/ObjectArray/ObjectListControl.tsx +0 -368
- package/src/lib/Controls/ObjectArray/styled-components.tsx +0 -13
- package/src/lib/ErrorHandling/GoAErrorControl.tsx +0 -53
- package/src/lib/ErrorHandling/categorizationValidation.spec.ts +0 -98
- package/src/lib/ErrorHandling/controlValildation.spec.ts +0 -57
- package/src/lib/ErrorHandling/errorCheck.spec.ts +0 -185
- package/src/lib/ErrorHandling/errorCheck.tsx +0 -86
- package/src/lib/ErrorHandling/layoutValildation.spec.ts +0 -47
- package/src/lib/ErrorHandling/otherValildation.spec.ts +0 -74
- package/src/lib/ErrorHandling/schemaValidation.ts +0 -115
- package/src/lib/common/Grid.tsx +0 -55
- package/src/lib/jsonforms-components.module.scss +0 -7
- package/src/lib/jsonforms-components.spec.tsx +0 -10
- package/src/lib/jsonforms-components.tsx +0 -14
- package/src/lib/layouts/GroupControl.tsx +0 -25
- package/src/lib/layouts/HorizontalLayoutControl.tsx +0 -30
- package/src/lib/layouts/VerticalLayoutControl.tsx +0 -28
- package/src/lib/util/layout.tsx +0 -68
- package/src/lib/util/schemaUtils.ts +0 -9
- package/src/lib/util/stringUtils.ts +0 -98
- package/src/lib/util/style-component.ts +0 -8
- package/tsconfig.json +0 -20
- package/tsconfig.lib.json +0 -19
- package/tsconfig.spec.json +0 -20
- /package/src/lib/Additional/{index.ts → index.d.ts} +0 -0
- /package/src/lib/Controls/FileUploader/{index.tsx → index.d.ts} +0 -0
- /package/src/lib/Controls/FormStepper/{index.tsx → index.d.ts} +0 -0
- /package/src/lib/Controls/Inputs/{index.tsx → index.d.ts} +0 -0
- /package/src/lib/Controls/ObjectArray/{index.tsx → index.d.ts} +0 -0
- /package/src/lib/Controls/{index.tsx → index.d.ts} +0 -0
- /package/src/lib/layouts/{index.ts → index.d.ts} +0 -0
|
@@ -1,46 +0,0 @@
|
|
|
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);
|
|
@@ -1,84 +0,0 @@
|
|
|
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
|
-
});
|
|
@@ -1,49 +0,0 @@
|
|
|
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
|
-
});
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import React, { useCallback, useState } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
ArrayLayoutProps,
|
|
4
|
-
RankedTester,
|
|
5
|
-
isObjectArrayControl,
|
|
6
|
-
isPrimitiveArrayControl,
|
|
7
|
-
or,
|
|
8
|
-
rankWith,
|
|
9
|
-
uiTypeIs,
|
|
10
|
-
and,
|
|
11
|
-
} from '@jsonforms/core';
|
|
12
|
-
import { withJsonFormsArrayLayoutProps } from '@jsonforms/react';
|
|
13
|
-
import { ObjectArrayControl } from './ObjectListControl';
|
|
14
|
-
import { Hidden } from '@mui/material';
|
|
15
|
-
import { DeleteDialog } from './DeleteDialog';
|
|
16
|
-
|
|
17
|
-
export const ArrayControl = (props: ArrayLayoutProps) => {
|
|
18
|
-
const [open, setOpen] = useState(false);
|
|
19
|
-
const [path, setPath] = useState<string>();
|
|
20
|
-
const [rowData, setRowData] = useState<number>(0);
|
|
21
|
-
const { removeItems, visible } = props;
|
|
22
|
-
|
|
23
|
-
const openDeleteDialog = useCallback(
|
|
24
|
-
(p: string, rowIndex: number) => {
|
|
25
|
-
setOpen(true);
|
|
26
|
-
setPath(p);
|
|
27
|
-
setRowData(rowIndex);
|
|
28
|
-
},
|
|
29
|
-
[setOpen, setPath, setRowData]
|
|
30
|
-
);
|
|
31
|
-
const deleteCancel = useCallback(() => setOpen(false), [setOpen]);
|
|
32
|
-
|
|
33
|
-
// eslint-disable-next-line
|
|
34
|
-
const deleteConfirm = useCallback(() => {
|
|
35
|
-
const p = path?.substring(0, path.lastIndexOf('.'));
|
|
36
|
-
if (removeItems && p) {
|
|
37
|
-
removeItems(p, [rowData])();
|
|
38
|
-
}
|
|
39
|
-
setOpen(false);
|
|
40
|
-
// eslint-disable-next-line
|
|
41
|
-
}, [setOpen, path, rowData]);
|
|
42
|
-
|
|
43
|
-
return (
|
|
44
|
-
<Hidden xsUp={!visible}>
|
|
45
|
-
<ObjectArrayControl {...props} openDeleteDialog={openDeleteDialog} />
|
|
46
|
-
<DeleteDialog
|
|
47
|
-
open={open}
|
|
48
|
-
onCancel={deleteCancel}
|
|
49
|
-
onConfirm={deleteConfirm}
|
|
50
|
-
title={props.translations.deleteDialogTitle || ''}
|
|
51
|
-
message={props.translations.deleteDialogMessage || ''}
|
|
52
|
-
/>
|
|
53
|
-
</Hidden>
|
|
54
|
-
);
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
export const GoAArrayControlTester: RankedTester = rankWith(3, or(isObjectArrayControl, isPrimitiveArrayControl));
|
|
58
|
-
export const GoAArrayControlRenderer = withJsonFormsArrayLayoutProps(ArrayControl);
|
|
59
|
-
export const GoAListWithDetailsTester: RankedTester = rankWith(3, and(uiTypeIs('ListWithDetail')));
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { ControlElement, createDefaultValue, JsonSchema, ArrayTranslations } from '@jsonforms/core';
|
|
3
|
-
import { GoAButton } from '@abgov/react-components-new';
|
|
4
|
-
|
|
5
|
-
export interface ObjectArrayToolbarProps {
|
|
6
|
-
numColumns: number;
|
|
7
|
-
errors: string;
|
|
8
|
-
label: string;
|
|
9
|
-
path: string;
|
|
10
|
-
uischema: ControlElement;
|
|
11
|
-
schema: JsonSchema;
|
|
12
|
-
rootSchema: JsonSchema;
|
|
13
|
-
enabled: boolean;
|
|
14
|
-
translations: ArrayTranslations;
|
|
15
|
-
// eslint-disable-next-line
|
|
16
|
-
addItem(path: string, value: any): () => void;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const ObjectArrayToolBar = React.memo(function TableToolbar({
|
|
20
|
-
numColumns,
|
|
21
|
-
errors,
|
|
22
|
-
label,
|
|
23
|
-
path,
|
|
24
|
-
addItem,
|
|
25
|
-
schema,
|
|
26
|
-
enabled,
|
|
27
|
-
translations,
|
|
28
|
-
rootSchema,
|
|
29
|
-
uischema,
|
|
30
|
-
}: ObjectArrayToolbarProps) {
|
|
31
|
-
const buttonPosition = uischema?.options?.addButtonPosition || 'left';
|
|
32
|
-
return (
|
|
33
|
-
<>
|
|
34
|
-
{/* Note: Paul 2024-01-05: need to add the GoATooltip after the upgrade of the ui components */}
|
|
35
|
-
{/* <GoATooltip content={translations.addTooltip}> */}
|
|
36
|
-
<div style={{ textAlign: buttonPosition }}>
|
|
37
|
-
<GoAButton
|
|
38
|
-
disabled={!enabled}
|
|
39
|
-
testId={`object-array-toolbar-${label}`}
|
|
40
|
-
aria-label={translations.addAriaLabel}
|
|
41
|
-
onClick={addItem(path, createDefaultValue(schema, rootSchema))}
|
|
42
|
-
>
|
|
43
|
-
{uischema?.options?.addButtonText || 'Add'}
|
|
44
|
-
</GoAButton>
|
|
45
|
-
</div>
|
|
46
|
-
{/* </GoATooltip> */}
|
|
47
|
-
</>
|
|
48
|
-
);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
export default ObjectArrayToolBar;
|
|
@@ -1,368 +0,0 @@
|
|
|
1
|
-
import isEmpty from 'lodash/isEmpty';
|
|
2
|
-
import { JsonFormsStateContext, useJsonForms } from '@jsonforms/react';
|
|
3
|
-
import range from 'lodash/range';
|
|
4
|
-
import React from 'react';
|
|
5
|
-
import { FormHelperText, Hidden, Typography } from '@mui/material';
|
|
6
|
-
import {
|
|
7
|
-
ArrayLayoutProps,
|
|
8
|
-
ControlElement,
|
|
9
|
-
JsonSchema,
|
|
10
|
-
Paths,
|
|
11
|
-
JsonFormsRendererRegistryEntry,
|
|
12
|
-
JsonFormsCellRendererRegistryEntry,
|
|
13
|
-
ArrayTranslations,
|
|
14
|
-
UISchemaElement,
|
|
15
|
-
Layout,
|
|
16
|
-
} from '@jsonforms/core';
|
|
17
|
-
|
|
18
|
-
import { WithDeleteDialogSupport } from './DeleteDialog';
|
|
19
|
-
import ObjectArrayToolBar from './ObjectArrayToolBar';
|
|
20
|
-
import merge from 'lodash/merge';
|
|
21
|
-
import { JsonFormsDispatch } from '@jsonforms/react';
|
|
22
|
-
import { GoAGrid, GoAIconButton, GoAContainer } from '@abgov/react-components-new';
|
|
23
|
-
import { ToolBarHeader, ObjectArrayTitle } from './styled-components';
|
|
24
|
-
|
|
25
|
-
// eslint-disable-next-line
|
|
26
|
-
const extractScopesFromUISchema = (uischema: any): string[] => {
|
|
27
|
-
const scopes: string[] = [];
|
|
28
|
-
|
|
29
|
-
if (uischema?.elements) {
|
|
30
|
-
// eslint-disable-next-line
|
|
31
|
-
uischema?.elements?.forEach((element: any) => {
|
|
32
|
-
if (element?.elements) {
|
|
33
|
-
// eslint-disable-next-line
|
|
34
|
-
element?.elements?.forEach((internalElement: any) => {
|
|
35
|
-
if (internalElement?.scope) {
|
|
36
|
-
scopes.push(internalElement?.scope);
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return scopes;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const GenerateRows = (
|
|
47
|
-
Cell: React.ComponentType<OwnPropsOfNonEmptyCell>,
|
|
48
|
-
schema: JsonSchema,
|
|
49
|
-
rowPath: string,
|
|
50
|
-
enabled: boolean,
|
|
51
|
-
cells?: JsonFormsCellRendererRegistryEntry[],
|
|
52
|
-
uischema?: ControlElement
|
|
53
|
-
) => {
|
|
54
|
-
if (schema.type === 'object') {
|
|
55
|
-
const props = {
|
|
56
|
-
schema,
|
|
57
|
-
rowPath,
|
|
58
|
-
enabled,
|
|
59
|
-
cells,
|
|
60
|
-
uischema,
|
|
61
|
-
};
|
|
62
|
-
return <Cell {...props} />;
|
|
63
|
-
} else {
|
|
64
|
-
// primitives
|
|
65
|
-
const props = {
|
|
66
|
-
schema,
|
|
67
|
-
rowPath,
|
|
68
|
-
cellPath: rowPath,
|
|
69
|
-
enabled,
|
|
70
|
-
};
|
|
71
|
-
return <Cell key={rowPath} {...props} />;
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const getValidColumnProps = (scopedSchema: JsonSchema) => {
|
|
76
|
-
if (scopedSchema.type === 'object' && typeof scopedSchema.properties === 'object') {
|
|
77
|
-
return Object.keys(scopedSchema.properties).filter((prop) => scopedSchema.properties?.[prop].type !== 'array');
|
|
78
|
-
}
|
|
79
|
-
// primitives
|
|
80
|
-
return [''];
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
export interface EmptyListProps {
|
|
84
|
-
numColumns: number;
|
|
85
|
-
translations: ArrayTranslations;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const EmptyList = ({ numColumns, translations }: EmptyListProps) => (
|
|
89
|
-
<GoAGrid minChildWidth="30ch">
|
|
90
|
-
<Typography align="center">
|
|
91
|
-
<b>{translations.noDataMessage}</b>
|
|
92
|
-
</Typography>
|
|
93
|
-
</GoAGrid>
|
|
94
|
-
);
|
|
95
|
-
|
|
96
|
-
interface NonEmptyCellProps extends OwnPropsOfNonEmptyCell {
|
|
97
|
-
rootSchema?: JsonSchema;
|
|
98
|
-
errors: string;
|
|
99
|
-
enabled: boolean;
|
|
100
|
-
}
|
|
101
|
-
interface OwnPropsOfNonEmptyCell {
|
|
102
|
-
rowPath: string;
|
|
103
|
-
propName?: string;
|
|
104
|
-
schema: JsonSchema;
|
|
105
|
-
enabled: boolean;
|
|
106
|
-
renderers?: JsonFormsRendererRegistryEntry[];
|
|
107
|
-
cells?: JsonFormsCellRendererRegistryEntry[];
|
|
108
|
-
uischema?: ControlElement;
|
|
109
|
-
}
|
|
110
|
-
const ctxToNonEmptyCellProps = (ctx: JsonFormsStateContext, ownProps: OwnPropsOfNonEmptyCell): NonEmptyCellProps => {
|
|
111
|
-
const path = ownProps.rowPath + (ownProps.schema.type === 'object' ? '.' + ownProps.propName : '');
|
|
112
|
-
const errors = '';
|
|
113
|
-
return {
|
|
114
|
-
uischema: ownProps.uischema,
|
|
115
|
-
rowPath: ownProps.rowPath,
|
|
116
|
-
schema: ownProps.schema,
|
|
117
|
-
rootSchema: ctx.core?.schema,
|
|
118
|
-
errors,
|
|
119
|
-
enabled: ownProps.enabled,
|
|
120
|
-
cells: ownProps.cells || ctx.cells,
|
|
121
|
-
renderers: ownProps.renderers || ctx.renderers,
|
|
122
|
-
};
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
interface NonEmptyRowComponentProps {
|
|
126
|
-
propName?: string;
|
|
127
|
-
schema: JsonSchema;
|
|
128
|
-
rootSchema?: JsonSchema;
|
|
129
|
-
rowPath: string;
|
|
130
|
-
errors: string;
|
|
131
|
-
enabled: boolean;
|
|
132
|
-
renderers?: JsonFormsRendererRegistryEntry[];
|
|
133
|
-
cells?: JsonFormsCellRendererRegistryEntry[];
|
|
134
|
-
isValid: boolean;
|
|
135
|
-
uischema?: ControlElement | Layout;
|
|
136
|
-
}
|
|
137
|
-
const NonEmptyCellComponent = React.memo(function NonEmptyCellComponent({
|
|
138
|
-
schema,
|
|
139
|
-
errors,
|
|
140
|
-
enabled,
|
|
141
|
-
renderers,
|
|
142
|
-
cells,
|
|
143
|
-
rowPath,
|
|
144
|
-
isValid,
|
|
145
|
-
uischema,
|
|
146
|
-
}: NonEmptyRowComponentProps) {
|
|
147
|
-
const propNames = getValidColumnProps(schema);
|
|
148
|
-
const propScopes = (uischema as ControlElement)?.scope
|
|
149
|
-
? propNames.map((name) => {
|
|
150
|
-
return `#/properties/${name}`;
|
|
151
|
-
})
|
|
152
|
-
: [];
|
|
153
|
-
|
|
154
|
-
const scopesInElements = extractScopesFromUISchema(uischema);
|
|
155
|
-
const scopesNotInElements = propScopes.filter((scope) => {
|
|
156
|
-
return !scopesInElements.includes(scope);
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
/* Create default elements for scope not defined in the uischema
|
|
160
|
-
* future work: merge the options
|
|
161
|
-
*/
|
|
162
|
-
const uiSchemaElementsForNotDefined = {
|
|
163
|
-
type: uischema?.options?.defaultType || 'VerticalLayout',
|
|
164
|
-
elements: scopesNotInElements.map((scope) => {
|
|
165
|
-
return {
|
|
166
|
-
type: 'Control',
|
|
167
|
-
scope,
|
|
168
|
-
};
|
|
169
|
-
}),
|
|
170
|
-
};
|
|
171
|
-
return (
|
|
172
|
-
<>
|
|
173
|
-
{
|
|
174
|
-
// eslint-disable-next-line
|
|
175
|
-
(uischema as Layout)?.elements?.map((element: UISchemaElement) => {
|
|
176
|
-
return (
|
|
177
|
-
<JsonFormsDispatch
|
|
178
|
-
key={rowPath}
|
|
179
|
-
schema={schema}
|
|
180
|
-
uischema={element}
|
|
181
|
-
path={rowPath}
|
|
182
|
-
enabled={enabled}
|
|
183
|
-
renderers={renderers}
|
|
184
|
-
cells={cells}
|
|
185
|
-
/>
|
|
186
|
-
);
|
|
187
|
-
})
|
|
188
|
-
}
|
|
189
|
-
<JsonFormsDispatch
|
|
190
|
-
schema={schema}
|
|
191
|
-
uischema={uiSchemaElementsForNotDefined}
|
|
192
|
-
path={rowPath}
|
|
193
|
-
enabled={enabled}
|
|
194
|
-
renderers={renderers}
|
|
195
|
-
cells={cells}
|
|
196
|
-
/>
|
|
197
|
-
<FormHelperText error={!isValid}>{!isValid && errors}</FormHelperText>
|
|
198
|
-
</>
|
|
199
|
-
);
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
const NonEmptyCell = (ownProps: OwnPropsOfNonEmptyCell) => {
|
|
203
|
-
const ctx = useJsonForms();
|
|
204
|
-
const emptyCellProps = ctxToNonEmptyCellProps(ctx, ownProps);
|
|
205
|
-
const isValid = isEmpty(emptyCellProps.errors);
|
|
206
|
-
|
|
207
|
-
return <NonEmptyCellComponent {...emptyCellProps} isValid={isValid} />;
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
interface NonEmptyRowProps {
|
|
211
|
-
childPath: string;
|
|
212
|
-
schema: JsonSchema;
|
|
213
|
-
rowIndex: number;
|
|
214
|
-
showSortButtons: boolean;
|
|
215
|
-
enabled: boolean;
|
|
216
|
-
cells?: JsonFormsCellRendererRegistryEntry[];
|
|
217
|
-
path: string;
|
|
218
|
-
translations: ArrayTranslations;
|
|
219
|
-
uischema: ControlElement;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
const NonEmptyRowComponent = ({
|
|
223
|
-
childPath,
|
|
224
|
-
schema,
|
|
225
|
-
rowIndex,
|
|
226
|
-
openDeleteDialog,
|
|
227
|
-
enabled,
|
|
228
|
-
cells,
|
|
229
|
-
path,
|
|
230
|
-
translations,
|
|
231
|
-
uischema,
|
|
232
|
-
}: NonEmptyRowProps & WithDeleteDialogSupport) => {
|
|
233
|
-
return (
|
|
234
|
-
<div key={childPath}>
|
|
235
|
-
{enabled ? (
|
|
236
|
-
<GoAContainer>
|
|
237
|
-
<GoAGrid minChildWidth="30ch">
|
|
238
|
-
<GoAIconButton
|
|
239
|
-
icon="trash"
|
|
240
|
-
aria-label={translations.removeAriaLabel}
|
|
241
|
-
onClick={() => openDeleteDialog(childPath, rowIndex)}
|
|
242
|
-
></GoAIconButton>
|
|
243
|
-
</GoAGrid>
|
|
244
|
-
{GenerateRows(NonEmptyCell, schema, childPath, enabled, cells, uischema)}
|
|
245
|
-
</GoAContainer>
|
|
246
|
-
) : null}
|
|
247
|
-
</div>
|
|
248
|
-
);
|
|
249
|
-
};
|
|
250
|
-
export const NonEmptyList = React.memo(NonEmptyRowComponent);
|
|
251
|
-
interface TableRowsProp {
|
|
252
|
-
data: number;
|
|
253
|
-
path: string;
|
|
254
|
-
schema: JsonSchema;
|
|
255
|
-
uischema: ControlElement;
|
|
256
|
-
//eslint-disable-next-line
|
|
257
|
-
config?: any;
|
|
258
|
-
enabled: boolean;
|
|
259
|
-
cells?: JsonFormsCellRendererRegistryEntry[];
|
|
260
|
-
translations: ArrayTranslations;
|
|
261
|
-
}
|
|
262
|
-
const ObjectArrayList = ({
|
|
263
|
-
data,
|
|
264
|
-
path,
|
|
265
|
-
schema,
|
|
266
|
-
openDeleteDialog,
|
|
267
|
-
uischema,
|
|
268
|
-
config,
|
|
269
|
-
enabled,
|
|
270
|
-
cells,
|
|
271
|
-
translations,
|
|
272
|
-
}: TableRowsProp & WithDeleteDialogSupport) => {
|
|
273
|
-
const isEmptyList = data === 0;
|
|
274
|
-
|
|
275
|
-
if (isEmptyList) {
|
|
276
|
-
return <EmptyList numColumns={getValidColumnProps(schema).length + 1} translations={translations} />;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
const appliedUiSchemaOptions = merge({}, config, uischema.options);
|
|
280
|
-
|
|
281
|
-
return (
|
|
282
|
-
<>
|
|
283
|
-
{range(data).map((index: number) => {
|
|
284
|
-
const childPath = Paths.compose(path, `${index}`);
|
|
285
|
-
|
|
286
|
-
return (
|
|
287
|
-
<NonEmptyList
|
|
288
|
-
key={childPath}
|
|
289
|
-
childPath={childPath}
|
|
290
|
-
rowIndex={index}
|
|
291
|
-
schema={schema}
|
|
292
|
-
openDeleteDialog={openDeleteDialog}
|
|
293
|
-
showSortButtons={appliedUiSchemaOptions.showSortButtons || appliedUiSchemaOptions.showArrayTableSortButtons}
|
|
294
|
-
enabled={enabled}
|
|
295
|
-
cells={cells}
|
|
296
|
-
path={path}
|
|
297
|
-
uischema={uischema}
|
|
298
|
-
translations={translations}
|
|
299
|
-
/>
|
|
300
|
-
);
|
|
301
|
-
})}
|
|
302
|
-
</>
|
|
303
|
-
);
|
|
304
|
-
};
|
|
305
|
-
|
|
306
|
-
// eslint-disable-next-line
|
|
307
|
-
export class ObjectArrayControl extends React.Component<ArrayLayoutProps & WithDeleteDialogSupport, any> {
|
|
308
|
-
// eslint-disable-next-line
|
|
309
|
-
addItem = (path: string, value: any) => this.props.addItem(path, value);
|
|
310
|
-
render() {
|
|
311
|
-
const {
|
|
312
|
-
label,
|
|
313
|
-
path,
|
|
314
|
-
schema,
|
|
315
|
-
rootSchema,
|
|
316
|
-
uischema,
|
|
317
|
-
errors,
|
|
318
|
-
openDeleteDialog,
|
|
319
|
-
visible,
|
|
320
|
-
enabled,
|
|
321
|
-
cells,
|
|
322
|
-
translations,
|
|
323
|
-
data,
|
|
324
|
-
config,
|
|
325
|
-
...additionalProps
|
|
326
|
-
} = this.props;
|
|
327
|
-
|
|
328
|
-
const controlElement = uischema as ControlElement;
|
|
329
|
-
// eslint-disable-next-line
|
|
330
|
-
const listTitle = label || uischema.options?.title;
|
|
331
|
-
|
|
332
|
-
return (
|
|
333
|
-
<Hidden xsUp={!visible}>
|
|
334
|
-
<div>
|
|
335
|
-
<ToolBarHeader>
|
|
336
|
-
{listTitle && <ObjectArrayTitle>{listTitle}</ObjectArrayTitle>}
|
|
337
|
-
<ObjectArrayToolBar
|
|
338
|
-
errors={errors}
|
|
339
|
-
label={label}
|
|
340
|
-
addItem={this.addItem}
|
|
341
|
-
numColumns={0}
|
|
342
|
-
path={path}
|
|
343
|
-
uischema={controlElement}
|
|
344
|
-
schema={schema}
|
|
345
|
-
rootSchema={rootSchema}
|
|
346
|
-
enabled={enabled}
|
|
347
|
-
translations={translations}
|
|
348
|
-
/>
|
|
349
|
-
</ToolBarHeader>
|
|
350
|
-
<div>
|
|
351
|
-
<ObjectArrayList
|
|
352
|
-
path={path}
|
|
353
|
-
schema={schema}
|
|
354
|
-
uischema={uischema}
|
|
355
|
-
enabled={enabled}
|
|
356
|
-
openDeleteDialog={openDeleteDialog}
|
|
357
|
-
translations={translations}
|
|
358
|
-
data={data}
|
|
359
|
-
cells={cells}
|
|
360
|
-
config={config}
|
|
361
|
-
{...additionalProps}
|
|
362
|
-
/>
|
|
363
|
-
</div>
|
|
364
|
-
</div>
|
|
365
|
-
</Hidden>
|
|
366
|
-
);
|
|
367
|
-
}
|
|
368
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import styled from 'styled-components';
|
|
2
|
-
|
|
3
|
-
export const DeleteDialogContent = styled.div`
|
|
4
|
-
margin-bottom: 1rem;
|
|
5
|
-
`;
|
|
6
|
-
|
|
7
|
-
export const ToolBarHeader = styled.div`
|
|
8
|
-
margin-bottom: 1.5rem;
|
|
9
|
-
`;
|
|
10
|
-
|
|
11
|
-
export const ObjectArrayTitle = styled.h2`
|
|
12
|
-
margin-bottom: 1.5rem;
|
|
13
|
-
`;
|