@openmrs/esm-ward-app 9.2.1-pre.7254 → 9.2.1-pre.7261

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 (111) hide show
  1. package/.turbo/turbo-build.log +8 -8
  2. package/dist/1741.js +1 -1
  3. package/dist/1741.js.map +1 -1
  4. package/dist/1987.js +1 -0
  5. package/dist/1987.js.map +1 -0
  6. package/dist/2216.js +1 -0
  7. package/dist/2216.js.map +1 -0
  8. package/dist/2728.js +1 -1
  9. package/dist/2728.js.map +1 -1
  10. package/dist/283.js +1 -1
  11. package/dist/283.js.map +1 -1
  12. package/dist/2948.js +1 -1
  13. package/dist/2948.js.map +1 -1
  14. package/dist/3365.js +1 -1
  15. package/dist/3365.js.map +1 -1
  16. package/dist/3413.js +1 -1
  17. package/dist/3413.js.map +1 -1
  18. package/dist/3673.js +1 -0
  19. package/dist/3673.js.map +1 -0
  20. package/dist/3982.js +1 -1
  21. package/dist/3982.js.map +1 -1
  22. package/dist/4189.js +1 -0
  23. package/dist/4189.js.map +1 -0
  24. package/dist/4300.js +1 -1
  25. package/dist/5603.js +1 -0
  26. package/dist/5603.js.map +1 -0
  27. package/dist/581.js +1 -1
  28. package/dist/581.js.map +1 -1
  29. package/dist/7179.js +1 -1
  30. package/dist/7179.js.map +1 -1
  31. package/dist/7512.js +1 -1
  32. package/dist/7512.js.map +1 -1
  33. package/dist/7661.js +1 -1
  34. package/dist/7661.js.map +1 -1
  35. package/dist/8501.js +1 -1
  36. package/dist/8501.js.map +1 -1
  37. package/dist/8522.js +1 -1
  38. package/dist/8522.js.map +1 -1
  39. package/dist/8610.js +1 -1
  40. package/dist/8610.js.map +1 -1
  41. package/dist/89.js +2 -1
  42. package/dist/89.js.map +1 -1
  43. package/dist/9117.js +1 -1
  44. package/dist/9117.js.map +1 -1
  45. package/dist/917.js +1 -0
  46. package/dist/917.js.map +1 -0
  47. package/dist/9756.js +1 -0
  48. package/dist/9756.js.map +1 -0
  49. package/dist/main.js +1 -1
  50. package/dist/main.js.map +1 -1
  51. package/dist/openmrs-esm-ward-app.js +1 -1
  52. package/dist/openmrs-esm-ward-app.js.buildmanifest.json +226 -177
  53. package/dist/openmrs-esm-ward-app.js.map +1 -1
  54. package/dist/routes.json +1 -1
  55. package/package.json +1 -1
  56. package/src/action-menu-buttons/clinical-forms-workspace-siderail.component.tsx +16 -24
  57. package/src/action-menu-buttons/discharge-workspace-siderail.component.tsx +6 -6
  58. package/src/action-menu-buttons/order-basket-action-button.component.tsx +31 -0
  59. package/src/action-menu-buttons/transfer-workspace-siderail.component.tsx +7 -18
  60. package/src/hooks/useEmrConfiguration.ts +19 -19
  61. package/src/index.ts +14 -16
  62. package/src/routes.json +127 -80
  63. package/src/types/index.ts +7 -3
  64. package/src/ward-patient-card/row-elements/ward-patient-pending-transfer.component.tsx +9 -4
  65. package/src/ward-patient-card/ward-patient-card.component.tsx +3 -11
  66. package/src/ward-view-header/admission-requests-bar.component.tsx +10 -6
  67. package/src/ward-view-header/admission-requests-bar.test.tsx +3 -3
  68. package/src/ward-workspace/admission-request-card/admission-request-card-actions.component.tsx +8 -6
  69. package/src/ward-workspace/admission-request-workspace/admission-requests-action-button.extension.tsx +6 -7
  70. package/src/ward-workspace/admission-request-workspace/admission-requests-empty-state.component.tsx +16 -29
  71. package/src/ward-workspace/admission-request-workspace/admission-requests-workspace.test.tsx +23 -8
  72. package/src/ward-workspace/admission-request-workspace/admission-requests.workspace.tsx +28 -28
  73. package/src/ward-workspace/admit-patient-button.component.tsx +3 -2
  74. package/src/ward-workspace/admit-patient-form-workspace/admit-patient-form.test.tsx +17 -16
  75. package/src/ward-workspace/admit-patient-form-workspace/admit-patient-form.workspace.tsx +72 -69
  76. package/src/ward-workspace/cancel-admission-request-workspace/cancel-admission-request.component.tsx +176 -0
  77. package/src/ward-workspace/cancel-admission-request-workspace/cancel-admission-request.test.tsx +11 -9
  78. package/src/ward-workspace/cancel-admission-request-workspace/cancel-admission-request.workspace.tsx +17 -167
  79. package/src/ward-workspace/cancel-admission-request-workspace/ward-patient-cancel-admission-request.workspace.tsx +16 -0
  80. package/src/ward-workspace/create-admission-encounter/create-admission-encounter-action-button.extension.tsx +23 -34
  81. package/src/ward-workspace/create-admission-encounter/create-admission-encounter.test.tsx +9 -4
  82. package/src/ward-workspace/create-admission-encounter/create-admission-encounter.workspace.tsx +39 -19
  83. package/src/ward-workspace/patient-details/ward-patient-action-button.component.tsx +17 -0
  84. package/src/ward-workspace/patient-details/ward-patient.workspace.tsx +27 -7
  85. package/src/ward-workspace/patient-discharge/patient-discharge.workspace.tsx +46 -40
  86. package/src/ward-workspace/patient-transfer-bed-swap/patient-admit-or-transfer-request-form.component.tsx +21 -13
  87. package/src/ward-workspace/patient-transfer-bed-swap/patient-bed-swap-form.component.tsx +10 -14
  88. package/src/ward-workspace/patient-transfer-bed-swap/patient-transfer-swap.workspace.tsx +42 -24
  89. package/src/ward-workspace/patient-transfer-request-workspace/patient-transfer-request.workspace.tsx +22 -8
  90. package/src/ward-workspace/ward-patient-notes/notes-action-button.component.tsx +17 -0
  91. package/src/ward-workspace/ward-patient-notes/{form/notes-form.scss → notes.scss} +0 -1
  92. package/src/ward-workspace/ward-patient-notes/notes.test.tsx +134 -0
  93. package/src/ward-workspace/ward-patient-notes/notes.workspace.tsx +174 -13
  94. package/translations/en.json +3 -1
  95. package/dist/1663.js +0 -1
  96. package/dist/1663.js.map +0 -1
  97. package/dist/2557.js +0 -1
  98. package/dist/2557.js.map +0 -1
  99. package/dist/7232.js +0 -2
  100. package/dist/7232.js.map +0 -1
  101. package/dist/7886.js +0 -1
  102. package/dist/7886.js.map +0 -1
  103. package/dist/9045.js +0 -1
  104. package/dist/9045.js.map +0 -1
  105. package/src/ward-workspace/admission-request-workspace/admission-requests-context.ts +0 -20
  106. package/src/ward-workspace/patient-clinical-forms-workspace/patient-clinical-forms.workspace.tsx +0 -29
  107. package/src/ward-workspace/patient-details/ward-patient-action-button.extension.tsx +0 -18
  108. package/src/ward-workspace/ward-patient-notes/form/notes-form.component.tsx +0 -186
  109. package/src/ward-workspace/ward-patient-notes/form/notes-form.test.tsx +0 -116
  110. package/src/ward-workspace/ward-patient-notes/notes-action-button.extension.tsx +0 -18
  111. /package/dist/{7232.js.LICENSE.txt → 89.js.LICENSE.txt} +0 -0
@@ -1,167 +1,17 @@
1
- import React, { useCallback, useEffect, useMemo, useState } from 'react';
2
- import { Button, ButtonSet, Form, InlineNotification, TextArea } from '@carbon/react';
3
- import classNames from 'classnames';
4
- import { zodResolver } from '@hookform/resolvers/zod';
5
- import { Controller, useForm } from 'react-hook-form';
6
- import { useTranslation } from 'react-i18next';
7
- import { z } from 'zod';
8
- import { getCoreTranslation, ResponsiveWrapper, showSnackbar, useAppContext } from '@openmrs/esm-framework';
9
- import type { ObsPayload, WardPatientWorkspaceProps, WardViewContext } from '../../types';
10
- import { useCreateEncounter } from '../../ward.resource';
11
- import WardPatientWorkspaceBanner from '../patient-banner/patient-banner.component';
12
- import styles from './cancel-admission-request.scss';
13
-
14
- export default function CancelAdmissionRequestWorkspace({
15
- closeWorkspaceWithSavedChanges,
16
- wardPatient,
17
- promptBeforeClosing,
18
- }: WardPatientWorkspaceProps) {
19
- const { patient, visit } = wardPatient ?? {};
20
- const { t } = useTranslation();
21
- const [isSubmitting, setIsSubmitting] = useState(false);
22
- const { createEncounter, emrConfiguration, isLoadingEmrConfiguration, errorFetchingEmrConfiguration } =
23
- useCreateEncounter();
24
- const { wardPatientGroupDetails } = useAppContext<WardViewContext>('ward-view-context') ?? {};
25
-
26
- const zodSchema = useMemo(
27
- () =>
28
- z.object({
29
- note: z
30
- .string()
31
- .trim()
32
- .min(1, {
33
- message: t(
34
- 'notesRequiredForCancellingRequest',
35
- 'Notes required for cancelling admission or transfer request',
36
- ),
37
- }),
38
- }),
39
- [t],
40
- );
41
-
42
- type FormValues = z.infer<typeof zodSchema>;
43
-
44
- const {
45
- formState: { errors, isDirty },
46
- control,
47
- handleSubmit,
48
- } = useForm<FormValues>({
49
- resolver: zodResolver(zodSchema),
50
- defaultValues: { note: '' },
51
- });
52
-
53
- useEffect(() => {
54
- promptBeforeClosing(() => isDirty);
55
- return () => promptBeforeClosing(null);
56
- }, [isDirty, promptBeforeClosing]);
57
-
58
- const onSubmit = useCallback(
59
- (values: FormValues) => {
60
- setIsSubmitting(true);
61
- const obs: Array<ObsPayload> = [
62
- {
63
- concept: emrConfiguration?.consultFreeTextCommentsConcept?.uuid,
64
- value: values.note,
65
- },
66
- {
67
- concept: emrConfiguration?.admissionDecisionConcept?.uuid,
68
- value: {
69
- uuid: emrConfiguration?.denyAdmissionConcept?.uuid,
70
- },
71
- },
72
- ];
73
-
74
- createEncounter(patient, emrConfiguration?.cancelADTRequestEncounterType, visit?.uuid, obs)
75
- .then(() => {
76
- showSnackbar({
77
- title: t('admissionRequestCancelled', 'Admission request cancelled.'),
78
- kind: 'success',
79
- });
80
- })
81
- .catch((err: Error) => {
82
- showSnackbar({
83
- title: t('errorCancellingAdmissionRequest', 'Error cancelling admission request'),
84
- subtitle: err.message,
85
- kind: 'error',
86
- });
87
- })
88
- .finally(() => {
89
- setIsSubmitting(false);
90
- closeWorkspaceWithSavedChanges();
91
- wardPatientGroupDetails.mutate();
92
- });
93
- },
94
- [
95
- emrConfiguration?.consultFreeTextCommentsConcept?.uuid,
96
- emrConfiguration?.admissionDecisionConcept?.uuid,
97
- emrConfiguration?.denyAdmissionConcept?.uuid,
98
- emrConfiguration?.cancelADTRequestEncounterType,
99
- createEncounter,
100
- patient,
101
- t,
102
- closeWorkspaceWithSavedChanges,
103
- wardPatientGroupDetails,
104
- visit?.uuid,
105
- ],
106
- );
107
-
108
- const onError = useCallback(() => {
109
- setIsSubmitting(false);
110
- }, []);
111
-
112
- if (!wardPatientGroupDetails) return null;
113
-
114
- return (
115
- <div className={styles.flexWrapper}>
116
- <WardPatientWorkspaceBanner wardPatient={wardPatient} />
117
- <Form
118
- onSubmit={handleSubmit(onSubmit, onError)}
119
- className={classNames(styles.formContainer, styles.workspaceContent)}>
120
- <div>
121
- {errorFetchingEmrConfiguration && (
122
- <div className={styles.formError}>
123
- <InlineNotification
124
- kind="error"
125
- title={t('somePartsOfTheFormDidntLoad', "Some parts of the form didn't load")}
126
- subtitle={t(
127
- 'fetchingEmrConfigurationFailed',
128
- 'Fetching EMR configuration failed. Try refreshing the page or contact your system administrator.',
129
- )}
130
- lowContrast
131
- hideCloseButton
132
- />
133
- </div>
134
- )}
135
- <div className={styles.field}>
136
- <Controller
137
- name="note"
138
- control={control}
139
- render={({ field, fieldState: { error } }) => (
140
- <ResponsiveWrapper>
141
- <TextArea
142
- {...field}
143
- id="clinical-notes"
144
- labelText={t('clinicalNotes', 'Clinical notes')}
145
- invalid={!!error}
146
- invalidText={error?.message}
147
- />
148
- </ResponsiveWrapper>
149
- )}
150
- />
151
- </div>
152
- </div>
153
- <ButtonSet className={styles.buttonSet}>
154
- <Button size="xl" kind="secondary" onClick={closeWorkspaceWithSavedChanges}>
155
- {getCoreTranslation('cancel')}
156
- </Button>
157
- <Button
158
- type="submit"
159
- size="xl"
160
- disabled={isLoadingEmrConfiguration || isSubmitting || errorFetchingEmrConfiguration || !patient}>
161
- {getCoreTranslation('save')}
162
- </Button>
163
- </ButtonSet>
164
- </Form>
165
- </div>
166
- );
167
- }
1
+ import React from 'react';
2
+ import type { WardPatientWorkspaceProps } from '../../types';
3
+ import CancelAdmissionRequest from './cancel-admission-request.component';
4
+ import { type Workspace2DefinitionProps } from '@openmrs/esm-framework/src';
5
+
6
+ /**
7
+ * This is the workspace that is rendered when clicking on the 'Cancel' button on a AdmissionRequestCard
8
+ * for a patient with a pending admission / transfer request to the current location
9
+ */
10
+ const CancelAdmissionRequestWorkspace: React.FC<Workspace2DefinitionProps<WardPatientWorkspaceProps, {}, {}>> = ({
11
+ closeWorkspace,
12
+ workspaceProps: { wardPatient },
13
+ }) => {
14
+ return <CancelAdmissionRequest closeWorkspace={closeWorkspace} wardPatient={wardPatient} />;
15
+ };
16
+
17
+ export default CancelAdmissionRequestWorkspace;
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import type { WardPatientWorkspaceDefinition } from '../../types';
3
+ import CancelAdmissionRequest from './cancel-admission-request.component';
4
+
5
+ /**
6
+ * This is the workspace that is rendered when clicking on the 'X' button on a Patient Card
7
+ * for a patient with a pending transfer request to a different location
8
+ */
9
+ const WardPatientCancelAdmissionRequestWorkspace: React.FC<WardPatientWorkspaceDefinition> = ({
10
+ closeWorkspace,
11
+ groupProps: { wardPatient },
12
+ }) => {
13
+ return <CancelAdmissionRequest closeWorkspace={closeWorkspace} wardPatient={wardPatient} />;
14
+ };
15
+
16
+ export default WardPatientCancelAdmissionRequestWorkspace;
@@ -1,44 +1,33 @@
1
- import React, { useState } from 'react';
1
+ import React from 'react';
2
2
  import { useTranslation } from 'react-i18next';
3
- import { ActionMenuButton, AddIcon, launchWorkspace } from '@openmrs/esm-framework';
4
- import { type CreateAdmissionEncounterWorkspaceProps } from './create-admission-encounter.workspace';
3
+ import { ActionMenuButton2, AddIcon, type Workspace2DefinitionProps } from '@openmrs/esm-framework';
5
4
 
6
5
  function CreateAdmissionRequestActionButton() {
7
6
  const { t } = useTranslation();
8
7
 
9
- // TODO: this is an attempt to save the previous search term for the
10
- // "Back to patient search" button, but it doesn't work. See:
11
- // https://openmrs.atlassian.net/browse/O3-4300
12
- const [searchTerm, setSearchTerm] = useState<string>('');
13
-
14
- // See PatientSearchWorkspaceProps in patient-search-app
15
- const workspaceProps = {
16
- initialQuery: searchTerm,
17
- nonNavigationSelectPatientAction: async (patientUuid) => {
18
- launchWorkspace<CreateAdmissionEncounterWorkspaceProps>('create-admission-encounter-workspace', {
19
- patientUuid,
20
- handleReturnToSearchList: launchSearchWorkspace,
21
- });
22
- },
23
- handleSearchTermUpdated: (value: string) => {
24
- setSearchTerm(value);
25
- },
26
- };
27
-
28
- const launchSearchWorkspace = () => {
29
- launchWorkspace('patient-search-workspace', {
30
- ...workspaceProps,
31
- workspaceTitle: t('addPatientToWard', 'Add patient to ward'),
32
- });
33
- };
34
-
35
8
  return (
36
- <ActionMenuButton
37
- getIcon={(props) => <AddIcon {...props} />}
9
+ <ActionMenuButton2
10
+ icon={(props) => <AddIcon {...props} />}
38
11
  label={t('addPatientToWard', 'Add patient to ward')}
39
- iconDescription={t('addPatientToWard', 'Add patient to ward')}
40
- handler={launchSearchWorkspace}
41
- type={'patient-search-workspace'}
12
+ workspaceToLaunch={{
13
+ workspaceName: 'ward-app-patient-search-workspace',
14
+ workspaceProps: {
15
+ workspaceTitle: t('addPatientToQueue', 'Add patient to queue'),
16
+ onPatientSelected(
17
+ patientUuid: string,
18
+ patient: fhir.Patient,
19
+ launchChildWorkspace: Workspace2DefinitionProps['launchChildWorkspace'],
20
+ closeWorkspace: Workspace2DefinitionProps['launchChildWorkspace'],
21
+ ) {
22
+ launchChildWorkspace('create-admission-encounter-workspace', {
23
+ selectedPatientUuid: patient.id,
24
+ });
25
+ },
26
+ },
27
+ windowProps: {
28
+ startVisitWorkspaceName: 'ward-app-start-visit-workspace',
29
+ },
30
+ }}
42
31
  />
43
32
  );
44
33
  }
@@ -231,11 +231,16 @@ describe('CreateAdmissionEncounterWorkspace', () => {
231
231
  function renderCreateAdmissionEncounterWorkspace(patentUuid: string) {
232
232
  renderWithSwr(
233
233
  <CreateAdmissionEncounterWorkspace
234
- patientUuid={patentUuid}
235
234
  closeWorkspace={jest.fn()}
236
- promptBeforeClosing={jest.fn()}
237
- closeWorkspaceWithSavedChanges={jest.fn()}
238
- setTitle={jest.fn()}
235
+ launchChildWorkspace={jest.fn()}
236
+ workspaceProps={{
237
+ selectedPatientUuid: patentUuid,
238
+ }}
239
+ windowProps={{
240
+ startVisitWorkspaceName: '',
241
+ }}
242
+ groupProps={undefined}
243
+ workspaceName={''}
239
244
  />,
240
245
  );
241
246
  }
@@ -1,7 +1,14 @@
1
1
  import React from 'react';
2
2
  import { useTranslation } from 'react-i18next';
3
3
  import { Button, InlineNotification, SkeletonText } from '@carbon/react';
4
- import { ArrowLeftIcon, type DefaultWorkspaceProps, useVisit } from '@openmrs/esm-framework';
4
+ import {
5
+ ArrowLeftIcon,
6
+ closeWorkspaceGroup2,
7
+ type DefaultWorkspaceProps,
8
+ useVisit,
9
+ Workspace2,
10
+ type Workspace2DefinitionProps,
11
+ } from '@openmrs/esm-framework';
5
12
  import { useAssignedBedByPatient } from '../../hooks/useAssignedBedByPatient';
6
13
  import { useInpatientAdmissionByPatients } from '../../hooks/useInpatientAdmissionByPatients';
7
14
  import { useInpatientRequestByPatients } from '../../hooks/useInpatientRequestByPatients';
@@ -12,8 +19,7 @@ import AdmitPatientButton from '../admit-patient-button.component';
12
19
  import WardPatientWorkspaceBanner from '../patient-banner/patient-banner.component';
13
20
 
14
21
  export interface CreateAdmissionEncounterWorkspaceProps {
15
- patientUuid: string;
16
- handleReturnToSearchList?: () => void;
22
+ selectedPatientUuid: string;
17
23
  }
18
24
 
19
25
  /**
@@ -21,36 +27,45 @@ export interface CreateAdmissionEncounterWorkspaceProps {
21
27
  * from the workspace triggered by the "Add patient to ward" button.
22
28
  * It directly admits them to the current ward locations
23
29
  */
24
- const CreateAdmissionEncounterWorkspace: React.FC<CreateAdmissionEncounterWorkspaceProps & DefaultWorkspaceProps> = ({
25
- patientUuid,
26
- handleReturnToSearchList,
27
- closeWorkspaceWithSavedChanges,
28
- }) => {
30
+ const CreateAdmissionEncounterWorkspace: React.FC<
31
+ Workspace2DefinitionProps<
32
+ CreateAdmissionEncounterWorkspaceProps,
33
+ {
34
+ startVisitWorkspaceName: string;
35
+ },
36
+ {}
37
+ >
38
+ > = ({ closeWorkspace, workspaceProps: { selectedPatientUuid } }) => {
29
39
  const { location } = useWardLocation();
30
- const { patient, isLoading: isLoadingPatient, error: errorLoadingPatient } = useRestPatient(patientUuid);
31
- const { activeVisit, isLoading: isLoadingVisit, error: errorLoadingVisit } = useVisit(patientUuid);
40
+ const { patient, isLoading: isLoadingPatient, error: errorLoadingPatient } = useRestPatient(selectedPatientUuid);
41
+ const { activeVisit, isLoading: isLoadingVisit, error: errorLoadingVisit } = useVisit(selectedPatientUuid);
32
42
  const { t } = useTranslation();
33
- const { data: bedData, isLoading: isLoadingBed, error: errorLoadingBed } = useAssignedBedByPatient(patientUuid);
43
+ const {
44
+ data: bedData,
45
+ isLoading: isLoadingBed,
46
+ error: errorLoadingBed,
47
+ } = useAssignedBedByPatient(selectedPatientUuid);
34
48
  const {
35
49
  data: inpatientAdmissions,
36
50
  isLoading: isLoadingInpatientAdmission,
37
51
  error: errorInpatientAdmission,
38
- } = useInpatientAdmissionByPatients([patientUuid]);
52
+ } = useInpatientAdmissionByPatients([selectedPatientUuid]);
39
53
  const {
40
54
  inpatientRequests,
41
55
  isLoading: isLoadingInpatientRequest,
42
56
  error: errorInpatientRequests,
43
- } = useInpatientRequestByPatients([patientUuid]);
57
+ } = useInpatientRequestByPatients([selectedPatientUuid]);
44
58
 
45
59
  const isLoading =
46
60
  isLoadingPatient || isLoadingVisit || isLoadingBed || isLoadingInpatientAdmission || isLoadingInpatientRequest;
47
61
  const hasError =
48
62
  errorLoadingPatient || errorLoadingVisit || errorLoadingBed || errorInpatientAdmission || errorInpatientRequests;
49
63
 
64
+ let content: JSX.Element = null;
50
65
  if (isLoading) {
51
- return <SkeletonText />;
66
+ content = <SkeletonText />;
52
67
  } else if (hasError) {
53
- return (
68
+ content = (
54
69
  <div>
55
70
  <InlineNotification
56
71
  kind="error"
@@ -62,7 +77,7 @@ const CreateAdmissionEncounterWorkspace: React.FC<CreateAdmissionEncounterWorksp
62
77
  renderIcon={(props) => <ArrowLeftIcon size={24} {...props} />}
63
78
  iconDescription={t('backToSearchResults', 'Back to search results')}
64
79
  size="sm"
65
- onClick={() => handleReturnToSearchList?.()}>
80
+ onClick={() => closeWorkspace()}>
66
81
  <span>{t('backToSearchResults', 'Back to search results')}</span>
67
82
  </Button>
68
83
  </div>
@@ -86,7 +101,7 @@ const CreateAdmissionEncounterWorkspace: React.FC<CreateAdmissionEncounterWorksp
86
101
  inpatientAdmission: inpatientAdmissions[0],
87
102
  inpatientRequest: null,
88
103
  };
89
- return (
104
+ content = (
90
105
  <div>
91
106
  <WardPatientWorkspaceBanner wardPatient={wardPatient} />
92
107
  {activeVisit ? (
@@ -126,7 +141,10 @@ const CreateAdmissionEncounterWorkspace: React.FC<CreateAdmissionEncounterWorksp
126
141
  <AdmitPatientButton
127
142
  wardPatient={wardPatient}
128
143
  dispositionType={inpatientAdmissions[0] ? 'TRANSFER' : 'ADMIT'}
129
- onAdmitPatientSuccess={() => closeWorkspaceWithSavedChanges()}
144
+ onAdmitPatientSuccess={async () => {
145
+ await closeWorkspace({ discardUnsavedChanges: true });
146
+ closeWorkspaceGroup2();
147
+ }}
130
148
  disabled={isAdmittedToCurrentLocation}
131
149
  />
132
150
  </div>
@@ -141,12 +159,14 @@ const CreateAdmissionEncounterWorkspace: React.FC<CreateAdmissionEncounterWorksp
141
159
  renderIcon={(props) => <ArrowLeftIcon size={24} {...props} />}
142
160
  iconDescription={t('backToSearchResults', 'Back to search results')}
143
161
  size="sm"
144
- onClick={() => handleReturnToSearchList?.()}>
162
+ onClick={() => closeWorkspace()}>
145
163
  <span>{t('backToSearchResults', 'Back to search results')}</span>
146
164
  </Button>
147
165
  </div>
148
166
  );
149
167
  }
168
+
169
+ return <Workspace2 title={t('admitPatient', 'Admit patient')}>{content}</Workspace2>;
150
170
  };
151
171
 
152
172
  export default CreateAdmissionEncounterWorkspace;
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import { useTranslation } from 'react-i18next';
3
+ import { ActionMenuButton2, UserAvatarIcon } from '@openmrs/esm-framework';
4
+
5
+ export default function WardPatientActionButton() {
6
+ const { t } = useTranslation();
7
+
8
+ return (
9
+ <ActionMenuButton2
10
+ icon={(props) => <UserAvatarIcon {...props} />}
11
+ label={t('Patient', 'patient')}
12
+ workspaceToLaunch={{
13
+ workspaceName: 'ward-patient-workspace',
14
+ }}
15
+ />
16
+ );
17
+ }
@@ -1,20 +1,40 @@
1
- import { attach, ExtensionSlot, useConfig } from '@openmrs/esm-framework';
1
+ import { attach, ExtensionSlot, useConfig, Workspace2 } from '@openmrs/esm-framework';
2
2
  import React from 'react';
3
- import { type WardPatientWorkspaceProps } from '../../types';
3
+ import { type WardPatientWorkspaceDefinition } from '../../types';
4
4
  import WardPatientWorkspaceBanner from '../patient-banner/patient-banner.component';
5
5
  import styles from './ward-patient.style.scss';
6
6
  import { type WardConfigObject } from '../../config-schema';
7
7
  import classNames from 'classnames';
8
+ import { useTranslation } from 'react-i18next';
8
9
 
9
10
  attach('ward-patient-workspace-header-slot', 'patient-vitals-info');
10
11
 
11
- export default function WardPatientWorkspace({ wardPatient }: WardPatientWorkspaceProps) {
12
- const { patient } = wardPatient ?? {};
12
+ export default function WardPatientWorkspace({
13
+ groupProps: { wardPatient },
14
+ launchChildWorkspace,
15
+ }: WardPatientWorkspaceDefinition) {
16
+ const { t } = useTranslation();
17
+ const { patient, visit } = wardPatient ?? {};
13
18
  const { hideWorkspaceVitalsLinks } = useConfig<WardConfigObject>();
14
- const extensionSlotState = { patient, patientUuid: patient?.uuid, hideLinks: hideWorkspaceVitalsLinks };
19
+ const extensionSlotState = {
20
+ patient,
21
+ patientUuid: patient?.uuid,
22
+ hideLinks: hideWorkspaceVitalsLinks,
23
+ visitContext: visit,
24
+ launchCustomVitalsForm: () => {
25
+ launchChildWorkspace('ward-patient-vitals-workspace', {
26
+ patientUuid: patient.uuid,
27
+ patient: {
28
+ id: patient.uuid,
29
+ birthDate: patient.person?.birthdate,
30
+ } as fhir.Patient,
31
+ visitContext: visit,
32
+ });
33
+ },
34
+ };
15
35
 
16
36
  return (
17
- <>
37
+ <Workspace2 title={t('wardPatient', 'Ward patient')}>
18
38
  {wardPatient && (
19
39
  <div className={classNames(styles.workspaceContainer, styles.patientWorkspace)}>
20
40
  <WardPatientWorkspaceBanner {...{ wardPatient }} />
@@ -26,6 +46,6 @@ export default function WardPatientWorkspace({ wardPatient }: WardPatientWorkspa
26
46
  />
27
47
  </div>
28
48
  )}
29
- </>
49
+ </Workspace2>
30
50
  );
31
51
  }
@@ -2,14 +2,16 @@ import React, { useCallback, useState } from 'react';
2
2
  import { useTranslation } from 'react-i18next';
3
3
  import { Button, ButtonSet, InlineNotification } from '@carbon/react';
4
4
  import { Exit } from '@carbon/react/icons';
5
- import { ExtensionSlot, showSnackbar, useAppContext } from '@openmrs/esm-framework';
6
- import { type WardPatientWorkspaceProps, type WardViewContext } from '../../types';
5
+ import { closeWorkspaceGroup2, ExtensionSlot, showSnackbar, useAppContext, Workspace2 } from '@openmrs/esm-framework';
6
+ import { type WardPatientWorkspaceDefinition, type WardPatientWorkspaceProps, type WardViewContext } from '../../types';
7
7
  import { removePatientFromBed, useCreateEncounter } from '../../ward.resource';
8
8
  import WardPatientWorkspaceBanner from '../patient-banner/patient-banner.component';
9
9
  import styles from './patient-discharge.scss';
10
10
 
11
- export default function PatientDischargeWorkspace(props: WardPatientWorkspaceProps) {
12
- const { wardPatient, closeWorkspaceWithSavedChanges } = props;
11
+ export default function PatientDischargeWorkspace({
12
+ groupProps: { wardPatient },
13
+ closeWorkspace,
14
+ }: WardPatientWorkspaceDefinition) {
13
15
  const { t } = useTranslation();
14
16
  const [isSubmitting, setIsSubmitting] = useState(false);
15
17
  const { createEncounter, emrConfiguration, isLoadingEmrConfiguration, errorFetchingEmrConfiguration } =
@@ -34,6 +36,9 @@ export default function PatientDischargeWorkspace(props: WardPatientWorkspacePro
34
36
  title: t('patientWasDischarged', 'Patient was discharged'),
35
37
  kind: 'success',
36
38
  });
39
+
40
+ closeWorkspace({ discardUnsavedChanges: true });
41
+ closeWorkspaceGroup2();
37
42
  }
38
43
  })
39
44
  .catch((err: Error) => {
@@ -45,51 +50,52 @@ export default function PatientDischargeWorkspace(props: WardPatientWorkspacePro
45
50
  })
46
51
  .finally(() => {
47
52
  setIsSubmitting(false);
48
- closeWorkspaceWithSavedChanges();
49
53
  wardPatientGroupDetails?.mutate?.();
50
54
  });
51
- }, [createEncounter, wardPatient, emrConfiguration, t, closeWorkspaceWithSavedChanges, wardPatientGroupDetails]);
55
+ }, [createEncounter, wardPatient, emrConfiguration, t, closeWorkspace, wardPatientGroupDetails]);
52
56
 
53
57
  if (!wardPatientGroupDetails) {
54
58
  return null;
55
59
  }
56
60
 
57
61
  return (
58
- <div className={styles.workspaceContent}>
59
- <div className={styles.patientWorkspaceBanner}>
60
- <WardPatientWorkspaceBanner wardPatient={props?.wardPatient} />
61
- </div>
62
- <div className={styles.workspaceForm}>
63
- <div>
64
- {errorFetchingEmrConfiguration && (
65
- <div className={styles.formError}>
66
- <InlineNotification
67
- kind="error"
68
- title={t('somePartsOfTheFormDidntLoad', "Some parts of the form didn't load")}
69
- subtitle={t(
70
- 'fetchingEmrConfigurationFailed',
71
- 'Fetching EMR configuration failed. Try refreshing the page or contact your system administrator.',
72
- )}
73
- lowContrast
74
- hideCloseButton
75
- />
76
- </div>
77
- )}
62
+ <Workspace2 title={t('discharge', 'Discharge')}>
63
+ <div className={styles.workspaceContent}>
64
+ <div className={styles.patientWorkspaceBanner}>
65
+ <WardPatientWorkspaceBanner wardPatient={wardPatient} />
66
+ </div>
67
+ <div className={styles.workspaceForm}>
68
+ <div>
69
+ {errorFetchingEmrConfiguration && (
70
+ <div className={styles.formError}>
71
+ <InlineNotification
72
+ kind="error"
73
+ title={t('somePartsOfTheFormDidntLoad', "Some parts of the form didn't load")}
74
+ subtitle={t(
75
+ 'fetchingEmrConfigurationFailed',
76
+ 'Fetching EMR configuration failed. Try refreshing the page or contact your system administrator.',
77
+ )}
78
+ lowContrast
79
+ hideCloseButton
80
+ />
81
+ </div>
82
+ )}
83
+ </div>
84
+ <ExtensionSlot name="ward-patient-discharge-slot" />
85
+ <ButtonSet className={styles.buttonSet}>
86
+ <Button
87
+ size="sm"
88
+ kind="ghost"
89
+ renderIcon={(props) => <Exit size={16} {...props} />}
90
+ disabled={
91
+ isLoadingEmrConfiguration || isSubmitting || errorFetchingEmrConfiguration || !wardPatient?.patient
92
+ }
93
+ onClick={submitDischarge}>
94
+ {t('proceedWithPatientDischarge', 'Proceed with patient discharge')}
95
+ </Button>
96
+ </ButtonSet>
78
97
  </div>
79
- <ExtensionSlot name="ward-patient-discharge-slot" />
80
- <ButtonSet className={styles.buttonSet}>
81
- <Button
82
- size="sm"
83
- kind="ghost"
84
- renderIcon={(props) => <Exit size={16} {...props} />}
85
- disabled={
86
- isLoadingEmrConfiguration || isSubmitting || errorFetchingEmrConfiguration || !wardPatient?.patient
87
- }
88
- onClick={submitDischarge}>
89
- {t('proceedWithPatientDischarge', 'Proceed with patient discharge')}
90
- </Button>
91
- </ButtonSet>
92
98
  </div>
93
- </div>
99
+ </Workspace2>
94
100
  );
95
101
  }