@openmrs/esm-form-engine-lib 4.2.2-pre.2543 → 4.2.2-pre.2550

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.
Files changed (35) hide show
  1. package/dist/components/processor-factory/form-processor-factory.component.js +111 -39
  2. package/dist/components/renderer/custom-hooks-renderer.component.js +2 -2
  3. package/dist/form-engine.component.js +5 -3
  4. package/dist/hooks/useFormFieldValidators.js +22 -12
  5. package/dist/hooks/useFormFieldValueAdapters.js +22 -15
  6. package/dist/hooks/useFormFields.js +35 -42
  7. package/dist/hooks/useInitialValues.js +12 -5
  8. package/dist/hooks/useProcessorDependencies.js +2 -2
  9. package/dist/processors/encounter/encounter-form-processor.js +10 -20
  10. package/dist/processors/form-processor.js +4 -1
  11. package/dist/src/components/processor-factory/form-processor-factory.component.d.ts.map +1 -1
  12. package/dist/src/components/renderer/custom-hooks-renderer.component.d.ts +5 -8
  13. package/dist/src/components/renderer/custom-hooks-renderer.component.d.ts.map +1 -1
  14. package/dist/src/form-engine.component.d.ts.map +1 -1
  15. package/dist/src/hooks/useFormFieldValidators.d.ts.map +1 -1
  16. package/dist/src/hooks/useFormFieldValueAdapters.d.ts.map +1 -1
  17. package/dist/src/hooks/useFormFields.d.ts.map +1 -1
  18. package/dist/src/hooks/useInitialValues.d.ts.map +1 -1
  19. package/dist/src/hooks/useProcessorDependencies.d.ts +2 -2
  20. package/dist/src/hooks/useProcessorDependencies.d.ts.map +1 -1
  21. package/dist/src/processors/encounter/encounter-form-processor.d.ts +6 -3
  22. package/dist/src/processors/encounter/encounter-form-processor.d.ts.map +1 -1
  23. package/dist/src/processors/form-processor.d.ts +21 -2
  24. package/dist/src/processors/form-processor.d.ts.map +1 -1
  25. package/package.json +1 -1
  26. package/src/components/processor-factory/form-processor-factory.component.tsx +151 -35
  27. package/src/components/renderer/custom-hooks-renderer.component.tsx +6 -8
  28. package/src/form-engine.component.tsx +6 -4
  29. package/src/hooks/useFormFieldValidators.ts +23 -13
  30. package/src/hooks/useFormFieldValueAdapters.ts +23 -16
  31. package/src/hooks/useFormFields.ts +28 -41
  32. package/src/hooks/useInitialValues.ts +15 -6
  33. package/src/hooks/useProcessorDependencies.ts +4 -3
  34. package/src/processors/encounter/encounter-form-processor.ts +12 -21
  35. package/src/processors/form-processor.ts +27 -1
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useMemo, useState } from "react";
1
+ import React, { useCallback, useEffect, useMemo, useState } from "react";
2
2
  import useProcessorDependencies from "../../hooks/useProcessorDependencies.js";
3
3
  import useInitialValues from "../../hooks/useInitialValues.js";
4
4
  import { FormRenderer } from "../renderer/form/form-renderer.component.js";
@@ -14,8 +14,29 @@ import { reportError } from "../../utils/error-utils.js";
14
14
  import { useTranslation } from "react-i18next";
15
15
  import Loader from "../loaders/loader.component.js";
16
16
  import { registerFormFieldAdaptersForCleanUp } from "../../lifecycle.js";
17
+ /** Context properties this component derives; a processor that sets one of these is ignored. */ const factoryOwnedContextKeys = [
18
+ 'patient',
19
+ 'formJson',
20
+ 'visit',
21
+ 'sessionMode',
22
+ 'sessionDate',
23
+ 'location',
24
+ 'currentProvider',
25
+ 'layoutType',
26
+ 'processor',
27
+ 'formFields',
28
+ 'formFieldAdapters',
29
+ 'formFieldValidators'
30
+ ];
31
+ function warnAboutIgnoredContextKeys(previous, next) {
32
+ const ignored = factoryOwnedContextKeys.filter((key)=>key in next && next[key] !== previous[key]);
33
+ if (ignored.length) {
34
+ console.warn(`A form processor tried to set the context propert${ignored.length === 1 ? 'y' : 'ies'} ` + `${ignored.join(', ')}, which the form engine derives itself. ${ignored.length === 1 ? 'It was' : 'They were'} ignored. Use the setters passed alongside setContext to update the domain object or custom dependencies.`);
35
+ }
36
+ }
17
37
  const FormProcessorFactory = ({ formJson, isSubForm = false, setIsLoadingFormDependencies })=>{
18
38
  const { patient, sessionMode, formProcessors, layoutType, location, provider, sessionDate, visit } = useFormFactory();
39
+ const { t } = useTranslation();
19
40
  const processor = useMemo(()=>{
20
41
  const ProcessorClass = formProcessors[formJson.processor];
21
42
  let processorInstance;
@@ -31,66 +52,116 @@ const FormProcessorFactory = ({ formJson, isSubForm = false, setIsLoadingFormDep
31
52
  formProcessors,
32
53
  formJson.processor
33
54
  ]);
34
- const [processorContext, setProcessorContext] = useState({
55
+ // Derive form fields and related data
56
+ const { formFields: rawFormFields, conceptReferences } = useFormFields(formJson);
57
+ const { concepts: formFieldsConcepts, isLoading: isLoadingConcepts } = useConcepts(Array.from(conceptReferences));
58
+ const formFieldsWithMeta = useFormFieldsMeta(rawFormFields, formFieldsConcepts);
59
+ const formFieldAdapters = useFormFieldValueAdapters(rawFormFields);
60
+ const formFieldValidators = useFormFieldValidators(rawFormFields);
61
+ const formFields = useMemo(()=>formFieldsWithMeta?.length ? formFieldsWithMeta : rawFormFields ?? [], [
62
+ formFieldsWithMeta,
63
+ rawFormFields
64
+ ]);
65
+ // We divide the context into the "mutable" parts, which can be changed by custom hooks
66
+ // and the "static" parts
67
+ const [mutableContext, setMutableContext] = useState({});
68
+ // Create the "static" part of the context
69
+ const baseContext = useMemo(()=>({
70
+ patient,
71
+ formJson,
72
+ sessionMode,
73
+ layoutType,
74
+ location,
75
+ currentProvider: provider,
76
+ processor,
77
+ sessionDate,
78
+ visit,
79
+ formFields,
80
+ formFieldAdapters: formFieldAdapters ?? {},
81
+ formFieldValidators: formFieldValidators ?? {}
82
+ }), [
35
83
  patient,
36
84
  formJson,
37
85
  sessionMode,
38
86
  layoutType,
39
87
  location,
40
- currentProvider: provider,
88
+ provider,
41
89
  processor,
42
90
  sessionDate,
43
91
  visit,
44
- formFields: [],
45
- formFieldAdapters: {},
46
- formFieldValidators: {}
47
- });
48
- const { t } = useTranslation();
49
- const { formFields: rawFormFields, conceptReferences } = useFormFields(formJson);
50
- const { concepts: formFieldsConcepts, isLoading: isLoadingConcepts } = useConcepts(Array.from(conceptReferences));
51
- const formFieldsWithMeta = useFormFieldsMeta(rawFormFields, formFieldsConcepts);
52
- const formFieldAdapters = useFormFieldValueAdapters(rawFormFields);
53
- const formFieldValidators = useFormFieldValidators(rawFormFields);
54
- const { isLoading: isLoadingCustomDeps } = useProcessorDependencies(processor, processorContext, setProcessorContext);
92
+ formFields,
93
+ formFieldAdapters,
94
+ formFieldValidators
95
+ ]);
96
+ // re-create the full processor context
97
+ const processorContext = useMemo(()=>({
98
+ ...baseContext,
99
+ ...mutableContext
100
+ }), [
101
+ baseContext,
102
+ mutableContext
103
+ ]);
104
+ // callback to update the mutable part of the context
105
+ const setProcessorContext = useCallback((updater)=>{
106
+ setMutableContext((prevMutable)=>{
107
+ // Build the "previous" full context to pass to the updater
108
+ const prevFull = {
109
+ ...baseContext,
110
+ ...prevMutable
111
+ };
112
+ const newFull = typeof updater === 'function' ? updater(prevFull) : updater;
113
+ // Only the updater form sees prevFull; a bare object may be a stale context, whose
114
+ // differences aren't attempted writes.
115
+ if (typeof updater === 'function') {
116
+ warnAboutIgnoredContextKeys(prevFull, newFull);
117
+ }
118
+ // Extract only the mutable parts from the result
119
+ return {
120
+ domainObjectValue: newFull.domainObjectValue,
121
+ previousDomainObjectValue: newFull.previousDomainObjectValue,
122
+ customDependencies: newFull.customDependencies
123
+ };
124
+ });
125
+ }, [
126
+ baseContext
127
+ ]);
128
+ const processorSetters = useMemo(()=>({
129
+ setDomainObjectValue: (value)=>setMutableContext((prev)=>({
130
+ ...prev,
131
+ domainObjectValue: value
132
+ })),
133
+ setPreviousDomainObjectValue: (value)=>setMutableContext((prev)=>({
134
+ ...prev,
135
+ previousDomainObjectValue: value
136
+ })),
137
+ setCustomDependencies: (dependencies)=>setMutableContext((prev)=>({
138
+ ...prev,
139
+ customDependencies: typeof dependencies === 'function' ? dependencies(prev.customDependencies ?? {}) : dependencies
140
+ }))
141
+ }), []);
142
+ const { isLoading: isLoadingCustomDeps } = useProcessorDependencies(processor, processorContext, setProcessorContext, processorSetters);
55
143
  const useCustomHooks = processor.getCustomHooks().useCustomHooks;
56
144
  const [isLoadingCustomHooks, setIsLoadingCustomHooks] = useState(!!useCustomHooks);
57
- const [isLoadingProcessorDependencies, setIsLoadingProcessorDependencies] = useState(true);
58
145
  const { isLoadingInitialValues, initialValues, error: initialValuesError } = useInitialValues(processor, isLoadingCustomDeps || isLoadingCustomHooks || isLoadingConcepts, processorContext);
59
- useEffect(()=>{
60
- const isLoading = isLoadingCustomDeps || isLoadingCustomHooks || isLoadingConcepts || isLoadingInitialValues;
61
- setIsLoadingFormDependencies(isLoading);
62
- setIsLoadingProcessorDependencies(isLoading);
63
- }, [
146
+ // Derive loading state with useMemo to avoid effect-based state updates
147
+ const isLoadingProcessorDependencies = useMemo(()=>isLoadingCustomDeps || isLoadingCustomHooks || isLoadingConcepts || isLoadingInitialValues, [
64
148
  isLoadingCustomDeps,
65
149
  isLoadingCustomHooks,
66
150
  isLoadingConcepts,
67
151
  isLoadingInitialValues
68
152
  ]);
153
+ // Notify parent of loading state changes
69
154
  useEffect(()=>{
70
- setProcessorContext((prev)=>({
71
- ...prev,
72
- ...formFieldAdapters && {
73
- formFieldAdapters
74
- },
75
- ...formFieldValidators && {
76
- formFieldValidators
77
- },
78
- ...formFieldsWithMeta?.length ? {
79
- formFields: formFieldsWithMeta
80
- } : rawFormFields?.length ? {
81
- formFields: rawFormFields
82
- } : {}
83
- }));
155
+ setIsLoadingFormDependencies(isLoadingProcessorDependencies);
84
156
  }, [
85
- formFieldAdapters,
86
- formFieldValidators,
87
- rawFormFields,
88
- formFieldsWithMeta
157
+ isLoadingProcessorDependencies,
158
+ setIsLoadingFormDependencies
89
159
  ]);
90
160
  useEffect(()=>{
91
161
  reportError(initialValuesError, t('errorLoadingInitialValues', 'Error loading initial values'));
92
162
  }, [
93
- initialValuesError
163
+ initialValuesError,
164
+ t
94
165
  ]);
95
166
  useEffect(()=>{
96
167
  if (formFieldAdapters) {
@@ -102,6 +173,7 @@ const FormProcessorFactory = ({ formJson, isSubForm = false, setIsLoadingFormDep
102
173
  return /*#__PURE__*/ React.createElement(React.Fragment, null, useCustomHooks && /*#__PURE__*/ React.createElement(CustomHooksRenderer, {
103
174
  context: processorContext,
104
175
  setContext: setProcessorContext,
176
+ setters: processorSetters,
105
177
  useCustomHooks: useCustomHooks,
106
178
  setIsLoadingCustomHooks: setIsLoadingCustomHooks
107
179
  }), isLoadingProcessorDependencies && !isSubForm ? /*#__PURE__*/ React.createElement(Loader, null) : /*#__PURE__*/ React.createElement(FormRenderer, {
@@ -1,9 +1,9 @@
1
1
  import { useEffect } from "react";
2
- export const CustomHooksRenderer = ({ context, setContext, useCustomHooks, setIsLoadingCustomHooks })=>{
2
+ export const CustomHooksRenderer = ({ context, setContext, setters, useCustomHooks, setIsLoadingCustomHooks })=>{
3
3
  const { isLoading = false, error = null, data, updateContext } = useCustomHooks(context);
4
4
  useEffect(()=>{
5
5
  if (!isLoading && updateContext) {
6
- updateContext(setContext);
6
+ updateContext(setContext, setters);
7
7
  setIsLoadingCustomHooks(false);
8
8
  }
9
9
  }, [
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
1
+ import React, { Suspense, useCallback, useEffect, useMemo, useRef, useState } from "react";
2
2
  import classNames from "classnames";
3
3
  import { Button, ButtonSet, InlineLoading } from "@carbon/react";
4
4
  import { I18nextProvider, useTranslation } from "react-i18next";
@@ -173,9 +173,11 @@ const FormEngine = ({ formJson, patientUUID, formUUID, encounterUUID, visit, for
173
173
  }) : /*#__PURE__*/ React.createElement("span", null, `${t('save', 'Save')}`))))))));
174
174
  };
175
175
  function I18FormEngine(props) {
176
- return /*#__PURE__*/ React.createElement(I18nextProvider, {
176
+ return /*#__PURE__*/ React.createElement(Suspense, {
177
+ fallback: /*#__PURE__*/ React.createElement(Loader, null)
178
+ }, /*#__PURE__*/ React.createElement(I18nextProvider, {
177
179
  i18n: window.i18next,
178
180
  defaultNS: formEngineAppName
179
- }, /*#__PURE__*/ React.createElement(FormEngine, props));
181
+ }, /*#__PURE__*/ React.createElement(FormEngine, props)));
180
182
  }
181
183
  export default I18FormEngine;
@@ -1,20 +1,30 @@
1
- import { useEffect, useState } from "react";
1
+ import { useMemo } from "react";
2
+ import useSWRImmutable from "swr/immutable";
2
3
  import { getRegisteredValidator } from "../registry/registry.js";
4
+ const EMPTY_VALIDATORS = {};
3
5
  export function useFormFieldValidators(fields) {
4
- const [validators, setValidators] = useState();
5
- useEffect(()=>{
6
- const supportedTypes = new Set();
6
+ const validatorTypesKey = useMemo(()=>{
7
+ const uniqueTypes = new Set();
7
8
  fields.forEach((field)=>{
8
- field.validators?.forEach((validator)=>supportedTypes.add(validator.type));
9
- });
10
- const supportedTypesArray = Array.from(supportedTypes);
11
- Promise.all(supportedTypesArray.map((type)=>getRegisteredValidator(type))).then((validators)=>{
12
- setValidators(Object.assign({}, ...validators.map((validator, index)=>({
13
- [supportedTypesArray[index]]: validator
14
- }))));
9
+ field.validators?.forEach((validator)=>uniqueTypes.add(validator.type));
15
10
  });
11
+ return Array.from(uniqueTypes).sort().join(',');
16
12
  }, [
17
13
  fields
18
14
  ]);
19
- return validators;
15
+ const { data: validators } = useSWRImmutable(validatorTypesKey ? [
16
+ 'formFieldValidators',
17
+ validatorTypesKey
18
+ ] : null, async ([, key])=>{
19
+ const types = key.split(',');
20
+ const loadedValidators = await Promise.all(types.map((type)=>getRegisteredValidator(type)));
21
+ const validatorsByType = {};
22
+ types.forEach((type, index)=>{
23
+ validatorsByType[type] = loadedValidators[index];
24
+ });
25
+ return validatorsByType;
26
+ }, {
27
+ keepPreviousData: true
28
+ });
29
+ return validators ?? EMPTY_VALIDATORS;
20
30
  }
@@ -1,21 +1,28 @@
1
- import { useState, useEffect } from "react";
1
+ import { useMemo } from "react";
2
+ import useSWRImmutable from "swr/immutable";
2
3
  import { getRegisteredFieldValueAdapter } from "../registry/registry.js";
4
+ const EMPTY_ADAPTERS = {};
3
5
  export const useFormFieldValueAdapters = (fields)=>{
4
- const [adapters, setAdapters] = useState({});
5
- useEffect(()=>{
6
- const supportedTypes = new Set();
7
- fields.forEach((field)=>{
8
- supportedTypes.add(field.type);
9
- });
10
- const supportedTypesArray = Array.from(supportedTypes);
11
- Promise.all(supportedTypesArray.map((type)=>getRegisteredFieldValueAdapter(type))).then((adapters)=>{
12
- const adaptersByType = supportedTypesArray.map((type, index)=>({
13
- [type]: adapters[index]
14
- }));
15
- setAdapters(Object.assign({}, ...adaptersByType));
16
- });
6
+ const typesKey = useMemo(()=>{
7
+ const uniqueTypes = new Set();
8
+ fields.forEach((field)=>uniqueTypes.add(field.type));
9
+ return Array.from(uniqueTypes).sort().join(',');
17
10
  }, [
18
11
  fields
19
12
  ]);
20
- return adapters;
13
+ const { data: adapters } = useSWRImmutable(typesKey ? [
14
+ 'formFieldValueAdapters',
15
+ typesKey
16
+ ] : null, async ([, key])=>{
17
+ const types = key.split(',');
18
+ const loadedAdapters = await Promise.all(types.map((type)=>getRegisteredFieldValueAdapter(type)));
19
+ const adaptersByType = {};
20
+ types.forEach((type, index)=>{
21
+ adaptersByType[type] = loadedAdapters[index];
22
+ });
23
+ return adaptersByType;
24
+ }, {
25
+ keepPreviousData: true
26
+ });
27
+ return adapters ?? EMPTY_ADAPTERS;
21
28
  };
@@ -1,60 +1,53 @@
1
1
  import { useMemo } from "react";
2
2
  export function useFormFields(form) {
3
- const [flattenedFields, conceptReferences] = useMemo(()=>{
3
+ const [flattenedFields, conceptReferencesKey] = useMemo(()=>{
4
4
  const flattenedFieldsTemp = [];
5
5
  const conceptReferencesTemp = new Set();
6
- const processFlattenedFields = (fields)=>{
7
- const flattenedFields = [];
8
- const conceptReferences = new Set();
9
- const processField = (field, parentGroupId)=>{
10
- // Add group ID to nested fields if applicable
11
- const processedField = parentGroupId ? {
12
- ...field,
13
- meta: {
14
- ...field.meta,
15
- groupId: parentGroupId
16
- }
17
- } : field;
18
- // Add field to flattened list
19
- flattenedFields.push(processedField);
20
- // Collect concept references
21
- if (processedField.questionOptions?.concept) {
22
- conceptReferences.add(processedField.questionOptions.concept);
6
+ const processField = (field, parentGroupId)=>{
7
+ // Add group ID to nested fields if applicable
8
+ const processedField = parentGroupId ? {
9
+ ...field,
10
+ meta: {
11
+ ...field.meta,
12
+ groupId: parentGroupId
23
13
  }
24
- // Collect concept references from answers
25
- processedField.questionOptions?.answers?.forEach((answer)=>{
26
- if (answer.concept) {
27
- conceptReferences.add(answer.concept);
28
- }
29
- });
30
- // Recursively process nested questions for obsGroup
31
- if (processedField.type === 'obsGroup' && processedField.questions) {
32
- processedField.questions.forEach((nestedField)=>{
33
- processField(nestedField, processedField.id);
34
- });
14
+ } : field;
15
+ // Add field to flattened list
16
+ flattenedFieldsTemp.push(processedField);
17
+ // Collect concept references
18
+ if (processedField.questionOptions?.concept) {
19
+ conceptReferencesTemp.add(processedField.questionOptions.concept);
20
+ }
21
+ // Collect concept references from answers
22
+ processedField.questionOptions?.answers?.forEach((answer)=>{
23
+ if (answer.concept) {
24
+ conceptReferencesTemp.add(answer.concept);
35
25
  }
36
- };
37
- // Process all input fields
38
- fields.forEach((field)=>processField(field));
39
- return {
40
- flattenedFields,
41
- conceptReferences
42
- };
26
+ });
27
+ // Recursively process nested questions for obsGroup
28
+ if (processedField.type === 'obsGroup' && processedField.questions) {
29
+ processedField.questions.forEach((nestedField)=>{
30
+ processField(nestedField, processedField.id);
31
+ });
32
+ }
43
33
  };
34
+ // Process all input fields
44
35
  form.pages?.forEach((page)=>page.sections?.forEach((section)=>{
45
- if (section.questions) {
46
- const { flattenedFields, conceptReferences } = processFlattenedFields(section.questions);
47
- flattenedFieldsTemp.push(...flattenedFields);
48
- conceptReferences.forEach((conceptReference)=>conceptReferencesTemp.add(conceptReference));
49
- }
36
+ section.questions?.forEach((field)=>processField(field));
50
37
  }));
38
+ // Serialised so the set below is rebuilt only when the references change. JSON rather than a
39
+ // delimiter because mapping codes may contain any character, commas included.
40
+ const sortedRefs = Array.from(conceptReferencesTemp).sort();
51
41
  return [
52
42
  flattenedFieldsTemp,
53
- conceptReferencesTemp
43
+ JSON.stringify(sortedRefs)
54
44
  ];
55
45
  }, [
56
46
  form
57
47
  ]);
48
+ const conceptReferences = useMemo(()=>new Set(JSON.parse(conceptReferencesKey)), [
49
+ conceptReferencesKey
50
+ ]);
58
51
  return {
59
52
  formFields: flattenedFields,
60
53
  conceptReferences
@@ -1,11 +1,18 @@
1
- import { useEffect, useState } from "react";
1
+ import { useEffect, useRef, useState } from "react";
2
2
  const useInitialValues = (formProcessor, isLoadingContextDependencies, context)=>{
3
3
  const [isLoadingInitialValues, setIsLoadingInitialValues] = useState(true);
4
4
  const [initialValues, setInitialValues] = useState({});
5
5
  const [error, setError] = useState(null);
6
+ const contextRef = useRef(context);
7
+ contextRef.current = context;
8
+ const hasStartedLoading = useRef(false);
9
+ const hasFormFields = context.formFields?.length > 0;
10
+ const hasFormFieldAdapters = Object.keys(context.formFieldAdapters ?? {}).length > 0;
6
11
  useEffect(()=>{
7
- if (formProcessor && !isLoadingContextDependencies && context.formFields?.length && Object.keys(context.formFieldAdapters).length && !Object.keys(initialValues).length) {
8
- formProcessor.getInitialValues(context).then((values)=>{
12
+ if (formProcessor && !isLoadingContextDependencies && hasFormFields && hasFormFieldAdapters && !hasStartedLoading.current) {
13
+ hasStartedLoading.current = true;
14
+ const currentContext = contextRef.current;
15
+ formProcessor.getInitialValues(currentContext).then((values)=>{
9
16
  setInitialValues(values);
10
17
  setIsLoadingInitialValues(false);
11
18
  }).catch((error)=>{
@@ -17,8 +24,8 @@ const useInitialValues = (formProcessor, isLoadingContextDependencies, context)=
17
24
  }, [
18
25
  formProcessor,
19
26
  isLoadingContextDependencies,
20
- context,
21
- initialValues
27
+ hasFormFields,
28
+ hasFormFieldAdapters
22
29
  ]);
23
30
  return {
24
31
  isLoadingInitialValues,
@@ -1,6 +1,6 @@
1
1
  import { useEffect, useState } from "react";
2
2
  import { reportError } from "../utils/error-utils.js";
3
- const useProcessorDependencies = (formProcessor, context, setContext)=>{
3
+ const useProcessorDependencies = (formProcessor, context, setContext, setters)=>{
4
4
  const [isLoading, setIsLoading] = useState(false);
5
5
  const [error, setError] = useState('');
6
6
  const { loadDependencies } = formProcessor;
@@ -8,7 +8,7 @@ const useProcessorDependencies = (formProcessor, context, setContext)=>{
8
8
  let ignore = false;
9
9
  if (loadDependencies) {
10
10
  setIsLoading(true);
11
- loadDependencies(context, setContext).then(()=>{
11
+ loadDependencies(context, setContext, setters).then(()=>{
12
12
  if (!ignore) {
13
13
  setIsLoading(false);
14
14
  }
@@ -32,19 +32,14 @@ function useCustomHooks(context) {
32
32
  },
33
33
  isLoading,
34
34
  error: null,
35
- updateContext: (setContext)=>{
36
- setContext((context)=>{
37
- context.processor.domainObjectValue = encounter;
38
- return {
39
- ...context,
40
- domainObjectValue: encounter,
41
- customDependencies: {
42
- ...context.customDependencies,
43
- patientPrograms: patientPrograms,
44
- defaultEncounterRole: encounterRole
45
- }
46
- };
47
- });
35
+ updateContext: (_setContext, { setDomainObjectValue, setCustomDependencies })=>{
36
+ context.processor.domainObjectValue = encounter;
37
+ setDomainObjectValue(encounter);
38
+ setCustomDependencies((previous)=>({
39
+ ...previous,
40
+ patientPrograms: patientPrograms,
41
+ defaultEncounterRole: encounterRole
42
+ }));
48
43
  }
49
44
  };
50
45
  }
@@ -293,15 +288,10 @@ export class EncounterFormProcessor extends FormProcessor {
293
288
  }
294
289
  return initialValues;
295
290
  }
296
- async loadDependencies(context, setContext) {
291
+ async loadDependencies(context, _setContext, { setPreviousDomainObjectValue }) {
297
292
  const { patient, formJson } = context;
298
293
  const encounter = await getPreviousEncounter(patient?.id, formJson.encounterType);
299
- setContext((context)=>{
300
- return {
301
- ...context,
302
- previousDomainObjectValue: encounter
303
- };
304
- });
294
+ setPreviousDomainObjectValue(encounter);
305
295
  return context;
306
296
  }
307
297
  async getHistoricalValue(field, context) {
@@ -15,7 +15,10 @@ export class FormProcessor {
15
15
  getDomainObject() {
16
16
  return this.domainObjectValue;
17
17
  }
18
- async loadDependencies(context, setContext) {
18
+ /**
19
+ * Loads whatever the processor needs before the form can render, merging the results into the
20
+ * processor context. `setContext` is deprecated; use `setters`.
21
+ */ async loadDependencies(context, setContext, setters) {
19
22
  return Promise.resolve({});
20
23
  }
21
24
  constructor(formJson){
@@ -1 +1 @@
1
- {"version":3,"file":"form-processor-factory.component.d.ts","sourceRoot":"","sources":["../../../../src/components/processor-factory/form-processor-factory.component.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAI5D,OAAO,EAAkC,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAc9E,UAAU,yBAAyB;IACjC,QAAQ,EAAE,UAAU,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,4BAA4B,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;CAC5D;AAED,QAAA,MAAM,oBAAoB,GAAI,wDAI3B,yBAAyB,sBAiG3B,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"form-processor-factory.component.d.ts","sourceRoot":"","sources":["../../../../src/components/processor-factory/form-processor-factory.component.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoD,MAAM,OAAO,CAAC;AAKzE,OAAO,EAAkC,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAe9E,UAAU,yBAAyB;IACjC,QAAQ,EAAE,UAAU,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,4BAA4B,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;CAC5D;AAqCD,QAAA,MAAM,oBAAoB,GAAI,wDAI3B,yBAAyB,sBAgL3B,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
@@ -1,13 +1,10 @@
1
1
  import { type FormProcessorContextProps } from '../../types';
2
- export declare const CustomHooksRenderer: ({ context, setContext, useCustomHooks, setIsLoadingCustomHooks, }: {
2
+ import { type FormProcessorContextSetters, type GetCustomHooksResponse } from '../../processors/form-processor';
3
+ export declare const CustomHooksRenderer: ({ context, setContext, setters, useCustomHooks, setIsLoadingCustomHooks, }: {
3
4
  context: FormProcessorContextProps;
4
- setContext: (context: FormProcessorContextProps) => void;
5
- useCustomHooks: (context: Partial<FormProcessorContextProps>) => {
6
- data: any;
7
- isLoading: boolean;
8
- error: any;
9
- updateContext: (setContext: React.Dispatch<React.SetStateAction<FormProcessorContextProps>>) => void;
10
- };
5
+ setContext: React.Dispatch<React.SetStateAction<FormProcessorContextProps>>;
6
+ setters: FormProcessorContextSetters;
7
+ useCustomHooks: GetCustomHooksResponse["useCustomHooks"];
11
8
  setIsLoadingCustomHooks: (isLoading: boolean) => void;
12
9
  }) => any;
13
10
  //# sourceMappingURL=custom-hooks-renderer.component.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"custom-hooks-renderer.component.d.ts","sourceRoot":"","sources":["../../../../src/components/renderer/custom-hooks-renderer.component.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAE7D,eAAO,MAAM,mBAAmB,GAAI,mEAKjC;IACD,OAAO,EAAE,yBAAyB,CAAC;IACnC,UAAU,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,IAAI,CAAC;IACzD,cAAc,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,yBAAyB,CAAC,KAAK;QAC/D,IAAI,EAAE,GAAG,CAAC;QACV,SAAS,EAAE,OAAO,CAAC;QACnB,KAAK,EAAE,GAAG,CAAC;QACX,aAAa,EAAE,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,yBAAyB,CAAC,CAAC,KAAK,IAAI,CAAC;KACtG,CAAC;IACF,uBAAuB,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;CACvD,QAWA,CAAC"}
1
+ {"version":3,"file":"custom-hooks-renderer.component.d.ts","sourceRoot":"","sources":["../../../../src/components/renderer/custom-hooks-renderer.component.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,KAAK,2BAA2B,EAAE,KAAK,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAEhH,eAAO,MAAM,mBAAmB,GAAI,4EAMjC;IACD,OAAO,EAAE,yBAAyB,CAAC;IACnC,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,yBAAyB,CAAC,CAAC,CAAC;IAC5E,OAAO,EAAE,2BAA2B,CAAC;IACrC,cAAc,EAAE,sBAAsB,CAAC,gBAAgB,CAAC,CAAC;IACzD,uBAAuB,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;CACvD,QAWA,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"form-engine.component.d.ts","sourceRoot":"","sources":["../../src/form-engine.component.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AAIjF,OAAO,EAAc,KAAK,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAWhE,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAQtF,UAAU,eAAe;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,6BAA6B,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjF,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC;AAkLD,iBAAS,aAAa,CAAC,KAAK,EAAE,eAAe,qBAM5C;AAED,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"form-engine.component.d.ts","sourceRoot":"","sources":["../../src/form-engine.component.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsE,MAAM,OAAO,CAAC;AAI3F,OAAO,EAAc,KAAK,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAWhE,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAQtF,UAAU,eAAe;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,6BAA6B,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjF,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC;AAkLD,iBAAS,aAAa,CAAC,KAAK,EAAE,eAAe,qBAQ5C;AAED,eAAe,aAAa,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useFormFieldValidators.d.ts","sourceRoot":"","sources":["../../../src/hooks/useFormFieldValidators.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAEnE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,sCAiBzD"}
1
+ {"version":3,"file":"useFormFieldValidators.d.ts","sourceRoot":"","sources":["../../../src/hooks/useFormFieldValidators.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAInE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,sCAwBzD"}
@@ -1 +1 @@
1
- {"version":3,"file":"useFormFieldValueAdapters.d.ts","sourceRoot":"","sources":["../../../src/hooks/useFormFieldValueAdapters.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAGtE,eAAO,MAAM,yBAAyB,GAAI,QAAQ,SAAS,EAAE,0CAkB5D,CAAC"}
1
+ {"version":3,"file":"useFormFieldValueAdapters.d.ts","sourceRoot":"","sources":["../../../src/hooks/useFormFieldValueAdapters.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAKtE,eAAO,MAAM,yBAAyB,GAAI,QAAQ,SAAS,EAAE,0CAsB5D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useFormFields.d.ts","sourceRoot":"","sources":["../../../src/hooks/useFormFields.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3D,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG;IAAE,UAAU,EAAE,SAAS,EAAE,CAAC;IAAC,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAAE,CA6D3G"}
1
+ {"version":3,"file":"useFormFields.d.ts","sourceRoot":"","sources":["../../../src/hooks/useFormFields.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3D,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG;IAAE,UAAU,EAAE,SAAS,EAAE,CAAC;IAAC,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAAE,CAgD3G"}
@@ -1 +1 @@
1
- {"version":3,"file":"useInitialValues.d.ts","sourceRoot":"","sources":["../../../src/hooks/useInitialValues.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,QAAA,MAAM,gBAAgB,GACpB,eAAe,aAAa,EAC5B,8BAA8B,OAAO,EACrC,SAAS,yBAAyB;;;;CA6BnC,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"useInitialValues.d.ts","sourceRoot":"","sources":["../../../src/hooks/useInitialValues.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,QAAA,MAAM,gBAAgB,GACpB,eAAe,aAAa,EAC5B,8BAA8B,OAAO,EACrC,SAAS,yBAAyB;;;;CAsCnC,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { type FormProcessorContextProps } from '../types';
2
- import { type FormProcessor } from '../processors/form-processor';
3
- declare const useProcessorDependencies: (formProcessor: FormProcessor, context: Partial<FormProcessorContextProps>, setContext: (context: FormProcessorContextProps) => void) => {
2
+ import { type FormProcessor, type FormProcessorContextSetters } from '../processors/form-processor';
3
+ declare const useProcessorDependencies: (formProcessor: FormProcessor, context: Partial<FormProcessorContextProps>, setContext: React.Dispatch<React.SetStateAction<FormProcessorContextProps>>, setters: FormProcessorContextSetters) => {
4
4
  isLoading: boolean;
5
5
  error: string;
6
6
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useProcessorDependencies.d.ts","sourceRoot":"","sources":["../../../src/hooks/useProcessorDependencies.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAGlE,QAAA,MAAM,wBAAwB,GAC5B,eAAe,aAAa,EAC5B,SAAS,OAAO,CAAC,yBAAyB,CAAC,EAC3C,YAAY,CAAC,OAAO,EAAE,yBAAyB,KAAK,IAAI;;;CA+BzD,CAAC;AAEF,eAAe,wBAAwB,CAAC"}
1
+ {"version":3,"file":"useProcessorDependencies.d.ts","sourceRoot":"","sources":["../../../src/hooks/useProcessorDependencies.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAGpG,QAAA,MAAM,wBAAwB,GAC5B,eAAe,aAAa,EAC5B,SAAS,OAAO,CAAC,yBAAyB,CAAC,EAC3C,YAAY,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,yBAAyB,CAAC,CAAC,EAC3E,SAAS,2BAA2B;;;CA+BrC,CAAC;AAEF,eAAe,wBAAwB,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { type OpenmrsResource } from '@openmrs/esm-framework';
2
2
  import { type FormField, type FormProcessorContextProps, type FormSchema, type ValueAndDisplay } from '../../types';
3
- import { FormProcessor } from '../form-processor';
3
+ import { FormProcessor, type FormProcessorContextSetters } from '../form-processor';
4
4
  import { type FormContextProps } from '../../provider/form-provider';
5
5
  declare function useCustomHooks(context: Partial<FormProcessorContextProps>): {
6
6
  data: {
@@ -10,7 +10,10 @@ declare function useCustomHooks(context: Partial<FormProcessorContextProps>): {
10
10
  };
11
11
  isLoading: boolean;
12
12
  error: any;
13
- updateContext: (setContext: React.Dispatch<React.SetStateAction<FormProcessorContextProps>>) => void;
13
+ updateContext: (_setContext: any, { setDomainObjectValue, setCustomDependencies }: {
14
+ setDomainObjectValue: any;
15
+ setCustomDependencies: any;
16
+ }) => void;
14
17
  };
15
18
  export declare class EncounterFormProcessor extends FormProcessor {
16
19
  prepareFormSchema(schema: FormSchema): FormSchema;
@@ -19,7 +22,7 @@ export declare class EncounterFormProcessor extends FormProcessor {
19
22
  useCustomHooks: typeof useCustomHooks;
20
23
  };
21
24
  getInitialValues(context: FormProcessorContextProps): Promise<{}>;
22
- loadDependencies(context: FormContextProps, setContext: React.Dispatch<React.SetStateAction<FormProcessorContextProps>>): Promise<FormContextProps>;
25
+ loadDependencies(context: FormContextProps, _setContext: React.Dispatch<React.SetStateAction<FormProcessorContextProps>>, { setPreviousDomainObjectValue }: FormProcessorContextSetters): Promise<FormContextProps>;
23
26
  getHistoricalValue(field: FormField, context: FormContextProps): Promise<ValueAndDisplay>;
24
27
  }
25
28
  export {};