diff --git a/packages/framework/esm-framework/docs/API.md b/packages/framework/esm-framework/docs/API.md index c06d86372..8549ab51b 100644 --- a/packages/framework/esm-framework/docs/API.md +++ b/packages/framework/esm-framework/docs/API.md @@ -6994,7 +6994,7 @@ Function to close an opened workspace #### Defined in -[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:288](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L288) +[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:305](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L305) ___ @@ -7045,7 +7045,7 @@ prop named `workspaceTitle` will override the title of the workspace. #### Defined in -[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:166](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L166) +[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:178](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L178) ___ @@ -7071,7 +7071,7 @@ Use this function to navigate to a new page and launch a workspace on that page. #### Defined in -[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:251](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L251) +[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:263](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L263) ___ @@ -7085,4 +7085,4 @@ ___ #### Defined in -[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:402](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L402) +[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:419](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L419) diff --git a/packages/framework/esm-framework/docs/interfaces/DefaultWorkspaceProps.md b/packages/framework/esm-framework/docs/interfaces/DefaultWorkspaceProps.md index 2ccae3c3b..9b73c889a 100644 --- a/packages/framework/esm-framework/docs/interfaces/DefaultWorkspaceProps.md +++ b/packages/framework/esm-framework/docs/interfaces/DefaultWorkspaceProps.md @@ -43,7 +43,7 @@ closed, given the user forcefully closes the workspace. #### Defined in -[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:38](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L38) +[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:47](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L47) ___ @@ -66,7 +66,7 @@ will directly close the workspace without any prompt #### Defined in -[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:48](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L48) +[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:57](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L57) ___ @@ -89,7 +89,7 @@ this workspace is closed; e.g. if there is unsaved data. #### Defined in -[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:43](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L43) +[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:52](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L52) ___ @@ -117,4 +117,4 @@ title needs to be set dynamically. #### Defined in -[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:63](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L63) +[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:72](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L72) diff --git a/packages/framework/esm-framework/docs/interfaces/OpenWorkspace.md b/packages/framework/esm-framework/docs/interfaces/OpenWorkspace.md index e85380c05..0c9a71801 100644 --- a/packages/framework/esm-framework/docs/interfaces/OpenWorkspace.md +++ b/packages/framework/esm-framework/docs/interfaces/OpenWorkspace.md @@ -202,7 +202,7 @@ ___ #### Defined in -[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:98](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L98) +[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:107](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L107) ## Methods @@ -232,7 +232,7 @@ closed, given the user forcefully closes the workspace. #### Defined in -[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:38](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L38) +[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:47](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L47) ___ @@ -259,7 +259,7 @@ will directly close the workspace without any prompt #### Defined in -[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:48](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L48) +[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:57](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L57) ___ @@ -304,7 +304,7 @@ this workspace is closed; e.g. if there is unsaved data. #### Defined in -[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:43](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L43) +[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:52](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L52) ___ @@ -336,4 +336,4 @@ title needs to be set dynamically. #### Defined in -[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:63](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L63) +[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:72](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L72) diff --git a/packages/framework/esm-framework/docs/interfaces/Prompt.md b/packages/framework/esm-framework/docs/interfaces/Prompt.md index 318476751..b55e30625 100644 --- a/packages/framework/esm-framework/docs/interfaces/Prompt.md +++ b/packages/framework/esm-framework/docs/interfaces/Prompt.md @@ -23,7 +23,7 @@ #### Defined in -[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:82](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L82) +[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:91](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L91) ___ @@ -35,7 +35,7 @@ Defaults to "Cancel" #### Defined in -[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:87](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L87) +[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:96](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L96) ___ @@ -47,7 +47,7 @@ Defaults to "Confirm" #### Defined in -[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:84](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L84) +[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:93](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L93) ___ @@ -57,7 +57,7 @@ ___ #### Defined in -[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:81](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L81) +[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:90](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L90) ## Methods @@ -71,4 +71,4 @@ ___ #### Defined in -[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:85](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L85) +[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:94](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L94) diff --git a/packages/framework/esm-framework/docs/interfaces/WorkspacesInfo.md b/packages/framework/esm-framework/docs/interfaces/WorkspacesInfo.md index 573647531..de12e1687 100644 --- a/packages/framework/esm-framework/docs/interfaces/WorkspacesInfo.md +++ b/packages/framework/esm-framework/docs/interfaces/WorkspacesInfo.md @@ -19,7 +19,7 @@ #### Defined in -[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:396](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L396) +[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:413](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L413) ___ @@ -29,7 +29,7 @@ ___ #### Defined in -[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:397](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L397) +[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:414](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L414) ___ @@ -39,7 +39,7 @@ ___ #### Defined in -[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:398](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L398) +[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:415](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L415) ___ @@ -49,4 +49,4 @@ ___ #### Defined in -[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:399](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L399) +[packages/framework/esm-styleguide/src/workspaces/workspaces.ts:416](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/workspaces.ts#L416) diff --git a/packages/framework/esm-styleguide/src/workspaces/container/workspace-renderer.component.tsx b/packages/framework/esm-styleguide/src/workspaces/container/workspace-renderer.component.tsx index ff8579bd5..6e3b404c8 100644 --- a/packages/framework/esm-styleguide/src/workspaces/container/workspace-renderer.component.tsx +++ b/packages/framework/esm-styleguide/src/workspaces/container/workspace-renderer.component.tsx @@ -39,7 +39,7 @@ export function WorkspaceRenderer({ workspace, additionalPropsFromPage }: Worksp ...workspaceFamilyState, ...workspace.additionalProps, }, - [workspace, additionalPropsFromPage], + [workspace, additionalPropsFromPage, workspaceFamilyState], ); return lifecycle ? ( diff --git a/packages/framework/esm-styleguide/src/workspaces/container/workspace-renderer.test.tsx b/packages/framework/esm-styleguide/src/workspaces/container/workspace-renderer.test.tsx new file mode 100644 index 000000000..71f128af0 --- /dev/null +++ b/packages/framework/esm-styleguide/src/workspaces/container/workspace-renderer.test.tsx @@ -0,0 +1,64 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { WorkspaceRenderer } from './workspace-renderer.component'; +import { getWorkspaceFamilyStore, OpenWorkspace } from '../workspaces'; +import Parcel from 'single-spa-react/parcel'; + +const mockFn = jest.fn(); + +jest.mock('single-spa-react/parcel', () => + jest.fn((props) => { + mockFn(props); + return
; + }), +); + +describe('WorkspaceRenderer', () => { + it('should render workspace', async () => { + const mockedCloseWorkspace = jest.fn(); + const mockedCloseWorkspaceWithSavedChanges = jest.fn(); + const mockedPromptBeforeClosing = jest.fn(); + const mockedSetTitle = jest.fn(); + const mockedLoadFn = jest.fn().mockImplementation(() => Promise.resolve({ default: 'file-content' })); + getWorkspaceFamilyStore('test-sidebar-family')?.setState({ + // Testing that the workspace family state should be overrided by additionalProps + foo: false, + workspaceFamilyState: {}, + }); + render( + , + ); + + expect(screen.getByText('Loading ...')).toBeInTheDocument(); + expect(mockedLoadFn).toHaveBeenCalled(); + await screen.findByTestId('mocked-parcel'); + + expect(mockFn).toHaveBeenCalledWith({ + config: 'file-content', + mountParcel: undefined, + closeWorkspace: mockedCloseWorkspace, + closeWorkspaceWithSavedChanges: mockedCloseWorkspaceWithSavedChanges, + promptBeforeClosing: mockedPromptBeforeClosing, + setTitle: mockedSetTitle, + foo: 'true', + bar: 'true', + workspaceFamilyState: {}, + }); + }); +}); diff --git a/packages/framework/esm-styleguide/src/workspaces/workspaces.test.ts b/packages/framework/esm-styleguide/src/workspaces/workspaces.test.ts index a2715577f..7fe772353 100644 --- a/packages/framework/esm-styleguide/src/workspaces/workspaces.test.ts +++ b/packages/framework/esm-styleguide/src/workspaces/workspaces.test.ts @@ -1,6 +1,7 @@ import { type Prompt, cancelPrompt, + closeWorkspace, getWorkspaceFamilyStore, getWorkspaceStore, launchWorkspace, @@ -8,7 +9,6 @@ import { } from './workspaces'; import { registerExtension, registerWorkspace } from '@openmrs/esm-extensions'; import { clearMockExtensionRegistry } from '@openmrs/esm-framework/mock'; -import { waitFor } from '@testing-library/dom'; describe('workspace system', () => { beforeEach(() => { @@ -499,7 +499,28 @@ describe('workspace system', () => { expect(workspaceFamilyStore?.getState()).toStrictEqual({}); }); - it('should share the same store with different workspaces with same sidebarFamilyName', () => { + it('should clear workspace family store by default if the workspace is closed, since `clearWorkspaceFamilyStore` is true by default', async () => { + registerWorkspace({ + name: 'ward-patient-workspace', + title: 'Ward Patient Workspace', + load: jest.fn(), + type: 'ward-patient', + moduleName: '@openmrs/esm-ward-app', + hasOwnSidebar: true, + sidebarFamily: 'ward-patient-sidebar', + }); + launchWorkspace('ward-patient-workspace', { + foo: true, + }); + const workspaceFamilyStore = getWorkspaceFamilyStore('ward-patient-sidebar'); + expect(workspaceFamilyStore).toBeTruthy(); + expect(workspaceFamilyStore?.getState()?.['foo']).toBe(true); + closeWorkspace('ward-patient-workspace'); + expect(workspaceFamilyStore?.getState()?.['foo']).toBeUndefined(); + expect(workspaceFamilyStore?.getState()).toStrictEqual({}); + }); + + it('should not clear the workspace store if the new workspace opened is of the same type as the already opened workspace', () => { const sidebarFamily = 'ward-patient-sidebar'; registerWorkspace({ name: 'ward-patient-workspace', @@ -509,7 +530,6 @@ describe('workspace system', () => { moduleName: '@openmrs/esm-ward-app', hasOwnSidebar: true, sidebarFamily, - canHide: true, }); registerWorkspace({ name: 'transfer-patient-workspace', @@ -529,19 +549,13 @@ describe('workspace system', () => { expect(sidebarFamilyStore).toBeTruthy(); expect(sidebarFamilyStore?.getState()?.['foo']).toBe(true); launchWorkspace('transfer-patient-workspace', { bar: false }); - expect(workspaceStore.getState().openWorkspaces.length).toBe(2); + expect(workspaceStore.getState().openWorkspaces.length).toBe(1); const transferPatientWorkspace = workspaceStore.getState().openWorkspaces[0]; - const wardPatientWorkspace = workspaceStore.getState().openWorkspaces[1]; - expect(wardPatientWorkspace.name).toBe('ward-patient-workspace'); - expect(wardPatientWorkspace).toBeTruthy(); - expect(sidebarFamilyStore?.getState()?.['foo']).toBe(true); - expect(sidebarFamilyStore?.getState()?.['bar']).toBe(false); - expect(transferPatientWorkspace.name).toBe('transfer-patient-workspace'); expect(sidebarFamilyStore?.getState()?.['foo']).toBe(true); expect(sidebarFamilyStore?.getState()?.['bar']).toBe(false); }); - it('should clear workspace if all the workspaces of the same family is closed', async () => { + it('should clear the store when new workspace with different sidebar is opened, given the original workspace cannot hide', () => { registerWorkspace({ name: 'ward-patient-workspace', title: 'Ward Patient Workspace', @@ -550,7 +564,6 @@ describe('workspace system', () => { moduleName: '@openmrs/esm-ward-app', hasOwnSidebar: true, sidebarFamily: 'ward-patient-sidebar', - canHide: true, }); registerWorkspace({ name: 'transfer-patient-workspace', @@ -559,25 +572,113 @@ describe('workspace system', () => { type: 'transfer-patient', moduleName: '@openmrs/esm-ward-app', hasOwnSidebar: true, + sidebarFamily: 'another-sidebar-family', + }); + const workspaceStore = getWorkspaceStore(); + launchWorkspace('ward-patient-workspace', { + foo: true, + }); + const wardPatientFamilyStore = getWorkspaceFamilyStore('ward-patient-sidebar'); + expect(workspaceStore.getState().openWorkspaces.length).toBe(1); + expect(wardPatientFamilyStore).toBeTruthy(); + expect(wardPatientFamilyStore?.getState()?.['foo']).toBe(true); + launchWorkspace('transfer-patient-workspace', { bar: false }); + const anotherSidebarFamilyStore = getWorkspaceFamilyStore('another-sidebar-family'); + expect(workspaceStore.getState().openWorkspaces.length).toBe(1); + expect(anotherSidebarFamilyStore?.getState()?.['bar']).toBe(false); + expect(wardPatientFamilyStore?.getState()?.['foo']).toBeUndefined(); + expect(wardPatientFamilyStore?.getState()).toStrictEqual({}); + }); + + it('should not clear the store when new workspace with different sidebar is opened, given the original workspace can hide', () => { + registerWorkspace({ + name: 'ward-patient-workspace', + title: 'Ward Patient Workspace', + load: jest.fn(), + type: 'ward-patient', + moduleName: '@openmrs/esm-ward-app', + hasOwnSidebar: true, sidebarFamily: 'ward-patient-sidebar', + canHide: true, + }); + registerWorkspace({ + name: 'transfer-patient-workspace', + title: 'Transfer Patient Workspace', + load: jest.fn(), + type: 'transfer-patient', + moduleName: '@openmrs/esm-ward-app', + hasOwnSidebar: true, + sidebarFamily: 'another-sidebar-family', }); + const workspaceStore = getWorkspaceStore(); launchWorkspace('ward-patient-workspace', { foo: true, }); + const wardPatientFamilyStore = getWorkspaceFamilyStore('ward-patient-sidebar'); + expect(workspaceStore.getState().openWorkspaces.length).toBe(1); + expect(wardPatientFamilyStore).toBeTruthy(); + expect(wardPatientFamilyStore?.getState()?.['foo']).toBe(true); launchWorkspace('transfer-patient-workspace', { bar: false }); + const anotherSidebarFamilyStore = getWorkspaceFamilyStore('another-sidebar-family'); + expect(workspaceStore.getState().openWorkspaces.length).toBe(2); + expect(anotherSidebarFamilyStore?.getState()?.['bar']).toBe(false); + expect(wardPatientFamilyStore?.getState()?.['foo']).toBe(true); + }); + + it('should not clear the workspace if a workspace of same sidebar family is opened', () => { + registerWorkspace({ + name: 'ward-patient-workspace', + title: 'Ward Patient Workspace', + load: jest.fn(), + type: 'ward-patient', + moduleName: '@openmrs/esm-ward-app', + hasOwnSidebar: true, + sidebarFamily: 'ward-patient-sidebar', + canHide: true, + }); + registerWorkspace({ + name: 'transfer-patient-workspace', + title: 'Transfer Patient Workspace', + load: jest.fn(), + type: 'transfer-patient', + moduleName: '@openmrs/esm-ward-app', + hasOwnSidebar: true, + sidebarFamily: 'ward-patient-sidebar', + }); const workspaceStore = getWorkspaceStore(); + launchWorkspace('ward-patient-workspace', { + foo: true, + }); + const wardPatientFamilyStore = getWorkspaceFamilyStore('ward-patient-sidebar'); + expect(workspaceStore.getState().openWorkspaces.length).toBe(1); + expect(wardPatientFamilyStore).toBeTruthy(); + expect(wardPatientFamilyStore?.getState()?.['foo']).toBe(true); + launchWorkspace('transfer-patient-workspace', { bar: false }); expect(workspaceStore.getState().openWorkspaces.length).toBe(2); - const transferPatientWorkspace = workspaceStore.getState().openWorkspaces[0]; - transferPatientWorkspace.closeWorkspace({ ignoreChanges: true }); - const wardPatientWorkspace = workspaceStore.getState().openWorkspaces[0]; - const wardPatientWorkspaceFamilyStore = getWorkspaceFamilyStore('ward-patient-sidebar'); - expect(wardPatientWorkspaceFamilyStore).toBeTruthy(); - expect(wardPatientWorkspaceFamilyStore?.getState()?.['foo']).toBe(true); - expect(wardPatientWorkspaceFamilyStore?.getState()?.['bar']).toBe(false); - // Closing the last opened workspace of the family - wardPatientWorkspace.closeWorkspace({ ignoreChanges: true }); - expect(wardPatientWorkspaceFamilyStore?.getState()?.['foo']).toBeUndefined(); - expect(wardPatientWorkspaceFamilyStore?.getState()?.['bar']).toBeUndefined(); + expect(wardPatientFamilyStore?.getState()?.['foo']).toBe(true); + expect(wardPatientFamilyStore?.getState()?.['bar']).toBe(false); + }); + + it('should retain default closeWorkspace options in case workspace options are passed', () => { + registerWorkspace({ + name: 'ward-patient-workspace', + title: 'Ward Patient Workspace', + load: jest.fn(), + type: 'ward-patient', + moduleName: '@openmrs/esm-ward-app', + hasOwnSidebar: true, + sidebarFamily: 'ward-patient-sidebar', + }); + launchWorkspace('ward-patient-workspace', { + foo: true, + }); + const workspaceFamilyStore = getWorkspaceFamilyStore('ward-patient-sidebar'); + expect(workspaceFamilyStore).toBeTruthy(); + expect(workspaceFamilyStore?.getState()?.['foo']).toBe(true); + // test that default options are interpolated when providing options to `closeWorkspace` + closeWorkspace('ward-patient-workspace', { ignoreChanges: true }); + expect(workspaceFamilyStore?.getState()?.['foo']).toBeUndefined(); + expect(workspaceFamilyStore?.getState()).toStrictEqual({}); }); }); }); diff --git a/packages/framework/esm-styleguide/src/workspaces/workspaces.ts b/packages/framework/esm-styleguide/src/workspaces/workspaces.ts index 24b10f1f3..ac9693361 100644 --- a/packages/framework/esm-styleguide/src/workspaces/workspaces.ts +++ b/packages/framework/esm-styleguide/src/workspaces/workspaces.ts @@ -26,6 +26,15 @@ export interface CloseWorkspaceOptions { onWorkspaceClose?: () => void; } +interface CloseWorkspaceInternalOptions extends CloseWorkspaceOptions { + /** + * Controls whether the workspace family store will be cleared when this workspace is closed. Defaults to true except when opening a new workspace of the same family. + * + * @default true + */ + clearWorkspaceFamilyStore?: boolean; +} + /** The default parameters received by all workspaces */ export interface DefaultWorkspaceProps { /** @@ -117,13 +126,16 @@ function promptBeforeLaunchingWorkspace( newWorkspaceDetails: { name: string; additionalProps?: object }, ) { const { name, additionalProps } = newWorkspaceDetails; + const newWorkspaceRegistration = getWorkspaceRegistration(name); const proceed = () => { - workspace.closeWorkspace({ + closeWorkspaceInternal(workspace.name, { ignoreChanges: true, // Calling the launchWorkspace again, since one of the `if` case // might resolve, but we need to check all the cases before launching the form. onWorkspaceClose: () => launchWorkspace(name, additionalProps), + // If the new workspace is of the same sidebar family, then we don't need to clear the workspace family store. + clearWorkspaceFamilyStore: newWorkspaceRegistration.sidebarFamily !== workspace.sidebarFamily, }); }; @@ -280,18 +292,22 @@ export function cancelPrompt() { store.setState({ ...state, prompt: null }); } +const defaultOptions: CloseWorkspaceOptions = { + ignoreChanges: false, + onWorkspaceClose: () => {}, +}; + /** * Function to close an opened workspace * @param name Workspace registration name * @param options Options to close workspace */ -export function closeWorkspace( - name: string, - options: CloseWorkspaceOptions = { - ignoreChanges: false, - onWorkspaceClose: () => {}, - }, -): boolean { +export function closeWorkspace(name: string, options: CloseWorkspaceOptions = {}) { + return closeWorkspaceInternal(name, { ...options, clearWorkspaceFamilyStore: true }); +} + +function closeWorkspaceInternal(name: string, options: CloseWorkspaceInternalOptions = {}): boolean { + options = { ...defaultOptions, ...options }; const store = getWorkspaceStore(); const updateStoreWithClosedWorkspace = () => { @@ -301,10 +317,11 @@ export function closeWorkspace( const newOpenWorkspaces = state.openWorkspaces.filter((w) => w.name != name); const workspaceFamilyStore = getWorkspaceFamilyStore(workspaceSidebarFamilyName); if ( + options.clearWorkspaceFamilyStore && workspaceFamilyStore && - !newOpenWorkspaces.some((workspace) => workspace.sidebarFamily === workspaceSidebarFamilyName) + !newOpenWorkspaces.some((w) => w.sidebarFamily === workspaceSidebarFamilyName) ) { - // Clearing the workspace family store if there are no more workspaces with the same sidebar family name + // Clearing the workspace family store if there are no more workspaces with the same sidebar family name and the new workspace is not of the same sidebar family, which is handled in the `launchWorkspace` function. workspaceFamilyStore.setState({}, true); const unsubscribe = workspaceFamilyStore.subscribe(() => {}); unsubscribe?.();