@openmrs/esm-react-utils 3.2.1-pre.967 → 3.2.1-pre.970
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/openmrs-esm-react-utils.js +2 -1
- package/dist/openmrs-esm-react-utils.js.LICENSE.txt +8 -0
- package/dist/openmrs-esm-react-utils.js.map +1 -1
- package/package.json +7 -7
- package/src/Extension.tsx +28 -3
- package/src/ExtensionSlot.tsx +2 -2
- package/src/index.ts +2 -2
- package/src/useAssignedExtensionIds.ts +16 -19
- package/src/useAssignedExtensions.ts +23 -0
- package/src/useConfig.ts +0 -3
- package/src/useConnectedExtensions.ts +10 -36
- package/src/useExtensionInternalStore.ts +10 -0
- package/src/useExtensionSlot.ts +6 -9
- package/src/useExtensionSlotConfig.ts +8 -9
- package/src/useExtensionStore.ts +11 -2
- package/src/useAttachedExtensionIds.ts +0 -18
- package/src/useExtension.ts +0 -31
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openmrs/esm-react-utils",
|
|
3
|
-
"version": "3.2.1-pre.
|
|
3
|
+
"version": "3.2.1-pre.970",
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
5
|
"description": "React utilities for OpenMRS.",
|
|
6
6
|
"browser": "dist/openmrs-esm-react-utils.js",
|
|
@@ -53,11 +53,11 @@
|
|
|
53
53
|
"react-i18next": "11.x"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@openmrs/esm-api": "^3.2.1-pre.
|
|
57
|
-
"@openmrs/esm-config": "^3.2.1-pre.
|
|
58
|
-
"@openmrs/esm-error-handling": "^3.2.1-pre.
|
|
59
|
-
"@openmrs/esm-extensions": "^3.2.1-pre.
|
|
60
|
-
"@openmrs/esm-globals": "^3.2.1-pre.
|
|
56
|
+
"@openmrs/esm-api": "^3.2.1-pre.970",
|
|
57
|
+
"@openmrs/esm-config": "^3.2.1-pre.970",
|
|
58
|
+
"@openmrs/esm-error-handling": "^3.2.1-pre.970",
|
|
59
|
+
"@openmrs/esm-extensions": "^3.2.1-pre.970",
|
|
60
|
+
"@openmrs/esm-globals": "^3.2.1-pre.970",
|
|
61
61
|
"i18next": "^19.6.0",
|
|
62
62
|
"react": "^16.13.1",
|
|
63
63
|
"react-dom": "^16.13.1",
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
"rxjs": "^6.5.3",
|
|
66
66
|
"unistore": "^3.5.2"
|
|
67
67
|
},
|
|
68
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "57dc1a5a7b655a60a431d88cd7991f2b9ab23ed9"
|
|
69
69
|
}
|
package/src/Extension.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { renderExtension } from "@openmrs/esm-extensions";
|
|
2
|
+
import React, { useCallback, useContext, useEffect, useState } from "react";
|
|
3
|
+
import { ComponentContext } from ".";
|
|
2
4
|
import { ExtensionData } from "./ComponentContext";
|
|
3
|
-
import { useExtension } from "./useExtension";
|
|
4
5
|
|
|
5
6
|
export interface ExtensionProps {
|
|
6
7
|
state?: Record<string, any>;
|
|
@@ -20,7 +21,31 @@ export interface ExtensionProps {
|
|
|
20
21
|
* and *must* only be used once within that `<ExtensionSlot>`.
|
|
21
22
|
*/
|
|
22
23
|
export const Extension: React.FC<ExtensionProps> = ({ state, wrap }) => {
|
|
23
|
-
const [
|
|
24
|
+
const [domElement, setDomElement] = useState<HTMLDivElement>();
|
|
25
|
+
const { extension } = useContext(ComponentContext);
|
|
26
|
+
|
|
27
|
+
const ref = useCallback((node) => {
|
|
28
|
+
setDomElement(node);
|
|
29
|
+
}, []);
|
|
30
|
+
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
if (domElement != null && extension) {
|
|
33
|
+
return renderExtension(
|
|
34
|
+
domElement,
|
|
35
|
+
extension.extensionSlotName,
|
|
36
|
+
extension.extensionSlotModuleName,
|
|
37
|
+
extension.extensionId,
|
|
38
|
+
undefined,
|
|
39
|
+
state
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
}, [
|
|
43
|
+
extension?.extensionSlotName,
|
|
44
|
+
extension?.extensionId,
|
|
45
|
+
extension?.extensionSlotModuleName,
|
|
46
|
+
state,
|
|
47
|
+
domElement,
|
|
48
|
+
]);
|
|
24
49
|
|
|
25
50
|
// The extension is rendered into the `<slot>`. It is surrounded by a
|
|
26
51
|
// `<div>` with relative positioning in order to allow the UI Editor
|
package/src/ExtensionSlot.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useRef, useMemo } from "react";
|
|
2
|
-
import { ConnectedExtension } from "
|
|
2
|
+
import { ConnectedExtension } from "@openmrs/esm-extensions";
|
|
3
3
|
import { ComponentContext } from "./ComponentContext";
|
|
4
4
|
import { Extension } from "./Extension";
|
|
5
5
|
import { useExtensionSlot } from "./useExtensionSlot";
|
|
@@ -76,7 +76,7 @@ export const ExtensionSlot: React.FC<ExtensionSlotProps> = ({
|
|
|
76
76
|
<ComponentContext.Provider
|
|
77
77
|
key={extension.id}
|
|
78
78
|
value={{
|
|
79
|
-
moduleName:
|
|
79
|
+
moduleName: extensionSlotModuleName, // moduleName is not used by the receiving Extension
|
|
80
80
|
extension: {
|
|
81
81
|
extensionId: extension.id,
|
|
82
82
|
extensionSlotName,
|
package/src/index.ts
CHANGED
|
@@ -5,15 +5,15 @@ export * from "./Extension";
|
|
|
5
5
|
export * from "./ExtensionSlot";
|
|
6
6
|
export * from "./getLifecycle";
|
|
7
7
|
export * from "./openmrsComponentDecorator";
|
|
8
|
+
export * from "./useAssignedExtensions";
|
|
8
9
|
export * from "./useAssignedExtensionIds";
|
|
9
|
-
export * from "./useAttachedExtensionIds";
|
|
10
10
|
export * from "./useBodyScrollLock";
|
|
11
11
|
export * from "./useConfig";
|
|
12
12
|
export * from "./useConnectedExtensions";
|
|
13
13
|
export * from "./useConnectivity";
|
|
14
14
|
export * from "./usePatient";
|
|
15
15
|
export * from "./useCurrentPatient";
|
|
16
|
-
export * from "./
|
|
16
|
+
export * from "./useExtensionInternalStore";
|
|
17
17
|
export * from "./useExtensionSlotConfig";
|
|
18
18
|
export * from "./useExtensionSlot";
|
|
19
19
|
export * from "./useExtensionSlotMeta";
|
|
@@ -1,29 +1,26 @@
|
|
|
1
1
|
import { useEffect, useState } from "react";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { useAttachedExtensionIds } from "./useAttachedExtensionIds";
|
|
2
|
+
import { getExtensionStore } from "@openmrs/esm-extensions";
|
|
3
|
+
import { isEqual } from "lodash";
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* Gets the assigned extension ids for a given extension slot name.
|
|
8
7
|
* Does not consider if offline or online.
|
|
9
|
-
* @param
|
|
8
|
+
* @param slotName The name of the slot to get the assigned IDs for.
|
|
9
|
+
*
|
|
10
|
+
* @deprecated Use `useAssignedExtensions`
|
|
10
11
|
*/
|
|
11
|
-
export function useAssignedExtensionIds(
|
|
12
|
-
const
|
|
13
|
-
const attachedIds = useAttachedExtensionIds(extensionSlotName);
|
|
14
|
-
const [assignedIds, setAssignedIds] = useState<Array<string>>([]);
|
|
12
|
+
export function useAssignedExtensionIds(slotName: string) {
|
|
13
|
+
const [ids, setIds] = useState<Array<string>>([]);
|
|
15
14
|
|
|
16
15
|
useEffect(() => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
return getExtensionStore().subscribe((state) => {
|
|
17
|
+
const newIds =
|
|
18
|
+
state.slots[slotName]?.assignedExtensions.map((e) => e.id) ?? [];
|
|
19
|
+
if (!isEqual(newIds, ids)) {
|
|
20
|
+
setIds(newIds);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}, []);
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
setAssignedIds(newAssignedIds);
|
|
25
|
-
}
|
|
26
|
-
}, [attachedIds, config]);
|
|
27
|
-
|
|
28
|
-
return assignedIds;
|
|
25
|
+
return ids;
|
|
29
26
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { AssignedExtension, getExtensionStore } from "@openmrs/esm-extensions";
|
|
3
|
+
import { isEqual } from "lodash";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Gets the assigned extensions for a given extension slot name.
|
|
7
|
+
* Does not consider if offline or online.
|
|
8
|
+
* @param slotName The name of the slot to get the assigned extensions for.
|
|
9
|
+
*/
|
|
10
|
+
export function useAssignedExtensions(slotName: string) {
|
|
11
|
+
const [extensions, setExtensions] = useState<Array<AssignedExtension>>([]);
|
|
12
|
+
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
return getExtensionStore().subscribe((state) => {
|
|
15
|
+
const newExtensions = state.slots[slotName]?.assignedExtensions ?? [];
|
|
16
|
+
if (!isEqual(newExtensions, extensions)) {
|
|
17
|
+
setExtensions(newExtensions);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}, []);
|
|
21
|
+
|
|
22
|
+
return extensions;
|
|
23
|
+
}
|
package/src/useConfig.ts
CHANGED
|
@@ -120,8 +120,5 @@ export function useConfig() {
|
|
|
120
120
|
[normalConfig, extensionConfig]
|
|
121
121
|
);
|
|
122
122
|
|
|
123
|
-
const configNameForDebugMessage = extension
|
|
124
|
-
? `${extension?.extensionSlotModuleName}-${extension?.extensionSlotName}-${extension?.extensionId}`
|
|
125
|
-
: moduleName;
|
|
126
123
|
return config;
|
|
127
124
|
}
|
|
@@ -1,51 +1,25 @@
|
|
|
1
1
|
import { useMemo } from "react";
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
ExtensionRegistration,
|
|
6
|
-
extensionStore,
|
|
7
|
-
getExtensionRegistrationFrom,
|
|
3
|
+
ConnectedExtension,
|
|
4
|
+
getConnectedExtensions,
|
|
8
5
|
} from "@openmrs/esm-extensions";
|
|
9
|
-
import { useAssignedExtensionIds } from "./useAssignedExtensionIds";
|
|
10
6
|
import { useConnectivity } from "./useConnectivity";
|
|
11
|
-
|
|
12
|
-
function isValidExtension(
|
|
13
|
-
extension: ConnectedExtension | { id: string }
|
|
14
|
-
): extension is ConnectedExtension {
|
|
15
|
-
return extension.hasOwnProperty("name");
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* We have the following extension modes:
|
|
20
|
-
*
|
|
21
|
-
* - attached (set via code in form of: attach, detach, ...)
|
|
22
|
-
* - configured (set via configuration in form of: added, removed, ...)
|
|
23
|
-
* - assigned (computed from attached and configured)
|
|
24
|
-
* - connected (computed from assigned using connectivity and online / offline)
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
export interface ConnectedExtension extends ExtensionRegistration {
|
|
28
|
-
id: string;
|
|
29
|
-
}
|
|
7
|
+
import { useAssignedExtensions } from "./useAssignedExtensions";
|
|
30
8
|
|
|
31
9
|
/**
|
|
32
10
|
* Gets the assigned extension for a given extension slot name.
|
|
33
11
|
* Considers if offline or online.
|
|
34
|
-
* @param
|
|
12
|
+
* @param slotName The name of the slot to get the assigned extensions for.
|
|
35
13
|
*/
|
|
36
14
|
export function useConnectedExtensions(
|
|
37
|
-
|
|
15
|
+
slotName: string
|
|
38
16
|
): Array<ConnectedExtension> {
|
|
39
17
|
const online = useConnectivity();
|
|
40
|
-
const
|
|
18
|
+
const assignedExtensions = useAssignedExtensions(slotName);
|
|
41
19
|
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
.map((id) => ({ id, ...getExtensionRegistrationFrom(state, id) }))
|
|
46
|
-
.filter(isValidExtension)
|
|
47
|
-
.filter((m) => checkStatusFor(online, m.online, m.offline));
|
|
48
|
-
}, [extensionIdsToRender, online]);
|
|
20
|
+
const connectedExtensions = useMemo(() => {
|
|
21
|
+
return getConnectedExtensions(assignedExtensions, online);
|
|
22
|
+
}, [assignedExtensions, online]);
|
|
49
23
|
|
|
50
|
-
return
|
|
24
|
+
return connectedExtensions;
|
|
51
25
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ExtensionInternalStore,
|
|
3
|
+
getExtensionInternalStore,
|
|
4
|
+
} from "@openmrs/esm-extensions";
|
|
5
|
+
import { createUseStore } from "./createUseStore";
|
|
6
|
+
|
|
7
|
+
/** @internal */
|
|
8
|
+
export const useExtensionInternalStore = createUseStore<ExtensionInternalStore>(
|
|
9
|
+
getExtensionInternalStore()
|
|
10
|
+
);
|
package/src/useExtensionSlot.ts
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { useContext, useEffect } from "react";
|
|
2
|
-
import {
|
|
3
|
-
registerExtensionSlot,
|
|
4
|
-
unregisterExtensionSlot,
|
|
5
|
-
} from "@openmrs/esm-extensions";
|
|
2
|
+
import { registerExtensionSlot } from "@openmrs/esm-extensions";
|
|
6
3
|
import { ComponentContext } from "./ComponentContext";
|
|
7
4
|
import { useConnectedExtensions } from "./useConnectedExtensions";
|
|
8
5
|
|
|
9
|
-
|
|
6
|
+
/** @internal */
|
|
7
|
+
export function useExtensionSlot(slotName: string) {
|
|
10
8
|
const { moduleName } = useContext(ComponentContext);
|
|
11
9
|
|
|
12
10
|
if (!moduleName) {
|
|
@@ -16,15 +14,14 @@ export function useExtensionSlot(extensionSlotName: string) {
|
|
|
16
14
|
}
|
|
17
15
|
|
|
18
16
|
useEffect(() => {
|
|
19
|
-
registerExtensionSlot(moduleName,
|
|
20
|
-
return () => unregisterExtensionSlot(moduleName, extensionSlotName);
|
|
17
|
+
registerExtensionSlot(moduleName, slotName);
|
|
21
18
|
}, []);
|
|
22
19
|
|
|
23
|
-
const extensions = useConnectedExtensions(
|
|
20
|
+
const extensions = useConnectedExtensions(slotName);
|
|
24
21
|
|
|
25
22
|
return {
|
|
26
23
|
extensions,
|
|
27
|
-
extensionSlotName,
|
|
24
|
+
extensionSlotName: slotName,
|
|
28
25
|
extensionSlotModuleName: moduleName,
|
|
29
26
|
};
|
|
30
27
|
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useCallback } from "react";
|
|
2
2
|
import {
|
|
3
3
|
ExtensionSlotConfigObject,
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
ExtensionSlotConfigStore,
|
|
5
|
+
getExtensionSlotConfigStore,
|
|
6
6
|
} from "@openmrs/esm-config";
|
|
7
|
-
import { ComponentContext } from "./ComponentContext";
|
|
8
7
|
import { useStoreState } from "./useStoreState";
|
|
9
8
|
|
|
10
9
|
const defaultConfig: ExtensionSlotConfigObject = {
|
|
@@ -13,12 +12,12 @@ const defaultConfig: ExtensionSlotConfigObject = {
|
|
|
13
12
|
remove: [],
|
|
14
13
|
};
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const store =
|
|
15
|
+
/** @internal */
|
|
16
|
+
export function useExtensionSlotConfig(slotName: string) {
|
|
17
|
+
const store = getExtensionSlotConfigStore(slotName);
|
|
19
18
|
const select = useCallback(
|
|
20
|
-
(s:
|
|
21
|
-
[
|
|
19
|
+
(s: ExtensionSlotConfigStore) => s.config,
|
|
20
|
+
[slotName]
|
|
22
21
|
);
|
|
23
22
|
const config = useStoreState(store, select);
|
|
24
23
|
return config || defaultConfig;
|
package/src/useExtensionStore.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
ExtensionInternalStore,
|
|
3
|
+
getExtensionInternalStore,
|
|
4
|
+
} from "@openmrs/esm-extensions";
|
|
2
5
|
import { createUseStore } from "./createUseStore";
|
|
3
6
|
|
|
4
|
-
|
|
7
|
+
/**
|
|
8
|
+
* The implementation of this will soon undergo a breaking change.
|
|
9
|
+
* This will return an `ExtensionStore` rather than `ExtensionInternalStore`.
|
|
10
|
+
*/
|
|
11
|
+
export const useExtensionStore = createUseStore<ExtensionInternalStore>(
|
|
12
|
+
getExtensionInternalStore()
|
|
13
|
+
);
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { useCallback } from "react";
|
|
2
|
-
import { extensionStore, ExtensionStore } from "@openmrs/esm-extensions";
|
|
3
|
-
import { useStoreState } from "./useStoreState";
|
|
4
|
-
|
|
5
|
-
const defaultArray: Array<string> = [];
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Gets the assigned extension ids for the given slot.
|
|
9
|
-
* @param extensionSlotName
|
|
10
|
-
*/
|
|
11
|
-
export function useAttachedExtensionIds(extensionSlotName: string) {
|
|
12
|
-
const select = useCallback(
|
|
13
|
-
(s: ExtensionStore) => s.slots[extensionSlotName]?.attachedIds,
|
|
14
|
-
[extensionSlotName]
|
|
15
|
-
);
|
|
16
|
-
const extensions = useStoreState(extensionStore, select);
|
|
17
|
-
return extensions || defaultArray;
|
|
18
|
-
}
|
package/src/useExtension.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { RefObject, useContext, useRef, useEffect } from "react";
|
|
2
|
-
import { renderExtension } from "@openmrs/esm-extensions";
|
|
3
|
-
import { ComponentContext, ExtensionData } from "./ComponentContext";
|
|
4
|
-
|
|
5
|
-
export function useExtension<TRef extends HTMLElement>(
|
|
6
|
-
state?: Record<string, any>
|
|
7
|
-
): [RefObject<TRef>, ExtensionData | undefined] {
|
|
8
|
-
const ref = useRef<TRef>(null);
|
|
9
|
-
const { extension } = useContext(ComponentContext);
|
|
10
|
-
|
|
11
|
-
useEffect(() => {
|
|
12
|
-
if (ref.current && extension) {
|
|
13
|
-
return renderExtension(
|
|
14
|
-
ref.current,
|
|
15
|
-
extension.extensionSlotName,
|
|
16
|
-
extension.extensionSlotModuleName,
|
|
17
|
-
extension.extensionId,
|
|
18
|
-
undefined,
|
|
19
|
-
state
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
}, [
|
|
23
|
-
extension?.extensionSlotName,
|
|
24
|
-
extension?.extensionId,
|
|
25
|
-
extension?.extensionSlotModuleName,
|
|
26
|
-
ref.current,
|
|
27
|
-
state,
|
|
28
|
-
]);
|
|
29
|
-
|
|
30
|
-
return [ref, extension];
|
|
31
|
-
}
|