From 845b05f8ce2dfa8ce91cb52b1c7fe638d6bc7387 Mon Sep 17 00:00:00 2001 From: Vineet Sharma Date: Wed, 24 Jan 2024 11:44:33 +0530 Subject: [PATCH 01/39] Updated the workspaces.ts to accomodate proper checks when closing workspaces --- .../src/workspaces/workspaces.ts | 176 +++++++++++++----- 1 file changed, 132 insertions(+), 44 deletions(-) diff --git a/packages/esm-patient-common-lib/src/workspaces/workspaces.ts b/packages/esm-patient-common-lib/src/workspaces/workspaces.ts index 516725394e..411d8fccc9 100644 --- a/packages/esm-patient-common-lib/src/workspaces/workspaces.ts +++ b/packages/esm-patient-common-lib/src/workspaces/workspaces.ts @@ -21,10 +21,17 @@ export interface WorkspaceStoreState { workspaceWindowState: WorkspaceWindowState; } +interface CloseWorkspaceOptions { + workspaceTitle?: string; + ignoreChanges?: boolean; + onWorkspaceClose?: () => void; + confirmBeforeClosing?: boolean; +} + export interface OpenWorkspace extends WorkspaceRegistration { additionalProps: object; - closeWorkspace(promptBeforeClosing?: boolean): void; - closeWorkspace(): void; + closeWorkspace(closeWorkspaceOptions?: CloseWorkspaceOptions): boolean; + closeWorkspace(): boolean; promptBeforeClosing(testFcn: () => boolean): void; } @@ -103,40 +110,28 @@ function getTitleFromExtension(ext: ExtensionRegistration) { return ext.name; } +function getWhetherWorkspaceCanBeClosed(name: string, ignoreChanges: boolean = false) { + const promptBeforeFn = getPromptBeforeClosingFcn(name); + return ignoreChanges || !promptBeforeFn || !promptBeforeFn(); +} + function promptBeforeLaunchingWorkspace( workspace: OpenWorkspace, newWorkspaceDetails: { name: string; additionalProps?: object }, ) { - const store = getWorkspaceStore(); const { name, additionalProps } = newWorkspaceDetails; - const promptCheckFcn = getPromptBeforeClosingFcn(workspace.name); const proceed = () => { - workspace.closeWorkspace(); - // Calling the launchPatientWorkspace again, since one of the `if` case - // might resolve, but we need to check all the cases before launching the form. - launchPatientWorkspace(name, additionalProps); + workspace.closeWorkspace({ + onWorkspaceClose: () => launchPatientWorkspace(name, additionalProps), + }); }; - if (!promptCheckFcn || promptCheckFcn()) { - const currentName = workspace.title ?? workspace.name; - const prompt: Prompt = { - title: translateFrom('@openmrs/esm-patient-chart-app', 'unsavedChanges', 'You have unsaved changes'), - body: translateFrom( - '@openmrs/esm-patient-chart-app', - 'unsavedChangesInForm', - 'There are unsaved changes in {{formName}}. Please save them before opening another form.', - { formName: currentName }, - ), - onConfirm: () => { - store.setState({ - prompt: null, - }); - proceed(); - }, - confirmText: translateFrom('@openmrs/esm-patient-chart-app', 'openAnyway', 'Open anyway'), - }; - store.setState((state) => ({ ...state, prompt })); + // Calling the launchPatientWorkspace again, since one of the `if` case + // might resolve, but we need to check all the cases before launching the form. + + if (!getWhetherWorkspaceCanBeClosed(workspace.name)) { + showWorkspacePrompts('closing-workspace-launching-new-workspace', proceed, workspace.title ?? workspace.name); } else { proceed(); } @@ -166,7 +161,11 @@ export function launchPatientWorkspace(name: string, additionalProps?: object) { const workspace = getWorkspaceRegistration(name); const newWorkspace = { ...workspace, - closeWorkspace: (ignoreChanges = true) => closeWorkspace(name, ignoreChanges), + closeWorkspace: (options: CloseWorkspaceOptions = {}) => + closeWorkspace(name, { + workspaceTitle: workspace.title, + ...options, + }), promptBeforeClosing: (testFcn) => promptBeforeClosing(name, testFcn), additionalProps, }; @@ -244,9 +243,14 @@ export function cancelPrompt() { store.setState({ ...state, prompt: null }); } -export function closeWorkspace(name: string, ignoreChanges: boolean) { +export function closeWorkspace( + name: string, + options: CloseWorkspaceOptions = { + ignoreChanges: false, + onWorkspaceClose: () => {}, + }, +): boolean { const store = getWorkspaceStore(); - const promptCheckFcn = getPromptBeforeClosingFcn(name); const updateStoreWithClosedWorkspace = () => { const state = store.getState(); @@ -258,24 +262,17 @@ export function closeWorkspace(name: string, ignoreChanges: boolean) { openWorkspaces: newOpenWorkspaces, workspaceWindowState: getUpdatedWorkspaceWindowState(newOpenWorkspaces?.[0]), }); + + options?.onWorkspaceClose?.(); }; - if (!ignoreChanges && promptCheckFcn && promptCheckFcn()) { - const prompt: Prompt = { - title: translateFrom('@openmrs/esm-patient-chart-app', 'unsavedChangesTitleText', 'Unsaved Changes'), - body: translateFrom( - '@openmrs/esm-patient-chart-app', - 'unsavedChangeText', - `You have unsaved changes in the side panel. Do you want to discard these changes?`, - ), - onConfirm: () => { - updateStoreWithClosedWorkspace(); - }, - confirmText: translateFrom('@openmrs/esm-patient-chart-app', 'discard', 'Discard'), - }; - store.setState({ ...store.getState(), prompt }); + if (!getWhetherWorkspaceCanBeClosed(name, options?.ignoreChanges)) { + const currentName = options?.workspaceTitle ?? name; + showWorkspacePrompts('closing-workspace', updateStoreWithClosedWorkspace, currentName); + return false; } else { updateStoreWithClosedWorkspace(); + return true; } } @@ -325,3 +322,94 @@ function getUpdatedWorkspaceWindowState(workspaceAtTop: OpenWorkspace) { export function resetWorkspaceStore() { getWorkspaceStore().setState(initialState); } + +type PromptType = 'closing-workspace' | 'closing-all-workspaces' | 'closing-workspace-launching-new-workspace'; + +export function showWorkspacePrompts( + promptType: PromptType, + onConfirmation: () => void = () => {}, + workspaceTitle: string = '', +) { + const store = getWorkspaceStore(); + + switch (promptType) { + case 'closing-workspace': { + const prompt: Prompt = { + title: translateFrom('@openmrs/esm-patient-chart-app', 'unsavedChanges', 'You have unsaved changes'), + body: translateFrom( + '@openmrs/esm-patient-chart-app', + 'unsavedChangesInForm', + 'There are unsaved changes in {{formName}}. Please save them before opening another form.', + { formName: workspaceTitle }, + ), + onConfirm: () => { + onConfirmation?.(); + }, + confirmText: translateFrom('@openmrs/esm-patient-chart-app', 'openAnyway', 'Open anyway'), + }; + store.setState((prevState) => ({ ...prevState, prompt })); + return; + } + + case 'closing-all-workspaces': { + const workspacesNotClosed = store + .getState() + .openWorkspaces.filter(({ name }) => !getWhetherWorkspaceCanBeClosed(name)) + .map(({ title }, indx) => `${indx + 1}. ${title}`); + + const prompt: Prompt = { + title: translateFrom('@openmrs/esm-patient-chart-app', 'unsavedChanges', 'You have unsaved changes'), + body: translateFrom( + '@openmrs/esm-patient-chart-app', + 'unsavedChangesInForms', + `There are unsaved changes in the following workspaces. Do you want to discard changes in the following workspaces? {{workspaceNames}}`, + { + workspaceNames: workspacesNotClosed.join(' '), + }, + ), + onConfirm: () => { + onConfirmation?.(); + }, + confirmText: translateFrom( + '@openmrs/esm-patient-chart-app', + 'closeWorkspaces', + 'Discard changes in {{count}} workspaces', + { count: workspacesNotClosed.length }, + ), + }; + store.setState((prevState) => ({ + ...prevState, + prompt, + })); + return; + } + case 'closing-workspace-launching-new-workspace': { + const prompt: Prompt = { + title: translateFrom('@openmrs/esm-patient-chart-app', 'unsavedChanges', 'You have unsaved changes'), + body: translateFrom( + '@openmrs/esm-patient-chart-app', + 'unsavedChangesInForm', + 'There are unsaved changes in {{formName}}. Please save them before opening another form.', + { formName: workspaceTitle }, + ), + onConfirm: () => { + store.setState((prevState) => ({ + ...prevState, + prompt: null, + })); + onConfirmation?.(); + }, + confirmText: translateFrom('@openmrs/esm-patient-chart-app', 'openAnyway', 'Open anyway'), + }; + store.setState((prevState) => ({ + ...prevState, + prompt, + })); + return; + } + default: { + onConfirmation?.(); + return; + } + } +} From af5f69d0acdd6e53aa4ceba9b1924664b9abbc1a Mon Sep 17 00:00:00 2001 From: Vineet Sharma Date: Wed, 24 Jan 2024 11:54:06 +0530 Subject: [PATCH 02/39] Allergies workspace registered correctly with register workspace --- .../esm-patient-allergies-app/src/index.ts | 20 +++++++++++++++---- .../esm-patient-allergies-app/src/routes.json | 12 ----------- .../translations/am.json | 1 + .../translations/ar.json | 1 + .../translations/en.json | 1 + .../translations/es.json | 1 + .../translations/fr.json | 1 + .../translations/he.json | 1 + .../translations/km.json | 1 + .../translations/zh.json | 1 + .../translations/zh_CN.json | 1 + 11 files changed, 25 insertions(+), 16 deletions(-) diff --git a/packages/esm-patient-allergies-app/src/index.ts b/packages/esm-patient-allergies-app/src/index.ts index 3eb5bed821..8a98a4b544 100644 --- a/packages/esm-patient-allergies-app/src/index.ts +++ b/packages/esm-patient-allergies-app/src/index.ts @@ -1,9 +1,15 @@ -import { defineConfigSchema, fhirBaseUrl, getSyncLifecycle, messageOmrsServiceWorker } from '@openmrs/esm-framework'; -import { createDashboardLink } from '@openmrs/esm-patient-common-lib'; +import { + defineConfigSchema, + fhirBaseUrl, + getAsyncLifecycle, + getSyncLifecycle, + messageOmrsServiceWorker, + translateFrom, +} from '@openmrs/esm-framework'; +import { createDashboardLink, registerWorkspace } from '@openmrs/esm-patient-common-lib'; import { configSchema } from './config-schema'; import { dashboardMeta } from './dashboard.meta'; import allergiesDetailedSummaryComponent from './allergies/allergies-detailed-summary.component'; -import allergyFormComponent from './allergies/allergies-form/allergy-form.component'; import allergyTileComponent from './allergies/allergies-tile.component'; const moduleName = '@openmrs/esm-patient-allergies-app'; @@ -45,6 +51,12 @@ export const allergiesDashboardLink = getSyncLifecycle( options, ); -export const allergiesForm = getSyncLifecycle(allergyFormComponent, options); +// t('recordNewAllergy', "Record a new allergy") +registerWorkspace({ + name: 'patient-allergy-form-workspace', + title: translateFrom(moduleName, 'recordNewAllergy', 'Record a new allergy'), + load: getAsyncLifecycle(() => import('./allergies/allergies-form/allergy-form.component'), options), + type: 'form', +}); export const allergyTile = getSyncLifecycle(allergyTileComponent, options); diff --git a/packages/esm-patient-allergies-app/src/routes.json b/packages/esm-patient-allergies-app/src/routes.json index 36a40340a8..a3a331da81 100644 --- a/packages/esm-patient-allergies-app/src/routes.json +++ b/packages/esm-patient-allergies-app/src/routes.json @@ -23,18 +23,6 @@ "columnSpan": 1 } }, - { - "name": "patient-allergy-form-workspace", - "component": "allergiesForm", - "online": true, - "offline": true, - "meta": { - "title": { - "key": "recordNewAllergy", - "default": "Record a new allergy" - } - } - }, { "name": "allergies-summary-dashboard", "component": "allergiesDashboardLink", diff --git a/packages/esm-patient-allergies-app/translations/am.json b/packages/esm-patient-allergies-app/translations/am.json index 14d79b2cc0..ec63e9f016 100644 --- a/packages/esm-patient-allergies-app/translations/am.json +++ b/packages/esm-patient-allergies-app/translations/am.json @@ -22,6 +22,7 @@ "otherNonCodedAllergicReaction": "Other non-coded allergic reaction", "reaction": "Reaction", "reactions": "Reactions", + "recordNewAllergy": "Record a new allergy", "saveAndClose": "Save and close", "seeAll": "See all", "selectAllergen": "Select the allergen", diff --git a/packages/esm-patient-allergies-app/translations/ar.json b/packages/esm-patient-allergies-app/translations/ar.json index 74ba4cdf2f..57e1436377 100644 --- a/packages/esm-patient-allergies-app/translations/ar.json +++ b/packages/esm-patient-allergies-app/translations/ar.json @@ -22,6 +22,7 @@ "otherNonCodedAllergicReaction": "رد فعل حساسية غير مشفر آخر", "reaction": "رد الفعل", "reactions": "ردود الفعل", + "recordNewAllergy": "Record a new allergy", "saveAndClose": "حفظ وإغلاق", "seeAll": "عرض الكل", "selectAllergen": "اختر المواد المسببة للحساسية", diff --git a/packages/esm-patient-allergies-app/translations/en.json b/packages/esm-patient-allergies-app/translations/en.json index 14d79b2cc0..ec63e9f016 100644 --- a/packages/esm-patient-allergies-app/translations/en.json +++ b/packages/esm-patient-allergies-app/translations/en.json @@ -22,6 +22,7 @@ "otherNonCodedAllergicReaction": "Other non-coded allergic reaction", "reaction": "Reaction", "reactions": "Reactions", + "recordNewAllergy": "Record a new allergy", "saveAndClose": "Save and close", "seeAll": "See all", "selectAllergen": "Select the allergen", diff --git a/packages/esm-patient-allergies-app/translations/es.json b/packages/esm-patient-allergies-app/translations/es.json index 838c42e670..178dcac59d 100644 --- a/packages/esm-patient-allergies-app/translations/es.json +++ b/packages/esm-patient-allergies-app/translations/es.json @@ -22,6 +22,7 @@ "otherNonCodedAllergicReaction": "Otra reacción alérgica no codificada", "reaction": "Reacción", "reactions": "Reacciones", + "recordNewAllergy": "Record a new allergy", "saveAndClose": "Guardar y cerrar", "seeAll": "Ver todo", "selectAllergen": "Seleccione el alérgeno", diff --git a/packages/esm-patient-allergies-app/translations/fr.json b/packages/esm-patient-allergies-app/translations/fr.json index 619106f274..2ad3915026 100644 --- a/packages/esm-patient-allergies-app/translations/fr.json +++ b/packages/esm-patient-allergies-app/translations/fr.json @@ -22,6 +22,7 @@ "otherNonCodedAllergicReaction": "Autre réaction allergique non-codée", "reaction": "Reaction", "reactions": "Réactions", + "recordNewAllergy": "Record a new allergy", "saveAndClose": "Sauvegarder et fermer", "seeAll": "Voir tout", "selectAllergen": "Sélectionnez l'allergène", diff --git a/packages/esm-patient-allergies-app/translations/he.json b/packages/esm-patient-allergies-app/translations/he.json index c26a7e1445..18c33d5a76 100644 --- a/packages/esm-patient-allergies-app/translations/he.json +++ b/packages/esm-patient-allergies-app/translations/he.json @@ -22,6 +22,7 @@ "otherNonCodedAllergicReaction": "תגובה אלרגנית אחרת לא מקודדת", "reaction": "תגובה", "reactions": "תגובות", + "recordNewAllergy": "Record a new allergy", "saveAndClose": "שמירה וסגירה", "seeAll": "הצג הכל", "selectAllergen": "בחר את האלרגן", diff --git a/packages/esm-patient-allergies-app/translations/km.json b/packages/esm-patient-allergies-app/translations/km.json index 91435f2164..13998be873 100644 --- a/packages/esm-patient-allergies-app/translations/km.json +++ b/packages/esm-patient-allergies-app/translations/km.json @@ -22,6 +22,7 @@ "otherNonCodedAllergicReaction": "ប្រតិកម្មអាលែហ្សីដែលមិនមានលេខកូដផ្សេងទៀត។", "reaction": "Reaction", "reactions": "ប្រតិកម្ម", + "recordNewAllergy": "Record a new allergy", "saveAndClose": "រក្សាទុក និងបិទ", "seeAll": "មើលឃើញទាំងអស់", "selectAllergen": "ជ្រើសរើសអាឡែរហ្សី", diff --git a/packages/esm-patient-allergies-app/translations/zh.json b/packages/esm-patient-allergies-app/translations/zh.json index 6bf67400cd..f3d8397f04 100644 --- a/packages/esm-patient-allergies-app/translations/zh.json +++ b/packages/esm-patient-allergies-app/translations/zh.json @@ -22,6 +22,7 @@ "otherNonCodedAllergicReaction": "其他非编码过敏反应", "reaction": "反应", "reactions": "反应", + "recordNewAllergy": "Record a new allergy", "saveAndClose": "保存并关闭", "seeAll": "查看全部", "selectAllergen": "选择过敏原", diff --git a/packages/esm-patient-allergies-app/translations/zh_CN.json b/packages/esm-patient-allergies-app/translations/zh_CN.json index 6bf67400cd..f3d8397f04 100644 --- a/packages/esm-patient-allergies-app/translations/zh_CN.json +++ b/packages/esm-patient-allergies-app/translations/zh_CN.json @@ -22,6 +22,7 @@ "otherNonCodedAllergicReaction": "其他非编码过敏反应", "reaction": "反应", "reactions": "反应", + "recordNewAllergy": "Record a new allergy", "saveAndClose": "保存并关闭", "seeAll": "查看全部", "selectAllergen": "选择过敏原", From c753397b199c4d4549f9a1c6cc9e2d75c6b94c37 Mon Sep 17 00:00:00 2001 From: Vineet Sharma Date: Wed, 24 Jan 2024 12:24:11 +0530 Subject: [PATCH 03/39] Fixed the closing workspace prompt --- .../src/workspaces/workspaces.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/esm-patient-common-lib/src/workspaces/workspaces.ts b/packages/esm-patient-common-lib/src/workspaces/workspaces.ts index 411d8fccc9..8eecdcf27c 100644 --- a/packages/esm-patient-common-lib/src/workspaces/workspaces.ts +++ b/packages/esm-patient-common-lib/src/workspaces/workspaces.ts @@ -335,18 +335,18 @@ export function showWorkspacePrompts( switch (promptType) { case 'closing-workspace': { const prompt: Prompt = { - title: translateFrom('@openmrs/esm-patient-chart-app', 'unsavedChanges', 'You have unsaved changes'), + title: translateFrom('@openmrs/esm-patient-chart-app', 'unsavedChangesTitleText', 'Unsaved Changes'), body: translateFrom( '@openmrs/esm-patient-chart-app', - 'unsavedChangesInForm', - 'There are unsaved changes in {{formName}}. Please save them before opening another form.', - { formName: workspaceTitle }, + 'unsavedChangeText', + `You have unsaved changes in the side panel. Do you want to discard these changes?`, ), onConfirm: () => { onConfirmation?.(); }, - confirmText: translateFrom('@openmrs/esm-patient-chart-app', 'openAnyway', 'Open anyway'), + confirmText: translateFrom('@openmrs/esm-patient-chart-app', 'discard', 'Discard'), }; + store.setState({ ...store.getState(), prompt }); store.setState((prevState) => ({ ...prevState, prompt })); return; } From a77418da2c8ba9f044c2038e8767760b11644397 Mon Sep 17 00:00:00 2001 From: Vineet Sharma Date: Wed, 24 Jan 2024 12:24:39 +0530 Subject: [PATCH 04/39] Added the promptBeforeClosing in the Appointments form --- .../appointments-base.component.tsx | 5 +---- .../appointments-form.component.tsx | 22 ++++++++++++++----- .../esm-patient-appointments-app/src/index.ts | 16 ++++++++------ .../src/routes.json | 4 ---- 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/packages/esm-patient-appointments-app/src/appointments/appointments-base.component.tsx b/packages/esm-patient-appointments-app/src/appointments/appointments-base.component.tsx index 39d710bfb5..5f8d62b138 100644 --- a/packages/esm-patient-appointments-app/src/appointments/appointments-base.component.tsx +++ b/packages/esm-patient-appointments-app/src/appointments/appointments-base.component.tsx @@ -36,10 +36,7 @@ const AppointmentsBase: React.FC = ({ patientUuid }) => { isValidating, } = useAppointments(patientUuid, startDate, new AbortController()); - const launchAppointmentsForm = () => - launchPatientWorkspace('appointments-form-workspace', { - workspaceTitle: t('scheduleAppointment', 'Schedule appointment'), - }); + const launchAppointmentsForm = () => launchPatientWorkspace('appointments-form-workspace'); if (isLoading) return ; if (isError) { diff --git a/packages/esm-patient-appointments-app/src/appointments/appointments-form/appointments-form.component.tsx b/packages/esm-patient-appointments-app/src/appointments/appointments-form/appointments-form.component.tsx index 1ac162152e..5b5c768dc5 100644 --- a/packages/esm-patient-appointments-app/src/appointments/appointments-form/appointments-form.component.tsx +++ b/packages/esm-patient-appointments-app/src/appointments/appointments-form/appointments-form.component.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import dayjs from 'dayjs'; import { @@ -25,7 +25,7 @@ import { Controller, useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { z } from 'zod'; import { useLocations, useSession, showSnackbar, useLayoutType } from '@openmrs/esm-framework'; -import { convertTime12to24 } from '@openmrs/esm-patient-common-lib'; +import { type DefaultWorkspaceProps, convertTime12to24 } from '@openmrs/esm-patient-common-lib'; import { saveAppointment, saveRecurringAppointments, @@ -60,12 +60,10 @@ const appointmentsFormSchema = z.object({ type AppointmentFormData = z.infer; -interface AppointmentsFormProps { +interface AppointmentsFormProps extends DefaultWorkspaceProps { appointment?: Appointment; recurringPattern?: RecurringPattern; - patientUuid?: string; context?: string; - closeWorkspace: () => void; } const AppointmentsForm: React.FC = ({ @@ -74,6 +72,7 @@ const AppointmentsForm: React.FC = ({ patientUuid, context, closeWorkspace, + promptBeforeClosing, }) => { const editedAppointmentTimeFormat = new Date(appointment?.startDateTime).getHours() >= 12 ? 'PM' : 'AM'; const defaultTimeFormat = appointment?.startDateTime @@ -109,7 +108,14 @@ const AppointmentsForm: React.FC = ({ ? dayjs(new Date(appointment?.startDateTime)).format('hh:mm') : dayjs(new Date()).format('hh:mm'); - const { control, getValues, setValue, watch, handleSubmit } = useForm({ + const { + control, + getValues, + setValue, + watch, + handleSubmit, + formState: { isDirty }, + } = useForm({ mode: 'all', resolver: zodResolver(appointmentsFormSchema), defaultValues: { @@ -131,6 +137,10 @@ const AppointmentsForm: React.FC = ({ }, }); + useEffect(() => { + promptBeforeClosing(() => isDirty); + }, [isDirty]); + const handleMultiselectChange = (e) => { setValue( 'selectedDaysOfWeekText', diff --git a/packages/esm-patient-appointments-app/src/index.ts b/packages/esm-patient-appointments-app/src/index.ts index 485ef2982a..98f2d4ad3d 100644 --- a/packages/esm-patient-appointments-app/src/index.ts +++ b/packages/esm-patient-appointments-app/src/index.ts @@ -1,5 +1,5 @@ -import { defineConfigSchema, getAsyncLifecycle, getSyncLifecycle } from '@openmrs/esm-framework'; -import { createDashboardLink } from '@openmrs/esm-patient-common-lib'; +import { defineConfigSchema, getAsyncLifecycle, getSyncLifecycle, translateFrom } from '@openmrs/esm-framework'; +import { createDashboardLink, registerWorkspace } from '@openmrs/esm-patient-common-lib'; import { dashboardMeta } from './dashboard.meta'; import appointmentsOverviewComponent from './appointments/appointments-overview.component'; import appointmentsDetailedSummaryComponent from './appointments/appointments-detailed-summary.component'; @@ -28,14 +28,16 @@ export const appointmentsSummaryDashboardLink = getSyncLifecycle( options, ); -export const appointmentsFormWorkspace = getAsyncLifecycle( - () => import('./appointments/appointments-form/appointments-form.component'), - options, -); - export const appointmentsCancelConfirmationDialog = getAsyncLifecycle( () => import('./appointments/appointments-cancel-modal.component'), options, ); export const upcomingAppointmentsWidget = getSyncLifecycle(upcomingAppointmentsWidgetComponent, options); + +// t('scheduleAppointment', 'Schedule appointment'); +registerWorkspace({ + name: 'appointments-form-workspace', + load: getAsyncLifecycle(() => import('./appointments/appointments-form/appointments-form.component'), options), + title: translateFrom(moduleName, 'scheduleAppointment', 'Schedule appointment'), +}); diff --git a/packages/esm-patient-appointments-app/src/routes.json b/packages/esm-patient-appointments-app/src/routes.json index f68be1a304..02760d5df9 100644 --- a/packages/esm-patient-appointments-app/src/routes.json +++ b/packages/esm-patient-appointments-app/src/routes.json @@ -33,10 +33,6 @@ "path": "Appointments" } }, - { - "name": "appointments-form-workspace", - "component": "appointmentsFormWorkspace" - }, { "name": "appointment-cancel-confirmation-dialog", "component": "appointmentsCancelConfirmationDialog" From 7b949cd146af17f89c1d4f06c55be95156b951c3 Mon Sep 17 00:00:00 2001 From: Vineet Sharma Date: Wed, 24 Jan 2024 12:26:09 +0530 Subject: [PATCH 05/39] Added the isDirty check in allergies form --- .../allergies-form/allergy-form.component.tsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/esm-patient-allergies-app/src/allergies/allergies-form/allergy-form.component.tsx b/packages/esm-patient-allergies-app/src/allergies/allergies-form/allergy-form.component.tsx index dac996df9f..10ad6fc467 100644 --- a/packages/esm-patient-allergies-app/src/allergies/allergies-form/allergy-form.component.tsx +++ b/packages/esm-patient-allergies-app/src/allergies/allergies-form/allergy-form.component.tsx @@ -66,7 +66,7 @@ type AllergyFormData = { comment: string; }; -function AllergyForm({ closeWorkspace, patientUuid }: DefaultWorkspaceProps) { +function AllergyForm({ closeWorkspace, patientUuid, promptBeforeClosing }: DefaultWorkspaceProps) { const { t } = useTranslation(); const { concepts } = useConfig(); const isTablet = useLayoutType() === 'tablet'; @@ -82,7 +82,14 @@ function AllergyForm({ closeWorkspace, patientUuid }: DefaultWorkspaceProps) { const [isDisabled, setIsDisabled] = useState(true); const { mutate } = useAllergies(patientUuid); - const { control, handleSubmit, watch, getValues, setValue } = useForm({ + const { + control, + handleSubmit, + watch, + getValues, + setValue, + formState: { isDirty }, + } = useForm({ mode: 'all', resolver: zodResolver(allergyFormSchema), defaultValues: { @@ -95,6 +102,10 @@ function AllergyForm({ closeWorkspace, patientUuid }: DefaultWorkspaceProps) { }, }); + useEffect(() => { + promptBeforeClosing(() => isDirty); + }, [isDirty]); + const selectedAllergen = watch('allergen'); const selectedAllergicReactions = watch('allergicReactions'); const selectedSeverityOfWorstReaction = watch('severityOfWorstReaction'); From b7443a9b8c9c52257a3476c3f2e3ef2af9b30e83 Mon Sep 17 00:00:00 2001 From: Vineet Sharma Date: Wed, 24 Jan 2024 12:27:14 +0530 Subject: [PATCH 06/39] Removed extra translations --- packages/esm-patient-biometrics-app/translations/zh.json | 1 - packages/esm-patient-biometrics-app/translations/zh_CN.json | 1 - 2 files changed, 2 deletions(-) delete mode 100644 packages/esm-patient-biometrics-app/translations/zh.json delete mode 100644 packages/esm-patient-biometrics-app/translations/zh_CN.json diff --git a/packages/esm-patient-biometrics-app/translations/zh.json b/packages/esm-patient-biometrics-app/translations/zh.json deleted file mode 100644 index 9e26dfeeb6..0000000000 --- a/packages/esm-patient-biometrics-app/translations/zh.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/packages/esm-patient-biometrics-app/translations/zh_CN.json b/packages/esm-patient-biometrics-app/translations/zh_CN.json deleted file mode 100644 index 9e26dfeeb6..0000000000 --- a/packages/esm-patient-biometrics-app/translations/zh_CN.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file From 4b598827ac8575a9552f59ab44eb127497689cb0 Mon Sep 17 00:00:00 2001 From: Vineet Sharma Date: Wed, 24 Jan 2024 12:44:39 +0530 Subject: [PATCH 07/39] Added the isDirty check in conditions workspace --- .../src/types/workspace.ts | 9 +++++++- .../src/workspaces/workspaces.ts | 9 +------- .../conditions-detailed-summary.component.tsx | 5 +--- .../conditions/conditions-form.component.tsx | 23 +++++++++++++++---- .../src/conditions/conditions-form.test.tsx | 2 +- .../conditions-overview.component.tsx | 5 +--- .../conditions-widget.component.tsx | 3 ++- .../esm-patient-conditions-app/src/index.ts | 16 +++++++------ .../src/routes.json | 4 ---- .../translations/am.json | 1 + .../translations/ar.json | 1 + .../translations/en.json | 1 + .../translations/es.json | 1 + .../translations/fr.json | 1 + .../translations/he.json | 1 + .../translations/km.json | 1 + .../translations/zh.json | 1 + .../translations/zh_CN.json | 1 + 18 files changed, 50 insertions(+), 35 deletions(-) diff --git a/packages/esm-patient-common-lib/src/types/workspace.ts b/packages/esm-patient-common-lib/src/types/workspace.ts index 4aed8d04f0..ca465b8223 100644 --- a/packages/esm-patient-common-lib/src/types/workspace.ts +++ b/packages/esm-patient-common-lib/src/types/workspace.ts @@ -1,6 +1,13 @@ /* The possible states a workspace window can be opened in. */ export type WorkspaceWindowState = 'maximized' | 'hidden' | 'normal'; +export interface CloseWorkspaceOptions { + workspaceTitle?: string; + ignoreChanges?: boolean; + onWorkspaceClose?: () => void; + confirmBeforeClosing?: boolean; +} + /** The default parameters received by all workspaces */ export interface DefaultWorkspaceProps { /** @@ -8,7 +15,7 @@ export interface DefaultWorkspaceProps { * prompted to save changes before closing, even if the `testFcn` passed to `promptBeforeClosing` * returns `true`. */ - closeWorkspace(ignoreChanges?: boolean): void; + closeWorkspace(closeWorkspaceOptions?: CloseWorkspaceOptions): void; /** * Call this with a no-args function that returns true if the user should be prompted before * this workspace is closed; e.g. if there is unsaved data. diff --git a/packages/esm-patient-common-lib/src/workspaces/workspaces.ts b/packages/esm-patient-common-lib/src/workspaces/workspaces.ts index 8eecdcf27c..e6829bcc47 100644 --- a/packages/esm-patient-common-lib/src/workspaces/workspaces.ts +++ b/packages/esm-patient-common-lib/src/workspaces/workspaces.ts @@ -2,7 +2,7 @@ import { type ExtensionRegistration, getGlobalStore, navigate, translateFrom } f // FIXME We should not rely on internals here import { getExtensionRegistration } from '@openmrs/esm-framework/src/internal'; import _i18n from 'i18next'; -import { type WorkspaceWindowState } from '../types/workspace'; +import { type WorkspaceWindowState, type CloseWorkspaceOptions } from '../types/workspace'; export interface Prompt { title: string; @@ -21,13 +21,6 @@ export interface WorkspaceStoreState { workspaceWindowState: WorkspaceWindowState; } -interface CloseWorkspaceOptions { - workspaceTitle?: string; - ignoreChanges?: boolean; - onWorkspaceClose?: () => void; - confirmBeforeClosing?: boolean; -} - export interface OpenWorkspace extends WorkspaceRegistration { additionalProps: object; closeWorkspace(closeWorkspaceOptions?: CloseWorkspaceOptions): boolean; diff --git a/packages/esm-patient-conditions-app/src/conditions/conditions-detailed-summary.component.tsx b/packages/esm-patient-conditions-app/src/conditions/conditions-detailed-summary.component.tsx index d683cc397a..4b1bdad552 100644 --- a/packages/esm-patient-conditions-app/src/conditions/conditions-detailed-summary.component.tsx +++ b/packages/esm-patient-conditions-app/src/conditions/conditions-detailed-summary.component.tsx @@ -88,10 +88,7 @@ function ConditionsDetailedSummary({ patient }) { : compare(cellA.sortKey, cellB.sortKey); }; - const launchConditionsForm = useCallback( - () => launchPatientWorkspace('conditions-form-workspace', { workspaceTitle: 'Record a Condition' }), - [], - ); + const launchConditionsForm = useCallback(() => launchPatientWorkspace('conditions-form-workspace'), []); const handleConditionStatusChange = ({ selectedItem }) => setFilter(selectedItem); diff --git a/packages/esm-patient-conditions-app/src/conditions/conditions-form.component.tsx b/packages/esm-patient-conditions-app/src/conditions/conditions-form.component.tsx index 8e2b0877bf..705d3c883e 100644 --- a/packages/esm-patient-conditions-app/src/conditions/conditions-form.component.tsx +++ b/packages/esm-patient-conditions-app/src/conditions/conditions-form.component.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useForm, FormProvider } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; @@ -8,12 +8,11 @@ import { useLayoutType } from '@openmrs/esm-framework'; import { type ConditionDataTableRow, useConditions } from './conditions.resource'; import ConditionsWidget from './conditions-widget.component'; import styles from './conditions-form.scss'; +import { type DefaultWorkspaceProps } from '@openmrs/esm-patient-common-lib'; -interface ConditionFormProps { - closeWorkspace: () => void; +interface ConditionFormProps extends DefaultWorkspaceProps { condition?: ConditionDataTableRow; formContext: 'creating' | 'editing'; - patientUuid?: string; } const conditionSchema = z.object({ @@ -25,7 +24,13 @@ const conditionSchema = z.object({ export type ConditionFormData = z.infer; -const ConditionsForm: React.FC = ({ closeWorkspace, condition, formContext, patientUuid }) => { +const ConditionsForm: React.FC = ({ + closeWorkspace, + condition, + formContext, + patientUuid, + promptBeforeClosing, +}) => { const { t } = useTranslation(); const isTablet = useLayoutType() === 'tablet'; const { conditions } = useConditions(patientUuid); @@ -50,6 +55,14 @@ const ConditionsForm: React.FC = ({ closeWorkspace, conditio }, }); + const { + formState: { isDirty }, + } = methods; + + useEffect(() => { + promptBeforeClosing(() => isDirty); + }, [isDirty]); + const onSubmit = (data) => { setIsSubmittingForm(true); }; diff --git a/packages/esm-patient-conditions-app/src/conditions/conditions-form.test.tsx b/packages/esm-patient-conditions-app/src/conditions/conditions-form.test.tsx index 6a92b0c378..bfcfa0dfbf 100644 --- a/packages/esm-patient-conditions-app/src/conditions/conditions-form.test.tsx +++ b/packages/esm-patient-conditions-app/src/conditions/conditions-form.test.tsx @@ -202,5 +202,5 @@ describe('Conditions Form', () => { }); function renderConditionsForm() { - render(); + render( {}} {...testProps} />); } diff --git a/packages/esm-patient-conditions-app/src/conditions/conditions-overview.component.tsx b/packages/esm-patient-conditions-app/src/conditions/conditions-overview.component.tsx index 09d0c1b280..36dd5b4f00 100644 --- a/packages/esm-patient-conditions-app/src/conditions/conditions-overview.component.tsx +++ b/packages/esm-patient-conditions-app/src/conditions/conditions-overview.component.tsx @@ -54,10 +54,7 @@ const ConditionsOverview: React.FC = ({ patientUuid }) const { conditions, isError, isLoading, isValidating } = useConditions(patientUuid); const [filter, setFilter] = useState<'All' | 'Active' | 'Inactive'>('Active'); - const launchConditionsForm = useCallback( - () => launchPatientWorkspace('conditions-form-workspace', { workspaceTitle: 'Record a Condition' }), - [], - ); + const launchConditionsForm = useCallback(() => launchPatientWorkspace('conditions-form-workspace'), []); const filteredConditions = useMemo(() => { if (!filter || filter == 'All') { diff --git a/packages/esm-patient-conditions-app/src/conditions/conditions-widget.component.tsx b/packages/esm-patient-conditions-app/src/conditions/conditions-widget.component.tsx index 69790bda9d..494183b13a 100644 --- a/packages/esm-patient-conditions-app/src/conditions/conditions-widget.component.tsx +++ b/packages/esm-patient-conditions-app/src/conditions/conditions-widget.component.tsx @@ -29,9 +29,10 @@ import { } from './conditions.resource'; import { type ConditionFormData } from './conditions-form.component'; import styles from './conditions-form.scss'; +import { type DefaultWorkspaceProps } from '@openmrs/esm-patient-common-lib'; interface ConditionsWidgetProps { - closeWorkspace?: () => void; + closeWorkspace?: DefaultWorkspaceProps['closeWorkspace']; conditionToEdit?: ConditionDataTableRow; editing?: boolean; patientUuid: string; diff --git a/packages/esm-patient-conditions-app/src/index.ts b/packages/esm-patient-conditions-app/src/index.ts index 2854e92427..ebd3401854 100644 --- a/packages/esm-patient-conditions-app/src/index.ts +++ b/packages/esm-patient-conditions-app/src/index.ts @@ -1,5 +1,5 @@ -import { defineConfigSchema, getAsyncLifecycle, getSyncLifecycle } from '@openmrs/esm-framework'; -import { createDashboardLink } from '@openmrs/esm-patient-common-lib'; +import { defineConfigSchema, getAsyncLifecycle, getSyncLifecycle, translateFrom } from '@openmrs/esm-framework'; +import { createDashboardLink, registerWorkspace } from '@openmrs/esm-patient-common-lib'; import { configSchema } from './config-schema'; import { dashboardMeta } from './dashboard.meta'; import conditionsOverviewComponent from './conditions/conditions-overview.component'; @@ -34,12 +34,14 @@ export const conditionsDashboardLink = options, ); -export const conditionsFormWorkspace = getAsyncLifecycle( - () => import('./conditions/conditions-form.component'), - options, -); - export const conditionDeleteConfirmationDialog = getAsyncLifecycle( () => import('./conditions/delete-condition-modal.component'), options, ); + +// t('recordCondition', 'Record a Condition') +registerWorkspace({ + name: 'conditions-form-workspace', + load: getAsyncLifecycle(() => import('./conditions/conditions-form.component'), options), + title: translateFrom(moduleName, 'recordCondition', 'Record a Condition'), +}); diff --git a/packages/esm-patient-conditions-app/src/routes.json b/packages/esm-patient-conditions-app/src/routes.json index 747fd5c5d2..e022adfb6f 100644 --- a/packages/esm-patient-conditions-app/src/routes.json +++ b/packages/esm-patient-conditions-app/src/routes.json @@ -37,10 +37,6 @@ "name": "conditions-widget", "component": "conditionsWidget" }, - { - "name": "conditions-form-workspace", - "component": "conditionsFormWorkspace" - }, { "name": "condition-delete-confirmation-dialog", "component": "conditionDeleteConfirmationDialog" diff --git a/packages/esm-patient-conditions-app/translations/am.json b/packages/esm-patient-conditions-app/translations/am.json index 173d5d5eff..271dafcc3b 100644 --- a/packages/esm-patient-conditions-app/translations/am.json +++ b/packages/esm-patient-conditions-app/translations/am.json @@ -25,6 +25,7 @@ "noConditionsToDisplay": "No conditions to display", "noResultsFor": "No results for", "onsetDate": "Onset date", + "recordCondition": "Record a Condition", "saveAndClose": "Save & close", "saving": "Saving", "searchConditions": "Search conditions", diff --git a/packages/esm-patient-conditions-app/translations/ar.json b/packages/esm-patient-conditions-app/translations/ar.json index 9444cb08f1..05e6b95b6a 100644 --- a/packages/esm-patient-conditions-app/translations/ar.json +++ b/packages/esm-patient-conditions-app/translations/ar.json @@ -25,6 +25,7 @@ "noConditionsToDisplay": "لا توجد حالات لعرضها", "noResultsFor": "لا توجد نتائج لـ", "onsetDate": "تاريخ البداية", + "recordCondition": "Record a Condition", "saveAndClose": "حفظ وإغلاق", "saving": "جاري الحفظ", "searchConditions": "بحث عن حالة", diff --git a/packages/esm-patient-conditions-app/translations/en.json b/packages/esm-patient-conditions-app/translations/en.json index 7dff1cfedf..bc28c2b21d 100644 --- a/packages/esm-patient-conditions-app/translations/en.json +++ b/packages/esm-patient-conditions-app/translations/en.json @@ -25,6 +25,7 @@ "noConditionsToDisplay": "No conditions to display", "noResultsFor": "No results for", "onsetDate": "Onset date", + "recordCondition": "Record a Condition", "saveAndClose": "Save & close", "saving": "Saving", "searchConditions": "Search conditions", diff --git a/packages/esm-patient-conditions-app/translations/es.json b/packages/esm-patient-conditions-app/translations/es.json index 7ac3432f79..ff2e746900 100644 --- a/packages/esm-patient-conditions-app/translations/es.json +++ b/packages/esm-patient-conditions-app/translations/es.json @@ -25,6 +25,7 @@ "noConditionsToDisplay": "No hay condiciones para mostrar", "noResultsFor": "Sin resultados para", "onsetDate": "Fecha de aparición", + "recordCondition": "Record a Condition", "saveAndClose": "Guardar y cerrar", "saving": "Guardando", "searchConditions": "Buscar condiciones", diff --git a/packages/esm-patient-conditions-app/translations/fr.json b/packages/esm-patient-conditions-app/translations/fr.json index 9b4bef646d..7d104a7252 100644 --- a/packages/esm-patient-conditions-app/translations/fr.json +++ b/packages/esm-patient-conditions-app/translations/fr.json @@ -25,6 +25,7 @@ "noConditionsToDisplay": "Aucune condition à afficher", "noResultsFor": "Pas de résultat pour", "onsetDate": "Date de début", + "recordCondition": "Record a Condition", "saveAndClose": "Sauvegarder et fermer", "saving": "Saving", "searchConditions": "Conditions de recherche", diff --git a/packages/esm-patient-conditions-app/translations/he.json b/packages/esm-patient-conditions-app/translations/he.json index 4e5a9726d9..fa5dd7c3f9 100644 --- a/packages/esm-patient-conditions-app/translations/he.json +++ b/packages/esm-patient-conditions-app/translations/he.json @@ -25,6 +25,7 @@ "noConditionsToDisplay": "אין מצבים להצגה", "noResultsFor": "אין תוצאות עבור", "onsetDate": "תאריך התחלה", + "recordCondition": "Record a Condition", "saveAndClose": "שמירה וסגירה", "saving": "שמור", "searchConditions": "חיפוש מצבים", diff --git a/packages/esm-patient-conditions-app/translations/km.json b/packages/esm-patient-conditions-app/translations/km.json index 34ed247fc4..fef4f4fa4d 100644 --- a/packages/esm-patient-conditions-app/translations/km.json +++ b/packages/esm-patient-conditions-app/translations/km.json @@ -25,6 +25,7 @@ "noConditionsToDisplay": "No conditions to display", "noResultsFor": "គ្មានលទ្ធផលសម្រាប់", "onsetDate": "កាលបរិច្ឆេទចាប់ផ្តើម", + "recordCondition": "Record a Condition", "saveAndClose": "រក្សាទុក និងបិទ", "saving": "Saving", "searchConditions": "លក្ខខណ្ឌស្វែងរក", diff --git a/packages/esm-patient-conditions-app/translations/zh.json b/packages/esm-patient-conditions-app/translations/zh.json index a48d39a8a4..cba9674ad5 100644 --- a/packages/esm-patient-conditions-app/translations/zh.json +++ b/packages/esm-patient-conditions-app/translations/zh.json @@ -25,6 +25,7 @@ "noConditionsToDisplay": "没有可显示的病情", "noResultsFor": "No results for", "onsetDate": "Onset date", + "recordCondition": "Record a Condition", "saveAndClose": "保存并关闭", "saving": "Saving", "searchConditions": "搜索病情", diff --git a/packages/esm-patient-conditions-app/translations/zh_CN.json b/packages/esm-patient-conditions-app/translations/zh_CN.json index a48d39a8a4..cba9674ad5 100644 --- a/packages/esm-patient-conditions-app/translations/zh_CN.json +++ b/packages/esm-patient-conditions-app/translations/zh_CN.json @@ -25,6 +25,7 @@ "noConditionsToDisplay": "没有可显示的病情", "noResultsFor": "No results for", "onsetDate": "Onset date", + "recordCondition": "Record a Condition", "saveAndClose": "保存并关闭", "saving": "Saving", "searchConditions": "搜索病情", From 7694a339ef4f830e43c05380ef5c6d64a8b30e4b Mon Sep 17 00:00:00 2001 From: Vineet Sharma Date: Mon, 29 Jan 2024 16:58:34 +0530 Subject: [PATCH 08/39] Added the isDirty check in start-visit workspace --- .../visit/visit-form/visit-form.component.tsx | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/packages/esm-patient-chart-app/src/visit/visit-form/visit-form.component.tsx b/packages/esm-patient-chart-app/src/visit/visit-form/visit-form.component.tsx index 4470fc8c44..51e895c669 100644 --- a/packages/esm-patient-chart-app/src/visit/visit-form/visit-form.component.tsx +++ b/packages/esm-patient-chart-app/src/visit/visit-form/visit-form.component.tsx @@ -83,8 +83,6 @@ const StartVisitForm: React.FC = ({ const { mutateVisits } = useVisits(patientUuid); const allVisitTypes = isOnline ? useVisitTypes() : useOfflineVisitType(); const { mutate } = useVisit(patientUuid); - const { mutate: mutateVisit } = useVisit(patientUuid); - const [ignoreChanges, setIgnoreChanges] = useState(true); const [errorFetchingResources, setErrorFetchingResources] = useState<{ blockSavingForm: boolean; }>(null); @@ -179,10 +177,14 @@ const StartVisitForm: React.FC = ({ handleSubmit, control, getValues, - formState: { errors }, + formState: { errors, isDirty }, setError, } = methods; + useEffect(() => { + promptBeforeClosing(() => isDirty); + }, [isDirty]); + const validateVisitStartStopDatetime = useCallback(() => { let visitStartDate = getValues('visitStartDate'); const visitStartTime = getValues('visitStartTime'); @@ -479,11 +481,6 @@ const StartVisitForm: React.FC = ({ ], ); - const handleOnChange = () => { - setIgnoreChanges((prevState) => !prevState); - promptBeforeClosing(() => true); - }; - let [maxVisitStartDatetime, minVisitStopDatetime] = useMemo(() => { if (!visitToEdit?.encounters?.length) { return [null, null]; @@ -510,7 +507,7 @@ const StartVisitForm: React.FC = ({ return ( -
+ {errorFetchingResources && ( = ({ - - diff --git a/packages/esm-patient-immunizations-app/src/index.ts b/packages/esm-patient-immunizations-app/src/index.ts index d1e972f2d8..686342b4d9 100644 --- a/packages/esm-patient-immunizations-app/src/index.ts +++ b/packages/esm-patient-immunizations-app/src/index.ts @@ -1,5 +1,5 @@ -import { defineConfigSchema, getAsyncLifecycle, getSyncLifecycle } from '@openmrs/esm-framework'; -import { createDashboardLink } from '@openmrs/esm-patient-common-lib'; +import { defineConfigSchema, getAsyncLifecycle, getSyncLifecycle, translateFrom } from '@openmrs/esm-framework'; +import { createDashboardLink, registerWorkspace } from '@openmrs/esm-patient-common-lib'; import { configSchema } from './config-schema'; import { dashboardMeta } from './dashboard.meta'; import immunizationsOverviewComponent from './immunizations/immunizations-overview.component'; @@ -32,7 +32,9 @@ export const immunizationsDashboardLink = options, ); -export const immunizationsForm = getAsyncLifecycle( - () => import('./immunizations/immunizations-form.component'), - options, -); +// t('immunizationWorkspaceTitle', 'Immunization Form') +export const immunizationsForm = registerWorkspace({ + name: 'immunization-form-workspace', + load: getAsyncLifecycle(() => import('./immunizations/immunizations-form.component'), options), + title: translateFrom(moduleName, 'immunizationWorkspaceTitle', 'Immunization Form'), +}); diff --git a/packages/esm-patient-immunizations-app/src/routes.json b/packages/esm-patient-immunizations-app/src/routes.json index e503acd87b..f0cada49d6 100644 --- a/packages/esm-patient-immunizations-app/src/routes.json +++ b/packages/esm-patient-immunizations-app/src/routes.json @@ -30,13 +30,6 @@ "path": "Immunizations" }, "order": 8 - }, - { - "name": "immunization-form-workspace", - "component": "immunizationsForm", - "meta": { - "title": "Immunization Form" - } } ], "pages": [] diff --git a/packages/esm-patient-immunizations-app/translations/am.json b/packages/esm-patient-immunizations-app/translations/am.json index bd85a7b15e..56d5fd459b 100644 --- a/packages/esm-patient-immunizations-app/translations/am.json +++ b/packages/esm-patient-immunizations-app/translations/am.json @@ -10,6 +10,7 @@ "immunization": "Immunization", "immunizations": "Immunizations", "Immunizations": "Immunizations", + "immunizationWorkspaceTitle": "Immunization Form", "lotNumber": "Lot Number", "manufacturer": "Manufacturer", "pleaseSelect": "Please select", diff --git a/packages/esm-patient-immunizations-app/translations/ar.json b/packages/esm-patient-immunizations-app/translations/ar.json index 950ea2073d..9effb15d83 100644 --- a/packages/esm-patient-immunizations-app/translations/ar.json +++ b/packages/esm-patient-immunizations-app/translations/ar.json @@ -10,6 +10,7 @@ "immunization": "Immunization", "immunizations": "التطعيمات", "Immunizations": "التطعيمات", + "immunizationWorkspaceTitle": "Immunization Form", "lotNumber": "رقم الدفعة", "manufacturer": "المصنع", "pleaseSelect": "يرجى الاختيار", diff --git a/packages/esm-patient-immunizations-app/translations/en.json b/packages/esm-patient-immunizations-app/translations/en.json index 2474b95098..aea19556d2 100644 --- a/packages/esm-patient-immunizations-app/translations/en.json +++ b/packages/esm-patient-immunizations-app/translations/en.json @@ -10,6 +10,7 @@ "immunization": "Immunization", "immunizations": "Immunizations", "Immunizations": "Immunizations", + "immunizationWorkspaceTitle": "Immunization Form", "lotNumber": "Lot Number", "manufacturer": "Manufacturer", "pleaseSelect": "Please select", diff --git a/packages/esm-patient-immunizations-app/translations/es.json b/packages/esm-patient-immunizations-app/translations/es.json index 4b551549b5..02fe34e196 100644 --- a/packages/esm-patient-immunizations-app/translations/es.json +++ b/packages/esm-patient-immunizations-app/translations/es.json @@ -10,6 +10,7 @@ "immunization": "Immunization", "immunizations": "Inmunizaciones", "Immunizations": "Inmunizaciones", + "immunizationWorkspaceTitle": "Immunization Form", "lotNumber": "Número de lote", "manufacturer": "Fabricante", "pleaseSelect": "Por favor, seleccione", diff --git a/packages/esm-patient-immunizations-app/translations/fr.json b/packages/esm-patient-immunizations-app/translations/fr.json index bd85a7b15e..56d5fd459b 100644 --- a/packages/esm-patient-immunizations-app/translations/fr.json +++ b/packages/esm-patient-immunizations-app/translations/fr.json @@ -10,6 +10,7 @@ "immunization": "Immunization", "immunizations": "Immunizations", "Immunizations": "Immunizations", + "immunizationWorkspaceTitle": "Immunization Form", "lotNumber": "Lot Number", "manufacturer": "Manufacturer", "pleaseSelect": "Please select", diff --git a/packages/esm-patient-immunizations-app/translations/he.json b/packages/esm-patient-immunizations-app/translations/he.json index 93872010be..6d03dc2e4e 100644 --- a/packages/esm-patient-immunizations-app/translations/he.json +++ b/packages/esm-patient-immunizations-app/translations/he.json @@ -10,6 +10,7 @@ "immunization": "Immunization", "immunizations": "חיסונים", "Immunizations": "חיסונים", + "immunizationWorkspaceTitle": "Immunization Form", "lotNumber": "מספר לוט", "manufacturer": "יצרן", "pleaseSelect": "בחר בבקשה", diff --git a/packages/esm-patient-immunizations-app/translations/km.json b/packages/esm-patient-immunizations-app/translations/km.json index 977688a35f..ee819cd1d2 100644 --- a/packages/esm-patient-immunizations-app/translations/km.json +++ b/packages/esm-patient-immunizations-app/translations/km.json @@ -10,6 +10,7 @@ "immunization": "Immunization", "immunizations": "ការចាក់ថ្នាំបង្ការរោគ", "Immunizations": "ការចាក់ថ្នាំបង្ការរោគ", + "immunizationWorkspaceTitle": "Immunization Form", "lotNumber": "Lot Number", "manufacturer": "Manufacturer", "pleaseSelect": "Please select", diff --git a/packages/esm-patient-immunizations-app/translations/zh.json b/packages/esm-patient-immunizations-app/translations/zh.json index bd85a7b15e..56d5fd459b 100644 --- a/packages/esm-patient-immunizations-app/translations/zh.json +++ b/packages/esm-patient-immunizations-app/translations/zh.json @@ -10,6 +10,7 @@ "immunization": "Immunization", "immunizations": "Immunizations", "Immunizations": "Immunizations", + "immunizationWorkspaceTitle": "Immunization Form", "lotNumber": "Lot Number", "manufacturer": "Manufacturer", "pleaseSelect": "Please select", diff --git a/packages/esm-patient-immunizations-app/translations/zh_CN.json b/packages/esm-patient-immunizations-app/translations/zh_CN.json index bd85a7b15e..56d5fd459b 100644 --- a/packages/esm-patient-immunizations-app/translations/zh_CN.json +++ b/packages/esm-patient-immunizations-app/translations/zh_CN.json @@ -10,6 +10,7 @@ "immunization": "Immunization", "immunizations": "Immunizations", "Immunizations": "Immunizations", + "immunizationWorkspaceTitle": "Immunization Form", "lotNumber": "Lot Number", "manufacturer": "Manufacturer", "pleaseSelect": "Please select", From f08149f65475376c1f04c186a9e3b1d7b0b124f6 Mon Sep 17 00:00:00 2001 From: Vineet Sharma Date: Mon, 29 Jan 2024 17:40:52 +0530 Subject: [PATCH 11/39] Updated the workspace title and workspace implementation in the patient lists --- packages/esm-patient-lists-app/src/index.ts | 13 +++++-------- .../workspaces/patient-list-details.workspace.tsx | 10 +++++----- .../src/workspaces/patient-lists.workspace.tsx | 13 +++++++++---- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/packages/esm-patient-lists-app/src/index.ts b/packages/esm-patient-lists-app/src/index.ts index a396465b33..c127305d0f 100644 --- a/packages/esm-patient-lists-app/src/index.ts +++ b/packages/esm-patient-lists-app/src/index.ts @@ -1,4 +1,4 @@ -import { defineConfigSchema, getAsyncLifecycle, getSyncLifecycle } from '@openmrs/esm-framework'; +import { defineConfigSchema, getAsyncLifecycle, getSyncLifecycle, translateFrom } from '@openmrs/esm-framework'; import { registerWorkspace } from '@openmrs/esm-patient-common-lib'; import { configSchema } from './config-schema'; @@ -15,18 +15,20 @@ export const importTranslation = require.context('../translations', false, /.jso export function startupApp() { defineConfigSchema(moduleName, configSchema); + // t('patientListsWorkspaceTitle', 'Patient Lists') registerWorkspace({ name: 'patient-lists', - title: 'Patient Lists', + title: translateFrom(moduleName, 'patientListsWorkspaceTitle', 'Patient Lists'), load: getAsyncLifecycle(() => import('./workspaces/patient-lists.workspace'), options), type: 'patient-lists', canHide: false, width: 'wider', }); + // t('patientListDetailWorkspaceTitle', 'Patient List Details') registerWorkspace({ name: 'patient-list-details', - title: 'Patient List Details', + title: translateFrom(moduleName, 'patientListDetailWorkspaceTitle', 'Patient List Details'), load: getAsyncLifecycle(() => import('./workspaces/patient-list-details.workspace'), options), type: 'patient-lists', canHide: false, @@ -35,8 +37,3 @@ export function startupApp() { } export const patientListsActionMenu = getSyncLifecycle(patientListsActionButtonComponent, options); - -export const patientListDetailsWorkspace = getAsyncLifecycle( - () => import('./workspaces/patient-list-details.workspace'), - options, -); diff --git a/packages/esm-patient-lists-app/src/workspaces/patient-list-details.workspace.tsx b/packages/esm-patient-lists-app/src/workspaces/patient-list-details.workspace.tsx index 02621cdce4..ccd983f0cb 100644 --- a/packages/esm-patient-lists-app/src/workspaces/patient-list-details.workspace.tsx +++ b/packages/esm-patient-lists-app/src/workspaces/patient-list-details.workspace.tsx @@ -2,14 +2,13 @@ import React, { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { Button } from '@carbon/react'; import { ArrowLeft } from '@carbon/react/icons'; -import { launchPatientWorkspace } from '@openmrs/esm-patient-common-lib'; +import { type DefaultWorkspaceProps, launchPatientWorkspace } from '@openmrs/esm-patient-common-lib'; import { formatDate, parseDate } from '@openmrs/esm-framework'; import { type MappedList, usePatientListMembers } from '../patient-lists.resource'; import PatientListDetailsTable from './patient-list-details-table.component'; import styles from './patient-list-details.scss'; -interface PatientListDetailsWorkspaceProps { - closeWorkspace: () => void; +interface PatientListDetailsWorkspaceProps extends DefaultWorkspaceProps { list: MappedList; } @@ -18,8 +17,9 @@ function PatientListDetailsWorkspace({ closeWorkspace, list }: PatientListDetail const { listMembers, isLoading } = usePatientListMembers(list.id); const closeListDetailsWorkspace = useCallback(() => { - closeWorkspace(); - launchPatientWorkspace('patient-lists'); + closeWorkspace({ + onWorkspaceClose: () => launchPatientWorkspace('patient-lists'), + }); }, []); return ( diff --git a/packages/esm-patient-lists-app/src/workspaces/patient-lists.workspace.tsx b/packages/esm-patient-lists-app/src/workspaces/patient-lists.workspace.tsx index 8eef02b9e9..80ae5fb2e8 100644 --- a/packages/esm-patient-lists-app/src/workspaces/patient-lists.workspace.tsx +++ b/packages/esm-patient-lists-app/src/workspaces/patient-lists.workspace.tsx @@ -20,12 +20,16 @@ import { TableToolbarSearch, Tile, } from '@carbon/react'; -import { closeWorkspace, launchPatientWorkspace, EmptyDataIllustration } from '@openmrs/esm-patient-common-lib'; +import { + launchPatientWorkspace, + EmptyDataIllustration, + type DefaultWorkspaceProps, +} from '@openmrs/esm-patient-common-lib'; import { useDebounce, useLayoutType } from '@openmrs/esm-framework'; import { usePatientLists } from '../patient-lists.resource'; import styles from './patient-lists.scss'; -function PatientListsWorkspace() { +function PatientListsWorkspace({ closeWorkspace }: DefaultWorkspaceProps) { const { t } = useTranslation(); const layout = useLayoutType(); const responsiveSize = layout === 'tablet' ? 'lg' : 'sm'; @@ -34,8 +38,9 @@ function PatientListsWorkspace() { const { patientLists, isLoading } = usePatientLists(); const launchListDetailsWorkspace = useCallback((list) => { - closeWorkspace('patient-lists', true); - launchPatientWorkspace('patient-list-details', { list, workspaceTitle: list.name }); + closeWorkspace({ + onWorkspaceClose: () => launchPatientWorkspace('patient-list-details', { list, workspaceTitle: list.name }), + }); }, []); const tableHeaders: Array = [ From ee58d587c2f2c76c508e70ea9a023b02e24c6082 Mon Sep 17 00:00:00 2001 From: Vineet Sharma Date: Mon, 29 Jan 2024 17:58:34 +0530 Subject: [PATCH 12/39] Updated the workspace title and workspace implementation in the medications app --- .../add-drug-order.workspace.tsx | 27 ++++++++--- .../drug-order-form.component.tsx | 17 +++++-- .../drug-search/drug-search.component.tsx | 45 ++++++++++--------- .../order-basket-search-results.component.tsx | 6 ++- .../esm-patient-medications-app/src/index.ts | 5 ++- .../translations/am.json | 1 + .../translations/ar.json | 1 + .../translations/en.json | 1 + .../translations/es.json | 1 + .../translations/fr.json | 1 + .../translations/he.json | 1 + .../translations/km.json | 1 + .../translations/zh.json | 1 + .../translations/zh_CN.json | 1 + 14 files changed, 74 insertions(+), 35 deletions(-) diff --git a/packages/esm-patient-medications-app/src/add-drug-order/add-drug-order.workspace.tsx b/packages/esm-patient-medications-app/src/add-drug-order/add-drug-order.workspace.tsx index dd74154355..8c6ce3aacd 100644 --- a/packages/esm-patient-medications-app/src/add-drug-order/add-drug-order.workspace.tsx +++ b/packages/esm-patient-medications-app/src/add-drug-order/add-drug-order.workspace.tsx @@ -13,14 +13,19 @@ export interface AddDrugOrderWorkspaceAdditionalProps { export interface AddDrugOrderWorkspace extends DefaultWorkspaceProps, AddDrugOrderWorkspaceAdditionalProps {} -export default function AddDrugOrderWorkspace({ order: initialOrder, closeWorkspace }: AddDrugOrderWorkspace) { +export default function AddDrugOrderWorkspace({ + order: initialOrder, + closeWorkspace, + promptBeforeClosing, +}: AddDrugOrderWorkspace) { const { orders, setOrders } = useOrderBasket('medications', prepMedicationOrderPostData); const [currentOrder, setCurrentOrder] = useState(initialOrder); const session = useSession(); const cancelDrugOrder = useCallback(() => { - closeWorkspace(); - launchPatientWorkspace('order-basket'); + closeWorkspace({ + onWorkspaceClose: () => launchPatientWorkspace('order-basket'), + }); }, [closeWorkspace, currentOrder, orders, setOrders]); const openOrderForm = useCallback( @@ -51,15 +56,23 @@ export default function AddDrugOrderWorkspace({ order: initialOrder, closeWorksp newOrders.push(finalizedOrder); } setOrders(newOrders); - closeWorkspace(); - launchPatientWorkspace('order-basket'); + closeWorkspace({ + onWorkspaceClose: () => launchPatientWorkspace('order-basket'), + }); }, [orders, setOrders, closeWorkspace, session.currentProvider.uuid], ); if (!currentOrder) { - return ; + return ; } else { - return ; + return ( + + ); } } diff --git a/packages/esm-patient-medications-app/src/add-drug-order/drug-order-form.component.tsx b/packages/esm-patient-medications-app/src/add-drug-order/drug-order-form.component.tsx index 343610da63..133e981170 100644 --- a/packages/esm-patient-medications-app/src/add-drug-order/drug-order-form.component.tsx +++ b/packages/esm-patient-medications-app/src/add-drug-order/drug-order-form.component.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useMemo, useRef, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import classNames from 'classnames'; import { useTranslation } from 'react-i18next'; import capitalize from 'lodash-es/capitalize'; @@ -42,6 +42,7 @@ export interface DrugOrderFormProps { initialOrderBasketItem: DrugOrderBasketItem; onSave: (finalizedOrder: DrugOrderBasketItem) => void; onCancel: () => void; + promptBeforeClosing: (testFcn: () => boolean) => void; } const comboSchema = { @@ -131,7 +132,7 @@ function InputWrapper({ children }) { ); } -export function DrugOrderForm({ initialOrderBasketItem, onSave, onCancel }: DrugOrderFormProps) { +export function DrugOrderForm({ initialOrderBasketItem, onSave, onCancel, promptBeforeClosing }: DrugOrderFormProps) { const { t } = useTranslation(); const isTablet = useLayoutType() === 'tablet'; const { orderConfigObject, error: errorFetchingOrderConfig } = useOrderConfig(); @@ -143,7 +144,13 @@ export function DrugOrderForm({ initialOrderBasketItem, onSave, onCancel }: Drug return initialOrderBasketItem?.startDate as Date; }, [initialOrderBasketItem?.startDate]); - const { handleSubmit, control, watch, setValue } = useForm({ + const { + handleSubmit, + control, + watch, + setValue, + formState: { isDirty }, + } = useForm({ mode: 'all', resolver: zodResolver(medicationOrderFormSchema), defaultValues: { @@ -166,6 +173,10 @@ export function DrugOrderForm({ initialOrderBasketItem, onSave, onCancel }: Drug }, }); + useEffect(() => { + promptBeforeClosing(() => isDirty); + }, [isDirty]); + const routeValue = watch('route')?.value; const unitValue = watch('unit')?.value; const dosage = watch('dosage'); diff --git a/packages/esm-patient-medications-app/src/add-drug-order/drug-search/drug-search.component.tsx b/packages/esm-patient-medications-app/src/add-drug-order/drug-search/drug-search.component.tsx index 7636a24cc1..9d0db25567 100644 --- a/packages/esm-patient-medications-app/src/add-drug-order/drug-search/drug-search.component.tsx +++ b/packages/esm-patient-medications-app/src/add-drug-order/drug-search/drug-search.component.tsx @@ -1,4 +1,4 @@ -import React, { useRef, useState } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Layer, Search } from '@carbon/react'; import { useDebounce, useLayoutType } from '@openmrs/esm-framework'; @@ -8,15 +8,20 @@ import styles from './order-basket-search.scss'; export interface DrugSearchProps { openOrderForm: (searchResult: DrugOrderBasketItem) => void; + promptBeforeClosing: (testFcn: () => boolean) => void; } -export default function DrugSearch({ openOrderForm }: DrugSearchProps) { +export default function DrugSearch({ openOrderForm, promptBeforeClosing }: DrugSearchProps) { const { t } = useTranslation(); const isTablet = useLayoutType() === 'tablet'; const [searchTerm, setSearchTerm] = useState(''); const debouncedSearchTerm = useDebounce(searchTerm); const searchInputRef = useRef(null); + useEffect(() => { + promptBeforeClosing(() => !!searchTerm); + }, [searchTerm]); + const focusAndClearSearchInput = () => { setSearchTerm(''); searchInputRef.current?.focus(); @@ -27,26 +32,24 @@ export default function DrugSearch({ openOrderForm }: DrugSearchProps) { }; return ( - <> -
- - - - + + -
- + + + ); } diff --git a/packages/esm-patient-medications-app/src/add-drug-order/drug-search/order-basket-search-results.component.tsx b/packages/esm-patient-medications-app/src/add-drug-order/drug-search/order-basket-search-results.component.tsx index d1bf6105c8..6d1f8491e1 100644 --- a/packages/esm-patient-medications-app/src/add-drug-order/drug-search/order-basket-search-results.component.tsx +++ b/packages/esm-patient-medications-app/src/add-drug-order/drug-search/order-basket-search-results.component.tsx @@ -141,8 +141,10 @@ const DrugSearchResultItem: React.FC = ({ drug, openO // Directly adding the order to basket should be marked as incomplete searchResult.isOrderIncomplete = true; setOrders([...orders, searchResult]); - closeWorkspace('add-drug-order', true); - launchPatientWorkspace('order-basket'); + closeWorkspace('add-drug-order', { + ignoreChanges: true, + onWorkspaceClose: () => launchPatientWorkspace('order-basket'), + }); }, [orders, setOrders], ); diff --git a/packages/esm-patient-medications-app/src/index.ts b/packages/esm-patient-medications-app/src/index.ts index ce579a3bf7..960c5aca13 100644 --- a/packages/esm-patient-medications-app/src/index.ts +++ b/packages/esm-patient-medications-app/src/index.ts @@ -1,4 +1,4 @@ -import { defineConfigSchema, getAsyncLifecycle, getSyncLifecycle } from '@openmrs/esm-framework'; +import { defineConfigSchema, getAsyncLifecycle, getSyncLifecycle, translateFrom } from '@openmrs/esm-framework'; import { createDashboardLink, registerWorkspace } from '@openmrs/esm-patient-common-lib'; import { configSchema } from './config-schema'; import { dashboardMeta } from './dashboard.meta'; @@ -37,9 +37,10 @@ export const medicationsDashboardLink = options, ); +// t('addDrugOrderWorkspaceTitle', 'Add drug order') registerWorkspace({ name: 'add-drug-order', type: 'order', - title: 'Add drug order', + title: translateFrom(moduleName, 'addDrugOrderWorkspaceTitle', 'Add drug order'), load: getAsyncLifecycle(() => import('./add-drug-order/add-drug-order.workspace'), options), }); diff --git a/packages/esm-patient-medications-app/translations/am.json b/packages/esm-patient-medications-app/translations/am.json index 0317265b52..ea0e4ecfe3 100644 --- a/packages/esm-patient-medications-app/translations/am.json +++ b/packages/esm-patient-medications-app/translations/am.json @@ -3,6 +3,7 @@ "activeMedicationsHeaderTitle": "active medications", "activeMedicationsTableTitle": "Active Medications", "add": "Add", + "addDrugOrderWorkspaceTitle": "Add drug order", "backToOrderBasket": "Back to order basket", "clearSearchResults": "Clear Results", "decrement": "Decrement", diff --git a/packages/esm-patient-medications-app/translations/ar.json b/packages/esm-patient-medications-app/translations/ar.json index 50cee60f7b..87da2d6c12 100644 --- a/packages/esm-patient-medications-app/translations/ar.json +++ b/packages/esm-patient-medications-app/translations/ar.json @@ -3,6 +3,7 @@ "activeMedicationsHeaderTitle": "الأدوية النشطة", "activeMedicationsTableTitle": "الأدوية النشطة", "add": "أضف", + "addDrugOrderWorkspaceTitle": "Add drug order", "backToOrderBasket": "العودة إلى سلة الطلب", "clearSearchResults": "مسح النتائج", "decrement": "تقليل", diff --git a/packages/esm-patient-medications-app/translations/en.json b/packages/esm-patient-medications-app/translations/en.json index 0317265b52..ea0e4ecfe3 100644 --- a/packages/esm-patient-medications-app/translations/en.json +++ b/packages/esm-patient-medications-app/translations/en.json @@ -3,6 +3,7 @@ "activeMedicationsHeaderTitle": "active medications", "activeMedicationsTableTitle": "Active Medications", "add": "Add", + "addDrugOrderWorkspaceTitle": "Add drug order", "backToOrderBasket": "Back to order basket", "clearSearchResults": "Clear Results", "decrement": "Decrement", diff --git a/packages/esm-patient-medications-app/translations/es.json b/packages/esm-patient-medications-app/translations/es.json index ff3c2904b8..43270cceb7 100644 --- a/packages/esm-patient-medications-app/translations/es.json +++ b/packages/esm-patient-medications-app/translations/es.json @@ -3,6 +3,7 @@ "activeMedicationsHeaderTitle": "Medicamentos activos", "activeMedicationsTableTitle": "Medicamentos Activos", "add": "Añadir", + "addDrugOrderWorkspaceTitle": "Add drug order", "backToOrderBasket": "Volver a la cesta de pedidos", "clearSearchResults": "Borrar resultados", "decrement": "Decremento", diff --git a/packages/esm-patient-medications-app/translations/fr.json b/packages/esm-patient-medications-app/translations/fr.json index 2e8345134b..d18b5b0869 100644 --- a/packages/esm-patient-medications-app/translations/fr.json +++ b/packages/esm-patient-medications-app/translations/fr.json @@ -3,6 +3,7 @@ "activeMedicationsHeaderTitle": "active medications", "activeMedicationsTableTitle": "Active Medications", "add": "Add", + "addDrugOrderWorkspaceTitle": "Add drug order", "backToOrderBasket": "Back to order basket", "clearSearchResults": "Clear Results", "decrement": "Decrement", diff --git a/packages/esm-patient-medications-app/translations/he.json b/packages/esm-patient-medications-app/translations/he.json index 6b5130873a..d01a09db25 100644 --- a/packages/esm-patient-medications-app/translations/he.json +++ b/packages/esm-patient-medications-app/translations/he.json @@ -3,6 +3,7 @@ "activeMedicationsHeaderTitle": "תרופות פעילות", "activeMedicationsTableTitle": "תרופות פעילות", "add": "הוסף", + "addDrugOrderWorkspaceTitle": "Add drug order", "backToOrderBasket": "חזור לסל ההזמנות", "clearSearchResults": "נקה תוצאות חיפוש", "decrement": "הפחתה", diff --git a/packages/esm-patient-medications-app/translations/km.json b/packages/esm-patient-medications-app/translations/km.json index 53789581fe..03da38317d 100644 --- a/packages/esm-patient-medications-app/translations/km.json +++ b/packages/esm-patient-medications-app/translations/km.json @@ -3,6 +3,7 @@ "activeMedicationsHeaderTitle": "កំពង់ប្រើប្រាស់ឱសថ", "activeMedicationsTableTitle": "កំពង់ប្រើប្រាស់ឱសថ", "add": "បន្ថែម", + "addDrugOrderWorkspaceTitle": "Add drug order", "backToOrderBasket": "ត្រឡប់ទៅប្រអប់តម្រៀបតាមលំដាប់លំដោយវិញ", "clearSearchResults": "លទ្ធផលច្បាស់លាស់", "decrement": "បន្ថយ", diff --git a/packages/esm-patient-medications-app/translations/zh.json b/packages/esm-patient-medications-app/translations/zh.json index 99de0d0ec9..c0206aa46f 100644 --- a/packages/esm-patient-medications-app/translations/zh.json +++ b/packages/esm-patient-medications-app/translations/zh.json @@ -3,6 +3,7 @@ "activeMedicationsHeaderTitle": "active medications", "activeMedicationsTableTitle": "Active Medications", "add": "添加", + "addDrugOrderWorkspaceTitle": "Add drug order", "backToOrderBasket": "Back to order basket", "clearSearchResults": "清除结果", "decrement": "Decrement", diff --git a/packages/esm-patient-medications-app/translations/zh_CN.json b/packages/esm-patient-medications-app/translations/zh_CN.json index 9457035c60..d1b4d46a6f 100644 --- a/packages/esm-patient-medications-app/translations/zh_CN.json +++ b/packages/esm-patient-medications-app/translations/zh_CN.json @@ -3,6 +3,7 @@ "activeMedicationsHeaderTitle": "active medications", "activeMedicationsTableTitle": "Active Medications", "add": "添加", + "addDrugOrderWorkspaceTitle": "Add drug order", "backToOrderBasket": "Back to order basket", "clearSearchResults": "清除结果", "decrement": "Decrement", From b32fa2e75c5a07d007dade37180759b51d72cbb6 Mon Sep 17 00:00:00 2001 From: Vineet Sharma Date: Mon, 29 Jan 2024 18:06:06 +0530 Subject: [PATCH 13/39] Updated the workspace title and workspace implementation in the note app --- packages/esm-patient-notes-app/src/index.ts | 11 ++++++++++- .../src/notes/visit-notes-form.component.tsx | 10 ++++++++-- packages/esm-patient-notes-app/src/routes.json | 12 ------------ packages/esm-patient-notes-app/translations/am.json | 3 ++- packages/esm-patient-notes-app/translations/ar.json | 3 ++- packages/esm-patient-notes-app/translations/en.json | 3 ++- packages/esm-patient-notes-app/translations/es.json | 3 ++- packages/esm-patient-notes-app/translations/fr.json | 3 ++- packages/esm-patient-notes-app/translations/he.json | 3 ++- packages/esm-patient-notes-app/translations/km.json | 3 ++- packages/esm-patient-notes-app/translations/zh.json | 3 ++- .../esm-patient-notes-app/translations/zh_CN.json | 3 ++- 12 files changed, 36 insertions(+), 24 deletions(-) diff --git a/packages/esm-patient-notes-app/src/index.ts b/packages/esm-patient-notes-app/src/index.ts index 9dfd30d042..b3a2ed698e 100644 --- a/packages/esm-patient-notes-app/src/index.ts +++ b/packages/esm-patient-notes-app/src/index.ts @@ -3,10 +3,12 @@ import { getAsyncLifecycle, getSyncLifecycle, messageOmrsServiceWorker, + translateFrom, } from '@openmrs/esm-framework'; import { configSchema } from './config-schema'; import notesOverviewComponent from './notes/notes-overview.component'; import visitNotesActionButtonComponent from './visit-note-action-button.component'; +import { registerWorkspace } from '@openmrs/esm-patient-common-lib'; const moduleName = '@openmrs/esm-patient-notes-app'; @@ -30,4 +32,11 @@ export const notesOverview = getSyncLifecycle(notesOverviewComponent, options); export const visitNotesActionButton = getSyncLifecycle(visitNotesActionButtonComponent, options); -export const visitNotesForm = getAsyncLifecycle(() => import('./notes/visit-notes-form.component'), options); +// t('visitNoteWorkspaceTitle', 'Visit Note') +export const visitNotesForm = registerWorkspace({ + name: 'visit-notes-form-workspace', + load: getAsyncLifecycle(() => import('./notes/visit-notes-form.component'), options), + title: translateFrom(moduleName, 'visitNoteWorkspaceTitle', 'Visit Note'), + type: 'visit-note', + canHide: true, +}); diff --git a/packages/esm-patient-notes-app/src/notes/visit-notes-form.component.tsx b/packages/esm-patient-notes-app/src/notes/visit-notes-form.component.tsx index c666d6c18f..93370d15c6 100644 --- a/packages/esm-patient-notes-app/src/notes/visit-notes-form.component.tsx +++ b/packages/esm-patient-notes-app/src/notes/visit-notes-form.component.tsx @@ -62,7 +62,7 @@ interface DiagnosisSearchProps { type VisitNotesFormData = z.infer; -const VisitNotesForm: React.FC = ({ closeWorkspace, patientUuid }) => { +const VisitNotesForm: React.FC = ({ closeWorkspace, patientUuid, promptBeforeClosing }) => { const searchTimeoutInMs = 500; const { t } = useTranslation(); const isTablet = useLayoutType() === 'tablet'; @@ -89,6 +89,12 @@ const VisitNotesForm: React.FC = ({ closeWorkspace, patie }, }); + const { isDirty } = formState; + + useEffect(() => { + promptBeforeClosing(() => isDirty); + }, [isDirty]); + const { mutateVisitNotes } = useVisitNotes(patientUuid); const locationUuid = session?.sessionLocation?.uuid; const providerUuid = session?.currentProvider?.uuid; @@ -520,7 +526,7 @@ const VisitNotesForm: React.FC = ({ closeWorkspace, patie -