@openmrs/esm-react-utils 3.1.15-pre.754 → 3.1.15-pre.767
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 +1 -2
- package/dist/openmrs-esm-react-utils.js.map +1 -1
- package/package.json +7 -7
- package/src/Extension.tsx +3 -28
- package/src/ExtensionSlot.tsx +3 -3
- package/src/index.ts +2 -2
- package/src/useAssignedExtensionIds.ts +19 -16
- package/src/useAttachedExtensionIds.ts +18 -0
- package/src/useConfig.ts +3 -0
- package/src/useConnectedExtensions.ts +36 -10
- package/src/useExtension.ts +31 -0
- package/src/useExtensionSlot.ts +9 -6
- package/src/useExtensionSlotConfig.ts +9 -8
- package/src/useExtensionStore.ts +2 -11
- package/dist/openmrs-esm-react-utils.js.LICENSE.txt +0 -8
- package/src/useAssignedExtensions.ts +0 -23
- package/src/useExtensionInternalStore.ts +0 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openmrs/esm-react-utils",
|
|
3
|
-
"version": "3.1.15-pre.
|
|
3
|
+
"version": "3.1.15-pre.767",
|
|
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.1.15-pre.
|
|
57
|
-
"@openmrs/esm-config": "^3.1.15-pre.
|
|
58
|
-
"@openmrs/esm-error-handling": "^3.1.15-pre.
|
|
59
|
-
"@openmrs/esm-extensions": "^3.1.15-pre.
|
|
60
|
-
"@openmrs/esm-globals": "^3.1.15-pre.
|
|
56
|
+
"@openmrs/esm-api": "^3.1.15-pre.767",
|
|
57
|
+
"@openmrs/esm-config": "^3.1.15-pre.767",
|
|
58
|
+
"@openmrs/esm-error-handling": "^3.1.15-pre.767",
|
|
59
|
+
"@openmrs/esm-extensions": "^3.1.15-pre.767",
|
|
60
|
+
"@openmrs/esm-globals": "^3.1.15-pre.767",
|
|
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": "c7b2c24b8fb56043e8165d95cdccd2c6ab34670b"
|
|
69
69
|
}
|
package/src/Extension.tsx
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import React, { useCallback, useContext, useEffect, useState } from "react";
|
|
3
|
-
import { ComponentContext } from ".";
|
|
1
|
+
import React from "react";
|
|
4
2
|
import { ExtensionData } from "./ComponentContext";
|
|
3
|
+
import { useExtension } from "./useExtension";
|
|
5
4
|
|
|
6
5
|
export interface ExtensionProps {
|
|
7
6
|
state?: Record<string, any>;
|
|
@@ -21,31 +20,7 @@ export interface ExtensionProps {
|
|
|
21
20
|
* and *must* only be used once within that `<ExtensionSlot>`.
|
|
22
21
|
*/
|
|
23
22
|
export const Extension: React.FC<ExtensionProps> = ({ state, wrap }) => {
|
|
24
|
-
const [
|
|
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
|
-
]);
|
|
23
|
+
const [ref, extension] = useExtension<HTMLDivElement>(state);
|
|
49
24
|
|
|
50
25
|
// The extension is rendered into the `<slot>`. It is surrounded by a
|
|
51
26
|
// `<div>` with relative positioning in order to allow the UI Editor
|
package/src/ExtensionSlot.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import React, { useRef, useMemo } from "react";
|
|
2
|
+
import { ConnectedExtension } from "./useConnectedExtensions";
|
|
3
3
|
import { ComponentContext } from "./ComponentContext";
|
|
4
4
|
import { Extension } from "./Extension";
|
|
5
5
|
import { useExtensionSlot } from "./useExtensionSlot";
|
|
@@ -72,7 +72,7 @@ export const ExtensionSlot: React.FC<ExtensionSlotProps> = ({
|
|
|
72
72
|
<ComponentContext.Provider
|
|
73
73
|
key={extension.id}
|
|
74
74
|
value={{
|
|
75
|
-
moduleName:
|
|
75
|
+
moduleName: extension.moduleName,
|
|
76
76
|
extension: {
|
|
77
77
|
extensionId: extension.id,
|
|
78
78
|
extensionSlotName,
|
package/src/index.ts
CHANGED
|
@@ -5,14 +5,14 @@ export * from "./Extension";
|
|
|
5
5
|
export * from "./ExtensionSlot";
|
|
6
6
|
export * from "./getLifecycle";
|
|
7
7
|
export * from "./openmrsComponentDecorator";
|
|
8
|
-
export * from "./useAssignedExtensions";
|
|
9
8
|
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 "./useCurrentPatient";
|
|
15
|
-
export * from "./
|
|
15
|
+
export * from "./useExtension";
|
|
16
16
|
export * from "./useExtensionSlotConfig";
|
|
17
17
|
export * from "./useExtensionSlot";
|
|
18
18
|
export * from "./useExtensionSlotMeta";
|
|
@@ -1,26 +1,29 @@
|
|
|
1
1
|
import { useEffect, useState } from "react";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { getAssignedIds } from "@openmrs/esm-extensions";
|
|
3
|
+
import { useExtensionSlotConfig } from "./useExtensionSlotConfig";
|
|
4
|
+
import { useAttachedExtensionIds } from "./useAttachedExtensionIds";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Gets the assigned extension ids for a given extension slot name.
|
|
7
8
|
* Does not consider if offline or online.
|
|
8
|
-
* @param
|
|
9
|
-
*
|
|
10
|
-
* @deprecated Use `useAssignedExtensions`
|
|
9
|
+
* @param extensionSlotName The name of the slot to get the assigned IDs for.
|
|
11
10
|
*/
|
|
12
|
-
export function useAssignedExtensionIds(
|
|
13
|
-
const
|
|
11
|
+
export function useAssignedExtensionIds(extensionSlotName: string) {
|
|
12
|
+
const config = useExtensionSlotConfig(extensionSlotName);
|
|
13
|
+
const attachedIds = useAttachedExtensionIds(extensionSlotName);
|
|
14
|
+
const [assignedIds, setAssignedIds] = useState<Array<string>>([]);
|
|
14
15
|
|
|
15
16
|
useEffect(() => {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
});
|
|
23
|
-
}, []);
|
|
17
|
+
const newAssignedIds = getAssignedIds(
|
|
18
|
+
extensionSlotName,
|
|
19
|
+
config,
|
|
20
|
+
attachedIds
|
|
21
|
+
);
|
|
24
22
|
|
|
25
|
-
|
|
23
|
+
if (newAssignedIds.join(",") !== assignedIds.join(",")) {
|
|
24
|
+
setAssignedIds(newAssignedIds);
|
|
25
|
+
}
|
|
26
|
+
}, [attachedIds, config]);
|
|
27
|
+
|
|
28
|
+
return assignedIds;
|
|
26
29
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
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/useConfig.ts
CHANGED
|
@@ -120,5 +120,8 @@ export function useConfig() {
|
|
|
120
120
|
[normalConfig, extensionConfig]
|
|
121
121
|
);
|
|
122
122
|
|
|
123
|
+
const configNameForDebugMessage = extension
|
|
124
|
+
? `${extension?.extensionSlotModuleName}-${extension?.extensionSlotName}-${extension?.extensionId}`
|
|
125
|
+
: moduleName;
|
|
123
126
|
return config;
|
|
124
127
|
}
|
|
@@ -1,25 +1,51 @@
|
|
|
1
1
|
import { useMemo } from "react";
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
checkStatusFor,
|
|
4
|
+
ExtensionMeta,
|
|
5
|
+
ExtensionRegistration,
|
|
6
|
+
extensionStore,
|
|
7
|
+
getExtensionRegistrationFrom,
|
|
5
8
|
} from "@openmrs/esm-extensions";
|
|
9
|
+
import { useAssignedExtensionIds } from "./useAssignedExtensionIds";
|
|
6
10
|
import { useConnectivity } from "./useConnectivity";
|
|
7
|
-
|
|
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
|
+
}
|
|
8
30
|
|
|
9
31
|
/**
|
|
10
32
|
* Gets the assigned extension for a given extension slot name.
|
|
11
33
|
* Considers if offline or online.
|
|
12
|
-
* @param
|
|
34
|
+
* @param extensionSlotName The name of the slot to get the assigned extensions for.
|
|
13
35
|
*/
|
|
14
36
|
export function useConnectedExtensions(
|
|
15
|
-
|
|
37
|
+
extensionSlotName: string
|
|
16
38
|
): Array<ConnectedExtension> {
|
|
17
39
|
const online = useConnectivity();
|
|
18
|
-
const
|
|
40
|
+
const extensionIdsToRender = useAssignedExtensionIds(extensionSlotName);
|
|
19
41
|
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
42
|
+
const extensions = useMemo(() => {
|
|
43
|
+
const state = extensionStore.getState();
|
|
44
|
+
return extensionIdsToRender
|
|
45
|
+
.map((id) => ({ id, ...getExtensionRegistrationFrom(state, id) }))
|
|
46
|
+
.filter(isValidExtension)
|
|
47
|
+
.filter((m) => checkStatusFor(online, m.online, m.offline));
|
|
48
|
+
}, [extensionIdsToRender, online]);
|
|
23
49
|
|
|
24
|
-
return
|
|
50
|
+
return extensions;
|
|
25
51
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
}
|
package/src/useExtensionSlot.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { useContext, useEffect } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
registerExtensionSlot,
|
|
4
|
+
unregisterExtensionSlot,
|
|
5
|
+
} from "@openmrs/esm-extensions";
|
|
3
6
|
import { ComponentContext } from "./ComponentContext";
|
|
4
7
|
import { useConnectedExtensions } from "./useConnectedExtensions";
|
|
5
8
|
|
|
6
|
-
|
|
7
|
-
export function useExtensionSlot(slotName: string) {
|
|
9
|
+
export function useExtensionSlot(extensionSlotName: string) {
|
|
8
10
|
const { moduleName } = useContext(ComponentContext);
|
|
9
11
|
|
|
10
12
|
if (!moduleName) {
|
|
@@ -14,14 +16,15 @@ export function useExtensionSlot(slotName: string) {
|
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
useEffect(() => {
|
|
17
|
-
registerExtensionSlot(moduleName,
|
|
19
|
+
registerExtensionSlot(moduleName, extensionSlotName);
|
|
20
|
+
return () => unregisterExtensionSlot(moduleName, extensionSlotName);
|
|
18
21
|
}, []);
|
|
19
22
|
|
|
20
|
-
const extensions = useConnectedExtensions(
|
|
23
|
+
const extensions = useConnectedExtensions(extensionSlotName);
|
|
21
24
|
|
|
22
25
|
return {
|
|
23
26
|
extensions,
|
|
24
|
-
extensionSlotName
|
|
27
|
+
extensionSlotName,
|
|
25
28
|
extensionSlotModuleName: moduleName,
|
|
26
29
|
};
|
|
27
30
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { useCallback } from "react";
|
|
1
|
+
import { useContext, useCallback } from "react";
|
|
2
2
|
import {
|
|
3
3
|
ExtensionSlotConfigObject,
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
ExtensionSlotConfigsStore,
|
|
5
|
+
getExtensionSlotsConfigStore,
|
|
6
6
|
} from "@openmrs/esm-config";
|
|
7
|
+
import { ComponentContext } from "./ComponentContext";
|
|
7
8
|
import { useStoreState } from "./useStoreState";
|
|
8
9
|
|
|
9
10
|
const defaultConfig: ExtensionSlotConfigObject = {
|
|
@@ -12,12 +13,12 @@ const defaultConfig: ExtensionSlotConfigObject = {
|
|
|
12
13
|
remove: [],
|
|
13
14
|
};
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const store =
|
|
16
|
+
export function useExtensionSlotConfig(extensionSlotName: string) {
|
|
17
|
+
const { moduleName } = useContext(ComponentContext);
|
|
18
|
+
const store = getExtensionSlotsConfigStore(moduleName);
|
|
18
19
|
const select = useCallback(
|
|
19
|
-
(s:
|
|
20
|
-
[
|
|
20
|
+
(s: ExtensionSlotConfigsStore) => s.extensionSlotConfigs[extensionSlotName],
|
|
21
|
+
[extensionSlotName]
|
|
21
22
|
);
|
|
22
23
|
const config = useStoreState(store, select);
|
|
23
24
|
return config || defaultConfig;
|
package/src/useExtensionStore.ts
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ExtensionInternalStore,
|
|
3
|
-
getExtensionInternalStore,
|
|
4
|
-
} from "@openmrs/esm-extensions";
|
|
1
|
+
import { ExtensionStore, extensionStore } from "@openmrs/esm-extensions";
|
|
5
2
|
import { createUseStore } from "./createUseStore";
|
|
6
3
|
|
|
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
|
-
);
|
|
4
|
+
export const useExtensionStore = createUseStore<ExtensionStore>(extensionStore);
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Lodash <https://lodash.com/>
|
|
4
|
-
* Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
|
|
5
|
-
* Released under MIT license <https://lodash.com/license>
|
|
6
|
-
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
|
7
|
-
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
|
8
|
-
*/
|
|
@@ -1,23 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
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
|
-
);
|