@evoke-platform/ui-components 1.16.0 → 1.18.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.js +3 -0
- package/dist/published/components/custom/Form/utils.d.ts +2 -2
- package/dist/published/components/custom/FormField/AddressFieldComponent/addressFieldComponent.js +1 -1
- package/dist/published/components/custom/FormField/BooleanSelect/BooleanSelect.js +15 -7
- package/dist/published/components/custom/FormField/InputFieldComponent/InputFieldComponent.js +1 -1
- package/dist/published/components/custom/FormField/Select/Select.js +1 -1
- package/dist/published/components/custom/FormV2/FormRenderer.d.ts +1 -0
- package/dist/published/components/custom/FormV2/FormRenderer.js +12 -7
- package/dist/published/components/custom/FormV2/FormRendererContainer.d.ts +1 -0
- package/dist/published/components/custom/FormV2/FormRendererContainer.js +52 -31
- package/dist/published/components/custom/FormV2/components/Body.d.ts +1 -0
- package/dist/published/components/custom/FormV2/components/Body.js +4 -2
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/DropdownRepeatableFieldInput.js +3 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/RepeatableField.js +8 -6
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/Document.js +1 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/Image.js +1 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/UserProperty.js +2 -0
- package/dist/published/components/custom/FormV2/components/FormletRenderer.d.ts +7 -0
- package/dist/published/components/custom/FormV2/components/FormletRenderer.js +22 -0
- package/dist/published/components/custom/FormV2/components/HtmlView.js +16 -9
- package/dist/published/components/custom/FormV2/components/MisconfiguredErrorMessage.d.ts +2 -0
- package/dist/published/components/custom/FormV2/components/MisconfiguredErrorMessage.js +15 -0
- package/dist/published/components/custom/FormV2/components/RecursiveEntryRenderer.js +17 -24
- package/dist/published/components/custom/FormV2/components/types.d.ts +2 -1
- package/dist/published/components/custom/FormV2/components/utils.d.ts +7 -2
- package/dist/published/components/custom/FormV2/components/utils.js +84 -4
- package/dist/published/components/custom/FormV2/tests/FormRenderer.test.js +228 -7
- package/dist/published/components/custom/FormV2/tests/FormRendererContainer.test.js +491 -35
- package/dist/published/components/custom/ViewDetailsV2/InstanceEntryRenderer.js +20 -9
- package/dist/published/components/custom/ViewDetailsV2/ViewDetailsV2Container.js +1 -0
- package/dist/published/stories/FormRenderer.stories.d.ts +3 -0
- package/dist/published/stories/FormRenderer.stories.js +1 -0
- package/dist/published/stories/FormRendererContainer.stories.d.ts +5 -0
- package/dist/published/stories/FormRendererData.d.ts +15 -0
- package/dist/published/stories/FormRendererData.js +63 -0
- package/dist/published/stories/sharedMswHandlers.js +4 -2
- package/package.json +1 -1
|
@@ -95,7 +95,7 @@ describe('FormRendererContainer', () => {
|
|
|
95
95
|
return HttpResponse.json(rnLicense);
|
|
96
96
|
}), http.get('/api/data/objects/specialtyType/instances', () => {
|
|
97
97
|
return HttpResponse.json([rnSpecialtyType1, rnSpecialtyType2]);
|
|
98
|
-
}), http.get('/api/data/forms/specialtyForm', () => {
|
|
98
|
+
}), http.get('/api/data/forms/specialtyForm/effective', () => {
|
|
99
99
|
return HttpResponse.json(createSpecialtyForm);
|
|
100
100
|
}));
|
|
101
101
|
render(React.createElement(FormRendererContainer, { objectId: 'specialty', formId: 'specialtyForm', dataType: 'objectInstances', actionId: '_create', associatedObject: { propertyId: 'license', instanceId: 'rnLicense' } }));
|
|
@@ -116,6 +116,73 @@ describe('FormRendererContainer', () => {
|
|
|
116
116
|
});
|
|
117
117
|
});
|
|
118
118
|
});
|
|
119
|
+
it('keeps the rich text editor mounted while typing when autosave is not configured', async () => {
|
|
120
|
+
const user = userEvent.setup();
|
|
121
|
+
const mountSpy = vi.fn();
|
|
122
|
+
const richTextForm = {
|
|
123
|
+
id: 'richTextForm',
|
|
124
|
+
name: 'Rich Text Form',
|
|
125
|
+
actionId: '_update',
|
|
126
|
+
objectId: 'richTextObject',
|
|
127
|
+
entries: [
|
|
128
|
+
{
|
|
129
|
+
parameterId: 'notes',
|
|
130
|
+
type: 'input',
|
|
131
|
+
display: {
|
|
132
|
+
label: 'Notes',
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
],
|
|
136
|
+
};
|
|
137
|
+
const richTextObject = {
|
|
138
|
+
id: 'richTextObject',
|
|
139
|
+
name: 'Rich Text Object',
|
|
140
|
+
actions: [
|
|
141
|
+
{
|
|
142
|
+
id: '_update',
|
|
143
|
+
name: 'Update',
|
|
144
|
+
type: 'update',
|
|
145
|
+
parameters: [
|
|
146
|
+
{
|
|
147
|
+
id: 'notes',
|
|
148
|
+
name: 'Notes',
|
|
149
|
+
type: 'richText',
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
outputEvent: 'updated',
|
|
153
|
+
},
|
|
154
|
+
],
|
|
155
|
+
properties: [
|
|
156
|
+
{
|
|
157
|
+
id: 'notes',
|
|
158
|
+
name: 'Notes',
|
|
159
|
+
type: 'richText',
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
};
|
|
163
|
+
const TestRichTextEditor = (props) => {
|
|
164
|
+
React.useEffect(() => {
|
|
165
|
+
mountSpy();
|
|
166
|
+
}, []);
|
|
167
|
+
return (React.createElement("textarea", { "aria-label": "Notes", value: props.value || '', onChange: (event) => props.handleUpdate?.(event.target.value), onBlur: () => props.onBlur?.() }));
|
|
168
|
+
};
|
|
169
|
+
server.use(http.get('/api/data/objects/richTextObject/effective', () => HttpResponse.json(richTextObject)), http.get('/api/data/objects/richTextObject/instances/test-instance', () => {
|
|
170
|
+
return HttpResponse.json({
|
|
171
|
+
id: 'test-instance',
|
|
172
|
+
name: 'Rich Text Instance',
|
|
173
|
+
notes: '',
|
|
174
|
+
});
|
|
175
|
+
}), http.get('/api/data/objects/richTextObject/instances/test-instance/object', () => {
|
|
176
|
+
return HttpResponse.json(richTextObject);
|
|
177
|
+
}), http.get('/api/data/forms/richTextForm/effective', () => HttpResponse.json(richTextForm)));
|
|
178
|
+
render(React.createElement(FormRendererContainer, { objectId: "richTextObject", formId: "richTextForm", dataType: "objectInstances", actionId: "_update", instanceId: "test-instance", richTextEditor: TestRichTextEditor }));
|
|
179
|
+
const notesField = await screen.findByRole('textbox', { name: 'Notes' });
|
|
180
|
+
await user.click(notesField);
|
|
181
|
+
await user.type(notesField, 'Focus should stay here');
|
|
182
|
+
const updatedNotesField = await screen.findByRole('textbox', { name: 'Notes' });
|
|
183
|
+
expect(updatedNotesField).toHaveFocus();
|
|
184
|
+
expect(mountSpy).toHaveBeenCalledTimes(1);
|
|
185
|
+
});
|
|
119
186
|
describe('autosave functionality', () => {
|
|
120
187
|
it('should trigger autosave when field loses focus', async () => {
|
|
121
188
|
const user = userEvent.setup();
|
|
@@ -129,7 +196,7 @@ describe('FormRendererContainer', () => {
|
|
|
129
196
|
});
|
|
130
197
|
}), http.get('/api/data/objects/specialty/instances/test-instance/object', () => {
|
|
131
198
|
return HttpResponse.json(specialtyObject);
|
|
132
|
-
}), http.get('/api/data/forms/specialtyForm', () => {
|
|
199
|
+
}), http.get('/api/data/forms/specialtyForm/effective', () => {
|
|
133
200
|
return HttpResponse.json({
|
|
134
201
|
...createSpecialtyForm,
|
|
135
202
|
actionId: '_update',
|
|
@@ -159,6 +226,254 @@ describe('FormRendererContainer', () => {
|
|
|
159
226
|
}),
|
|
160
227
|
}));
|
|
161
228
|
});
|
|
229
|
+
it('should autosave only fields configured on the form', async () => {
|
|
230
|
+
const user = userEvent.setup();
|
|
231
|
+
let autosaveRequestBody;
|
|
232
|
+
server.use(http.get('/api/data/objects/specialty/instances/test-instance', () => {
|
|
233
|
+
return HttpResponse.json({
|
|
234
|
+
id: 'test-instance',
|
|
235
|
+
name: 'Original Name',
|
|
236
|
+
specialtyType: { id: 'someSpecialtyTypeId', name: 'Some Specialty Type' },
|
|
237
|
+
license: { id: 'someLicenseId', name: 'Some License' },
|
|
238
|
+
additionalTraining: 'Board Certified',
|
|
239
|
+
});
|
|
240
|
+
}), http.get('/api/data/objects/specialty/instances/test-instance/object', () => {
|
|
241
|
+
return HttpResponse.json(specialtyObject);
|
|
242
|
+
}), http.get('/api/data/forms/specialtyForm/effective', () => {
|
|
243
|
+
return HttpResponse.json({
|
|
244
|
+
...createSpecialtyForm,
|
|
245
|
+
actionId: '_update',
|
|
246
|
+
autosaveActionId: '_autosave',
|
|
247
|
+
});
|
|
248
|
+
}), http.post('/api/data/objects/specialty/instances/test-instance/actions', async ({ request }) => {
|
|
249
|
+
const body = (await request.json());
|
|
250
|
+
if (body.actionId === '_autosave') {
|
|
251
|
+
autosaveRequestBody = body;
|
|
252
|
+
}
|
|
253
|
+
return HttpResponse.json({
|
|
254
|
+
id: 'test-instance',
|
|
255
|
+
...body.input,
|
|
256
|
+
});
|
|
257
|
+
}));
|
|
258
|
+
render(React.createElement(FormRendererContainer, { objectId: 'specialty', formId: 'specialtyForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-instance' }));
|
|
259
|
+
const nameField = await screen.findByRole('textbox', { name: 'Name' });
|
|
260
|
+
await user.clear(nameField);
|
|
261
|
+
await user.type(nameField, 'Updated Name');
|
|
262
|
+
await user.tab();
|
|
263
|
+
await waitFor(() => {
|
|
264
|
+
expect(autosaveRequestBody).toBeDefined();
|
|
265
|
+
});
|
|
266
|
+
expect(autosaveRequestBody?.input).toEqual({
|
|
267
|
+
// Should not include additionalTraining since it's not configured on the form
|
|
268
|
+
name: 'Updated Name',
|
|
269
|
+
license: { id: 'someLicenseId', name: 'Some License' },
|
|
270
|
+
specialtyType: { id: 'someSpecialtyTypeId', name: 'Some Specialty Type' },
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
it('should include conditionally visible form fields from autosave payload', async () => {
|
|
274
|
+
const user = userEvent.setup();
|
|
275
|
+
let autosaveRequestBody;
|
|
276
|
+
const specialtyFormWithHiddenField = {
|
|
277
|
+
id: 'specialtyForm',
|
|
278
|
+
name: 'Specialty Form',
|
|
279
|
+
objectId: 'specialty',
|
|
280
|
+
actionId: '_update',
|
|
281
|
+
autosaveActionId: '_autosave',
|
|
282
|
+
entries: [
|
|
283
|
+
{
|
|
284
|
+
parameterId: 'name',
|
|
285
|
+
type: 'input',
|
|
286
|
+
display: {
|
|
287
|
+
label: 'Name',
|
|
288
|
+
},
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
parameterId: 'additionalTraining',
|
|
292
|
+
type: 'input',
|
|
293
|
+
display: {
|
|
294
|
+
label: 'Additional Training',
|
|
295
|
+
visibility: {
|
|
296
|
+
operator: 'all',
|
|
297
|
+
conditions: [
|
|
298
|
+
{
|
|
299
|
+
property: 'name',
|
|
300
|
+
operator: 'eq',
|
|
301
|
+
value: 'Show Hidden',
|
|
302
|
+
isInstanceProperty: false,
|
|
303
|
+
},
|
|
304
|
+
],
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
],
|
|
309
|
+
};
|
|
310
|
+
server.use(http.get('/api/data/objects/specialty/instances/test-instance', () => {
|
|
311
|
+
return HttpResponse.json({
|
|
312
|
+
id: 'test-instance',
|
|
313
|
+
name: 'Original Name',
|
|
314
|
+
specialtyType: null,
|
|
315
|
+
license: null,
|
|
316
|
+
additionalTraining: 'Should Autosave',
|
|
317
|
+
});
|
|
318
|
+
}), http.get('/api/data/objects/specialty/instances/test-instance/object', () => {
|
|
319
|
+
return HttpResponse.json(specialtyObject);
|
|
320
|
+
}), http.get('/api/data/forms/specialtyForm/effective', () => {
|
|
321
|
+
return HttpResponse.json(specialtyFormWithHiddenField);
|
|
322
|
+
}), http.post('/api/data/objects/specialty/instances/test-instance/actions', async ({ request }) => {
|
|
323
|
+
const body = (await request.json());
|
|
324
|
+
if (body.actionId === '_autosave') {
|
|
325
|
+
autosaveRequestBody = body;
|
|
326
|
+
}
|
|
327
|
+
return HttpResponse.json({
|
|
328
|
+
id: 'test-instance',
|
|
329
|
+
...body.input,
|
|
330
|
+
});
|
|
331
|
+
}));
|
|
332
|
+
render(React.createElement(FormRendererContainer, { objectId: 'specialty', formId: 'specialtyForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-instance' }));
|
|
333
|
+
const nameField = await screen.findByRole('textbox', { name: 'Name' });
|
|
334
|
+
await user.clear(nameField);
|
|
335
|
+
await user.type(nameField, 'Show Hidden');
|
|
336
|
+
await user.tab();
|
|
337
|
+
await waitFor(() => {
|
|
338
|
+
expect(autosaveRequestBody).toBeDefined();
|
|
339
|
+
});
|
|
340
|
+
// Should include additionalTraining since it's visible
|
|
341
|
+
expect(autosaveRequestBody?.input).toEqual({
|
|
342
|
+
name: 'Show Hidden',
|
|
343
|
+
additionalTraining: 'Should Autosave',
|
|
344
|
+
});
|
|
345
|
+
});
|
|
346
|
+
it('should exclude hidden form fields from autosave payload', async () => {
|
|
347
|
+
const user = userEvent.setup();
|
|
348
|
+
let autosaveRequestBody;
|
|
349
|
+
const specialtyFormWithHiddenField = {
|
|
350
|
+
id: 'specialtyForm',
|
|
351
|
+
name: 'Specialty Form',
|
|
352
|
+
objectId: 'specialty',
|
|
353
|
+
actionId: '_update',
|
|
354
|
+
autosaveActionId: '_autosave',
|
|
355
|
+
entries: [
|
|
356
|
+
{
|
|
357
|
+
parameterId: 'name',
|
|
358
|
+
type: 'input',
|
|
359
|
+
display: {
|
|
360
|
+
label: 'Name',
|
|
361
|
+
},
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
parameterId: 'additionalTraining',
|
|
365
|
+
type: 'input',
|
|
366
|
+
display: {
|
|
367
|
+
label: 'Additional Training',
|
|
368
|
+
visibility: {
|
|
369
|
+
operator: 'all',
|
|
370
|
+
conditions: [
|
|
371
|
+
{
|
|
372
|
+
property: 'name',
|
|
373
|
+
operator: 'eq',
|
|
374
|
+
value: 'Show Hidden',
|
|
375
|
+
isInstanceProperty: false,
|
|
376
|
+
},
|
|
377
|
+
],
|
|
378
|
+
},
|
|
379
|
+
},
|
|
380
|
+
},
|
|
381
|
+
],
|
|
382
|
+
};
|
|
383
|
+
server.use(http.get('/api/data/objects/specialty/instances/test-instance', () => {
|
|
384
|
+
return HttpResponse.json({
|
|
385
|
+
id: 'test-instance',
|
|
386
|
+
name: 'Original Name',
|
|
387
|
+
specialtyType: null,
|
|
388
|
+
license: null,
|
|
389
|
+
additionalTraining: 'Should Not Autosave',
|
|
390
|
+
});
|
|
391
|
+
}), http.get('/api/data/objects/specialty/instances/test-instance/object', () => {
|
|
392
|
+
return HttpResponse.json(specialtyObject);
|
|
393
|
+
}), http.get('/api/data/forms/specialtyForm/effective', () => {
|
|
394
|
+
return HttpResponse.json(specialtyFormWithHiddenField);
|
|
395
|
+
}), http.post('/api/data/objects/specialty/instances/test-instance/actions', async ({ request }) => {
|
|
396
|
+
const body = (await request.json());
|
|
397
|
+
if (body.actionId === '_autosave') {
|
|
398
|
+
autosaveRequestBody = body;
|
|
399
|
+
}
|
|
400
|
+
return HttpResponse.json({
|
|
401
|
+
id: 'test-instance',
|
|
402
|
+
...body.input,
|
|
403
|
+
});
|
|
404
|
+
}));
|
|
405
|
+
render(React.createElement(FormRendererContainer, { objectId: 'specialty', formId: 'specialtyForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-instance' }));
|
|
406
|
+
const nameField = await screen.findByRole('textbox', { name: 'Name' });
|
|
407
|
+
await user.clear(nameField);
|
|
408
|
+
await user.type(nameField, 'Updated Name');
|
|
409
|
+
await user.tab();
|
|
410
|
+
await waitFor(() => {
|
|
411
|
+
expect(autosaveRequestBody).toBeDefined();
|
|
412
|
+
});
|
|
413
|
+
// Should not include additionalTraining since it's hidden
|
|
414
|
+
expect(autosaveRequestBody?.input).toEqual({
|
|
415
|
+
name: 'Updated Name',
|
|
416
|
+
});
|
|
417
|
+
});
|
|
418
|
+
it('should exclude non-configured address subfields from autosave payload', async () => {
|
|
419
|
+
const user = userEvent.setup();
|
|
420
|
+
let autosaveRequestBody;
|
|
421
|
+
server.use(http.get('/api/data/objects/license/instances/test-license', () => {
|
|
422
|
+
return HttpResponse.json({
|
|
423
|
+
id: 'test-license',
|
|
424
|
+
name: 'RN-123456',
|
|
425
|
+
address: {
|
|
426
|
+
line1: '123 Main St',
|
|
427
|
+
line2: 'Suite 200',
|
|
428
|
+
city: 'Boston',
|
|
429
|
+
county: 'Suffolk',
|
|
430
|
+
state: 'MA',
|
|
431
|
+
zipCode: '02101',
|
|
432
|
+
country: 'US',
|
|
433
|
+
},
|
|
434
|
+
});
|
|
435
|
+
}), http.get('/api/data/objects/license/instances/test-license/object', () => {
|
|
436
|
+
return HttpResponse.json(licenseObject);
|
|
437
|
+
}), http.get('/api/data/forms/licenseForm/effective', () => {
|
|
438
|
+
return HttpResponse.json({
|
|
439
|
+
...licenseForm,
|
|
440
|
+
autosaveActionId: '_autosave',
|
|
441
|
+
});
|
|
442
|
+
}), http.get('/api/data/locations/search', () => {
|
|
443
|
+
return HttpResponse.json([]);
|
|
444
|
+
}), http.post('/api/data/objects/license/instances/test-license/actions', async ({ request }) => {
|
|
445
|
+
const body = (await request.json());
|
|
446
|
+
if (body.actionId === '_autosave') {
|
|
447
|
+
autosaveRequestBody = body;
|
|
448
|
+
}
|
|
449
|
+
return HttpResponse.json({
|
|
450
|
+
id: 'test-license',
|
|
451
|
+
...body.input,
|
|
452
|
+
});
|
|
453
|
+
}));
|
|
454
|
+
render(React.createElement(FormRendererContainer, { objectId: 'license', formId: 'licenseForm', dataType: 'objectInstances', actionId: '_update', instanceId: 'test-license' }));
|
|
455
|
+
const cityField = await screen.findByRole('textbox', { name: 'City' });
|
|
456
|
+
await user.clear(cityField);
|
|
457
|
+
// react state may not have finished updating state internally yet, so wait for the field to be cleared before proceeding
|
|
458
|
+
await waitFor(() => {
|
|
459
|
+
expect(cityField).toHaveValue('');
|
|
460
|
+
});
|
|
461
|
+
await user.type(cityField, 'Cambridge');
|
|
462
|
+
await user.tab();
|
|
463
|
+
await waitFor(() => {
|
|
464
|
+
expect(autosaveRequestBody).toBeDefined();
|
|
465
|
+
});
|
|
466
|
+
expect(autosaveRequestBody?.input).toEqual({
|
|
467
|
+
name: 'RN-123456',
|
|
468
|
+
// Only configured address fields should be included
|
|
469
|
+
address: {
|
|
470
|
+
line1: '123 Main St',
|
|
471
|
+
city: 'Cambridge',
|
|
472
|
+
state: 'MA',
|
|
473
|
+
zipCode: '02101',
|
|
474
|
+
},
|
|
475
|
+
});
|
|
476
|
+
});
|
|
162
477
|
it('should show saving indicator during autosave', async () => {
|
|
163
478
|
const user = userEvent.setup();
|
|
164
479
|
let resolveSave;
|
|
@@ -175,7 +490,7 @@ describe('FormRendererContainer', () => {
|
|
|
175
490
|
});
|
|
176
491
|
}), http.get('/api/data/objects/specialty/instances/test-instance/object', () => {
|
|
177
492
|
return HttpResponse.json(specialtyObject);
|
|
178
|
-
}), http.get('/api/data/forms/specialtyForm', () => {
|
|
493
|
+
}), http.get('/api/data/forms/specialtyForm/effective', () => {
|
|
179
494
|
return HttpResponse.json({
|
|
180
495
|
...createSpecialtyForm,
|
|
181
496
|
actionId: '_update',
|
|
@@ -226,7 +541,7 @@ describe('FormRendererContainer', () => {
|
|
|
226
541
|
});
|
|
227
542
|
}), http.get('/api/data/objects/specialty/instances/test-instance/object', () => {
|
|
228
543
|
return HttpResponse.json(specialtyObject);
|
|
229
|
-
}), http.get('/api/data/forms/specialtyForm', () => {
|
|
544
|
+
}), http.get('/api/data/forms/specialtyForm/effective', () => {
|
|
230
545
|
return HttpResponse.json({
|
|
231
546
|
...createSpecialtyForm,
|
|
232
547
|
actionId: '_update',
|
|
@@ -261,7 +576,7 @@ describe('FormRendererContainer', () => {
|
|
|
261
576
|
});
|
|
262
577
|
}), http.get('/api/data/objects/specialty/instances/test-instance/object', () => {
|
|
263
578
|
return HttpResponse.json(specialtyObject);
|
|
264
|
-
}), http.get('/api/data/forms/specialtyForm', () => {
|
|
579
|
+
}), http.get('/api/data/forms/specialtyForm/effective', () => {
|
|
265
580
|
return HttpResponse.json({
|
|
266
581
|
...createSpecialtyForm,
|
|
267
582
|
actionId: '_update',
|
|
@@ -306,7 +621,7 @@ describe('FormRendererContainer', () => {
|
|
|
306
621
|
});
|
|
307
622
|
}), http.get('/api/data/objects/license/instances/test-license/object', () => {
|
|
308
623
|
return HttpResponse.json(licenseObject);
|
|
309
|
-
}), http.get('/api/data/forms/licenseForm', () => {
|
|
624
|
+
}), http.get('/api/data/forms/licenseForm/effective', () => {
|
|
310
625
|
return HttpResponse.json({
|
|
311
626
|
...licenseForm,
|
|
312
627
|
autosaveActionId: '_autosave',
|
|
@@ -363,7 +678,7 @@ describe('FormRendererContainer', () => {
|
|
|
363
678
|
if (sanitizedVersion === 'true') {
|
|
364
679
|
return HttpResponse.json(licenseObject);
|
|
365
680
|
}
|
|
366
|
-
}), http.get('/api/data/forms/licenseForm', () => {
|
|
681
|
+
}), http.get('/api/data/forms/licenseForm/effective', () => {
|
|
367
682
|
return HttpResponse.json({
|
|
368
683
|
...licenseForm,
|
|
369
684
|
autosaveActionId: '_autosave',
|
|
@@ -411,7 +726,7 @@ describe('FormRendererContainer', () => {
|
|
|
411
726
|
if (sanitizedVersion === 'true') {
|
|
412
727
|
return HttpResponse.json(licenseObject);
|
|
413
728
|
}
|
|
414
|
-
}), http.get('/api/data/forms/licenseForm', () => {
|
|
729
|
+
}), http.get('/api/data/forms/licenseForm/effective', () => {
|
|
415
730
|
return HttpResponse.json({
|
|
416
731
|
...licenseForm,
|
|
417
732
|
autosaveActionId: '_autosave',
|
|
@@ -466,7 +781,7 @@ describe('FormRendererContainer', () => {
|
|
|
466
781
|
});
|
|
467
782
|
}), http.get('/api/data/objects/specialty/instances/test-instance/object', () => {
|
|
468
783
|
return HttpResponse.json(specialtyObject);
|
|
469
|
-
}), http.get('/api/data/forms/specialtyForm', () => {
|
|
784
|
+
}), http.get('/api/data/forms/specialtyForm/effective', () => {
|
|
470
785
|
return HttpResponse.json({
|
|
471
786
|
...createSpecialtyForm,
|
|
472
787
|
actionId: '_update',
|
|
@@ -488,7 +803,7 @@ describe('FormRendererContainer', () => {
|
|
|
488
803
|
});
|
|
489
804
|
}), http.get('/api/data/objects/specialty/instances/test-instance/object', () => {
|
|
490
805
|
return HttpResponse.json(specialtyObject);
|
|
491
|
-
}), http.get('/api/data/forms/specialtyForm', () => {
|
|
806
|
+
}), http.get('/api/data/forms/specialtyForm/effective', () => {
|
|
492
807
|
return HttpResponse.json({
|
|
493
808
|
...createSpecialtyForm,
|
|
494
809
|
actionId: '_update',
|
|
@@ -514,6 +829,81 @@ describe('FormRendererContainer', () => {
|
|
|
514
829
|
// Verify autosave was not triggered
|
|
515
830
|
expect(autosaveActionSpy).not.toHaveBeenCalled();
|
|
516
831
|
});
|
|
832
|
+
it('should trigger autosave when a rich text field loses focus', async () => {
|
|
833
|
+
const user = userEvent.setup();
|
|
834
|
+
const autosaveActionSpy = vi.fn();
|
|
835
|
+
const richTextForm = {
|
|
836
|
+
id: 'richTextAutosaveForm',
|
|
837
|
+
name: 'Rich Text Autosave Form',
|
|
838
|
+
objectId: 'richTextObject',
|
|
839
|
+
actionId: '_update',
|
|
840
|
+
autosaveActionId: '_autosave',
|
|
841
|
+
entries: [
|
|
842
|
+
{
|
|
843
|
+
parameterId: 'notes',
|
|
844
|
+
type: 'input',
|
|
845
|
+
display: {
|
|
846
|
+
label: 'Notes',
|
|
847
|
+
},
|
|
848
|
+
},
|
|
849
|
+
],
|
|
850
|
+
};
|
|
851
|
+
const richTextObject = {
|
|
852
|
+
id: 'richTextObject',
|
|
853
|
+
name: 'Rich Text Object',
|
|
854
|
+
actions: [
|
|
855
|
+
{
|
|
856
|
+
id: '_update',
|
|
857
|
+
name: 'Update',
|
|
858
|
+
type: 'update',
|
|
859
|
+
parameters: [
|
|
860
|
+
{
|
|
861
|
+
id: 'notes',
|
|
862
|
+
name: 'Notes',
|
|
863
|
+
type: 'richText',
|
|
864
|
+
},
|
|
865
|
+
],
|
|
866
|
+
outputEvent: 'updated',
|
|
867
|
+
},
|
|
868
|
+
],
|
|
869
|
+
properties: [
|
|
870
|
+
{
|
|
871
|
+
id: 'notes',
|
|
872
|
+
name: 'Notes',
|
|
873
|
+
type: 'richText',
|
|
874
|
+
},
|
|
875
|
+
],
|
|
876
|
+
};
|
|
877
|
+
const TestRichTextEditor = (props) => {
|
|
878
|
+
return (React.createElement("textarea", { "aria-label": "Notes", value: props.value || '', onChange: (event) => props.handleUpdate?.(event.target.value), onBlur: () => props.onBlur?.() }));
|
|
879
|
+
};
|
|
880
|
+
server.use(http.get('/api/data/objects/richTextObject/effective', () => HttpResponse.json(richTextObject)), http.get('/api/data/objects/richTextObject/instances/test-instance', () => {
|
|
881
|
+
return HttpResponse.json({
|
|
882
|
+
id: 'test-instance',
|
|
883
|
+
name: 'Rich Text Instance',
|
|
884
|
+
notes: '',
|
|
885
|
+
});
|
|
886
|
+
}), http.get('/api/data/objects/richTextObject/instances/test-instance/object', () => {
|
|
887
|
+
return HttpResponse.json(richTextObject);
|
|
888
|
+
}), http.get('/api/data/forms/richTextAutosaveForm/effective', () => HttpResponse.json(richTextForm)), http.post('/api/data/objects/richTextObject/instances/test-instance/actions', async ({ request }) => {
|
|
889
|
+
const body = (await request.json());
|
|
890
|
+
autosaveActionSpy(body);
|
|
891
|
+
return HttpResponse.json({
|
|
892
|
+
id: 'test-instance',
|
|
893
|
+
...body.input,
|
|
894
|
+
});
|
|
895
|
+
}));
|
|
896
|
+
render(React.createElement(FormRendererContainer, { objectId: "richTextObject", formId: "richTextAutosaveForm", dataType: "objectInstances", actionId: "_update", instanceId: "test-instance", richTextEditor: TestRichTextEditor }));
|
|
897
|
+
const notesField = await screen.findByRole('textbox', { name: 'Notes' });
|
|
898
|
+
await user.type(notesField, 'Autosave me');
|
|
899
|
+
await user.tab();
|
|
900
|
+
expect(autosaveActionSpy).toHaveBeenCalledWith(expect.objectContaining({
|
|
901
|
+
actionId: '_autosave',
|
|
902
|
+
input: expect.objectContaining({
|
|
903
|
+
notes: expect.stringContaining('Autosave me'),
|
|
904
|
+
}),
|
|
905
|
+
}));
|
|
906
|
+
});
|
|
517
907
|
it('should trigger autosave immediately when a radio button is selected', async () => {
|
|
518
908
|
const user = userEvent.setup();
|
|
519
909
|
const autosaveActionSpy = vi.fn();
|
|
@@ -552,7 +942,7 @@ describe('FormRendererContainer', () => {
|
|
|
552
942
|
});
|
|
553
943
|
}), http.get('/api/data/objects/license/instances/test-license/object', () => {
|
|
554
944
|
return HttpResponse.json(licenseObject);
|
|
555
|
-
}), http.get('/api/data/forms/licenseForm', () => {
|
|
945
|
+
}), http.get('/api/data/forms/licenseForm/effective', () => {
|
|
556
946
|
return HttpResponse.json(licenseFormWithRadioButtons);
|
|
557
947
|
}), http.post('/api/data/objects/license/instances/test-license/actions', async ({ request }) => {
|
|
558
948
|
const body = (await request.json());
|
|
@@ -615,7 +1005,7 @@ describe('FormRendererContainer', () => {
|
|
|
615
1005
|
});
|
|
616
1006
|
}), http.get('/api/data/objects/license/instances/test-license/object', () => {
|
|
617
1007
|
return HttpResponse.json(licenseObject);
|
|
618
|
-
}), http.get('/api/data/forms/licenseForm', () => {
|
|
1008
|
+
}), http.get('/api/data/forms/licenseForm/effective', () => {
|
|
619
1009
|
return HttpResponse.json(licenseFormWithRadioButtons);
|
|
620
1010
|
}), http.post('/api/data/objects/license/instances/test-license/actions', async ({ request }) => {
|
|
621
1011
|
const body = (await request.json());
|
|
@@ -661,7 +1051,7 @@ describe('FormRendererContainer', () => {
|
|
|
661
1051
|
},
|
|
662
1052
|
],
|
|
663
1053
|
};
|
|
664
|
-
server.use(http.get('/api/data/objects/license/instances/test-license', () => HttpResponse.json({ id: 'test-license', name: 'RN-123456', status: 'Active' })), http.get('/api/data/objects/license/instances/test-license/object', () => HttpResponse.json(licenseObject)), http.get('/api/data/forms/licenseForm', () => HttpResponse.json(licenseFormWithDropdown)), http.post('/api/data/objects/license/instances/test-license/actions', async ({ request }) => {
|
|
1054
|
+
server.use(http.get('/api/data/objects/license/instances/test-license', () => HttpResponse.json({ id: 'test-license', name: 'RN-123456', status: 'Active' })), http.get('/api/data/objects/license/instances/test-license/object', () => HttpResponse.json(licenseObject)), http.get('/api/data/forms/licenseForm/effective', () => HttpResponse.json(licenseFormWithDropdown)), http.post('/api/data/objects/license/instances/test-license/actions', async ({ request }) => {
|
|
665
1055
|
const body = (await request.json());
|
|
666
1056
|
autosaveActionSpy(body);
|
|
667
1057
|
return HttpResponse.json({ id: 'test-license', name: 'RN-123456', status: body.input.status });
|
|
@@ -704,7 +1094,7 @@ describe('FormRendererContainer', () => {
|
|
|
704
1094
|
},
|
|
705
1095
|
],
|
|
706
1096
|
};
|
|
707
|
-
server.use(http.get('/api/data/objects/license/instances/test-license', () => HttpResponse.json({ id: 'test-license', name: 'RN-123456', status: 'Active' })), http.get('/api/data/objects/license/instances/test-license/object', () => HttpResponse.json(licenseObject)), http.get('/api/data/forms/licenseForm', () => HttpResponse.json(licenseFormWithDropdown)), http.post('/api/data/objects/license/instances/test-license/actions', async ({ request }) => {
|
|
1097
|
+
server.use(http.get('/api/data/objects/license/instances/test-license', () => HttpResponse.json({ id: 'test-license', name: 'RN-123456', status: 'Active' })), http.get('/api/data/objects/license/instances/test-license/object', () => HttpResponse.json(licenseObject)), http.get('/api/data/forms/licenseForm/effective', () => HttpResponse.json(licenseFormWithDropdown)), http.post('/api/data/objects/license/instances/test-license/actions', async ({ request }) => {
|
|
708
1098
|
const body = (await request.json());
|
|
709
1099
|
autosaveActionSpy(body);
|
|
710
1100
|
return HttpResponse.json({ id: 'test-license', name: 'RN-123456', status: body.input.status });
|
|
@@ -752,7 +1142,7 @@ describe('FormRendererContainer', () => {
|
|
|
752
1142
|
],
|
|
753
1143
|
};
|
|
754
1144
|
const licenseInstanceInitial = { id: 'test-license', name: 'RN-123456' };
|
|
755
|
-
server.use(http.get('/api/data/objects/license/instances/test-license', () => HttpResponse.json(licenseInstanceInitial)), http.get('/api/data/objects/license/instances/test-license/object', () => HttpResponse.json(licenseObject)), http.get('/api/data/forms/licenseForm', () => HttpResponse.json(licenseFormWithMultiSelect)), http.post('/api/data/objects/license/instances/test-license/actions', async ({ request }) => {
|
|
1145
|
+
server.use(http.get('/api/data/objects/license/instances/test-license', () => HttpResponse.json(licenseInstanceInitial)), http.get('/api/data/objects/license/instances/test-license/object', () => HttpResponse.json(licenseObject)), http.get('/api/data/forms/licenseForm/effective', () => HttpResponse.json(licenseFormWithMultiSelect)), http.post('/api/data/objects/license/instances/test-license/actions', async ({ request }) => {
|
|
756
1146
|
const body = (await request.json());
|
|
757
1147
|
autosaveActionSpy(body);
|
|
758
1148
|
return HttpResponse.json({
|
|
@@ -802,7 +1192,7 @@ describe('FormRendererContainer', () => {
|
|
|
802
1192
|
],
|
|
803
1193
|
};
|
|
804
1194
|
const licenseInstanceInitial = { id: 'test-license', name: 'RN-123456', categories: ['Electrical'] };
|
|
805
|
-
server.use(http.get('/api/data/objects/license/instances/test-license', () => HttpResponse.json(licenseInstanceInitial)), http.get('/api/data/objects/license/instances/test-license/object', () => HttpResponse.json(licenseObject)), http.get('/api/data/forms/licenseForm', () => HttpResponse.json(licenseFormWithMultiSelect)), http.post('/api/data/objects/license/instances/test-license/actions', async ({ request }) => {
|
|
1195
|
+
server.use(http.get('/api/data/objects/license/instances/test-license', () => HttpResponse.json(licenseInstanceInitial)), http.get('/api/data/objects/license/instances/test-license/object', () => HttpResponse.json(licenseObject)), http.get('/api/data/forms/licenseForm/effective', () => HttpResponse.json(licenseFormWithMultiSelect)), http.post('/api/data/objects/license/instances/test-license/actions', async ({ request }) => {
|
|
806
1196
|
const body = (await request.json());
|
|
807
1197
|
autosaveActionSpy(body);
|
|
808
1198
|
return HttpResponse.json({
|
|
@@ -857,7 +1247,7 @@ describe('FormRendererContainer', () => {
|
|
|
857
1247
|
id: 'test-license',
|
|
858
1248
|
name: 'RN-123456',
|
|
859
1249
|
categories: ['Electrical', 'Plumbing'],
|
|
860
|
-
})), http.get('/api/data/objects/license/instances/test-license/object', () => HttpResponse.json(licenseObject)), http.get('/api/data/forms/licenseForm', () => HttpResponse.json(licenseFormWithMultiSelect)), http.post('/api/data/objects/license/instances/test-license/actions', async ({ request }) => {
|
|
1250
|
+
})), http.get('/api/data/objects/license/instances/test-license/object', () => HttpResponse.json(licenseObject)), http.get('/api/data/forms/licenseForm/effective', () => HttpResponse.json(licenseFormWithMultiSelect)), http.post('/api/data/objects/license/instances/test-license/actions', async ({ request }) => {
|
|
861
1251
|
const body = (await request.json());
|
|
862
1252
|
autosaveActionSpy(body);
|
|
863
1253
|
return HttpResponse.json({
|
|
@@ -914,7 +1304,7 @@ describe('FormRendererContainer', () => {
|
|
|
914
1304
|
id: 'test-license',
|
|
915
1305
|
name: 'RN-123456',
|
|
916
1306
|
categories: ['Electrical', 'Plumbing'],
|
|
917
|
-
})), http.get('/api/data/objects/license/instances/test-license/object', () => HttpResponse.json(licenseObject)), http.get('/api/data/forms/licenseForm', () => HttpResponse.json(licenseFormWithMultiSelect)), http.post('/api/data/objects/license/instances/test-license/actions', async ({ request }) => {
|
|
1307
|
+
})), http.get('/api/data/objects/license/instances/test-license/object', () => HttpResponse.json(licenseObject)), http.get('/api/data/forms/licenseForm/effective', () => HttpResponse.json(licenseFormWithMultiSelect)), http.post('/api/data/objects/license/instances/test-license/actions', async ({ request }) => {
|
|
918
1308
|
const body = (await request.json());
|
|
919
1309
|
autosaveActionSpy(body);
|
|
920
1310
|
return HttpResponse.json({
|
|
@@ -969,7 +1359,7 @@ describe('FormRendererContainer', () => {
|
|
|
969
1359
|
id: 'test-license',
|
|
970
1360
|
name: 'RN-123456',
|
|
971
1361
|
categories: ['Electrical', 'Plumbing'],
|
|
972
|
-
})), http.get('/api/data/objects/license/instances/test-license/object', () => HttpResponse.json(licenseObject)), http.get('/api/data/forms/licenseForm', () => HttpResponse.json(licenseFormWithMultiSelect)), http.post('/api/data/objects/license/instances/test-license/actions', async ({ request }) => {
|
|
1362
|
+
})), http.get('/api/data/objects/license/instances/test-license/object', () => HttpResponse.json(licenseObject)), http.get('/api/data/forms/licenseForm/effective', () => HttpResponse.json(licenseFormWithMultiSelect)), http.post('/api/data/objects/license/instances/test-license/actions', async ({ request }) => {
|
|
973
1363
|
const body = (await request.json());
|
|
974
1364
|
autosaveActionSpy(body);
|
|
975
1365
|
return HttpResponse.json({
|
|
@@ -1015,7 +1405,7 @@ describe('FormRendererContainer', () => {
|
|
|
1015
1405
|
],
|
|
1016
1406
|
properties: [],
|
|
1017
1407
|
};
|
|
1018
|
-
server.use(http.get(`/api/data/objects/${simpleObject.id}/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/${form.id}`, () => HttpResponse.json(form)));
|
|
1408
|
+
server.use(http.get(`/api/data/objects/${simpleObject.id}/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/${form.id}/effective`, () => HttpResponse.json(form)));
|
|
1019
1409
|
render(React.createElement(FormRendererContainer, { objectId: simpleObject.id, formId: form.id, dataType: "objectInstances" }));
|
|
1020
1410
|
await screen.findByText('Simple Form');
|
|
1021
1411
|
});
|
|
@@ -1041,7 +1431,7 @@ describe('FormRendererContainer', () => {
|
|
|
1041
1431
|
],
|
|
1042
1432
|
properties: [],
|
|
1043
1433
|
};
|
|
1044
|
-
server.use(http.get(`/api/data/objects/${simpleObject.id}/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/${form.id}`, () => HttpResponse.json(form)));
|
|
1434
|
+
server.use(http.get(`/api/data/objects/${simpleObject.id}/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/${form.id}/effective`, () => HttpResponse.json(form)));
|
|
1045
1435
|
render(React.createElement(FormRendererContainer, { objectId: simpleObject.id, formId: form.id, title: {
|
|
1046
1436
|
hidden: false,
|
|
1047
1437
|
}, dataType: "objectInstances" }));
|
|
@@ -1069,7 +1459,7 @@ describe('FormRendererContainer', () => {
|
|
|
1069
1459
|
],
|
|
1070
1460
|
properties: [],
|
|
1071
1461
|
};
|
|
1072
|
-
server.use(http.get(`/api/data/objects/${simpleObject.id}/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/${form.id}`, () => HttpResponse.json(form)));
|
|
1462
|
+
server.use(http.get(`/api/data/objects/${simpleObject.id}/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/${form.id}/effective`, () => HttpResponse.json(form)));
|
|
1073
1463
|
render(React.createElement(FormRendererContainer, { objectId: simpleObject.id, formId: form.id, title: {
|
|
1074
1464
|
hidden: true,
|
|
1075
1465
|
}, dataType: "objectInstances" }));
|
|
@@ -1099,7 +1489,7 @@ describe('FormRendererContainer', () => {
|
|
|
1099
1489
|
],
|
|
1100
1490
|
properties: [],
|
|
1101
1491
|
};
|
|
1102
|
-
server.use(http.get(`/api/data/objects/${simpleObject.id}/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/${form.id}`, () => HttpResponse.json(form)));
|
|
1492
|
+
server.use(http.get(`/api/data/objects/${simpleObject.id}/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/${form.id}/effective`, () => HttpResponse.json(form)));
|
|
1103
1493
|
render(React.createElement(FormRendererContainer, { objectId: simpleObject.id, formId: form.id, actionId: '_create' }));
|
|
1104
1494
|
await screen.findByRole('button', { name: 'Submit' });
|
|
1105
1495
|
});
|
|
@@ -1125,7 +1515,7 @@ describe('FormRendererContainer', () => {
|
|
|
1125
1515
|
],
|
|
1126
1516
|
properties: [],
|
|
1127
1517
|
};
|
|
1128
|
-
server.use(http.get(`/api/data/objects/${simpleObject.id}/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/${form.id}`, () => HttpResponse.json(form)));
|
|
1518
|
+
server.use(http.get(`/api/data/objects/${simpleObject.id}/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/${form.id}/effective`, () => HttpResponse.json(form)));
|
|
1129
1519
|
render(React.createElement(FormRendererContainer, { objectId: simpleObject.id, formId: form.id, actionId: '_create' }));
|
|
1130
1520
|
await screen.findByRole('button', { name: 'Discard Changes' });
|
|
1131
1521
|
});
|
|
@@ -1167,7 +1557,7 @@ describe('FormRendererContainer', () => {
|
|
|
1167
1557
|
},
|
|
1168
1558
|
],
|
|
1169
1559
|
};
|
|
1170
|
-
server.use(http.get(`/api/data/objects/${simpleObject.id}/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/${form.id}`, () => HttpResponse.json(form)));
|
|
1560
|
+
server.use(http.get(`/api/data/objects/${simpleObject.id}/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/${form.id}/effective`, () => HttpResponse.json(form)));
|
|
1171
1561
|
const user = userEvent.setup();
|
|
1172
1562
|
render(React.createElement(FormRendererContainer, { objectId: simpleObject.id, formId: form.id, actionId: '_create' }));
|
|
1173
1563
|
const firstNameInput = await screen.findByRole('textbox', { name: 'First Name' });
|
|
@@ -1176,6 +1566,72 @@ describe('FormRendererContainer', () => {
|
|
|
1176
1566
|
await user.click(discardButton);
|
|
1177
1567
|
await waitFor(() => expect(firstNameInput).toHaveValue(''));
|
|
1178
1568
|
});
|
|
1569
|
+
it('should reset rich text content without remounting the editor when discarding changes', async () => {
|
|
1570
|
+
const user = userEvent.setup();
|
|
1571
|
+
const mountSpy = vi.fn();
|
|
1572
|
+
const form = {
|
|
1573
|
+
id: 'richTextDiscardForm',
|
|
1574
|
+
name: 'Rich Text Form',
|
|
1575
|
+
entries: [
|
|
1576
|
+
{
|
|
1577
|
+
type: 'input',
|
|
1578
|
+
parameterId: 'notes',
|
|
1579
|
+
display: {
|
|
1580
|
+
label: 'Notes',
|
|
1581
|
+
},
|
|
1582
|
+
},
|
|
1583
|
+
],
|
|
1584
|
+
actionId: '_update',
|
|
1585
|
+
objectId: 'richTextDiscardObject',
|
|
1586
|
+
};
|
|
1587
|
+
const richTextObject = {
|
|
1588
|
+
id: 'richTextDiscardObject',
|
|
1589
|
+
name: 'Rich Text Object',
|
|
1590
|
+
actions: [
|
|
1591
|
+
{
|
|
1592
|
+
id: '_update',
|
|
1593
|
+
name: 'Update',
|
|
1594
|
+
type: 'update',
|
|
1595
|
+
parameters: [
|
|
1596
|
+
{
|
|
1597
|
+
id: 'notes',
|
|
1598
|
+
name: 'Notes',
|
|
1599
|
+
type: 'richText',
|
|
1600
|
+
},
|
|
1601
|
+
],
|
|
1602
|
+
outputEvent: 'updated',
|
|
1603
|
+
},
|
|
1604
|
+
],
|
|
1605
|
+
properties: [
|
|
1606
|
+
{
|
|
1607
|
+
id: 'notes',
|
|
1608
|
+
name: 'Notes',
|
|
1609
|
+
type: 'richText',
|
|
1610
|
+
},
|
|
1611
|
+
],
|
|
1612
|
+
};
|
|
1613
|
+
const TestRichTextEditor = (props) => {
|
|
1614
|
+
React.useEffect(() => {
|
|
1615
|
+
mountSpy();
|
|
1616
|
+
}, []);
|
|
1617
|
+
return (React.createElement("textarea", { "aria-label": "Notes", value: props.value || '', onChange: (event) => props.handleUpdate?.(event.target.value), onBlur: () => props.onBlur?.() }));
|
|
1618
|
+
};
|
|
1619
|
+
server.use(http.get('/api/data/objects/richTextDiscardObject/effective', () => HttpResponse.json(richTextObject)), http.get('/api/data/forms/richTextDiscardForm/effective', () => HttpResponse.json(form)), http.get('/api/data/objects/richTextDiscardObject/instances/test-instance', () => HttpResponse.json({
|
|
1620
|
+
id: 'test-instance',
|
|
1621
|
+
name: 'Rich Text Instance',
|
|
1622
|
+
notes: 'Original notes',
|
|
1623
|
+
})), http.get('/api/data/objects/richTextDiscardObject/instances/test-instance/object', () => HttpResponse.json(richTextObject)));
|
|
1624
|
+
render(React.createElement(FormRendererContainer, { objectId: "richTextDiscardObject", formId: "richTextDiscardForm", dataType: "objectInstances", actionId: "_update", instanceId: "test-instance", richTextEditor: TestRichTextEditor }));
|
|
1625
|
+
const notesField = await screen.findByRole('textbox', { name: 'Notes' });
|
|
1626
|
+
expect(notesField).toHaveValue('{\\rtf1\\ansi\\deff0 {\\fonttbl {\\f0 Calibri;}} \\f0\\fs22 Original notes}');
|
|
1627
|
+
await user.clear(notesField);
|
|
1628
|
+
await user.type(notesField, 'Updated notes');
|
|
1629
|
+
expect(notesField).toHaveValue('Updated notes');
|
|
1630
|
+
const discardButton = await screen.findByRole('button', { name: 'Discard Changes' });
|
|
1631
|
+
await user.click(discardButton);
|
|
1632
|
+
await waitFor(() => expect(notesField).toHaveValue('{\\rtf1\\ansi\\deff0 {\\fonttbl {\\f0 Calibri;}} \\f0\\fs22 Original notes}'));
|
|
1633
|
+
expect(mountSpy).toHaveBeenCalledTimes(1);
|
|
1634
|
+
});
|
|
1179
1635
|
it('should show a not found error if the instance cannot be found', async () => {
|
|
1180
1636
|
const form = {
|
|
1181
1637
|
id: 'simpleForm',
|
|
@@ -1221,7 +1677,7 @@ describe('FormRendererContainer', () => {
|
|
|
1221
1677
|
},
|
|
1222
1678
|
],
|
|
1223
1679
|
};
|
|
1224
|
-
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({
|
|
1680
|
+
server.use(http.get(`/api/data/objects/simpleObject/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/simpleForm/effective`, () => HttpResponse.json(form)), http.get('/api/data/objects/simpleObject/instances/123', () => HttpResponse.json({
|
|
1225
1681
|
message: 'Not Found',
|
|
1226
1682
|
}, { status: 404 })), http.get('/api/data/objects/simpleObject/instances/123/object', () => HttpResponse.json(simpleObject)));
|
|
1227
1683
|
render(React.createElement(FormRendererContainer, { formId: form.id, actionId: "_update", objectId: "simpleObject", instanceId: '123' }));
|
|
@@ -1272,7 +1728,7 @@ describe('FormRendererContainer', () => {
|
|
|
1272
1728
|
},
|
|
1273
1729
|
],
|
|
1274
1730
|
};
|
|
1275
|
-
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({
|
|
1731
|
+
server.use(http.get(`/api/data/objects/simpleObject/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/simpleForm/effective`, () => HttpResponse.json(form)), http.get('/api/data/objects/simpleObject/instances/123', () => HttpResponse.json({
|
|
1276
1732
|
message: 'Unauthorized',
|
|
1277
1733
|
}, { status: 403 })), http.get('/api/data/objects/simpleObject/instances/123/object', () => HttpResponse.json({
|
|
1278
1734
|
message: 'Unauthorized',
|
|
@@ -1320,7 +1776,7 @@ describe('FormRendererContainer', () => {
|
|
|
1320
1776
|
],
|
|
1321
1777
|
properties: [],
|
|
1322
1778
|
};
|
|
1323
|
-
server.use(http.get(`/api/data/objects/simpleObject/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/simpleForm`, () => HttpResponse.json(form)));
|
|
1779
|
+
server.use(http.get(`/api/data/objects/simpleObject/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/simpleForm/effective`, () => HttpResponse.json(form)));
|
|
1324
1780
|
render(React.createElement(FormRendererContainer, { formId: form.id, objectId: "simpleObject", actionId: "_create" }));
|
|
1325
1781
|
await screen.findByText('Simple Form');
|
|
1326
1782
|
});
|
|
@@ -1339,7 +1795,7 @@ describe('FormRendererContainer', () => {
|
|
|
1339
1795
|
],
|
|
1340
1796
|
properties: [],
|
|
1341
1797
|
};
|
|
1342
|
-
server.use(http.get(`/api/data/objects/simpleObject/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/notAForm`, () => HttpResponse.json({ error: 'Not Found' }, { status: 404 })));
|
|
1798
|
+
server.use(http.get(`/api/data/objects/simpleObject/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/notAForm/effective`, () => HttpResponse.json({ error: 'Not Found' }, { status: 404 })));
|
|
1343
1799
|
render(React.createElement(FormRendererContainer, { formId: 'notAForm', objectId: "simpleObject", dataType: "objectInstances" }));
|
|
1344
1800
|
await screen.findByText('The requested content could not be found.');
|
|
1345
1801
|
});
|
|
@@ -1365,7 +1821,7 @@ describe('FormRendererContainer', () => {
|
|
|
1365
1821
|
],
|
|
1366
1822
|
properties: [],
|
|
1367
1823
|
};
|
|
1368
|
-
server.use(http.get(`/api/data/objects/simpleObject/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/simpleForm`, () => HttpResponse.json(form)));
|
|
1824
|
+
server.use(http.get(`/api/data/objects/simpleObject/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/simpleForm/effective`, () => HttpResponse.json(form)));
|
|
1369
1825
|
render(React.createElement(FormRendererContainer, { formId: form.id, objectId: "simpleObject", dataType: "objectInstances" }));
|
|
1370
1826
|
await screen.findByText('It looks like something is missing.');
|
|
1371
1827
|
});
|
|
@@ -1391,7 +1847,7 @@ describe('FormRendererContainer', () => {
|
|
|
1391
1847
|
],
|
|
1392
1848
|
properties: [],
|
|
1393
1849
|
};
|
|
1394
|
-
server.use(http.get(`/api/data/objects/simpleObject/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/simpleForm`, () => HttpResponse.json(form)));
|
|
1850
|
+
server.use(http.get(`/api/data/objects/simpleObject/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/simpleForm/effective`, () => HttpResponse.json(form)));
|
|
1395
1851
|
render(React.createElement(FormRendererContainer, { formId: form.id, objectId: "simpleObject", actionId: "_create", dataType: "objectInstances" }));
|
|
1396
1852
|
await screen.findByText('It looks like something is missing.');
|
|
1397
1853
|
});
|
|
@@ -1421,7 +1877,7 @@ describe('FormRendererContainer', () => {
|
|
|
1421
1877
|
],
|
|
1422
1878
|
properties: [],
|
|
1423
1879
|
};
|
|
1424
|
-
server.use(http.get(`/api/data/objects/simpleObject/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/simpleForm`, () => HttpResponse.json(form)));
|
|
1880
|
+
server.use(http.get(`/api/data/objects/simpleObject/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/simpleForm/effective`, () => HttpResponse.json(form)));
|
|
1425
1881
|
render(React.createElement(FormRendererContainer, { objectId: "simpleObject", actionId: "_create", dataType: "objectInstances" }));
|
|
1426
1882
|
await screen.findByText('Simple Form');
|
|
1427
1883
|
});
|
|
@@ -1442,7 +1898,7 @@ describe('FormRendererContainer', () => {
|
|
|
1442
1898
|
],
|
|
1443
1899
|
properties: [],
|
|
1444
1900
|
};
|
|
1445
|
-
server.use(http.get(`/api/data/objects/simpleObject/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/notAForm`, () => HttpResponse.json({ error: 'Not Found' }, { status: 404 })));
|
|
1901
|
+
server.use(http.get(`/api/data/objects/simpleObject/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/notAForm/effective`, () => HttpResponse.json({ error: 'Not Found' }, { status: 404 })));
|
|
1446
1902
|
render(React.createElement(FormRendererContainer, { objectId: "simpleObject", actionId: "_create", dataType: "objectInstances" }));
|
|
1447
1903
|
await screen.findByText('The requested content could not be found.');
|
|
1448
1904
|
});
|
|
@@ -1488,7 +1944,7 @@ describe('FormRendererContainer', () => {
|
|
|
1488
1944
|
],
|
|
1489
1945
|
properties: [],
|
|
1490
1946
|
};
|
|
1491
|
-
server.use(http.get(`/api/data/objects/simpleObject/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/simpleForm`, () => HttpResponse.json(form)));
|
|
1947
|
+
server.use(http.get(`/api/data/objects/simpleObject/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/simpleForm/effective`, () => HttpResponse.json(form)));
|
|
1492
1948
|
render(React.createElement(FormRendererContainer, { objectId: "simpleObject", actionId: "_create", dataType: "objectInstances" }));
|
|
1493
1949
|
await screen.findByText('It looks like something is missing.');
|
|
1494
1950
|
});
|
|
@@ -1548,7 +2004,7 @@ describe('FormRendererContainer', () => {
|
|
|
1548
2004
|
],
|
|
1549
2005
|
};
|
|
1550
2006
|
beforeEach(() => {
|
|
1551
|
-
server.use(http.get(`/api/data/objects/${validationTestObject.id}/effective`, () => HttpResponse.json(validationTestObject)), http.get(`/api/data/forms/${form.id}`, () => HttpResponse.json(form)));
|
|
2007
|
+
server.use(http.get(`/api/data/objects/${validationTestObject.id}/effective`, () => HttpResponse.json(validationTestObject)), http.get(`/api/data/forms/${form.id}/effective`, () => HttpResponse.json(form)));
|
|
1552
2008
|
});
|
|
1553
2009
|
it('should display validation errors after trying to submit the form', async () => {
|
|
1554
2010
|
const user = userEvent.setup();
|