@kenyaemr/esm-patient-clinical-view-app 5.4.2-pre.2283 → 5.4.2-pre.2288
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/255.js +2 -0
- package/dist/255.js.map +1 -0
- package/dist/292.js +1 -0
- package/dist/292.js.map +1 -0
- package/dist/300.js +1 -1
- package/dist/kenyaemr-esm-patient-clinical-view-app.js +1 -1
- package/dist/kenyaemr-esm-patient-clinical-view-app.js.buildmanifest.json +59 -60
- package/dist/kenyaemr-esm-patient-clinical-view-app.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/routes.json +1 -1
- package/package.json +1 -1
- package/src/index.ts +0 -8
- package/translations/en.json +0 -12
- package/dist/317.js +0 -1
- package/dist/317.js.map +0 -1
- package/dist/359.js +0 -2
- package/dist/359.js.map +0 -1
- package/src/deceased-panel/dashboard-link/dashboard-link.component.tsx +0 -29
- package/src/deceased-panel/hook/useEncounter.ts +0 -29
- package/src/deceased-panel/hook/useMorgueVisit.ts +0 -41
- package/src/deceased-panel/hook/usePerson.ts +0 -13
- package/src/deceased-panel/mortuary-summary/mortuary-summary.component.tsx +0 -62
- package/src/deceased-panel/mortuary-summary/mortuary-summary.scss +0 -82
- package/src/deceased-panel/panels/attachement.component.tsx +0 -21
- package/src/deceased-panel/panels/autopsy.component.tsx +0 -215
- package/src/deceased-panel/panels/billing-history.component.tsx +0 -13
- package/src/deceased-panel/panels/observations/observation.component.tsx +0 -57
- package/src/deceased-panel/panels/observations/observation.scss +0 -24
- package/src/deceased-panel/panels/panels.scss +0 -46
- package/src/deceased-panel/tabs/tabs.component.tsx +0 -35
- package/src/deceased-panel/tabs/tabs.scss +0 -45
- /package/dist/{359.js.LICENSE.txt → 255.js.LICENSE.txt} +0 -0
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { ConfigurableLink } from '@openmrs/esm-framework';
|
|
3
|
-
import { getPatientUuidFromStore } from '@openmrs/esm-patient-common-lib';
|
|
4
|
-
import classNames from 'classnames';
|
|
5
|
-
import { useTranslation } from 'react-i18next';
|
|
6
|
-
import { usePerson } from '../../../../esm-morgue-app/src/hook/useMorgue.resource';
|
|
7
|
-
|
|
8
|
-
const DeceasedPanelDashboardLink = () => {
|
|
9
|
-
const { t } = useTranslation();
|
|
10
|
-
const patientUuid = getPatientUuidFromStore();
|
|
11
|
-
const { person, isLoading } = usePerson(patientUuid);
|
|
12
|
-
const url = `\${openmrsSpaBase}/patient/${patientUuid}/chart/deceased-panel`;
|
|
13
|
-
|
|
14
|
-
if (isLoading) {
|
|
15
|
-
return null;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
if (person?.dead) {
|
|
19
|
-
return (
|
|
20
|
-
<ConfigurableLink className={classNames('cds--side-nav__link', 'active-left-nav-link')} to={url}>
|
|
21
|
-
{t('mortuaryDetails', 'Mortuary details')}
|
|
22
|
-
</ConfigurableLink>
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return null;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export default DeceasedPanelDashboardLink;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import useSWR from 'swr';
|
|
2
|
-
import { openmrsFetch, useConfig } from '@openmrs/esm-framework';
|
|
3
|
-
import groupBy from 'lodash-es/groupBy';
|
|
4
|
-
import { OpenmrsEncounter } from '../../types';
|
|
5
|
-
import { ConfigObject } from '../../config-schema';
|
|
6
|
-
|
|
7
|
-
export function useAutospyEncounter(patientUuid: string, encounterType: string) {
|
|
8
|
-
const encounterRepresentation =
|
|
9
|
-
'custom:(uuid,encounterDatetime,encounterType,location:(uuid,name),' +
|
|
10
|
-
'patient:(uuid,display),encounterProviders:(uuid,provider:(uuid,name)),' +
|
|
11
|
-
'obs:(uuid,obsDatetime,voided,groupMembers,concept:(uuid,name:(uuid,name)),value:(uuid,name:(uuid,name),' +
|
|
12
|
-
'names:(uuid,conceptNameType,name))),form:(uuid,name),' +
|
|
13
|
-
'visit:(visitType:(uuid,display)))';
|
|
14
|
-
|
|
15
|
-
const url = `/ws/rest/v1/encounter?encounterType=${encounterType}&patient=${patientUuid}&v=${encounterRepresentation}`;
|
|
16
|
-
|
|
17
|
-
const { data, error, isLoading, isValidating, mutate } = useSWR<{ data: { results: OpenmrsEncounter[] } }, Error>(
|
|
18
|
-
url,
|
|
19
|
-
openmrsFetch,
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
return {
|
|
23
|
-
encounters: data?.data ? data?.data?.results : [],
|
|
24
|
-
isLoading,
|
|
25
|
-
isValidating,
|
|
26
|
-
error,
|
|
27
|
-
mutate,
|
|
28
|
-
};
|
|
29
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { FetchResponse, openmrsFetch, restBaseUrl, useConfig } from '@openmrs/esm-framework';
|
|
2
|
-
import useSWR from 'swr';
|
|
3
|
-
import { ConfigObject } from '../../config-schema';
|
|
4
|
-
import { Visit } from '../../types';
|
|
5
|
-
|
|
6
|
-
export const useActiveMorgueVisit = (uuid: string) => {
|
|
7
|
-
const { morgueVisitTypeUuid } = useConfig<ConfigObject>();
|
|
8
|
-
const url = `${restBaseUrl}/visit?v=full&includeInactive=false&totalCount=true&visitType=${morgueVisitTypeUuid}&q=${uuid}`;
|
|
9
|
-
|
|
10
|
-
const { data, error, isLoading } = useSWR<FetchResponse<{ results: Visit[] }>>(url, openmrsFetch);
|
|
11
|
-
|
|
12
|
-
return { activeVisit: data?.data?.results[0], error, isLoading };
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export const usePatientDischargedStatus = (uuid: string) => {
|
|
16
|
-
const customRepresentation = 'custom:(visitType:(uuid),startDatetime,stopDatetime,encounters:(encounterType:(uuid)))';
|
|
17
|
-
const url = `${restBaseUrl}/visit?v=${customRepresentation}&patient=${uuid}&limit=1`;
|
|
18
|
-
|
|
19
|
-
const { data, error, isLoading } = useSWR<
|
|
20
|
-
FetchResponse<{
|
|
21
|
-
results: Array<{
|
|
22
|
-
visitType: { uuid: string };
|
|
23
|
-
startDatetime: string;
|
|
24
|
-
stopDatetime: string;
|
|
25
|
-
encounters: Array<{
|
|
26
|
-
encounterType: {
|
|
27
|
-
uuid: string;
|
|
28
|
-
};
|
|
29
|
-
}>;
|
|
30
|
-
}>;
|
|
31
|
-
}>
|
|
32
|
-
>(url, openmrsFetch);
|
|
33
|
-
|
|
34
|
-
const status = data?.data?.results[0];
|
|
35
|
-
|
|
36
|
-
return {
|
|
37
|
-
status,
|
|
38
|
-
error,
|
|
39
|
-
isLoading,
|
|
40
|
-
};
|
|
41
|
-
};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { FetchResponse, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
|
|
2
|
-
import useSWR from 'swr';
|
|
3
|
-
import { Patient } from '../../types';
|
|
4
|
-
|
|
5
|
-
const usePerson = (uuid: string) => {
|
|
6
|
-
const customRepresentation = `custom:(uuid,display,gender,birthdate,dead,age,deathDate,causeOfDeath:(uuid,display))`;
|
|
7
|
-
const url = `${restBaseUrl}/person/${uuid}?v=${customRepresentation}`;
|
|
8
|
-
const { isLoading, error, data } = useSWR<FetchResponse<Patient['person']>>(url, openmrsFetch);
|
|
9
|
-
const person = data?.data;
|
|
10
|
-
return { isLoading, error, person };
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export default usePerson;
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import classNames from 'classnames';
|
|
3
|
-
import { useTranslation } from 'react-i18next';
|
|
4
|
-
import { Tab, TabList, TabPanel, TabPanels, Tabs, InlineLoading } from '@carbon/react';
|
|
5
|
-
import { ExtensionSlot, useConfig, useLayoutType } from '@openmrs/esm-framework';
|
|
6
|
-
|
|
7
|
-
import styles from './mortuary-summary.scss';
|
|
8
|
-
import BillingHistoryView from '../panels/billing-history.component';
|
|
9
|
-
import AutopsyView from '../panels/autopsy.component';
|
|
10
|
-
import AttachmentView from '../panels/attachement.component';
|
|
11
|
-
import { getPatientUuidFromStore } from '@openmrs/esm-patient-common-lib';
|
|
12
|
-
import usePerson from '../hook/usePerson';
|
|
13
|
-
import { useActiveMorgueVisit } from '../hook/useMorgueVisit';
|
|
14
|
-
|
|
15
|
-
const MortuarySummary: React.FC = () => {
|
|
16
|
-
const config = useConfig();
|
|
17
|
-
const { t } = useTranslation();
|
|
18
|
-
const layout = useLayoutType();
|
|
19
|
-
const patientUuid = getPatientUuidFromStore();
|
|
20
|
-
const { person, isLoading } = usePerson(patientUuid);
|
|
21
|
-
const { activeVisit, isLoading: isActiveLoading } = useActiveMorgueVisit(patientUuid);
|
|
22
|
-
|
|
23
|
-
if (isLoading || isActiveLoading) {
|
|
24
|
-
return (
|
|
25
|
-
<InlineLoading status="active" iconDescription="Loading" description={t('loadData', 'Loading summary data...')} />
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return (
|
|
30
|
-
<div className={styles.summaryContainer}>
|
|
31
|
-
<p className={styles.morgueLabel}>{''}</p>
|
|
32
|
-
<ExtensionSlot name="deceased-banner-info-slot" state={{ patientUuid }} />
|
|
33
|
-
<Tabs>
|
|
34
|
-
<TabList aria-label="morgue summary tabs" className={styles.tablist}>
|
|
35
|
-
<Tab className={styles.tab} id="billing-tab">
|
|
36
|
-
{t('billingHistory', 'Billing history')}
|
|
37
|
-
</Tab>
|
|
38
|
-
<Tab className={classNames(styles.tab, styles.bodyLong01)} id="autopsy-tab">
|
|
39
|
-
{t('autopsyReport', 'Autopsy report')}
|
|
40
|
-
</Tab>
|
|
41
|
-
|
|
42
|
-
<Tab className={styles.tab} id="medications-tab">
|
|
43
|
-
{t('attachements', 'Attachements')}
|
|
44
|
-
</Tab>
|
|
45
|
-
</TabList>
|
|
46
|
-
<TabPanels>
|
|
47
|
-
<TabPanel>
|
|
48
|
-
<BillingHistoryView />
|
|
49
|
-
</TabPanel>
|
|
50
|
-
<TabPanel>
|
|
51
|
-
<AutopsyView />
|
|
52
|
-
</TabPanel>
|
|
53
|
-
<TabPanel>
|
|
54
|
-
<AttachmentView />
|
|
55
|
-
</TabPanel>
|
|
56
|
-
</TabPanels>
|
|
57
|
-
</Tabs>
|
|
58
|
-
</div>
|
|
59
|
-
);
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
export default MortuarySummary;
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
@use '@carbon/colors';
|
|
2
|
-
@use '@carbon/layout';
|
|
3
|
-
@use '@carbon/type';
|
|
4
|
-
@use '@openmrs/esm-styleguide/src/vars' as *;
|
|
5
|
-
|
|
6
|
-
.morgueLabel {
|
|
7
|
-
margin-top: layout.$spacing-03;
|
|
8
|
-
margin-left: layout.$spacing-06;
|
|
9
|
-
font-size: type.type-scale(2);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
.summaryContainer {
|
|
13
|
-
background-color: colors.$white;
|
|
14
|
-
display: grid;
|
|
15
|
-
grid-template-columns: max-content auto;
|
|
16
|
-
|
|
17
|
-
:global(.cds--tabs) {
|
|
18
|
-
min-height: 8rem;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
.verticalTabs {
|
|
23
|
-
margin: layout.$spacing-05 0;
|
|
24
|
-
scroll-behavior: smooth;
|
|
25
|
-
|
|
26
|
-
> ul {
|
|
27
|
-
flex-direction: column;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
:global(.cds--tabs--scrollable .cds--tabs--scrollable__nav-item + .cds--tabs--scrollable__nav-item) {
|
|
31
|
-
margin-left: 0;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
:global(.cds--tabs--scrollable .cds--tabs--scrollable__nav-link) {
|
|
35
|
-
border-bottom: 0 !important;
|
|
36
|
-
border-left: layout.$spacing-01 solid $color-gray-30;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.tab {
|
|
41
|
-
outline: 0;
|
|
42
|
-
outline-offset: 0;
|
|
43
|
-
min-height: 2rem !important;
|
|
44
|
-
|
|
45
|
-
&:active,
|
|
46
|
-
&:focus {
|
|
47
|
-
outline: layout.$spacing-01 solid var(--brand-03) !important;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
&[aria-selected='true'] {
|
|
51
|
-
border-left: 3px solid var(--brand-03);
|
|
52
|
-
border-bottom: none;
|
|
53
|
-
font-weight: 600;
|
|
54
|
-
margin-left: 0 !important;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
&[aria-selected='false'] {
|
|
58
|
-
border-bottom: none;
|
|
59
|
-
border-left: layout.$spacing-01 solid $ui-03;
|
|
60
|
-
margin-left: 0 !important;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
.tablist {
|
|
65
|
-
:global(.cds--tab--list) {
|
|
66
|
-
flex-direction: column;
|
|
67
|
-
max-height: fit-content;
|
|
68
|
-
overflow-x: visible;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
> button :global(.cds--tabs .cds--tabs__nav-link) {
|
|
72
|
-
border-bottom: none;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
.text02 {
|
|
77
|
-
color: colors.$gray-70;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
.bodyLong01 {
|
|
81
|
-
@include type.type-style('body-01');
|
|
82
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { ExtensionSlot, navigate, usePatient } from '@openmrs/esm-framework';
|
|
3
|
-
import { useTranslation } from 'react-i18next';
|
|
4
|
-
import { EmptyState, getPatientUuidFromStore } from '@openmrs/esm-patient-common-lib';
|
|
5
|
-
import styles from './panels.scss';
|
|
6
|
-
|
|
7
|
-
const AttachmentView: React.FC = () => {
|
|
8
|
-
const { t } = useTranslation();
|
|
9
|
-
const patientUuid = getPatientUuidFromStore();
|
|
10
|
-
|
|
11
|
-
return (
|
|
12
|
-
<ExtensionSlot
|
|
13
|
-
name="patient-chart-attachments-dashboard-slot"
|
|
14
|
-
state={{
|
|
15
|
-
patientUuid,
|
|
16
|
-
}}
|
|
17
|
-
/>
|
|
18
|
-
);
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export default AttachmentView;
|
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { useTranslation } from 'react-i18next';
|
|
3
|
-
import {
|
|
4
|
-
formatDate,
|
|
5
|
-
isDesktop,
|
|
6
|
-
launchWorkspace,
|
|
7
|
-
parseDate,
|
|
8
|
-
useConfig,
|
|
9
|
-
useLayoutType,
|
|
10
|
-
usePagination,
|
|
11
|
-
} from '@openmrs/esm-framework';
|
|
12
|
-
import {
|
|
13
|
-
CardHeader,
|
|
14
|
-
EmptyState,
|
|
15
|
-
ErrorState,
|
|
16
|
-
getPatientUuidFromStore,
|
|
17
|
-
usePaginationInfo,
|
|
18
|
-
} from '@openmrs/esm-patient-common-lib';
|
|
19
|
-
import {
|
|
20
|
-
Button,
|
|
21
|
-
DataTable,
|
|
22
|
-
TableContainer,
|
|
23
|
-
Table,
|
|
24
|
-
TableHead,
|
|
25
|
-
TableRow,
|
|
26
|
-
TableHeader,
|
|
27
|
-
TableBody,
|
|
28
|
-
TableCell,
|
|
29
|
-
OverflowMenu,
|
|
30
|
-
OverflowMenuItem,
|
|
31
|
-
TableExpandHeader,
|
|
32
|
-
DataTableSkeleton,
|
|
33
|
-
TableExpandRow,
|
|
34
|
-
TableExpandedRow,
|
|
35
|
-
Pagination,
|
|
36
|
-
} from '@carbon/react';
|
|
37
|
-
import { Add } from '@carbon/react/icons';
|
|
38
|
-
import styles from './panels.scss';
|
|
39
|
-
import { ConfigObject } from '../../config-schema';
|
|
40
|
-
import { useAutospyEncounter } from '../hook/useEncounter';
|
|
41
|
-
import EncounterObservations from './observations/observation.component';
|
|
42
|
-
import { Observation } from '../../types';
|
|
43
|
-
|
|
44
|
-
const AutopsyView: React.FC = () => {
|
|
45
|
-
const { t } = useTranslation();
|
|
46
|
-
const patientUuid = getPatientUuidFromStore();
|
|
47
|
-
const { formsList, autopsyEncounterFormUuid } = useConfig<ConfigObject>();
|
|
48
|
-
const { encounters, isLoading, error, mutate, isValidating } = useAutospyEncounter(
|
|
49
|
-
patientUuid,
|
|
50
|
-
autopsyEncounterFormUuid,
|
|
51
|
-
);
|
|
52
|
-
const headerTitle = t('autopsyReport', 'Autopsy report');
|
|
53
|
-
const layout = useLayoutType();
|
|
54
|
-
const [pageSize, setPageSize] = React.useState(10);
|
|
55
|
-
const responsiveSize = isDesktop(layout) ? 'sm' : 'lg';
|
|
56
|
-
const { paginated, goTo, results, currentPage } = usePagination(encounters, pageSize);
|
|
57
|
-
const { pageSizes } = usePaginationInfo(pageSize, encounters?.length, currentPage, results?.length);
|
|
58
|
-
|
|
59
|
-
const handleLaunchAutopsyForm = (encounterUUID = '') => {
|
|
60
|
-
launchWorkspace('patient-form-entry-workspace', {
|
|
61
|
-
workspaceTitle: t('autopsyReport', 'Autopsy report'),
|
|
62
|
-
mutateForm: () => mutate(),
|
|
63
|
-
formInfo: {
|
|
64
|
-
encounterUuid: encounterUUID,
|
|
65
|
-
formUuid: formsList?.autopsyFormUuid,
|
|
66
|
-
patientUuid,
|
|
67
|
-
visitTypeUuid: '',
|
|
68
|
-
visitUuid: '',
|
|
69
|
-
},
|
|
70
|
-
});
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
const tableHeader = [
|
|
74
|
-
{
|
|
75
|
-
key: 'date',
|
|
76
|
-
header: t('dateTime', 'Date & time'),
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
key: 'visitType',
|
|
80
|
-
header: t('visitType', 'Visit type'),
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
key: 'encounterType',
|
|
84
|
-
header: t('encounterType', 'Encounter type'),
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
key: 'formName',
|
|
88
|
-
header: t('formName', 'Form name'),
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
key: 'mortician',
|
|
92
|
-
header: t('mortician', 'Mortician name'),
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
key: 'action',
|
|
96
|
-
header: t('action', 'Action'),
|
|
97
|
-
},
|
|
98
|
-
];
|
|
99
|
-
|
|
100
|
-
if (isLoading) {
|
|
101
|
-
return <DataTableSkeleton headers={tableHeader} aria-label={headerTitle} />;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if (error) {
|
|
105
|
-
return <ErrorState error={error} headerTitle={headerTitle} />;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (!encounters || encounters.length === 0) {
|
|
109
|
-
return <EmptyState displayText={headerTitle} headerTitle={headerTitle} launchForm={handleLaunchAutopsyForm} />;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const tableRows = encounters.map((encounter) => ({
|
|
113
|
-
id: `${encounter.uuid}`,
|
|
114
|
-
date: formatDate(parseDate(encounter?.encounterDatetime)),
|
|
115
|
-
visitType: encounter?.visit?.visitType?.display,
|
|
116
|
-
encounterType: encounter?.encounterType?.display,
|
|
117
|
-
formName: encounter?.form?.name,
|
|
118
|
-
mortician: encounter?.encounterProviders[0]?.provider?.name,
|
|
119
|
-
action: (
|
|
120
|
-
<OverflowMenu aria-label="overflow-menu" flipped={false}>
|
|
121
|
-
<OverflowMenuItem onClick={() => handleLaunchAutopsyForm(encounter.uuid)} itemText={t('edit', 'Edit')} />
|
|
122
|
-
</OverflowMenu>
|
|
123
|
-
),
|
|
124
|
-
obs: encounter?.obs,
|
|
125
|
-
}));
|
|
126
|
-
|
|
127
|
-
return (
|
|
128
|
-
<div className={styles.widgetCard}>
|
|
129
|
-
<CardHeader title={headerTitle}>
|
|
130
|
-
<Button
|
|
131
|
-
size="md"
|
|
132
|
-
kind="ghost"
|
|
133
|
-
onClick={() => handleLaunchAutopsyForm()}
|
|
134
|
-
renderIcon={(props) => <Add size={24} {...props} />}
|
|
135
|
-
iconDescription={t('add', 'Add')}>
|
|
136
|
-
{t('add', 'Add')}
|
|
137
|
-
</Button>
|
|
138
|
-
</CardHeader>
|
|
139
|
-
<DataTable isSortable rows={tableRows} headers={tableHeader} size={responsiveSize} useZebraStyles>
|
|
140
|
-
{({
|
|
141
|
-
rows,
|
|
142
|
-
headers,
|
|
143
|
-
getExpandHeaderProps,
|
|
144
|
-
getTableProps,
|
|
145
|
-
getTableContainerProps,
|
|
146
|
-
getHeaderProps,
|
|
147
|
-
getRowProps,
|
|
148
|
-
}) => (
|
|
149
|
-
<TableContainer {...getTableContainerProps}>
|
|
150
|
-
<Table className={styles.table} {...getTableProps()} aria-label="Bill list">
|
|
151
|
-
<TableHead>
|
|
152
|
-
<TableRow>
|
|
153
|
-
<TableExpandHeader enableToggle {...getExpandHeaderProps()} />
|
|
154
|
-
{headers.map((header, i) => (
|
|
155
|
-
<TableHeader
|
|
156
|
-
key={i}
|
|
157
|
-
{...getHeaderProps({
|
|
158
|
-
header,
|
|
159
|
-
})}>
|
|
160
|
-
{header.header}
|
|
161
|
-
</TableHeader>
|
|
162
|
-
))}
|
|
163
|
-
</TableRow>
|
|
164
|
-
</TableHead>
|
|
165
|
-
<TableBody>
|
|
166
|
-
{rows.map((row, i) => {
|
|
167
|
-
const encounter = encounters.find((enc) => enc.uuid === row.id);
|
|
168
|
-
|
|
169
|
-
return (
|
|
170
|
-
<React.Fragment key={row.id}>
|
|
171
|
-
<TableExpandRow {...getRowProps({ row })}>
|
|
172
|
-
{row.cells.map((cell, index) => (
|
|
173
|
-
<TableCell key={cell.id}>{cell.value}</TableCell>
|
|
174
|
-
))}
|
|
175
|
-
</TableExpandRow>
|
|
176
|
-
{row.isExpanded && encounter ? (
|
|
177
|
-
<TableExpandedRow className={styles.expandedRow} colSpan={headers.length + 1}>
|
|
178
|
-
<div className={styles.container} key={i}>
|
|
179
|
-
<EncounterObservations observations={encounter.obs as Observation[]} />
|
|
180
|
-
</div>
|
|
181
|
-
</TableExpandedRow>
|
|
182
|
-
) : (
|
|
183
|
-
<TableExpandedRow className={styles.hiddenRow} colSpan={headers.length + 2} />
|
|
184
|
-
)}
|
|
185
|
-
</React.Fragment>
|
|
186
|
-
);
|
|
187
|
-
})}
|
|
188
|
-
</TableBody>
|
|
189
|
-
</Table>
|
|
190
|
-
</TableContainer>
|
|
191
|
-
)}
|
|
192
|
-
</DataTable>
|
|
193
|
-
{paginated && (
|
|
194
|
-
<Pagination
|
|
195
|
-
forwardText={t('nextPage', 'Next page')}
|
|
196
|
-
backwardText={t('previousPage', 'Previous page')}
|
|
197
|
-
page={currentPage}
|
|
198
|
-
pageSize={pageSize}
|
|
199
|
-
pageSizes={pageSizes}
|
|
200
|
-
totalItems={encounters.length}
|
|
201
|
-
className={styles.pagination}
|
|
202
|
-
size={responsiveSize}
|
|
203
|
-
onChange={({ page: newPage, pageSize }) => {
|
|
204
|
-
if (newPage !== currentPage) {
|
|
205
|
-
goTo(newPage);
|
|
206
|
-
}
|
|
207
|
-
setPageSize(pageSize);
|
|
208
|
-
}}
|
|
209
|
-
/>
|
|
210
|
-
)}
|
|
211
|
-
</div>
|
|
212
|
-
);
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
export default AutopsyView;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { ExtensionSlot, navigate, usePatient } from '@openmrs/esm-framework';
|
|
3
|
-
import { useTranslation } from 'react-i18next';
|
|
4
|
-
import { EmptyState, getPatientUuidFromStore } from '@openmrs/esm-patient-common-lib';
|
|
5
|
-
import styles from './panels.scss';
|
|
6
|
-
|
|
7
|
-
const BillingHistoryView: React.FC = () => {
|
|
8
|
-
const { t } = useTranslation();
|
|
9
|
-
const patientUuid = getPatientUuidFromStore();
|
|
10
|
-
return <ExtensionSlot name="patient-chart-billing-dashboard-slot" state={{ patientUuid }} />;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export default BillingHistoryView;
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { useTranslation } from 'react-i18next';
|
|
3
|
-
import { SkeletonText } from '@carbon/react';
|
|
4
|
-
import { useConfig } from '@openmrs/esm-framework';
|
|
5
|
-
import styles from './observation.scss';
|
|
6
|
-
import { Observation } from '../../../types';
|
|
7
|
-
|
|
8
|
-
interface EncounterObservationsProps {
|
|
9
|
-
observations: Array<Observation>;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const EncounterObservations: React.FC<EncounterObservationsProps> = ({ observations }) => {
|
|
13
|
-
const { t } = useTranslation();
|
|
14
|
-
const { obsConceptUuidsToHide = [] } = useConfig();
|
|
15
|
-
|
|
16
|
-
const filterObservations = (obsList: Array<Observation>) =>
|
|
17
|
-
obsConceptUuidsToHide.length ? obsList.filter((obs) => !obsConceptUuidsToHide.includes(obs.concept.uuid)) : obsList;
|
|
18
|
-
|
|
19
|
-
const renderAnswer = (value: any) => (typeof value === 'object' ? value?.name?.name || '' : value);
|
|
20
|
-
|
|
21
|
-
if (!observations) {
|
|
22
|
-
return <SkeletonText />;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const filteredObservations = filterObservations(observations);
|
|
26
|
-
|
|
27
|
-
return (
|
|
28
|
-
<div className={styles.observation}>
|
|
29
|
-
{filteredObservations.length > 0 ? (
|
|
30
|
-
filteredObservations.map((obs) =>
|
|
31
|
-
obs.groupMembers ? (
|
|
32
|
-
<React.Fragment key={obs.uuid}>
|
|
33
|
-
<span className={styles.parentConcept}>{obs.concept?.name?.name}</span>
|
|
34
|
-
{obs.groupMembers.map((member) => (
|
|
35
|
-
<React.Fragment key={member.uuid}>
|
|
36
|
-
<span className={styles.childConcept}>{member.concept?.display}</span>
|
|
37
|
-
<span>{renderAnswer(member.value)}</span>
|
|
38
|
-
</React.Fragment>
|
|
39
|
-
))}
|
|
40
|
-
</React.Fragment>
|
|
41
|
-
) : (
|
|
42
|
-
<React.Fragment key={obs.uuid}>
|
|
43
|
-
<span>{obs.concept?.name?.name}</span>
|
|
44
|
-
<span>{renderAnswer(obs.value)}</span>
|
|
45
|
-
</React.Fragment>
|
|
46
|
-
),
|
|
47
|
-
)
|
|
48
|
-
) : (
|
|
49
|
-
<div className={styles.observation}>
|
|
50
|
-
<p>{t('noObservationsFound', 'No observations found')}</p>
|
|
51
|
-
</div>
|
|
52
|
-
)}
|
|
53
|
-
</div>
|
|
54
|
-
);
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
export default EncounterObservations;
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
@use '@carbon/layout';
|
|
2
|
-
|
|
3
|
-
.observation {
|
|
4
|
-
display: grid;
|
|
5
|
-
grid-template-columns: 1fr 1fr;
|
|
6
|
-
grid-gap: layout.$spacing-03;
|
|
7
|
-
margin: layout.$spacing-05 layout.$spacing-05 layout.$spacing-05 0;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
.observation > span {
|
|
11
|
-
align-self: center;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
.parentConcept {
|
|
15
|
-
font-weight: bold;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
.childConcept {
|
|
19
|
-
padding-left: 0.8rem;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
.questionText {
|
|
23
|
-
font-weight: bold;
|
|
24
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
@use '@carbon/layout';
|
|
2
|
-
@use '@carbon/colors';
|
|
3
|
-
|
|
4
|
-
.observation {
|
|
5
|
-
display: grid;
|
|
6
|
-
grid-template-columns: 1fr 1fr;
|
|
7
|
-
grid-gap: layout.$spacing-03;
|
|
8
|
-
margin-block: layout.$spacing-05;
|
|
9
|
-
margin-inline: 0 layout.$spacing-05;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
.observation > span {
|
|
13
|
-
align-self: center;
|
|
14
|
-
justify-self: start;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
.parentConcept {
|
|
18
|
-
font-weight: bold;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
.childConcept {
|
|
22
|
-
padding-inline-start: layout.$spacing-04;
|
|
23
|
-
}
|
|
24
|
-
.medicalHistoryContainer {
|
|
25
|
-
background-color: colors.$gray-30;
|
|
26
|
-
width: 98%;
|
|
27
|
-
margin: 0 auto;
|
|
28
|
-
max-width: 95vw;
|
|
29
|
-
padding-bottom: 0;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
.filterContainer {
|
|
33
|
-
display: flex;
|
|
34
|
-
justify-content: flex-end;
|
|
35
|
-
align-items: center;
|
|
36
|
-
margin-bottom: 1rem;
|
|
37
|
-
gap: 0.5rem;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.search {
|
|
41
|
-
max-width: 300px;
|
|
42
|
-
}
|
|
43
|
-
.table {
|
|
44
|
-
border: 1px solid colors.$gray-30;
|
|
45
|
-
padding: layout.$spacing-05 layout.$spacing-05;
|
|
46
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { Layer, Tile } from '@carbon/react';
|
|
2
|
-
import { ExtensionSlot, useConfig } from '@openmrs/esm-framework';
|
|
3
|
-
import { getPatientUuidFromStore } from '@openmrs/esm-patient-common-lib';
|
|
4
|
-
import React from 'react';
|
|
5
|
-
import { useTranslation } from 'react-i18next';
|
|
6
|
-
import { ConfigObject } from '../../config-schema';
|
|
7
|
-
import { usePatientDischargedStatus } from '../hook/useMorgueVisit';
|
|
8
|
-
import MortuarySummary from '../mortuary-summary/mortuary-summary.component';
|
|
9
|
-
import styles from './tabs.scss';
|
|
10
|
-
|
|
11
|
-
const DeceasedDetailsView: React.FC = () => {
|
|
12
|
-
const { t } = useTranslation();
|
|
13
|
-
const patientUuid = getPatientUuidFromStore();
|
|
14
|
-
|
|
15
|
-
return (
|
|
16
|
-
<div className={styles.deceasedDetailsContainer}>
|
|
17
|
-
<Layer className={styles.container}>
|
|
18
|
-
<Tile>
|
|
19
|
-
<div className={styles.headingContainer}>
|
|
20
|
-
<div className={styles.desktopHeading}>
|
|
21
|
-
<h4>{t('mortuaryView', 'Mortuary view')}</h4>
|
|
22
|
-
</div>
|
|
23
|
-
<div className={styles.actionBtn}>
|
|
24
|
-
<ExtensionSlot name="mortuary-action-buttons-slot" state={{ patientUuid }} />
|
|
25
|
-
</div>
|
|
26
|
-
</div>
|
|
27
|
-
</Tile>
|
|
28
|
-
|
|
29
|
-
<MortuarySummary />
|
|
30
|
-
</Layer>
|
|
31
|
-
</div>
|
|
32
|
-
);
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
export default DeceasedDetailsView;
|