@openmrs/esm-form-engine-lib 3.0.0 → 3.0.1-pre.1652
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/00718f89a2ec9729/00718f89a2ec9729.gz +0 -0
- package/121aae94b7b7602c/121aae94b7b7602c.gz +0 -0
- package/1f1205a43e369f8a/1f1205a43e369f8a.gz +0 -0
- package/56d74d49545e0e3e/56d74d49545e0e3e.gz +0 -0
- package/README.md +65 -30
- package/__mocks__/forms/rfe-forms/obs-group-test_form.json +188 -124
- package/dist/openmrs-esm-form-engine-lib.js +1 -1
- package/package.json +5 -4
- package/src/components/group/obs-group.component.tsx +5 -5
- package/src/components/inputs/content-switcher/content-switcher.component.tsx +6 -1
- package/src/components/inputs/date/date.component.tsx +1 -1
- package/src/components/inputs/multi-select/multi-select.component.tsx +4 -4
- package/src/components/inputs/number/number.component.tsx +2 -2
- package/src/components/inputs/radio/radio.component.tsx +1 -1
- package/src/components/inputs/select/dropdown.component.tsx +2 -2
- package/src/components/inputs/ui-select-extended/ui-select-extended.component.tsx +39 -18
- package/src/components/inputs/ui-select-extended/ui-select-extended.test.tsx +0 -1
- package/src/components/inputs/workspace-launcher/workspace-launcher.component.tsx +3 -1
- package/src/components/sidebar/sidebar.component.tsx +5 -6
- package/src/components/sidebar/sidebar.scss +5 -0
- package/src/components/value/value.component.tsx +4 -1
- package/src/form-engine.component.tsx +17 -13
- package/src/form-engine.scss +8 -0
- package/src/form-engine.test.tsx +44 -1
- package/src/hooks/{useConcepts.tsx → useConcepts.ts} +1 -2
- package/src/hooks/useDataSourceDependentValue.ts +1 -1
- package/src/hooks/{useEncounter.tsx → useEncounter.ts} +9 -1
- package/src/hooks/{useFormJson.tsx → useFormJson.ts} +12 -2
- package/src/hooks/{usePatientData.tsx → usePatientData.ts} +1 -1
- package/src/hooks/usePatientPrograms.ts +29 -23
- package/src/hooks/useProcessorDependencies.ts +14 -4
- package/src/processors/encounter/encounter-form-processor.ts +19 -22
- package/src/types/domain.ts +4 -0
- package/src/types/schema.ts +5 -0
- package/src/utils/common-expression-helpers.test.ts +1 -1
- package/src/utils/common-expression-helpers.ts +10 -7
- package/translations/en.json +3 -3
- package/src/hooks/useClobData.tsx +0 -21
- package/src/hooks/useFieldValidationResults.ts +0 -18
- package/src/hooks/useFormsConfig.tsx +0 -27
- package/src/hooks/useRestMaxResultsCount.ts +0 -5
- package/src/hooks/useSystemSetting.ts +0 -36
- package/src/hooks/{useEncounterRole.tsx → useEncounterRole.ts} +1 -1
- package/src/hooks/{useFormCollapse.tsx → useFormCollapse.ts} +1 -1
@@ -1,17 +1,5 @@
|
|
1
|
-
import {
|
2
|
-
type FormField,
|
3
|
-
type FormPage,
|
4
|
-
type FormProcessorContextProps,
|
5
|
-
type FormSchema,
|
6
|
-
type FormSection,
|
7
|
-
type ValueAndDisplay,
|
8
|
-
} from '../../types';
|
9
|
-
import { usePatientPrograms } from '../../hooks/usePatientPrograms';
|
10
1
|
import { useEffect, useState } from 'react';
|
11
|
-
import {
|
12
|
-
import { isEmpty } from '../../validators/form-validator';
|
13
|
-
import { type FormContextProps } from '../../provider/form-provider';
|
14
|
-
import { FormProcessor } from '../form-processor';
|
2
|
+
import { type OpenmrsResource, showSnackbar, translateFrom } from '@openmrs/esm-framework';
|
15
3
|
import {
|
16
4
|
getMutableSessionProps,
|
17
5
|
hydrateRepeatField,
|
@@ -23,23 +11,32 @@ import {
|
|
23
11
|
savePatientIdentifiers,
|
24
12
|
savePatientPrograms,
|
25
13
|
} from './encounter-processor-helper';
|
26
|
-
import {
|
27
|
-
|
14
|
+
import {
|
15
|
+
type FormField,
|
16
|
+
type FormPage,
|
17
|
+
type FormProcessorContextProps,
|
18
|
+
type FormSchema,
|
19
|
+
type FormSection,
|
20
|
+
type ValueAndDisplay,
|
21
|
+
} from '../../types';
|
22
|
+
import { evaluateAsyncExpression, type FormNode } from '../../utils/expression-runner';
|
28
23
|
import { extractErrorMessagesFromResponse } from '../../utils/error-utils';
|
24
|
+
import { extractObsValueAndDisplay } from '../../utils/form-helper';
|
25
|
+
import { FormProcessor } from '../form-processor';
|
29
26
|
import { getPreviousEncounter, saveEncounter } from '../../api';
|
30
|
-
import { useEncounterRole } from '../../hooks/useEncounterRole';
|
31
|
-
import { evaluateAsyncExpression, type FormNode } from '../../utils/expression-runner';
|
32
27
|
import { hasRendering } from '../../utils/common-utils';
|
33
|
-
import {
|
28
|
+
import { isEmpty } from '../../validators/form-validator';
|
29
|
+
import { moduleName } from '../../globals';
|
30
|
+
import { type FormContextProps } from '../../provider/form-provider';
|
31
|
+
import { useEncounter } from '../../hooks/useEncounter';
|
32
|
+
import { useEncounterRole } from '../../hooks/useEncounterRole';
|
33
|
+
import { usePatientPrograms } from '../../hooks/usePatientPrograms';
|
34
34
|
|
35
35
|
function useCustomHooks(context: Partial<FormProcessorContextProps>) {
|
36
36
|
const [isLoading, setIsLoading] = useState(true);
|
37
37
|
const { encounter, isLoading: isLoadingEncounter } = useEncounter(context.formJson);
|
38
38
|
const { encounterRole, isLoading: isLoadingEncounterRole } = useEncounterRole();
|
39
|
-
const {
|
40
|
-
context.patient?.id,
|
41
|
-
context.formJson,
|
42
|
-
);
|
39
|
+
const { isLoadingPatientPrograms, patientPrograms } = usePatientPrograms(context.patient?.id, context.formJson);
|
43
40
|
|
44
41
|
useEffect(() => {
|
45
42
|
setIsLoading(isLoadingPatientPrograms || isLoadingEncounter || isLoadingEncounterRole);
|
package/src/types/domain.ts
CHANGED
@@ -165,6 +165,10 @@ export interface PatientProgram extends OpenmrsResource {
|
|
165
165
|
states?: Array<ProgramWorkflowState>;
|
166
166
|
}
|
167
167
|
|
168
|
+
export interface ProgramsFetchResponse {
|
169
|
+
results: Array<PatientProgram>;
|
170
|
+
}
|
171
|
+
|
168
172
|
export interface PatientProgramPayload {
|
169
173
|
program?: string;
|
170
174
|
uuid?: string;
|
package/src/types/schema.ts
CHANGED
@@ -84,6 +84,7 @@ export interface FormField {
|
|
84
84
|
questionInfo?: string;
|
85
85
|
historicalExpression?: string;
|
86
86
|
constrainMaxWidth?: boolean;
|
87
|
+
hideSteppers?: boolean;
|
87
88
|
/** @deprecated */
|
88
89
|
inlineMultiCheckbox?: boolean;
|
89
90
|
meta?: QuestionMetaProps;
|
@@ -143,6 +144,10 @@ export interface FormQuestionOptions {
|
|
143
144
|
*/
|
144
145
|
max?: string;
|
145
146
|
min?: string;
|
147
|
+
/**
|
148
|
+
* specifies the increment or decrement step for number field values
|
149
|
+
*/
|
150
|
+
step?: number;
|
146
151
|
/**
|
147
152
|
* maxLength and maxLength are used to validate text field length
|
148
153
|
*/
|
@@ -171,7 +171,7 @@ describe('CommonExpressionHelpers', () => {
|
|
171
171
|
it('should return the correct number of months on ART', () => {
|
172
172
|
const artStartDate = new Date('2020-01-01');
|
173
173
|
const today = new Date();
|
174
|
-
const monthsOnART =
|
174
|
+
const monthsOnART = dayjs(today).diff(dayjs(artStartDate), 'months');
|
175
175
|
expect(helpers.calcMonthsOnART(artStartDate)).toBe(monthsOnART);
|
176
176
|
});
|
177
177
|
|
@@ -118,19 +118,22 @@ export class CommonExpressionHelpers {
|
|
118
118
|
};
|
119
119
|
|
120
120
|
calcMonthsOnART = (artStartDate: Date) => {
|
121
|
-
if (artStartDate == null)
|
121
|
+
if (artStartDate == null) {
|
122
|
+
return null;
|
123
|
+
}
|
122
124
|
|
123
125
|
if (!(artStartDate instanceof Date)) {
|
124
126
|
throw new Error('DateFormatException: value passed is not a valid date');
|
125
127
|
}
|
126
128
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
if (
|
131
|
-
|
129
|
+
const today = new Date();
|
130
|
+
const artInDays = Math.round((today.getTime() - artStartDate.getTime()) / 86400000);
|
131
|
+
|
132
|
+
if (artInDays < 30) {
|
133
|
+
return 0;
|
132
134
|
}
|
133
|
-
|
135
|
+
|
136
|
+
return dayjs(today).diff(artStartDate, 'month');
|
134
137
|
};
|
135
138
|
|
136
139
|
calcViralLoadStatus = (viralLoadCount: number) => {
|
package/translations/en.json
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
"add": "Add",
|
3
3
|
"addCameraImage": "Add camera image",
|
4
4
|
"addFile": "Add files",
|
5
|
+
"blank": "Blank",
|
5
6
|
"cameraCapture": "Camera capture",
|
6
7
|
"cancel": "Cancel",
|
7
8
|
"chooseAnOption": "Choose an option",
|
@@ -17,7 +18,7 @@
|
|
17
18
|
"fileUploadDescriptionAny": "Upload any file type",
|
18
19
|
"invalidWorkspaceName": "Invalid workspace name.",
|
19
20
|
"invalidWorkspaceNameSubtitle": "Please provide a valid workspace name.",
|
20
|
-
"launchWorkspace": "",
|
21
|
+
"launchWorkspace": "Launch Workspace",
|
21
22
|
"loading": "Loading",
|
22
23
|
"notification": "Notification",
|
23
24
|
"nullMandatoryField": "Please fill the required fields",
|
@@ -26,13 +27,12 @@
|
|
26
27
|
"remove": "Remove",
|
27
28
|
"required": "Required",
|
28
29
|
"reuseValue": "Reuse value",
|
29
|
-
"revert": "Revert",
|
30
30
|
"save": "Save",
|
31
31
|
"search": "Search",
|
32
|
+
"searching": "Searching",
|
32
33
|
"submitting": "Submitting",
|
33
34
|
"time": "Time",
|
34
35
|
"unspecified": "Unspecified",
|
35
|
-
"unspecifyAll": "Unspecify All",
|
36
36
|
"upload": "Upload",
|
37
37
|
"uploadedPhoto": "Uploaded photo",
|
38
38
|
"uploadImage": "Upload image",
|
@@ -1,21 +0,0 @@
|
|
1
|
-
import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
|
2
|
-
import { useMemo } from 'react';
|
3
|
-
import { type FormSchema, type OpenmrsForm } from '../types';
|
4
|
-
import useSWRImmutable from 'swr/immutable';
|
5
|
-
|
6
|
-
export function useClobData(form: OpenmrsForm) {
|
7
|
-
const valueReferenceUuid = useMemo(
|
8
|
-
() => form?.resources?.find(({ name }) => name === 'JSON schema').valueReference,
|
9
|
-
[form],
|
10
|
-
);
|
11
|
-
const { data, error } = useSWRImmutable<{ data: FormSchema }, Error>(
|
12
|
-
valueReferenceUuid ? `${restBaseUrl}/clobdata/${valueReferenceUuid}` : null,
|
13
|
-
openmrsFetch,
|
14
|
-
);
|
15
|
-
|
16
|
-
return {
|
17
|
-
clobdata: data?.data,
|
18
|
-
clobdataError: error || null,
|
19
|
-
isLoadingClobData: (!data && !error) || false,
|
20
|
-
};
|
21
|
-
}
|
@@ -1,18 +0,0 @@
|
|
1
|
-
import { useEffect, useState } from 'react';
|
2
|
-
import { type FormField } from '../types';
|
3
|
-
|
4
|
-
export function useFieldValidationResults(field: FormField) {
|
5
|
-
const [errors, setErrors] = useState([]);
|
6
|
-
const [warnings, setWarnings] = useState([]);
|
7
|
-
|
8
|
-
useEffect(() => {
|
9
|
-
if (field.meta?.submission?.errors) {
|
10
|
-
setErrors(field.meta.submission.errors);
|
11
|
-
}
|
12
|
-
if (field.meta?.submission?.warnings) {
|
13
|
-
setWarnings(field.meta.submission.warnings);
|
14
|
-
}
|
15
|
-
}, [field.meta?.submission]);
|
16
|
-
|
17
|
-
return { errors, warnings, setErrors, setWarnings };
|
18
|
-
}
|
@@ -1,27 +0,0 @@
|
|
1
|
-
import { useEffect, useState } from 'react';
|
2
|
-
import get from 'lodash-es/get';
|
3
|
-
import { getConfig } from '@openmrs/esm-framework';
|
4
|
-
import { ConceptTrue, ConceptFalse } from '../constants';
|
5
|
-
|
6
|
-
export interface FormsConfig {
|
7
|
-
conceptTrue: string;
|
8
|
-
conceptFalse: string;
|
9
|
-
}
|
10
|
-
const defaultOptions: FormsConfig = {
|
11
|
-
conceptTrue: ConceptTrue,
|
12
|
-
conceptFalse: ConceptFalse,
|
13
|
-
};
|
14
|
-
|
15
|
-
export function useFormsConfig(moduleName: string, configPath: string) {
|
16
|
-
const [config, setConfig] = useState<FormsConfig>(defaultOptions);
|
17
|
-
|
18
|
-
useEffect(() => {
|
19
|
-
if (moduleName && configPath) {
|
20
|
-
getConfig(moduleName).then((c) => {
|
21
|
-
setConfig({ config, ...get(c, configPath, config) });
|
22
|
-
});
|
23
|
-
}
|
24
|
-
}, [moduleName, configPath, config]);
|
25
|
-
|
26
|
-
return config;
|
27
|
-
}
|
@@ -1,36 +0,0 @@
|
|
1
|
-
import { openmrsFetch, restBaseUrl, showSnackbar } from '@openmrs/esm-framework';
|
2
|
-
import { useEffect } from 'react';
|
3
|
-
import { useTranslation } from 'react-i18next';
|
4
|
-
import useSWRImmutable from 'swr/immutable';
|
5
|
-
|
6
|
-
export interface SystemSetting {
|
7
|
-
uuid: string;
|
8
|
-
property: string;
|
9
|
-
value: string;
|
10
|
-
}
|
11
|
-
|
12
|
-
export default function useSystemSetting(setting: string) {
|
13
|
-
const { t } = useTranslation();
|
14
|
-
const apiUrl = `${restBaseUrl}/systemsetting/${setting}?v=custom:(value)`;
|
15
|
-
const { data, error, isLoading } = useSWRImmutable<{ data: SystemSetting }, Error>(apiUrl, openmrsFetch);
|
16
|
-
|
17
|
-
useEffect(() => {
|
18
|
-
if (error) {
|
19
|
-
showSnackbar({
|
20
|
-
title: t('error', 'Error'),
|
21
|
-
subtitle: error?.message,
|
22
|
-
kind: 'error',
|
23
|
-
isLowContrast: false,
|
24
|
-
});
|
25
|
-
}
|
26
|
-
}, [error]);
|
27
|
-
|
28
|
-
return {
|
29
|
-
systemSetting: data?.data,
|
30
|
-
error: error,
|
31
|
-
isLoading: isLoading,
|
32
|
-
isValueUuid:
|
33
|
-
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(data?.data?.value) ||
|
34
|
-
/^[0-9a-f]{36}$/i.test(data?.data?.value),
|
35
|
-
};
|
36
|
-
}
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import { type OpenmrsResource, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
|
2
1
|
import useSWRImmutable from 'swr/immutable';
|
2
|
+
import { type OpenmrsResource, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
|
3
3
|
|
4
4
|
export function useEncounterRole() {
|
5
5
|
const { data, error, isLoading } = useSWRImmutable<{ data: { results: Array<OpenmrsResource> } }, Error>(
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import type { FormExpanded, SessionMode } from '../types';
|
2
1
|
import { useCallback, useEffect, useState } from 'react';
|
2
|
+
import type { FormExpanded, SessionMode } from '../types';
|
3
3
|
|
4
4
|
export function useFormCollapse(sessionMode: SessionMode) {
|
5
5
|
const [isFormExpanded, setIsFormExpanded] = useState<FormExpanded>(undefined);
|