@kenyaemr/esm-bed-management-app 1.0.1-pre.4
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/.editorconfig +12 -0
- package/.eslintignore +2 -0
- package/.eslintrc +37 -0
- package/.husky/pre-commit +4 -0
- package/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/.prettierignore +14 -0
- package/.turbo.json +18 -0
- package/.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs +541 -0
- package/.yarn/plugins/@yarnpkg/plugin-version.cjs +550 -0
- package/.yarn/versions/6816f0d4.yml +0 -0
- package/LICENSE +373 -0
- package/README.md +40 -0
- package/dist/187.js +1 -0
- package/dist/187.js.map +1 -0
- package/dist/207.js +1 -0
- package/dist/207.js.map +1 -0
- package/dist/26.js +2 -0
- package/dist/26.js.LICENSE.txt +32 -0
- package/dist/26.js.map +1 -0
- package/dist/283.js +1 -0
- package/dist/283.js.map +1 -0
- package/dist/294.js +2 -0
- package/dist/294.js.LICENSE.txt +9 -0
- package/dist/294.js.map +1 -0
- package/dist/330.js +2 -0
- package/dist/330.js.LICENSE.txt +44 -0
- package/dist/330.js.map +1 -0
- package/dist/352.js +1 -0
- package/dist/352.js.map +1 -0
- package/dist/404.js +1 -0
- package/dist/404.js.map +1 -0
- package/dist/455.js +2 -0
- package/dist/455.js.LICENSE.txt +9 -0
- package/dist/455.js.map +1 -0
- package/dist/558.js +2 -0
- package/dist/558.js.LICENSE.txt +14 -0
- package/dist/558.js.map +1 -0
- package/dist/574.js +1 -0
- package/dist/629.js +1 -0
- package/dist/629.js.map +1 -0
- package/dist/707.js +1 -0
- package/dist/707.js.map +1 -0
- package/dist/800.js +2 -0
- package/dist/800.js.LICENSE.txt +3 -0
- package/dist/800.js.map +1 -0
- package/dist/884.js +1 -0
- package/dist/884.js.map +1 -0
- package/dist/933.js +1 -0
- package/dist/933.js.map +1 -0
- package/dist/959.js +1 -0
- package/dist/959.js.map +1 -0
- package/dist/esm-kenyaemr-bed-management-app.js +1 -0
- package/dist/esm-kenyaemr-bed-management-app.js.buildmanifest.json +532 -0
- package/dist/esm-kenyaemr-bed-management-app.js.map +1 -0
- package/dist/main.js +1 -0
- package/dist/main.js.map +1 -0
- package/dist/routes.json +1 -0
- package/i18next-parser.config.js +89 -0
- package/jest.config.js +0 -0
- package/package.json +112 -0
- package/src/__mocks__/react-i18next.js +55 -0
- package/src/admin-card-link.component.tsx +27 -0
- package/src/assets/landing-page.png +0 -0
- package/src/assets/logo.svg +1 -0
- package/src/bed-administration/bed-administration-form.component.tsx +326 -0
- package/src/bed-administration/bed-administration-form.scss +0 -0
- package/src/bed-administration/bed-administration-table.component.tsx +317 -0
- package/src/bed-administration/bed-administration-table.scss +112 -0
- package/src/bed-administration/bed-administration-types.ts +12 -0
- package/src/bed-administration/bed-administration.resource.ts +59 -0
- package/src/bed-administration/edit-bed-form.component.tsx +100 -0
- package/src/bed-administration/new-bed-form.component.tsx +112 -0
- package/src/bed-admission/active-patients/active-patients-table.component.tsx +299 -0
- package/src/bed-admission/active-patients/active-visits.resource.ts +171 -0
- package/src/bed-admission/active-patients/admission-action-button-styles.scss +0 -0
- package/src/bed-admission/active-patients/admission-action-button.component.tsx +26 -0
- package/src/bed-admission/active-patients/index.tsx +15 -0
- package/src/bed-admission/active-patients/patient-queues.resource.ts +136 -0
- package/src/bed-admission/active-patients/styles.scss +284 -0
- package/src/bed-admission/active-patients/view-action-menu.component.tsx +33 -0
- package/src/bed-admission/admitted-patients/active-admissions.resource.ts +121 -0
- package/src/bed-admission/admitted-patients/admitted-patients-table.component.tsx +280 -0
- package/src/bed-admission/admitted-patients/admitted-patients.component.tsx +22 -0
- package/src/bed-admission/admitted-patients/location-combo-box.component.tsx +55 -0
- package/src/bed-admission/admitted-patients/styles.scss +284 -0
- package/src/bed-admission/bed-admission-tabs-styles.scss +30 -0
- package/src/bed-admission/bed-admission-tabs.component.tsx +69 -0
- package/src/bed-admission/bed-admission.component.tsx +15 -0
- package/src/bed-admission/bed-admission.resource.ts +35 -0
- package/src/bed-admission/bed-layout/bed-layout-list.component.tsx +101 -0
- package/src/bed-admission/bed-layout/bed-layout.component.tsx +64 -0
- package/src/bed-admission/bed-layout/bed-layout.scss +118 -0
- package/src/bed-admission/bed-layout/min-bed-layout.component.tsx +26 -0
- package/src/bed-admission/createDashboardLink.tsx +47 -0
- package/src/bed-admission/discharged-patients/discharged-patients.componet.tsx +19 -0
- package/src/bed-admission/helpers/functions.ts +102 -0
- package/src/bed-admission/types.ts +133 -0
- package/src/config-schema.ts +21 -0
- package/src/declarations.d.ts +7 -0
- package/src/empty-state/empty-state.component.tsx +69 -0
- package/src/empty-state/empty-state.scss +62 -0
- package/src/header/header.component.tsx +51 -0
- package/src/header/header.scss +72 -0
- package/src/header/illustration.component.tsx +13 -0
- package/src/home.component.tsx +15 -0
- package/src/home.scss +5 -0
- package/src/index.ts +65 -0
- package/src/left-panel/left-panel.component.tsx +33 -0
- package/src/left-panel/left-panel.scss +41 -0
- package/src/left-panel-link.component.tsx +49 -0
- package/src/root.component.tsx +35 -0
- package/src/root.scss +11 -0
- package/src/routes.json +46 -0
- package/src/setup-tests.ts +1 -0
- package/src/summary/summary.component.tsx +74 -0
- package/src/summary/summary.resource.ts +123 -0
- package/src/summary/summary.scss +72 -0
- package/src/types.ts +152 -0
- package/src/ward-card/ward-card.component.tsx +41 -0
- package/src/ward-card/ward-card.scss +51 -0
- package/src/ward-with-beds/ward-with-beds.component.tsx +186 -0
- package/src/ward-with-beds/ward-with-beds.scss +27 -0
- package/src/workspace/allocate-bed-workspace.component.tsx +141 -0
- package/src/workspace/allocate-bed.scss +117 -0
- package/src/workspace/overlay.component.tsx +55 -0
- package/src/workspace/overlay.scss +96 -0
- package/translations/en.json +7 -0
- package/tsconfig.json +23 -0
- package/webpack.config.js +1 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
@use '@carbon/type';
|
|
2
|
+
@use '@carbon/colors';
|
|
3
|
+
@use '@carbon/styles/scss/spacing';
|
|
4
|
+
@import '~@openmrs/esm-styleguide/src/vars';
|
|
5
|
+
|
|
6
|
+
.bedLayout {
|
|
7
|
+
position: relative;
|
|
8
|
+
margin: 20px;
|
|
9
|
+
display: flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
justify-content: space-between;
|
|
12
|
+
padding: 0 20px;
|
|
13
|
+
border-radius: 8px;
|
|
14
|
+
border: 1px solid #42be65;
|
|
15
|
+
|
|
16
|
+
.bedPillow {
|
|
17
|
+
background-color: #fff;
|
|
18
|
+
border-radius: 3rem;
|
|
19
|
+
border: 1px solid #42be65;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.bedNumber {
|
|
23
|
+
font-weight: bold;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
&:hover {
|
|
27
|
+
cursor: pointer;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.bedLayoutSelected {
|
|
32
|
+
background-color: #42be65 !important;
|
|
33
|
+
color: #fff !important;
|
|
34
|
+
border: 5px solid #e4e1c9 !important;
|
|
35
|
+
opacity:1 !important;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
;
|
|
39
|
+
|
|
40
|
+
.bedInfoMain {
|
|
41
|
+
display: flex;
|
|
42
|
+
align-self: center;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.bedInfoContainer {
|
|
46
|
+
display: flex;
|
|
47
|
+
justify-content: flex-end;
|
|
48
|
+
padding-right: 4rem;
|
|
49
|
+
border-bottom: 1px solid #a8a8a8;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.bedInfoText {
|
|
53
|
+
align-self: center;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.disabled {
|
|
57
|
+
opacity: 0.8;
|
|
58
|
+
pointer-events: none;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.errorContainer {
|
|
62
|
+
width: 90%;
|
|
63
|
+
position: absolute;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.loadingContainer {
|
|
67
|
+
position: absolute;
|
|
68
|
+
margin: spacing.$spacing-02 spacing.$spacing-05 0;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.bed {
|
|
72
|
+
height: 60px;
|
|
73
|
+
width: 8rem;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.pillow {
|
|
77
|
+
width: 10px;
|
|
78
|
+
height: 40px;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.available {
|
|
82
|
+
background-color: #fff;
|
|
83
|
+
color: #525252;
|
|
84
|
+
opacity: 1;
|
|
85
|
+
pointer-events: auto;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.occupied {
|
|
89
|
+
background-color: #42be65;
|
|
90
|
+
color: #fff;
|
|
91
|
+
opacity: 0.5;
|
|
92
|
+
pointer-events: none;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.minOccupied {
|
|
96
|
+
height: 1.5rem;
|
|
97
|
+
width: 2.5rem;
|
|
98
|
+
color: #fff;
|
|
99
|
+
background-color: rgb(66, 190, 101);
|
|
100
|
+
padding: 0 6px;
|
|
101
|
+
border-radius: 5px;
|
|
102
|
+
pointer-events: none;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.minAvailable {
|
|
106
|
+
height: 1.5rem;
|
|
107
|
+
width: 2.5rem;
|
|
108
|
+
color: none;
|
|
109
|
+
background-color: #fff;
|
|
110
|
+
padding: 0 6px;
|
|
111
|
+
border-radius: 5px;
|
|
112
|
+
pointer-events: none;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.minPillow {
|
|
116
|
+
width: 7px;
|
|
117
|
+
height: 1rem;
|
|
118
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import styles from "./bed-layout.scss";
|
|
3
|
+
import BedLayout from "./bed-layout.component";
|
|
4
|
+
|
|
5
|
+
const MinBedLayout: React.FC = () => {
|
|
6
|
+
return (
|
|
7
|
+
<div className={styles.bedInfoContainer}>
|
|
8
|
+
<div className={styles.bedInfoMain}>
|
|
9
|
+
<BedLayout
|
|
10
|
+
bedPillowStyles={styles.minPillow}
|
|
11
|
+
layOutStyles={styles.minOccupied}
|
|
12
|
+
/>{" "}
|
|
13
|
+
<span className={styles.bedInfoText}>Occupied</span>
|
|
14
|
+
</div>
|
|
15
|
+
<div className={styles.bedInfoMain}>
|
|
16
|
+
<BedLayout
|
|
17
|
+
bedPillowStyles={styles.minPillow}
|
|
18
|
+
layOutStyles={styles.minAvailable}
|
|
19
|
+
/>{" "}
|
|
20
|
+
<span className={styles.bedInfoText}>Available</span>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default MinBedLayout;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React, { useMemo } from "react";
|
|
2
|
+
import last from "lodash-es/last";
|
|
3
|
+
import { BrowserRouter, useLocation } from "react-router-dom";
|
|
4
|
+
import { ConfigurableLink } from "@openmrs/esm-framework";
|
|
5
|
+
|
|
6
|
+
export interface LinkConfig {
|
|
7
|
+
name: string;
|
|
8
|
+
title: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function LinkExtension({ config }: { config: LinkConfig }) {
|
|
12
|
+
const { name, title } = config;
|
|
13
|
+
const location = useLocation();
|
|
14
|
+
|
|
15
|
+
let urlSegment = useMemo(
|
|
16
|
+
() => decodeURIComponent(last(location.pathname.split("/"))),
|
|
17
|
+
[location.pathname]
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
const isUUID = (value) => {
|
|
21
|
+
const regex =
|
|
22
|
+
/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/;
|
|
23
|
+
return regex.test(value);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
if (isUUID(urlSegment)) {
|
|
27
|
+
urlSegment = "summary";
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<ConfigurableLink
|
|
32
|
+
to={`${window.getOpenmrsSpaBase()}home${name ? `/${name}` : ""}`}
|
|
33
|
+
className={`cds--side-nav__link ${
|
|
34
|
+
name === urlSegment && "active-left-nav-link"
|
|
35
|
+
}`}
|
|
36
|
+
>
|
|
37
|
+
{title}
|
|
38
|
+
</ConfigurableLink>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const createDashboardLink = (config: LinkConfig) => () =>
|
|
43
|
+
(
|
|
44
|
+
<BrowserRouter>
|
|
45
|
+
<LinkExtension config={config} />
|
|
46
|
+
</BrowserRouter>
|
|
47
|
+
);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import ActivePatientsTable from "../active-patients/active-patients-table.component";
|
|
3
|
+
interface DischargedPatientsListProps {
|
|
4
|
+
status: string;
|
|
5
|
+
setPatientCount: (value: number) => void;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const DischargedPatientsList: React.FC<DischargedPatientsListProps> = ({
|
|
9
|
+
status,
|
|
10
|
+
setPatientCount,
|
|
11
|
+
}) => {
|
|
12
|
+
return (
|
|
13
|
+
<>
|
|
14
|
+
<ActivePatientsTable status={status} setPatientCount={setPatientCount} />
|
|
15
|
+
</>
|
|
16
|
+
);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default DischargedPatientsList;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { OpenmrsResource } from "@openmrs/esm-framework";
|
|
2
|
+
import last from "lodash-es/last";
|
|
3
|
+
|
|
4
|
+
export type QueuePriority = "Emergency" | "Not Urgent" | "Priority" | "Urgent";
|
|
5
|
+
export type MappedQueuePriority = Omit<QueuePriority, "Urgent">;
|
|
6
|
+
|
|
7
|
+
export const getTagType = (priority: string) => {
|
|
8
|
+
switch (priority as MappedQueuePriority) {
|
|
9
|
+
case "Emergency":
|
|
10
|
+
return "red";
|
|
11
|
+
case "Not Urgent":
|
|
12
|
+
return "green";
|
|
13
|
+
default:
|
|
14
|
+
return "gray";
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const buildStatusString = (status: string) => {
|
|
19
|
+
if (!status) {
|
|
20
|
+
return "";
|
|
21
|
+
}
|
|
22
|
+
if (status === "pending") {
|
|
23
|
+
return `${status}`;
|
|
24
|
+
} else if (status === "picked") {
|
|
25
|
+
return `Attending`;
|
|
26
|
+
} else if (status === "completed") {
|
|
27
|
+
return `Finished`;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const trimVisitNumber = (visitNumber: string) => {
|
|
32
|
+
if (!visitNumber) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
return visitNumber.substring(15);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const formatWaitTime = (waitTime: string, t) => {
|
|
39
|
+
const num = parseInt(waitTime);
|
|
40
|
+
const hours = num / 60;
|
|
41
|
+
const rhours = Math.floor(hours);
|
|
42
|
+
const minutes = (hours - rhours) * 60;
|
|
43
|
+
const rminutes = Math.round(minutes);
|
|
44
|
+
if (rhours > 0) {
|
|
45
|
+
return (
|
|
46
|
+
rhours +
|
|
47
|
+
" " +
|
|
48
|
+
`${t("hoursAnd", "hours and ")}` +
|
|
49
|
+
rminutes +
|
|
50
|
+
" " +
|
|
51
|
+
`${t("minutes", "minutes")}`
|
|
52
|
+
);
|
|
53
|
+
} else {
|
|
54
|
+
return rminutes + " " + `${t("minutes", "minutes")}`;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const getTagColor = (waitTime: string) => {
|
|
59
|
+
const num = parseInt(waitTime);
|
|
60
|
+
if (num <= 30) {
|
|
61
|
+
return "green";
|
|
62
|
+
} else if (num > 30 && num <= 45) {
|
|
63
|
+
return "orange";
|
|
64
|
+
} else {
|
|
65
|
+
return "red";
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const getGender = (gender, t) => {
|
|
70
|
+
switch (gender) {
|
|
71
|
+
case "M":
|
|
72
|
+
return t("male", "Male");
|
|
73
|
+
case "F":
|
|
74
|
+
return t("female", "Female");
|
|
75
|
+
case "O":
|
|
76
|
+
return t("other", "Other");
|
|
77
|
+
case "U":
|
|
78
|
+
return t("unknown", "Unknown");
|
|
79
|
+
default:
|
|
80
|
+
return gender;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export function findObsByConceptUUID(
|
|
85
|
+
arr: Array<OpenmrsResource>,
|
|
86
|
+
ids: Array<string>
|
|
87
|
+
) {
|
|
88
|
+
for (const visit of arr) {
|
|
89
|
+
return visit.obs.filter((o) => {
|
|
90
|
+
return ids.includes(o.concept.uuid);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function timeDiffInMinutes(date1: Date, date2: Date) {
|
|
96
|
+
return Math.round((date1.getTime() - date2.getTime()) / (1000 * 3600 * 24));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export const getOriginFromPathName = (pathname = "") => {
|
|
100
|
+
const from = pathname.split("/");
|
|
101
|
+
return last(from);
|
|
102
|
+
};
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
export interface PatientQueueResponse {
|
|
2
|
+
results: Array<PatientQueue>;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export interface PatientQueue {
|
|
6
|
+
uuid: string;
|
|
7
|
+
creator: {
|
|
8
|
+
uuid: string;
|
|
9
|
+
display: string;
|
|
10
|
+
username: string;
|
|
11
|
+
systemId: string;
|
|
12
|
+
person: UuidDisplay;
|
|
13
|
+
privileges: [];
|
|
14
|
+
roles: Array<UuidDisplay>;
|
|
15
|
+
retired: boolean;
|
|
16
|
+
};
|
|
17
|
+
dateCreated: string;
|
|
18
|
+
changedBy?: string;
|
|
19
|
+
dateChanged?: string;
|
|
20
|
+
voided: boolean;
|
|
21
|
+
dateVoided: string;
|
|
22
|
+
voidedBy: string;
|
|
23
|
+
patient: {
|
|
24
|
+
uuid: string;
|
|
25
|
+
display: string;
|
|
26
|
+
identifiers: Array<UuidDisplay>;
|
|
27
|
+
person: {
|
|
28
|
+
uuid: string;
|
|
29
|
+
display: string;
|
|
30
|
+
gender: string;
|
|
31
|
+
age: number;
|
|
32
|
+
birthdate: string;
|
|
33
|
+
birthdateEstimated: boolean;
|
|
34
|
+
dead: boolean;
|
|
35
|
+
deathDate?: string;
|
|
36
|
+
causeOfDeath?: string;
|
|
37
|
+
preferredName: UuidDisplay;
|
|
38
|
+
preferredAddress: UuidDisplay;
|
|
39
|
+
attributes: [];
|
|
40
|
+
voided: boolean;
|
|
41
|
+
birthtime?: string;
|
|
42
|
+
deathdateEstimated: boolean;
|
|
43
|
+
};
|
|
44
|
+
voided: boolean;
|
|
45
|
+
};
|
|
46
|
+
provider: {
|
|
47
|
+
uuid: string;
|
|
48
|
+
display: string;
|
|
49
|
+
person: UuidDisplay;
|
|
50
|
+
identifier: string;
|
|
51
|
+
attributes: [];
|
|
52
|
+
retired: boolean;
|
|
53
|
+
};
|
|
54
|
+
locationFrom: QueueLocation;
|
|
55
|
+
locationTo: QueueLocation;
|
|
56
|
+
encounter: {
|
|
57
|
+
uuid: string;
|
|
58
|
+
};
|
|
59
|
+
status: string; // TODO add status enum
|
|
60
|
+
priority: number; // TODO add priority enum
|
|
61
|
+
priorityComment: string;
|
|
62
|
+
visitNumber: string;
|
|
63
|
+
comment: string;
|
|
64
|
+
queueRoom: QueueRoom;
|
|
65
|
+
datePicked: string;
|
|
66
|
+
dateCompleted: string;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface QueueLocation {
|
|
70
|
+
uuid: string;
|
|
71
|
+
display: string;
|
|
72
|
+
name: string;
|
|
73
|
+
description: string;
|
|
74
|
+
address1?: string;
|
|
75
|
+
address2?: string;
|
|
76
|
+
cityVillage?: string;
|
|
77
|
+
stateProvince?: string;
|
|
78
|
+
country: string;
|
|
79
|
+
postalCode?: string;
|
|
80
|
+
latitude?: string;
|
|
81
|
+
longitude?: string;
|
|
82
|
+
countyDistrict?: string;
|
|
83
|
+
address3?: string;
|
|
84
|
+
address4?: string;
|
|
85
|
+
address5?: string;
|
|
86
|
+
address6?: string;
|
|
87
|
+
tags: Array<UuidDisplay>;
|
|
88
|
+
parentLocation: UuidDisplay;
|
|
89
|
+
childLocations: Array<UuidDisplay>;
|
|
90
|
+
retired: boolean;
|
|
91
|
+
attributes: [];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface QueueRoom {
|
|
95
|
+
uuid: string;
|
|
96
|
+
display: string;
|
|
97
|
+
name: string;
|
|
98
|
+
description: string;
|
|
99
|
+
address1?: string;
|
|
100
|
+
address2?: string;
|
|
101
|
+
cityVillage?: string;
|
|
102
|
+
stateProvince?: string;
|
|
103
|
+
country?: string;
|
|
104
|
+
postalCode?: string;
|
|
105
|
+
latitude?: string;
|
|
106
|
+
longitude?: string;
|
|
107
|
+
countyDistrict?: string;
|
|
108
|
+
address3?: string;
|
|
109
|
+
address4?: string;
|
|
110
|
+
address5?: string;
|
|
111
|
+
address6?: string;
|
|
112
|
+
tags: Array<UuidDisplay>;
|
|
113
|
+
parentLocation: UuidDisplay;
|
|
114
|
+
childLocations: Array<QueueLocation>;
|
|
115
|
+
retired: boolean;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface UuidDisplay {
|
|
119
|
+
uuid: string;
|
|
120
|
+
display: string;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export interface patientDetailsProps {
|
|
124
|
+
name: string;
|
|
125
|
+
patientUuid: string;
|
|
126
|
+
encounter: {
|
|
127
|
+
uuid: string;
|
|
128
|
+
};
|
|
129
|
+
locationUuid: string;
|
|
130
|
+
locationTo: string;
|
|
131
|
+
locationFrom: string;
|
|
132
|
+
queueUuid: string;
|
|
133
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Type } from "@openmrs/esm-framework";
|
|
2
|
+
import { boolean } from "zod";
|
|
3
|
+
|
|
4
|
+
export const configSchema = {
|
|
5
|
+
admissionLocationTagUuid: {
|
|
6
|
+
_type: Type.UUID,
|
|
7
|
+
_description:
|
|
8
|
+
"UUID for the location tag of the `Admission Location`. Patients may only be admitted to inpatient care in a location with this tag",
|
|
9
|
+
_default: "839c65c7-9998-4b90-b80b-39727dfe9fa2",
|
|
10
|
+
},
|
|
11
|
+
inpatientVisitUuid: {
|
|
12
|
+
_type: Type.UUID,
|
|
13
|
+
_description: "UUID for the inpatient visit",
|
|
14
|
+
_default: "a73e2ac6-263b-47fc-99fc-e0f2c09fc914",
|
|
15
|
+
},
|
|
16
|
+
restrictWardAdministrationToLoginLocation: {
|
|
17
|
+
_type: boolean,
|
|
18
|
+
_description: "UUID for the inpatient visit",
|
|
19
|
+
_default: false,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Layer, Tile } from "@carbon/react";
|
|
3
|
+
import styles from "./empty-state.scss";
|
|
4
|
+
|
|
5
|
+
type EmptyStateProps = {
|
|
6
|
+
msg: string;
|
|
7
|
+
helper: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const EmptyState: React.FC<EmptyStateProps> = ({
|
|
11
|
+
msg,
|
|
12
|
+
helper,
|
|
13
|
+
}: EmptyStateProps) => {
|
|
14
|
+
return (
|
|
15
|
+
<Layer className={styles.layer}>
|
|
16
|
+
<Tile className={styles.tile}>
|
|
17
|
+
<svg width={64} height={64} viewBox="0 0 64 64">
|
|
18
|
+
<title>Empty data illustration</title>
|
|
19
|
+
<g fill="none" fillRule="evenodd">
|
|
20
|
+
<path
|
|
21
|
+
d="M38.133 13.186H21.947c-.768.001-1.39.623-1.39 1.391V50.55l-.186.057-3.97 1.216a.743.743 0 01-.927-.493L3.664 12.751a.742.742 0 01.492-.926l6.118-1.874 17.738-5.43 6.119-1.873a.741.741 0 01.926.492L38.076 13l.057.186z"
|
|
22
|
+
fill="#F4F4F4"
|
|
23
|
+
/>
|
|
24
|
+
<path
|
|
25
|
+
d="M41.664 13L38.026 1.117A1.576 1.576 0 0036.056.07l-8.601 2.633-17.737 5.43-8.603 2.634a1.578 1.578 0 00-1.046 1.97l12.436 40.616a1.58 1.58 0 001.969 1.046l5.897-1.805.185-.057v-.194l-.185.057-5.952 1.822a1.393 1.393 0 01-1.737-.923L.247 12.682a1.39 1.39 0 01.923-1.738L9.772 8.31 27.51 2.881 36.112.247a1.393 1.393 0 011.737.923L41.47 13l.057.186h.193l-.057-.185z"
|
|
26
|
+
fill="#8D8D8D"
|
|
27
|
+
/>
|
|
28
|
+
<path
|
|
29
|
+
d="M11.378 11.855a.836.836 0 01-.798-.59L9.385 7.361a.835.835 0 01.554-1.042l16.318-4.996a.836.836 0 011.042.554l1.195 3.902a.836.836 0 01-.554 1.043l-16.318 4.995a.831.831 0 01-.244.037z"
|
|
30
|
+
fill="#C6C6C6"
|
|
31
|
+
/>
|
|
32
|
+
<circle fill="#C6C6C6" cx={17.636} cy={2.314} r={1.855} />
|
|
33
|
+
<circle
|
|
34
|
+
fill="#FFF"
|
|
35
|
+
fillRule="nonzero"
|
|
36
|
+
cx={17.636}
|
|
37
|
+
cy={2.314}
|
|
38
|
+
r={1.175}
|
|
39
|
+
/>
|
|
40
|
+
<path
|
|
41
|
+
d="M55.893 53.995H24.544a.79.79 0 01-.788-.789V15.644a.79.79 0 01.788-.788h31.349a.79.79 0 01.788.788v37.562a.79.79 0 01-.788.789z"
|
|
42
|
+
fill="#F4F4F4"
|
|
43
|
+
/>
|
|
44
|
+
<path
|
|
45
|
+
d="M41.47 13H21.948a1.579 1.579 0 00-1.576 1.577V52.4l.185-.057V14.577c.001-.768.623-1.39 1.391-1.39h19.581L41.471 13zm17.02 0H21.947a1.579 1.579 0 00-1.576 1.577v42.478c0 .87.706 1.576 1.576 1.577H58.49a1.579 1.579 0 001.576-1.577V14.577a1.579 1.579 0 00-1.576-1.576zm1.39 44.055c0 .768-.622 1.39-1.39 1.392H21.947c-.768-.001-1.39-.624-1.39-1.392V14.577c0-.768.622-1.39 1.39-1.39H58.49c.768 0 1.39.622 1.39 1.39v42.478z"
|
|
46
|
+
fill="#8D8D8D"
|
|
47
|
+
/>
|
|
48
|
+
<path
|
|
49
|
+
d="M48.751 17.082H31.686a.836.836 0 01-.835-.835v-4.081c0-.46.374-.834.835-.835H48.75c.461 0 .834.374.835.835v4.08c0 .462-.374.835-.835.836z"
|
|
50
|
+
fill="#C6C6C6"
|
|
51
|
+
/>
|
|
52
|
+
<circle fill="#C6C6C6" cx={40.218} cy={9.755} r={1.855} />
|
|
53
|
+
<circle
|
|
54
|
+
fill="#FFF"
|
|
55
|
+
fillRule="nonzero"
|
|
56
|
+
cx={40.218}
|
|
57
|
+
cy={9.755}
|
|
58
|
+
r={1.13}
|
|
59
|
+
/>
|
|
60
|
+
</g>
|
|
61
|
+
</svg>
|
|
62
|
+
<p className={styles.content}>{msg}</p>
|
|
63
|
+
<p className={styles.explainer}>{helper}</p>
|
|
64
|
+
</Tile>
|
|
65
|
+
</Layer>
|
|
66
|
+
);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export default EmptyState;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
@use '@carbon/colors';
|
|
2
|
+
@use '@carbon/layout';
|
|
3
|
+
@use "@carbon/type";
|
|
4
|
+
|
|
5
|
+
.desktopHeading {
|
|
6
|
+
h4 {
|
|
7
|
+
@include type.type-style("heading-compact-02");
|
|
8
|
+
color: colors.$gray-70;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.tabletHeading {
|
|
13
|
+
h4 {
|
|
14
|
+
@include type.type-style("heading-03");
|
|
15
|
+
color: colors.$gray-70;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.desktopHeading,
|
|
20
|
+
.tabletHeading {
|
|
21
|
+
text-align: left;
|
|
22
|
+
text-transform: capitalize;
|
|
23
|
+
margin-bottom: layout.$spacing-05;
|
|
24
|
+
|
|
25
|
+
h4:after {
|
|
26
|
+
content: "";
|
|
27
|
+
display: block;
|
|
28
|
+
width: 2rem;
|
|
29
|
+
padding-top: 0.188rem;
|
|
30
|
+
border-bottom: 0.375rem solid var(--brand-03);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.heading:after {
|
|
35
|
+
content: "";
|
|
36
|
+
display: block;
|
|
37
|
+
width: 2rem;
|
|
38
|
+
padding-top: 0.188rem;
|
|
39
|
+
border-bottom: 0.375rem solid var(--brand-03);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.tile {
|
|
43
|
+
padding: 2rem;
|
|
44
|
+
border: 1px solid colors.$gray-20;
|
|
45
|
+
margin: 1.5rem;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.layer {
|
|
49
|
+
text-align: center;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.content {
|
|
53
|
+
@include type.type-style("heading-compact-02");
|
|
54
|
+
color: colors.$gray-70;
|
|
55
|
+
margin-top: layout.$spacing-05;
|
|
56
|
+
margin-bottom: layout.$spacing-03;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.explainer {
|
|
60
|
+
@include type.type-style('body-compact-01');
|
|
61
|
+
color: colors.$gray-70;
|
|
62
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {
|
|
3
|
+
ConfigurableLink,
|
|
4
|
+
formatDate,
|
|
5
|
+
useSession,
|
|
6
|
+
} from "@openmrs/esm-framework";
|
|
7
|
+
import { useTranslation } from "react-i18next";
|
|
8
|
+
import { Calendar, Location } from "@carbon/react/icons";
|
|
9
|
+
import Illustration from "./illustration.component";
|
|
10
|
+
import styles from "./header.scss";
|
|
11
|
+
|
|
12
|
+
type HeaderProps = {
|
|
13
|
+
route: string;
|
|
14
|
+
headerTitle?: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const Header: React.FC<HeaderProps> = ({
|
|
18
|
+
route,
|
|
19
|
+
headerTitle = "Bed Management",
|
|
20
|
+
}) => {
|
|
21
|
+
const { t } = useTranslation();
|
|
22
|
+
const userSession = useSession();
|
|
23
|
+
const userLocation = userSession?.sessionLocation?.display;
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div className={styles.header}>
|
|
27
|
+
<div className={styles["left-justified-items"]}>
|
|
28
|
+
<ConfigurableLink to={`${window.getOpenmrsSpaBase()}bed-management`}>
|
|
29
|
+
<Illustration />
|
|
30
|
+
</ConfigurableLink>
|
|
31
|
+
<div className={styles["page-labels"]}>
|
|
32
|
+
<p>{t("headerTitle", headerTitle)}</p>
|
|
33
|
+
<p className={styles["page-name"]}>{route}</p>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
<div className={styles["right-justified-items"]}>
|
|
37
|
+
<div className={styles["date-and-location"]}>
|
|
38
|
+
<Location size={16} />
|
|
39
|
+
<span className={styles.value}>{userLocation}</span>
|
|
40
|
+
<span className={styles.middot}>·</span>
|
|
41
|
+
<Calendar size={16} />
|
|
42
|
+
<span className={styles.value}>
|
|
43
|
+
{formatDate(new Date(), { mode: "standard" })}
|
|
44
|
+
</span>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export default Header;
|