Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(feat) O3-2760: Present workspaces should leverage the promptBeforeClosing function #1613

Merged
merged 46 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
845b05f
Updated the workspaces.ts to accomodate proper checks when closing wo…
vasharma05 Jan 24, 2024
af5f69d
Allergies workspace registered correctly with register workspace
vasharma05 Jan 24, 2024
c753397
Fixed the closing workspace prompt
vasharma05 Jan 24, 2024
a77418d
Added the promptBeforeClosing in the Appointments form
vasharma05 Jan 24, 2024
7b949cd
Added the isDirty check in allergies form
vasharma05 Jan 24, 2024
b7443a9
Removed extra translations
vasharma05 Jan 24, 2024
4b59882
Added the isDirty check in conditions workspace
vasharma05 Jan 24, 2024
7694a33
Added the isDirty check in start-visit workspace
vasharma05 Jan 29, 2024
fc217a5
Updated the workspaces implementation in the forms app
vasharma05 Jan 29, 2024
ce0f30c
Updated the workspace title and implementation in the immunization app
vasharma05 Jan 29, 2024
f08149f
Updated the workspace title and workspace implementation in the patie…
vasharma05 Jan 29, 2024
ee58d58
Updated the workspace title and workspace implementation in the medic…
vasharma05 Jan 29, 2024
b32fa2e
Updated the workspace title and workspace implementation in the note app
vasharma05 Jan 29, 2024
7571d1f
Updated the workspace title and workspace implementation in the order…
vasharma05 Jan 29, 2024
5dc2ad1
Updated the workspace title and workspace implementation in the progr…
vasharma05 Jan 29, 2024
4c72519
Updated the workspace title and workspace implementation in the vital…
vasharma05 Feb 1, 2024
033fc97
Added JSDoc in the workspaces.ts
vasharma05 Feb 1, 2024
8e69b41
Merge branch 'main' of https://www.github.com/openmrs/openmrs-esm-pat…
vasharma05 Feb 2, 2024
4665234
Merge branch 'main' of https://www.github.com/openmrs/openmrs-esm-pat…
vasharma05 Feb 2, 2024
cb67ac6
Removed duplicate functions from workspaces.ts
vasharma05 Feb 2, 2024
d71829e
Exported getWhetherWorkspaceCanBeClosed from common-lib
vasharma05 Feb 2, 2024
3c0d6e5
Updated workspaces.ts with JS Doc
vasharma05 Feb 5, 2024
c5eb5ef
Updated and fixed failing tests
vasharma05 Feb 5, 2024
09c599a
Fixed TS errors
vasharma05 Feb 5, 2024
8eee039
Updated keys and values of translations
vasharma05 Feb 5, 2024
31e596a
Final changes
vasharma05 Feb 5, 2024
2f08cae
Merge branch 'main' of https://www.github.com/openmrs/openmrs-esm-pat…
vasharma05 Feb 5, 2024
67d97b5
Updated translations
vasharma05 Feb 5, 2024
fe52f88
Updated tests with text
vasharma05 Feb 5, 2024
a6a489b
Switching between order workspaces should not prompt the users to clo…
vasharma05 Feb 5, 2024
f7b3e67
Updated translations
vasharma05 Feb 5, 2024
a69e6dc
Updated `ignoreChanges` description
vasharma05 Feb 7, 2024
88d2a97
Merge branch 'feat/O3-2760' of https://www.github.com/openmrs/openmrs…
vasharma05 Feb 7, 2024
d21f49b
Review changes
vasharma05 Feb 7, 2024
3780617
Introduced new function 'discardChangesAndCloseWorkspace' to close wo…
vasharma05 Feb 7, 2024
cc55902
Updated text
vasharma05 Feb 12, 2024
f5c71d0
Reverted the implementation of discardChangesAndCloseWorkspace
vasharma05 Feb 16, 2024
ef9e258
Prompt function should be removed if the workspace is closed
vasharma05 Feb 16, 2024
b25b1ee
Merge branch 'main' of https://www.github.com/openmrs/openmrs-esm-pat…
vasharma05 Feb 16, 2024
ac8b76f
Fixed failing test
vasharma05 Feb 16, 2024
17615cf
Fixed TS issues
vasharma05 Feb 16, 2024
ac2f597
Merge branch 'feat/O3-2760' of https://www.github.com/openmrs/openmrs…
vasharma05 Feb 16, 2024
dc8b294
Review changes
vasharma05 Feb 16, 2024
aea04ec
Merge branch 'main' of https://www.github.com/openmrs/openmrs-esm-pat…
vasharma05 Feb 21, 2024
a4c5e3f
Removed appointments workspace
vasharma05 Feb 21, 2024
a16a39b
Updated translation
vasharma05 Feb 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,22 @@ import { type Visit } from '@openmrs/esm-framework';
import useFormSchema from '../hooks/useFormSchema';
import FormError from './form-error.component';
import styles from './form-renderer.scss';
import { type DefaultWorkspaceProps } from '@openmrs/esm-patient-common-lib';

interface FormRendererProps {
interface FormRendererProps extends DefaultWorkspaceProps {
formUuid: string;
patientUuid: string;
visit?: Visit;
closeWorkspace: () => void;
encounterUuid?: string;
}

const FormRenderer: React.FC<FormRendererProps> = ({ formUuid, patientUuid, visit, closeWorkspace, encounterUuid }) => {
const FormRenderer: React.FC<FormRendererProps> = ({
formUuid,
patientUuid,
visit,
discardChangesAndCloseWorkspace,
encounterUuid,
}) => {
const { t } = useTranslation();
const { schema, error, isLoading } = useFormSchema(formUuid);

Expand All @@ -30,7 +36,7 @@ const FormRenderer: React.FC<FormRendererProps> = ({ formUuid, patientUuid, visi
if (error) {
return (
<div className={styles.errorContainer}>
<FormError closeWorkspace={closeWorkspace} />
<FormError closeWorkspace={discardChangesAndCloseWorkspace} />
</div>
);
}
Expand All @@ -43,8 +49,8 @@ const FormRenderer: React.FC<FormRendererProps> = ({ formUuid, patientUuid, visi
patientUUID={patientUuid}
visit={visit}
formJson={schema}
handleClose={closeWorkspace}
onSubmit={() => closeWorkspace()}
handleClose={discardChangesAndCloseWorkspace}
onSubmit={discardChangesAndCloseWorkspace}
/>
)}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ describe('FormRenderer', () => {
formUuid: 'test-form-uuid',
patientUuid: 'test-patient-uuid',
closeWorkspace: jest.fn(),
discardChangesAndCloseWorkspace: jest.fn(),
promptBeforeClosing: jest.fn(),
};

test('renders FormError component when there is an error', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ type AllergyFormData = {
comment: string;
};

function AllergyForm({ closeWorkspace, patientUuid }: DefaultWorkspaceProps) {
function AllergyForm(props: DefaultWorkspaceProps) {
const { discardChangesAndCloseWorkspace, patientUuid, promptBeforeClosing } = props;
const { t } = useTranslation();
const { concepts } = useConfig();
const isTablet = useLayoutType() === 'tablet';
Expand All @@ -82,7 +83,14 @@ function AllergyForm({ closeWorkspace, patientUuid }: DefaultWorkspaceProps) {
const [isDisabled, setIsDisabled] = useState(true);
const { mutate } = useAllergies(patientUuid);

const { control, handleSubmit, watch, getValues, setValue } = useForm<AllergyFormData>({
const {
control,
handleSubmit,
watch,
getValues,
setValue,
formState: { isDirty },
} = useForm<AllergyFormData>({
mode: 'all',
resolver: zodResolver(allergyFormSchema),
defaultValues: {
Expand All @@ -95,6 +103,10 @@ function AllergyForm({ closeWorkspace, patientUuid }: DefaultWorkspaceProps) {
},
});

useEffect(() => {
promptBeforeClosing(() => isDirty);
}, [isDirty]);

const selectedAllergen = watch('allergen');
const selectedAllergicReactions = watch('allergicReactions');
const selectedSeverityOfWorstReaction = watch('severityOfWorstReaction');
Expand Down Expand Up @@ -154,7 +166,7 @@ function AllergyForm({ closeWorkspace, patientUuid }: DefaultWorkspaceProps) {
(response: FetchResponse) => {
if (response.status === 201) {
mutate();
closeWorkspace();
discardChangesAndCloseWorkspace();
showSnackbar({
isLowContrast: true,
kind: 'success',
Expand All @@ -174,7 +186,7 @@ function AllergyForm({ closeWorkspace, patientUuid }: DefaultWorkspaceProps) {
)
.finally(() => abortController.abort());
},
[otherConceptUuid, patientUuid, closeWorkspace, t, mutate],
[otherConceptUuid, patientUuid, discardChangesAndCloseWorkspace, t, mutate],
);

return (
Expand Down Expand Up @@ -333,7 +345,7 @@ function AllergyForm({ closeWorkspace, patientUuid }: DefaultWorkspaceProps) {
<ButtonSet
className={classNames(isTablet ? styles.tabletButtons : styles.desktopButtons, styles.actionButtons)}
>
<Button className={styles.button} onClick={closeWorkspace} kind="secondary">
<Button className={styles.button} onClick={discardChangesAndCloseWorkspace} kind="secondary">
{t('discard', 'Discard')}
</Button>
<Button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ describe('AllergyForm ', () => {
function renderAllergyForm() {
const testProps = {
closeWorkspace: () => {},
discardChangesAndCloseWorkspace: () => {},
promptBeforeClosing: () => {},
patient: mockPatient,
patientUuid: mockPatient.id,
Expand Down
20 changes: 16 additions & 4 deletions packages/esm-patient-allergies-app/src/index.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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);
12 changes: 0 additions & 12 deletions packages/esm-patient-allergies-app/src/routes.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,6 @@
"columnSpan": 4
}
},
{
"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",
Expand Down
1 change: 1 addition & 0 deletions packages/esm-patient-allergies-app/translations/am.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions packages/esm-patient-allergies-app/translations/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"otherNonCodedAllergicReaction": "رد فعل حساسية غير مشفر آخر",
"reaction": "رد الفعل",
"reactions": "ردود الفعل",
"recordNewAllergy": "Record a new allergy",
"saveAndClose": "حفظ وإغلاق",
"seeAll": "عرض الكل",
"selectAllergen": "اختر المواد المسببة للحساسية",
Expand Down
1 change: 1 addition & 0 deletions packages/esm-patient-allergies-app/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions packages/esm-patient-allergies-app/translations/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions packages/esm-patient-allergies-app/translations/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions packages/esm-patient-allergies-app/translations/he.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"otherNonCodedAllergicReaction": "תגובה אלרגנית אחרת לא מקודדת",
"reaction": "תגובה",
"reactions": "תגובות",
"recordNewAllergy": "Record a new allergy",
"saveAndClose": "שמירה וסגירה",
"seeAll": "הצג הכל",
"selectAllergen": "בחר את האלרגן",
Expand Down
1 change: 1 addition & 0 deletions packages/esm-patient-allergies-app/translations/km.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"otherNonCodedAllergicReaction": "ប្រតិកម្មអាលែហ្សីដែលមិនមានលេខកូដផ្សេងទៀត។",
"reaction": "Reaction",
"reactions": "ប្រតិកម្ម",
"recordNewAllergy": "Record a new allergy",
"saveAndClose": "រក្សាទុក និងបិទ",
"seeAll": "មើលឃើញទាំងអស់",
"selectAllergen": "ជ្រើសរើសអាឡែរហ្សី",
Expand Down
1 change: 1 addition & 0 deletions packages/esm-patient-allergies-app/translations/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"otherNonCodedAllergicReaction": "其他非编码过敏反应",
"reaction": "反应",
"reactions": "反应",
"recordNewAllergy": "Record a new allergy",
"saveAndClose": "保存并关闭",
"seeAll": "查看全部",
"selectAllergen": "选择过敏原",
Expand Down
1 change: 1 addition & 0 deletions packages/esm-patient-allergies-app/translations/zh_CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"otherNonCodedAllergicReaction": "其他非编码过敏反应",
"reaction": "反应",
"reactions": "反应",
"recordNewAllergy": "Record a new allergy",
"saveAndClose": "保存并关闭",
"seeAll": "查看全部",
"selectAllergen": "选择过敏原",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,7 @@ const AppointmentsBase: React.FC<AppointmentsBaseProps> = ({ 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 <DataTableSkeleton role="progressbar" compact={!isTablet} zebra />;
if (isError) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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,
Expand Down Expand Up @@ -60,20 +60,19 @@ const appointmentsFormSchema = z.object({

type AppointmentFormData = z.infer<typeof appointmentsFormSchema>;

interface AppointmentsFormProps {
interface AppointmentsFormProps extends DefaultWorkspaceProps {
appointment?: Appointment;
recurringPattern?: RecurringPattern;
patientUuid?: string;
context?: string;
closeWorkspace: () => void;
}

const AppointmentsForm: React.FC<AppointmentsFormProps> = ({
appointment,
recurringPattern,
patientUuid,
context,
closeWorkspace,
discardChangesAndCloseWorkspace,
promptBeforeClosing,
}) => {
const editedAppointmentTimeFormat = new Date(appointment?.startDateTime).getHours() >= 12 ? 'PM' : 'AM';
const defaultTimeFormat = appointment?.startDateTime
Expand Down Expand Up @@ -109,7 +108,14 @@ const AppointmentsForm: React.FC<AppointmentsFormProps> = ({
? dayjs(new Date(appointment?.startDateTime)).format('hh:mm')
: dayjs(new Date()).format('hh:mm');

const { control, getValues, setValue, watch, handleSubmit } = useForm<AppointmentFormData>({
const {
control,
getValues,
setValue,
watch,
handleSubmit,
formState: { isDirty },
} = useForm<AppointmentFormData>({
mode: 'all',
resolver: zodResolver(appointmentsFormSchema),
defaultValues: {
Expand All @@ -131,6 +137,10 @@ const AppointmentsForm: React.FC<AppointmentsFormProps> = ({
},
});

useEffect(() => {
promptBeforeClosing(() => isDirty);
}, [isDirty]);

const handleMultiselectChange = (e) => {
setValue(
'selectedDaysOfWeekText',
Expand Down Expand Up @@ -188,7 +198,7 @@ const AppointmentsForm: React.FC<AppointmentsFormProps> = ({
({ status }) => {
if (status === 200) {
setIsSubmitting(false);
closeWorkspace();
discardChangesAndCloseWorkspace();
mutate();

showSnackbar({
Expand Down Expand Up @@ -581,7 +591,7 @@ const AppointmentsForm: React.FC<AppointmentsFormProps> = ({
</section>
</Stack>
<ButtonSet className={isTablet ? styles.tablet : styles.desktop}>
<Button className={styles.button} onClick={closeWorkspace} kind="secondary">
<Button className={styles.button} onClick={discardChangesAndCloseWorkspace} kind="secondary">
{t('discard', 'Discard')}
</Button>
<Button className={styles.button} disabled={isSubmitting} onClick={handleSubmit(handleSaveAppointment)}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const testProps = {
closeWorkspace: jest.fn(),
patientUuid: mockPatient.id,
promptBeforeClosing: jest.fn(),
discardChangesAndCloseWorkspace: jest.fn(),
};

const mockCreateAppointment = saveAppointment as jest.Mock;
Expand Down Expand Up @@ -129,7 +130,7 @@ describe('AppointmentForm', () => {
const cancelButton = screen.getByRole('button', { name: /Discard/i });
await user.click(cancelButton);

expect(testProps.closeWorkspace).toHaveBeenCalledTimes(1);
expect(testProps.discardChangesAndCloseWorkspace).toHaveBeenCalledTimes(1);
});

it('renders a success snackbar upon successfully scheduling an appointment', async () => {
Expand Down
16 changes: 9 additions & 7 deletions packages/esm-patient-appointments-app/src/index.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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'),
});
Loading
Loading