@openmrs/esm-styleguide 10.0.1-pre.5717 → 10.0.1-pre.5723
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/dist/workspaces2/active-workspace-window.component.d.ts.map +1 -1
- package/dist/workspaces2/active-workspace-window.component.js +3 -3
- package/dist/workspaces2/workspace2.component.d.ts +9 -8
- package/dist/workspaces2/workspace2.component.d.ts.map +1 -1
- package/dist/workspaces2/workspace2.d.ts +11 -4
- package/dist/workspaces2/workspace2.d.ts.map +1 -1
- package/dist/workspaces2/workspace2.js +9 -0
- package/dist/workspaces2/workspace2.module.scss +0 -3
- package/package.json +25 -25
- package/src/workspaces2/active-workspace-window.component.tsx +5 -4
- package/src/workspaces2/active-workspace-window.test.tsx +46 -3
- package/src/workspaces2/exported-workspace.test.tsx +3 -3
- package/src/workspaces2/workspace2.component.tsx +14 -9
- package/src/workspaces2/workspace2.module.scss +0 -3
- package/src/workspaces2/workspace2.test.ts +68 -0
- package/src/workspaces2/workspace2.ts +16 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
[0] Successfully compiled: 117 files, copied 171 files with swc (
|
|
1
|
+
[0] Successfully compiled: 117 files, copied 171 files with swc (176.65ms)
|
|
2
2
|
[0] swc --strip-leading-paths --copy-files src -d dist && svgo -rf dist --quiet exited with code 0
|
|
3
3
|
[1] tsc --project tsconfig.build.json exited with code 0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"active-workspace-window.component.d.ts","sourceRoot":"","sources":["../../src/workspaces2/active-workspace-window.component.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuD,MAAM,OAAO,CAAC;AAM5E,OAAO,EACL,KAAK,YAAY,EAKlB,MAAM,yBAAyB,CAAC;AAOjC,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAGzE,UAAU,oBAAoB;IAC5B,YAAY,EAAE,YAAY,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IACvC,OAAO,EAAE,sBAAsB,CAAC;IAChC;;;;OAIG;IACH,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;CACzB;AAKD;;;GAGG;AACH,QAAA,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA4DzD,CAAC;
|
|
1
|
+
{"version":3,"file":"active-workspace-window.component.d.ts","sourceRoot":"","sources":["../../src/workspaces2/active-workspace-window.component.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuD,MAAM,OAAO,CAAC;AAM5E,OAAO,EACL,KAAK,YAAY,EAKlB,MAAM,yBAAyB,CAAC;AAOjC,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAGzE,UAAU,oBAAoB;IAC5B,YAAY,EAAE,YAAY,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IACvC,OAAO,EAAE,sBAAsB,CAAC;IAChC;;;;OAIG;IACH,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;CACzB;AAKD;;;GAGG;AACH,QAAA,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA4DzD,CAAC;AAqRF,eAAe,qBAAqB,CAAC"}
|
|
@@ -9,7 +9,7 @@ import { isDesktop, useLayoutType, useStore } from "@openmrs/esm-react-utils";
|
|
|
9
9
|
import { loadLifeCycles } from "@openmrs/esm-routes";
|
|
10
10
|
import { getCoreTranslation } from "@openmrs/esm-translations";
|
|
11
11
|
import { ArrowRightIcon, CloseIcon } from "../icons/index.js";
|
|
12
|
-
import { closeWorkspaceGroup2, useWorkspace2Store } from "./workspace2.js";
|
|
12
|
+
import { closeWorkspaceGroup2, getOpenedWindowWidth, useWorkspace2Store } from "./workspace2.js";
|
|
13
13
|
import styles from "./workspace2.module.scss";
|
|
14
14
|
// module-level so the store subscription's snapshot getter stays stable across renders
|
|
15
15
|
const selectRegisteredWorkspacesByName = (state)=>state.registeredWorkspacesByName;
|
|
@@ -171,12 +171,12 @@ const ActiveWorkspace = ({ lifeCycle, openedWorkspace, openedWindow, groupProps,
|
|
|
171
171
|
* window system.
|
|
172
172
|
*/ const WorkspaceChrome = ({ openedWorkspace, openedWindow, isRootWorkspace, showActionMenu, closeWindow, children })=>{
|
|
173
173
|
const layout = useLayoutType();
|
|
174
|
-
const { openedGroup, openedWindows, registeredWindowsByName, registeredGroupsByName, isMostRecentlyOpenedWindowHidden, setWindowMaximized, hideWindow } = useWorkspace2Store();
|
|
174
|
+
const { openedGroup, openedWindows, registeredWindowsByName, registeredWorkspacesByName, registeredGroupsByName, isMostRecentlyOpenedWindowHidden, setWindowMaximized, hideWindow } = useWorkspace2Store();
|
|
175
175
|
const windowName = openedWindow.windowName;
|
|
176
176
|
const { maximized } = openedWindow;
|
|
177
177
|
const title = openedWorkspace.title ?? '';
|
|
178
178
|
const windowDef = registeredWindowsByName[windowName];
|
|
179
|
-
const width =
|
|
179
|
+
const width = getOpenedWindowWidth(openedWindow, registeredWorkspacesByName, registeredWindowsByName);
|
|
180
180
|
const icon = windowDef?.icon;
|
|
181
181
|
const canMaximize = windowDef?.canMaximize;
|
|
182
182
|
const canCloseGroup = openedGroup ? registeredGroupsByName[openedGroup.groupName]?.persistence === 'closable' : false;
|
|
@@ -36,15 +36,16 @@ export interface Workspace2DefinitionProps<WorkspaceProps extends object = objec
|
|
|
36
36
|
windowName: string;
|
|
37
37
|
isRootWorkspace: boolean;
|
|
38
38
|
showActionMenu: boolean;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The props the framework actually passes to a workspace: the public `Workspace2DefinitionProps` plus
|
|
42
|
+
* the setters `<Workspace2>` uses to report its `title` and `hasUnsavedChanges` to the workspace window.
|
|
43
|
+
* Not part of the public API.
|
|
44
|
+
*/
|
|
45
|
+
export interface Workspace2InternalProps<WorkspaceProps extends object = object, WindowProps extends object = object, GroupProps extends object = object> extends Workspace2DefinitionProps<WorkspaceProps, WindowProps, GroupProps> {
|
|
46
|
+
/** Records the title of this workspace, for display in the workspace window header. */
|
|
43
47
|
setWorkspaceTitle(title: string): void;
|
|
44
|
-
/**
|
|
45
|
-
* Records whether this workspace has unsaved changes.
|
|
46
|
-
* @internal Called by `<Workspace2>`; use its `hasUnsavedChanges` prop instead.
|
|
47
|
-
*/
|
|
48
|
+
/** Records whether this workspace has unsaved changes. */
|
|
48
49
|
setHasUnsavedChanges(hasUnsavedChanges: boolean): void;
|
|
49
50
|
}
|
|
50
51
|
export type Workspace2Definition<WorkspaceProps extends object, WindowProps extends object, GroupProps extends object> = React.FC<Workspace2DefinitionProps<WorkspaceProps, WindowProps, GroupProps>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace2.component.d.ts","sourceRoot":"","sources":["../../src/workspaces2/workspace2.component.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAa,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGzD,UAAU,eAAe;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,CAAC;IACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,yBAAyB,CACxC,cAAc,SAAS,MAAM,GAAG,MAAM,EACtC,WAAW,SAAS,MAAM,GAAG,MAAM,EACnC,UAAU,SAAS,MAAM,GAAG,MAAM;IAElC;;;;;;OAMG;IACH,oBAAoB,CAAC,KAAK,SAAS,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzG;;;;;;OAMG;IACH,cAAc,CAAC,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,OAAO,CAAC;QAAC,qBAAqB,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEvG,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B;;;OAGG;IACH,aAAa,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAClD,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"workspace2.component.d.ts","sourceRoot":"","sources":["../../src/workspaces2/workspace2.component.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAa,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGzD,UAAU,eAAe;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,CAAC;IACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,yBAAyB,CACxC,cAAc,SAAS,MAAM,GAAG,MAAM,EACtC,WAAW,SAAS,MAAM,GAAG,MAAM,EACnC,UAAU,SAAS,MAAM,GAAG,MAAM;IAElC;;;;;;OAMG;IACH,oBAAoB,CAAC,KAAK,SAAS,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzG;;;;;;OAMG;IACH,cAAc,CAAC,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,OAAO,CAAC;QAAC,qBAAqB,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEvG,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B;;;OAGG;IACH,aAAa,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAClD,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAuB,CACtC,cAAc,SAAS,MAAM,GAAG,MAAM,EACtC,WAAW,SAAS,MAAM,GAAG,MAAM,EACnC,UAAU,SAAS,MAAM,GAAG,MAAM,CAClC,SAAQ,yBAAyB,CAAC,cAAc,EAAE,WAAW,EAAE,UAAU,CAAC;IAC1E,uFAAuF;IACvF,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvC,0DAA0D;IAC1D,oBAAoB,CAAC,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAC;CACxD;AAED,MAAM,MAAM,oBAAoB,CAC9B,cAAc,SAAS,MAAM,EAC7B,WAAW,SAAS,MAAM,EAC1B,UAAU,SAAS,MAAM,IACvB,KAAK,CAAC,EAAE,CAAC,yBAAyB,CAAC,cAAc,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;AAEjF;;;;;GAKG;AACH,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAiBhD,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type OpenedWindow, type OpenedWorkspace, type WorkspaceStoreState2 } from '@openmrs/esm-extensions';
|
|
2
|
+
import { type WorkspaceDefinition2 } from '@openmrs/esm-globals';
|
|
2
3
|
import { type Workspace2DefinitionProps } from './workspace2.component';
|
|
3
4
|
/**
|
|
4
5
|
* Attempts to launch the specified workspace group with the given group props. Note that only one workspace group
|
|
@@ -127,7 +128,7 @@ export declare const workspace2StoreActions: {
|
|
|
127
128
|
registeredWindowsByName: Record<string, import("@openmrs/esm-globals").WorkspaceWindowDefinition2 & {
|
|
128
129
|
moduleName: string;
|
|
129
130
|
}>;
|
|
130
|
-
registeredWorkspacesByName: Record<string,
|
|
131
|
+
registeredWorkspacesByName: Record<string, WorkspaceDefinition2 & {
|
|
131
132
|
moduleName: string;
|
|
132
133
|
}>;
|
|
133
134
|
openedGroup: import("@openmrs/esm-extensions").OpenedGroup | null;
|
|
@@ -141,7 +142,7 @@ export declare const workspace2StoreActions: {
|
|
|
141
142
|
registeredWindowsByName: Record<string, import("@openmrs/esm-globals").WorkspaceWindowDefinition2 & {
|
|
142
143
|
moduleName: string;
|
|
143
144
|
}>;
|
|
144
|
-
registeredWorkspacesByName: Record<string,
|
|
145
|
+
registeredWorkspacesByName: Record<string, WorkspaceDefinition2 & {
|
|
145
146
|
moduleName: string;
|
|
146
147
|
}>;
|
|
147
148
|
openedGroup: import("@openmrs/esm-extensions").OpenedGroup | null;
|
|
@@ -156,7 +157,7 @@ export declare const workspace2StoreActions: {
|
|
|
156
157
|
registeredWindowsByName: Record<string, import("@openmrs/esm-globals").WorkspaceWindowDefinition2 & {
|
|
157
158
|
moduleName: string;
|
|
158
159
|
}>;
|
|
159
|
-
registeredWorkspacesByName: Record<string,
|
|
160
|
+
registeredWorkspacesByName: Record<string, WorkspaceDefinition2 & {
|
|
160
161
|
moduleName: string;
|
|
161
162
|
}>;
|
|
162
163
|
openedGroup: import("@openmrs/esm-extensions").OpenedGroup | null;
|
|
@@ -170,7 +171,7 @@ export declare const workspace2StoreActions: {
|
|
|
170
171
|
registeredWindowsByName: Record<string, import("@openmrs/esm-globals").WorkspaceWindowDefinition2 & {
|
|
171
172
|
moduleName: string;
|
|
172
173
|
}>;
|
|
173
|
-
registeredWorkspacesByName: Record<string,
|
|
174
|
+
registeredWorkspacesByName: Record<string, WorkspaceDefinition2 & {
|
|
174
175
|
moduleName: string;
|
|
175
176
|
}>;
|
|
176
177
|
openedGroup: import("@openmrs/esm-extensions").OpenedGroup | null;
|
|
@@ -197,6 +198,12 @@ export declare const useWorkspace2Context: () => Workspace2DefinitionProps<objec
|
|
|
197
198
|
* @returns a list of registered workspaces.
|
|
198
199
|
*/
|
|
199
200
|
export declare const getRegisteredWorkspace2Names: () => string[];
|
|
201
|
+
/**
|
|
202
|
+
* Returns the width an opened window renders at: its leaf workspace's `width`, falling back to the
|
|
203
|
+
* window's `width`, then `'narrow'`. Every workspace in the window uses this width so that a wider
|
|
204
|
+
* workspace lower in the stack doesn't show behind a narrower one.
|
|
205
|
+
*/
|
|
206
|
+
export declare function getOpenedWindowWidth(openedWindow: OpenedWindow, registeredWorkspacesByName: WorkspaceStoreState2['registeredWorkspacesByName'], registeredWindowsByName: WorkspaceStoreState2['registeredWindowsByName']): NonNullable<WorkspaceDefinition2['width']>;
|
|
200
207
|
/**
|
|
201
208
|
* Builds the window an `<ExportedWorkspace>` starts with: the workspace's real registered window
|
|
202
209
|
* (so `launchChildWorkspace` keeps working), containing just the requested workspace.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace2.d.ts","sourceRoot":"","sources":["../../src/workspaces2/workspace2.ts"],"names":[],"mappings":"AAGA,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,eAAe,EAEpB,KAAK,oBAAoB,EAC1B,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"workspace2.d.ts","sourceRoot":"","sources":["../../src/workspaces2/workspace2.ts"],"names":[],"mappings":"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"}
|
|
@@ -606,6 +606,15 @@ export function useWorkspace2Store() {
|
|
|
606
606
|
*/ export const getRegisteredWorkspace2Names = ()=>{
|
|
607
607
|
return Object.keys(workspace2Store.getState().registeredWorkspacesByName);
|
|
608
608
|
};
|
|
609
|
+
/**
|
|
610
|
+
* Returns the width an opened window renders at: its leaf workspace's `width`, falling back to the
|
|
611
|
+
* window's `width`, then `'narrow'`. Every workspace in the window uses this width so that a wider
|
|
612
|
+
* workspace lower in the stack doesn't show behind a narrower one.
|
|
613
|
+
*/ export function getOpenedWindowWidth(openedWindow, registeredWorkspacesByName, registeredWindowsByName) {
|
|
614
|
+
const leaf = openedWindow.openedWorkspaces[openedWindow.openedWorkspaces.length - 1];
|
|
615
|
+
const leafWidth = leaf ? registeredWorkspacesByName[leaf.workspaceName]?.width : undefined;
|
|
616
|
+
return leafWidth ?? registeredWindowsByName[openedWindow.windowName]?.width ?? 'narrow';
|
|
617
|
+
}
|
|
609
618
|
function newOpenedWorkspace(workspaceName, workspaceProps) {
|
|
610
619
|
return {
|
|
611
620
|
workspaceName,
|
|
@@ -61,12 +61,9 @@ $extraWideWorkspaceWidth: 48.25rem;
|
|
|
61
61
|
width: var(--workspaceWidth);
|
|
62
62
|
border-inline-start: 1px solid $text-03;
|
|
63
63
|
background-color: #fff;
|
|
64
|
-
will-change: width;
|
|
65
|
-
transition: width 0.5s ease-in-out;
|
|
66
64
|
|
|
67
65
|
&.maximized {
|
|
68
66
|
width: 100%;
|
|
69
|
-
transition: none !important;
|
|
70
67
|
}
|
|
71
68
|
}
|
|
72
69
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openmrs/esm-styleguide",
|
|
3
|
-
"version": "10.0.1-pre.
|
|
3
|
+
"version": "10.0.1-pre.5723",
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
5
|
"description": "The styleguide for OpenMRS SPA",
|
|
6
6
|
"module": "dist/internal.js",
|
|
@@ -79,18 +79,18 @@
|
|
|
79
79
|
"uuid": "^11.1.1"
|
|
80
80
|
},
|
|
81
81
|
"peerDependencies": {
|
|
82
|
-
"@openmrs/esm-api": "^10.0.1-pre.
|
|
83
|
-
"@openmrs/esm-config": "^10.0.1-pre.
|
|
84
|
-
"@openmrs/esm-emr-api": "^10.0.1-pre.
|
|
85
|
-
"@openmrs/esm-error-handling": "^10.0.1-pre.
|
|
86
|
-
"@openmrs/esm-extensions": "^10.0.1-pre.
|
|
87
|
-
"@openmrs/esm-globals": "^10.0.1-pre.
|
|
88
|
-
"@openmrs/esm-navigation": "^10.0.1-pre.
|
|
89
|
-
"@openmrs/esm-react-utils": "^10.0.1-pre.
|
|
90
|
-
"@openmrs/esm-routes": "^10.0.1-pre.
|
|
91
|
-
"@openmrs/esm-state": "^10.0.1-pre.
|
|
92
|
-
"@openmrs/esm-translations": "^10.0.1-pre.
|
|
93
|
-
"@openmrs/esm-utils": "^10.0.1-pre.
|
|
82
|
+
"@openmrs/esm-api": "^10.0.1-pre.5723",
|
|
83
|
+
"@openmrs/esm-config": "^10.0.1-pre.5723",
|
|
84
|
+
"@openmrs/esm-emr-api": "^10.0.1-pre.5723",
|
|
85
|
+
"@openmrs/esm-error-handling": "^10.0.1-pre.5723",
|
|
86
|
+
"@openmrs/esm-extensions": "^10.0.1-pre.5723",
|
|
87
|
+
"@openmrs/esm-globals": "^10.0.1-pre.5723",
|
|
88
|
+
"@openmrs/esm-navigation": "^10.0.1-pre.5723",
|
|
89
|
+
"@openmrs/esm-react-utils": "^10.0.1-pre.5723",
|
|
90
|
+
"@openmrs/esm-routes": "^10.0.1-pre.5723",
|
|
91
|
+
"@openmrs/esm-state": "^10.0.1-pre.5723",
|
|
92
|
+
"@openmrs/esm-translations": "^10.0.1-pre.5723",
|
|
93
|
+
"@openmrs/esm-utils": "^10.0.1-pre.5723",
|
|
94
94
|
"dayjs": "1.x",
|
|
95
95
|
"i18next": "25.x",
|
|
96
96
|
"react": "18.x",
|
|
@@ -99,18 +99,18 @@
|
|
|
99
99
|
"swr": "2.x"
|
|
100
100
|
},
|
|
101
101
|
"devDependencies": {
|
|
102
|
-
"@openmrs/esm-api": "10.0.1-pre.
|
|
103
|
-
"@openmrs/esm-config": "10.0.1-pre.
|
|
104
|
-
"@openmrs/esm-emr-api": "10.0.1-pre.
|
|
105
|
-
"@openmrs/esm-error-handling": "10.0.1-pre.
|
|
106
|
-
"@openmrs/esm-extensions": "10.0.1-pre.
|
|
107
|
-
"@openmrs/esm-globals": "10.0.1-pre.
|
|
108
|
-
"@openmrs/esm-navigation": "10.0.1-pre.
|
|
109
|
-
"@openmrs/esm-react-utils": "10.0.1-pre.
|
|
110
|
-
"@openmrs/esm-routes": "10.0.1-pre.
|
|
111
|
-
"@openmrs/esm-state": "10.0.1-pre.
|
|
112
|
-
"@openmrs/esm-translations": "10.0.1-pre.
|
|
113
|
-
"@openmrs/esm-utils": "10.0.1-pre.
|
|
102
|
+
"@openmrs/esm-api": "10.0.1-pre.5723",
|
|
103
|
+
"@openmrs/esm-config": "10.0.1-pre.5723",
|
|
104
|
+
"@openmrs/esm-emr-api": "10.0.1-pre.5723",
|
|
105
|
+
"@openmrs/esm-error-handling": "10.0.1-pre.5723",
|
|
106
|
+
"@openmrs/esm-extensions": "10.0.1-pre.5723",
|
|
107
|
+
"@openmrs/esm-globals": "10.0.1-pre.5723",
|
|
108
|
+
"@openmrs/esm-navigation": "10.0.1-pre.5723",
|
|
109
|
+
"@openmrs/esm-react-utils": "10.0.1-pre.5723",
|
|
110
|
+
"@openmrs/esm-routes": "10.0.1-pre.5723",
|
|
111
|
+
"@openmrs/esm-state": "10.0.1-pre.5723",
|
|
112
|
+
"@openmrs/esm-translations": "10.0.1-pre.5723",
|
|
113
|
+
"@openmrs/esm-utils": "10.0.1-pre.5723",
|
|
114
114
|
"@swc/cli": "0.8.1",
|
|
115
115
|
"@swc/core": "1.15.21",
|
|
116
116
|
"@types/geopattern": "^1.2.9",
|
|
@@ -15,8 +15,8 @@ import { isDesktop, useLayoutType, useStore } from '@openmrs/esm-react-utils';
|
|
|
15
15
|
import { loadLifeCycles } from '@openmrs/esm-routes';
|
|
16
16
|
import { getCoreTranslation } from '@openmrs/esm-translations';
|
|
17
17
|
import { ArrowRightIcon, CloseIcon } from '../icons';
|
|
18
|
-
import { closeWorkspaceGroup2, useWorkspace2Store } from './workspace2';
|
|
19
|
-
import { type
|
|
18
|
+
import { closeWorkspaceGroup2, getOpenedWindowWidth, useWorkspace2Store } from './workspace2';
|
|
19
|
+
import { type Workspace2InternalProps } from './workspace2.component';
|
|
20
20
|
import { type WorkspaceWindowActions } from './workspace-window-actions';
|
|
21
21
|
import styles from './workspace2.module.scss';
|
|
22
22
|
|
|
@@ -127,7 +127,7 @@ const ActiveWorkspace: React.FC<ActiveWorkspaceProps> = ({
|
|
|
127
127
|
isLeafWorkspace,
|
|
128
128
|
showActionMenu,
|
|
129
129
|
}) => {
|
|
130
|
-
const props:
|
|
130
|
+
const props: Workspace2InternalProps = useMemo(
|
|
131
131
|
() =>
|
|
132
132
|
openedWorkspace && {
|
|
133
133
|
closeWorkspace: async (options = {}) => {
|
|
@@ -262,6 +262,7 @@ const WorkspaceChrome: React.FC<WorkspaceChromeProps> = ({
|
|
|
262
262
|
openedGroup,
|
|
263
263
|
openedWindows,
|
|
264
264
|
registeredWindowsByName,
|
|
265
|
+
registeredWorkspacesByName,
|
|
265
266
|
registeredGroupsByName,
|
|
266
267
|
isMostRecentlyOpenedWindowHidden,
|
|
267
268
|
setWindowMaximized,
|
|
@@ -273,7 +274,7 @@ const WorkspaceChrome: React.FC<WorkspaceChromeProps> = ({
|
|
|
273
274
|
const title = openedWorkspace.title ?? '';
|
|
274
275
|
|
|
275
276
|
const windowDef = registeredWindowsByName[windowName];
|
|
276
|
-
const width =
|
|
277
|
+
const width = getOpenedWindowWidth(openedWindow, registeredWorkspacesByName, registeredWindowsByName);
|
|
277
278
|
const icon = windowDef?.icon;
|
|
278
279
|
const canMaximize = windowDef?.canMaximize;
|
|
279
280
|
const canCloseGroup = openedGroup ? registeredGroupsByName[openedGroup.groupName]?.persistence === 'closable' : false;
|
|
@@ -4,7 +4,8 @@ import { act, render, screen } from '@testing-library/react';
|
|
|
4
4
|
import { workspace2Store, type OpenedWindow, type OpenedWorkspace } from '@openmrs/esm-extensions';
|
|
5
5
|
import { loadLifeCycles } from '@openmrs/esm-routes';
|
|
6
6
|
import ActiveWorkspaceWindow from './active-workspace-window.component';
|
|
7
|
-
import
|
|
7
|
+
import styles from './workspace2.module.scss';
|
|
8
|
+
import { type Workspace2InternalProps } from './workspace2.component';
|
|
8
9
|
import { type WorkspaceWindowActions } from './workspace-window-actions';
|
|
9
10
|
|
|
10
11
|
vi.mock('@openmrs/esm-routes', () => ({
|
|
@@ -13,13 +14,13 @@ vi.mock('@openmrs/esm-routes', () => ({
|
|
|
13
14
|
|
|
14
15
|
// Records the props each parcel was handed, keyed by workspace name, so tests can call them the way
|
|
15
16
|
// the workspace component would.
|
|
16
|
-
const { parcelProps } = vi.hoisted(() => ({ parcelProps: {} as Record<string,
|
|
17
|
+
const { parcelProps } = vi.hoisted(() => ({ parcelProps: {} as Record<string, Workspace2InternalProps> }));
|
|
17
18
|
vi.mock('single-spa-react/parcel', () => ({
|
|
18
19
|
default: ({
|
|
19
20
|
config,
|
|
20
21
|
wrapClassName,
|
|
21
22
|
...props
|
|
22
|
-
}: { config: { name: string }; wrapClassName?: string } &
|
|
23
|
+
}: { config: { name: string }; wrapClassName?: string } & Workspace2InternalProps) => {
|
|
23
24
|
parcelProps[props.workspaceName] = props;
|
|
24
25
|
// Surface the wrapper class the real Parcel would apply, so tests can assert stacking/visibility.
|
|
25
26
|
return (
|
|
@@ -106,6 +107,48 @@ describe('ActiveWorkspaceWindow', () => {
|
|
|
106
107
|
}
|
|
107
108
|
});
|
|
108
109
|
|
|
110
|
+
it('applies the leaf width to loading and mounted chrome, and restores it when the child closes', async () => {
|
|
111
|
+
const state = workspace2Store.getState();
|
|
112
|
+
workspace2Store.setState({
|
|
113
|
+
registeredWorkspacesByName: {
|
|
114
|
+
...state.registeredWorkspacesByName,
|
|
115
|
+
'form-workspace': { ...state.registeredWorkspacesByName['form-workspace'], width: 'extra-wide' },
|
|
116
|
+
'admit-workspace': { ...state.registeredWorkspacesByName['admit-workspace'], width: 'narrow' },
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
const parent = makeOpenedWorkspace('form-workspace', 'parent');
|
|
120
|
+
const child = makeOpenedWorkspace('admit-workspace', 'child');
|
|
121
|
+
const actions = makeActions();
|
|
122
|
+
let resolveChild: (config: { name: string }) => void;
|
|
123
|
+
mockLoadLifeCycles.mockImplementation((_, component) =>
|
|
124
|
+
component === 'form'
|
|
125
|
+
? Promise.resolve({ name: 'form' } as never)
|
|
126
|
+
: (new Promise((resolve) => {
|
|
127
|
+
resolveChild = resolve as never;
|
|
128
|
+
}) as never),
|
|
129
|
+
);
|
|
130
|
+
const { container, rerender } = render(renderWindow(makeOpenedWindow([parent]), actions, true));
|
|
131
|
+
await flushLifeCycles();
|
|
132
|
+
// Width classes live on the chrome containers, including the loading state with no title bar.
|
|
133
|
+
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
|
|
134
|
+
expect(container.querySelectorAll(`.${styles.extraWideWorkspace}`)).toHaveLength(1);
|
|
135
|
+
rerender(renderWindow(makeOpenedWindow([parent, child]), actions, true));
|
|
136
|
+
// Width classes live on the chrome containers, including the loading state with no title bar.
|
|
137
|
+
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
|
|
138
|
+
expect(container.querySelectorAll(`.${styles.narrowWorkspace}`)).toHaveLength(2);
|
|
139
|
+
await act(async () => {
|
|
140
|
+
resolveChild({ name: 'admit' });
|
|
141
|
+
});
|
|
142
|
+
expect(screen.getAllByTestId('parcel')).toHaveLength(2);
|
|
143
|
+
// Width classes live on the chrome containers, including the loading state with no title bar.
|
|
144
|
+
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
|
|
145
|
+
expect(container.querySelectorAll(`.${styles.narrowWorkspace}`)).toHaveLength(2);
|
|
146
|
+
rerender(renderWindow(makeOpenedWindow([parent]), actions, true));
|
|
147
|
+
// Width classes live on the chrome containers, including the loading state with no title bar.
|
|
148
|
+
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
|
|
149
|
+
expect(container.querySelectorAll(`.${styles.extraWideWorkspace}`)).toHaveLength(1);
|
|
150
|
+
});
|
|
151
|
+
|
|
109
152
|
it('does not render a replaced workspace with the previous workspace lifecycle at the same stack position', async () => {
|
|
110
153
|
// The form lifecycle resolves immediately. The admit lifecycle resolves only
|
|
111
154
|
// when we release it, keeping the reload from the stack change pending, which
|
|
@@ -5,7 +5,7 @@ import { workspace2Store } from '@openmrs/esm-extensions';
|
|
|
5
5
|
import { loadLifeCycles } from '@openmrs/esm-routes';
|
|
6
6
|
import { showModal } from '../modals';
|
|
7
7
|
import { ExportedWorkspace, type ExportedWorkspaceWindowInfo } from './exported-workspace.component';
|
|
8
|
-
import { type
|
|
8
|
+
import { type Workspace2InternalProps } from './workspace2.component';
|
|
9
9
|
|
|
10
10
|
vi.mock('@openmrs/esm-routes', () => ({
|
|
11
11
|
loadLifeCycles: vi.fn(),
|
|
@@ -18,9 +18,9 @@ vi.mock('../modals', () => ({
|
|
|
18
18
|
// The parcel is where the workspace component (and its <Workspace2>) would mount. We stub it out,
|
|
19
19
|
// surface the workspace name it was handed, and record its props (keyed by workspace name) so tests
|
|
20
20
|
// can call them the way the workspace component would.
|
|
21
|
-
const { parcelProps } = vi.hoisted(() => ({ parcelProps: {} as Record<string,
|
|
21
|
+
const { parcelProps } = vi.hoisted(() => ({ parcelProps: {} as Record<string, Workspace2InternalProps> }));
|
|
22
22
|
vi.mock('single-spa-react/parcel', () => ({
|
|
23
|
-
default: (props:
|
|
23
|
+
default: (props: Workspace2InternalProps) => {
|
|
24
24
|
parcelProps[props.workspaceName] = props;
|
|
25
25
|
return <div data-testid="parcel">{props.workspaceName}</div>;
|
|
26
26
|
},
|
|
@@ -42,17 +42,22 @@ export interface Workspace2DefinitionProps<
|
|
|
42
42
|
windowName: string;
|
|
43
43
|
isRootWorkspace: boolean;
|
|
44
44
|
showActionMenu: boolean;
|
|
45
|
+
}
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
/**
|
|
48
|
+
* The props the framework actually passes to a workspace: the public `Workspace2DefinitionProps` plus
|
|
49
|
+
* the setters `<Workspace2>` uses to report its `title` and `hasUnsavedChanges` to the workspace window.
|
|
50
|
+
* Not part of the public API.
|
|
51
|
+
*/
|
|
52
|
+
export interface Workspace2InternalProps<
|
|
53
|
+
WorkspaceProps extends object = object,
|
|
54
|
+
WindowProps extends object = object,
|
|
55
|
+
GroupProps extends object = object,
|
|
56
|
+
> extends Workspace2DefinitionProps<WorkspaceProps, WindowProps, GroupProps> {
|
|
57
|
+
/** Records the title of this workspace, for display in the workspace window header. */
|
|
50
58
|
setWorkspaceTitle(title: string): void;
|
|
51
59
|
|
|
52
|
-
/**
|
|
53
|
-
* Records whether this workspace has unsaved changes.
|
|
54
|
-
* @internal Called by `<Workspace2>`; use its `hasUnsavedChanges` prop instead.
|
|
55
|
-
*/
|
|
60
|
+
/** Records whether this workspace has unsaved changes. */
|
|
56
61
|
setHasUnsavedChanges(hasUnsavedChanges: boolean): void;
|
|
57
62
|
}
|
|
58
63
|
|
|
@@ -71,7 +76,7 @@ export type Workspace2Definition<
|
|
|
71
76
|
export const Workspace2: React.FC<Workspace2Props> = ({ title, children, hasUnsavedChanges = false }) => {
|
|
72
77
|
// These are bound to this workspace instance, in whichever store holds it (the global store, or an
|
|
73
78
|
// `<ExportedWorkspace>`'s local store). They skip writes that change nothing.
|
|
74
|
-
const { setHasUnsavedChanges, setWorkspaceTitle } = useWorkspace2Context();
|
|
79
|
+
const { setHasUnsavedChanges, setWorkspaceTitle } = useWorkspace2Context() as Workspace2InternalProps;
|
|
75
80
|
|
|
76
81
|
useEffect(() => {
|
|
77
82
|
setHasUnsavedChanges(hasUnsavedChanges ?? false);
|
|
@@ -61,12 +61,9 @@ $extraWideWorkspaceWidth: 48.25rem;
|
|
|
61
61
|
width: var(--workspaceWidth);
|
|
62
62
|
border-inline-start: 1px solid $text-03;
|
|
63
63
|
background-color: #fff;
|
|
64
|
-
will-change: width;
|
|
65
|
-
transition: width 0.5s ease-in-out;
|
|
66
64
|
|
|
67
65
|
&.maximized {
|
|
68
66
|
width: 100%;
|
|
69
|
-
transition: none !important;
|
|
70
67
|
}
|
|
71
68
|
}
|
|
72
69
|
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
closeWorkspaceInWindow,
|
|
10
10
|
openChildWorkspaceInWindow,
|
|
11
11
|
updateOpenedWorkspaceInWindow,
|
|
12
|
+
getOpenedWindowWidth,
|
|
12
13
|
workspace2StoreActions,
|
|
13
14
|
} from './workspace2';
|
|
14
15
|
|
|
@@ -268,3 +269,70 @@ describe('updateOpenedWorkspaceInWindow', () => {
|
|
|
268
269
|
expect(updateOpenedWorkspaceInWindow(window, 'uuid-parent-workspace', { hasUnsavedChanges: false })).toBe(window);
|
|
269
270
|
});
|
|
270
271
|
});
|
|
272
|
+
|
|
273
|
+
describe('getOpenedWindowWidth', () => {
|
|
274
|
+
const registeredWindowsByName = {
|
|
275
|
+
'test-window': { name: 'test-window', group: 'test-group', width: 'wider' as const, moduleName: 'test' },
|
|
276
|
+
'plain-window': { name: 'plain-window', group: 'test-group', moduleName: 'test' },
|
|
277
|
+
};
|
|
278
|
+
const registeredWorkspacesByName = {
|
|
279
|
+
'inherits-width': { name: 'inherits-width', component: 'a', window: 'test-window', moduleName: 'test' },
|
|
280
|
+
'extra-wide': {
|
|
281
|
+
name: 'extra-wide',
|
|
282
|
+
component: 'b',
|
|
283
|
+
window: 'test-window',
|
|
284
|
+
width: 'extra-wide' as const,
|
|
285
|
+
moduleName: 'test',
|
|
286
|
+
},
|
|
287
|
+
'narrow-on-plain': { name: 'narrow-on-plain', component: 'c', window: 'plain-window', moduleName: 'test' },
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
function makeWindow(windowName: string, workspaceNames: Array<string>) {
|
|
291
|
+
return {
|
|
292
|
+
windowName,
|
|
293
|
+
openedWorkspaces: workspaceNames.map((n) => makeOpenedWorkspace(n)),
|
|
294
|
+
props: null,
|
|
295
|
+
maximized: false,
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
it("uses the window's width when the leaf workspace declares none", () => {
|
|
300
|
+
expect(
|
|
301
|
+
getOpenedWindowWidth(
|
|
302
|
+
makeWindow('test-window', ['inherits-width']),
|
|
303
|
+
registeredWorkspacesByName,
|
|
304
|
+
registeredWindowsByName,
|
|
305
|
+
),
|
|
306
|
+
).toBe('wider');
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
it("uses the leaf workspace's width over the window's width", () => {
|
|
310
|
+
expect(
|
|
311
|
+
getOpenedWindowWidth(
|
|
312
|
+
makeWindow('test-window', ['inherits-width', 'extra-wide']),
|
|
313
|
+
registeredWorkspacesByName,
|
|
314
|
+
registeredWindowsByName,
|
|
315
|
+
),
|
|
316
|
+
).toBe('extra-wide');
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
it('ignores the width of non-leaf workspaces', () => {
|
|
320
|
+
expect(
|
|
321
|
+
getOpenedWindowWidth(
|
|
322
|
+
makeWindow('test-window', ['extra-wide', 'inherits-width']),
|
|
323
|
+
registeredWorkspacesByName,
|
|
324
|
+
registeredWindowsByName,
|
|
325
|
+
),
|
|
326
|
+
).toBe('wider');
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
it("defaults to 'narrow' when neither the workspace nor the window declares a width", () => {
|
|
330
|
+
expect(
|
|
331
|
+
getOpenedWindowWidth(
|
|
332
|
+
makeWindow('plain-window', ['narrow-on-plain']),
|
|
333
|
+
registeredWorkspacesByName,
|
|
334
|
+
registeredWindowsByName,
|
|
335
|
+
),
|
|
336
|
+
).toBe('narrow');
|
|
337
|
+
});
|
|
338
|
+
});
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
workspace2Store,
|
|
11
11
|
type WorkspaceStoreState2,
|
|
12
12
|
} from '@openmrs/esm-extensions';
|
|
13
|
+
import { type WorkspaceDefinition2 } from '@openmrs/esm-globals';
|
|
13
14
|
import { useStoreWithActions, type Actions } from '@openmrs/esm-react-utils';
|
|
14
15
|
import { shallowEqual } from '@openmrs/esm-utils';
|
|
15
16
|
import { showModal } from '../modals';
|
|
@@ -683,6 +684,21 @@ export const getRegisteredWorkspace2Names = () => {
|
|
|
683
684
|
return Object.keys(workspace2Store.getState().registeredWorkspacesByName);
|
|
684
685
|
};
|
|
685
686
|
|
|
687
|
+
/**
|
|
688
|
+
* Returns the width an opened window renders at: its leaf workspace's `width`, falling back to the
|
|
689
|
+
* window's `width`, then `'narrow'`. Every workspace in the window uses this width so that a wider
|
|
690
|
+
* workspace lower in the stack doesn't show behind a narrower one.
|
|
691
|
+
*/
|
|
692
|
+
export function getOpenedWindowWidth(
|
|
693
|
+
openedWindow: OpenedWindow,
|
|
694
|
+
registeredWorkspacesByName: WorkspaceStoreState2['registeredWorkspacesByName'],
|
|
695
|
+
registeredWindowsByName: WorkspaceStoreState2['registeredWindowsByName'],
|
|
696
|
+
): NonNullable<WorkspaceDefinition2['width']> {
|
|
697
|
+
const leaf = openedWindow.openedWorkspaces[openedWindow.openedWorkspaces.length - 1];
|
|
698
|
+
const leafWidth = leaf ? registeredWorkspacesByName[leaf.workspaceName]?.width : undefined;
|
|
699
|
+
return leafWidth ?? registeredWindowsByName[openedWindow.windowName]?.width ?? 'narrow';
|
|
700
|
+
}
|
|
701
|
+
|
|
686
702
|
function newOpenedWorkspace(workspaceName: string, workspaceProps: Record<string, any> | null): OpenedWorkspace {
|
|
687
703
|
return {
|
|
688
704
|
workspaceName,
|