@openmrs/esm-bed-management-app 7.0.3-pre.94
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 +36 -0
- package/README.md +8 -0
- package/dist/130.js +2 -0
- package/dist/130.js.LICENSE.txt +3 -0
- package/dist/130.js.map +1 -0
- package/dist/148.js +1 -0
- package/dist/148.js.map +1 -0
- package/dist/169.js +1 -0
- package/dist/169.js.map +1 -0
- package/dist/271.js +1 -0
- package/dist/319.js +1 -0
- package/dist/460.js +1 -0
- package/dist/501.js +1 -0
- package/dist/501.js.map +1 -0
- package/dist/542.js +1 -0
- package/dist/542.js.map +1 -0
- package/dist/574.js +1 -0
- package/dist/591.js +2 -0
- package/dist/591.js.LICENSE.txt +32 -0
- package/dist/591.js.map +1 -0
- package/dist/644.js +1 -0
- package/dist/668.js +2 -0
- package/dist/668.js.LICENSE.txt +15 -0
- package/dist/668.js.map +1 -0
- package/dist/729.js +1 -0
- package/dist/729.js.map +1 -0
- package/dist/757.js +1 -0
- package/dist/766.js +2 -0
- package/dist/766.js.LICENSE.txt +35 -0
- package/dist/766.js.map +1 -0
- package/dist/784.js +2 -0
- package/dist/784.js.LICENSE.txt +9 -0
- package/dist/784.js.map +1 -0
- package/dist/788.js +1 -0
- package/dist/805.js +1 -0
- package/dist/805.js.map +1 -0
- package/dist/807.js +1 -0
- package/dist/833.js +1 -0
- package/dist/main.js +1 -0
- package/dist/main.js.map +1 -0
- package/dist/openmrs-esm-bed-management-app.js +1 -0
- package/dist/openmrs-esm-bed-management-app.js.buildmanifest.json +579 -0
- package/dist/openmrs-esm-bed-management-app.js.map +1 -0
- package/dist/routes.json +1 -0
- package/jest.config.js +3 -0
- package/package.json +55 -0
- package/src/__mocks__/react-i18next.js +50 -0
- package/src/admin-card-link.component.tsx +24 -0
- package/src/bed-administration/bed-administration-form.component.tsx +292 -0
- package/src/bed-administration/bed-administration-form.scss +0 -0
- package/src/bed-administration/bed-administration-table.component.tsx +258 -0
- package/src/bed-administration/bed-administration-table.scss +112 -0
- package/src/bed-administration/bed-administration-types.ts +20 -0
- package/src/bed-administration/bed-administration.resource.ts +57 -0
- package/src/bed-administration/edit-bed-form.component.tsx +89 -0
- package/src/bed-administration/new-bed-form.component.tsx +96 -0
- package/src/bed-tag/bed-tag-administration-table.component.tsx +192 -0
- package/src/bed-tag/bed-tags-admin-form.component.tsx +127 -0
- package/src/bed-tag/edit-tag-form.component.tsx +72 -0
- package/src/bed-tag/new-tag-form.component.tsx +76 -0
- package/src/bed-type/bed-type-admin-form.component.tsx +166 -0
- package/src/bed-type/bed-type-administration-table.component.tsx +198 -0
- package/src/bed-type/edit-bed-type.component.tsx +72 -0
- package/src/bed-type/new-bed-type-form.component.tsx +80 -0
- package/src/card-header/card-header.component.tsx +20 -0
- package/src/card-header/card-header.scss +45 -0
- package/src/config-schema.ts +13 -0
- package/src/declarations.d.ts +7 -0
- package/src/empty-state/empty-state.component.tsx +54 -0
- package/src/empty-state/empty-state.scss +62 -0
- package/src/header/header.component.tsx +42 -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 +51 -0
- package/src/left-panel/left-panel.component.tsx +23 -0
- package/src/left-panel/left-panel.scss +42 -0
- package/src/left-panel-link.component.tsx +39 -0
- package/src/root.component.tsx +39 -0
- package/src/root.scss +11 -0
- package/src/routes.json +56 -0
- package/src/setup-tests.ts +1 -0
- package/src/summary/summary.component.tsx +60 -0
- package/src/summary/summary.resource.ts +232 -0
- package/src/summary/summary.scss +74 -0
- package/src/types.ts +173 -0
- package/src/ward-card/ward-card.component.tsx +34 -0
- package/src/ward-card/ward-card.scss +51 -0
- package/src/ward-with-beds/ward-with-beds.component.tsx +167 -0
- package/src/ward-with-beds/ward-with-beds.scss +27 -0
- package/translations/am.json +52 -0
- package/translations/ar.json +52 -0
- package/translations/en.json +52 -0
- package/translations/es.json +52 -0
- package/translations/fr.json +52 -0
- package/translations/he.json +52 -0
- package/translations/km.json +52 -0
- package/translations/zh.json +52 -0
- package/translations/zh_CN.json +52 -0
- package/tsconfig.json +5 -0
- package/webpack.config.js +1 -0
|
@@ -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 { editBedTag, useBedTag } from '../summary/summary.resource';
|
|
6
|
+
import { type BedTagDataAdministration } from '../bed-administration/bed-administration-types';
|
|
7
|
+
import BedTagsAdministrationForm from './bed-tags-admin-form.component';
|
|
8
|
+
import { type BedTagData, type Mutator } from '../types';
|
|
9
|
+
|
|
10
|
+
interface EditBedTagFormProps {
|
|
11
|
+
showModal: boolean;
|
|
12
|
+
onModalChange: (showModal: boolean) => void;
|
|
13
|
+
editData: BedTagData;
|
|
14
|
+
mutate: Mutator;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const EditBedTagForm: React.FC<EditBedTagFormProps> = ({ showModal, onModalChange, editData, mutate }) => {
|
|
18
|
+
const { t } = useTranslation();
|
|
19
|
+
|
|
20
|
+
const headerTitle = t('editBed', 'Edit Tag');
|
|
21
|
+
const { bedTypeData } = useBedTag();
|
|
22
|
+
const availableBedTypes = bedTypeData ? bedTypeData : [];
|
|
23
|
+
|
|
24
|
+
const handleCreateQuestion = useCallback(
|
|
25
|
+
(formData: BedTagDataAdministration) => {
|
|
26
|
+
const bedUuid = editData.uuid;
|
|
27
|
+
const { name } = formData;
|
|
28
|
+
const bedTagPayload = {
|
|
29
|
+
name,
|
|
30
|
+
};
|
|
31
|
+
editBedTag({ bedTagPayload, bedTagId: bedUuid })
|
|
32
|
+
.then(() => {
|
|
33
|
+
showToast({
|
|
34
|
+
title: t('formSaved', 'Bed Tag'),
|
|
35
|
+
kind: 'success',
|
|
36
|
+
critical: true,
|
|
37
|
+
description: bedTagPayload.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
|
+
<BedTagsAdministrationForm
|
|
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 EditBedTagForm;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
3
|
+
import { showToast, showNotification, useConfig } from '@openmrs/esm-framework';
|
|
4
|
+
import { useBedType } from '../bed-administration/bed-administration.resource';
|
|
5
|
+
import BedTagsAdministrationForm from './bed-tags-admin-form.component';
|
|
6
|
+
import { saveBedTag, useLocationsWithAdmissionTag } from '../summary/summary.resource';
|
|
7
|
+
import { type BedTagData, type Mutator } from '../types';
|
|
8
|
+
|
|
9
|
+
interface BedTagFormProps {
|
|
10
|
+
showModal: boolean;
|
|
11
|
+
onModalChange: (showModal: boolean) => void;
|
|
12
|
+
mutate: () => any;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const NewTagForm: React.FC<BedTagFormProps> = ({ showModal, onModalChange, mutate }) => {
|
|
16
|
+
const { t } = useTranslation();
|
|
17
|
+
const { data: admissionLocations } = useLocationsWithAdmissionTag();
|
|
18
|
+
const headerTitle = t('addBedTag', 'Create Bed Tag');
|
|
19
|
+
const { bedTypes } = useBedType();
|
|
20
|
+
const availableBedTypes = bedTypes ? bedTypes : [];
|
|
21
|
+
|
|
22
|
+
const initialData: BedTagData = {
|
|
23
|
+
uuid: '',
|
|
24
|
+
name: '',
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const handleCreateQuestion = useCallback(
|
|
28
|
+
(formData: BedTagData) => {
|
|
29
|
+
const { name } = formData;
|
|
30
|
+
|
|
31
|
+
const bedTagPayload = {
|
|
32
|
+
name,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
saveBedTag({ bedTagPayload })
|
|
36
|
+
.then(() => {
|
|
37
|
+
showToast({
|
|
38
|
+
title: t('formCreated', 'Add Bed Tag'),
|
|
39
|
+
kind: 'success',
|
|
40
|
+
critical: true,
|
|
41
|
+
description: `Tag ${name} was created successfully.`,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
mutate();
|
|
45
|
+
onModalChange(false);
|
|
46
|
+
})
|
|
47
|
+
.catch((error) => {
|
|
48
|
+
showNotification({
|
|
49
|
+
title: t('errorCreatingForm', 'Error creating bed'),
|
|
50
|
+
kind: 'error',
|
|
51
|
+
critical: true,
|
|
52
|
+
description: error?.message,
|
|
53
|
+
});
|
|
54
|
+
onModalChange(false);
|
|
55
|
+
});
|
|
56
|
+
onModalChange(false);
|
|
57
|
+
},
|
|
58
|
+
[onModalChange, mutate, t],
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<>
|
|
63
|
+
<BedTagsAdministrationForm
|
|
64
|
+
onModalChange={onModalChange}
|
|
65
|
+
allLocations={admissionLocations}
|
|
66
|
+
availableBedTypes={availableBedTypes}
|
|
67
|
+
showModal={showModal}
|
|
68
|
+
handleCreateQuestion={handleCreateQuestion}
|
|
69
|
+
headerTitle={headerTitle}
|
|
70
|
+
initialData={initialData}
|
|
71
|
+
/>
|
|
72
|
+
</>
|
|
73
|
+
);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export default NewTagForm;
|
|
@@ -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 { 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
|
+
<Form onSubmit={handleSubmit(onSubmit, onError)}>
|
|
85
|
+
<ModalBody hasScrollingContent>
|
|
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
|
+
</ModalBody>
|
|
153
|
+
<ModalFooter>
|
|
154
|
+
<Button onClick={() => onModalChange(false)} kind="secondary">
|
|
155
|
+
{t('cancel', 'Cancel')}
|
|
156
|
+
</Button>
|
|
157
|
+
<Button disabled={!isDirty} type="submit">
|
|
158
|
+
<span>{t('save', 'Save')}</span>
|
|
159
|
+
</Button>
|
|
160
|
+
</ModalFooter>
|
|
161
|
+
</Form>
|
|
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
|
+
}
|