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

(fix) O3-2426: Closing drug search panel should send user back to order basket if they previously had it open #1452

Closed
wants to merge 7 commits into from
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ const WorkspaceWindow: React.FC<ContextWorkspaceParams> = () => {
onClick={toggleWindowState}
size="lg"
>
{maximized ? <Maximize /> : <Minimize />}
{maximized ? <Minimize /> : <Maximize />}
</HeaderGlobalAction>
)}
{canHide ? (
Expand Down
19 changes: 16 additions & 3 deletions packages/esm-patient-common-lib/src/workspaces/workspaces.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,15 @@ describe('workspace system', () => {

test('registering, launching, and closing a workspace', () => {
const store = getWorkspaceStore();
const mockedOnCloseWorkspace = jest.fn();
registerWorkspace({ name: 'allergies', title: 'Allergies', load: jest.fn() });
launchPatientWorkspace('allergies', { foo: true });
launchPatientWorkspace('allergies', { foo: true, onCloseWorkspace: mockedOnCloseWorkspace });
expect(store.getState().openWorkspaces.length).toEqual(1);
const allergies = store.getState().openWorkspaces[0];
expect(allergies.name).toBe('allergies');
expect(allergies.additionalProps['foo']).toBe(true);
allergies.closeWorkspace();
expect(mockedOnCloseWorkspace).toHaveBeenCalled();
expect(store.getState().openWorkspaces.length).toEqual(0);
});

Expand Down Expand Up @@ -304,18 +306,23 @@ describe('workspace system', () => {

test('respects promptBeforeClosing function', () => {
const store = getWorkspaceStore();
const mockedOnCloseWorkspace = jest.fn();
registerWorkspace({ name: 'hiv', title: 'HIV', load: jest.fn() });
registerWorkspace({ name: 'diabetes', title: 'Diabetes', load: jest.fn() });
launchPatientWorkspace('hiv');
store.getState().openWorkspaces[0].promptBeforeClosing(() => false);
launchPatientWorkspace('diabetes');
launchPatientWorkspace('diabetes', {
onCloseWorkspace: mockedOnCloseWorkspace,
});
expect(store.getState().prompt).toBeNull();
expect(store.getState().openWorkspaces[0].name).toBe('diabetes');
store.getState().openWorkspaces[0].promptBeforeClosing(() => true);
launchPatientWorkspace('hiv');
expect(store.getState().openWorkspaces[0].name).toBe('diabetes');
expect(store.getState().prompt.title).toBe('You have unsaved changes');
store.getState().prompt.onConfirm();
// Should call the `onCloseWorkspace` function if passed
expect(mockedOnCloseWorkspace).toHaveBeenCalled();
expect(store.getState().openWorkspaces[0].name).toBe('hiv');
});

Expand Down Expand Up @@ -343,8 +350,11 @@ describe('workspace system', () => {

test('respects promptBeforeClosing function before closing workspace, with unsaved changes', () => {
const store = getWorkspaceStore();
const mockedOnCloseWorkspace = jest.fn();
registerWorkspace({ name: 'hiv', title: 'HIV', load: jest.fn() });
launchPatientWorkspace('hiv');
launchPatientWorkspace('hiv', {
onCloseWorkspace: mockedOnCloseWorkspace,
});
store.getState().openWorkspaces[0].promptBeforeClosing(() => true);
store.getState().openWorkspaces[0].closeWorkspace(false);
expect(store.getState().prompt.title).toBe('Unsaved Changes');
Expand All @@ -353,6 +363,9 @@ describe('workspace system', () => {
);
expect(store.getState().prompt.confirmText).toBe('Discard');
store.getState().prompt.onConfirm();
expect(store.getState().prompt).toBeNull();
// Should call the `onCloseWorkspace` function if passed
expect(mockedOnCloseWorkspace).toHaveBeenCalled();
expect(store.getState().openWorkspaces.length).toBe(0);
});
});
36 changes: 29 additions & 7 deletions packages/esm-patient-common-lib/src/workspaces/workspaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ export interface WorkspaceRegistration {
preferredWindowSize?: WorkspaceWindowState;
}

interface WorkspaceAdditionalProps {
workspaceTitle?: string;
onCloseWorkspace?: () => void;
[x: string]: any;
}

let registeredWorkspaces: Record<string, WorkspaceRegistration> = {};

/**
Expand Down Expand Up @@ -154,12 +160,12 @@ function promptBeforeLaunchingWorkspace(
* @param name The name of the workspace to launch
* @param additionalProps Props to pass to the workspace component being launched
*/
export function launchPatientWorkspace(name: string, additionalProps?: object) {
export function launchPatientWorkspace(name: string, additionalProps?: WorkspaceAdditionalProps) {
const store = getWorkspaceStore();
const workspace = getWorkspaceRegistration(name);
const newWorkspace = {
...workspace,
closeWorkspace: (ignoreChanges = true) => closeWorkspace(name, ignoreChanges),
closeWorkspace: (ignoreChanges = true) => closeWorkspace(name, ignoreChanges, additionalProps?.onCloseWorkspace),
promptBeforeClosing: (testFcn) => promptBeforeClosing(name, testFcn),
additionalProps,
};
Expand Down Expand Up @@ -239,9 +245,27 @@ export function cancelPrompt() {
store.setState({ ...state, prompt: null });
}

export function closeWorkspace(name: string, ignoreChanges: boolean) {
export function closeWorkspace(name: string, ignoreChanges: boolean, onCloseWorkspace?: () => void) {
const store = getWorkspaceStore();
const promptCheckFcn = getPromptBeforeClosingFcn(name);
const updateStoreWithClosedWorkspace = () => {
const state = store.getState();
const newOpenWorkspaces = state.openWorkspaces.filter((w) => w.name !== name);

store.setState({
...state,
prompt: null,
openWorkspaces: newOpenWorkspaces,
});

if (onCloseWorkspace && typeof onCloseWorkspace === 'function') {
try {
onCloseWorkspace();
} catch (e) {
console.error(`Custom 'onCloseWorkspace' for workspace ${name} caused an error`, e);
}
}
};
if (!ignoreChanges && promptCheckFcn && promptCheckFcn()) {
const prompt: Prompt = {
title: translateFrom('@openmrs/esm-patient-chart-app', 'unsavedChangesTitleText', 'Unsaved Changes'),
Expand All @@ -251,15 +275,13 @@ export function closeWorkspace(name: string, ignoreChanges: boolean) {
`You have unsaved changes in the side panel. Do you want to discard these changes?`,
),
onConfirm: () => {
const state = store.getState();
store.setState({ ...state, prompt: null, openWorkspaces: state.openWorkspaces.filter((w) => w.name != name) });
updateStoreWithClosedWorkspace();
},
confirmText: translateFrom('@openmrs/esm-patient-chart-app', 'discard', 'Discard'),
};
store.setState({ ...store.getState(), prompt });
} else {
const state = store.getState();
store.setState({ ...state, openWorkspaces: state.openWorkspaces.filter((w) => w.name != name) });
updateStoreWithClosedWorkspace();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,14 @@ export default function DrugOrderBasketPanelExtension() {
};
}, [orders]);

const onClose = useCallback(() => {
launchPatientWorkspace('order-basket');
}, []);

const openDrugSearch = () => {
launchPatientWorkspace('add-drug-order');
launchPatientWorkspace('add-drug-order', {
onCloseWorkspace: onClose,
});
};

const openDrugForm = (order: DrugOrderBasketItem) => {
Expand Down
Loading