@evoke-platform/ui-components 1.13.0-dev.7 → 1.14.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/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.d.ts +4 -4
- package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.js +72 -145
- package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.test.js +67 -189
- package/dist/published/components/custom/CriteriaBuilder/PropertyTree.d.ts +6 -6
- package/dist/published/components/custom/CriteriaBuilder/PropertyTree.js +25 -12
- package/dist/published/components/custom/CriteriaBuilder/PropertyTreeItem.d.ts +5 -4
- package/dist/published/components/custom/CriteriaBuilder/PropertyTreeItem.js +22 -34
- package/dist/published/components/custom/CriteriaBuilder/types.d.ts +11 -2
- package/dist/published/components/custom/CriteriaBuilder/utils.d.ts +34 -6
- package/dist/published/components/custom/CriteriaBuilder/utils.js +89 -18
- package/dist/published/components/custom/Form/FormComponents/DocumentComponent/Document.js +1 -1
- package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentList.js +3 -6
- package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/RepeatableField.js +1 -1
- package/dist/published/components/custom/Form/utils.d.ts +0 -1
- package/dist/published/components/custom/FormField/DateTimePickerSelect/DateTimePickerSelect.js +1 -2
- package/dist/published/components/custom/FormV2/FormRenderer.d.ts +2 -2
- package/dist/published/components/custom/FormV2/FormRenderer.js +29 -26
- package/dist/published/components/custom/FormV2/FormRendererContainer.d.ts +3 -1
- package/dist/published/components/custom/FormV2/FormRendererContainer.js +88 -95
- package/dist/published/components/custom/FormV2/components/Body.js +1 -1
- package/dist/published/components/custom/FormV2/components/Footer.js +1 -1
- package/dist/published/components/custom/FormV2/components/FormContext.d.ts +0 -1
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/ActionDialog.d.ts +0 -1
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/DropdownRepeatableField.js +143 -86
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/DropdownRepeatableFieldInput.d.ts +2 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/DropdownRepeatableFieldInput.js +4 -1
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/RepeatableField.js +186 -106
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/Criteria.js +49 -36
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/Document.d.ts +2 -3
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/Document.js +32 -51
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/DocumentList.d.ts +3 -4
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/DocumentList.js +38 -40
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/UserProperty.js +21 -17
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/relatedObjectFiles/InstanceLookup.js +1 -1
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/relatedObjectFiles/ObjectPropertyInput.js +169 -95
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/relatedObjectFiles/RelatedObjectInstance.d.ts +2 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/relatedObjectFiles/RelatedObjectInstance.js +6 -12
- package/dist/published/components/custom/FormV2/components/FormSections.js +0 -1
- package/dist/published/components/custom/FormV2/components/Header.d.ts +1 -0
- package/dist/published/components/custom/FormV2/components/Header.js +19 -8
- package/dist/published/components/custom/FormV2/components/HtmlView.d.ts +9 -0
- package/dist/published/components/custom/FormV2/components/HtmlView.js +46 -0
- package/dist/published/components/custom/FormV2/components/RecursiveEntryRenderer.d.ts +1 -2
- package/dist/published/components/custom/FormV2/components/RecursiveEntryRenderer.js +20 -46
- package/dist/published/components/custom/FormV2/components/types.d.ts +1 -6
- package/dist/published/components/custom/FormV2/components/utils.d.ts +11 -11
- package/dist/published/components/custom/FormV2/components/utils.js +104 -181
- package/dist/published/components/custom/FormV2/tests/FormRenderer.test.js +17 -50
- package/dist/published/components/custom/FormV2/tests/FormRendererContainer.test.js +131 -40
- package/dist/published/components/custom/HistoryLog/HistoryData.js +1 -2
- package/dist/published/components/custom/HistoryLog/index.js +1 -2
- package/dist/published/components/custom/ViewDetailsV2/InstanceEntryRenderer.d.ts +1 -2
- package/dist/published/components/custom/ViewDetailsV2/InstanceEntryRenderer.js +22 -61
- package/dist/published/components/custom/ViewDetailsV2/ViewDetailsV2Container.d.ts +3 -0
- package/dist/published/components/custom/ViewDetailsV2/ViewDetailsV2Container.js +5 -8
- package/dist/published/stories/Backdrop.stories.d.ts +2 -2
- package/dist/published/stories/CriteriaBuilder.stories.js +22 -70
- package/dist/published/stories/FormLabel.stories.d.ts +2 -2
- package/dist/published/stories/FormRenderer.stories.d.ts +3 -3
- package/dist/published/stories/FormRendererContainer.stories.d.ts +15 -5
- package/dist/published/stories/ViewDetailsV2Container.stories.d.ts +9 -0
- package/dist/published/theme/hooks.d.ts +1 -2
- package/package.json +11 -17
- package/dist/published/components/custom/FormV2/components/ConditionalQueryClientProvider.d.ts +0 -5
- package/dist/published/components/custom/FormV2/components/ConditionalQueryClientProvider.js +0 -21
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
2
1
|
import { render as baseRender, screen, waitFor, within } from '@testing-library/react';
|
|
3
2
|
import userEvent from '@testing-library/user-event';
|
|
4
3
|
import { isEmpty, isEqual, set } from 'lodash';
|
|
@@ -15,9 +14,12 @@ global.ResizeObserver = class ResizeObserver {
|
|
|
15
14
|
unobserve() { }
|
|
16
15
|
disconnect() { }
|
|
17
16
|
};
|
|
17
|
+
const WithProviders = ({ children }) => {
|
|
18
|
+
return React.createElement(MemoryRouter, null, children);
|
|
19
|
+
};
|
|
20
|
+
const render = (ui, options) => baseRender(ui, { wrapper: WithProviders, ...options });
|
|
18
21
|
describe('FormRenderer', () => {
|
|
19
22
|
let server;
|
|
20
|
-
let queryClient;
|
|
21
23
|
beforeAll(() => {
|
|
22
24
|
server = setupServer(http.get('/api/data/objects/specialtyType/effective', () => HttpResponse.json(specialtyTypeObject)), http.get('/api/data/objects/specialtyType/effective', (req) => {
|
|
23
25
|
const sanitizedVersion = new URL(req.request.url).searchParams.get('sanitizedVersion');
|
|
@@ -63,28 +65,12 @@ describe('FormRenderer', () => {
|
|
|
63
65
|
}), http.get('/api/accessManagement/users', () => HttpResponse.json(users)));
|
|
64
66
|
server.listen();
|
|
65
67
|
});
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
queryClient = new QueryClient({
|
|
69
|
-
defaultOptions: {
|
|
70
|
-
queries: {
|
|
71
|
-
retry: false,
|
|
72
|
-
},
|
|
73
|
-
},
|
|
74
|
-
});
|
|
68
|
+
afterAll(() => {
|
|
69
|
+
server.close();
|
|
75
70
|
});
|
|
76
71
|
afterEach(() => {
|
|
77
72
|
server.resetHandlers();
|
|
78
|
-
queryClient.clear();
|
|
79
73
|
});
|
|
80
|
-
afterEach(() => {
|
|
81
|
-
server.resetHandlers();
|
|
82
|
-
});
|
|
83
|
-
const WithProviders = ({ children }) => {
|
|
84
|
-
return (React.createElement(QueryClientProvider, { client: queryClient },
|
|
85
|
-
React.createElement(MemoryRouter, null, children)));
|
|
86
|
-
};
|
|
87
|
-
const render = (ui, options) => baseRender(ui, { wrapper: WithProviders, ...options });
|
|
88
74
|
describe('validation criteria', () => {
|
|
89
75
|
it(`filters related object field with validation criteria that references a related object's nested data`, async () => {
|
|
90
76
|
const user = userEvent.setup();
|
|
@@ -428,7 +414,7 @@ describe('FormRenderer', () => {
|
|
|
428
414
|
type: 'input',
|
|
429
415
|
parameterId: 'specialtyType',
|
|
430
416
|
display: {
|
|
431
|
-
label: '
|
|
417
|
+
label: 'Speciality Type',
|
|
432
418
|
mode: 'existingOnly',
|
|
433
419
|
},
|
|
434
420
|
},
|
|
@@ -514,7 +500,7 @@ describe('FormRenderer', () => {
|
|
|
514
500
|
type: 'input',
|
|
515
501
|
parameterId: 'specialtyType',
|
|
516
502
|
display: {
|
|
517
|
-
label: '
|
|
503
|
+
label: 'Speciality Type',
|
|
518
504
|
},
|
|
519
505
|
},
|
|
520
506
|
],
|
|
@@ -600,7 +586,7 @@ describe('FormRenderer', () => {
|
|
|
600
586
|
type: 'input',
|
|
601
587
|
parameterId: 'specialtyType',
|
|
602
588
|
display: {
|
|
603
|
-
label: '
|
|
589
|
+
label: 'Speciality Type',
|
|
604
590
|
relatedObjectDisplay: 'dialogBox',
|
|
605
591
|
mode: 'existingOnly',
|
|
606
592
|
},
|
|
@@ -668,7 +654,7 @@ describe('FormRenderer', () => {
|
|
|
668
654
|
type: 'input',
|
|
669
655
|
parameterId: 'specialtyType',
|
|
670
656
|
display: {
|
|
671
|
-
label: '
|
|
657
|
+
label: 'Speciality Type',
|
|
672
658
|
relatedObjectDisplay: 'dialogBox',
|
|
673
659
|
mode: 'existingOnly',
|
|
674
660
|
},
|
|
@@ -698,7 +684,7 @@ describe('FormRenderer', () => {
|
|
|
698
684
|
type: 'input',
|
|
699
685
|
parameterId: 'specialtyType',
|
|
700
686
|
display: {
|
|
701
|
-
label: '
|
|
687
|
+
label: 'Speciality Type',
|
|
702
688
|
createActionId: '_create',
|
|
703
689
|
},
|
|
704
690
|
},
|
|
@@ -958,7 +944,7 @@ describe('FormRenderer', () => {
|
|
|
958
944
|
type: 'input',
|
|
959
945
|
parameterId: 'specialtyType',
|
|
960
946
|
display: {
|
|
961
|
-
label: '
|
|
947
|
+
label: 'Speciality Type',
|
|
962
948
|
relatedObjectDisplay: 'dropdown',
|
|
963
949
|
mode: 'existingOnly',
|
|
964
950
|
},
|
|
@@ -1035,7 +1021,7 @@ describe('FormRenderer', () => {
|
|
|
1035
1021
|
const user = userEvent.setup();
|
|
1036
1022
|
render(React.createElement(FormRenderer, { form: form, onChange: () => { } }));
|
|
1037
1023
|
// Navigate to and open dropdown
|
|
1038
|
-
const dropdown = await screen.findByRole('combobox', { name: '
|
|
1024
|
+
const dropdown = await screen.findByRole('combobox', { name: 'Speciality Type' });
|
|
1039
1025
|
await user.click(dropdown);
|
|
1040
1026
|
await screen.findByRole('listbox');
|
|
1041
1027
|
// Verify that the existing option is present
|
|
@@ -1190,7 +1176,7 @@ describe('FormRenderer', () => {
|
|
|
1190
1176
|
type: 'input',
|
|
1191
1177
|
parameterId: 'specialtyType',
|
|
1192
1178
|
display: {
|
|
1193
|
-
label: '
|
|
1179
|
+
label: 'Speciality Type',
|
|
1194
1180
|
createActionId: '_create',
|
|
1195
1181
|
relatedObjectId: 'specialtyType',
|
|
1196
1182
|
},
|
|
@@ -1497,7 +1483,7 @@ describe('FormRenderer', () => {
|
|
|
1497
1483
|
await user.click(addButton);
|
|
1498
1484
|
await screen.findByRole('dialog');
|
|
1499
1485
|
// Make sure other form entry is present
|
|
1500
|
-
await screen.findByRole('textbox', { name:
|
|
1486
|
+
await screen.findByRole('textbox', { name: /Name */i });
|
|
1501
1487
|
const relatedObjectField = screen.queryByRole('textbox', { name: 'Related Object' });
|
|
1502
1488
|
expect(relatedObjectField).not.toBeInTheDocument();
|
|
1503
1489
|
});
|
|
@@ -1511,31 +1497,12 @@ describe('FormRenderer', () => {
|
|
|
1511
1497
|
id: 'testInstanceId',
|
|
1512
1498
|
name: 'Test Instance',
|
|
1513
1499
|
},
|
|
1514
|
-
}))
|
|
1515
|
-
// This is called by refetchRelatedInstances() after successful POST
|
|
1516
|
-
http.get('/api/data/objects/collectionObject/instances', (req) => {
|
|
1517
|
-
const filter = new URL(req.request.url).searchParams.get('filter');
|
|
1518
|
-
if (filter) {
|
|
1519
|
-
// Return the newly created item when refetching
|
|
1520
|
-
return HttpResponse.json([
|
|
1521
|
-
{
|
|
1522
|
-
id: 'newCollectionItemId',
|
|
1523
|
-
name: 'New Collection Item',
|
|
1524
|
-
objectId: 'collectionObject',
|
|
1525
|
-
relatedObject: {
|
|
1526
|
-
id: 'testInstanceId',
|
|
1527
|
-
name: 'Test Instance',
|
|
1528
|
-
},
|
|
1529
|
-
},
|
|
1530
|
-
]);
|
|
1531
|
-
}
|
|
1532
|
-
return HttpResponse.json([]);
|
|
1533
|
-
}));
|
|
1500
|
+
})));
|
|
1534
1501
|
render(React.createElement(FormRenderer, { form: form, onChange: () => { } }));
|
|
1535
1502
|
const addButton = await screen.findByRole('button', { name: /add/i });
|
|
1536
1503
|
await user.click(addButton);
|
|
1537
1504
|
await screen.findByRole('dialog');
|
|
1538
|
-
const nameField = await screen.findByRole('textbox', { name:
|
|
1505
|
+
const nameField = await screen.findByRole('textbox', { name: /Name */ });
|
|
1539
1506
|
await user.type(nameField, 'New Collection Item');
|
|
1540
1507
|
const submitButton = screen.getByRole('button', { name: 'Create Collection Item' });
|
|
1541
1508
|
await user.click(submitButton);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { QueryCache, QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
2
1
|
import { render as baseRender, screen, waitFor, within } from '@testing-library/react';
|
|
3
2
|
import userEvent from '@testing-library/user-event';
|
|
4
3
|
import { isEqual } from 'lodash';
|
|
@@ -15,9 +14,12 @@ global.ResizeObserver = class ResizeObserver {
|
|
|
15
14
|
unobserve() { }
|
|
16
15
|
disconnect() { }
|
|
17
16
|
};
|
|
17
|
+
const WithProviders = ({ children }) => {
|
|
18
|
+
return React.createElement(MemoryRouter, null, children);
|
|
19
|
+
};
|
|
20
|
+
const render = (ui, options) => baseRender(ui, { wrapper: WithProviders, ...options });
|
|
18
21
|
describe('FormRendererContainer', () => {
|
|
19
22
|
let server;
|
|
20
|
-
let queryClient;
|
|
21
23
|
beforeAll(() => {
|
|
22
24
|
server = setupServer(http.get('/api/data/objects/specialtyType/effective', () => HttpResponse.json(specialtyTypeObject)), http.get('/api/data/objects/specialtyType/effective', (req) => {
|
|
23
25
|
const sanitizedVersion = new URL(req.request.url).searchParams.get('sanitizedVersion');
|
|
@@ -43,7 +45,7 @@ describe('FormRendererContainer', () => {
|
|
|
43
45
|
// The two objects in the array of conditions in the "where" filter represent the potential filters that can be applied when retrieving "specialty" instances.
|
|
44
46
|
// The first object is for the the validation criteria, but it is empty if the "license" field, which is referenced in the validation criteria, hasn't been filled out yet.
|
|
45
47
|
// The second object is for the search criteria which the user enters in the "specialty" field, but it is empty if no search text has been entered.
|
|
46
|
-
if (isEqual(whereFilter, {}))
|
|
48
|
+
if (isEqual(whereFilter, { and: [{}, {}] }))
|
|
47
49
|
return HttpResponse.json([
|
|
48
50
|
rnSpecialtyType1,
|
|
49
51
|
rnSpecialtyType2,
|
|
@@ -59,35 +61,12 @@ describe('FormRendererContainer', () => {
|
|
|
59
61
|
}));
|
|
60
62
|
server.listen();
|
|
61
63
|
});
|
|
62
|
-
beforeEach(() => {
|
|
63
|
-
// Create a fresh QueryClient for each test, need to pass `retry: false` to avoid retries interfering with error state tests
|
|
64
|
-
queryClient = new QueryClient({
|
|
65
|
-
queryCache: new QueryCache({
|
|
66
|
-
onError: (error, query) => {
|
|
67
|
-
const message = query.meta?.errorMessage ?? 'Something went wrong:';
|
|
68
|
-
console.error(message, error);
|
|
69
|
-
},
|
|
70
|
-
}),
|
|
71
|
-
defaultOptions: {
|
|
72
|
-
queries: {
|
|
73
|
-
retry: false,
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
64
|
afterAll(() => {
|
|
79
65
|
server.close();
|
|
80
|
-
queryClient.clear();
|
|
81
66
|
});
|
|
82
67
|
afterEach(() => {
|
|
83
68
|
server.resetHandlers();
|
|
84
|
-
queryClient.clear();
|
|
85
69
|
});
|
|
86
|
-
const WithProviders = ({ children }) => {
|
|
87
|
-
return (React.createElement(QueryClientProvider, { client: queryClient },
|
|
88
|
-
React.createElement(MemoryRouter, null, children)));
|
|
89
|
-
};
|
|
90
|
-
const render = (ui, options) => baseRender(ui, { wrapper: WithProviders, ...options });
|
|
91
70
|
describe('validation criteria', () => {
|
|
92
71
|
it(`filters related object field with validation criteria that references a defaulted related object's nested data`, async () => {
|
|
93
72
|
const user = userEvent.setup();
|
|
@@ -144,6 +123,9 @@ describe('FormRendererContainer', () => {
|
|
|
144
123
|
});
|
|
145
124
|
}));
|
|
146
125
|
render(React.createElement(FormRendererContainer, { objectId: 'specialty', formId: 'specialtyForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-instance' }));
|
|
126
|
+
await waitFor(() => {
|
|
127
|
+
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
|
|
128
|
+
});
|
|
147
129
|
const nameField = await screen.findByRole('textbox', { name: 'Name' });
|
|
148
130
|
// Clear the existing value and type new value
|
|
149
131
|
await user.clear(nameField);
|
|
@@ -191,6 +173,9 @@ describe('FormRendererContainer', () => {
|
|
|
191
173
|
});
|
|
192
174
|
}));
|
|
193
175
|
render(React.createElement(FormRendererContainer, { objectId: 'specialty', formId: 'specialtyForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-instance' }));
|
|
176
|
+
await waitFor(() => {
|
|
177
|
+
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
|
|
178
|
+
});
|
|
194
179
|
const nameField = await screen.findByRole('textbox', { name: 'Name' });
|
|
195
180
|
await user.type(nameField, 'Test Specialty');
|
|
196
181
|
await user.tab();
|
|
@@ -235,6 +220,9 @@ describe('FormRendererContainer', () => {
|
|
|
235
220
|
return HttpResponse.json({ error: 'Save failed' }, { status: 500 });
|
|
236
221
|
}));
|
|
237
222
|
render(React.createElement(FormRendererContainer, { objectId: 'specialty', formId: 'specialtyForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-instance' }));
|
|
223
|
+
await waitFor(() => {
|
|
224
|
+
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
|
|
225
|
+
});
|
|
238
226
|
const nameField = await screen.findByRole('textbox', { name: 'Name' });
|
|
239
227
|
await user.type(nameField, 'Test Specialty');
|
|
240
228
|
await user.tab();
|
|
@@ -276,6 +264,9 @@ describe('FormRendererContainer', () => {
|
|
|
276
264
|
});
|
|
277
265
|
}));
|
|
278
266
|
render(React.createElement(FormRendererContainer, { objectId: 'specialty', formId: 'specialtyForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-instance' }));
|
|
267
|
+
await waitFor(() => {
|
|
268
|
+
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
|
|
269
|
+
});
|
|
279
270
|
const nameField = await screen.findByRole('textbox', { name: 'Name' });
|
|
280
271
|
// Click into the field and blur it without changing value
|
|
281
272
|
await user.click(nameField);
|
|
@@ -326,6 +317,9 @@ describe('FormRendererContainer', () => {
|
|
|
326
317
|
});
|
|
327
318
|
}));
|
|
328
319
|
render(React.createElement(FormRendererContainer, { objectId: 'license', formId: 'licenseForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-license' }));
|
|
320
|
+
await waitFor(() => {
|
|
321
|
+
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
|
|
322
|
+
});
|
|
329
323
|
// Find the city field
|
|
330
324
|
const cityField = await screen.findByRole('textbox', { name: 'City' });
|
|
331
325
|
// Clear and type new value
|
|
@@ -378,6 +372,9 @@ describe('FormRendererContainer', () => {
|
|
|
378
372
|
});
|
|
379
373
|
}));
|
|
380
374
|
render(React.createElement(FormRendererContainer, { objectId: 'license', formId: 'licenseForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-license' }));
|
|
375
|
+
await waitFor(() => {
|
|
376
|
+
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
|
|
377
|
+
});
|
|
381
378
|
// Find the city field
|
|
382
379
|
const cityField = await screen.findByRole('textbox', { name: 'City' });
|
|
383
380
|
// Click into field and blur without changing
|
|
@@ -436,6 +433,9 @@ describe('FormRendererContainer', () => {
|
|
|
436
433
|
});
|
|
437
434
|
}));
|
|
438
435
|
render(React.createElement(FormRendererContainer, { objectId: 'license', formId: 'licenseForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-license' }));
|
|
436
|
+
await waitFor(() => {
|
|
437
|
+
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
|
|
438
|
+
});
|
|
439
439
|
// Find the line1 field (it's a searchbox because of address autocomplete)
|
|
440
440
|
const line1Field = await screen.findByRole('searchbox', { name: 'Address Line 1' });
|
|
441
441
|
// Type to trigger autocomplete
|
|
@@ -472,7 +472,9 @@ describe('FormRendererContainer', () => {
|
|
|
472
472
|
});
|
|
473
473
|
}));
|
|
474
474
|
render(React.createElement(FormRendererContainer, { objectId: 'specialty', formId: 'specialtyForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-instance' }));
|
|
475
|
-
await
|
|
475
|
+
await waitFor(() => {
|
|
476
|
+
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
|
|
477
|
+
});
|
|
476
478
|
// When autosaveActionId is present the discard button should be hidden
|
|
477
479
|
expect(screen.queryByRole('button', { name: /discard/i })).not.toBeInTheDocument();
|
|
478
480
|
});
|
|
@@ -503,7 +505,11 @@ describe('FormRendererContainer', () => {
|
|
|
503
505
|
}));
|
|
504
506
|
const user = userEvent.setup();
|
|
505
507
|
render(React.createElement(FormRendererContainer, { objectId: 'specialty', formId: 'specialtyForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-instance' }));
|
|
506
|
-
|
|
508
|
+
await waitFor(() => {
|
|
509
|
+
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
|
|
510
|
+
});
|
|
511
|
+
// Change a field value
|
|
512
|
+
const nameInput = screen.getByRole('textbox', { name: /name/i });
|
|
507
513
|
await user.clear(nameInput);
|
|
508
514
|
await user.type(nameInput, 'Test Specialty');
|
|
509
515
|
await user.tab();
|
|
@@ -991,6 +997,90 @@ describe('FormRendererContainer', () => {
|
|
|
991
997
|
});
|
|
992
998
|
});
|
|
993
999
|
});
|
|
1000
|
+
it('should display title by default', async () => {
|
|
1001
|
+
const form = {
|
|
1002
|
+
id: 'simpleForm',
|
|
1003
|
+
name: 'Simple Form',
|
|
1004
|
+
entries: [],
|
|
1005
|
+
actionId: '_create',
|
|
1006
|
+
objectId: 'simpleObject',
|
|
1007
|
+
};
|
|
1008
|
+
const simpleObject = {
|
|
1009
|
+
id: 'simpleObject',
|
|
1010
|
+
name: 'Simple Object',
|
|
1011
|
+
actions: [
|
|
1012
|
+
{
|
|
1013
|
+
id: '_create',
|
|
1014
|
+
name: 'Create',
|
|
1015
|
+
type: 'create',
|
|
1016
|
+
parameters: [],
|
|
1017
|
+
outputEvent: 'created',
|
|
1018
|
+
},
|
|
1019
|
+
],
|
|
1020
|
+
properties: [],
|
|
1021
|
+
};
|
|
1022
|
+
server.use(http.get(`/api/data/objects/${simpleObject.id}/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/${form.id}`, () => HttpResponse.json(form)));
|
|
1023
|
+
render(React.createElement(FormRendererContainer, { objectId: simpleObject.id, formId: form.id, dataType: "objectInstances" }));
|
|
1024
|
+
await screen.findByText('Simple Form');
|
|
1025
|
+
});
|
|
1026
|
+
it('should display title', async () => {
|
|
1027
|
+
const form = {
|
|
1028
|
+
id: 'simpleForm',
|
|
1029
|
+
name: 'Simple Form',
|
|
1030
|
+
entries: [],
|
|
1031
|
+
actionId: '_create',
|
|
1032
|
+
objectId: 'simpleObject',
|
|
1033
|
+
};
|
|
1034
|
+
const simpleObject = {
|
|
1035
|
+
id: 'simpleObject',
|
|
1036
|
+
name: 'Simple Object',
|
|
1037
|
+
actions: [
|
|
1038
|
+
{
|
|
1039
|
+
id: '_create',
|
|
1040
|
+
name: 'Create',
|
|
1041
|
+
type: 'create',
|
|
1042
|
+
parameters: [],
|
|
1043
|
+
outputEvent: 'created',
|
|
1044
|
+
},
|
|
1045
|
+
],
|
|
1046
|
+
properties: [],
|
|
1047
|
+
};
|
|
1048
|
+
server.use(http.get(`/api/data/objects/${simpleObject.id}/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/${form.id}`, () => HttpResponse.json(form)));
|
|
1049
|
+
render(React.createElement(FormRendererContainer, { objectId: simpleObject.id, formId: form.id, title: {
|
|
1050
|
+
hidden: false,
|
|
1051
|
+
}, dataType: "objectInstances" }));
|
|
1052
|
+
await screen.findByText('Simple Form');
|
|
1053
|
+
});
|
|
1054
|
+
it('should not display title', async () => {
|
|
1055
|
+
const form = {
|
|
1056
|
+
id: 'simpleForm',
|
|
1057
|
+
name: 'Simple Form',
|
|
1058
|
+
entries: [],
|
|
1059
|
+
actionId: '_create',
|
|
1060
|
+
objectId: 'simpleObject',
|
|
1061
|
+
};
|
|
1062
|
+
const simpleObject = {
|
|
1063
|
+
id: 'simpleObject',
|
|
1064
|
+
name: 'Simple Object',
|
|
1065
|
+
actions: [
|
|
1066
|
+
{
|
|
1067
|
+
id: '_create',
|
|
1068
|
+
name: 'Create',
|
|
1069
|
+
type: 'create',
|
|
1070
|
+
parameters: [],
|
|
1071
|
+
outputEvent: 'created',
|
|
1072
|
+
},
|
|
1073
|
+
],
|
|
1074
|
+
properties: [],
|
|
1075
|
+
};
|
|
1076
|
+
server.use(http.get(`/api/data/objects/${simpleObject.id}/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/${form.id}`, () => HttpResponse.json(form)));
|
|
1077
|
+
render(React.createElement(FormRendererContainer, { objectId: simpleObject.id, formId: form.id, title: {
|
|
1078
|
+
hidden: true,
|
|
1079
|
+
}, dataType: "objectInstances" }));
|
|
1080
|
+
await waitFor(() => {
|
|
1081
|
+
expect(screen.queryByText('Simple Form')).not.toBeInTheDocument();
|
|
1082
|
+
});
|
|
1083
|
+
});
|
|
994
1084
|
it('should display a submit button', async () => {
|
|
995
1085
|
const form = {
|
|
996
1086
|
id: 'simpleForm',
|
|
@@ -1014,7 +1104,7 @@ describe('FormRendererContainer', () => {
|
|
|
1014
1104
|
properties: [],
|
|
1015
1105
|
};
|
|
1016
1106
|
server.use(http.get(`/api/data/objects/${simpleObject.id}/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/${form.id}`, () => HttpResponse.json(form)));
|
|
1017
|
-
render(React.createElement(FormRendererContainer, { objectId: simpleObject.id, formId: form.id,
|
|
1107
|
+
render(React.createElement(FormRendererContainer, { objectId: simpleObject.id, formId: form.id, dataType: "objectInstances" }));
|
|
1018
1108
|
await screen.findByRole('button', { name: 'Submit' });
|
|
1019
1109
|
});
|
|
1020
1110
|
it('should display a button to discard changes', async () => {
|
|
@@ -1040,7 +1130,7 @@ describe('FormRendererContainer', () => {
|
|
|
1040
1130
|
properties: [],
|
|
1041
1131
|
};
|
|
1042
1132
|
server.use(http.get(`/api/data/objects/${simpleObject.id}/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/${form.id}`, () => HttpResponse.json(form)));
|
|
1043
|
-
render(React.createElement(FormRendererContainer, { objectId: simpleObject.id, formId: form.id,
|
|
1133
|
+
render(React.createElement(FormRendererContainer, { objectId: simpleObject.id, formId: form.id, dataType: "objectInstances" }));
|
|
1044
1134
|
await screen.findByRole('button', { name: 'Discard Changes' });
|
|
1045
1135
|
});
|
|
1046
1136
|
it('should reset the form when discarding changes', async () => {
|
|
@@ -1083,7 +1173,7 @@ describe('FormRendererContainer', () => {
|
|
|
1083
1173
|
};
|
|
1084
1174
|
server.use(http.get(`/api/data/objects/${simpleObject.id}/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/${form.id}`, () => HttpResponse.json(form)));
|
|
1085
1175
|
const user = userEvent.setup();
|
|
1086
|
-
render(React.createElement(FormRendererContainer, { objectId: simpleObject.id, formId: form.id,
|
|
1176
|
+
render(React.createElement(FormRendererContainer, { objectId: simpleObject.id, formId: form.id, dataType: "objectInstances" }));
|
|
1087
1177
|
const firstNameInput = await screen.findByRole('textbox', { name: 'First Name' });
|
|
1088
1178
|
await user.type(firstNameInput, 'John');
|
|
1089
1179
|
const discardButton = await screen.findByRole('button', { name: 'Discard Changes' });
|
|
@@ -1137,8 +1227,10 @@ describe('FormRendererContainer', () => {
|
|
|
1137
1227
|
};
|
|
1138
1228
|
server.use(http.get(`/api/data/objects/simpleObject/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/simpleForm`, () => HttpResponse.json(form)), http.get('/api/data/objects/simpleObject/instances/123', () => HttpResponse.json({
|
|
1139
1229
|
message: 'Not Found',
|
|
1140
|
-
}, { status: 404 })), http.get('/api/data/objects/simpleObject/instances/123/object', () => HttpResponse.json(
|
|
1141
|
-
|
|
1230
|
+
}, { status: 404 })), http.get('/api/data/objects/simpleObject/instances/123/object', () => HttpResponse.json({
|
|
1231
|
+
message: 'Not Found',
|
|
1232
|
+
}, { status: 404 })));
|
|
1233
|
+
render(React.createElement(FormRendererContainer, { formId: form.id, actionId: "_update", objectId: "simpleObject", instanceId: '123', dataType: "objectInstances" }));
|
|
1142
1234
|
await screen.findByText('The requested content could not be found.');
|
|
1143
1235
|
});
|
|
1144
1236
|
it('should show an unauthorized error if the instance access is unauthorized', async () => {
|
|
@@ -1235,7 +1327,7 @@ describe('FormRendererContainer', () => {
|
|
|
1235
1327
|
properties: [],
|
|
1236
1328
|
};
|
|
1237
1329
|
server.use(http.get(`/api/data/objects/simpleObject/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/simpleForm`, () => HttpResponse.json(form)));
|
|
1238
|
-
render(React.createElement(FormRendererContainer, { formId: form.id, objectId: "simpleObject",
|
|
1330
|
+
render(React.createElement(FormRendererContainer, { formId: form.id, objectId: "simpleObject", dataType: "objectInstances" }));
|
|
1239
1331
|
await screen.findByText('Simple Form');
|
|
1240
1332
|
});
|
|
1241
1333
|
it('should show a not found error when the form cannot be found', async () => {
|
|
@@ -1466,7 +1558,7 @@ describe('FormRendererContainer', () => {
|
|
|
1466
1558
|
});
|
|
1467
1559
|
it('should display validation errors after trying to submit the form', async () => {
|
|
1468
1560
|
const user = userEvent.setup();
|
|
1469
|
-
render(React.createElement(FormRendererContainer, { objectId: validationTestObject.id, formId: form.id,
|
|
1561
|
+
render(React.createElement(FormRendererContainer, { objectId: validationTestObject.id, formId: form.id, dataType: "objectInstances" }));
|
|
1470
1562
|
const submitButton = await screen.findByRole('button', { name: 'Submit' });
|
|
1471
1563
|
await user.click(submitButton);
|
|
1472
1564
|
// List items are named by author, but they don't
|
|
@@ -1477,7 +1569,7 @@ describe('FormRendererContainer', () => {
|
|
|
1477
1569
|
});
|
|
1478
1570
|
it('should clear validation errors after they have been resolved', async () => {
|
|
1479
1571
|
const user = userEvent.setup();
|
|
1480
|
-
render(React.createElement(FormRendererContainer, { objectId: validationTestObject.id, formId: form.id,
|
|
1572
|
+
render(React.createElement(FormRendererContainer, { objectId: validationTestObject.id, formId: form.id, dataType: "objectInstances" }));
|
|
1481
1573
|
const submitButton = await screen.findByRole('button', { name: 'Submit' });
|
|
1482
1574
|
await user.click(submitButton);
|
|
1483
1575
|
// Make sure error elements appear
|
|
@@ -1488,7 +1580,7 @@ describe('FormRendererContainer', () => {
|
|
|
1488
1580
|
});
|
|
1489
1581
|
it('should scroll to validation errors after submission', async () => {
|
|
1490
1582
|
const user = userEvent.setup();
|
|
1491
|
-
render(React.createElement(FormRendererContainer, { objectId: validationTestObject.id, formId: form.id,
|
|
1583
|
+
render(React.createElement(FormRendererContainer, { objectId: validationTestObject.id, formId: form.id, dataType: "objectInstances" }));
|
|
1492
1584
|
const submitButton = await screen.findByRole('button', { name: 'Submit' });
|
|
1493
1585
|
await user.click(submitButton);
|
|
1494
1586
|
expect(scrollIntoViewMock).toHaveBeenCalled();
|
|
@@ -1496,7 +1588,7 @@ describe('FormRendererContainer', () => {
|
|
|
1496
1588
|
it('should not scroll to validation errors after submission if there are none', async () => {
|
|
1497
1589
|
const user = userEvent.setup();
|
|
1498
1590
|
server.use(http.post(`/api/data/objects/${validationTestObject.id}/instances/actions`, () => HttpResponse.json({}, { status: 200 })));
|
|
1499
|
-
render(React.createElement(FormRendererContainer, { objectId: validationTestObject.id, formId: form.id,
|
|
1591
|
+
render(React.createElement(FormRendererContainer, { objectId: validationTestObject.id, formId: form.id, dataType: "objectInstances" }));
|
|
1500
1592
|
const requiredField = await screen.findByRole('textbox', { name: /Required Field */i });
|
|
1501
1593
|
await user.type(requiredField, 'Some content here...');
|
|
1502
1594
|
const submitButton = await screen.findByRole('button', { name: 'Submit' });
|
|
@@ -1519,8 +1611,7 @@ describe('FormRendererContainer', () => {
|
|
|
1519
1611
|
// Wait for the delete confirmation message to appear
|
|
1520
1612
|
const confirmation = await screen.findByText(/you are about to delete/i);
|
|
1521
1613
|
expect(confirmation).toBeInTheDocument();
|
|
1522
|
-
|
|
1523
|
-
expect(confirmation).toHaveTextContent(/Persons Name/);
|
|
1614
|
+
await screen.findByText(/Persons Name/);
|
|
1524
1615
|
// Ensure the "Delete" button is rendered
|
|
1525
1616
|
await screen.findByRole('button', { name: /delete/i });
|
|
1526
1617
|
});
|
|
@@ -6,8 +6,7 @@ import React from 'react';
|
|
|
6
6
|
import { Typography } from '../../core';
|
|
7
7
|
import { Box, Grid } from '../../layout';
|
|
8
8
|
import DisplayedProperty from './DisplayedProperty';
|
|
9
|
-
|
|
10
|
-
const { format } = require('small-date');
|
|
9
|
+
import { format } from 'small-date';
|
|
11
10
|
export const nanoid = customAlphabet(uppercase + lowercase);
|
|
12
11
|
const styles = {
|
|
13
12
|
timelineHeader: {
|
|
@@ -9,8 +9,7 @@ import Box from '../../layout/Box';
|
|
|
9
9
|
import HistoryFilter from './Filter';
|
|
10
10
|
import HistoricalData from './HistoryData';
|
|
11
11
|
import HistoryLoading from './HistoryLoading';
|
|
12
|
-
|
|
13
|
-
const { format } = require('small-date');
|
|
12
|
+
import { format } from 'small-date';
|
|
14
13
|
/**
|
|
15
14
|
* Renders a timeline of the instance's history log.
|
|
16
15
|
* Users can filter the history by type and sort by date.
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import { EntryRendererProps } from '../FormV2/components/types';
|
|
3
|
-
declare function ViewOnlyEntryRenderer(props: EntryRendererProps):
|
|
2
|
+
declare function ViewOnlyEntryRenderer(props: EntryRendererProps): any;
|
|
4
3
|
export default ViewOnlyEntryRenderer;
|