From d3a791ac0292290773ec2fae8e8d161523ac4509 Mon Sep 17 00:00:00 2001 From: Dennis Kigen Date: Fri, 21 Jun 2024 08:28:58 +0300 Subject: [PATCH 1/3] (refactor) Refactor modals to match naming conventions (#1875) --- packages/esm-form-engine-app/package.json | 2 +- ...al.component.tsx => delete-question.modal.tsx} | 0 packages/esm-form-engine-app/src/index.ts | 2 +- .../esm-generic-patient-widgets-app/package.json | 2 +- packages/esm-patient-allergies-app/package.json | 2 +- ...dal.component.tsx => delete-allergy.modal.tsx} | 0 packages/esm-patient-allergies-app/src/index.ts | 2 +- packages/esm-patient-attachments-app/package.json | 2 +- ....component.tsx => delete-attachment.modal.tsx} | 2 +- ...irmation-modal.scss => delete-attachment.scss} | 0 packages/esm-patient-attachments-app/src/index.ts | 11 ++++------- packages/esm-patient-banner-app/package.json | 2 +- .../print-identifier-sticker-modal.test.tsx | 2 +- ...ent.tsx => print-identifier-sticker.modal.tsx} | 2 +- ...r-modal.scss => print-identifier-sticker.scss} | 0 packages/esm-patient-banner-app/src/index.ts | 2 +- packages/esm-patient-chart-app/package.json | 2 +- ...e-modal.component.tsx => mark-alive.modal.tsx} | 0 packages/esm-patient-chart-app/src/index.ts | 15 ++++++--------- ....component.tsx => modify-visit-date.modal.tsx} | 0 ...l.component.tsx => delete-encounter.modal.tsx} | 0 .../esm-patient-chart-app/translations/en.json | 2 +- packages/esm-patient-conditions-app/package.json | 2 +- ...l.component.tsx => delete-condition.modal.tsx} | 0 packages/esm-patient-conditions-app/src/index.ts | 2 +- packages/esm-patient-flags-app/package.json | 2 +- packages/esm-patient-forms-app/package.json | 2 +- .../esm-patient-immunizations-app/package.json | 2 +- packages/esm-patient-labs-app/package.json | 2 +- packages/esm-patient-lists-app/package.json | 2 +- packages/esm-patient-medications-app/package.json | 2 +- packages/esm-patient-notes-app/package.json | 2 +- packages/esm-patient-orders-app/package.json | 2 +- packages/esm-patient-programs-app/package.json | 2 +- packages/esm-patient-vitals-app/package.json | 2 +- packages/esm-patient-vitals-app/src/index.ts | 2 +- ...tsx => delete-vitals-and-biometrics.modal.tsx} | 0 .../esm-patient-vitals-app/translations/en.json | 2 +- 38 files changed, 37 insertions(+), 43 deletions(-) rename packages/esm-form-engine-app/src/form-renderer/repeat/{delete-question-modal.component.tsx => delete-question.modal.tsx} (100%) rename packages/esm-patient-allergies-app/src/allergies/{delete-allergy-modal.component.tsx => delete-allergy.modal.tsx} (100%) rename packages/esm-patient-attachments-app/src/attachments/{delete-attachment-confirmation-modal.component.tsx => delete-attachment.modal.tsx} (95%) rename packages/esm-patient-attachments-app/src/attachments/{delete-attachment-confirmation-modal.scss => delete-attachment.scss} (100%) rename packages/esm-patient-banner-app/src/banner-tags/{print-identifier-sticker-modal.component.tsx => print-identifier-sticker.modal.tsx} (98%) rename packages/esm-patient-banner-app/src/banner-tags/{print-identifier-sticker-modal.scss => print-identifier-sticker.scss} (100%) rename packages/esm-patient-chart-app/src/deceased/{mark-alive-modal.component.tsx => mark-alive.modal.tsx} (100%) rename packages/esm-patient-chart-app/src/visit/visit-prompt/{modify-visit-date-dialog.component.tsx => modify-visit-date.modal.tsx} (100%) rename packages/esm-patient-chart-app/src/visit/visits-widget/past-visits-components/{delete-encounter-modal.component.tsx => delete-encounter.modal.tsx} (100%) rename packages/esm-patient-conditions-app/src/conditions/{delete-condition-modal.component.tsx => delete-condition.modal.tsx} (100%) rename packages/esm-patient-vitals-app/src/vitals-biometrics-form/{delete-vitals-biometrics-modal.component.tsx => delete-vitals-and-biometrics.modal.tsx} (100%) diff --git a/packages/esm-form-engine-app/package.json b/packages/esm-form-engine-app/package.json index 7f991a370c..914aced227 100644 --- a/packages/esm-form-engine-app/package.json +++ b/packages/esm-form-engine-app/package.json @@ -17,7 +17,7 @@ "test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js --color", "coverage": "yarn test --coverage", "typescript": "tsc", - "extract-translations": "i18next 'src/**/*.component.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" + "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.modal.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" }, "browserslist": [ "extends browserslist-config-openmrs" diff --git a/packages/esm-form-engine-app/src/form-renderer/repeat/delete-question-modal.component.tsx b/packages/esm-form-engine-app/src/form-renderer/repeat/delete-question.modal.tsx similarity index 100% rename from packages/esm-form-engine-app/src/form-renderer/repeat/delete-question-modal.component.tsx rename to packages/esm-form-engine-app/src/form-renderer/repeat/delete-question.modal.tsx diff --git a/packages/esm-form-engine-app/src/index.ts b/packages/esm-form-engine-app/src/index.ts index 75b0ffc652..0b081b4e21 100644 --- a/packages/esm-form-engine-app/src/index.ts +++ b/packages/esm-form-engine-app/src/index.ts @@ -25,6 +25,6 @@ export const formCollapseToggle = getAsyncLifecycle( ); export const deleteQuestionModal = getAsyncLifecycle( - () => import('./form-renderer/repeat/delete-question-modal.component'), + () => import('./form-renderer/repeat/delete-question.modal'), options, ); diff --git a/packages/esm-generic-patient-widgets-app/package.json b/packages/esm-generic-patient-widgets-app/package.json index c5874404d3..3f4838bcee 100644 --- a/packages/esm-generic-patient-widgets-app/package.json +++ b/packages/esm-generic-patient-widgets-app/package.json @@ -17,7 +17,7 @@ "test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js --color", "coverage": "yarn test --coverage", "typescript": "tsc", - "extract-translations": "i18next 'src/**/*.component.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" + "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.modal.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" }, "browserslist": [ "extends browserslist-config-openmrs" diff --git a/packages/esm-patient-allergies-app/package.json b/packages/esm-patient-allergies-app/package.json index 4bb0d41989..0c97525f11 100644 --- a/packages/esm-patient-allergies-app/package.json +++ b/packages/esm-patient-allergies-app/package.json @@ -17,7 +17,7 @@ "test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js --color", "coverage": "yarn test --coverage", "typescript": "tsc", - "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.extension.tsx' 'src/**/*.workspace.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" + "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.modal.tsx' 'src/**/*.extension.tsx' 'src/**/*.workspace.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" }, "browserslist": [ "extends browserslist-config-openmrs" diff --git a/packages/esm-patient-allergies-app/src/allergies/delete-allergy-modal.component.tsx b/packages/esm-patient-allergies-app/src/allergies/delete-allergy.modal.tsx similarity index 100% rename from packages/esm-patient-allergies-app/src/allergies/delete-allergy-modal.component.tsx rename to packages/esm-patient-allergies-app/src/allergies/delete-allergy.modal.tsx diff --git a/packages/esm-patient-allergies-app/src/index.ts b/packages/esm-patient-allergies-app/src/index.ts index 1f8eeaf5cd..7c03fa43c1 100644 --- a/packages/esm-patient-allergies-app/src/index.ts +++ b/packages/esm-patient-allergies-app/src/index.ts @@ -61,6 +61,6 @@ export const allergyFormWorkspace = getAsyncLifecycle( export const allergyTile = getSyncLifecycle(allergyTileComponent, options); export const allergyDeleteConfirmationDialog = getAsyncLifecycle( - () => import('./allergies/delete-allergy-modal.component'), + () => import('./allergies/delete-allergy.modal'), options, ); diff --git a/packages/esm-patient-attachments-app/package.json b/packages/esm-patient-attachments-app/package.json index 161260de59..4b05a69833 100644 --- a/packages/esm-patient-attachments-app/package.json +++ b/packages/esm-patient-attachments-app/package.json @@ -17,7 +17,7 @@ "test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js --color", "coverage": "yarn test --coverage", "typescript": "tsc", - "extract-translations": "i18next 'src/**/*.component.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" + "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.modal.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" }, "browserslist": [ "extends browserslist-config-openmrs" diff --git a/packages/esm-patient-attachments-app/src/attachments/delete-attachment-confirmation-modal.component.tsx b/packages/esm-patient-attachments-app/src/attachments/delete-attachment.modal.tsx similarity index 95% rename from packages/esm-patient-attachments-app/src/attachments/delete-attachment-confirmation-modal.component.tsx rename to packages/esm-patient-attachments-app/src/attachments/delete-attachment.modal.tsx index 16d8d26f91..244a5e59c1 100644 --- a/packages/esm-patient-attachments-app/src/attachments/delete-attachment-confirmation-modal.component.tsx +++ b/packages/esm-patient-attachments-app/src/attachments/delete-attachment.modal.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { Button, ModalHeader, ModalBody, ModalFooter } from '@carbon/react'; import { type Attachment } from '@openmrs/esm-framework'; -import styles from './delete-attachment-confirmation-modal.scss'; +import styles from './delete-attachment.scss'; interface DeleteAttachmentConfirmationProps { attachment: Attachment; diff --git a/packages/esm-patient-attachments-app/src/attachments/delete-attachment-confirmation-modal.scss b/packages/esm-patient-attachments-app/src/attachments/delete-attachment.scss similarity index 100% rename from packages/esm-patient-attachments-app/src/attachments/delete-attachment-confirmation-modal.scss rename to packages/esm-patient-attachments-app/src/attachments/delete-attachment.scss diff --git a/packages/esm-patient-attachments-app/src/index.ts b/packages/esm-patient-attachments-app/src/index.ts index e8454c43e4..a215c7e7ab 100644 --- a/packages/esm-patient-attachments-app/src/index.ts +++ b/packages/esm-patient-attachments-app/src/index.ts @@ -42,10 +42,7 @@ export const capturePhotoWidget = getAsyncLifecycle(() => import('./camera-media moduleName, }); -export const deleteAttachmentModal = getAsyncLifecycle( - () => import('./attachments/delete-attachment-confirmation-modal.component'), - { - featureName: 'delete-attachment-modal', - moduleName, - }, -); +export const deleteAttachmentModal = getAsyncLifecycle(() => import('./attachments/delete-attachment.modal'), { + featureName: 'delete-attachment-modal', + moduleName, +}); diff --git a/packages/esm-patient-banner-app/package.json b/packages/esm-patient-banner-app/package.json index ea7afc2680..989e2aad50 100644 --- a/packages/esm-patient-banner-app/package.json +++ b/packages/esm-patient-banner-app/package.json @@ -17,7 +17,7 @@ "test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js --color", "coverage": "yarn test --coverage", "typescript": "tsc", - "extract-translations": "i18next 'src/**/*.component.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" + "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.modal.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" }, "browserslist": [ "extends browserslist-config-openmrs" diff --git a/packages/esm-patient-banner-app/src/banner-tags/print-identifier-sticker-modal.test.tsx b/packages/esm-patient-banner-app/src/banner-tags/print-identifier-sticker-modal.test.tsx index 0e024171bc..a5ae2a24f3 100644 --- a/packages/esm-patient-banner-app/src/banner-tags/print-identifier-sticker-modal.test.tsx +++ b/packages/esm-patient-banner-app/src/banner-tags/print-identifier-sticker-modal.test.tsx @@ -3,7 +3,7 @@ import userEvent from '@testing-library/user-event'; import { render, screen } from '@testing-library/react'; import { useReactToPrint } from 'react-to-print'; import { mockPatient } from 'tools'; -import PrintIdentifierSticker from './print-identifier-sticker-modal.component'; +import PrintIdentifierSticker from './print-identifier-sticker.modal'; const mockedCloseModal = jest.fn(); const mockedUseReactToPrint = jest.mocked(useReactToPrint); diff --git a/packages/esm-patient-banner-app/src/banner-tags/print-identifier-sticker-modal.component.tsx b/packages/esm-patient-banner-app/src/banner-tags/print-identifier-sticker.modal.tsx similarity index 98% rename from packages/esm-patient-banner-app/src/banner-tags/print-identifier-sticker-modal.component.tsx rename to packages/esm-patient-banner-app/src/banner-tags/print-identifier-sticker.modal.tsx index fbe5e3739f..e05045e58f 100644 --- a/packages/esm-patient-banner-app/src/banner-tags/print-identifier-sticker-modal.component.tsx +++ b/packages/esm-patient-banner-app/src/banner-tags/print-identifier-sticker.modal.tsx @@ -4,7 +4,7 @@ import { useReactToPrint } from 'react-to-print'; import { Button, InlineLoading, ModalBody, ModalFooter, ModalHeader } from '@carbon/react'; import { age, displayName, showSnackbar, useConfig } from '@openmrs/esm-framework'; import { type ConfigObject } from '../config-schema'; -import styles from './print-identifier-sticker-modal.scss'; +import styles from './print-identifier-sticker.scss'; interface PrintIdentifierStickerProps { closeModal: () => void; diff --git a/packages/esm-patient-banner-app/src/banner-tags/print-identifier-sticker-modal.scss b/packages/esm-patient-banner-app/src/banner-tags/print-identifier-sticker.scss similarity index 100% rename from packages/esm-patient-banner-app/src/banner-tags/print-identifier-sticker-modal.scss rename to packages/esm-patient-banner-app/src/banner-tags/print-identifier-sticker.scss diff --git a/packages/esm-patient-banner-app/src/index.ts b/packages/esm-patient-banner-app/src/index.ts index b8c655a887..8a538bfbd1 100644 --- a/packages/esm-patient-banner-app/src/index.ts +++ b/packages/esm-patient-banner-app/src/index.ts @@ -35,7 +35,7 @@ export const deceasedPatientTag = getSyncLifecycle(deceasedPatientTagComponent, export const patientBanner = getSyncLifecycle(patientBannerComponent, options); export const printIdentifierStickerModal = getAsyncLifecycle( - () => import('./banner-tags/print-identifier-sticker-modal.component'), + () => import('./banner-tags/print-identifier-sticker.modal'), options, ); diff --git a/packages/esm-patient-chart-app/package.json b/packages/esm-patient-chart-app/package.json index fe102ad712..21dcd6d2be 100644 --- a/packages/esm-patient-chart-app/package.json +++ b/packages/esm-patient-chart-app/package.json @@ -17,7 +17,7 @@ "test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js --color", "coverage": "yarn test --coverage", "typescript": "tsc", - "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.hook.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" + "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.modal.tsx' 'src/**/*.hook.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" }, "browserslist": [ "extends browserslist-config-openmrs" diff --git a/packages/esm-patient-chart-app/src/deceased/mark-alive-modal.component.tsx b/packages/esm-patient-chart-app/src/deceased/mark-alive.modal.tsx similarity index 100% rename from packages/esm-patient-chart-app/src/deceased/mark-alive-modal.component.tsx rename to packages/esm-patient-chart-app/src/deceased/mark-alive.modal.tsx diff --git a/packages/esm-patient-chart-app/src/index.ts b/packages/esm-patient-chart-app/src/index.ts index 2290b7badf..9c2698ca6a 100644 --- a/packages/esm-patient-chart-app/src/index.ts +++ b/packages/esm-patient-chart-app/src/index.ts @@ -187,13 +187,10 @@ export const deleteVisitDialog = getAsyncLifecycle(() => import('./visit/visit-p moduleName, }); -export const modifyVisitDateDialog = getAsyncLifecycle( - () => import('./visit/visit-prompt/modify-visit-date-dialog.component'), - { - featureName: 'delete visit', - moduleName, - }, -); +export const modifyVisitDateDialog = getAsyncLifecycle(() => import('./visit/visit-prompt/modify-visit-date.modal'), { + featureName: 'delete visit', + moduleName, +}); export const endVisitDialog = getAsyncLifecycle(() => import('./visit/visit-prompt/end-visit-dialog.component'), { featureName: 'end visit', @@ -205,13 +202,13 @@ export const confirmDeceasedDialog = getAsyncLifecycle(() => import('./deceased/ moduleName, }); -export const confirmAliveDialog = getAsyncLifecycle(() => import('./deceased/mark-alive-modal.component'), { +export const confirmAliveDialog = getAsyncLifecycle(() => import('./deceased/mark-alive.modal'), { featureName: 'confirm alive', moduleName, }); export const deleteEncounterModal = getAsyncLifecycle( - () => import('./visit/visits-widget/past-visits-components/delete-encounter-modal.component'), + () => import('./visit/visits-widget/past-visits-components/delete-encounter.modal'), { featureName: 'delete-encounter-modal', moduleName, diff --git a/packages/esm-patient-chart-app/src/visit/visit-prompt/modify-visit-date-dialog.component.tsx b/packages/esm-patient-chart-app/src/visit/visit-prompt/modify-visit-date.modal.tsx similarity index 100% rename from packages/esm-patient-chart-app/src/visit/visit-prompt/modify-visit-date-dialog.component.tsx rename to packages/esm-patient-chart-app/src/visit/visit-prompt/modify-visit-date.modal.tsx diff --git a/packages/esm-patient-chart-app/src/visit/visits-widget/past-visits-components/delete-encounter-modal.component.tsx b/packages/esm-patient-chart-app/src/visit/visits-widget/past-visits-components/delete-encounter.modal.tsx similarity index 100% rename from packages/esm-patient-chart-app/src/visit/visits-widget/past-visits-components/delete-encounter-modal.component.tsx rename to packages/esm-patient-chart-app/src/visit/visits-widget/past-visits-components/delete-encounter.modal.tsx diff --git a/packages/esm-patient-chart-app/translations/en.json b/packages/esm-patient-chart-app/translations/en.json index 38430306ca..bee0f7e9f6 100644 --- a/packages/esm-patient-chart-app/translations/en.json +++ b/packages/esm-patient-chart-app/translations/en.json @@ -80,7 +80,7 @@ "location": "Location", "male": "Male", "markAlive": "Mark alive", - "markAsAlive": "Mark as alive", + "markAsAlive": "Mark As Alive", "markAsDeceased": "Are you sure you want to mark patient as deceased?", "markDeceased": "Mark deceased", "markingPatientDeceasedInfoText": "Marking the patient as deceased will end any active visits for this patient", diff --git a/packages/esm-patient-conditions-app/package.json b/packages/esm-patient-conditions-app/package.json index 0595a3f54f..4485058d07 100644 --- a/packages/esm-patient-conditions-app/package.json +++ b/packages/esm-patient-conditions-app/package.json @@ -17,7 +17,7 @@ "test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js --color", "coverage": "yarn test --coverage", "typescript": "tsc", - "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.extension.tsx' 'src/**/*.workspace.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" + "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.modal.tsx' 'src/**/*.extension.tsx' 'src/**/*.workspace.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" }, "browserslist": [ "extends browserslist-config-openmrs" diff --git a/packages/esm-patient-conditions-app/src/conditions/delete-condition-modal.component.tsx b/packages/esm-patient-conditions-app/src/conditions/delete-condition.modal.tsx similarity index 100% rename from packages/esm-patient-conditions-app/src/conditions/delete-condition-modal.component.tsx rename to packages/esm-patient-conditions-app/src/conditions/delete-condition.modal.tsx diff --git a/packages/esm-patient-conditions-app/src/index.ts b/packages/esm-patient-conditions-app/src/index.ts index 92c7cf86f4..c7d2da387d 100644 --- a/packages/esm-patient-conditions-app/src/index.ts +++ b/packages/esm-patient-conditions-app/src/index.ts @@ -35,7 +35,7 @@ export const conditionsDashboardLink = ); export const conditionDeleteConfirmationDialog = getAsyncLifecycle( - () => import('./conditions/delete-condition-modal.component'), + () => import('./conditions/delete-condition.modal'), options, ); diff --git a/packages/esm-patient-flags-app/package.json b/packages/esm-patient-flags-app/package.json index db4e43aadd..6e19ab9c48 100644 --- a/packages/esm-patient-flags-app/package.json +++ b/packages/esm-patient-flags-app/package.json @@ -17,7 +17,7 @@ "test": "cross-env TZ=UTC jest --config jest.config.js --verbose false --passWithNoTests --color", "test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js --color", "coverage": "yarn test --coverage", - "extract-translations": "i18next 'src/**/*.component.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" + "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.modal.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" }, "browserslist": [ "extends browserslist-config-openmrs" diff --git a/packages/esm-patient-forms-app/package.json b/packages/esm-patient-forms-app/package.json index 08db9a6f3f..3d6f1c6073 100644 --- a/packages/esm-patient-forms-app/package.json +++ b/packages/esm-patient-forms-app/package.json @@ -17,7 +17,7 @@ "test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js --color", "coverage": "yarn test --coverage", "typescript": "tsc", - "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.extension.tsx' 'src/**/*.workspace.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" + "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.modal.tsx' 'src/**/*.extension.tsx' 'src/**/*.workspace.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" }, "browserslist": [ "extends browserslist-config-openmrs" diff --git a/packages/esm-patient-immunizations-app/package.json b/packages/esm-patient-immunizations-app/package.json index ba923e8a8b..9032d4e463 100644 --- a/packages/esm-patient-immunizations-app/package.json +++ b/packages/esm-patient-immunizations-app/package.json @@ -17,7 +17,7 @@ "test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js --color", "coverage": "yarn test --coverage", "typescript": "tsc", - "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.extension.tsx' 'src/**/*.workspace.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" + "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.modal.tsx' 'src/**/*.extension.tsx' 'src/**/*.workspace.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" }, "browserslist": [ "extends browserslist-config-openmrs" diff --git a/packages/esm-patient-labs-app/package.json b/packages/esm-patient-labs-app/package.json index e881bea5ca..0b8e950e00 100644 --- a/packages/esm-patient-labs-app/package.json +++ b/packages/esm-patient-labs-app/package.json @@ -17,7 +17,7 @@ "test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js --color", "coverage": "yarn test --coverage", "typescript": "tsc", - "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.extension.tsx' 'src/**/*.workspace.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" + "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.modal.tsx' 'src/**/*.extension.tsx' 'src/**/*.workspace.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" }, "browserslist": [ "extends browserslist-config-openmrs" diff --git a/packages/esm-patient-lists-app/package.json b/packages/esm-patient-lists-app/package.json index accebf22df..2c227e4039 100644 --- a/packages/esm-patient-lists-app/package.json +++ b/packages/esm-patient-lists-app/package.json @@ -17,7 +17,7 @@ "test": "cross-env TZ=UTC jest --config jest.config.js --verbose false --passWithNoTests --color", "test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js --color", "coverage": "yarn test --coverage", - "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.extension.tsx' 'src/**/*.workspace.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" + "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.modal.tsx' 'src/**/*.extension.tsx' 'src/**/*.workspace.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" }, "browserslist": [ "extends browserslist-config-openmrs" diff --git a/packages/esm-patient-medications-app/package.json b/packages/esm-patient-medications-app/package.json index 8484322b98..4eaf30df83 100644 --- a/packages/esm-patient-medications-app/package.json +++ b/packages/esm-patient-medications-app/package.json @@ -17,7 +17,7 @@ "test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js --color", "coverage": "yarn test --coverage", "typescript": "tsc", - "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.extension.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" + "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.modal.tsx' 'src/**/*.extension.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" }, "browserslist": [ "extends browserslist-config-openmrs" diff --git a/packages/esm-patient-notes-app/package.json b/packages/esm-patient-notes-app/package.json index 4548a65d46..82493dda70 100644 --- a/packages/esm-patient-notes-app/package.json +++ b/packages/esm-patient-notes-app/package.json @@ -17,7 +17,7 @@ "test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js --color", "coverage": "yarn test --coverage", "typescript": "tsc", - "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.extension.tsx' 'src/**/*.workspace.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" + "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.modal.tsx' 'src/**/*.extension.tsx' 'src/**/*.workspace.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" }, "browserslist": [ "extends browserslist-config-openmrs" diff --git a/packages/esm-patient-orders-app/package.json b/packages/esm-patient-orders-app/package.json index 862e0104e3..f9eae9f058 100644 --- a/packages/esm-patient-orders-app/package.json +++ b/packages/esm-patient-orders-app/package.json @@ -17,7 +17,7 @@ "test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js --color", "coverage": "yarn test --coverage", "typescript": "tsc", - "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.extension.tsx' 'src/**/*.workspace.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" + "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.modal.tsx' 'src/**/*.extension.tsx' 'src/**/*.workspace.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" }, "browserslist": [ "extends browserslist-config-openmrs" diff --git a/packages/esm-patient-programs-app/package.json b/packages/esm-patient-programs-app/package.json index 5062c7dade..2864fc2948 100644 --- a/packages/esm-patient-programs-app/package.json +++ b/packages/esm-patient-programs-app/package.json @@ -17,7 +17,7 @@ "test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js --color", "coverage": "yarn test --coverage", "typescript": "tsc", - "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.extension.tsx' 'src/**/*.workspace.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" + "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.modal.tsx' 'src/**/*.extension.tsx' 'src/**/*.workspace.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" }, "browserslist": [ "extends browserslist-config-openmrs" diff --git a/packages/esm-patient-vitals-app/package.json b/packages/esm-patient-vitals-app/package.json index e71b8e796a..2dbfdd7afb 100644 --- a/packages/esm-patient-vitals-app/package.json +++ b/packages/esm-patient-vitals-app/package.json @@ -17,7 +17,7 @@ "test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js --color", "coverage": "yarn test --coverage", "typescript": "tsc", - "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.extension.tsx' 'src/**/*.workspace.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" + "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.modal.tsx' 'src/**/*.extension.tsx' 'src/**/*.workspace.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" }, "browserslist": [ "extends browserslist-config-openmrs" diff --git a/packages/esm-patient-vitals-app/src/index.ts b/packages/esm-patient-vitals-app/src/index.ts index 95a3136d79..772e652c42 100644 --- a/packages/esm-patient-vitals-app/src/index.ts +++ b/packages/esm-patient-vitals-app/src/index.ts @@ -61,7 +61,7 @@ export const vitalsAndBiometricsDashboardLink = export const weightTile = getAsyncLifecycle(() => import('./weight-tile/weight-tile.component'), options); export const vitalsAndBiometricsDeleteModal = getAsyncLifecycle( - () => import('./vitals-biometrics-form/delete-vitals-biometrics-modal.component'), + () => import('./vitals-biometrics-form/delete-vitals-and-biometrics.modal'), options, ); diff --git a/packages/esm-patient-vitals-app/src/vitals-biometrics-form/delete-vitals-biometrics-modal.component.tsx b/packages/esm-patient-vitals-app/src/vitals-biometrics-form/delete-vitals-and-biometrics.modal.tsx similarity index 100% rename from packages/esm-patient-vitals-app/src/vitals-biometrics-form/delete-vitals-biometrics-modal.component.tsx rename to packages/esm-patient-vitals-app/src/vitals-biometrics-form/delete-vitals-and-biometrics.modal.tsx diff --git a/packages/esm-patient-vitals-app/translations/en.json b/packages/esm-patient-vitals-app/translations/en.json index ae4a5313a1..38be9842c5 100644 --- a/packages/esm-patient-vitals-app/translations/en.json +++ b/packages/esm-patient-vitals-app/translations/en.json @@ -60,7 +60,7 @@ "Vitals & Biometrics": "Vitals & Biometrics", "vitalsAndBiometrics": "Vitals and biometrics", "vitalsAndBiometricsDeleted": "Vitals and Biometrics deleted", - "vitalsAndBiometricsDeleteError": "Error deleting vitals and biometrics", + "vitalsAndBiometricsDeleteError": "Error deleting Vitals and Biometrics", "vitalsAndBiometricsEditError": "Error editing vitals and biometrics", "vitalsAndBiometricsNowAvailable": "They are now visible on the Vitals and Biometrics page", "vitalsAndBiometricsRecorded": "Vitals and Biometrics saved", From 08190800482d14ef4bcc6f4fa2e577fdc2262395 Mon Sep 17 00:00:00 2001 From: Dennis Kigen Date: Fri, 21 Jun 2024 21:44:15 +0300 Subject: [PATCH 2/3] (refactor) O3-3445: Action button items should use the OverflowMenuItem component (#1869) * (refactor) O3-3445: Action button items in the patient banner should use OverflowMenuItem * Rename closeModal function for consistency --- .../src/actions-buttons/action-button.scss | 3 +++ .../add-past-visit.component.tsx | 27 +++++++------------ .../cancel-visit.component.tsx | 25 +++++++---------- .../mark-patient-alive.component.tsx | 14 +++++----- .../mark-patient-deceased.component.tsx | 12 ++++----- .../print-identifier-sticker.component.tsx | 11 ++++---- .../actions-buttons/start-visit.component.tsx | 24 +++++++---------- .../actions-buttons/stop-visit.component.tsx | 23 ++++++---------- .../confirmation-dialog.component.tsx | 10 +++---- .../src/deceased/deceased-form.component.tsx | 3 +-- .../src/deceased/mark-alive.modal.tsx | 12 ++++----- 11 files changed, 68 insertions(+), 96 deletions(-) create mode 100644 packages/esm-patient-chart-app/src/actions-buttons/action-button.scss diff --git a/packages/esm-patient-chart-app/src/actions-buttons/action-button.scss b/packages/esm-patient-chart-app/src/actions-buttons/action-button.scss new file mode 100644 index 0000000000..2a7fdf7d6c --- /dev/null +++ b/packages/esm-patient-chart-app/src/actions-buttons/action-button.scss @@ -0,0 +1,3 @@ +.menuitem { + max-width: none; +} diff --git a/packages/esm-patient-chart-app/src/actions-buttons/add-past-visit.component.tsx b/packages/esm-patient-chart-app/src/actions-buttons/add-past-visit.component.tsx index 36f84bae3c..1a2a4a6352 100644 --- a/packages/esm-patient-chart-app/src/actions-buttons/add-past-visit.component.tsx +++ b/packages/esm-patient-chart-app/src/actions-buttons/add-past-visit.component.tsx @@ -1,6 +1,8 @@ import React, { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; +import { OverflowMenuItem } from '@carbon/react'; import { showModal } from '@openmrs/esm-framework'; +import styles from './action-button.scss'; interface AddPastVisitOverflowMenuItemProps { patientUuid?: string; @@ -13,29 +15,20 @@ const AddPastVisitOverflowMenuItem: React.FC }) => { const { t } = useTranslation(); - const openModal = useCallback(() => { + const handleLaunchModal = useCallback(() => { const dispose = showModal('start-visit-dialog', { - patientUuid, - launchPatientChart, closeModal: () => dispose(), + launchPatientChart, + patientUuid, }); }, [patientUuid, launchPatientChart]); return ( -
  • - -
  • + ); }; diff --git a/packages/esm-patient-chart-app/src/actions-buttons/cancel-visit.component.tsx b/packages/esm-patient-chart-app/src/actions-buttons/cancel-visit.component.tsx index 33dfce1d21..8a4a609354 100644 --- a/packages/esm-patient-chart-app/src/actions-buttons/cancel-visit.component.tsx +++ b/packages/esm-patient-chart-app/src/actions-buttons/cancel-visit.component.tsx @@ -1,6 +1,8 @@ import React, { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; +import { OverflowMenuItem } from '@carbon/react'; import { useVisit, showModal } from '@openmrs/esm-framework'; +import styles from './action-button.scss'; interface CancelVisitOverflowMenuItemProps { patientUuid: string; @@ -8,9 +10,9 @@ interface CancelVisitOverflowMenuItemProps { const CancelVisitOverflowMenuItem: React.FC = ({ patientUuid }) => { const { t } = useTranslation(); - const { currentVisit } = useVisit(patientUuid); - const openModal = useCallback(() => { + + const handleLaunchModal = useCallback(() => { const dispose = showModal('cancel-visit-dialog', { closeModal: () => dispose(), patientUuid, @@ -19,20 +21,11 @@ const CancelVisitOverflowMenuItem: React.FC = return ( currentVisit && ( -
  • - -
  • + ) ); }; diff --git a/packages/esm-patient-chart-app/src/actions-buttons/mark-patient-alive.component.tsx b/packages/esm-patient-chart-app/src/actions-buttons/mark-patient-alive.component.tsx index 8af40d8af3..57cbfea83e 100644 --- a/packages/esm-patient-chart-app/src/actions-buttons/mark-patient-alive.component.tsx +++ b/packages/esm-patient-chart-app/src/actions-buttons/mark-patient-alive.component.tsx @@ -1,8 +1,9 @@ import React, { useCallback } from 'react'; -import { OverflowMenuItem } from '@carbon/react'; import { useTranslation } from 'react-i18next'; +import { OverflowMenuItem } from '@carbon/react'; import { showModal } from '@openmrs/esm-framework'; import { usePatientDeceased } from '../deceased/deceased.resource'; +import styles from './action-button.scss'; interface MarkPatientAliveOverflowMenuItemProps { patientUuid?: string; @@ -10,13 +11,12 @@ interface MarkPatientAliveOverflowMenuItemProps { const MarkPatientAliveOverflowMenuItem: React.FC = ({ patientUuid }) => { const { t } = useTranslation(); - const { isDead, isLoading: isPatientLoading } = usePatientDeceased(patientUuid); - const openModal = useCallback(() => { + const handleLaunchModal = useCallback(() => { const dispose = showModal('confirm-alive-modal', { patientUuid, - closeDialog: () => dispose(), + closeModal: () => dispose(), }); }, [patientUuid]); @@ -24,11 +24,9 @@ const MarkPatientAliveOverflowMenuItem: React.FC ) ); diff --git a/packages/esm-patient-chart-app/src/actions-buttons/mark-patient-deceased.component.tsx b/packages/esm-patient-chart-app/src/actions-buttons/mark-patient-deceased.component.tsx index 174916770c..8455f54363 100644 --- a/packages/esm-patient-chart-app/src/actions-buttons/mark-patient-deceased.component.tsx +++ b/packages/esm-patient-chart-app/src/actions-buttons/mark-patient-deceased.component.tsx @@ -1,23 +1,23 @@ import React, { useCallback } from 'react'; -import { OverflowMenuItem } from '@carbon/react'; import { useTranslation } from 'react-i18next'; +import { OverflowMenuItem } from '@carbon/react'; import { launchPatientWorkspace } from '@openmrs/esm-patient-common-lib'; import { usePatientDeceased } from '../deceased/deceased.resource'; +import styles from './action-button.scss'; const MarkPatientDeceasedOverflowMenuItem = ({ patientUuid }) => { const { t } = useTranslation(); - const handleClick = useCallback(() => launchPatientWorkspace('mark-patient-deceased-workspace-form'), []); const { isDead, isLoading: isPatientLoading } = usePatientDeceased(patientUuid); + const handleLaunchModal = useCallback(() => launchPatientWorkspace('mark-patient-deceased-workspace-form'), []); + return ( !isPatientLoading && !isDead && ( ) ); diff --git a/packages/esm-patient-chart-app/src/actions-buttons/print-identifier-sticker.component.tsx b/packages/esm-patient-chart-app/src/actions-buttons/print-identifier-sticker.component.tsx index 33d8aa9e59..f56b8001fd 100644 --- a/packages/esm-patient-chart-app/src/actions-buttons/print-identifier-sticker.component.tsx +++ b/packages/esm-patient-chart-app/src/actions-buttons/print-identifier-sticker.component.tsx @@ -1,7 +1,8 @@ import React, { useCallback } from 'react'; -import { OverflowMenuItem } from '@carbon/react'; import { useTranslation } from 'react-i18next'; +import { OverflowMenuItem } from '@carbon/react'; import { showModal, useConfig, usePatient } from '@openmrs/esm-framework'; +import styles from './action-button.scss'; interface PrintIdentifierStickerOverflowMenuItemProps { patientUuid: string; @@ -16,7 +17,7 @@ const PrintIdentifierStickerOverflowMenuItem: React.FC { + const handleLaunchModal = useCallback(() => { const dispose = showModal('print-identifier-sticker-modal', { closeModal: () => dispose(), patient, @@ -27,11 +28,9 @@ const PrintIdentifierStickerOverflowMenuItem: React.FC ) ); diff --git a/packages/esm-patient-chart-app/src/actions-buttons/start-visit.component.tsx b/packages/esm-patient-chart-app/src/actions-buttons/start-visit.component.tsx index 3f54137f70..92a83a6ab0 100644 --- a/packages/esm-patient-chart-app/src/actions-buttons/start-visit.component.tsx +++ b/packages/esm-patient-chart-app/src/actions-buttons/start-visit.component.tsx @@ -1,7 +1,9 @@ import React, { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; +import { OverflowMenuItem } from '@carbon/react'; import { usePatient, useVisit } from '@openmrs/esm-framework'; import { launchPatientWorkspace } from '@openmrs/esm-patient-common-lib'; +import styles from './action-button.scss'; interface StartVisitOverflowMenuItemProps { patientUuid: string; @@ -11,26 +13,18 @@ const StartVisitOverflowMenuItem: React.FC = ({ const { t } = useTranslation(); const { currentVisit } = useVisit(patientUuid); const { patient } = usePatient(patientUuid); - const handleClick = useCallback(() => launchPatientWorkspace('start-visit-workspace-form'), []); - const isDeceased = Boolean(patient?.deceasedDateTime); + const handleLaunchModal = useCallback(() => launchPatientWorkspace('start-visit-workspace-form'), []); + return ( !currentVisit && !isDeceased && ( -
  • - -
  • + ) ); }; diff --git a/packages/esm-patient-chart-app/src/actions-buttons/stop-visit.component.tsx b/packages/esm-patient-chart-app/src/actions-buttons/stop-visit.component.tsx index e9b4c5808e..3f00db6ff6 100644 --- a/packages/esm-patient-chart-app/src/actions-buttons/stop-visit.component.tsx +++ b/packages/esm-patient-chart-app/src/actions-buttons/stop-visit.component.tsx @@ -1,6 +1,8 @@ import React, { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { showModal, useVisit } from '@openmrs/esm-framework'; +import { OverflowMenuItem } from '@carbon/react'; +import styles from './action-button.scss'; interface StopVisitOverflowMenuItemProps { patientUuid: string; @@ -10,7 +12,7 @@ const StopVisitOverflowMenuItem: React.FC = ({ p const { t } = useTranslation(); const { currentVisit } = useVisit(patientUuid); - const openModal = useCallback(() => { + const handleLaunchModal = useCallback(() => { const dispose = showModal('end-visit-dialog', { closeModal: () => dispose(), patientUuid, @@ -19,20 +21,11 @@ const StopVisitOverflowMenuItem: React.FC = ({ p return ( currentVisit && ( -
  • - -
  • + ) ); }; diff --git a/packages/esm-patient-chart-app/src/deceased/confirmation-dialog.component.tsx b/packages/esm-patient-chart-app/src/deceased/confirmation-dialog.component.tsx index e8e405229c..7d073936ce 100644 --- a/packages/esm-patient-chart-app/src/deceased/confirmation-dialog.component.tsx +++ b/packages/esm-patient-chart-app/src/deceased/confirmation-dialog.component.tsx @@ -4,25 +4,25 @@ import { Button, ModalBody, ModalFooter, ModalHeader } from '@carbon/react'; import { useTranslation } from 'react-i18next'; interface ConfirmationDialogProps { - closeDialog: () => void; + closeModal: () => void; handleSubmit: (e: any) => void; } -const ConfirmMarkAsDeceasedDialog: React.FC = ({ closeDialog, handleSubmit }) => { +const ConfirmMarkAsDeceasedDialog: React.FC = ({ closeModal, handleSubmit }) => { const { t } = useTranslation(); return (
    - + {t('markAsDeceased', 'Are you sure you want to mark patient as deceased?')} - From 93806802694e4ff46ae5387bf18b36c3f2490130 Mon Sep 17 00:00:00 2001 From: Dennis Kigen Date: Fri, 21 Jun 2024 22:44:27 +0300 Subject: [PATCH 3/3] (refactor) Refactor Mark patient deceased form and Mark patient alive modal (#1872) * (refactor) Refactor Mark patient deceased form and Mark patient alive modal * Fixup * Show cause of death in banner tag --- .../deceased-patient-tag.extension.tsx | 12 +- .../src/banner-tags/useCauseOfDeath.ts | 28 +++ packages/esm-patient-chart-app/package.json | 2 +- .../mark-patient-alive.component.tsx | 12 +- .../mark-patient-deceased.component.tsx | 6 +- .../deceased.resource.ts => data.resource.ts} | 36 +-- .../base-concept-answer.component.tsx | 86 ------- .../confirmation-dialog.component.tsx | 36 --- .../src/deceased/deceased-form.component.tsx | 142 ----------- .../src/deceased/mark-alive.modal.tsx | 55 ---- packages/esm-patient-chart-app/src/index.ts | 53 ++-- .../mark-patient-alive.modal.tsx | 50 ++++ .../mark-patient-deceased-form.scss} | 67 +++-- .../mark-patient-deceased-form.workspace.tsx | 238 ++++++++++++++++++ .../esm-patient-chart-app/src/routes.json | 33 ++- .../translations/en.json | 27 +- 16 files changed, 453 insertions(+), 430 deletions(-) create mode 100644 packages/esm-patient-banner-app/src/banner-tags/useCauseOfDeath.ts rename packages/esm-patient-chart-app/src/{deceased/deceased.resource.ts => data.resource.ts} (87%) delete mode 100644 packages/esm-patient-chart-app/src/deceased/base-concept-answer.component.tsx delete mode 100644 packages/esm-patient-chart-app/src/deceased/confirmation-dialog.component.tsx delete mode 100644 packages/esm-patient-chart-app/src/deceased/deceased-form.component.tsx delete mode 100644 packages/esm-patient-chart-app/src/deceased/mark-alive.modal.tsx create mode 100644 packages/esm-patient-chart-app/src/mark-patient-alive/mark-patient-alive.modal.tsx rename packages/esm-patient-chart-app/src/{deceased/deceased-form.scss => mark-patient-deceased/mark-patient-deceased-form.scss} (60%) create mode 100644 packages/esm-patient-chart-app/src/mark-patient-deceased/mark-patient-deceased-form.workspace.tsx diff --git a/packages/esm-patient-banner-app/src/banner-tags/deceased-patient-tag.extension.tsx b/packages/esm-patient-banner-app/src/banner-tags/deceased-patient-tag.extension.tsx index d3983ccdb0..48974cc505 100644 --- a/packages/esm-patient-banner-app/src/banner-tags/deceased-patient-tag.extension.tsx +++ b/packages/esm-patient-banner-app/src/banner-tags/deceased-patient-tag.extension.tsx @@ -1,15 +1,18 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; -import { Tag, DefinitionTooltip } from '@carbon/react'; +import { DefinitionTooltip, Tag } from '@carbon/react'; import { formatDatetime, parseDate } from '@openmrs/esm-framework'; +import { useCauseOfDeath } from './useCauseOfDeath'; import styles from './deceased-patient-tag.scss'; interface DeceasedPatientBannerTagProps { - patient: Pick; + patient: fhir.Patient; } + const DeceasedPatientBannerTag: React.FC = ({ patient }) => { const { t } = useTranslation(); const isDeceased = Boolean(patient?.deceasedDateTime); + const { causeOfDeath } = useCauseOfDeath(patient?.id); return ( isDeceased && ( @@ -18,7 +21,10 @@ const DeceasedPatientBannerTag: React.FC = ({ pat definition={
    {t('deceased', 'Deceased')}
    - {formatDatetime(parseDate(patient?.deceasedDateTime))} + + {formatDatetime(parseDate(patient?.deceasedDateTime))} + {causeOfDeath ? ` ${t('from_lower', 'from')} ${causeOfDeath}` : null} +
    } > diff --git a/packages/esm-patient-banner-app/src/banner-tags/useCauseOfDeath.ts b/packages/esm-patient-banner-app/src/banner-tags/useCauseOfDeath.ts new file mode 100644 index 0000000000..50a80a5c62 --- /dev/null +++ b/packages/esm-patient-banner-app/src/banner-tags/useCauseOfDeath.ts @@ -0,0 +1,28 @@ +import { openmrsFetch } from '@openmrs/esm-framework'; +import { useMemo } from 'react'; +import useSWR from 'swr'; + +interface CauseOfDeathResponse { + data: { + causeOfDeath: { + display: string; + }; + }; +} + +export function useCauseOfDeath(patientUuid: string) { + const customRepresentation = 'custom:(causeOfDeath:(display)'; + const url = `/ws/rest/v1/person/${patientUuid}?v=${customRepresentation}`; + + const { data, error } = useSWR(patientUuid ? url : null, openmrsFetch); + + const results = useMemo( + () => ({ + causeOfDeath: data?.data?.causeOfDeath?.display, + error, + }), + [data?.data?.causeOfDeath, error], + ); + + return results; +} diff --git a/packages/esm-patient-chart-app/package.json b/packages/esm-patient-chart-app/package.json index 21dcd6d2be..d2b7487b8f 100644 --- a/packages/esm-patient-chart-app/package.json +++ b/packages/esm-patient-chart-app/package.json @@ -17,7 +17,7 @@ "test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js --color", "coverage": "yarn test --coverage", "typescript": "tsc", - "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.modal.tsx' 'src/**/*.hook.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" + "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.modal.tsx' 'src/**/*.workspace.tsx' 'src/**/*.hook.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js" }, "browserslist": [ "extends browserslist-config-openmrs" diff --git a/packages/esm-patient-chart-app/src/actions-buttons/mark-patient-alive.component.tsx b/packages/esm-patient-chart-app/src/actions-buttons/mark-patient-alive.component.tsx index 57cbfea83e..9132908b90 100644 --- a/packages/esm-patient-chart-app/src/actions-buttons/mark-patient-alive.component.tsx +++ b/packages/esm-patient-chart-app/src/actions-buttons/mark-patient-alive.component.tsx @@ -2,7 +2,7 @@ import React, { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { OverflowMenuItem } from '@carbon/react'; import { showModal } from '@openmrs/esm-framework'; -import { usePatientDeceased } from '../deceased/deceased.resource'; +import { usePatientDeceasedStatus } from '../data.resource'; import styles from './action-button.scss'; interface MarkPatientAliveOverflowMenuItemProps { @@ -11,21 +11,21 @@ interface MarkPatientAliveOverflowMenuItemProps { const MarkPatientAliveOverflowMenuItem: React.FC = ({ patientUuid }) => { const { t } = useTranslation(); - const { isDead, isLoading: isPatientLoading } = usePatientDeceased(patientUuid); + const { isDead, isLoading: isLoadingPatient } = usePatientDeceasedStatus(patientUuid); const handleLaunchModal = useCallback(() => { - const dispose = showModal('confirm-alive-modal', { - patientUuid, + const dispose = showModal('mark-patient-alive-modal', { closeModal: () => dispose(), + patientUuid, }); }, [patientUuid]); return ( - !isPatientLoading && + !isLoadingPatient && isDead && ( ) diff --git a/packages/esm-patient-chart-app/src/actions-buttons/mark-patient-deceased.component.tsx b/packages/esm-patient-chart-app/src/actions-buttons/mark-patient-deceased.component.tsx index 8455f54363..e35cdeb6fc 100644 --- a/packages/esm-patient-chart-app/src/actions-buttons/mark-patient-deceased.component.tsx +++ b/packages/esm-patient-chart-app/src/actions-buttons/mark-patient-deceased.component.tsx @@ -2,12 +2,12 @@ import React, { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { OverflowMenuItem } from '@carbon/react'; import { launchPatientWorkspace } from '@openmrs/esm-patient-common-lib'; -import { usePatientDeceased } from '../deceased/deceased.resource'; +import { usePatientDeceasedStatus } from '../data.resource'; import styles from './action-button.scss'; const MarkPatientDeceasedOverflowMenuItem = ({ patientUuid }) => { const { t } = useTranslation(); - const { isDead, isLoading: isPatientLoading } = usePatientDeceased(patientUuid); + const { isDead, isLoading: isPatientLoading } = usePatientDeceasedStatus(patientUuid); const handleLaunchModal = useCallback(() => launchPatientWorkspace('mark-patient-deceased-workspace-form'), []); @@ -16,7 +16,7 @@ const MarkPatientDeceasedOverflowMenuItem = ({ patientUuid }) => { !isDead && ( ) diff --git a/packages/esm-patient-chart-app/src/deceased/deceased.resource.ts b/packages/esm-patient-chart-app/src/data.resource.ts similarity index 87% rename from packages/esm-patient-chart-app/src/deceased/deceased.resource.ts rename to packages/esm-patient-chart-app/src/data.resource.ts index 00c0fd4fd0..55ad208c0f 100644 --- a/packages/esm-patient-chart-app/src/deceased/deceased.resource.ts +++ b/packages/esm-patient-chart-app/src/data.resource.ts @@ -7,34 +7,34 @@ interface CauseOfDeathFetchResponse { value: string; } -interface DeathPayload { - deathDate?: Date; - dead: boolean; - causeOfDeath?: string; -} - export interface ConceptAnswer { - uuid: string; - name: string; display: string; + name: string; + uuid: string; } interface ConceptAnswersResponse { answers?: Array; } -export function usePatientDeathConcepts() { +interface DeathPayload { + causeOfDeath?: string; + dead: boolean; + deathDate?: Date; +} + +export function useCausesOfDeath() { const { isCauseOfDeathLoading, isCauseOfDeathValidating, value: causeOfDeathConcept } = useCauseOfDeathConcept(); const { isConceptLoading, isConceptAnswerValidating, conceptAnswers } = useConceptAnswers(causeOfDeathConcept); return { - conceptAnswers: conceptAnswers, + causesOfDeath: conceptAnswers, isLoading: isCauseOfDeathLoading || isConceptLoading, isValidating: isConceptAnswerValidating || isCauseOfDeathValidating, }; } -export function usePatientDeceased(patientUuid: string) { +export function usePatientDeceasedStatus(patientUuid: string) { const { isLoading: isPatientLoading, patient } = usePatient(patientUuid); if (isPatientLoading) { @@ -67,15 +67,15 @@ export function markPatientDeceased( deceasedDate: Date, personUuid: string, selectedCauseOfDeathValue: string | undefined, - abortController: AbortController, ) { + const abortController = new AbortController(); const payload: DeathPayload = { causeOfDeath: selectedCauseOfDeathValue, dead: true, }; if (deceasedDate) { - payload.deathDate = new Date(deceasedDate.getFullYear(), deceasedDate.getMonth(), deceasedDate.getDay()); + payload.deathDate = deceasedDate; } else { payload.deathDate = null; } @@ -83,13 +83,14 @@ export function markPatientDeceased( return changePatientDeathStatus(personUuid, payload, abortController); } -export function markPatientAlive(personUuid: string, abortController: AbortController) { +export function markPatientAlive(personUuid: string) { + const abortController = new AbortController(); return changePatientDeathStatus( personUuid, { - deathDate: null, causeOfDeath: null, dead: false, + deathDate: null, }, abortController, ); @@ -115,7 +116,7 @@ export function useConceptAnswers(conceptUuid: string) { } export function useCauseOfDeathConcept() { - const { data, error, isLoading, isValidating } = useSWR<{ data: CauseOfDeathFetchResponse }>( + const { data, error, isLoading, isValidating } = useSWR<{ data: CauseOfDeathFetchResponse }, Error>( `${restBaseUrl}/systemsetting/concept.causeOfDeath`, openmrsFetch, { @@ -129,7 +130,8 @@ export function useCauseOfDeathConcept() { value: data?.data?.value ?? undefined, isCauseOfDeathLoading: isLoading, isCauseOfDeathValidating: isValidating, + error, }; - }, [data, isLoading, isValidating]); + }, [data?.data?.value, error, isLoading, isValidating]); return result; } diff --git a/packages/esm-patient-chart-app/src/deceased/base-concept-answer.component.tsx b/packages/esm-patient-chart-app/src/deceased/base-concept-answer.component.tsx deleted file mode 100644 index 712ad26139..0000000000 --- a/packages/esm-patient-chart-app/src/deceased/base-concept-answer.component.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import React, { useState, useMemo } from 'react'; -import { useTranslation } from 'react-i18next'; -import classNames from 'classnames'; -import debounce from 'lodash-es/debounce'; -import isEmpty from 'lodash-es/isEmpty'; -import { RadioButton, RadioButtonGroup, Search } from '@carbon/react'; -import { EmptyState, PatientChartPagination } from '@openmrs/esm-patient-common-lib'; -import { useLayoutType, usePagination, ResponsiveWrapper } from '@openmrs/esm-framework'; -import type { ConceptAnswer } from './deceased.resource'; -import styles from './deceased-form.scss'; - -interface BaseConceptAnswerProps { - onChange: (event) => void; - isPatientDead: boolean; - conceptAnswers; -} - -const BaseConceptAnswer: React.FC = ({ onChange, isPatientDead, conceptAnswers }) => { - const { t } = useTranslation(); - const isTablet = useLayoutType() === 'tablet'; - const [searchTerm, setSearchTerm] = useState(''); - - const searchResults = useMemo(() => { - if (!isEmpty(searchTerm)) { - return conceptAnswers.filter( - (conceptAnswer) => conceptAnswer.display.toLowerCase().search(searchTerm.toLowerCase()) !== -1, - ); - } else { - return conceptAnswers; - } - }, [searchTerm, conceptAnswers]); - - const handleSearch = React.useMemo(() => debounce((searchTerm) => setSearchTerm(searchTerm), 300), [setSearchTerm]); - - const { results, currentPage, goTo } = usePagination(searchResults, 10); - - return ( -
    - - handleSearch(event.target.value)} - placeholder={t('searchForCauseOfDeath', 'Search for a cause of death')} - labelText="" - /> - - - {results.length ? ( - <> - - {results?.map(({ uuid, display, name }) => ( - - ))} - -
    - goTo(page)} - /> -
    - - ) : ( - - )} -
    - ); -}; - -export default BaseConceptAnswer; diff --git a/packages/esm-patient-chart-app/src/deceased/confirmation-dialog.component.tsx b/packages/esm-patient-chart-app/src/deceased/confirmation-dialog.component.tsx deleted file mode 100644 index 7d073936ce..0000000000 --- a/packages/esm-patient-chart-app/src/deceased/confirmation-dialog.component.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react'; - -import { Button, ModalBody, ModalFooter, ModalHeader } from '@carbon/react'; -import { useTranslation } from 'react-i18next'; - -interface ConfirmationDialogProps { - closeModal: () => void; - handleSubmit: (e: any) => void; -} - -const ConfirmMarkAsDeceasedDialog: React.FC = ({ closeModal, handleSubmit }) => { - const { t } = useTranslation(); - - return ( -
    - - {t('markAsDeceased', 'Are you sure you want to mark patient as deceased?')} - - - - -
    - ); -}; - -export default ConfirmMarkAsDeceasedDialog; diff --git a/packages/esm-patient-chart-app/src/deceased/deceased-form.component.tsx b/packages/esm-patient-chart-app/src/deceased/deceased-form.component.tsx deleted file mode 100644 index 18ad1379f5..0000000000 --- a/packages/esm-patient-chart-app/src/deceased/deceased-form.component.tsx +++ /dev/null @@ -1,142 +0,0 @@ -import React, { useState, useMemo } from 'react'; -import dayjs from 'dayjs'; -import { useTranslation } from 'react-i18next'; -import { - Button, - ButtonSet, - DatePicker, - DatePickerInput, - Form, - Row, - DatePickerSkeleton, - DataTableSkeleton, -} from '@carbon/react'; -import { WarningFilled } from '@carbon/react/icons'; -import { type DefaultPatientWorkspaceProps } from '@openmrs/esm-patient-common-lib'; -import { ExtensionSlot, useLayoutType, showSnackbar, showModal, ResponsiveWrapper } from '@openmrs/esm-framework'; -import { markPatientDeceased, usePatientDeathConcepts, usePatientDeceased } from './deceased.resource'; -import BaseConceptAnswer from './base-concept-answer.component'; -import styles from './deceased-form.scss'; - -const MarkPatientDeceasedForm: React.FC = ({ patientUuid, closeWorkspace }) => { - const { t } = useTranslation(); - const isTablet = useLayoutType() === 'tablet'; - const state = useMemo(() => ({ patientUuid }), [patientUuid]); - const [selectedCauseOfDeath, setSelectedCauseOfDeath] = useState(''); - const { conceptAnswers } = usePatientDeathConcepts(); - const { deathDate, isDead, isLoading } = usePatientDeceased(patientUuid); - const [newDeceasedDate, setNewDeceasedDate] = useState( - isDead ? new Date(dayjs(deathDate).year(), dayjs(deathDate).month(), dayjs(deathDate).date() - 1) : new Date(), - ); - - const handleSubmit = (e) => { - e.preventDefault(); - markPatientDeceased(newDeceasedDate, patientUuid, selectedCauseOfDeath, new AbortController()) - .then((response) => { - if (response.ok) { - showSnackbar({ - isLowContrast: true, - kind: 'success', - title: t('confirmDeceased', 'Confirm Deceased'), - subtitle: t('setDeceasedSuccessfully', 'Patient has been marked dead successfully'), - }); - closeWorkspace(); - } - }) - .catch((error) => { - showSnackbar({ - title: t('setDeceasedError', 'Error marking patient deceased'), - kind: 'error', - isLowContrast: false, - subtitle: error?.message, - }); - }); - }; - - const onSaveClick = () => { - const dispose = showModal('confirm-deceased-dialog', { - closeModal: () => dispose(), - handleSubmit, - }); - }; - - return ( -
    -
    - {isTablet && ( - - - - )} -
    - - - - {t( - 'markingPatientDeceasedInfoText', - 'Marking the patient as deceased will end any active visits for this patient', - )} - - -
    -
    {t('dateOfDeath', 'Date of Death')}
    - {!conceptAnswers ? ( - - ) : ( - - setNewDeceasedDate(date)} - value={newDeceasedDate} - > - - - - )} -
    -
    - {!isDead &&
    {t('causeOfDeath', 'Cause of death')}
    } - {!conceptAnswers ? ( -
    - -
    - ) : ( - { - setSelectedCauseOfDeath(answer); - }} - conceptAnswers={conceptAnswers} - isPatientDead={isDead} - /> - )} -
    -
    -
    - - - - -
    - ); -}; - -export default MarkPatientDeceasedForm; diff --git a/packages/esm-patient-chart-app/src/deceased/mark-alive.modal.tsx b/packages/esm-patient-chart-app/src/deceased/mark-alive.modal.tsx deleted file mode 100644 index bde685ce70..0000000000 --- a/packages/esm-patient-chart-app/src/deceased/mark-alive.modal.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import React from 'react'; -import { useTranslation } from 'react-i18next'; - -import { showSnackbar } from '@openmrs/esm-framework'; -import { Button, ModalFooter, ModalHeader, ModalBody } from '@carbon/react'; -import { markPatientAlive } from './deceased.resource'; - -interface ConfirmationDialogProps { - closeModal: () => void; - patientUuid: string; -} - -const MarkPatientAsAlive: React.FC = ({ closeModal, patientUuid }) => { - const { t } = useTranslation(); - - const handleSubmit = (e) => { - e.preventDefault(); - closeModal(); - markPatientAlive(patientUuid, new AbortController()) - .then((response) => { - if (response.ok) { - closeModal(); - showSnackbar({ - isLowContrast: true, - kind: 'success', - title: t('markAsAlive', 'Mark As Alive'), - subtitle: t('setAliveSuccessfully', 'Patient has been marked alive successfully'), - }); - } - }) - .catch((error) => { - showSnackbar({ - title: t('setAliveError', 'Error marking patient alive'), - kind: 'error', - isLowContrast: false, - subtitle: error?.message, - }); - }); - }; - - return ( -
    - - {t('confirmMarkAsAlive', 'Are you sure, you want to mark patient as alive?')} - - - - -
    - ); -}; - -export default MarkPatientAsAlive; diff --git a/packages/esm-patient-chart-app/src/index.ts b/packages/esm-patient-chart-app/src/index.ts index 9c2698ca6a..c39b30bbd4 100644 --- a/packages/esm-patient-chart-app/src/index.ts +++ b/packages/esm-patient-chart-app/src/index.ts @@ -1,35 +1,35 @@ import { defineConfigSchema, + defineExtensionConfigSchema, getAsyncLifecycle, getSyncLifecycle, - defineExtensionConfigSchema, registerFeatureFlag, } from '@openmrs/esm-framework'; -import { createDashboardLink } from '@openmrs/esm-patient-common-lib'; import * as PatientCommonLib from '@openmrs/esm-patient-common-lib'; +import { createDashboardLink } from '@openmrs/esm-patient-common-lib'; import { esmPatientChartSchema } from './config-schema'; -import { moduleName } from './constants'; -import { summaryDashboardMeta, encountersDashboardMeta } from './dashboard.meta'; -import { setupOfflineVisitsSync, setupCacheableRoutes } from './offline'; import { genericDashboardConfigSchema } from './side-nav/generic-dashboard.component'; import { genericNavGroupConfigSchema } from './side-nav/generic-nav-group.component'; -import patientChartPageComponent from './root.component'; -import markPatientAliveActionButtonComponent from './actions-buttons/mark-patient-alive.component'; -import markPatientDeceasedActionButtonComponent from './actions-buttons/mark-patient-deceased.component'; -import startVisitActionButtonComponent from './actions-buttons/start-visit.component'; -import startVisitActionButtonOnPatientSearch from './visit/start-visit-button.component'; -import stopVisitActionButtonComponent from './actions-buttons/stop-visit.component'; -import cancelVisitActionButtonComponent from './actions-buttons/cancel-visit.component'; +import { moduleName } from './constants'; +import { setupOfflineVisitsSync, setupCacheableRoutes } from './offline'; +import { summaryDashboardMeta, encountersDashboardMeta } from './dashboard.meta'; import addPastVisitActionButtonComponent from './actions-buttons/add-past-visit.component'; -import printIdentifierStickerActionButtonComponent from './actions-buttons/print-identifier-sticker.component'; +import cancelVisitActionButtonComponent from './actions-buttons/cancel-visit.component'; import currentVisitSummaryComponent from './visit/visits-widget/current-visit-summary.component'; +import genericDashboardComponent from './side-nav/generic-dashboard.component'; +import genericNavGroupComponent from './side-nav/generic-nav-group.component'; +import markPatientAliveActionButtonComponent from './actions-buttons/mark-patient-alive.component'; +import markPatientDeceasedActionButtonComponent from './actions-buttons/mark-patient-deceased.component'; import pastVisitsDetailOverviewComponent from './visit/past-visit-overview.component'; import pastVisitsOverviewComponent from './visit/visits-widget/visit-detail-overview.component'; +import patientChartPageComponent from './root.component'; import patientDetailsTileComponent from './patient-details-tile/patient-details-tile.component'; -import visitAttributeTagsComponent from './patient-banner-tags/visit-attribute-tags.component'; -import genericNavGroupComponent from './side-nav/generic-nav-group.component'; -import genericDashboardComponent from './side-nav/generic-dashboard.component'; +import printIdentifierStickerActionButtonComponent from './actions-buttons/print-identifier-sticker.component'; +import startVisitActionButtonComponent from './actions-buttons/start-visit.component'; +import startVisitActionButtonOnPatientSearch from './visit/start-visit-button.component'; import startVisitFormComponent from './visit/visit-form/visit-form.component'; +import stopVisitActionButtonComponent from './actions-buttons/stop-visit.component'; +import visitAttributeTagsComponent from './patient-banner-tags/visit-attribute-tags.component'; // This allows @openmrs/esm-patient-common-lib to be accessed by modules that are not // using webpack. This is used for ngx-formentry. @@ -167,10 +167,14 @@ export const startVisitForm = getSyncLifecycle(startVisitFormComponent, { moduleName, }); -export const markPatientDeceasedForm = getAsyncLifecycle(() => import('./deceased/deceased-form.component'), { - featureName: 'mark-patient-deceased-form', - moduleName, -}); +// t('markPatientDeceased', 'Mark patient deceased') +export const markPatientDeceasedForm = getAsyncLifecycle( + () => import('./mark-patient-deceased/mark-patient-deceased-form.workspace'), + { + featureName: 'mark-patient-deceased-form', + moduleName, + }, +); export const cancelVisitDialog = getAsyncLifecycle(() => import('./visit/visit-prompt/cancel-visit-dialog.component'), { featureName: 'cancel visit', @@ -197,13 +201,8 @@ export const endVisitDialog = getAsyncLifecycle(() => import('./visit/visit-prom moduleName, }); -export const confirmDeceasedDialog = getAsyncLifecycle(() => import('./deceased/confirmation-dialog.component'), { - featureName: 'confirm death', - moduleName, -}); - -export const confirmAliveDialog = getAsyncLifecycle(() => import('./deceased/mark-alive.modal'), { - featureName: 'confirm alive', +export const markPatientAliveModal = getAsyncLifecycle(() => import('./mark-patient-alive/mark-patient-alive.modal'), { + featureName: 'Mark patient alive', moduleName, }); diff --git a/packages/esm-patient-chart-app/src/mark-patient-alive/mark-patient-alive.modal.tsx b/packages/esm-patient-chart-app/src/mark-patient-alive/mark-patient-alive.modal.tsx new file mode 100644 index 0000000000..9148580fa9 --- /dev/null +++ b/packages/esm-patient-chart-app/src/mark-patient-alive/mark-patient-alive.modal.tsx @@ -0,0 +1,50 @@ +import React, { useCallback } from 'react'; +import { useTranslation } from 'react-i18next'; +import { Button, ModalBody, ModalFooter, ModalHeader } from '@carbon/react'; +import { showSnackbar } from '@openmrs/esm-framework'; +import { markPatientAlive } from '../data.resource'; + +interface MarkPatientAliveProps { + closeModal: () => void; + patientUuid: string; +} + +const MarkPatientAlive: React.FC = ({ closeModal, patientUuid }) => { + const { t } = useTranslation(); + + const handleSubmit = useCallback(() => { + closeModal(); + + markPatientAlive(patientUuid) + .then(() => { + closeModal(); + showSnackbar({ + title: t('markAliveSuccessfully', 'Patient marked alive succesfully'), + }); + window.location.reload(); + }) + .catch((error) => { + showSnackbar({ + title: t('errorMarkingPatientAlive', 'Error marking patient alive'), + kind: 'error', + isLowContrast: false, + subtitle: error?.message, + }); + }); + }, [closeModal, patientUuid, t]); + + return ( +
    + + {t('markPatientAliveConfirmation', 'Are you sure you want to mark this patient alive?')} + + + + +
    + ); +}; + +export default MarkPatientAlive; diff --git a/packages/esm-patient-chart-app/src/deceased/deceased-form.scss b/packages/esm-patient-chart-app/src/mark-patient-deceased/mark-patient-deceased-form.scss similarity index 60% rename from packages/esm-patient-chart-app/src/deceased/deceased-form.scss rename to packages/esm-patient-chart-app/src/mark-patient-deceased/mark-patient-deceased-form.scss index d2c4e4d66d..f75de8f8c7 100644 --- a/packages/esm-patient-chart-app/src/deceased/deceased-form.scss +++ b/packages/esm-patient-chart-app/src/mark-patient-deceased/mark-patient-deceased-form.scss @@ -1,32 +1,39 @@ -@use '@carbon/styles/scss/spacing'; -@use '@carbon/styles/scss/type'; +@use '@carbon/layout'; +@use '@carbon/type'; @import "~@openmrs/esm-styleguide/src/vars"; - .container { - margin: spacing.$spacing-05; + margin: layout.$spacing-05; & section { - margin: spacing.$spacing-05 0; + margin: layout.$spacing-05 0; } } .heading { @include type.type-style("productive-heading-03"); color: $text-02; - margin: spacing.$spacing-05; + margin: layout.$spacing-05; } .sectionTitle { @include type.type-style("productive-heading-02"); color: $text-02; - margin: 0 0 spacing.$spacing-03 0; + margin: 0 0 layout.$spacing-03 0; } .conceptAnswerOverviewWrapper { - margin: spacing.$spacing-05 0rem; + margin: layout.$spacing-03 0rem; border: 0.0625rem solid $grey-2; background-color: $ui-01; + + :global(.cds--tile) { + border: none !important; + } +} + +.errorOutline { + outline: 1px solid $danger; } .conceptAnswerOverviewWrapper div:nth-child(3) > div:nth-child(2) { @@ -41,8 +48,8 @@ display: flex; flex-direction: column; align-items: flex-start; - margin-top: spacing.$spacing-03; - min-height: spacing.$spacing-10; + margin-top: layout.$spacing-03; + min-height: layout.$spacing-10; width: 100%; @include type.type-style('body-short-01'); color: $text-02; @@ -50,12 +57,12 @@ } .radioButton { - padding: spacing.$spacing-02 spacing.$spacing-05; - margin: spacing.$spacing-03 0; + padding: layout.$spacing-02 layout.$spacing-05; + margin: layout.$spacing-03 0; } .contentSwitcher { - height: spacing.$spacing-09; + height: layout.$spacing-09; } .headerGridRow { @@ -66,7 +73,7 @@ .dataGridRow { display: grid; grid-template-columns: 50% 10% 1fr; - margin: spacing.$spacing-03 spacing.$spacing-05; + margin: layout.$spacing-03 layout.$spacing-05; } .form { @@ -77,39 +84,55 @@ } .button { - height: spacing.$spacing-10; + height: layout.$spacing-10; display: flex; align-content: flex-start; align-items: baseline; min-width: 50%; + + :global(.cds--inline-loading) { + min-height: 1rem; + } + + :global(.cds--inline-loading__text) { + font-size: unset; + } } .conceptAnswerOverviewWrapperTablet { - padding: spacing.$spacing-06 spacing.$spacing-05; + padding: layout.$spacing-06 layout.$spacing-05; background-color: $ui-02; } .conceptAnswerOverviewWrapperDesktop { padding: 0rem; - - .paginationContainer div { - background-color: $ui-01; - } } .warningContainer { display: flex; background-color: $warning-background; - padding: spacing.$spacing-05; + padding: layout.$spacing-05; align-items: center; } + .warningIcon { display: flex; align-self: center; fill: $inverse-support-03; - margin-right: spacing.$spacing-03; + margin-right: layout.$spacing-03; + align-self: start; } .warningText { font-size: 0.875rem; } + +.datePicker { + padding-bottom: 0.5rem; + width: 100%; +} + +.errorMessage { + @include type.type-style("label-02"); + color: $danger; +} diff --git a/packages/esm-patient-chart-app/src/mark-patient-deceased/mark-patient-deceased-form.workspace.tsx b/packages/esm-patient-chart-app/src/mark-patient-deceased/mark-patient-deceased-form.workspace.tsx new file mode 100644 index 0000000000..cfb8c53f79 --- /dev/null +++ b/packages/esm-patient-chart-app/src/mark-patient-deceased/mark-patient-deceased-form.workspace.tsx @@ -0,0 +1,238 @@ +import React, { useCallback, useMemo, useState } from 'react'; +import classNames from 'classnames'; +import dayjs from 'dayjs'; +import fuzzy from 'fuzzy'; +import { useTranslation } from 'react-i18next'; +import { + Button, + ButtonSet, + DatePicker, + DatePickerInput, + DatePickerSkeleton, + Form, + InlineLoading, + RadioButton, + RadioButtonGroup, + Row, + Search, + StructuredListSkeleton, +} from '@carbon/react'; +import { Controller, useForm, type SubmitHandler } from 'react-hook-form'; +import { z } from 'zod'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { WarningFilled } from '@carbon/react/icons'; +import { EmptyState, type DefaultPatientWorkspaceProps } from '@openmrs/esm-patient-common-lib'; +import { ExtensionSlot, useLayoutType, showSnackbar, ResponsiveWrapper } from '@openmrs/esm-framework'; +import { markPatientDeceased, useCausesOfDeath, usePatientDeceasedStatus } from '../data.resource'; +import styles from './mark-patient-deceased-form.scss'; + +const MarkPatientDeceasedForm: React.FC = ({ closeWorkspace, patientUuid }) => { + const { t } = useTranslation(); + const isTablet = useLayoutType() === 'tablet'; + const memoizedPatientUuid = useMemo(() => ({ patientUuid }), [patientUuid]); + const { causesOfDeath, isLoading: isLoadingCausesOfDeath } = useCausesOfDeath(); + const { deathDate, isDead } = usePatientDeceasedStatus(patientUuid); + const [isSubmitting, setIsSubmitting] = useState(false); + const [searchTerm, setSearchTerm] = useState(''); + + const filteredCausesOfDeath = useMemo(() => { + if (!searchTerm) { + return causesOfDeath; + } + + return searchTerm + ? fuzzy + .filter(searchTerm, causesOfDeath, { + extract: (causeOfDeathConcept) => causeOfDeathConcept.display, + }) + .sort((r1, r2) => r1.score - r2.score) + .map((result) => result.original) + : causesOfDeath; + }, [searchTerm, causesOfDeath]); + + const schema = z.object({ + causeOfDeath: z.string(), + deathDate: z.date().nullable(), + }); + + type MarkPatientDeceasedFormSchema = z.infer; + + const { + control, + formState: { errors }, + handleSubmit, + setError, + } = useForm({ + mode: 'onSubmit', + resolver: zodResolver(schema), + defaultValues: { + causeOfDeath: '', + deathDate: isDead + ? new Date(dayjs(deathDate).year(), dayjs(deathDate).month(), dayjs(deathDate).date() - 1) + : new Date(), + }, + }); + + const onSubmit: SubmitHandler = useCallback( + (data) => { + setIsSubmitting(true); + const { causeOfDeath, deathDate } = data; + + if (!causeOfDeath || !deathDate) { + if (!deathDate) { + setError('deathDate', { + type: 'manual', + message: t('deathDateRequired', 'Please select the date of death'), + }); + } + + if (!causeOfDeath) { + setError('causeOfDeath', { + type: 'manual', + message: t('causeOfDeathIsRequired', 'Please select the cause of death'), + }); + } + setIsSubmitting(false); + return; + } + + markPatientDeceased(deathDate, patientUuid, causeOfDeath) + .then(() => { + closeWorkspace(); + window.location.reload(); + }) + .catch((error) => { + showSnackbar({ + kind: 'error', + isLowContrast: false, + subtitle: error?.message, + title: t('errorMarkingPatientDeceased', 'Error marking patient deceased'), + }); + }) + .finally(() => { + setIsSubmitting(false); + }); + }, + [closeWorkspace, patientUuid, setError, t], + ); + + const onError = (errors) => console.error(errors); + + return ( +
    +
    + {isTablet && ( + + + + )} +
    + + + + {t('markDeceasedWarning', 'Marking the patient as deceased will end any active visits for this patient')} + + +
    +
    {t('dateOfDeath', 'Date of death')}
    + {causesOfDeath?.length ? ( + + ( + onChange(date)} + value={value} + > + + + )} + /> + {errors?.deathDate &&

    {errors?.deathDate?.message}

    } +
    + ) : ( + + )} +
    +
    + {!isDead &&
    {t('causeOfDeath', 'Cause of death')}
    } + +
    + {isLoadingCausesOfDeath ? : null} + {causesOfDeath?.length ? ( + + setSearchTerm(event.target.value)} + placeholder={t('searchForCauseOfDeath', 'Search for a cause of death')} + labelText="" + /> + + ) : null} + {causesOfDeath?.length ? ( + ( + + {(filteredCausesOfDeath ? filteredCausesOfDeath : causesOfDeath).map( + ({ uuid, display, name }) => ( + + ), + )} + + )} + /> + ) : null} + + {!isLoadingCausesOfDeath && !causesOfDeath?.length ? ( + + ) : null} +
    + {errors?.causeOfDeath &&

    {errors?.causeOfDeath?.message}

    } +
    +
    +
    + + + + +
    + ); +}; + +export default MarkPatientDeceasedForm; diff --git a/packages/esm-patient-chart-app/src/routes.json b/packages/esm-patient-chart-app/src/routes.json index 5457d895a1..9f71fe6ec0 100644 --- a/packages/esm-patient-chart-app/src/routes.json +++ b/packages/esm-patient-chart-app/src/routes.json @@ -128,13 +128,6 @@ "online": true, "offline": true }, - { - "name": "mark-patient-deceased-workspace-form", - "component": "markPatientDeceasedForm", - "meta": { - "title": "Mark Deceased" - } - }, { "name": "patient-details-tile", "slot": "visit-form-header-slot", @@ -185,18 +178,6 @@ "online": true, "offline": true }, - { - "name": "confirm-deceased-dialog", - "component": "confirmDeceasedDialog", - "online": true, - "offline": true - }, - { - "name": "confirm-alive-modal", - "component": "confirmAliveDialog", - "online": true, - "offline": true - }, { "name": "start-visit-button-patient-search", "slot": "start-visit-button-slot", @@ -251,6 +232,12 @@ "order": 1 } ], + "modals": [ + { + "name": "mark-patient-alive-modal", + "component": "markPatientAliveModal" + } + ], "pages": [ { "component": "root", @@ -258,5 +245,13 @@ "online": true, "offline": true } + ], + "workspaces": [ + { + "name": "mark-patient-deceased-workspace-form", + "component": "markPatientDeceasedForm", + "title": "Mark patient deceased", + "type": "form" + } ] } diff --git a/packages/esm-patient-chart-app/translations/en.json b/packages/esm-patient-chart-app/translations/en.json index bee0f7e9f6..31fbd331e2 100644 --- a/packages/esm-patient-chart-app/translations/en.json +++ b/packages/esm-patient-chart-app/translations/en.json @@ -12,18 +12,18 @@ "cancelVisit": "Cancel visit", "cancelVisitExplainerMessage": "Cancelling this visit will delete its associated encounters", "causeOfDeath": "Cause of death", - "causeOfDeath_title": "Cause of Death", + "causeOfDeath_lower": "cause of death concepts configured in the system", + "causeOfDeathIsRequired": "Please select the cause of death", "checkFilters": "Check the filters above", "close": "Close", "confirm": "Confirm", - "confirmDeceased": "Confirm Deceased", "confirmDeletingVisitTextWithStartAndEndDate": "Are you sure you want to delete {{visit}} which started {{visitStartDate}} and ended {{visitEndDate}}?", - "confirmMarkAsAlive": "Are you sure, you want to mark patient as alive?", "confirmModifyingVisitDateToAccomodateEncounter": "The encounter date falls outside the designated visit date range. Would you like to modify the visit date to accommodate the new encounter date?", "currentVisit": "Current Visit", "date": "Date", "dateAndTime": "Date & time", - "dateOfDeath": "Date of Death", + "dateOfDeath": "Date of death", + "deathDateRequired": "Please select the date of death", "delete": "Delete", "deleteEncounter": "Delete Encounter", "deleteEncounterConfirmationText": "Are you sure you want to delete this encounter? This action can't be undone.", @@ -59,6 +59,8 @@ "errorDeletingVisit": "Error deleting visit", "errorDeletingVisitAttribute": "Could not delete {{attributeName}} attribute", "errorEndingVisit": "Error ending visit", + "errorMarkingPatientAlive": "Error marking patient alive", + "errorMarkingPatientDeceased": "Error marking patient deceased", "errorOccuredDeletingVisit": "An error occured when deleting visit", "errorUpdatingVisitAttribute": "Could not update {{attributeName}} attribute", "errorUpdatingVisitDetails": "Error updating visit details", @@ -80,10 +82,11 @@ "location": "Location", "male": "Male", "markAlive": "Mark alive", - "markAsAlive": "Mark As Alive", - "markAsDeceased": "Are you sure you want to mark patient as deceased?", - "markDeceased": "Mark deceased", - "markingPatientDeceasedInfoText": "Marking the patient as deceased will end any active visits for this patient", + "markAliveSuccessfully": "Patient marked alive succesfully", + "markDeceasedWarning": "Marking the patient as deceased will end any active visits for this patient", + "markPatientAlive": "Mark patient alive", + "markPatientAliveConfirmation": "Are you sure you want to mark this patient alive?", + "markPatientDeceased": "Mark patient deceased", "medications": "Medications", "medications__lower": "medications", "missingVisitType": "Missing visit type", @@ -125,6 +128,8 @@ "refills": "Refills", "refreshToTryAgain": "Please refresh to try again", "retrospectiveEntry": "Retrospective Entry", + "saveAndClose": "Save and close", + "saving": "Saving", "searchForAVisitType": "Search for a visit type", "searchForCauseOfDeath": "Search for a cause of death", "searchThisList": "Search this list", @@ -133,11 +138,6 @@ "selectLocation": "Select a location", "selectProgramType": "Select program type", "selectVisitType": "Please select a Visit Type", - "setAliveError": "Error marking patient alive", - "setAliveSuccessfully": "Patient has been marked alive successfully", - "setDeceased": "Set Deceased", - "setDeceasedError": "Error marking patient deceased", - "setDeceasedSuccessfully": "Patient has been marked dead successfully", "start": "Start", "startAVisit": "Start a visit", "startDate": "Start date", @@ -180,5 +180,6 @@ "visitType": "Visit type", "visitType_title": "Visit Type", "visitTypeRequired": "Visit type is required", + "warning": "Warning", "yes": "Yes" }