@kenyaemr/esm-bed-management-app 1.0.1-pre.4 → 8.0.2

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.
Files changed (177) hide show
  1. package/.turbo/turbo-build.log +36 -0
  2. package/README.md +6 -38
  3. package/dist/130.js +2 -0
  4. package/dist/{800.js.LICENSE.txt → 130.js.LICENSE.txt} +2 -0
  5. package/dist/130.js.map +1 -0
  6. package/dist/148.js +1 -0
  7. package/dist/148.js.map +1 -0
  8. package/dist/169.js +1 -0
  9. package/dist/169.js.map +1 -0
  10. package/dist/271.js +1 -0
  11. package/dist/319.js +1 -0
  12. package/dist/325.js +1 -0
  13. package/dist/325.js.map +1 -0
  14. package/dist/339.js +1 -0
  15. package/dist/339.js.map +1 -0
  16. package/dist/455.js +1 -1
  17. package/dist/455.js.LICENSE.txt +6 -0
  18. package/dist/455.js.map +1 -1
  19. package/dist/460.js +1 -0
  20. package/dist/501.js +1 -0
  21. package/dist/501.js.map +1 -0
  22. package/dist/542.js +1 -0
  23. package/dist/542.js.map +1 -0
  24. package/dist/574.js +1 -1
  25. package/dist/591.js +2 -0
  26. package/dist/{26.js.LICENSE.txt → 591.js.LICENSE.txt} +3 -3
  27. package/dist/591.js.map +1 -0
  28. package/dist/644.js +1 -0
  29. package/dist/757.js +1 -0
  30. package/dist/766.js +2 -0
  31. package/dist/{330.js.LICENSE.txt → 766.js.LICENSE.txt} +0 -9
  32. package/dist/766.js.map +1 -0
  33. package/dist/{294.js → 784.js} +2 -2
  34. package/dist/{294.js.map → 784.js.map} +1 -1
  35. package/dist/788.js +1 -0
  36. package/dist/807.js +1 -0
  37. package/dist/833.js +1 -0
  38. package/dist/main.js +1 -1
  39. package/dist/main.js.map +1 -1
  40. package/dist/openmrs-esm-bed-management-app.js +1 -0
  41. package/dist/{esm-kenyaemr-bed-management-app.js.buildmanifest.json → openmrs-esm-bed-management-app.js.buildmanifest.json} +202 -155
  42. package/dist/openmrs-esm-bed-management-app.js.map +1 -0
  43. package/dist/routes.json +1 -1
  44. package/jest.config.js +3 -0
  45. package/package-lock.json +5893 -0
  46. package/package.json +25 -83
  47. package/src/__mocks__/react-i18next.js +18 -14
  48. package/src/admin-card-link.component.tsx +7 -10
  49. package/src/bed-administration/bed-administration-form.component.tsx +65 -99
  50. package/src/bed-administration/bed-administration-table.component.tsx +68 -127
  51. package/src/bed-administration/bed-administration-table.scss +12 -16
  52. package/src/bed-administration/bed-administration-types.ts +8 -0
  53. package/src/bed-administration/bed-administration.resource.ts +16 -18
  54. package/src/bed-administration/edit-bed-form.component.tsx +20 -31
  55. package/src/bed-administration/new-bed-form.component.tsx +28 -44
  56. package/src/bed-tag/bed-tag-administration-table.component.tsx +192 -0
  57. package/src/bed-tag/bed-tags-admin-form.component.tsx +127 -0
  58. package/src/bed-tag/edit-tag-form.component.tsx +72 -0
  59. package/src/bed-tag/new-tag-form.component.tsx +76 -0
  60. package/src/bed-type/bed-type-admin-form.component.tsx +166 -0
  61. package/src/bed-type/bed-type-administration-table.component.tsx +198 -0
  62. package/src/bed-type/edit-bed-type.component.tsx +72 -0
  63. package/src/bed-type/new-bed-type-form.component.tsx +80 -0
  64. package/src/card-header/card-header.component.tsx +20 -0
  65. package/src/card-header/card-header.scss +45 -0
  66. package/src/config-schema.ts +9 -17
  67. package/src/declarations.d.ts +5 -5
  68. package/src/empty-state/empty-state.component.tsx +6 -21
  69. package/src/empty-state/empty-state.scss +10 -10
  70. package/src/header/header.component.tsx +14 -23
  71. package/src/header/header.scss +11 -11
  72. package/src/header/illustration.component.tsx +3 -3
  73. package/src/home.component.tsx +4 -4
  74. package/src/index.ts +26 -40
  75. package/src/left-panel/left-panel.component.tsx +7 -17
  76. package/src/left-panel/left-panel.scss +8 -7
  77. package/src/left-panel-link.component.tsx +14 -24
  78. package/src/root.component.tsx +14 -10
  79. package/src/root.scss +2 -2
  80. package/src/routes.json +12 -2
  81. package/src/setup-tests.ts +1 -1
  82. package/src/summary/summary.component.tsx +16 -30
  83. package/src/summary/summary.resource.ts +169 -60
  84. package/src/summary/summary.scss +31 -29
  85. package/src/types.ts +50 -29
  86. package/src/ward-card/ward-card.component.tsx +5 -12
  87. package/src/ward-card/ward-card.scss +2 -2
  88. package/src/ward-with-beds/ward-with-beds.component.tsx +28 -47
  89. package/src/ward-with-beds/ward-with-beds.scss +5 -5
  90. package/translations/am.json +51 -0
  91. package/translations/ar.json +51 -0
  92. package/translations/en.json +48 -4
  93. package/translations/es.json +51 -0
  94. package/translations/fr.json +51 -0
  95. package/translations/he.json +51 -0
  96. package/translations/km.json +51 -0
  97. package/translations/zh.json +51 -0
  98. package/translations/zh_CN.json +51 -0
  99. package/tsconfig.json +3 -21
  100. package/webpack.config.js +1 -1
  101. package/.editorconfig +0 -12
  102. package/.eslintignore +0 -2
  103. package/.eslintrc +0 -37
  104. package/.husky/pre-commit +0 -4
  105. package/.idea/inspectionProfiles/Project_Default.xml +0 -6
  106. package/.idea/modules.xml +0 -8
  107. package/.idea/vcs.xml +0 -6
  108. package/.prettierignore +0 -14
  109. package/.turbo.json +0 -18
  110. package/.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs +0 -541
  111. package/.yarn/plugins/@yarnpkg/plugin-version.cjs +0 -550
  112. package/.yarn/versions/6816f0d4.yml +0 -0
  113. package/LICENSE +0 -373
  114. package/dist/187.js +0 -1
  115. package/dist/187.js.map +0 -1
  116. package/dist/207.js +0 -1
  117. package/dist/207.js.map +0 -1
  118. package/dist/26.js +0 -2
  119. package/dist/26.js.map +0 -1
  120. package/dist/283.js +0 -1
  121. package/dist/283.js.map +0 -1
  122. package/dist/330.js +0 -2
  123. package/dist/330.js.map +0 -1
  124. package/dist/352.js +0 -1
  125. package/dist/352.js.map +0 -1
  126. package/dist/404.js +0 -1
  127. package/dist/404.js.map +0 -1
  128. package/dist/558.js +0 -2
  129. package/dist/558.js.LICENSE.txt +0 -14
  130. package/dist/558.js.map +0 -1
  131. package/dist/629.js +0 -1
  132. package/dist/629.js.map +0 -1
  133. package/dist/707.js +0 -1
  134. package/dist/707.js.map +0 -1
  135. package/dist/800.js +0 -2
  136. package/dist/800.js.map +0 -1
  137. package/dist/884.js +0 -1
  138. package/dist/884.js.map +0 -1
  139. package/dist/933.js +0 -1
  140. package/dist/933.js.map +0 -1
  141. package/dist/959.js +0 -1
  142. package/dist/959.js.map +0 -1
  143. package/dist/esm-kenyaemr-bed-management-app.js +0 -1
  144. package/dist/esm-kenyaemr-bed-management-app.js.map +0 -1
  145. package/i18next-parser.config.js +0 -89
  146. package/src/assets/landing-page.png +0 -0
  147. package/src/assets/logo.svg +0 -1
  148. package/src/bed-admission/active-patients/active-patients-table.component.tsx +0 -299
  149. package/src/bed-admission/active-patients/active-visits.resource.ts +0 -171
  150. package/src/bed-admission/active-patients/admission-action-button-styles.scss +0 -0
  151. package/src/bed-admission/active-patients/admission-action-button.component.tsx +0 -26
  152. package/src/bed-admission/active-patients/index.tsx +0 -15
  153. package/src/bed-admission/active-patients/patient-queues.resource.ts +0 -136
  154. package/src/bed-admission/active-patients/styles.scss +0 -284
  155. package/src/bed-admission/active-patients/view-action-menu.component.tsx +0 -33
  156. package/src/bed-admission/admitted-patients/active-admissions.resource.ts +0 -121
  157. package/src/bed-admission/admitted-patients/admitted-patients-table.component.tsx +0 -280
  158. package/src/bed-admission/admitted-patients/admitted-patients.component.tsx +0 -22
  159. package/src/bed-admission/admitted-patients/location-combo-box.component.tsx +0 -55
  160. package/src/bed-admission/admitted-patients/styles.scss +0 -284
  161. package/src/bed-admission/bed-admission-tabs-styles.scss +0 -30
  162. package/src/bed-admission/bed-admission-tabs.component.tsx +0 -69
  163. package/src/bed-admission/bed-admission.component.tsx +0 -15
  164. package/src/bed-admission/bed-admission.resource.ts +0 -35
  165. package/src/bed-admission/bed-layout/bed-layout-list.component.tsx +0 -101
  166. package/src/bed-admission/bed-layout/bed-layout.component.tsx +0 -64
  167. package/src/bed-admission/bed-layout/bed-layout.scss +0 -118
  168. package/src/bed-admission/bed-layout/min-bed-layout.component.tsx +0 -26
  169. package/src/bed-admission/createDashboardLink.tsx +0 -47
  170. package/src/bed-admission/discharged-patients/discharged-patients.componet.tsx +0 -19
  171. package/src/bed-admission/helpers/functions.ts +0 -102
  172. package/src/bed-admission/types.ts +0 -133
  173. package/src/workspace/allocate-bed-workspace.component.tsx +0 -141
  174. package/src/workspace/allocate-bed.scss +0 -117
  175. package/src/workspace/overlay.component.tsx +0 -55
  176. package/src/workspace/overlay.scss +0 -96
  177. /package/dist/{294.js.LICENSE.txt → 784.js.LICENSE.txt} +0 -0
@@ -0,0 +1,166 @@
1
+ import React, { useState } from 'react';
2
+ import { z } from 'zod';
3
+ import { useForm, Controller } from 'react-hook-form';
4
+ import { zodResolver } from '@hookform/resolvers/zod';
5
+ import {
6
+ Button,
7
+ ComposedModal,
8
+ Form,
9
+ FormGroup,
10
+ ModalBody,
11
+ ModalFooter,
12
+ ModalHeader,
13
+ Stack,
14
+ TextArea,
15
+ TextInput,
16
+ InlineNotification,
17
+ } from '@carbon/react';
18
+ import { useTranslation } from 'react-i18next';
19
+ import { getCoreTranslation, type Location } from '@openmrs/esm-framework';
20
+ import type { BedType, BedTypeData } from '../types';
21
+
22
+ const BedTypeAdministrationSchema = z.object({
23
+ name: z.string().max(255),
24
+ displayName: z.string().max(255),
25
+ description: z.string().max(255),
26
+ });
27
+
28
+ interface BedAdministrationFormProps {
29
+ showModal: boolean;
30
+ onModalChange: (showModal: boolean) => void;
31
+ availableBedTypes: Array<BedType>;
32
+ allLocations: Location[];
33
+ handleCreateQuestion?: (formData: BedTypeData) => void;
34
+ headerTitle: string;
35
+ initialData: BedTypeData;
36
+ }
37
+
38
+ interface ErrorType {
39
+ message: string;
40
+ }
41
+
42
+ const BedTypeAdministrationForm: React.FC<BedAdministrationFormProps> = ({
43
+ showModal,
44
+ onModalChange,
45
+ handleCreateQuestion,
46
+ headerTitle,
47
+ initialData,
48
+ }) => {
49
+ const { t } = useTranslation();
50
+
51
+ const [showErrorNotification, setShowErrorNotification] = useState(false);
52
+ const [formStateError, setFormStateError] = useState('');
53
+
54
+ const {
55
+ handleSubmit,
56
+ control,
57
+ formState: { isDirty },
58
+ } = useForm<BedTypeData>({
59
+ mode: 'all',
60
+ resolver: zodResolver(BedTypeAdministrationSchema),
61
+ defaultValues: {
62
+ name: initialData.name || '',
63
+ displayName: initialData.displayName || '',
64
+ description: initialData.description || '',
65
+ },
66
+ });
67
+
68
+ const onSubmit = (formData: BedTypeData) => {
69
+ const result = BedTypeAdministrationSchema.safeParse(formData);
70
+ if (result.success) {
71
+ setShowErrorNotification(false);
72
+ handleCreateQuestion(formData);
73
+ }
74
+ };
75
+
76
+ const onError = (error: { [key: string]: ErrorType }) => {
77
+ setFormStateError(Object.entries(error)[0][1].message);
78
+ setShowErrorNotification(true);
79
+ };
80
+
81
+ return (
82
+ <ComposedModal open={showModal} onClose={() => onModalChange(false)} preventCloseOnClickOutside>
83
+ <ModalHeader title={headerTitle} />
84
+ <ModalBody hasScrollingContent>
85
+ <Form>
86
+ <Stack gap={3}>
87
+ <FormGroup legendText={''}>
88
+ <Controller
89
+ name="name"
90
+ control={control}
91
+ render={({ field, fieldState }) => (
92
+ <>
93
+ <TextInput
94
+ id="bedName"
95
+ labelText={t('bedName', 'Bed Name')}
96
+ placeholder={t('bedTypePlaceholder', '')}
97
+ invalidText={fieldState.error?.message}
98
+ {...field}
99
+ />
100
+ </>
101
+ )}
102
+ />
103
+ </FormGroup>
104
+ <FormGroup legendText={''}>
105
+ <Controller
106
+ name="displayName"
107
+ control={control}
108
+ render={({ field, fieldState }) => (
109
+ <>
110
+ <TextInput
111
+ id="displayName"
112
+ labelText={t('displayName', 'Display Name')}
113
+ placeholder={t('displayNamePlaceholder', '')}
114
+ invalidText={fieldState.error?.message}
115
+ {...field}
116
+ />
117
+ </>
118
+ )}
119
+ />
120
+ </FormGroup>
121
+ <FormGroup>
122
+ <Controller
123
+ name="description"
124
+ control={control}
125
+ render={({ field, fieldState }) => (
126
+ <>
127
+ <TextArea
128
+ rows={2}
129
+ id="description"
130
+ invalidText={fieldState?.error?.message}
131
+ labelText={t('description', 'Description')}
132
+ {...field}
133
+ placeholder={t('description', 'Enter the bed description')}
134
+ />
135
+ </>
136
+ )}
137
+ />
138
+ </FormGroup>
139
+
140
+ {showErrorNotification && (
141
+ <InlineNotification
142
+ lowContrast
143
+ title={t('error', 'Error')}
144
+ style={{ minWidth: '100%', margin: '0', padding: '0' }}
145
+ role="alert"
146
+ kind="error"
147
+ subtitle={t('pleaseFillField', formStateError) + '.'}
148
+ onClose={() => setShowErrorNotification(false)}
149
+ />
150
+ )}
151
+ </Stack>
152
+ </Form>
153
+ </ModalBody>
154
+ <ModalFooter>
155
+ <Button onClick={() => onModalChange(false)} kind="secondary">
156
+ {getCoreTranslation('cancel', 'Cancel')}
157
+ </Button>
158
+ <Button disabled={!isDirty} onClick={handleSubmit(onSubmit, onError)}>
159
+ <span>{t('save', 'Save')}</span>
160
+ </Button>
161
+ </ModalFooter>
162
+ </ComposedModal>
163
+ );
164
+ };
165
+
166
+ export default BedTypeAdministrationForm;
@@ -0,0 +1,198 @@
1
+ import React, { useEffect, useMemo, useState } from 'react';
2
+ import { useTranslation } from 'react-i18next';
3
+ import {
4
+ Button,
5
+ DataTable,
6
+ DataTableSkeleton,
7
+ InlineLoading,
8
+ Pagination,
9
+ Table,
10
+ TableBody,
11
+ TableCell,
12
+ TableContainer,
13
+ TableHead,
14
+ TableHeader,
15
+ TableRow,
16
+ Tile,
17
+ } from '@carbon/react';
18
+ import { Add, Edit } from '@carbon/react/icons';
19
+ import { ErrorState, isDesktop as desktopLayout, useLayoutType } from '@openmrs/esm-framework';
20
+ import type { BedTypeData } from '../types';
21
+ import { useBedType } from '../summary/summary.resource';
22
+ import Header from '../header/header.component';
23
+ import BedTypeForm from './new-bed-type-form.component';
24
+ import styles from '../bed-administration/bed-administration-table.scss';
25
+ import { CardHeader } from '../card-header/card-header.component';
26
+ import EditBedTypeForm from './edit-bed-type.component';
27
+
28
+ const BedTypeAdministrationTable: React.FC = () => {
29
+ const { t } = useTranslation();
30
+ const headerTitle = t('bedType', 'Bed Type');
31
+ const layout = useLayoutType();
32
+ const isTablet = layout === 'tablet';
33
+ const responsiveSize = isTablet ? 'lg' : 'sm';
34
+ const isDesktop = desktopLayout(layout);
35
+ const [showEditBedModal, setShowEditBedModal] = useState(false);
36
+ const [isBedDataLoading, setIsBedDataLoading] = useState(false);
37
+ const [showBedTypeModal, setAddBedTypeModal] = useState(false);
38
+ const [currentPage, setCurrentPage] = useState(1);
39
+ const [editData, setEditData] = useState<BedTypeData>();
40
+ const [pageSize] = useState(10);
41
+ const { bedTypeData, isError, loading, validate, mutate } = useBedType();
42
+ const [currentPageSize, setPageSize] = useState(10);
43
+ const pageSizes = [10, 20, 30, 40, 50];
44
+ const tableHeaders = [
45
+ {
46
+ header: t('name', 'Name'),
47
+ key: 'name',
48
+ },
49
+ {
50
+ header: t('displayName', 'Display Name'),
51
+ key: 'displayName',
52
+ },
53
+ {
54
+ header: t('description', 'Description'),
55
+ key: 'description',
56
+ },
57
+ {
58
+ key: 'actions',
59
+ header: t('actions', 'Actions'),
60
+ },
61
+ ];
62
+
63
+ const tableRows = useMemo(() => {
64
+ return bedTypeData?.map((entry) => ({
65
+ id: entry.uuid,
66
+ name: entry?.name,
67
+ displayName: entry?.displayName,
68
+ description: entry?.description,
69
+ actions: (
70
+ <>
71
+ <Button
72
+ enterDelayMs={300}
73
+ renderIcon={Edit}
74
+ onClick={(e) => {
75
+ e.preventDefault();
76
+ setEditData(entry);
77
+ setShowEditBedModal(true);
78
+ setAddBedTypeModal(false);
79
+ }}
80
+ kind={'ghost'}
81
+ iconDescription={t('editBedType', 'Edit Bed Type')}
82
+ hasIconOnly
83
+ size={responsiveSize}
84
+ tooltipAlignment="start"
85
+ />
86
+ </>
87
+ ),
88
+ }));
89
+ }, [responsiveSize, bedTypeData, t]);
90
+
91
+ if (isBedDataLoading || loading) {
92
+ return (
93
+ <>
94
+ <Header route="Bed Type" />
95
+ <div className={styles.widgetCard}>
96
+ <DataTableSkeleton role="progressbar" compact={isDesktop} zebra />
97
+ </div>
98
+ </>
99
+ );
100
+ }
101
+
102
+ if (isError) {
103
+ return (
104
+ <>
105
+ <Header route="Bed Type" />
106
+ <div className={styles.widgetCard}>
107
+ <ErrorState error={isError} headerTitle={headerTitle} />
108
+ </div>
109
+ </>
110
+ );
111
+ }
112
+
113
+ return (
114
+ <>
115
+ <Header route="Bed Type" />
116
+
117
+ <div className={styles.widgetCard}>
118
+ {showBedTypeModal ? (
119
+ <BedTypeForm onModalChange={setAddBedTypeModal} showModal={showBedTypeModal} mutate={mutate} />
120
+ ) : null}
121
+ {showEditBedModal ? (
122
+ <EditBedTypeForm
123
+ onModalChange={setShowEditBedModal}
124
+ showModal={showEditBedModal}
125
+ editData={editData}
126
+ mutate={mutate}
127
+ />
128
+ ) : null}
129
+ <CardHeader title={headerTitle}>
130
+ <span className={styles.backgroundDataFetchingIndicator}>
131
+ <span>{validate ? <InlineLoading /> : null}</span>
132
+ </span>
133
+ {bedTypeData?.length ? (
134
+ <Button
135
+ kind="ghost"
136
+ renderIcon={(props) => <Add size={16} {...props} />}
137
+ onClick={() => setAddBedTypeModal(true)}>
138
+ {t('addBedtype', 'Add Bed Type')}
139
+ </Button>
140
+ ) : null}
141
+ </CardHeader>
142
+ <DataTable rows={tableRows} headers={tableHeaders} isSortable size={isTablet ? 'lg' : 'sm'} useZebraStyles>
143
+ {({ rows, headers, getTableProps }) => (
144
+ <TableContainer>
145
+ <Table {...getTableProps()}>
146
+ <TableHead>
147
+ <TableRow>
148
+ {headers.map((header) => (
149
+ <TableHeader>{header.header?.content ?? header.header}</TableHeader>
150
+ ))}
151
+ </TableRow>
152
+ </TableHead>
153
+ <TableBody>
154
+ {rows.map((row) => (
155
+ <TableRow key={row.id}>
156
+ {row.cells.map((cell) => (
157
+ <TableCell key={cell.id}>{cell.value?.content ?? cell.value}</TableCell>
158
+ ))}
159
+ </TableRow>
160
+ ))}
161
+ </TableBody>
162
+ </Table>
163
+ {rows.length === 0 ? (
164
+ <div className={styles.tileContainer}>
165
+ <Tile className={styles.tile}>
166
+ <div className={styles.tileContent}>
167
+ <p className={styles.content}>{t('No data', 'No data to display')}</p>
168
+ <p className={styles.helper}>{t('checkFilters', 'Check the filters above')}</p>
169
+ </div>
170
+ <p className={styles.separator}>{t('or', 'or')}</p>
171
+ <Button
172
+ kind="ghost"
173
+ size="sm"
174
+ renderIcon={(props) => <Add size={16} {...props} />}
175
+ onClick={() => setAddBedTypeModal(true)}>
176
+ {t('bedType', 'Add Bed Type')}
177
+ </Button>
178
+ </Tile>
179
+ </div>
180
+ ) : null}
181
+ <Pagination
182
+ page={currentPage}
183
+ pageSize={pageSize}
184
+ pageSizes={[10, 20, 30, 40, 50]}
185
+ totalItems={bedTypeData.length}
186
+ onChange={({ page, pageSize }) => {
187
+ setCurrentPage(page);
188
+ setPageSize(pageSize);
189
+ }}
190
+ />
191
+ </TableContainer>
192
+ )}
193
+ </DataTable>
194
+ </div>
195
+ </>
196
+ );
197
+ };
198
+ export default BedTypeAdministrationTable;
@@ -0,0 +1,72 @@
1
+ import React, { useCallback } from 'react';
2
+ import { useTranslation } from 'react-i18next';
3
+ import { showToast, showNotification, useConfig } from '@openmrs/esm-framework';
4
+
5
+ import { editBedType, useBedType } from '../summary/summary.resource';
6
+ import { type BedTypeDataAdministration } from '../bed-administration/bed-administration-types';
7
+ import { type BedTypeData, type Mutator } from '../types';
8
+ import BedTypeAdministrationForm from './bed-type-admin-form.component';
9
+
10
+ interface EditBedTypeFormProps {
11
+ showModal: boolean;
12
+ onModalChange: (showModal: boolean) => void;
13
+ editData: BedTypeData;
14
+ mutate: Mutator;
15
+ }
16
+
17
+ const EditBedTypeForm: React.FC<EditBedTypeFormProps> = ({ showModal, onModalChange, editData, mutate }) => {
18
+ const { t } = useTranslation();
19
+ const headerTitle = t('editBedType', 'Edit Bed Type');
20
+ const { bedTypeData } = useBedType();
21
+ const availableBedTypes = bedTypeData ? bedTypeData : [];
22
+ const handleCreateQuestion = useCallback(
23
+ (formData: BedTypeDataAdministration) => {
24
+ const bedUuid = editData.uuid;
25
+ const { name, displayName, description } = formData;
26
+ const bedTypePayload = {
27
+ name,
28
+ displayName,
29
+ description,
30
+ };
31
+ editBedType({ bedTypePayload, bedTypeId: bedUuid })
32
+ .then(() => {
33
+ showToast({
34
+ title: t('formSaved', 'Bed Type'),
35
+ kind: 'success',
36
+ critical: true,
37
+ description: bedTypePayload.name + ' ' + t('saveSuccessMessage', 'was saved successfully.'),
38
+ });
39
+
40
+ mutate();
41
+ onModalChange(false);
42
+ })
43
+ .catch((error) => {
44
+ showNotification({
45
+ title: t('errorCreatingForm', 'Error creating bed'),
46
+ kind: 'error',
47
+ critical: true,
48
+ description: error?.message,
49
+ });
50
+ onModalChange(false);
51
+ });
52
+ onModalChange(false);
53
+ },
54
+ [onModalChange, mutate, editData, t],
55
+ );
56
+
57
+ return (
58
+ <>
59
+ <BedTypeAdministrationForm
60
+ onModalChange={onModalChange}
61
+ availableBedTypes={availableBedTypes}
62
+ showModal={showModal}
63
+ handleCreateQuestion={handleCreateQuestion}
64
+ headerTitle={headerTitle}
65
+ initialData={editData}
66
+ allLocations={[]}
67
+ />
68
+ </>
69
+ );
70
+ };
71
+
72
+ export default EditBedTypeForm;
@@ -0,0 +1,80 @@
1
+ import React, { useCallback } from 'react';
2
+ import { useTranslation } from 'react-i18next';
3
+ import { showToast, showNotification, useConfig } from '@openmrs/esm-framework';
4
+ import type { BedTypeData, Mutator } from '../types';
5
+ import { useBedType } from '../bed-administration/bed-administration.resource';
6
+ import { saveBedType, useLocationsWithAdmissionTag } from '../summary/summary.resource';
7
+ import BedTypeAdministrationForm from './bed-type-admin-form.component';
8
+
9
+ interface BedTypeFormProps {
10
+ showModal: boolean;
11
+ onModalChange: (showModal: boolean) => void;
12
+ mutate: Mutator;
13
+ }
14
+
15
+ const NewBedTypeForm: React.FC<BedTypeFormProps> = ({ showModal, onModalChange, mutate }) => {
16
+ const { t } = useTranslation();
17
+ const { data: admissionLocations } = useLocationsWithAdmissionTag();
18
+ const headerTitle = t('addBedType', 'Create Bed type');
19
+ const { bedTypes } = useBedType();
20
+ const availableBedTypes = bedTypes ? bedTypes : [];
21
+
22
+ const initialData: BedTypeData = {
23
+ uuid: '',
24
+ name: '',
25
+ displayName: '',
26
+ description: '',
27
+ };
28
+
29
+ const handleCreateQuestion = useCallback(
30
+ (formData: BedTypeData) => {
31
+ const { name, displayName, description } = formData;
32
+
33
+ const bedTypePayload = {
34
+ name,
35
+ displayName,
36
+ description,
37
+ };
38
+
39
+ saveBedType({ bedTypePayload })
40
+ .then(() => {
41
+ showToast({
42
+ title: t('formCreated', 'Add bed Type'),
43
+ kind: 'success',
44
+ critical: true,
45
+ description: `Bed ${name} was created successfully.`,
46
+ });
47
+
48
+ mutate();
49
+ onModalChange(false);
50
+ })
51
+ .catch((error) => {
52
+ showNotification({
53
+ title: t('errorCreatingForm', 'Error creating bed'),
54
+ kind: 'error',
55
+ critical: true,
56
+ description: error?.message,
57
+ });
58
+ onModalChange(false);
59
+ });
60
+ onModalChange(false);
61
+ },
62
+ [onModalChange, mutate, t],
63
+ );
64
+
65
+ return (
66
+ <>
67
+ <BedTypeAdministrationForm
68
+ onModalChange={onModalChange}
69
+ allLocations={admissionLocations}
70
+ availableBedTypes={availableBedTypes}
71
+ showModal={showModal}
72
+ handleCreateQuestion={handleCreateQuestion}
73
+ headerTitle={headerTitle}
74
+ initialData={initialData}
75
+ />
76
+ </>
77
+ );
78
+ };
79
+
80
+ export default NewBedTypeForm;
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import classNames from 'classnames';
3
+ import { useLayoutType } from '@openmrs/esm-framework';
4
+ import styles from './card-header.scss';
5
+
6
+ interface CardHeaderProps {
7
+ title: string;
8
+ children: React.ReactNode;
9
+ }
10
+
11
+ export function CardHeader({ title, children }: CardHeaderProps) {
12
+ const isTablet = useLayoutType() === 'tablet';
13
+
14
+ return (
15
+ <div className={classNames(isTablet ? styles.tabletHeader : styles.desktopHeader)}>
16
+ <h4>{title}</h4>
17
+ {children}
18
+ </div>
19
+ );
20
+ }
@@ -0,0 +1,45 @@
1
+ @use '@carbon/layout';
2
+ @use '@carbon/type';
3
+ @use '@openmrs/esm-styleguide/src/vars' as *;
4
+
5
+ .desktopHeader,
6
+ .tabletHeader {
7
+ display: flex;
8
+ justify-content: space-between;
9
+ align-items: center;
10
+ padding: layout.$spacing-04 0 layout.$spacing-04 layout.$spacing-05;
11
+ background-color: $ui-background;
12
+
13
+ h4:after {
14
+ content: '';
15
+ display: block;
16
+ width: layout.$spacing-07;
17
+ padding-top: 0.188rem;
18
+ border-bottom: 0.375rem solid var(--brand-03);
19
+ }
20
+ }
21
+
22
+ .desktopHeader {
23
+ height: layout.$spacing-09;
24
+ h4 {
25
+ @include type.type-style('heading-compact-02');
26
+ color: $text-02;
27
+ }
28
+ }
29
+
30
+ .tabletHeader {
31
+ height: 4.5rem;
32
+ h4 {
33
+ @include type.type-style('heading-03');
34
+ color: $text-02;
35
+ }
36
+ }
37
+
38
+ // Overriding styles for RTL support
39
+ html[dir='rtl'] {
40
+ .desktopHeader,
41
+ .tabletHeader {
42
+ text-align: right;
43
+ padding: layout.$spacing-04 layout.$spacing-05 layout.$spacing-04 0;
44
+ }
45
+ }
@@ -1,21 +1,13 @@
1
- import { Type } from "@openmrs/esm-framework";
2
- import { boolean } from "zod";
1
+ import { Type } from '@openmrs/esm-framework';
3
2
 
4
3
  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,
4
+ admissionLocationTagName: {
5
+ _type: Type.String,
6
+ _description: 'Patients may only be admitted to inpatient care in a location with this tag',
7
+ _default: 'Admission Location',
20
8
  },
21
9
  };
10
+
11
+ export interface BedManagementConfig {
12
+ admissionLocationTagName: string;
13
+ }
@@ -1,7 +1,7 @@
1
- declare module "@carbon/react";
2
- declare module "*.css";
3
- declare module "*.scss";
4
- declare module "*.png";
5
- declare module "*.svg";
1
+ declare module '@carbon/react';
2
+ declare module '*.css';
3
+ declare module '*.scss';
4
+ declare module '*.png';
5
+ declare module '*.svg';
6
6
 
7
7
  declare type SideNavProps = object;
@@ -1,16 +1,13 @@
1
- import React from "react";
2
- import { Layer, Tile } from "@carbon/react";
3
- import styles from "./empty-state.scss";
1
+ import React from 'react';
2
+ import { Layer, Tile } from '@carbon/react';
3
+ import styles from './empty-state.scss';
4
4
 
5
5
  type EmptyStateProps = {
6
6
  msg: string;
7
7
  helper: string;
8
8
  };
9
9
 
10
- const EmptyState: React.FC<EmptyStateProps> = ({
11
- msg,
12
- helper,
13
- }: EmptyStateProps) => {
10
+ const EmptyState: React.FC<EmptyStateProps> = ({ msg, helper }: EmptyStateProps) => {
14
11
  return (
15
12
  <Layer className={styles.layer}>
16
13
  <Tile className={styles.tile}>
@@ -30,13 +27,7 @@ const EmptyState: React.FC<EmptyStateProps> = ({
30
27
  fill="#C6C6C6"
31
28
  />
32
29
  <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
- />
30
+ <circle fill="#FFF" fillRule="nonzero" cx={17.636} cy={2.314} r={1.175} />
40
31
  <path
41
32
  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
33
  fill="#F4F4F4"
@@ -50,13 +41,7 @@ const EmptyState: React.FC<EmptyStateProps> = ({
50
41
  fill="#C6C6C6"
51
42
  />
52
43
  <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
- />
44
+ <circle fill="#FFF" fillRule="nonzero" cx={40.218} cy={9.755} r={1.13} />
60
45
  </g>
61
46
  </svg>
62
47
  <p className={styles.content}>{msg}</p>