@openmrs/esm-form-engine-lib 2.1.0-pre.1402 → 2.1.0-pre.1409
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/package.json +1 -1
- package/src/adapters/obs-adapter.ts +7 -2
- package/src/hooks/useInitialValues.test.ts +76 -0
- package/src/hooks/useInitialValues.ts +1 -0
- package/src/types/index.ts +13 -0
- package/src/types/schema.ts +0 -14
- package/src/utils/common-utils.test.ts +37 -1
- package/src/utils/common-utils.ts +12 -0
- package/src/utils/form-helper.test.ts +0 -30
- package/src/utils/form-helper.ts +0 -12
- package/0a00cb94b7e3c7b1/0a00cb94b7e3c7b1.gz +0 -0
- package/75691be0a762fc30/75691be0a762fc30.gz +0 -0
- package/cf9b433cc012cb49/cf9b433cc012cb49.gz +0 -0
- package/d9d8dc63b0ddd5c9/d9d8dc63b0ddd5c9.gz +0 -0
package/package.json
CHANGED
@@ -8,8 +8,13 @@ import {
|
|
8
8
|
type Attachment,
|
9
9
|
type ValueAndDisplay,
|
10
10
|
} from '../types';
|
11
|
-
import {
|
12
|
-
|
11
|
+
import {
|
12
|
+
hasRendering,
|
13
|
+
gracefullySetSubmission,
|
14
|
+
clearSubmission,
|
15
|
+
flattenObsList,
|
16
|
+
parseToLocalDateTime,
|
17
|
+
} from '../utils/common-utils';
|
13
18
|
import { type FormContextProps } from '../provider/form-provider';
|
14
19
|
import { type FormFieldValueAdapter } from '../types';
|
15
20
|
import { isEmpty } from '../validators/form-validator';
|
@@ -0,0 +1,76 @@
|
|
1
|
+
import { act, renderHook, waitFor } from '@testing-library/react';
|
2
|
+
|
3
|
+
import useInitialValues from './useInitialValues';
|
4
|
+
import { type FormField } from '../types';
|
5
|
+
|
6
|
+
export const mockFormFields: FormField[] = [
|
7
|
+
{
|
8
|
+
label: 'First Name',
|
9
|
+
type: 'text',
|
10
|
+
id: 'firstName',
|
11
|
+
questionOptions: {
|
12
|
+
rendering: 'text',
|
13
|
+
},
|
14
|
+
value: '',
|
15
|
+
isRequired: true,
|
16
|
+
validators: [{ required: true }],
|
17
|
+
},
|
18
|
+
{
|
19
|
+
label: 'Date of Birth',
|
20
|
+
type: 'date',
|
21
|
+
questionOptions: {
|
22
|
+
rendering: 'date',
|
23
|
+
},
|
24
|
+
datePickerFormat: 'both',
|
25
|
+
id: 'dob',
|
26
|
+
value: null,
|
27
|
+
isRequired: true,
|
28
|
+
validators: [{ required: true }],
|
29
|
+
},
|
30
|
+
];
|
31
|
+
|
32
|
+
describe('useInitialValues', () => {
|
33
|
+
let formProcessor;
|
34
|
+
let context;
|
35
|
+
|
36
|
+
beforeEach(() => {
|
37
|
+
formProcessor = {
|
38
|
+
getInitialValues: jest.fn(),
|
39
|
+
};
|
40
|
+
context = {
|
41
|
+
formFields: mockFormFields,
|
42
|
+
formFieldAdapters: { adapter1: {}, adapter2: {} },
|
43
|
+
};
|
44
|
+
});
|
45
|
+
|
46
|
+
it('should not call getInitialValues if context dependencies are not loaded', () => {
|
47
|
+
const { result } = renderHook(() => useInitialValues(formProcessor, true, context));
|
48
|
+
|
49
|
+
expect(result.current.isLoadingInitialValues).toBe(true);
|
50
|
+
expect(formProcessor.getInitialValues).not.toHaveBeenCalled();
|
51
|
+
});
|
52
|
+
|
53
|
+
it('should set error if getInitialValues rejects', async () => {
|
54
|
+
const mockError = new Error('Failed to fetch initial values');
|
55
|
+
formProcessor.getInitialValues.mockRejectedValue(mockError);
|
56
|
+
|
57
|
+
const { result } = await act(() => renderHook(() => useInitialValues(formProcessor, false, context)));
|
58
|
+
|
59
|
+
expect(result.current.error).toEqual(mockError);
|
60
|
+
expect(result.current.isLoadingInitialValues).toBe(false);
|
61
|
+
});
|
62
|
+
|
63
|
+
it('should set initial values when dependencies are loaded', async () => {
|
64
|
+
const mockInitialValues = { firstName: 'John Doe', dob: '1992-10-10' };
|
65
|
+
formProcessor.getInitialValues.mockResolvedValue(mockInitialValues);
|
66
|
+
|
67
|
+
const { result } = renderHook(() => useInitialValues(formProcessor, false, context));
|
68
|
+
|
69
|
+
await waitFor(() => expect(result.current.isLoadingInitialValues).toBe(true));
|
70
|
+
|
71
|
+
expect(formProcessor.getInitialValues).toHaveBeenCalledWith(context);
|
72
|
+
expect(result.current.initialValues).toEqual(mockInitialValues);
|
73
|
+
expect(result.current.isLoadingInitialValues).toBe(false);
|
74
|
+
expect(result.current.error).toBe(null);
|
75
|
+
});
|
76
|
+
});
|
package/src/types/index.ts
CHANGED
@@ -110,6 +110,19 @@ export interface PostSubmissionAction {
|
|
110
110
|
): void;
|
111
111
|
}
|
112
112
|
|
113
|
+
export interface FormFieldInputProps {
|
114
|
+
value: any;
|
115
|
+
field: FormField;
|
116
|
+
errors: ValidationResult[];
|
117
|
+
warnings: ValidationResult[];
|
118
|
+
/**
|
119
|
+
* Callback function to handle changes to the field value in the React Hook Form context.
|
120
|
+
*
|
121
|
+
* @param value - The new value of the field.
|
122
|
+
*/
|
123
|
+
setFieldValue: (value: any) => void;
|
124
|
+
}
|
125
|
+
|
113
126
|
/**
|
114
127
|
* Field validator
|
115
128
|
*/
|
package/src/types/schema.ts
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
import { type OpenmrsResource } from '@openmrs/esm-framework';
|
2
2
|
import { type OpenmrsEncounter } from './domain';
|
3
|
-
import { type ValidationResult } from '..';
|
4
3
|
|
5
4
|
export interface FormSchema {
|
6
5
|
name: string;
|
@@ -88,19 +87,6 @@ export interface FormField {
|
|
88
87
|
meta?: QuestionMetaProps;
|
89
88
|
}
|
90
89
|
|
91
|
-
export interface FormFieldInputProps {
|
92
|
-
value: any;
|
93
|
-
field: FormField;
|
94
|
-
errors: ValidationResult[];
|
95
|
-
warnings: ValidationResult[];
|
96
|
-
/**
|
97
|
-
* Callback function to handle changes to the field value in the React Hook Form context.
|
98
|
-
*
|
99
|
-
* @param value - The new value of the field.
|
100
|
-
*/
|
101
|
-
setFieldValue: (value: any) => void;
|
102
|
-
}
|
103
|
-
|
104
90
|
export interface HideProps {
|
105
91
|
hideWhenExpression: string;
|
106
92
|
}
|
@@ -1,4 +1,11 @@
|
|
1
|
-
import {
|
1
|
+
import {
|
2
|
+
flattenObsList,
|
3
|
+
hasRendering,
|
4
|
+
clearSubmission,
|
5
|
+
gracefullySetSubmission,
|
6
|
+
hasSubmission,
|
7
|
+
parseToLocalDateTime,
|
8
|
+
} from './common-utils';
|
2
9
|
import { isEmpty } from '../validators/form-validator';
|
3
10
|
import { type FormField, type OpenmrsObs } from '../types';
|
4
11
|
import { obsList } from '__mocks__/forms/rfe-forms/obs-list-data';
|
@@ -134,3 +141,32 @@ describe('utils functions', () => {
|
|
134
141
|
});
|
135
142
|
});
|
136
143
|
});
|
144
|
+
|
145
|
+
describe('parseToLocalDateTime', () => {
|
146
|
+
it('should parse valid date string with time correctly', () => {
|
147
|
+
const dateString = '2023-06-27T14:30:00';
|
148
|
+
const expectedDate = new Date(2023, 5, 27, 14, 30, 0);
|
149
|
+
const parsedDate = parseToLocalDateTime(dateString);
|
150
|
+
|
151
|
+
expect(parsedDate).toEqual(expectedDate);
|
152
|
+
});
|
153
|
+
|
154
|
+
it('should parse valid date string without time correctly', () => {
|
155
|
+
const dateString = '2023-06-27';
|
156
|
+
const expectedDate = new Date(2023, 5, 27);
|
157
|
+
const parsedDate = parseToLocalDateTime(dateString);
|
158
|
+
|
159
|
+
// Set hours, minutes, and seconds to 0 since the input doesn't contain time
|
160
|
+
expectedDate.setHours(0, 0, 0, 0);
|
161
|
+
|
162
|
+
expect(parsedDate).toEqual(expectedDate);
|
163
|
+
});
|
164
|
+
|
165
|
+
it('should handle invalid date string format gracefully', () => {
|
166
|
+
const dateString = 'invalid-date-string';
|
167
|
+
const parsedDate = parseToLocalDateTime(dateString);
|
168
|
+
|
169
|
+
// Check if the parsedDate is an Invalid Date
|
170
|
+
expect(isNaN(parsedDate.getTime())).toBe(true);
|
171
|
+
});
|
172
|
+
});
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import dayjs from 'dayjs';
|
1
2
|
import { type FormField, type OpenmrsObs, type RenderType } from '../types';
|
2
3
|
import { isEmpty } from '../validators/form-validator';
|
3
4
|
|
@@ -53,3 +54,14 @@ export function hasSubmission(field: FormField) {
|
|
53
54
|
export function isViewMode(sessionMode: string) {
|
54
55
|
return sessionMode === 'view' || sessionMode === 'embedded-view';
|
55
56
|
}
|
57
|
+
|
58
|
+
export function parseToLocalDateTime(dateString: string): Date {
|
59
|
+
const dateObj = dayjs(dateString).toDate();
|
60
|
+
try {
|
61
|
+
const localTimeTokens = dateString.split('T')[1].split(':');
|
62
|
+
dateObj.setHours(parseInt(localTimeTokens[0]), parseInt(localTimeTokens[1]), 0);
|
63
|
+
} catch (e) {
|
64
|
+
console.error(e);
|
65
|
+
}
|
66
|
+
return dateObj;
|
67
|
+
}
|
@@ -2,7 +2,6 @@ import {
|
|
2
2
|
findConceptByReference,
|
3
3
|
evaluateConditionalAnswered,
|
4
4
|
evaluateFieldReadonlyProp,
|
5
|
-
parseToLocalDateTime,
|
6
5
|
evaluateDisabled,
|
7
6
|
} from './form-helper';
|
8
7
|
import { DefaultValueValidator } from '../validators/default-value-validator';
|
@@ -384,35 +383,6 @@ describe('Form Engine Helper', () => {
|
|
384
383
|
});
|
385
384
|
});
|
386
385
|
|
387
|
-
describe('parseToLocalDateTime', () => {
|
388
|
-
it('should parse valid date string with time correctly', () => {
|
389
|
-
const dateString = '2023-06-27T14:30:00';
|
390
|
-
const expectedDate = new Date(2023, 5, 27, 14, 30, 0);
|
391
|
-
const parsedDate = parseToLocalDateTime(dateString);
|
392
|
-
|
393
|
-
expect(parsedDate).toEqual(expectedDate);
|
394
|
-
});
|
395
|
-
|
396
|
-
it('should parse valid date string without time correctly', () => {
|
397
|
-
const dateString = '2023-06-27';
|
398
|
-
const expectedDate = new Date(2023, 5, 27);
|
399
|
-
const parsedDate = parseToLocalDateTime(dateString);
|
400
|
-
|
401
|
-
// Set hours, minutes, and seconds to 0 since the input doesn't contain time
|
402
|
-
expectedDate.setHours(0, 0, 0, 0);
|
403
|
-
|
404
|
-
expect(parsedDate).toEqual(expectedDate);
|
405
|
-
});
|
406
|
-
|
407
|
-
it('should handle invalid date string format gracefully', () => {
|
408
|
-
const dateString = 'invalid-date-string';
|
409
|
-
const parsedDate = parseToLocalDateTime(dateString);
|
410
|
-
|
411
|
-
// Check if the parsedDate is an Invalid Date
|
412
|
-
expect(isNaN(parsedDate.getTime())).toBe(true);
|
413
|
-
});
|
414
|
-
});
|
415
|
-
|
416
386
|
describe('evaluateDisabled', () => {
|
417
387
|
let mockExpressionRunnerFn;
|
418
388
|
let node;
|
package/src/utils/form-helper.ts
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
import dayjs from 'dayjs';
|
2
1
|
import { type LayoutType } from '@openmrs/esm-framework';
|
3
2
|
import { type FormField, type FormPage, type FormSection, type SessionMode } from '../types';
|
4
3
|
import { isEmpty } from '../validators/form-validator';
|
@@ -58,17 +57,6 @@ export function findPagesWithErrors(pages: Set<FormPage>, errorFields: FormField
|
|
58
57
|
return pagesWithErrors;
|
59
58
|
}
|
60
59
|
|
61
|
-
export function parseToLocalDateTime(dateString: string): Date {
|
62
|
-
const dateObj = dayjs(dateString).toDate();
|
63
|
-
try {
|
64
|
-
const localTimeTokens = dateString.split('T')[1].split(':');
|
65
|
-
dateObj.setHours(parseInt(localTimeTokens[0]), parseInt(localTimeTokens[1]), 0);
|
66
|
-
} catch (e) {
|
67
|
-
console.error(e);
|
68
|
-
}
|
69
|
-
return dateObj;
|
70
|
-
}
|
71
|
-
|
72
60
|
export function evalConditionalRequired(field: FormField, allFields: FormField[], formValues: Record<string, any>) {
|
73
61
|
if (typeof field.required !== 'object') {
|
74
62
|
return false;
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|