@kenyaemr/esm-ward-app 8.1.1-pre.129 → 8.1.2-pre.154

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 (125) hide show
  1. package/.turbo/turbo-build.log +25 -22
  2. package/dist/109.js +1 -1
  3. package/dist/109.js.map +1 -1
  4. package/dist/124.js +1 -1
  5. package/dist/124.js.map +1 -1
  6. package/dist/125.js +1 -1
  7. package/dist/125.js.map +1 -1
  8. package/dist/126.js +1 -0
  9. package/dist/126.js.map +1 -0
  10. package/dist/130.js +1 -1
  11. package/dist/130.js.map +1 -1
  12. package/dist/146.js +1 -1
  13. package/dist/146.js.map +1 -1
  14. package/dist/15.js +1 -1
  15. package/dist/15.js.map +1 -1
  16. package/dist/348.js +1 -1
  17. package/dist/362.js +1 -0
  18. package/dist/362.js.map +1 -0
  19. package/dist/443.js +1 -0
  20. package/dist/443.js.map +1 -0
  21. package/dist/471.js +1 -1
  22. package/dist/471.js.map +1 -1
  23. package/dist/481.js +1 -1
  24. package/dist/481.js.map +1 -1
  25. package/dist/53.js +1 -1
  26. package/dist/53.js.map +1 -1
  27. package/dist/534.js +1 -0
  28. package/dist/534.js.map +1 -0
  29. package/dist/559.js +1 -1
  30. package/dist/559.js.map +1 -1
  31. package/dist/574.js +1 -1
  32. package/dist/576.js +1 -1
  33. package/dist/576.js.map +1 -1
  34. package/dist/577.js +1 -1
  35. package/dist/577.js.map +1 -1
  36. package/dist/598.js +1 -0
  37. package/dist/598.js.map +1 -0
  38. package/dist/662.js +1 -1
  39. package/dist/662.js.map +1 -1
  40. package/dist/767.js +1 -1
  41. package/dist/921.js +1 -1
  42. package/dist/921.js.map +1 -1
  43. package/dist/922.js +1 -1
  44. package/dist/922.js.map +1 -1
  45. package/dist/925.js +2 -0
  46. package/dist/925.js.LICENSE.txt +40 -0
  47. package/dist/925.js.map +1 -0
  48. package/dist/kenyaemr-esm-ward-app.js +1 -1
  49. package/dist/kenyaemr-esm-ward-app.js.buildmanifest.json +169 -139
  50. package/dist/kenyaemr-esm-ward-app.js.map +1 -1
  51. package/dist/main.js +1 -1
  52. package/dist/main.js.LICENSE.txt +35 -0
  53. package/dist/main.js.map +1 -1
  54. package/dist/routes.json +1 -1
  55. package/mock.tsx +5 -4
  56. package/package-lock.json +2 -2
  57. package/package.json +4 -4
  58. package/src/action-menu-buttons/clinical-forms-workspace-siderail.component.tsx +1 -1
  59. package/src/action-menu-buttons/discharge-workspace-siderail.component.tsx +1 -1
  60. package/src/beds/bed-share-divider.component.tsx +21 -0
  61. package/src/beds/bed-share-divider.scss +18 -0
  62. package/src/beds/ward-bed.component.tsx +7 -17
  63. package/src/beds/ward-bed.scss +1 -15
  64. package/src/beds/ward-bed.test.tsx +3 -3
  65. package/src/config-schema.ts +6 -0
  66. package/src/hooks/useEmrConfiguration.ts +8 -0
  67. package/src/index.ts +6 -6
  68. package/src/location-selector/location-selector.component.tsx +8 -7
  69. package/src/root.component.tsx +0 -2
  70. package/src/routes.json +20 -6
  71. package/src/types/index.ts +9 -4
  72. package/src/ward-patient-card/row-elements/ward-patient-identifier.tsx +2 -2
  73. package/src/ward-patient-card/row-elements/ward-patient-pending-transfer.tsx +22 -4
  74. package/src/ward-patient-card/ward-patient-card.component.tsx +24 -6
  75. package/src/ward-patient-card/ward-patient-card.scss +6 -0
  76. package/src/ward-view/default-ward/default-ward-beds.component.tsx +3 -5
  77. package/src/ward-view/default-ward/default-ward-patient-card-header.component.tsx +1 -1
  78. package/src/ward-view/default-ward/default-ward-patient-card.component.tsx +2 -2
  79. package/src/ward-view/default-ward/default-ward-unassigned-patients.component.tsx +2 -2
  80. package/src/ward-view/materal-ward/maternal-ward-beds.component.tsx +9 -2
  81. package/src/ward-view/materal-ward/maternal-ward-patient-card-header.component.tsx +1 -1
  82. package/src/ward-view/materal-ward/maternal-ward-patient-card.component.tsx +2 -2
  83. package/src/ward-view/materal-ward/maternal-ward-view.resource.ts +7 -7
  84. package/src/ward-view/ward-view.component.tsx +1 -2
  85. package/src/ward-view/ward.component.tsx +19 -11
  86. package/src/ward-view-header/admission-requests-bar.component.tsx +4 -2
  87. package/src/ward-view-header/admission-requests.scss +11 -1
  88. package/src/ward-view-header/ward-metrics.test.tsx +5 -13
  89. package/src/ward-workspace/admission-request-card/admission-request-card-actions.component.tsx +17 -62
  90. package/src/ward-workspace/admission-request-card/admission-request-card-header.component.tsx +1 -1
  91. package/src/ward-workspace/admission-request-card/admission-request-card.component.tsx +2 -2
  92. package/src/ward-workspace/admit-patient-button.component.tsx +82 -0
  93. package/src/ward-workspace/admit-patient-form-workspace/admit-patient-form.scss +7 -0
  94. package/src/ward-workspace/admit-patient-form-workspace/admit-patient-form.test.tsx +28 -13
  95. package/src/ward-workspace/admit-patient-form-workspace/admit-patient-form.workspace.tsx +72 -66
  96. package/src/ward-workspace/cancel-admission-request-workspace/cancel-admission-request.scss +55 -0
  97. package/src/ward-workspace/cancel-admission-request-workspace/cancel-admission-request.test.tsx +99 -0
  98. package/src/ward-workspace/cancel-admission-request-workspace/cancel-admission-request.workspace.tsx +174 -0
  99. package/src/ward-workspace/patient-banner/patient-banner.component.tsx +9 -7
  100. package/src/ward-workspace/patient-banner/style.scss +3 -19
  101. package/src/ward-workspace/patient-clinical-forms-workspace/patient-clinical-forms.workspace.tsx +8 -2
  102. package/src/ward-workspace/patient-details/ward-patient-action-button.extension.tsx +2 -3
  103. package/src/ward-workspace/patient-details/ward-patient.style.scss +12 -0
  104. package/src/ward-workspace/patient-details/ward-patient.workspace.tsx +18 -47
  105. package/src/ward-workspace/patient-discharge/patient-discharge.workspace.tsx +14 -24
  106. package/src/ward-workspace/patient-transfer-bed-swap/patient-bed-swap-form.component.tsx +12 -34
  107. package/src/ward-workspace/patient-transfer-bed-swap/patient-transfer-request-form.component.tsx +48 -35
  108. package/src/ward-workspace/patient-transfer-bed-swap/patient-transfer-swap.scss +4 -0
  109. package/src/ward-workspace/patient-transfer-bed-swap/patient-transfer-swap.workspace.tsx +1 -1
  110. package/src/ward-workspace/ward-patient-notes/form/notes-form.component.tsx +30 -25
  111. package/src/ward-workspace/ward-patient-notes/notes.workspace.tsx +1 -1
  112. package/src/ward.resource.ts +32 -22
  113. package/translations/en.json +7 -1
  114. package/dist/153.js +0 -1
  115. package/dist/153.js.map +0 -1
  116. package/dist/169.js +0 -1
  117. package/dist/169.js.map +0 -1
  118. package/dist/303.js +0 -2
  119. package/dist/303.js.LICENSE.txt +0 -5
  120. package/dist/303.js.map +0 -1
  121. package/dist/501.js +0 -1
  122. package/dist/501.js.map +0 -1
  123. package/dist/920.js +0 -1
  124. package/dist/920.js.map +0 -1
  125. package/src/ward-workspace/admit-patient-form-workspace/types.ts +0 -7
@@ -6,12 +6,12 @@ import WardPatientCard from '../../ward-patient-card/ward-patient-card.component
6
6
  import styles from '../../ward-patient-card/ward-patient-card.scss';
7
7
  import DefaultWardPatientCardHeader from './default-ward-patient-card-header.component';
8
8
 
9
- const DefaultWardPatientCard: WardPatientCardType = (wardPatient) => {
9
+ const DefaultWardPatientCard: WardPatientCardType = ({ wardPatient }) => {
10
10
  const { bed } = wardPatient;
11
11
 
12
12
  const card = (
13
13
  <WardPatientCard wardPatient={wardPatient}>
14
- <DefaultWardPatientCardHeader {...wardPatient} />
14
+ <DefaultWardPatientCardHeader {...{ wardPatient }} />
15
15
  <PendingItemsRow id={'pending-items'} wardPatient={wardPatient} />
16
16
  <AdmissionRequestNoteRow id={'admission-request-note'} wardPatient={wardPatient} />
17
17
  </WardPatientCard>
@@ -8,13 +8,13 @@ import DefaultWardPatientCard from './default-ward-patient-card.component';
8
8
  * @returns
9
9
  */
10
10
  function DefaultWardUnassignedPatients() {
11
- const {wardPatientGroupDetails} = useAppContext<WardViewContext>('ward-view-context') ?? {};
11
+ const { wardPatientGroupDetails } = useAppContext<WardViewContext>('ward-view-context') ?? {};
12
12
  const { wardUnassignedPatientsList } = wardPatientGroupDetails ?? {};
13
13
 
14
14
  const wardUnassignedPatients = wardUnassignedPatientsList?.map((inpatientAdmission) => {
15
15
  return (
16
16
  <DefaultWardPatientCard
17
- {...{
17
+ wardPatient={{
18
18
  patient: inpatientAdmission.patient,
19
19
  visit: inpatientAdmission.visit,
20
20
  bed: null,
@@ -6,7 +6,7 @@ import { bedLayoutToBed } from '../ward-view.resource';
6
6
  import MaternalWardPatientCard from './maternal-ward-patient-card.component';
7
7
 
8
8
  const MaternalWardBeds: React.FC<MotherChildRelationships> = (motherChildRelationships) => {
9
- const { motherByChildUuid } = motherChildRelationships ?? {};
9
+ const { motherByChildUuid, isLoading: isLoadingMotherChildRelationships } = motherChildRelationships ?? {};
10
10
  const { wardPatientGroupDetails } = useAppContext<WardViewContext>('ward-view-context') ?? {};
11
11
  const { bedLayouts, wardAdmittedPatientsWithBed } = wardPatientGroupDetails ?? {};
12
12
 
@@ -56,7 +56,14 @@ const MaternalWardBeds: React.FC<MotherChildRelationships> = (motherChildRelatio
56
56
  />
57
57
  ));
58
58
 
59
- return <WardBed key={bed.uuid} bed={bed} patientCards={patientCards} />;
59
+ return (
60
+ <WardBed
61
+ key={bed.uuid}
62
+ bed={bed}
63
+ patientCards={patientCards}
64
+ isLoadingDivider={isLoadingMotherChildRelationships}
65
+ />
66
+ );
60
67
  });
61
68
 
62
69
  return <>{wardBeds}</>;
@@ -10,7 +10,7 @@ import WardPatientObs from '../../ward-patient-card/row-elements/ward-patient-ob
10
10
  import WardPatientTimeSinceAdmission from '../../ward-patient-card/row-elements/ward-patient-time-since-admission';
11
11
  import styles from '../../ward-patient-card/ward-patient-card.scss';
12
12
 
13
- const MaternalWardPatientCardHeader: WardPatientCardType = (wardPatient) => {
13
+ const MaternalWardPatientCardHeader: WardPatientCardType = ({ wardPatient }) => {
14
14
  const { patient, bed, visit, inpatientAdmission } = wardPatient;
15
15
  const { firstAdmissionOrTransferEncounter } = inpatientAdmission ?? {};
16
16
 
@@ -43,7 +43,7 @@ const MaternalWardPatientCard: React.FC<MaternalWardPatientCardProps> = (props)
43
43
  const card = (
44
44
  <>
45
45
  <WardPatientCard wardPatient={wardPatient}>
46
- <MaternalWardPatientCardHeader {...wardPatient} />
46
+ <MaternalWardPatientCardHeader {...{ wardPatient }} />
47
47
  <div className={classNames(styles.wardPatientCardRow, styles.dotSeparatedChildren)}>
48
48
  <WardPatientTimeOnWard
49
49
  encounterAssigningToCurrentInpatientLocation={encounterAssigningToCurrentInpatientLocation}
@@ -59,7 +59,7 @@ const MaternalWardPatientCard: React.FC<MaternalWardPatientCardProps> = (props)
59
59
  <React.Fragment key={childWardPatient.patient.uuid}>
60
60
  <MotherChildBedShareDivider />
61
61
  <WardPatientCard wardPatient={childWardPatient}>
62
- <MaternalWardPatientCardHeader {...childWardPatient} />
62
+ <MaternalWardPatientCardHeader wardPatient={childWardPatient} />
63
63
  <PendingItemsRow id={'pending-items'} wardPatient={childWardPatient} />
64
64
  </WardPatientCard>
65
65
  </React.Fragment>
@@ -2,12 +2,15 @@ import { showNotification } from '@openmrs/esm-framework';
2
2
  import { useMemo } from 'react';
3
3
  import { useTranslation } from 'react-i18next';
4
4
  import { useMotherAndChildren, type MothersAndChildrenSearchCriteria } from '../../hooks/useMotherAndChildren';
5
- import { type PatientAndAdmission } from '../../types';
5
+ import { type MotherChildRelationships, type PatientAndAdmission } from '../../types';
6
6
 
7
7
  const motherAndChildrenRep =
8
8
  'custom:(childAdmission,mother:(person,identifiers:full,uuid),child:(person,identifiers:full,uuid),motherAdmission)';
9
9
 
10
- export function useMotherChildrenRelationshipsByPatient(allWardPatientUuids: string[], fetch: boolean) {
10
+ export function useMotherChildrenRelationshipsByPatient(
11
+ allWardPatientUuids: string[],
12
+ fetch: boolean,
13
+ ): MotherChildRelationships {
11
14
  const { t } = useTranslation();
12
15
 
13
16
  const getChildrenRequestParams: MothersAndChildrenSearchCriteria = {
@@ -53,12 +56,9 @@ export function useMotherChildrenRelationshipsByPatient(allWardPatientUuids: str
53
56
  }
54
57
 
55
58
  const relationships = useMemo(() => {
56
- if (isLoadingChildrenData || isLoadingMotherData) {
57
- return null;
58
- }
59
-
60
59
  const motherByChildUuid = new Map<string, PatientAndAdmission>();
61
60
  const childrenByMotherUuid = new Map<string, PatientAndAdmission[]>();
61
+ const isLoading = isLoadingChildrenData || isLoadingMotherData;
62
62
 
63
63
  for (const { child, childAdmission, mother, motherAdmission } of motherData ?? []) {
64
64
  motherByChildUuid.set(child.uuid, { patient: mother, currentAdmission: motherAdmission });
@@ -82,7 +82,7 @@ export function useMotherChildrenRelationshipsByPatient(allWardPatientUuids: str
82
82
  }
83
83
  }
84
84
 
85
- return { motherByChildUuid, childrenByMotherUuid };
85
+ return { motherByChildUuid, childrenByMotherUuid, isLoading };
86
86
  }, [childrenData, motherData, isLoadingChildrenData, isLoadingMotherData]);
87
87
 
88
88
  return relationships;
@@ -13,7 +13,6 @@ const WardView: React.FC<{}> = () => {
13
13
  const { t } = useTranslation();
14
14
 
15
15
  const locationUuid = location?.uuid;
16
- const isVertical = useFeatureFlag('ward-view-vertical-tiling');
17
16
  const wardConfig = useWardConfig(locationUuid);
18
17
 
19
18
  if (isLoadingLocation) {
@@ -27,7 +26,7 @@ const WardView: React.FC<{}> = () => {
27
26
  const wardId = wardConfig.id;
28
27
 
29
28
  return (
30
- <div className={classNames(styles.wardView, { [styles.verticalTiling]: isVertical })}>
29
+ <div className={classNames(styles.wardView, styles.verticalTiling)}>
31
30
  <ExtensionSlot name={wardId} />
32
31
  </div>
33
32
  );
@@ -1,22 +1,21 @@
1
- import { InlineNotification } from '@carbon/react';
2
- import { useAppContext, useFeatureFlag } from '@openmrs/esm-framework';
3
- import classNames from 'classnames';
4
1
  import React, { useEffect, useRef, type ReactNode } from 'react';
2
+ import classNames from 'classnames';
3
+ import { InlineNotification } from '@carbon/react';
5
4
  import { useTranslation } from 'react-i18next';
6
- import EmptyBedSkeleton from '../beds/empty-bed-skeleton';
7
- import useWardLocation from '../hooks/useWardLocation';
5
+ import { useAppContext, useFeatureFlag } from '@openmrs/esm-framework';
8
6
  import { type WardViewContext } from '../types';
7
+ import useWardLocation from '../hooks/useWardLocation';
8
+ import EmptyBedSkeleton from '../beds/empty-bed-skeleton';
9
9
  import styles from './ward-view.scss';
10
10
 
11
11
  const Ward = ({ wardBeds, wardUnassignedPatients }: { wardBeds: ReactNode; wardUnassignedPatients: ReactNode }) => {
12
12
  const { location } = useWardLocation();
13
13
  const { t } = useTranslation();
14
- const isVertical = useFeatureFlag('ward-view-vertical-tiling');
15
14
 
16
- const {wardPatientGroupDetails} = useAppContext<WardViewContext>('ward-view-context') ?? {};
15
+ const { wardPatientGroupDetails } = useAppContext<WardViewContext>('ward-view-context') ?? {};
17
16
  const { bedLayouts } = wardPatientGroupDetails ?? {};
18
17
  const { isLoading: isLoadingAdmissionLocation, error: errorLoadingAdmissionLocation } =
19
- wardPatientGroupDetails?.admissionLocationResponse ?? {};
18
+ wardPatientGroupDetails?.admissionLocationResponse ?? {};
20
19
  const {
21
20
  isLoading: isLoadingInpatientAdmissions,
22
21
  error: errorLoadingInpatientAdmissions,
@@ -44,19 +43,28 @@ const Ward = ({ wardBeds, wardUnassignedPatients }: { wardBeds: ReactNode; wardU
44
43
  if (scrollToLoadMoreTrigger.current) {
45
44
  observer.observe(scrollToLoadMoreTrigger.current);
46
45
  }
46
+
47
47
  return () => {
48
48
  if (scrollToLoadMoreTrigger.current) {
49
+ // TODO: Fix this more meaningfully
50
+ // eslint-disable-next-line react-hooks/exhaustive-deps
49
51
  observer.unobserve(scrollToLoadMoreTrigger.current);
50
52
  }
51
53
  };
52
54
  },
53
- [scrollToLoadMoreTrigger, hasMoreInpatientAdmissions, errorLoadingInpatientAdmissions, loadMoreInpatientAdmissions],
55
+ [
56
+ errorLoadingInpatientAdmissions,
57
+ hasMoreInpatientAdmissions,
58
+ isLoadingInpatientAdmissions,
59
+ loadMoreInpatientAdmissions,
60
+ scrollToLoadMoreTrigger,
61
+ ],
54
62
  );
55
63
 
56
64
  if (!wardPatientGroupDetails) return <></>;
57
65
 
58
66
  return (
59
- <div className={classNames(styles.wardViewMain, { [styles.verticalTiling]: isVertical })}>
67
+ <div className={classNames(styles.wardViewMain, styles.verticalTiling)}>
60
68
  {wardBeds}
61
69
  {bedLayouts?.length == 0 && isBedManagementModuleInstalled && (
62
70
  <InlineNotification
@@ -103,4 +111,4 @@ const EmptyBeds = () => {
103
111
  );
104
112
  };
105
113
 
106
- export default Ward;
114
+ export default Ward;
@@ -16,7 +16,7 @@ const AdmissionRequestsBar: React.FC<AdmissionRequestsBarProps> = ({ wardPending
16
16
  const { t } = useTranslation();
17
17
  const layout = useLayoutType();
18
18
 
19
- if (isLoading || !inpatientRequests?.length) {
19
+ if (isLoading || !inpatientRequests) {
20
20
  return null;
21
21
  }
22
22
 
@@ -31,7 +31,9 @@ const AdmissionRequestsBar: React.FC<AdmissionRequestsBarProps> = ({ wardPending
31
31
  }
32
32
 
33
33
  return (
34
- <div className={styles.admissionRequestsContainer}>
34
+ <div className={`${styles.admissionRequestsContainer} ${
35
+ inpatientRequests?.length ? styles.blackBackground : styles.lightBlueBackground
36
+ }`}>
35
37
  <Movement className={styles.movementIcon} size="24" />
36
38
  <span className={styles.content}>
37
39
  {t('admissionRequestsCount', '{{count}} admission request', {
@@ -30,8 +30,18 @@
30
30
  margin-right: layout.$spacing-03;
31
31
  }
32
32
 
33
+ .blackBackground {
34
+ background-color: #393939;
35
+ color: white;
36
+ }
37
+
38
+ .lightBlueBackground {
39
+ background-color: $color-blue-10;
40
+ border-left: 4px solid $color-blue-60-2;
41
+ color: #393939;
42
+ }
43
+
33
44
  .content {
34
45
  @include type.type-style('heading-compact-01');
35
- color: $ui-02;
36
46
  margin-right: layout.$spacing-03;
37
47
  }
@@ -1,19 +1,11 @@
1
+ import { useAppContext } from '@openmrs/esm-framework';
2
+ import { screen } from '@testing-library/react';
1
3
  import React from 'react';
2
- import WardMetrics from './ward-metrics.component';
3
4
  import { renderWithSwr } from '../../../../tools/test-utils';
4
- import {
5
- createAndGetWardPatientGrouping,
6
- getInpatientAdmissionsUuidMap,
7
- getWardMetrics,
8
- } from '../ward-view/ward-view.resource';
9
- import { useAdmissionLocation } from '../hooks/useAdmissionLocation';
10
- import { mockAdmissionLocation, mockInpatientAdmissions, mockInpatientRequest } from '__mocks__';
11
- import { useInpatientAdmission } from '../hooks/useInpatientAdmission';
12
- import useWardLocation from '../hooks/useWardLocation';
13
- import { screen } from '@testing-library/react';
14
- import { useAppContext } from '@openmrs/esm-framework';
15
- import { type WardViewContext } from '../types';
16
5
  import { mockWardViewContext } from '../../mock';
6
+ import { type WardViewContext } from '../types';
7
+ import { getWardMetrics } from '../ward-view/ward-view.resource';
8
+ import WardMetrics from './ward-metrics.component';
17
9
 
18
10
  const wardMetrics = [
19
11
  { name: 'patients', key: 'patients', defaultTranslation: 'Patients' },
@@ -1,34 +1,17 @@
1
1
  import { Button } from '@carbon/react';
2
- import {
3
- ArrowRightIcon,
4
- launchWorkspace,
5
- showSnackbar,
6
- useAppContext,
7
- useFeatureFlag,
8
- useLayoutType,
9
- } from '@openmrs/esm-framework';
2
+ import { launchWorkspace, useAppContext, useLayoutType } from '@openmrs/esm-framework';
10
3
  import React, { useCallback, useContext } from 'react';
11
4
  import { useTranslation } from 'react-i18next';
12
- import useWardLocation from '../../hooks/useWardLocation';
13
5
  import type { WardPatientCardType, WardPatientWorkspaceProps, WardViewContext } from '../../types';
14
6
  import { useAdmitPatient } from '../../ward.resource';
15
7
  import { AdmissionRequestsWorkspaceContext } from '../admission-request-workspace/admission-requests.workspace';
16
- import type { AdmitPatientFormWorkspaceProps } from '../admit-patient-form-workspace/types';
8
+ import AdmissionPatientButton from '../admit-patient-button.component';
17
9
  import styles from './admission-request-card.scss';
18
10
 
19
- const AdmissionRequestCardActions: WardPatientCardType = (wardPatient) => {
20
- const { patient, inpatientRequest } = wardPatient;
21
- const { dispositionType } = inpatientRequest;
11
+ const AdmissionRequestCardActions: WardPatientCardType = ({ wardPatient }) => {
22
12
  const { t } = useTranslation();
23
- const { location } = useWardLocation();
24
13
  const responsiveSize = useLayoutType() === 'tablet' ? 'lg' : 'md';
25
- const { WardPatientHeader, wardPatientGroupDetails } = useAppContext<WardViewContext>('ward-view-context') ?? {};
26
- const { admitPatient, isLoadingEmrConfiguration, errorFetchingEmrConfiguration } = useAdmitPatient();
27
-
28
- const launchPatientAdmissionForm = useCallback(
29
- () => launchWorkspace<AdmitPatientFormWorkspaceProps>('admit-patient-form-workspace', { patient, dispositionType }),
30
- [],
31
- );
14
+ const { WardPatientHeader } = useAppContext<WardViewContext>('ward-view-context') ?? {};
32
15
 
33
16
  const launchPatientTransferForm = useCallback(() => {
34
17
  launchWorkspace<WardPatientWorkspaceProps>('patient-transfer-request-workspace', {
@@ -36,56 +19,28 @@ const AdmissionRequestCardActions: WardPatientCardType = (wardPatient) => {
36
19
  WardPatientHeader,
37
20
  });
38
21
  }, [wardPatient, WardPatientHeader]);
39
- const isBedManagementModuleInstalled = useFeatureFlag('bedmanagement-module');
40
- const { closeWorkspaceWithSavedChanges } = useContext(AdmissionRequestsWorkspaceContext);
41
22
 
42
- // If bed management module is installed, open the next form
43
- // for bed selection. If not, admit patient directly
44
- const onAdmit = () => {
45
- if (isBedManagementModuleInstalled) {
46
- launchPatientAdmissionForm();
47
- } else {
48
- admitPatient(patient, dispositionType)
49
- .then(
50
- (response) => {
51
- if (response && response?.ok) {
52
- showSnackbar({
53
- kind: 'success',
54
- title: t('patientAdmittedSuccessfully', 'Patient admitted successfully'),
55
- subtitle: t('patientAdmittedWoBed', 'Patient admitted successfully to {{location}}', {
56
- location: location?.display,
57
- }),
58
- });
59
- }
60
- },
61
- (err: Error) => {
62
- showSnackbar({
63
- kind: 'error',
64
- title: t('errorCreatingEncounter', 'Failed to admit patient'),
65
- subtitle: err.message,
66
- });
67
- },
68
- )
69
- .finally(() => {
70
- wardPatientGroupDetails?.mutate?.();
71
- closeWorkspaceWithSavedChanges();
72
- });
73
- }
23
+ const launchCancelAdmissionForm = () => {
24
+ launchWorkspace<WardPatientWorkspaceProps>('cancel-admission-request-workspace', {
25
+ wardPatient,
26
+ WardPatientHeader,
27
+ });
74
28
  };
75
29
 
30
+ const { closeWorkspaceWithSavedChanges } = useContext(AdmissionRequestsWorkspaceContext);
31
+
76
32
  return (
77
33
  <div className={styles.admissionRequestActionBar}>
78
34
  <Button kind="ghost" size={responsiveSize} onClick={launchPatientTransferForm}>
79
35
  {t('transferElsewhere', 'Transfer elsewhere')}
80
36
  </Button>
81
- <Button
82
- kind="ghost"
83
- renderIcon={ArrowRightIcon}
84
- size={responsiveSize}
85
- disabled={isLoadingEmrConfiguration || errorFetchingEmrConfiguration}
86
- onClick={onAdmit}>
87
- {t('admitPatient', 'Admit patient')}
37
+ <Button kind="ghost" size={responsiveSize} onClick={launchCancelAdmissionForm}>
38
+ {t('cancel', 'Cancel')}
88
39
  </Button>
40
+ <AdmissionPatientButton
41
+ wardPatient={wardPatient}
42
+ onAdmitPatientSuccess={() => closeWorkspaceWithSavedChanges()}
43
+ />
89
44
  </div>
90
45
  );
91
46
  };
@@ -8,7 +8,7 @@ import WardPatientIdentifier from '../../ward-patient-card/row-elements/ward-pat
8
8
  import WardPatientName from '../../ward-patient-card/row-elements/ward-patient-name';
9
9
  import styles from './admission-request-card.scss';
10
10
 
11
- const AdmissionRequestCardHeader: WardPatientCardType = (wardPatient) => {
11
+ const AdmissionRequestCardHeader: WardPatientCardType = ({ wardPatient }) => {
12
12
  const { inpatientRequest } = wardPatient;
13
13
  const { dispositionEncounter } = inpatientRequest;
14
14
  const { patient } = wardPatient;
@@ -12,9 +12,9 @@ interface AdmissionRequestCardProps {
12
12
  const AdmissionRequestCard: React.FC<AdmissionRequestCardProps> = ({ wardPatient, children }) => {
13
13
  return (
14
14
  <div className={styles.admissionRequestCard}>
15
- <AdmissionRequestCardHeader {...wardPatient} />
15
+ <AdmissionRequestCardHeader {...{ wardPatient }} />
16
16
  {children}
17
- <AdmissionRequestCardActions {...wardPatient} />
17
+ <AdmissionRequestCardActions {...{ wardPatient }} />
18
18
  </div>
19
19
  );
20
20
  };
@@ -0,0 +1,82 @@
1
+ import { Button } from '@carbon/react';
2
+ import {
3
+ ArrowRightIcon,
4
+ launchWorkspace,
5
+ showSnackbar,
6
+ useAppContext,
7
+ useFeatureFlag,
8
+ useLayoutType,
9
+ } from '@openmrs/esm-framework';
10
+ import React from 'react';
11
+ import { useTranslation } from 'react-i18next';
12
+ import useWardLocation from '../hooks/useWardLocation';
13
+ import type { WardPatient, WardPatientWorkspaceProps, WardViewContext } from '../types';
14
+ import { useAdmitPatient } from '../ward.resource';
15
+
16
+ interface AdmissionPatientButtonProps {
17
+ wardPatient: WardPatient;
18
+ onAdmitPatientSuccess();
19
+ }
20
+
21
+ const AdmissionPatientButton: React.FC<AdmissionPatientButtonProps> = ({ wardPatient, onAdmitPatientSuccess }) => {
22
+ const { patient, inpatientRequest, bed } = wardPatient ?? {};
23
+ const dispositionType = inpatientRequest?.dispositionType ?? 'ADMIT';
24
+ const { t } = useTranslation();
25
+ const { location } = useWardLocation();
26
+ const responsiveSize = useLayoutType() === 'tablet' ? 'lg' : 'md';
27
+ const { WardPatientHeader, wardPatientGroupDetails } = useAppContext<WardViewContext>('ward-view-context') ?? {};
28
+ const { admitPatient, isLoadingEmrConfiguration, errorFetchingEmrConfiguration } = useAdmitPatient();
29
+
30
+ const launchPatientAdmissionForm = () =>
31
+ launchWorkspace<WardPatientWorkspaceProps>('admit-patient-form-workspace', { wardPatient, WardPatientHeader });
32
+
33
+ const isBedManagementModuleInstalled = useFeatureFlag('bedmanagement-module');
34
+
35
+ // If bed management module is installed and the patient does not currently assigned a bed,
36
+ // open the next form for bed selection. If not, admit patient directly
37
+ // (Note that it is possible, albeit an edge case, for a patient to have a bed assigned while not admitted)
38
+ const onAdmit = () => {
39
+ if (isBedManagementModuleInstalled && !bed) {
40
+ launchPatientAdmissionForm();
41
+ } else {
42
+ admitPatient(patient, dispositionType)
43
+ .then(
44
+ (response) => {
45
+ if (response && response?.ok) {
46
+ showSnackbar({
47
+ kind: 'success',
48
+ title: t('patientAdmittedSuccessfully', 'Patient admitted successfully'),
49
+ subtitle: t('patientAdmittedWoBed', 'Patient admitted successfully to {{location}}', {
50
+ location: location?.display,
51
+ }),
52
+ });
53
+ }
54
+ },
55
+ (err: Error) => {
56
+ showSnackbar({
57
+ kind: 'error',
58
+ title: t('errorCreatingEncounter', 'Failed to admit patient'),
59
+ subtitle: err.message,
60
+ });
61
+ },
62
+ )
63
+ .finally(() => {
64
+ wardPatientGroupDetails?.mutate?.();
65
+ onAdmitPatientSuccess();
66
+ });
67
+ }
68
+ };
69
+
70
+ return (
71
+ <Button
72
+ kind="ghost"
73
+ renderIcon={ArrowRightIcon}
74
+ size={responsiveSize}
75
+ disabled={isLoadingEmrConfiguration || errorFetchingEmrConfiguration}
76
+ onClick={onAdmit}>
77
+ {t('admitPatient', 'Admit patient')}
78
+ </Button>
79
+ );
80
+ };
81
+
82
+ export default AdmissionPatientButton;
@@ -2,6 +2,13 @@
2
2
  @use '@carbon/layout';
3
3
  @use '@openmrs/esm-styleguide/src/vars' as *;
4
4
 
5
+ .flexWrapper {
6
+ height: 100%;
7
+ display: flex;
8
+ flex-direction: column;
9
+ color: #393939;
10
+ }
11
+
5
12
  .form {
6
13
  display: flex;
7
14
  height: 100%;
@@ -1,16 +1,22 @@
1
- import { showSnackbar, useAppContext, useFeatureFlag, useSession } from '@openmrs/esm-framework';
1
+ import {
2
+ CloseWorkspaceOptions,
3
+ type DefaultWorkspaceProps,
4
+ showSnackbar,
5
+ useAppContext,
6
+ useFeatureFlag,
7
+ useSession,
8
+ } from '@openmrs/esm-framework';
2
9
  import { screen } from '@testing-library/react';
3
10
  import userEvent from '@testing-library/user-event';
4
11
  import React from 'react';
5
- import { mockLocationInpatientWard, mockPatientAlice } from '../../../../../__mocks__';
12
+ import { mockInpatientRequestAlice, mockLocationInpatientWard, mockPatientAlice } from '../../../../../__mocks__';
6
13
  import { renderWithSwr } from '../../../../../tools';
7
14
  import { mockWardPatientGroupDetails, mockWardViewContext } from '../../../mock';
8
15
  import { useAssignedBedByPatient } from '../../hooks/useAssignedBedByPatient';
9
16
  import useWardLocation from '../../hooks/useWardLocation';
10
- import type { DispositionType, WardViewContext } from '../../types';
17
+ import type { DispositionType, WardPatient, WardViewContext } from '../../types';
11
18
  import { assignPatientToBed, removePatientFromBed, useAdmitPatient } from '../../ward.resource';
12
19
  import AdmitPatientFormWorkspace from './admit-patient-form.workspace';
13
- import type { AdmitPatientFormWorkspaceProps } from './types';
14
20
 
15
21
  jest.mock('../../hooks/useAdmissionLocation', () => ({
16
22
  useAdmissionLocation: jest.fn(),
@@ -35,7 +41,6 @@ jest.mock('../../hooks/useAssignedBedByPatient', () => ({
35
41
  }));
36
42
 
37
43
  jest.mock('../../ward.resource', () => ({
38
- createEncounter: jest.fn(),
39
44
  useAdmitPatient: jest.fn(),
40
45
  assignPatientToBed: jest.fn(),
41
46
  removePatientFromBed: jest.fn(),
@@ -52,25 +57,35 @@ const mockedUseAdmitPatient = jest.mocked(useAdmitPatient);
52
57
 
53
58
  jest.mocked(useAppContext<WardViewContext>).mockReturnValue(mockWardViewContext);
54
59
 
60
+ const mockedAdmitPatient = jest.fn();
55
61
  const mockUseAdmitPatientObj: ReturnType<typeof useAdmitPatient> = {
56
- admitPatient: jest.fn(),
62
+ admitPatient: mockedAdmitPatient,
57
63
  isLoadingEmrConfiguration: false,
58
64
  errorFetchingEmrConfiguration: false,
59
65
  };
60
66
  jest.mocked(useAdmitPatient).mockReturnValue(mockUseAdmitPatientObj);
61
- const mockedAdmitPatient = mockUseAdmitPatientObj.admitPatient;
62
67
 
63
- const mockWorkspaceProps: AdmitPatientFormWorkspaceProps = {
64
- patient: mockPatientAlice,
65
- closeWorkspace: jest.fn(),
68
+ const mockWorkspaceProps: DefaultWorkspaceProps = {
66
69
  closeWorkspaceWithSavedChanges: jest.fn(),
67
70
  promptBeforeClosing: jest.fn(),
68
71
  setTitle: jest.fn(),
69
- dispositionType: 'ADMIT',
72
+ closeWorkspace: jest.fn(),
73
+ };
74
+
75
+ const mockWardPatientAliceProps: WardPatient = {
76
+ visit: mockInpatientRequestAlice.visit,
77
+ patient: mockPatientAlice,
78
+ bed: null,
79
+ inpatientAdmission: null,
80
+ inpatientRequest: mockInpatientRequestAlice,
70
81
  };
71
82
 
72
- function renderAdmissionForm(dispositionType: DispositionType = 'ADMIT') {
73
- renderWithSwr(<AdmitPatientFormWorkspace {...{ ...mockWorkspaceProps, dispositionType }} />);
83
+ function renderAdmissionForm() {
84
+ renderWithSwr(
85
+ <AdmitPatientFormWorkspace
86
+ {...{ ...mockWorkspaceProps, wardPatient: mockWardPatientAliceProps, WardPatientHeader: jest.fn() }}
87
+ />,
88
+ );
74
89
  }
75
90
 
76
91
  describe('Testing AdmitPatientForm', () => {