@openmrs/esm-react-utils 3.2.1-pre.1039 → 3.2.1-pre.1048

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openmrs/esm-react-utils",
3
- "version": "3.2.1-pre.1039",
3
+ "version": "3.2.1-pre.1048",
4
4
  "license": "MPL-2.0",
5
5
  "description": "React utilities for OpenMRS.",
6
6
  "browser": "dist/openmrs-esm-react-utils.js",
@@ -55,11 +55,11 @@
55
55
  "react-i18next": "11.x"
56
56
  },
57
57
  "devDependencies": {
58
- "@openmrs/esm-api": "^3.2.1-pre.1039",
59
- "@openmrs/esm-config": "^3.2.1-pre.1039",
60
- "@openmrs/esm-error-handling": "^3.2.1-pre.1039",
61
- "@openmrs/esm-extensions": "^3.2.1-pre.1039",
62
- "@openmrs/esm-globals": "^3.2.1-pre.1039",
58
+ "@openmrs/esm-api": "^3.2.1-pre.1048",
59
+ "@openmrs/esm-config": "^3.2.1-pre.1048",
60
+ "@openmrs/esm-error-handling": "^3.2.1-pre.1048",
61
+ "@openmrs/esm-extensions": "^3.2.1-pre.1048",
62
+ "@openmrs/esm-globals": "^3.2.1-pre.1048",
63
63
  "dayjs": "^1.10.8",
64
64
  "i18next": "^19.6.0",
65
65
  "react": "^16.13.1",
@@ -68,5 +68,5 @@
68
68
  "rxjs": "^6.5.3",
69
69
  "unistore": "^3.5.2"
70
70
  },
71
- "gitHead": "5988b37b8acd680071d33155427320d626ede999"
71
+ "gitHead": "bf4a66160d2e39fe676a9cc14f6005936ba0b7bc"
72
72
  }
package/src/useConfig.ts CHANGED
@@ -1,31 +1,50 @@
1
1
  import { useContext, useEffect, useMemo, useState } from "react";
2
2
  import {
3
3
  getConfigStore,
4
- getExtensionConfigStore,
4
+ getExtensionsConfigStore,
5
5
  ConfigStore,
6
+ ExtensionsConfigStore,
7
+ getExtensionConfigFromStore,
6
8
  } from "@openmrs/esm-config";
7
9
  import { ComponentContext, ExtensionData } from "./ComponentContext";
8
10
  import { ConfigObject } from "@openmrs/esm-config";
9
11
  import { Store } from "unistore";
12
+ import isEqual from "lodash-es/isEqual";
10
13
 
11
14
  const promises: Record<string, Promise<ConfigObject>> = {};
12
15
  const errorMessage = `No ComponentContext has been provided. This should come from "openmrsComponentDecorator".
13
16
  Usually this is already applied when using "getAsyncLifecycle" or "getSyncLifecycle".`;
14
17
 
15
- function readInitialConfig(store: Store<ConfigStore> | undefined) {
16
- if (!store) {
17
- return undefined;
18
- } else {
18
+ function readInitialConfig(store: Store<ConfigStore>) {
19
+ return () => {
20
+ const state = store.getState();
21
+
22
+ if (state.loaded && state.config) {
23
+ return state.config;
24
+ }
25
+
26
+ return null;
27
+ };
28
+ }
29
+
30
+ function readInitialExtensionConfig(
31
+ store: Store<ExtensionsConfigStore>,
32
+ extension: ExtensionData | undefined
33
+ ) {
34
+ if (extension) {
19
35
  return () => {
20
36
  const state = store.getState();
21
-
22
- if (state.loaded && state.config) {
23
- return state.config;
37
+ const extConfig = getExtensionConfigFromStore(
38
+ state,
39
+ extension.extensionSlotName,
40
+ extension.extensionId
41
+ );
42
+ if (extConfig.loaded && extConfig.config) {
43
+ return extConfig.config;
24
44
  }
25
-
26
- return undefined;
27
45
  };
28
46
  }
47
+ return null;
29
48
  }
30
49
 
31
50
  function createConfigPromise(store: Store<ConfigStore>) {
@@ -39,7 +58,26 @@ function createConfigPromise(store: Store<ConfigStore>) {
39
58
  });
40
59
  }
41
60
 
42
- function useConfigStore(store: Store<ConfigStore> | undefined) {
61
+ function createExtensionConfigPromise(
62
+ store: Store<ExtensionsConfigStore>,
63
+ extension: ExtensionData
64
+ ) {
65
+ return new Promise<ConfigObject>((resolve) => {
66
+ const unsubscribe = store.subscribe((state) => {
67
+ const extConfig = getExtensionConfigFromStore(
68
+ state,
69
+ extension.extensionSlotName,
70
+ extension.extensionId
71
+ );
72
+ if (extConfig.loaded && extConfig.config) {
73
+ resolve(extConfig.config);
74
+ unsubscribe();
75
+ }
76
+ });
77
+ });
78
+ }
79
+
80
+ function useConfigStore(store: Store<ConfigStore>) {
43
81
  const [state, setState] = useState(readInitialConfig(store));
44
82
 
45
83
  useEffect(() => {
@@ -53,24 +91,45 @@ function useConfigStore(store: Store<ConfigStore> | undefined) {
53
91
  return state;
54
92
  }
55
93
 
56
- function useExtensionConfig(extension: ExtensionData | undefined) {
57
- const store = useMemo(
58
- () =>
59
- extension &&
60
- getExtensionConfigStore(
61
- extension.extensionSlotModuleName,
62
- extension.extensionSlotName,
63
- extension.extensionId
64
- ),
65
- [extension]
94
+ function useExtensionConfigStore(
95
+ store: Store<ExtensionsConfigStore>,
96
+ extension: ExtensionData | undefined
97
+ ) {
98
+ const [config, setConfig] = useState<ConfigObject | null>(
99
+ readInitialExtensionConfig(store, extension)
66
100
  );
67
- const state = useConfigStore(store);
101
+
102
+ useEffect(() => {
103
+ if (extension) {
104
+ return store.subscribe((state) => {
105
+ const extConfig = getExtensionConfigFromStore(
106
+ state,
107
+ extension.extensionSlotName,
108
+ extension.extensionId
109
+ );
110
+ if (
111
+ extConfig.loaded &&
112
+ extConfig.config &&
113
+ !isEqual(extConfig.config, config)
114
+ ) {
115
+ setConfig(extConfig.config);
116
+ }
117
+ });
118
+ }
119
+ }, [store, extension, config]);
120
+
121
+ return config;
122
+ }
123
+
124
+ function useExtensionConfig(extension: ExtensionData | undefined) {
125
+ const store = useMemo(getExtensionsConfigStore, []);
126
+ const state = useExtensionConfigStore(store, extension);
68
127
 
69
128
  if (!state && extension) {
70
- const cacheId = `${extension.extensionSlotModuleName}-${extension.extensionSlotName}-${extension.extensionId}`;
129
+ const cacheId = `${extension.extensionSlotName}-${extension.extensionId}`;
71
130
 
72
131
  if (!promises[cacheId] && store) {
73
- promises[cacheId] = createConfigPromise(store);
132
+ promises[cacheId] = createExtensionConfigPromise(store, extension);
74
133
  }
75
134
 
76
135
  // React will prevent the client component from rendering until the promise resolves