@openmrs/esm-generic-patient-widgets-app 11.3.1-pre.9398 → 11.3.1-pre.9403
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/.turbo/turbo-build.log +16 -16
- package/dist/1936.js +1 -0
- package/dist/1936.js.map +1 -0
- package/dist/2606.js +2 -0
- package/dist/2606.js.map +1 -0
- package/dist/4300.js +1 -1
- package/dist/5670.js +1 -1
- package/dist/7545.js +2 -0
- package/dist/7545.js.map +1 -0
- package/dist/8803.js +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/openmrs-esm-generic-patient-widgets-app.js +1 -1
- package/dist/openmrs-esm-generic-patient-widgets-app.js.buildmanifest.json +91 -91
- package/dist/openmrs-esm-generic-patient-widgets-app.js.map +1 -1
- package/dist/routes.json +1 -1
- package/package.json +2 -2
- package/src/config-schema-obs-horizontal.ts +12 -0
- package/src/obs-graph/obs-graph.component.tsx +12 -12
- package/src/obs-switchable/obs-switchable.component.tsx +5 -9
- package/src/obs-switchable/obs-switchable.test.tsx +22 -12
- package/src/obs-table/obs-table.component.tsx +2 -1
- package/src/obs-table-horizontal/obs-table-horizontal.component.tsx +466 -56
- package/src/obs-table-horizontal/obs-table-horizontal.resource.ts +67 -0
- package/src/obs-table-horizontal/obs-table-horizontal.scss +47 -0
- package/src/obs-table-horizontal/obs-table-horizontal.test.tsx +912 -0
- package/src/resources/useConcepts.ts +14 -4
- package/src/resources/useEncounterTypes.ts +34 -0
- package/src/resources/useObs.ts +29 -47
- package/translations/en.json +6 -1
- package/dist/251.js +0 -2
- package/dist/251.js.map +0 -1
- package/dist/8743.js +0 -2
- package/dist/8743.js.map +0 -1
- package/dist/9351.js +0 -1
- package/dist/9351.js.map +0 -1
- /package/dist/{251.js.LICENSE.txt → 2606.js.LICENSE.txt} +0 -0
- /package/dist/{8743.js.LICENSE.txt → 7545.js.LICENSE.txt} +0 -0
|
@@ -6,6 +6,13 @@ export interface ConceptReferenceResponse {
|
|
|
6
6
|
[key: string]: {
|
|
7
7
|
uuid: string;
|
|
8
8
|
display: string;
|
|
9
|
+
datatype: {
|
|
10
|
+
name: string;
|
|
11
|
+
};
|
|
12
|
+
answers: Array<{
|
|
13
|
+
uuid: string;
|
|
14
|
+
display: string;
|
|
15
|
+
}>;
|
|
9
16
|
};
|
|
10
17
|
}
|
|
11
18
|
|
|
@@ -15,11 +22,13 @@ export function useConcepts(conceptUuids: Array<string>) {
|
|
|
15
22
|
(key: Array<string>) => Promise.all(key.map((url) => openmrsFetch<ConceptReferenceResponse>(url))),
|
|
16
23
|
);
|
|
17
24
|
|
|
18
|
-
const
|
|
19
|
-
const concepts =
|
|
20
|
-
? Object.values(
|
|
25
|
+
const res: ConceptReferenceResponse = data?.reduce((acc, response) => ({ ...acc, ...response.data }), {});
|
|
26
|
+
const concepts = res
|
|
27
|
+
? Object.values(res).map((value) => ({
|
|
21
28
|
uuid: value.uuid,
|
|
22
29
|
display: value.display,
|
|
30
|
+
dataType: value.datatype.name,
|
|
31
|
+
answers: value.answers,
|
|
23
32
|
}))
|
|
24
33
|
: [];
|
|
25
34
|
|
|
@@ -36,6 +45,7 @@ export function useConcepts(conceptUuids: Array<string>) {
|
|
|
36
45
|
|
|
37
46
|
function getConceptReferenceUrls(conceptUuids: Array<string>) {
|
|
38
47
|
return chunk(conceptUuids, 10).map(
|
|
39
|
-
(partition) =>
|
|
48
|
+
(partition) =>
|
|
49
|
+
`${restBaseUrl}/conceptreferences?references=${partition.join(',')}&v=custom:(uuid,display,datatype,answers)`,
|
|
40
50
|
);
|
|
41
51
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { restBaseUrl, type Privilege } from '@openmrs/esm-framework';
|
|
2
|
+
import useSWRImmutable from 'swr/immutable';
|
|
3
|
+
|
|
4
|
+
export interface EncounterType {
|
|
5
|
+
uuid: string;
|
|
6
|
+
editPrivilege?: Privilege;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface UseEncountersResult {
|
|
10
|
+
encounterTypes: Array<EncounterType>;
|
|
11
|
+
error: Error;
|
|
12
|
+
isLoading: boolean;
|
|
13
|
+
isValidating: boolean;
|
|
14
|
+
mutate: () => Promise<any>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function useEncounterTypes() {
|
|
18
|
+
const customRep = 'custom:(uuid,editPrivilege)';
|
|
19
|
+
const url = new URL(`${restBaseUrl}/encountertype`, window.location.toString());
|
|
20
|
+
url.searchParams.set('v', customRep);
|
|
21
|
+
|
|
22
|
+
const { data, error, isLoading, isValidating, mutate } = useSWRImmutable<
|
|
23
|
+
{ data: { results: Array<EncounterType> } },
|
|
24
|
+
Error
|
|
25
|
+
>(`${restBaseUrl}/encountertype?v=${customRep}`);
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
encounterTypes: data?.data?.results || [],
|
|
29
|
+
error: error,
|
|
30
|
+
isLoading,
|
|
31
|
+
isValidating,
|
|
32
|
+
mutate,
|
|
33
|
+
};
|
|
34
|
+
}
|
package/src/resources/useObs.ts
CHANGED
|
@@ -9,11 +9,13 @@ type CommonConfig = ConfigObjectSwitchable | ConfigObjectHorizontal;
|
|
|
9
9
|
export interface UseObsResult {
|
|
10
10
|
data: {
|
|
11
11
|
observations: Array<ObsResult>;
|
|
12
|
-
concepts: Array<{ uuid: string; display: string }>;
|
|
12
|
+
concepts: Array<{ uuid: string; display: string; dataType: string }>;
|
|
13
|
+
encounters: Array<{ reference: string; display: string; encounterTypeUuid: string }>;
|
|
13
14
|
};
|
|
14
15
|
error: Error;
|
|
15
16
|
isLoading: boolean;
|
|
16
17
|
isValidating: boolean;
|
|
18
|
+
mutate: () => Promise<any>;
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
export type ObsResult = fhir.Observation & {
|
|
@@ -26,6 +28,7 @@ export type ObsResult = fhir.Observation & {
|
|
|
26
28
|
* Reference to the encounter resource, in the format `Encounter/{uuid}`
|
|
27
29
|
*/
|
|
28
30
|
reference: string;
|
|
31
|
+
encounterTypeUuid?: string;
|
|
29
32
|
};
|
|
30
33
|
};
|
|
31
34
|
|
|
@@ -37,52 +40,41 @@ export const pageSize = 100;
|
|
|
37
40
|
* get the label.
|
|
38
41
|
*/
|
|
39
42
|
export function useObs(patientUuid: string): UseObsResult {
|
|
40
|
-
const { encounterTypes, data
|
|
43
|
+
const { encounterTypes, data } = useConfig<CommonConfig>();
|
|
41
44
|
const urlEncounterTypes: string = encounterTypes.length ? `&encounter.type=${encounterTypes.toString()}` : '';
|
|
42
45
|
|
|
43
46
|
// TODO: Make sorting respect oldestFirst/graphOldestFirst
|
|
44
47
|
let url = `${fhirBaseUrl}/Observation?subject:Patient=${patientUuid}&code=${data
|
|
45
48
|
.map((d) => d.concept)
|
|
46
|
-
.join(',')}&_summary=data&_sort=-date&_count=${pageSize}${urlEncounterTypes}`;
|
|
49
|
+
.join(',')}&_summary=data&_include=Observation:encounter&_sort=-date&_count=${pageSize}${urlEncounterTypes}`;
|
|
47
50
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
data.map((d) => [
|
|
56
|
-
d.concept,
|
|
57
|
-
result?.data?.entry?.find((e) => (e.resource as fhir.Observation).code.coding.find((c) => d.concept === c.code)),
|
|
58
|
-
]),
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
const conceptsNeedingLabel = data.filter((d) => result && !d.label && !obsForConcept[d.concept]);
|
|
51
|
+
const {
|
|
52
|
+
data: result,
|
|
53
|
+
error,
|
|
54
|
+
isLoading,
|
|
55
|
+
isValidating,
|
|
56
|
+
mutate,
|
|
57
|
+
} = useSWR<{ data: fhir.Bundle }, Error>(url, openmrsFetch);
|
|
62
58
|
|
|
63
|
-
const { concepts
|
|
64
|
-
const concepts = data.map((d) => ({
|
|
65
|
-
uuid: d.concept,
|
|
66
|
-
display:
|
|
67
|
-
d.label ||
|
|
68
|
-
obsForConcept[d.concept]?.resource?.code?.text ||
|
|
69
|
-
conceptsForLabels.find((c) => c.uuid === d.concept)?.display,
|
|
70
|
-
}));
|
|
59
|
+
const { concepts } = useConcepts(data.map((d) => d.concept));
|
|
71
60
|
|
|
72
|
-
const encounters =
|
|
73
|
-
const observations = filterAndMapObservations(result?.data?.entry, encounters);
|
|
61
|
+
const encounters = getEncountersFromResources(result?.data?.entry);
|
|
62
|
+
const observations = filterAndMapObservations(result?.data?.entry, encounters, concepts);
|
|
74
63
|
return {
|
|
75
|
-
data: { observations, concepts },
|
|
64
|
+
data: { observations, concepts, encounters },
|
|
76
65
|
error: error,
|
|
77
66
|
isLoading,
|
|
78
67
|
isValidating,
|
|
68
|
+
mutate,
|
|
79
69
|
};
|
|
80
70
|
}
|
|
81
71
|
|
|
82
72
|
function filterAndMapObservations(
|
|
83
73
|
entries: Array<fhir.BundleEntry>,
|
|
84
|
-
encounters: Array<{ reference: string; display: string }>,
|
|
74
|
+
encounters: Array<{ reference: string; display: string; encounterTypeUuid: string }>,
|
|
75
|
+
concepts: Array<{ uuid: string; display: string; dataType: string }>,
|
|
85
76
|
): ObsResult[] {
|
|
77
|
+
const conceptByUuid = Object.fromEntries(concepts.map((c) => [c.uuid, c]));
|
|
86
78
|
return (
|
|
87
79
|
entries
|
|
88
80
|
?.filter((entry) => entry?.resource?.resourceType === 'Observation')
|
|
@@ -91,39 +83,29 @@ function filterAndMapObservations(
|
|
|
91
83
|
const observation: ObsResult = {
|
|
92
84
|
...resource,
|
|
93
85
|
conceptUuid: resource.code.coding.find((c) => isUuid(c.code))?.code,
|
|
86
|
+
dataType: conceptByUuid[resource.code.coding.find((c) => isUuid(c.code))?.code]?.dataType,
|
|
94
87
|
};
|
|
95
|
-
if (resource.hasOwnProperty('valueDateTime')) {
|
|
96
|
-
observation.dataType = 'DateTime';
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (entry.resource.hasOwnProperty('valueString')) {
|
|
100
|
-
observation.dataType = 'Text';
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
if (entry.resource.hasOwnProperty('valueQuantity')) {
|
|
104
|
-
observation.dataType = 'Number';
|
|
105
|
-
}
|
|
106
88
|
|
|
107
|
-
|
|
108
|
-
observation.dataType = 'Coded';
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
observation.encounter.name = encounters.find(
|
|
89
|
+
const encounter = encounters.find(
|
|
112
90
|
(e) =>
|
|
113
91
|
e.reference === (resource as fhir.Observation & { encounter: { reference?: string } }).encounter.reference,
|
|
114
|
-
)
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
observation.encounter.name = encounter?.display;
|
|
95
|
+
observation.encounter.encounterTypeUuid = encounter?.encounterTypeUuid;
|
|
115
96
|
|
|
116
97
|
return observation;
|
|
117
98
|
}) || []
|
|
118
99
|
);
|
|
119
100
|
}
|
|
120
101
|
|
|
121
|
-
function
|
|
102
|
+
function getEncountersFromResources(resources: Array<fhir.BundleEntry>) {
|
|
122
103
|
return resources
|
|
123
104
|
?.filter((entry) => entry?.resource?.resourceType === 'Encounter')
|
|
124
105
|
.map((entry: fhir.BundleEntry) => ({
|
|
125
106
|
reference: `Encounter/${entry.resource.id}`,
|
|
126
107
|
display: (entry.resource as fhir.Encounter).type?.[0]?.coding?.[0]?.display || '--',
|
|
108
|
+
encounterTypeUuid: (entry.resource as fhir.Encounter).type?.[0]?.coding?.[0]?.code,
|
|
127
109
|
}));
|
|
128
110
|
}
|
|
129
111
|
|
package/translations/en.json
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
+
"addEncounter": "Add encounter",
|
|
2
3
|
"date": "Date",
|
|
3
4
|
"dateAndTime": "Date and time",
|
|
4
|
-
"
|
|
5
|
+
"editabilityNote": "Tap an observation to edit",
|
|
6
|
+
"encounterType": "Encounter type",
|
|
7
|
+
"errorSavingObservation": "Error saving observation",
|
|
8
|
+
"noValue": "No value",
|
|
9
|
+
"observationSaved": "Observation saved successfully"
|
|
5
10
|
}
|