@openmrs/esm-react-utils 5.8.2-pre.2324 → 5.8.2-pre.2341

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": "5.8.2-pre.2324",
3
+ "version": "5.8.2-pre.2341",
4
4
  "license": "MPL-2.0",
5
5
  "description": "React utilities for OpenMRS.",
6
6
  "browser": "dist/openmrs-esm-react-utils.js",
@@ -61,15 +61,15 @@
61
61
  "swr": "2.x"
62
62
  },
63
63
  "devDependencies": {
64
- "@openmrs/esm-api": "5.8.2-pre.2324",
65
- "@openmrs/esm-config": "5.8.2-pre.2324",
66
- "@openmrs/esm-context": "5.8.2-pre.2324",
67
- "@openmrs/esm-error-handling": "5.8.2-pre.2324",
68
- "@openmrs/esm-extensions": "5.8.2-pre.2324",
69
- "@openmrs/esm-feature-flags": "5.8.2-pre.2324",
70
- "@openmrs/esm-globals": "5.8.2-pre.2324",
71
- "@openmrs/esm-navigation": "5.8.2-pre.2324",
72
- "@openmrs/esm-utils": "5.8.2-pre.2324",
64
+ "@openmrs/esm-api": "5.8.2-pre.2341",
65
+ "@openmrs/esm-config": "5.8.2-pre.2341",
66
+ "@openmrs/esm-context": "5.8.2-pre.2341",
67
+ "@openmrs/esm-error-handling": "5.8.2-pre.2341",
68
+ "@openmrs/esm-extensions": "5.8.2-pre.2341",
69
+ "@openmrs/esm-feature-flags": "5.8.2-pre.2341",
70
+ "@openmrs/esm-globals": "5.8.2-pre.2341",
71
+ "@openmrs/esm-navigation": "5.8.2-pre.2341",
72
+ "@openmrs/esm-utils": "5.8.2-pre.2341",
73
73
  "dayjs": "^1.10.8",
74
74
  "i18next": "^21.10.0",
75
75
  "react": "^18.1.0",
package/src/usePatient.ts CHANGED
@@ -1,86 +1,15 @@
1
1
  /** @module @category API */
2
- import { useEffect, useReducer } from 'react';
3
- import type { PatientUuid } from '@openmrs/esm-api';
2
+ import { useEffect, useMemo, useState } from 'react';
3
+ import useSWR from 'swr';
4
4
  import { fetchCurrentPatient } from '@openmrs/esm-api';
5
5
 
6
6
  export type NullablePatient = fhir.Patient | null;
7
7
 
8
- export interface CurrentPatientState {
9
- patientUuid: string | null;
10
- patient: NullablePatient;
11
- isPendingUuid: boolean;
12
- isLoadingPatient: boolean;
13
- err: Error | null;
14
- }
15
-
16
- interface LoadPatient {
17
- type: ActionTypes.loadPatient;
18
- patientUuid: string | null;
19
- }
20
-
21
- interface NewPatient {
22
- type: ActionTypes.newPatient;
23
- patient: NullablePatient;
24
- }
25
-
26
- interface PatientLoadError {
27
- type: ActionTypes.loadError;
28
- err: Error | null;
29
- }
30
-
31
- type Action = LoadPatient | NewPatient | PatientLoadError;
32
-
33
- enum ActionTypes {
34
- loadPatient = 'loadPatient',
35
- newPatient = 'newPatient',
36
- loadError = 'patientLoadError',
37
- }
38
-
39
- const initialState: CurrentPatientState = {
40
- patientUuid: null,
41
- patient: null,
42
- isPendingUuid: true,
43
- isLoadingPatient: false,
44
- err: null,
45
- };
46
-
47
- function getPatientUuidFromUrl(): PatientUuid {
8
+ function getPatientUuidFromUrl() {
48
9
  const match = /\/patient\/([a-zA-Z0-9\-]+)\/?/.exec(location.pathname);
49
10
  return match && match[1];
50
11
  }
51
12
 
52
- function reducer(state: CurrentPatientState, action: Action): CurrentPatientState {
53
- switch (action.type) {
54
- case ActionTypes.loadPatient:
55
- return {
56
- ...state,
57
- patientUuid: action.patientUuid,
58
- patient: null,
59
- isPendingUuid: false,
60
- isLoadingPatient: true,
61
- err: null,
62
- };
63
- case ActionTypes.newPatient:
64
- return {
65
- ...state,
66
- patient: action.patient,
67
- isPendingUuid: false,
68
- isLoadingPatient: false,
69
- err: null,
70
- };
71
- case ActionTypes.loadError:
72
- return {
73
- ...state,
74
- patient: null,
75
- isPendingUuid: false,
76
- isLoadingPatient: false,
77
- err: action.err,
78
- };
79
- default:
80
- return state;
81
- }
82
- }
83
-
84
13
  /**
85
14
  * This React hook returns a patient object. If the `patientUuid` is provided
86
15
  * as a parameter, then the patient for that UUID is returned. If the parameter
@@ -88,66 +17,35 @@ function reducer(state: CurrentPatientState, action: Action): CurrentPatientStat
88
17
  * a route listener is set up to update the patient whenever the route changes.
89
18
  */
90
19
  export function usePatient(patientUuid?: string) {
91
- const [state, dispatch] = useReducer(reducer, {
92
- ...initialState,
93
- patientUuid: patientUuid ?? null,
94
- isPendingUuid: !patientUuid,
95
- isLoadingPatient: !!patientUuid,
96
- });
97
-
98
- useEffect(() => {
99
- if (state.isPendingUuid) {
100
- const patientUuidFromUrl = getPatientUuidFromUrl();
101
- if (patientUuidFromUrl) {
102
- dispatch({
103
- type: ActionTypes.loadPatient,
104
- patientUuid: patientUuidFromUrl,
105
- });
106
- } else {
107
- dispatch({ type: ActionTypes.newPatient, patient: null });
108
- }
109
- }
20
+ const [currentPatientUuid, setCurrentPatientUuid] = useState(patientUuid ?? getPatientUuidFromUrl());
110
21
 
111
- let active = true;
112
- if (state.isLoadingPatient && state.patientUuid) {
113
- fetchCurrentPatient(state.patientUuid).then(
114
- (patient) =>
115
- active &&
116
- dispatch({
117
- patient: patient,
118
- type: ActionTypes.newPatient,
119
- }),
120
- (err) =>
121
- active &&
122
- dispatch({
123
- err,
124
- type: ActionTypes.loadError,
125
- }),
126
- );
127
- }
128
- return () => {
129
- active = false;
130
- };
131
- }, [state.isPendingUuid, state.isLoadingPatient, state.patientUuid]);
22
+ const {
23
+ data: patient,
24
+ error,
25
+ isValidating,
26
+ } = useSWR<NullablePatient, Error | null>(currentPatientUuid ? ['patient', currentPatientUuid] : null, () =>
27
+ fetchCurrentPatient(currentPatientUuid!, {}),
28
+ );
132
29
 
133
30
  useEffect(() => {
134
- const handleRouteUpdate = (evt) => {
31
+ const handleRouteUpdate = () => {
135
32
  const newPatientUuid = getPatientUuidFromUrl();
136
- if (newPatientUuid != state.patientUuid) {
137
- dispatch({
138
- type: ActionTypes.loadPatient,
139
- patientUuid: newPatientUuid,
140
- });
33
+ if (newPatientUuid !== currentPatientUuid) {
34
+ setCurrentPatientUuid(newPatientUuid);
141
35
  }
142
36
  };
37
+
143
38
  window.addEventListener('single-spa:routing-event', handleRouteUpdate);
144
39
  return () => window.removeEventListener('single-spa:routing-event', handleRouteUpdate);
145
- }, [state.patientUuid]);
146
-
147
- return {
148
- isLoading: state.isPendingUuid || state.isLoadingPatient,
149
- patient: state.patient,
150
- patientUuid: patientUuid ?? state.patientUuid,
151
- error: state.err,
152
- };
40
+ }, [currentPatientUuid]);
41
+
42
+ return useMemo(
43
+ () => ({
44
+ isLoading: isValidating && !error && !patient,
45
+ patient,
46
+ patientUuid: currentPatientUuid,
47
+ error,
48
+ }),
49
+ [isValidating, error, patient, currentPatientUuid],
50
+ );
153
51
  }