@openmrs/esm-patient-chart-app 11.3.0 → 11.3.1-patch.9310
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 +27 -24
- package/dist/1119.js +1 -1
- package/dist/1197.js +1 -1
- package/dist/1815.js +2 -0
- package/dist/1815.js.map +1 -0
- package/dist/2146.js +1 -1
- package/dist/2690.js +1 -1
- package/dist/2761.js +1 -1
- package/dist/2761.js.map +1 -1
- package/dist/2859.js +1 -1
- package/dist/2859.js.map +1 -1
- package/dist/3099.js +1 -1
- package/dist/3584.js +1 -1
- package/dist/3697.js +1 -0
- package/dist/3697.js.map +1 -0
- package/dist/4055.js +1 -1
- package/dist/4132.js +1 -1
- package/dist/4300.js +1 -1
- package/dist/4335.js +1 -1
- package/dist/4618.js +1 -1
- package/dist/4632.js +1 -1
- package/dist/4632.js.map +1 -1
- package/dist/4652.js +1 -1
- package/dist/4718.js +1 -1
- package/dist/4754.js +1 -1
- package/dist/4944.js +1 -1
- package/dist/5173.js +1 -1
- package/dist/5205.js +1 -1
- package/dist/5241.js +1 -1
- package/dist/5442.js +1 -1
- package/dist/5661.js +1 -1
- package/dist/5670.js +1 -0
- package/dist/5670.js.map +1 -0
- package/dist/5827.js +1 -0
- package/dist/5827.js.map +1 -0
- package/dist/6022.js +1 -1
- package/dist/6336.js +1 -0
- package/dist/6336.js.map +1 -0
- package/dist/6411.js +1 -1
- package/dist/6411.js.map +1 -1
- package/dist/6468.js +1 -1
- package/dist/6529.js +1 -1
- package/dist/6568.js +1 -0
- package/dist/6568.js.map +1 -0
- package/dist/6679.js +1 -1
- package/dist/68.js +2 -0
- package/dist/68.js.map +1 -0
- package/dist/6840.js +1 -1
- package/dist/6859.js +1 -1
- package/dist/6924.js +1 -0
- package/dist/6924.js.map +1 -0
- package/dist/7097.js +1 -1
- package/dist/7159.js +1 -1
- package/dist/723.js +1 -1
- package/dist/7617.js +1 -1
- package/dist/7816.js +2 -0
- package/dist/7816.js.map +1 -0
- package/dist/7818.js +1 -0
- package/dist/7818.js.map +1 -0
- package/dist/7822.js +1 -0
- package/dist/7822.js.map +1 -0
- package/dist/795.js +1 -1
- package/dist/8163.js +1 -1
- package/dist/8260.js +1 -0
- package/dist/8260.js.map +1 -0
- package/dist/8278.js +1 -0
- package/dist/8278.js.map +1 -0
- package/dist/8349.js +1 -1
- package/dist/8454.js +1 -1
- package/dist/8454.js.map +1 -1
- package/dist/8618.js +1 -1
- package/dist/8709.js +1 -1
- package/dist/8709.js.map +1 -1
- package/dist/890.js +1 -1
- package/dist/9007.js +1 -1
- package/dist/9007.js.map +1 -1
- package/dist/9214.js +1 -1
- package/dist/{4727.js → 9294.js} +1 -1
- package/dist/9294.js.map +1 -0
- package/dist/9329.js +1 -0
- package/dist/9329.js.map +1 -0
- package/dist/9538.js +1 -1
- package/dist/9569.js +1 -1
- package/dist/986.js +1 -1
- package/dist/9879.js +1 -1
- package/dist/9895.js +1 -1
- package/dist/9900.js +1 -1
- package/dist/9913.js +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/openmrs-esm-patient-chart-app.js +1 -1
- package/dist/openmrs-esm-patient-chart-app.js.buildmanifest.json +457 -453
- package/dist/openmrs-esm-patient-chart-app.js.map +1 -1
- package/dist/routes.json +1 -1
- package/package.json +5 -4
- package/src/actions-buttons/delete-visit.component.tsx +8 -3
- package/src/actions-buttons/mark-patient-deceased.component.tsx +2 -2
- package/src/actions-buttons/start-visit.component.tsx +10 -5
- package/src/actions-buttons/start-visit.test.tsx +9 -5
- package/src/actions-buttons/stop-visit.component.tsx +1 -1
- package/src/clinical-views/encounter-list/{encounter-list-tabs.component.tsx → encounter-list-tabs.extension.tsx} +10 -6
- package/src/clinical-views/encounter-list/tag.component.test.tsx +306 -0
- package/src/clinical-views/encounter-list/tag.component.tsx +27 -28
- package/src/clinical-views/encounter-tile/encounter-tile.component.tsx +7 -6
- package/src/clinical-views/encounter-tile/tile.scss +0 -1
- package/src/clinical-views/hooks/useEncountersByVisit.ts +13 -0
- package/src/clinical-views/hooks/useLastEncounter.ts +1 -1
- package/src/clinical-views/types.ts +2 -1
- package/src/clinical-views/utils/concept-utils.ts +24 -0
- package/src/clinical-views/utils/helpers.ts +2 -2
- package/src/clinical-views/utils/index.ts +4 -1
- package/src/config-schema.ts +42 -9
- package/src/dashboard.meta.ts +4 -2
- package/src/index.ts +21 -22
- package/src/mark-patient-deceased/mark-patient-deceased-form.test.tsx +22 -11
- package/src/mark-patient-deceased/mark-patient-deceased-form.workspace.tsx +147 -138
- package/src/patient-banner-tags/{visit-attribute-tags.component.tsx → visit-attribute-tags.extension.tsx} +9 -4
- package/src/patient-chart/chart-review/dashboard-view.component.tsx +2 -2
- package/src/patient-chart/patient-chart.component.tsx +19 -36
- package/src/patient-chart/patient-chart.resources.ts +150 -0
- package/src/routes.json +17 -6
- package/src/visit/hooks/useDeleteVisit.test.tsx +39 -42
- package/src/visit/hooks/useDeleteVisit.tsx +33 -17
- package/src/visit/start-visit-button.component.tsx +2 -2
- package/src/visit/start-visit-button.test.tsx +2 -2
- package/src/visit/visit-action-items/edit-visit-details.component.tsx +29 -8
- package/src/visit/visit-form/base-visit-type.component.tsx +2 -2
- package/src/visit/visit-form/exported-visit-form.workspace.tsx +697 -0
- package/src/visit/visit-form/visit-attribute-type.component.tsx +2 -1
- package/src/visit/visit-form/visit-form.resource.ts +2 -1
- package/src/visit/visit-form/visit-form.test.tsx +28 -25
- package/src/visit/visit-form/visit-form.workspace.tsx +63 -643
- package/src/visit/visit-history-table/visit-actions-cell.component.tsx +3 -2
- package/src/visit/visit-history-table/visit-date-cell.component.tsx +1 -0
- package/src/visit/visit-history-table/visit-diagnoses-cell.component.tsx +1 -0
- package/src/visit/visit-history-table/visit-history-table.component.tsx +3 -2
- package/src/visit/visit-history-table/visit-type-cell.component.tsx +1 -0
- package/src/visit/visit-prompt/{delete-visit-dialog.component.tsx → delete-visit-dialog.modal.tsx} +10 -4
- package/src/visit/visit-prompt/delete-visit-dialog.test.tsx +21 -3
- package/src/visit/visit-prompt/{end-visit-dialog.component.tsx → end-visit-dialog.modal.tsx} +7 -1
- package/src/visit/visit-prompt/end-visit-dialog.test.tsx +20 -1
- package/src/visit/visit-prompt/{start-visit-dialog.component.tsx → start-visit-dialog.modal.tsx} +10 -4
- package/src/visit/visit-prompt/start-visit-dialog.test.tsx +3 -3
- package/src/visit/visits-widget/active-visit-buttons/active-visit-buttons.tsx +7 -6
- package/src/visit/visits-widget/current-visit-summary.extension.tsx +48 -0
- package/src/visit/visits-widget/current-visit-summary.test.tsx +45 -25
- package/src/visit/visits-widget/past-visits-components/encounters-table/encounters-table.component.tsx +15 -37
- package/src/visit/visits-widget/past-visits-components/encounters-table/encounters-table.resource.ts +0 -1
- package/src/visit/visits-widget/past-visits-components/medications-summary.component.tsx +2 -3
- package/src/visit/visits-widget/past-visits-components/visit-summary.component.tsx +8 -1
- package/src/visit/visits-widget/past-visits-components/visit-summary.scss +1 -1
- package/src/visit/visits-widget/single-visit-details/visit-timeline/visit-timeline.component.tsx +94 -0
- package/src/visit/visits-widget/single-visit-details/visit-timeline/visit-timeline.scss +60 -0
- package/src/visit/visits-widget/visit-context/retrospective-data-date-time-picker/retrospective-date-time-picker.component.tsx +6 -7
- package/src/visit/visits-widget/visit-context/{visit-context-header.component.tsx → visit-context-header.extension.tsx} +17 -15
- package/src/visit/visits-widget/visit-context/visit-context-header.test.tsx +35 -29
- package/src/visit/visits-widget/visit-context/visit-context-switcher.modal.tsx +15 -13
- package/src/visit/visits-widget/visit-context/visit-context-switcher.test.tsx +31 -9
- package/src/visit/visits-widget/visit-detail-overview.component.tsx +3 -2
- package/src/visit/visits-widget/visit-detail-overview.test.tsx +4 -4
- package/src/visit/visits-widget/visit.resource.tsx +1 -1
- package/translations/am.json +6 -0
- package/translations/ar.json +6 -0
- package/translations/ar_SY.json +6 -0
- package/translations/bn.json +6 -0
- package/translations/de.json +6 -0
- package/translations/en.json +7 -2
- package/translations/en_US.json +6 -0
- package/translations/es.json +6 -0
- package/translations/es_MX.json +6 -0
- package/translations/fr.json +15 -9
- package/translations/he.json +6 -0
- package/translations/hi.json +6 -0
- package/translations/hi_IN.json +6 -0
- package/translations/id.json +6 -0
- package/translations/it.json +24 -18
- package/translations/ka.json +6 -0
- package/translations/km.json +6 -0
- package/translations/ku.json +6 -0
- package/translations/ky.json +6 -0
- package/translations/lg.json +6 -0
- package/translations/ne.json +6 -0
- package/translations/pl.json +6 -0
- package/translations/pt.json +6 -0
- package/translations/pt_BR.json +6 -0
- package/translations/qu.json +6 -0
- package/translations/ro_RO.json +6 -0
- package/translations/ru_RU.json +6 -0
- package/translations/si.json +6 -0
- package/translations/sw.json +6 -0
- package/translations/sw_KE.json +6 -0
- package/translations/tr.json +6 -0
- package/translations/tr_TR.json +6 -0
- package/translations/uk.json +6 -0
- package/translations/uz.json +6 -0
- package/translations/uz@Latn.json +6 -0
- package/translations/uz_UZ.json +6 -0
- package/translations/vi.json +6 -0
- package/translations/zh.json +6 -0
- package/translations/zh_CN.json +6 -0
- package/dist/2537.js +0 -1
- package/dist/2537.js.map +0 -1
- package/dist/2735.js +0 -2
- package/dist/2735.js.map +0 -1
- package/dist/276.js +0 -1
- package/dist/276.js.map +0 -1
- package/dist/3042.js +0 -1
- package/dist/3042.js.map +0 -1
- package/dist/3119.js +0 -1
- package/dist/3119.js.map +0 -1
- package/dist/3184.js +0 -1
- package/dist/3184.js.map +0 -1
- package/dist/385.js +0 -2
- package/dist/385.js.map +0 -1
- package/dist/3905.js +0 -1
- package/dist/3905.js.map +0 -1
- package/dist/4713.js +0 -1
- package/dist/4713.js.map +0 -1
- package/dist/4727.js.map +0 -1
- package/dist/717.js +0 -1
- package/dist/717.js.map +0 -1
- package/dist/9162.js +0 -2
- package/dist/9162.js.map +0 -1
- package/dist/9206.js +0 -1
- package/dist/9206.js.map +0 -1
- package/dist/9615.js +0 -1
- package/dist/9615.js.map +0 -1
- package/src/visit/visits-widget/current-visit-summary.component.tsx +0 -55
- /package/dist/{9162.js.LICENSE.txt → 1815.js.LICENSE.txt} +0 -0
- /package/dist/{385.js.LICENSE.txt → 68.js.LICENSE.txt} +0 -0
- /package/dist/{2735.js.LICENSE.txt → 7816.js.LICENSE.txt} +0 -0
|
@@ -9,36 +9,35 @@ export const renderTag = (
|
|
|
9
9
|
statusColorMappings: Record<string, string>,
|
|
10
10
|
config: ConfigConcepts,
|
|
11
11
|
) => {
|
|
12
|
-
const columnStatus = getObsFromEncounter({ encounter
|
|
12
|
+
const columnStatus = getObsFromEncounter({ encounter, obsConcept: concept, config });
|
|
13
13
|
const columnStatusObs = findObs(encounter, concept);
|
|
14
14
|
|
|
15
|
-
if (columnStatus
|
|
15
|
+
if (columnStatus === '--') {
|
|
16
16
|
return '--';
|
|
17
|
-
} else {
|
|
18
|
-
return (
|
|
19
|
-
<Tag
|
|
20
|
-
type={
|
|
21
|
-
typeof columnStatusObs?.value === 'object' && 'uuid' in columnStatusObs.value
|
|
22
|
-
? (statusColorMappings[columnStatusObs.value.uuid] as
|
|
23
|
-
| 'red'
|
|
24
|
-
| 'magenta'
|
|
25
|
-
| 'purple'
|
|
26
|
-
| 'blue'
|
|
27
|
-
| 'cyan'
|
|
28
|
-
| 'teal'
|
|
29
|
-
| 'green'
|
|
30
|
-
| 'gray'
|
|
31
|
-
| 'cool-gray'
|
|
32
|
-
| 'warm-gray'
|
|
33
|
-
| 'high-contrast'
|
|
34
|
-
| 'outline')
|
|
35
|
-
: undefined
|
|
36
|
-
}
|
|
37
|
-
title={typeof columnStatus === 'string' ? columnStatus : ''}
|
|
38
|
-
style={{ minWidth: '80px' }}
|
|
39
|
-
>
|
|
40
|
-
{typeof columnStatus === 'string' ? columnStatus : ''}
|
|
41
|
-
</Tag>
|
|
42
|
-
);
|
|
43
17
|
}
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<Tag
|
|
21
|
+
type={
|
|
22
|
+
typeof columnStatusObs?.value === 'object' && 'uuid' in columnStatusObs.value
|
|
23
|
+
? (statusColorMappings[columnStatusObs.value.uuid] as
|
|
24
|
+
| 'red'
|
|
25
|
+
| 'magenta'
|
|
26
|
+
| 'purple'
|
|
27
|
+
| 'blue'
|
|
28
|
+
| 'cyan'
|
|
29
|
+
| 'teal'
|
|
30
|
+
| 'green'
|
|
31
|
+
| 'gray'
|
|
32
|
+
| 'cool-gray'
|
|
33
|
+
| 'warm-gray'
|
|
34
|
+
| 'high-contrast'
|
|
35
|
+
| 'outline')
|
|
36
|
+
: undefined
|
|
37
|
+
}
|
|
38
|
+
style={{ minWidth: '80px' }}
|
|
39
|
+
>
|
|
40
|
+
{typeof columnStatus === 'string' ? columnStatus : ''}
|
|
41
|
+
</Tag>
|
|
42
|
+
);
|
|
44
43
|
};
|
|
@@ -5,6 +5,7 @@ import { isNil } from 'lodash-es';
|
|
|
5
5
|
import { useLayoutType } from '@openmrs/esm-framework';
|
|
6
6
|
import { useLastEncounter } from '../hooks';
|
|
7
7
|
import type { EncounterTileColumn, EncounterTileProps } from '../types';
|
|
8
|
+
import { withUnit, getConceptUnitsFromEncounter } from '../utils/concept-utils';
|
|
8
9
|
import styles from './tile.scss';
|
|
9
10
|
|
|
10
11
|
export const EncounterTile = memo(({ patientUuid, columns, headerTitle }: EncounterTileProps) => {
|
|
@@ -41,6 +42,10 @@ const EncounterData: React.FC<{
|
|
|
41
42
|
}> = ({ patientUuid, column }) => {
|
|
42
43
|
const { t } = useTranslation();
|
|
43
44
|
const { lastEncounter, isLoading, error, isValidating } = useLastEncounter(patientUuid, column.encounterTypeUuid);
|
|
45
|
+
const units = getConceptUnitsFromEncounter(lastEncounter, column.concept);
|
|
46
|
+
const summaryUnits = column.summaryConcept?.primaryConcept
|
|
47
|
+
? getConceptUnitsFromEncounter(lastEncounter, column.summaryConcept.primaryConcept)
|
|
48
|
+
: null;
|
|
44
49
|
const obsValue = column.getObsValue(lastEncounter);
|
|
45
50
|
const summaryValue =
|
|
46
51
|
column.hasSummary === true && column.getSummaryObsValue && typeof column.getSummaryObsValue === 'function'
|
|
@@ -64,15 +69,11 @@ const EncounterData: React.FC<{
|
|
|
64
69
|
<>
|
|
65
70
|
<span className={styles.tileTitle}>{t(column.header)}</span>
|
|
66
71
|
{!(obsValue === '--' && summaryValue !== '--' && !isNil(summaryValue)) && (
|
|
67
|
-
<
|
|
68
|
-
<p>{obsValue}</p>
|
|
69
|
-
</span>
|
|
72
|
+
<div className={styles.tileValue}>{withUnit(obsValue, units)}</div>
|
|
70
73
|
)}
|
|
71
74
|
|
|
72
75
|
{!isNil(summaryValue) && summaryValue !== '--' && (
|
|
73
|
-
<
|
|
74
|
-
<p>{summaryValue}</p>
|
|
75
|
-
</span>
|
|
76
|
+
<div className={styles.tileValue}>{withUnit(summaryValue, summaryUnits)}</div>
|
|
76
77
|
)}
|
|
77
78
|
</>
|
|
78
79
|
);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Encounter, restBaseUrl, useOpenmrsFetchAll } from '@openmrs/esm-framework';
|
|
2
|
+
|
|
3
|
+
export function useEncountersByVisit(patientUuid: string, visitUuid: string) {
|
|
4
|
+
const customRepresentation =
|
|
5
|
+
'custom:(uuid,encounterType:(uuid,display),encounterProviders:(provider:(person:(display))),encounterDatetime,visit:(uuid))';
|
|
6
|
+
const url = `${restBaseUrl}/encounter?patient=${patientUuid}&order=desc&visit=${visitUuid}&v=${customRepresentation}`;
|
|
7
|
+
const { data: encounters, ...rest } = useOpenmrsFetchAll<Encounter>(url);
|
|
8
|
+
|
|
9
|
+
return {
|
|
10
|
+
encounters,
|
|
11
|
+
...rest,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
@@ -5,7 +5,7 @@ import useSWR from 'swr';
|
|
|
5
5
|
const encounterRepresentation =
|
|
6
6
|
'custom:(uuid,encounterDatetime,encounterType,location:(uuid,name),' +
|
|
7
7
|
'patient:(uuid,display,age,identifiers,person),encounterProviders:(uuid,provider:(uuid,name)),' +
|
|
8
|
-
'obs:(uuid,obsDatetime,voided,groupMembers,concept:(uuid,display,name:(uuid,name)),value:(uuid,name:(uuid,name,display),' +
|
|
8
|
+
'obs:(uuid,obsDatetime,voided,groupMembers,concept:(uuid,display,units,name:(uuid,name)),value:(uuid,name:(uuid,name,display),' +
|
|
9
9
|
'names:(uuid,conceptNameType,name,display))),form:(uuid,name))';
|
|
10
10
|
|
|
11
11
|
export function useLastEncounter(patientUuid: string, encounterType: string) {
|
|
@@ -38,7 +38,7 @@ export interface Encounter extends OpenmrsResource {
|
|
|
38
38
|
|
|
39
39
|
export interface Observation {
|
|
40
40
|
uuid: string;
|
|
41
|
-
concept: { uuid: string; name: string };
|
|
41
|
+
concept: { uuid: string; name: string; units?: string };
|
|
42
42
|
value:
|
|
43
43
|
| {
|
|
44
44
|
uuid: string;
|
|
@@ -245,6 +245,7 @@ export interface EncounterTileColumn {
|
|
|
245
245
|
getSummaryObsValue?: (encounter: Encounter) => string;
|
|
246
246
|
encounter?: Encounter;
|
|
247
247
|
hasSummary?: boolean;
|
|
248
|
+
summaryConcept?: SummaryConcept;
|
|
248
249
|
}
|
|
249
250
|
export interface EncounterTileProps {
|
|
250
251
|
patientUuid: string;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Encounter } from '../types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Helper function to extract units from an encounter for a specific concept
|
|
5
|
+
* @param encounter The encounter containing observations
|
|
6
|
+
* @param conceptUuid The concept UUID to find
|
|
7
|
+
* @returns The units string if found
|
|
8
|
+
*/
|
|
9
|
+
export function getConceptUnitsFromEncounter(encounter: Encounter | null, conceptUuid: string): string {
|
|
10
|
+
if (!encounter || !encounter.obs || !conceptUuid) {
|
|
11
|
+
return '';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Find the observation for this concept
|
|
15
|
+
const obs = encounter.obs.find((o) => o.concept?.uuid === conceptUuid);
|
|
16
|
+
|
|
17
|
+
// Return the units if found
|
|
18
|
+
return obs?.concept?.units || '';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const withUnit = (value: string | number, unit: string | null | undefined) => {
|
|
22
|
+
if (!value || value === '--') return value;
|
|
23
|
+
return unit ? `${value} ${unit}` : value;
|
|
24
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { age, formatDate,
|
|
1
|
+
import { age, formatDate, launchWorkspace2, parseDate, type Visit } from '@openmrs/esm-framework';
|
|
2
2
|
import { launchStartVisitPrompt } from '@openmrs/esm-patient-common-lib';
|
|
3
3
|
import type {
|
|
4
4
|
ConfigConcepts,
|
|
@@ -25,7 +25,7 @@ export function launchEncounterForm(
|
|
|
25
25
|
if (!visit && requireActiveVisitForEncounterTile) {
|
|
26
26
|
launchStartVisitPrompt();
|
|
27
27
|
} else
|
|
28
|
-
|
|
28
|
+
launchWorkspace2('patient-form-entry-workspace', {
|
|
29
29
|
workspaceTitle: form?.display ?? form?.name,
|
|
30
30
|
mutateForm: onFormSave,
|
|
31
31
|
formInfo: {
|
|
@@ -13,6 +13,7 @@ export const getEncounterTileColumns = (tileDefinition: MenuCardProps, config: C
|
|
|
13
13
|
concept: column.concept,
|
|
14
14
|
encounterTypeUuid: column.encounterType,
|
|
15
15
|
hasSummary: column.hasSummary || false,
|
|
16
|
+
summaryConcept: column.summaryConcept,
|
|
16
17
|
getObsValue: (encounter: Encounter) => {
|
|
17
18
|
let obsValue;
|
|
18
19
|
if (column.conceptMappings) {
|
|
@@ -35,7 +36,9 @@ export const getEncounterTileColumns = (tileDefinition: MenuCardProps, config: C
|
|
|
35
36
|
config: config,
|
|
36
37
|
});
|
|
37
38
|
}
|
|
38
|
-
return typeof obsValue === 'string' || (typeof obsValue === 'number' && !isNaN(obsValue))
|
|
39
|
+
return typeof obsValue === 'string' || (typeof obsValue === 'number' && !isNaN(obsValue))
|
|
40
|
+
? obsValue
|
|
41
|
+
: obsValue?.name?.name ?? '--';
|
|
39
42
|
},
|
|
40
43
|
getSummaryObsValue: column.hasSummary
|
|
41
44
|
? (encounter: Encounter) => {
|
package/src/config-schema.ts
CHANGED
|
@@ -19,7 +19,8 @@ export const esmPatientChartSchema = {
|
|
|
19
19
|
encounterEditableDuration: {
|
|
20
20
|
_type: Type.Number,
|
|
21
21
|
_default: 0,
|
|
22
|
-
_description:
|
|
22
|
+
_description:
|
|
23
|
+
'The number of minutes an encounter is editable after it is created. 0 means the encounter is editable forever.',
|
|
23
24
|
},
|
|
24
25
|
encounterEditableDurationOverridePrivileges: {
|
|
25
26
|
_type: Type.Array,
|
|
@@ -27,7 +28,8 @@ export const esmPatientChartSchema = {
|
|
|
27
28
|
_type: Type.String,
|
|
28
29
|
},
|
|
29
30
|
_default: [],
|
|
30
|
-
_description:
|
|
31
|
+
_description:
|
|
32
|
+
'The privileges that allow users to edit encounters even after the editable duration (set by `encounterEditableDuration`) has expired. Any privilege in the list is sufficient to edit the encounter.',
|
|
31
33
|
},
|
|
32
34
|
freeTextFieldConceptUuid: {
|
|
33
35
|
_type: Type.ConceptUuid,
|
|
@@ -82,12 +84,6 @@ export const esmPatientChartSchema = {
|
|
|
82
84
|
_description: 'Shows the All Encounters Tab of Patient Visits section in Patient Chart',
|
|
83
85
|
_default: true,
|
|
84
86
|
},
|
|
85
|
-
showExtraVisitAttributesSlot: {
|
|
86
|
-
_type: Type.Boolean,
|
|
87
|
-
_description:
|
|
88
|
-
'Whether on start visit form should handle submission of the extra visit attributes from the extra visit attributes slot',
|
|
89
|
-
_default: false,
|
|
90
|
-
},
|
|
91
87
|
showRecommendedVisitTypeTab: {
|
|
92
88
|
_type: Type.Boolean,
|
|
93
89
|
_description: 'Whether start visit form should display recommended visit type tab. Requires `visitTypeResourceUrl`',
|
|
@@ -160,11 +156,39 @@ export const esmPatientChartSchema = {
|
|
|
160
156
|
_description: 'Default concept uuid for other in forms',
|
|
161
157
|
_default: '5622AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
162
158
|
},
|
|
159
|
+
tileDefinitions: {
|
|
160
|
+
_type: Type.Array,
|
|
161
|
+
_default: [
|
|
162
|
+
{
|
|
163
|
+
title: 'Weight and Height',
|
|
164
|
+
columns: [
|
|
165
|
+
{
|
|
166
|
+
title: 'Weight',
|
|
167
|
+
concept: '5089AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
168
|
+
encounterType: '67a71486-1a54-468f-ac3e-7091a9a79584',
|
|
169
|
+
hasSummary: true,
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
title: 'Height',
|
|
173
|
+
concept: '5090AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
174
|
+
encounterType: '67a71486-1a54-468f-ac3e-7091a9a79584',
|
|
175
|
+
hasSummary: true,
|
|
176
|
+
},
|
|
177
|
+
],
|
|
178
|
+
},
|
|
179
|
+
],
|
|
180
|
+
_description: 'Definitions for clinical summary tiles with their concepts and encounter types',
|
|
181
|
+
},
|
|
163
182
|
requireActiveVisitForEncounterTile: {
|
|
164
183
|
_type: Type.Boolean,
|
|
165
184
|
_description: 'Whether to require an active visit for the encounter tile',
|
|
166
185
|
_default: true,
|
|
167
186
|
},
|
|
187
|
+
drugOrderTypeUUID: {
|
|
188
|
+
_type: Type.UUID,
|
|
189
|
+
_description: "UUID for the 'Drug' order type to fetch medications",
|
|
190
|
+
_default: '131168f4-15f5-102d-96e4-000c29c2a5d7',
|
|
191
|
+
},
|
|
168
192
|
};
|
|
169
193
|
|
|
170
194
|
export interface ChartConfig {
|
|
@@ -183,7 +207,6 @@ export interface ChartConfig {
|
|
|
183
207
|
offlineVisitTypeUuid: string;
|
|
184
208
|
restrictByVisitLocationTag: boolean;
|
|
185
209
|
showAllEncountersTab: boolean;
|
|
186
|
-
showExtraVisitAttributesSlot: boolean;
|
|
187
210
|
showRecommendedVisitTypeTab: boolean;
|
|
188
211
|
showServiceQueueFields: boolean; // used by extension from esm-service-queues-app
|
|
189
212
|
showUpcomingAppointments: boolean; // used by extension from esm-appointments-app
|
|
@@ -198,5 +221,15 @@ export interface ChartConfig {
|
|
|
198
221
|
requireActiveVisitForEncounterTile: boolean;
|
|
199
222
|
trueConceptUuid: string;
|
|
200
223
|
falseConceptUuid: string;
|
|
224
|
+
tileDefinitions: Array<{
|
|
225
|
+
title: string;
|
|
226
|
+
columns: Array<{
|
|
227
|
+
title: string;
|
|
228
|
+
concept: string;
|
|
229
|
+
encounterType: string;
|
|
230
|
+
hasSummary?: boolean;
|
|
231
|
+
}>;
|
|
232
|
+
}>;
|
|
201
233
|
otherConceptUuid: string;
|
|
234
|
+
drugOrderTypeUUID: string;
|
|
202
235
|
}
|
package/src/dashboard.meta.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
import { type DashboardLinkConfig } from '@openmrs/esm-patient-common-lib';
|
|
2
|
+
|
|
3
|
+
export const summaryDashboardMeta: DashboardLinkConfig & { slot: string } = {
|
|
2
4
|
slot: 'patient-chart-summary-dashboard-slot',
|
|
3
5
|
path: 'Patient Summary',
|
|
4
6
|
title: 'Patient Summary',
|
|
5
7
|
icon: 'omrs-icon-report',
|
|
6
8
|
};
|
|
7
9
|
|
|
8
|
-
export const encountersDashboardMeta = {
|
|
10
|
+
export const encountersDashboardMeta: DashboardLinkConfig & { slot: string } = {
|
|
9
11
|
slot: 'patient-chart-encounters-dashboard-slot',
|
|
10
12
|
path: 'Visits',
|
|
11
13
|
title: 'Visits',
|
package/src/index.ts
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
defineConfigSchema,
|
|
3
|
-
defineExtensionConfigSchema,
|
|
4
|
-
getAsyncLifecycle,
|
|
5
|
-
getSyncLifecycle,
|
|
6
|
-
} from '@openmrs/esm-framework';
|
|
1
|
+
import { defineConfigSchema, getAsyncLifecycle, getSyncLifecycle } from '@openmrs/esm-framework';
|
|
7
2
|
import * as Framework from '@openmrs/esm-framework';
|
|
8
3
|
import { createDashboardLink } from '@openmrs/esm-patient-common-lib';
|
|
9
4
|
import { esmPatientChartSchema } from './config-schema';
|
|
@@ -11,7 +6,7 @@ import { moduleName } from './constants';
|
|
|
11
6
|
import { setupCacheableRoutes, setupOfflineVisitsSync } from './offline';
|
|
12
7
|
import { summaryDashboardMeta, encountersDashboardMeta } from './dashboard.meta';
|
|
13
8
|
import deleteVisitActionButtonComponent from './actions-buttons/delete-visit.component';
|
|
14
|
-
import currentVisitSummaryComponent from './visit/visits-widget/current-visit-summary.
|
|
9
|
+
import currentVisitSummaryComponent from './visit/visits-widget/current-visit-summary.extension';
|
|
15
10
|
import markPatientAliveActionButtonComponent from './actions-buttons/mark-patient-alive.component';
|
|
16
11
|
import markPatientDeceasedActionButtonComponent from './actions-buttons/mark-patient-deceased.component';
|
|
17
12
|
import pastVisitsOverviewComponent from './visit/visits-widget/visit-detail-overview.component';
|
|
@@ -20,7 +15,7 @@ import patientDetailsTileComponent from './patient-details-tile/patient-details-
|
|
|
20
15
|
import startVisitActionButtonComponent from './actions-buttons/start-visit.component';
|
|
21
16
|
import startVisitActionButtonOnPatientSearch from './visit/start-visit-button.component';
|
|
22
17
|
import stopVisitActionButtonComponent from './actions-buttons/stop-visit.component';
|
|
23
|
-
import visitAttributeTagsComponent from './patient-banner-tags/visit-attribute-tags.
|
|
18
|
+
import visitAttributeTagsComponent from './patient-banner-tags/visit-attribute-tags.extension';
|
|
24
19
|
|
|
25
20
|
// This allows @openmrs/esm-framework to be accessed by modules that are not
|
|
26
21
|
// using webpack. This is used for ngx-formentry.
|
|
@@ -50,37 +45,37 @@ export const patientSummaryDashboardLink =
|
|
|
50
45
|
);
|
|
51
46
|
|
|
52
47
|
export const markPatientAliveActionButton = getSyncLifecycle(markPatientAliveActionButtonComponent, {
|
|
53
|
-
featureName: 'patient-
|
|
48
|
+
featureName: 'patient-action-mark-alive',
|
|
54
49
|
moduleName,
|
|
55
50
|
});
|
|
56
51
|
|
|
57
52
|
export const markPatientDeceasedActionButton = getSyncLifecycle(markPatientDeceasedActionButtonComponent, {
|
|
58
|
-
featureName: 'patient-
|
|
53
|
+
featureName: 'patient-action-mark-deceased',
|
|
59
54
|
moduleName,
|
|
60
55
|
});
|
|
61
56
|
|
|
62
57
|
export const startVisitActionButton = getSyncLifecycle(startVisitActionButtonComponent, {
|
|
63
|
-
featureName: 'patient-
|
|
58
|
+
featureName: 'patient-action-start-visit',
|
|
64
59
|
moduleName,
|
|
65
60
|
});
|
|
66
61
|
|
|
67
62
|
export const stopVisitActionButton = getSyncLifecycle(stopVisitActionButtonComponent, {
|
|
68
|
-
featureName: 'patient-
|
|
63
|
+
featureName: 'patient-action-stop-visit',
|
|
69
64
|
moduleName,
|
|
70
65
|
});
|
|
71
66
|
|
|
72
67
|
export const deleteVisitActionMenuButton = getSyncLifecycle(deleteVisitActionButtonComponent, {
|
|
73
|
-
featureName: 'patient-
|
|
68
|
+
featureName: 'patient-action-delete-visit',
|
|
74
69
|
moduleName,
|
|
75
70
|
});
|
|
76
71
|
|
|
77
72
|
export const startVisitPatientSearchActionButton = getSyncLifecycle(startVisitActionButtonOnPatientSearch, {
|
|
78
|
-
featureName: '
|
|
73
|
+
featureName: 'patient-search-action-start-visit',
|
|
79
74
|
moduleName,
|
|
80
75
|
});
|
|
81
76
|
|
|
82
77
|
export const stopVisitPatientSearchActionButton = getSyncLifecycle(stopVisitActionButtonComponent, {
|
|
83
|
-
featureName: 'patient-
|
|
78
|
+
featureName: 'patient-search-action-stop-visit',
|
|
84
79
|
moduleName,
|
|
85
80
|
});
|
|
86
81
|
|
|
@@ -104,7 +99,7 @@ export const currentVisitSummary = getSyncLifecycle(currentVisitSummaryComponent
|
|
|
104
99
|
});
|
|
105
100
|
|
|
106
101
|
export const pastVisitsDetailOverview = getSyncLifecycle(pastVisitsOverviewComponent, {
|
|
107
|
-
featureName: 'visits-detail-
|
|
102
|
+
featureName: 'visits-detail-overview',
|
|
108
103
|
moduleName,
|
|
109
104
|
});
|
|
110
105
|
|
|
@@ -118,12 +113,16 @@ export const visitAttributeTags = getSyncLifecycle(visitAttributeTagsComponent,
|
|
|
118
113
|
moduleName,
|
|
119
114
|
});
|
|
120
115
|
|
|
121
|
-
// t('startVisitWorkspaceTitle', 'Start a visit')
|
|
122
116
|
export const startVisitWorkspace = getAsyncLifecycle(() => import('./visit/visit-form/visit-form.workspace'), {
|
|
123
117
|
featureName: 'start-visit-form',
|
|
124
118
|
moduleName,
|
|
125
119
|
});
|
|
126
120
|
|
|
121
|
+
export const exportedVisitForm = getAsyncLifecycle(() => import('./visit/visit-form/exported-visit-form.workspace'), {
|
|
122
|
+
featureName: 'exported-visit-form',
|
|
123
|
+
moduleName,
|
|
124
|
+
});
|
|
125
|
+
|
|
127
126
|
// t('markPatientDeceased', 'Mark patient deceased')
|
|
128
127
|
export const markPatientDeceasedForm = getAsyncLifecycle(
|
|
129
128
|
() => import('./mark-patient-deceased/mark-patient-deceased-form.workspace'),
|
|
@@ -133,12 +132,12 @@ export const markPatientDeceasedForm = getAsyncLifecycle(
|
|
|
133
132
|
},
|
|
134
133
|
);
|
|
135
134
|
|
|
136
|
-
export const startVisitModal = getAsyncLifecycle(() => import('./visit/visit-prompt/start-visit-dialog.
|
|
135
|
+
export const startVisitModal = getAsyncLifecycle(() => import('./visit/visit-prompt/start-visit-dialog.modal'), {
|
|
137
136
|
featureName: 'start visit',
|
|
138
137
|
moduleName,
|
|
139
138
|
});
|
|
140
139
|
|
|
141
|
-
export const deleteVisitModal = getAsyncLifecycle(() => import('./visit/visit-prompt/delete-visit-dialog.
|
|
140
|
+
export const deleteVisitModal = getAsyncLifecycle(() => import('./visit/visit-prompt/delete-visit-dialog.modal'), {
|
|
142
141
|
featureName: 'delete visit',
|
|
143
142
|
moduleName,
|
|
144
143
|
});
|
|
@@ -148,7 +147,7 @@ export const modifyVisitDateModal = getAsyncLifecycle(() => import('./visit/visi
|
|
|
148
147
|
moduleName,
|
|
149
148
|
});
|
|
150
149
|
|
|
151
|
-
export const endVisitModal = getAsyncLifecycle(() => import('./visit/visit-prompt/end-visit-dialog.
|
|
150
|
+
export const endVisitModal = getAsyncLifecycle(() => import('./visit/visit-prompt/end-visit-dialog.modal'), {
|
|
152
151
|
featureName: 'end visit',
|
|
153
152
|
moduleName,
|
|
154
153
|
});
|
|
@@ -182,7 +181,7 @@ export const activeVisitActionsComponent = getAsyncLifecycle(
|
|
|
182
181
|
);
|
|
183
182
|
|
|
184
183
|
export const encounterListTableTabs = getAsyncLifecycle(
|
|
185
|
-
() => import('./clinical-views/encounter-list/encounter-list-tabs.
|
|
184
|
+
() => import('./clinical-views/encounter-list/encounter-list-tabs.extension'),
|
|
186
185
|
{ featureName: 'encounter-list-table-tabs', moduleName },
|
|
187
186
|
);
|
|
188
187
|
|
|
@@ -192,7 +191,7 @@ export const visitContextSwitcherModal = getAsyncLifecycle(
|
|
|
192
191
|
);
|
|
193
192
|
|
|
194
193
|
export const visitContextHeader = getAsyncLifecycle(
|
|
195
|
-
() => import('./visit/visits-widget/visit-context/visit-context-header.
|
|
194
|
+
() => import('./visit/visits-widget/visit-context/visit-context-header.extension'),
|
|
196
195
|
{ featureName: 'visit-context-header', moduleName },
|
|
197
196
|
);
|
|
198
197
|
|
|
@@ -6,10 +6,14 @@ import { esmPatientChartSchema, type ChartConfig } from '../config-schema';
|
|
|
6
6
|
import { mockPatient } from 'tools';
|
|
7
7
|
import { markPatientDeceased, useCausesOfDeath } from '../data.resource';
|
|
8
8
|
import MarkPatientDeceasedForm from './mark-patient-deceased-form.workspace';
|
|
9
|
+
import { type PatientWorkspace2DefinitionProps } from '@openmrs/esm-patient-common-lib/src';
|
|
9
10
|
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
window
|
|
11
|
+
const mockReload = jest.fn();
|
|
12
|
+
|
|
13
|
+
Object.defineProperty(window, 'location', {
|
|
14
|
+
value: { ...window.location, reload: mockReload },
|
|
15
|
+
writable: true,
|
|
16
|
+
});
|
|
13
17
|
|
|
14
18
|
const mockMarkPatientDeceased = jest.mocked(markPatientDeceased);
|
|
15
19
|
const mockUseCausesOfDeath = jest.mocked(useCausesOfDeath);
|
|
@@ -17,7 +21,7 @@ const mockUseConfig = jest.mocked(useConfig<ChartConfig>);
|
|
|
17
21
|
const mockShowSnackbar = jest.mocked(showSnackbar);
|
|
18
22
|
const mockCloseWorkspace = jest.fn();
|
|
19
23
|
|
|
20
|
-
jest.mock('../data.resource
|
|
24
|
+
jest.mock('../data.resource', () => ({
|
|
21
25
|
markPatientDeceased: jest.fn().mockResolvedValue({}),
|
|
22
26
|
useCausesOfDeath: jest.fn(),
|
|
23
27
|
}));
|
|
@@ -25,13 +29,20 @@ jest.mock('../data.resource.ts', () => ({
|
|
|
25
29
|
describe('MarkPatientDeceasedForm', () => {
|
|
26
30
|
const freeTextFieldConceptUuid = '1234e218-6c8a-4ca3-8edb-9f6d9c8c8c7f';
|
|
27
31
|
|
|
28
|
-
const defaultProps = {
|
|
29
|
-
patientUuid: mockPatient.id,
|
|
30
|
-
patient: mockPatient,
|
|
32
|
+
const defaultProps: PatientWorkspace2DefinitionProps<{}, {}> = {
|
|
31
33
|
closeWorkspace: mockCloseWorkspace,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
workspaceName: null,
|
|
35
|
+
launchChildWorkspace: jest.fn(),
|
|
36
|
+
windowProps: {},
|
|
37
|
+
workspaceProps: {},
|
|
38
|
+
groupProps: {
|
|
39
|
+
patientUuid: mockPatient.id,
|
|
40
|
+
patient: mockPatient,
|
|
41
|
+
visitContext: null,
|
|
42
|
+
mutateVisitContext: null,
|
|
43
|
+
},
|
|
44
|
+
windowName: '',
|
|
45
|
+
isRootWorkspace: false,
|
|
35
46
|
};
|
|
36
47
|
|
|
37
48
|
const codedCausesOfDeath = [
|
|
@@ -71,7 +82,7 @@ describe('MarkPatientDeceasedForm', () => {
|
|
|
71
82
|
});
|
|
72
83
|
|
|
73
84
|
afterAll(() => {
|
|
74
|
-
|
|
85
|
+
jest.restoreAllMocks();
|
|
75
86
|
});
|
|
76
87
|
|
|
77
88
|
it('renders the cause of death form', () => {
|