@openmrs/esm-react-utils 3.2.0 → 3.2.1-pre.1015
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 +23 -0
- package/dist/openmrs-esm-react-utils.js.map +1 -1
- package/package.json +9 -8
- package/src/Extension.tsx +28 -3
- package/src/ExtensionSlot.tsx +3 -3
- package/src/index.ts +2 -2
- package/src/useAssignedExtensionIds.ts +16 -19
- package/src/useAssignedExtensions.ts +29 -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 +4 -2
- package/src/usePatient.ts +13 -13
- package/src/useVisit.ts +26 -41
- 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.
|
|
3
|
+
"version": "3.2.1-pre.1015",
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
5
|
"description": "React utilities for OpenMRS.",
|
|
6
6
|
"browser": "dist/openmrs-esm-react-utils.js",
|
|
@@ -39,7 +39,8 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"lodash-es": "^4.17.21",
|
|
42
|
-
"single-spa-react": "^4.1.1"
|
|
42
|
+
"single-spa-react": "^4.1.1",
|
|
43
|
+
"swr": "^1.2.2"
|
|
43
44
|
},
|
|
44
45
|
"peerDependencies": {
|
|
45
46
|
"@openmrs/esm-api": "3.x",
|
|
@@ -53,11 +54,11 @@
|
|
|
53
54
|
"react-i18next": "11.x"
|
|
54
55
|
},
|
|
55
56
|
"devDependencies": {
|
|
56
|
-
"@openmrs/esm-api": "^3.2.
|
|
57
|
-
"@openmrs/esm-config": "^3.2.
|
|
58
|
-
"@openmrs/esm-error-handling": "^3.2.
|
|
59
|
-
"@openmrs/esm-extensions": "^3.2.
|
|
60
|
-
"@openmrs/esm-globals": "^3.2.
|
|
57
|
+
"@openmrs/esm-api": "^3.2.1-pre.1015",
|
|
58
|
+
"@openmrs/esm-config": "^3.2.1-pre.1015",
|
|
59
|
+
"@openmrs/esm-error-handling": "^3.2.1-pre.1015",
|
|
60
|
+
"@openmrs/esm-extensions": "^3.2.1-pre.1015",
|
|
61
|
+
"@openmrs/esm-globals": "^3.2.1-pre.1015",
|
|
61
62
|
"i18next": "^19.6.0",
|
|
62
63
|
"react": "^16.13.1",
|
|
63
64
|
"react-dom": "^16.13.1",
|
|
@@ -65,5 +66,5 @@
|
|
|
65
66
|
"rxjs": "^6.5.3",
|
|
66
67
|
"unistore": "^3.5.2"
|
|
67
68
|
},
|
|
68
|
-
"gitHead": "
|
|
69
|
+
"gitHead": "2a10b8956cd63006bd913b18a2a482fa9a0134ec"
|
|
69
70
|
}
|
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,
|
|
@@ -87,7 +87,7 @@ export const ExtensionSlot: React.FC<ExtensionSlotProps> = ({
|
|
|
87
87
|
{children ?? <Extension state={stateRef.current} />}
|
|
88
88
|
</ComponentContext.Provider>
|
|
89
89
|
)),
|
|
90
|
-
[select, extensions, extensionSlotName]
|
|
90
|
+
[select, extensions, extensionSlotName, stateRef.current]
|
|
91
91
|
);
|
|
92
92
|
|
|
93
93
|
return (
|
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,29 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import {
|
|
3
|
+
AssignedExtension,
|
|
4
|
+
ExtensionStore,
|
|
5
|
+
getExtensionStore,
|
|
6
|
+
} from "@openmrs/esm-extensions";
|
|
7
|
+
import { isEqual } from "lodash";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Gets the assigned extensions for a given extension slot name.
|
|
11
|
+
* Does not consider if offline or online.
|
|
12
|
+
* @param slotName The name of the slot to get the assigned extensions for.
|
|
13
|
+
*/
|
|
14
|
+
export function useAssignedExtensions(slotName: string) {
|
|
15
|
+
const [extensions, setExtensions] = useState<Array<AssignedExtension>>([]);
|
|
16
|
+
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
function update(state: ExtensionStore) {
|
|
19
|
+
const newExtensions = state.slots[slotName]?.assignedExtensions ?? [];
|
|
20
|
+
if (!isEqual(newExtensions, extensions)) {
|
|
21
|
+
setExtensions(newExtensions);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
update(getExtensionStore().getState());
|
|
25
|
+
return getExtensionStore().subscribe(update);
|
|
26
|
+
}, [slotName]);
|
|
27
|
+
|
|
28
|
+
return extensions;
|
|
29
|
+
}
|
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,6 @@
|
|
|
1
|
-
import { ExtensionStore,
|
|
1
|
+
import { ExtensionStore, getExtensionStore } from "@openmrs/esm-extensions";
|
|
2
2
|
import { createUseStore } from "./createUseStore";
|
|
3
3
|
|
|
4
|
-
export const useExtensionStore = createUseStore<ExtensionStore>(
|
|
4
|
+
export const useExtensionStore = createUseStore<ExtensionStore>(
|
|
5
|
+
getExtensionStore()
|
|
6
|
+
);
|
package/src/usePatient.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEffect,
|
|
1
|
+
import { useEffect, useReducer } from "react";
|
|
2
2
|
import { fetchCurrentPatient, PatientUuid } from "@openmrs/esm-api";
|
|
3
3
|
|
|
4
4
|
type NullablePatient = fhir.Patient | null;
|
|
@@ -6,6 +6,7 @@ type NullablePatient = fhir.Patient | null;
|
|
|
6
6
|
interface CurrentPatientState {
|
|
7
7
|
patientUuid: string | null;
|
|
8
8
|
patient: NullablePatient;
|
|
9
|
+
isPendingUuid: boolean;
|
|
9
10
|
isLoadingPatient: boolean;
|
|
10
11
|
err: Error | null;
|
|
11
12
|
}
|
|
@@ -36,7 +37,8 @@ enum ActionTypes {
|
|
|
36
37
|
const initialState: CurrentPatientState = {
|
|
37
38
|
patientUuid: null,
|
|
38
39
|
patient: null,
|
|
39
|
-
|
|
40
|
+
isPendingUuid: true,
|
|
41
|
+
isLoadingPatient: false,
|
|
40
42
|
err: null,
|
|
41
43
|
};
|
|
42
44
|
|
|
@@ -55,6 +57,7 @@ function reducer(
|
|
|
55
57
|
...state,
|
|
56
58
|
patientUuid: action.patientUuid,
|
|
57
59
|
patient: null,
|
|
60
|
+
isPendingUuid: false,
|
|
58
61
|
isLoadingPatient: true,
|
|
59
62
|
err: null,
|
|
60
63
|
};
|
|
@@ -62,6 +65,7 @@ function reducer(
|
|
|
62
65
|
return {
|
|
63
66
|
...state,
|
|
64
67
|
patient: action.patient,
|
|
68
|
+
isPendingUuid: false,
|
|
65
69
|
isLoadingPatient: false,
|
|
66
70
|
err: null,
|
|
67
71
|
};
|
|
@@ -69,6 +73,7 @@ function reducer(
|
|
|
69
73
|
return {
|
|
70
74
|
...state,
|
|
71
75
|
patient: null,
|
|
76
|
+
isPendingUuid: false,
|
|
72
77
|
isLoadingPatient: false,
|
|
73
78
|
err: action.err,
|
|
74
79
|
};
|
|
@@ -87,15 +92,12 @@ export function usePatient(patientUuid?: string) {
|
|
|
87
92
|
const [state, dispatch] = useReducer(reducer, {
|
|
88
93
|
...initialState,
|
|
89
94
|
patientUuid: patientUuid ?? null,
|
|
95
|
+
isPendingUuid: !patientUuid,
|
|
96
|
+
isLoadingPatient: !!patientUuid,
|
|
90
97
|
});
|
|
91
98
|
|
|
92
99
|
useEffect(() => {
|
|
93
|
-
if (state.
|
|
94
|
-
dispatch({
|
|
95
|
-
type: ActionTypes.loadPatient,
|
|
96
|
-
patientUuid: state.patientUuid,
|
|
97
|
-
});
|
|
98
|
-
} else {
|
|
100
|
+
if (state.isPendingUuid) {
|
|
99
101
|
const patientUuidFromUrl = getPatientUuidFromUrl();
|
|
100
102
|
if (patientUuidFromUrl) {
|
|
101
103
|
dispatch({
|
|
@@ -106,9 +108,7 @@ export function usePatient(patientUuid?: string) {
|
|
|
106
108
|
dispatch({ type: ActionTypes.newPatient, patient: null });
|
|
107
109
|
}
|
|
108
110
|
}
|
|
109
|
-
}, [state.patientUuid]);
|
|
110
111
|
|
|
111
|
-
useEffect(() => {
|
|
112
112
|
let active = true;
|
|
113
113
|
if (state.isLoadingPatient && state.patientUuid) {
|
|
114
114
|
fetchCurrentPatient(state.patientUuid).then(
|
|
@@ -129,7 +129,7 @@ export function usePatient(patientUuid?: string) {
|
|
|
129
129
|
return () => {
|
|
130
130
|
active = false;
|
|
131
131
|
};
|
|
132
|
-
}, [state.isLoadingPatient, state.patientUuid]);
|
|
132
|
+
}, [state.isPendingUuid, state.isLoadingPatient, state.patientUuid]);
|
|
133
133
|
|
|
134
134
|
useEffect(() => {
|
|
135
135
|
const handleRouteUpdate = (evt) => {
|
|
@@ -144,10 +144,10 @@ export function usePatient(patientUuid?: string) {
|
|
|
144
144
|
window.addEventListener("single-spa:routing-event", handleRouteUpdate);
|
|
145
145
|
return () =>
|
|
146
146
|
window.removeEventListener("single-spa:routing-event", handleRouteUpdate);
|
|
147
|
-
}, []);
|
|
147
|
+
}, [state.patientUuid]);
|
|
148
148
|
|
|
149
149
|
return {
|
|
150
|
-
isLoading: state.isLoadingPatient,
|
|
150
|
+
isLoading: state.isPendingUuid || state.isLoadingPatient,
|
|
151
151
|
patient: state.patient,
|
|
152
152
|
patientUuid: patientUuid ?? state.patientUuid,
|
|
153
153
|
error: state.err,
|
package/src/useVisit.ts
CHANGED
|
@@ -1,49 +1,34 @@
|
|
|
1
|
-
import { useState, useEffect } from "react";
|
|
2
|
-
import dayjs from "dayjs";
|
|
3
1
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
VisitMode,
|
|
7
|
-
VisitStatus,
|
|
2
|
+
defaultVisitCustomRepresentation,
|
|
3
|
+
openmrsFetch,
|
|
8
4
|
Visit,
|
|
9
5
|
} from "@openmrs/esm-api";
|
|
6
|
+
import useSWR from "swr";
|
|
10
7
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
if (visit) {
|
|
18
|
-
setCurrentVisit(visit?.visitData ?? null);
|
|
19
|
-
} else {
|
|
20
|
-
setCurrentVisit(null);
|
|
21
|
-
}
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
return () => sub.unsubscribe();
|
|
25
|
-
}, [patientUuid]);
|
|
8
|
+
interface VisitReturnType {
|
|
9
|
+
error: Error;
|
|
10
|
+
mutate: () => void;
|
|
11
|
+
isValidating: boolean;
|
|
12
|
+
currentVisit: Visit | null;
|
|
13
|
+
}
|
|
26
14
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
15
|
+
/**
|
|
16
|
+
* This React hook returns a visit object. If the `patientUuid` is provided
|
|
17
|
+
* as a parameter, then the currentVisit, error and mutate function
|
|
18
|
+
* for that patient visit is returned.
|
|
19
|
+
* @param patientUuid Unique patient identifier `string`
|
|
20
|
+
* @returns Object {`error` `isValidating`, `currentVisit`, `mutate`}
|
|
21
|
+
*/
|
|
22
|
+
export function useVisit(patientUuid: string): VisitReturnType {
|
|
23
|
+
const { data, error, mutate, isValidating } = useSWR<{
|
|
24
|
+
data: { results: Array<Visit> };
|
|
25
|
+
}>(
|
|
26
|
+
`/ws/rest/v1/visit?patient=${patientUuid}&v=${defaultVisitCustomRepresentation}&includeInactive=false`,
|
|
27
|
+
openmrsFetch
|
|
28
|
+
);
|
|
34
29
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
mode: VisitMode.LOADING,
|
|
38
|
-
visitData: currentVisit,
|
|
39
|
-
status: VisitStatus.ONGOING,
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
setError
|
|
44
|
-
);
|
|
45
|
-
return () => sub && sub.unsubscribe();
|
|
46
|
-
}, [patientUuid]);
|
|
30
|
+
const currentVisit =
|
|
31
|
+
data?.data.results.find((visit) => visit.stopDatetime === null) ?? null;
|
|
47
32
|
|
|
48
|
-
return {
|
|
33
|
+
return { error, mutate, isValidating, currentVisit };
|
|
49
34
|
}
|
|
@@ -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
|
-
}
|