@egen-civitas/esm-extensions 1.0.0
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/README.md +4 -0
- package/dist/extensions.d.ts +92 -0
- package/dist/extensions.d.ts.map +1 -0
- package/dist/extensions.js +394 -0
- package/dist/helpers.d.ts +3 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +7 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/left-nav.d.ts +38 -0
- package/dist/left-nav.d.ts.map +1 -0
- package/dist/left-nav.js +28 -0
- package/dist/modals.d.ts +12 -0
- package/dist/modals.d.ts.map +1 -0
- package/dist/modals.js +28 -0
- package/dist/public.d.ts +7 -0
- package/dist/public.d.ts.map +1 -0
- package/dist/public.js +4 -0
- package/dist/render.d.ts +12 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +62 -0
- package/dist/store.d.ts +97 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +54 -0
- package/dist/types.d.ts +11 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/workspaces.d.ts +61 -0
- package/dist/workspaces.d.ts.map +1 -0
- package/dist/workspaces.js +122 -0
- package/dist/workspaces2.d.ts +61 -0
- package/dist/workspaces2.d.ts.map +1 -0
- package/dist/workspaces2.js +116 -0
- package/mock-jest.ts +31 -0
- package/mock.ts +33 -0
- package/package.json +96 -0
package/dist/public.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { getExtensionNameFromId, registerExtension, attach, detach, detachAll, getAssignedExtensions, registerExtensionSlot } from "./extensions.js";
|
|
2
|
+
export { setLeftNav, unsetLeftNav } from "./left-nav.js";
|
|
3
|
+
export { renderExtension } from "./render.js";
|
|
4
|
+
export { getExtensionStore } from "./store.js";
|
package/dist/render.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** @module @category Extension */
|
|
2
|
+
import { type Parcel, type ParcelConfig } from 'single-spa';
|
|
3
|
+
export interface CancelLoading {
|
|
4
|
+
(): void;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Mounts into a DOM node (representing an extension slot)
|
|
8
|
+
* a lazy-loaded component from *any* frontend module
|
|
9
|
+
* that registered an extension component for this slot.
|
|
10
|
+
*/
|
|
11
|
+
export declare function renderExtension(domElement: HTMLElement, extensionSlotName: string, extensionSlotModuleName: string, extensionId: string, renderFunction?: (application: ParcelConfig) => ParcelConfig, additionalProps?: Record<string, any>): Promise<Parcel | null>;
|
|
12
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,OAAO,EAAmB,KAAK,MAAM,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAK7E,MAAM,WAAW,aAAa;IAC5B,IAAI,IAAI,CAAC;CACV;AAID;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,WAAW,EACvB,iBAAiB,EAAE,MAAM,EACzB,uBAAuB,EAAE,MAAM,EAC/B,WAAW,EAAE,MAAM,EACnB,cAAc,GAAE,CAAC,WAAW,EAAE,YAAY,KAAK,YAAuB,EACtE,eAAe,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GACxC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyDxB"}
|
package/dist/render.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/** @module @category Extension */ import { mountRootParcel } from "single-spa";
|
|
2
|
+
import { getExtensionNameFromId, getExtensionRegistration } from "./extensions.js";
|
|
3
|
+
import { checkStatus } from "./helpers.js";
|
|
4
|
+
import { updateInternalExtensionStore } from "./store.js";
|
|
5
|
+
let parcelCount = 0;
|
|
6
|
+
/**
|
|
7
|
+
* Mounts into a DOM node (representing an extension slot)
|
|
8
|
+
* a lazy-loaded component from *any* frontend module
|
|
9
|
+
* that registered an extension component for this slot.
|
|
10
|
+
*/ export async function renderExtension(domElement, extensionSlotName, extensionSlotModuleName, extensionId, renderFunction = (x)=>x, additionalProps = {}) {
|
|
11
|
+
const extensionName = getExtensionNameFromId(extensionId);
|
|
12
|
+
const extensionRegistration = getExtensionRegistration(extensionId);
|
|
13
|
+
let parcel = null;
|
|
14
|
+
if (domElement) {
|
|
15
|
+
if (!extensionRegistration) {
|
|
16
|
+
throw Error(`Couldn't find extension '${extensionName}' to attach to '${extensionSlotName}'`);
|
|
17
|
+
}
|
|
18
|
+
const { meta, moduleName, online, offline, load } = extensionRegistration;
|
|
19
|
+
if (checkStatus(online, offline)) {
|
|
20
|
+
updateInternalExtensionStore((state)=>{
|
|
21
|
+
const instance = {
|
|
22
|
+
domElement,
|
|
23
|
+
id: extensionId,
|
|
24
|
+
slotName: extensionSlotName,
|
|
25
|
+
slotModuleName: extensionSlotModuleName
|
|
26
|
+
};
|
|
27
|
+
return {
|
|
28
|
+
...state,
|
|
29
|
+
extensions: {
|
|
30
|
+
...state.extensions,
|
|
31
|
+
[extensionName]: {
|
|
32
|
+
...state.extensions[extensionName],
|
|
33
|
+
instances: [
|
|
34
|
+
...state.extensions[extensionName].instances,
|
|
35
|
+
instance
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
const lifecycle = await load();
|
|
42
|
+
const id = parcelCount++;
|
|
43
|
+
parcel = mountRootParcel(renderFunction({
|
|
44
|
+
...lifecycle,
|
|
45
|
+
name: `${extensionSlotName}/${extensionName}-${id}`
|
|
46
|
+
}), {
|
|
47
|
+
...additionalProps,
|
|
48
|
+
_meta: meta,
|
|
49
|
+
_extensionContext: {
|
|
50
|
+
extensionId,
|
|
51
|
+
extensionSlotName,
|
|
52
|
+
extensionSlotModuleName,
|
|
53
|
+
extensionModuleName: moduleName
|
|
54
|
+
},
|
|
55
|
+
domElement
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
} else {
|
|
59
|
+
console.warn(`Tried to render ${extensionId} into ${extensionSlotName} but no DOM element was available.`);
|
|
60
|
+
}
|
|
61
|
+
return parcel;
|
|
62
|
+
}
|
package/dist/store.d.ts
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { ConfigObject, ExtensionSlotConfig } from '@egen-civitas/esm-config';
|
|
2
|
+
import { type LifeCycles } from 'single-spa';
|
|
3
|
+
export interface ExtensionMeta {
|
|
4
|
+
[_: string]: any;
|
|
5
|
+
}
|
|
6
|
+
export interface ExtensionRegistration {
|
|
7
|
+
readonly name: string;
|
|
8
|
+
load(): Promise<LifeCycles>;
|
|
9
|
+
readonly moduleName: string;
|
|
10
|
+
readonly meta: Readonly<ExtensionMeta>;
|
|
11
|
+
readonly order?: number;
|
|
12
|
+
readonly online?: boolean;
|
|
13
|
+
readonly offline?: boolean;
|
|
14
|
+
readonly privileges?: string | Array<string>;
|
|
15
|
+
readonly featureFlag?: string;
|
|
16
|
+
readonly displayExpression?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface ExtensionInfo extends ExtensionRegistration {
|
|
19
|
+
/**
|
|
20
|
+
* The instances where the extension has been rendered using `renderExtension`.
|
|
21
|
+
*/
|
|
22
|
+
instances: Array<ExtensionInstance>;
|
|
23
|
+
}
|
|
24
|
+
export interface ExtensionInstance {
|
|
25
|
+
id: string;
|
|
26
|
+
slotName: string;
|
|
27
|
+
slotModuleName: string;
|
|
28
|
+
}
|
|
29
|
+
export interface ExtensionInternalStore {
|
|
30
|
+
/** Slots indexed by name */
|
|
31
|
+
slots: Record<string, ExtensionSlotInfo>;
|
|
32
|
+
/** Extensions indexed by name */
|
|
33
|
+
extensions: Record<string, ExtensionInfo>;
|
|
34
|
+
}
|
|
35
|
+
export type ExtensionSlotCustomState = Record<string | symbol | number, unknown> | undefined | null;
|
|
36
|
+
export interface ExtensionSlotInfo {
|
|
37
|
+
/**
|
|
38
|
+
* The module in which the extension slot exists. Undefined if the slot
|
|
39
|
+
* hasn't been registered yet (but it has been attached or assigned to
|
|
40
|
+
* an extension.
|
|
41
|
+
*/
|
|
42
|
+
moduleName?: string;
|
|
43
|
+
/** The name under which the extension slot has been registered. */
|
|
44
|
+
name: string;
|
|
45
|
+
/**
|
|
46
|
+
* The set of extension IDs which have been attached to this slot using `attach`.
|
|
47
|
+
* However, not all of these extension IDs should be rendered.
|
|
48
|
+
* `assignedIds` is the set defining those.
|
|
49
|
+
*/
|
|
50
|
+
attachedIds: Array<string>;
|
|
51
|
+
/** The configuration provided for this slot. `null` if not yet loaded. */
|
|
52
|
+
config: Omit<ExtensionSlotConfig, 'configuration'> | null;
|
|
53
|
+
state?: ExtensionSlotCustomState;
|
|
54
|
+
}
|
|
55
|
+
export interface ExtensionStore {
|
|
56
|
+
slots: Record<string, ExtensionSlotState>;
|
|
57
|
+
}
|
|
58
|
+
export interface ExtensionSlotState {
|
|
59
|
+
moduleName?: string;
|
|
60
|
+
assignedExtensions: Array<AssignedExtension>;
|
|
61
|
+
state?: ExtensionSlotCustomState;
|
|
62
|
+
}
|
|
63
|
+
export interface AssignedExtension {
|
|
64
|
+
readonly id: string;
|
|
65
|
+
readonly name: string;
|
|
66
|
+
readonly moduleName: string;
|
|
67
|
+
readonly meta: Readonly<ExtensionMeta>;
|
|
68
|
+
/** The extension's config. Note that this will be `null` until the slot is mounted. */
|
|
69
|
+
readonly config: Readonly<ConfigObject> | null;
|
|
70
|
+
readonly online?: boolean | object;
|
|
71
|
+
readonly offline?: boolean | object;
|
|
72
|
+
readonly featureFlag?: string;
|
|
73
|
+
}
|
|
74
|
+
/** @deprecated replaced with AssignedExtension */
|
|
75
|
+
export interface ConnectedExtension {
|
|
76
|
+
readonly id: string;
|
|
77
|
+
readonly name: string;
|
|
78
|
+
readonly moduleName: string;
|
|
79
|
+
readonly meta: Readonly<ExtensionMeta>;
|
|
80
|
+
/** The extension's config. Note that this will be `null` until the slot is mounted. */
|
|
81
|
+
readonly config: Readonly<ConfigObject> | null;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* This gets the extension system's internal store. It is subject
|
|
85
|
+
* to change radically and without warning. It should not be used
|
|
86
|
+
* outside esm-core.
|
|
87
|
+
* @internal
|
|
88
|
+
*/
|
|
89
|
+
export declare const getExtensionInternalStore: () => import("zustand").StoreApi<ExtensionInternalStore>;
|
|
90
|
+
/** @internal */
|
|
91
|
+
export declare function updateInternalExtensionStore(updater: (state: ExtensionInternalStore) => ExtensionInternalStore): void;
|
|
92
|
+
/**
|
|
93
|
+
* This returns a store that modules can use to get information about the
|
|
94
|
+
* state of the extension system.
|
|
95
|
+
*/
|
|
96
|
+
export declare const getExtensionStore: () => import("zustand").StoreApi<ExtensionStore>;
|
|
97
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
|
package/dist/store.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** @module @category Extension */ import { isEqual } from "lodash-es";
|
|
2
|
+
import { configExtensionStore } from "@egen-civitas/esm-config";
|
|
3
|
+
import { createGlobalStore, getGlobalStore } from "@egen-civitas/esm-state";
|
|
4
|
+
const extensionInternalStore = createGlobalStore('extensionsInternal', {
|
|
5
|
+
slots: {},
|
|
6
|
+
extensions: {}
|
|
7
|
+
});
|
|
8
|
+
/**
|
|
9
|
+
* This gets the extension system's internal store. It is subject
|
|
10
|
+
* to change radically and without warning. It should not be used
|
|
11
|
+
* outside esm-core.
|
|
12
|
+
* @internal
|
|
13
|
+
*/ export const getExtensionInternalStore = ()=>getGlobalStore('extensionsInternal', {
|
|
14
|
+
slots: {},
|
|
15
|
+
extensions: {}
|
|
16
|
+
});
|
|
17
|
+
/** @internal */ export function updateInternalExtensionStore(updater) {
|
|
18
|
+
// This is a function that updates the internal extension store.
|
|
19
|
+
const state = extensionInternalStore.getState();
|
|
20
|
+
const newState = updater(state);
|
|
21
|
+
if (newState !== state) {
|
|
22
|
+
extensionInternalStore.setState(newState);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* This returns a store that modules can use to get information about the
|
|
27
|
+
* state of the extension system.
|
|
28
|
+
*/ export const getExtensionStore = ()=>getGlobalStore('extensions', {
|
|
29
|
+
slots: {}
|
|
30
|
+
});
|
|
31
|
+
/**
|
|
32
|
+
* esm-config maintains its own store of the extension information it needs
|
|
33
|
+
* to generate extension configs. We keep it updated based on what's in
|
|
34
|
+
* `extensionStore`.
|
|
35
|
+
*/ updateConfigExtensionStore(extensionInternalStore.getState());
|
|
36
|
+
extensionInternalStore.subscribe(updateConfigExtensionStore);
|
|
37
|
+
function updateConfigExtensionStore(extensionState) {
|
|
38
|
+
const configExtensionRecords = [];
|
|
39
|
+
for (let extensionInfo of Object.values(extensionState.extensions)){
|
|
40
|
+
for (let instance of extensionInfo.instances){
|
|
41
|
+
configExtensionRecords.push({
|
|
42
|
+
slotModuleName: instance.slotModuleName,
|
|
43
|
+
extensionModuleName: extensionInfo.moduleName,
|
|
44
|
+
slotName: instance.slotName,
|
|
45
|
+
extensionId: instance.id
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (!isEqual(configExtensionStore.getState().mountedExtensions, configExtensionRecords)) {
|
|
50
|
+
configExtensionStore.setState({
|
|
51
|
+
mountedExtensions: configExtensionRecords
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface ExtensionData {
|
|
2
|
+
extensionSlotName: string;
|
|
3
|
+
extensionSlotModuleName: string;
|
|
4
|
+
extensionId: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ComponentConfig {
|
|
7
|
+
moduleName: string;
|
|
8
|
+
featureName: string;
|
|
9
|
+
extension?: ExtensionData;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,uBAAuB,EAAE,MAAM,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type LifeCycles } from 'single-spa';
|
|
3
|
+
import { type WorkspaceGroupDefinition, type WorkspaceWindowState } from '@egen-civitas/esm-globals';
|
|
4
|
+
/** See [[WorkspaceDefinition]] for more information about these properties */
|
|
5
|
+
export interface WorkspaceRegistration {
|
|
6
|
+
name: string;
|
|
7
|
+
title: string;
|
|
8
|
+
titleNode?: ReactNode;
|
|
9
|
+
type: string;
|
|
10
|
+
canHide: boolean;
|
|
11
|
+
canMaximize: boolean;
|
|
12
|
+
width: 'narrow' | 'wider' | 'extra-wide';
|
|
13
|
+
preferredWindowSize: WorkspaceWindowState;
|
|
14
|
+
load(): Promise<LifeCycles>;
|
|
15
|
+
moduleName: string;
|
|
16
|
+
groups: Array<string>;
|
|
17
|
+
}
|
|
18
|
+
export type WorkspaceGroupRegistration = WorkspaceGroupDefinition & {
|
|
19
|
+
members: Array<string>;
|
|
20
|
+
};
|
|
21
|
+
/** See [[WorkspaceDefinition]] for more information about these properties */
|
|
22
|
+
export interface RegisterWorkspaceOptions {
|
|
23
|
+
name: string;
|
|
24
|
+
title: string;
|
|
25
|
+
type?: string;
|
|
26
|
+
canHide?: boolean;
|
|
27
|
+
canMaximize?: boolean;
|
|
28
|
+
width?: 'narrow' | 'wider' | 'extra-wide';
|
|
29
|
+
preferredWindowSize?: WorkspaceWindowState;
|
|
30
|
+
component: string;
|
|
31
|
+
moduleName: string;
|
|
32
|
+
groups?: Array<string>;
|
|
33
|
+
load(): Promise<LifeCycles>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Tells the workspace system about a workspace. This is used by the app shell
|
|
37
|
+
* to register workspaces defined in the `routes.json` file.
|
|
38
|
+
* @internal
|
|
39
|
+
*/
|
|
40
|
+
export declare function registerWorkspace(workspace: RegisterWorkspaceOptions): void;
|
|
41
|
+
/**
|
|
42
|
+
* Tells the workspace system about a workspace group. This is used by the app shell
|
|
43
|
+
* to register workspace groups defined in the `routes.json` file.
|
|
44
|
+
* @internal
|
|
45
|
+
*/
|
|
46
|
+
export declare function registerWorkspaceGroup(workspaceGroup: WorkspaceGroupRegistration): void;
|
|
47
|
+
/**
|
|
48
|
+
* This exists for compatibility with the old way of registering
|
|
49
|
+
* workspaces (as extensions).
|
|
50
|
+
*
|
|
51
|
+
* @param name of the workspace
|
|
52
|
+
*/
|
|
53
|
+
export declare function getWorkspaceRegistration(name: string): WorkspaceRegistration;
|
|
54
|
+
/**
|
|
55
|
+
* This provides the workspace group registration and is also compatible with the
|
|
56
|
+
* old way of registering workspace groups (as extensions), but isn't recommended.
|
|
57
|
+
*
|
|
58
|
+
* @param name of the workspace
|
|
59
|
+
*/
|
|
60
|
+
export declare function getWorkspaceGroupRegistration(name: string): WorkspaceGroupRegistration;
|
|
61
|
+
//# sourceMappingURL=workspaces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspaces.d.ts","sourceRoot":"","sources":["../src/workspaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,KAAK,wBAAwB,EAAE,KAAK,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAKrG,8EAA8E;AAC9E,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,KAAK,EAAE,QAAQ,GAAG,OAAO,GAAG,YAAY,CAAC;IACzC,mBAAmB,EAAE,oBAAoB,CAAC;IAC1C,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CACvB;AAED,MAAM,MAAM,0BAA0B,GAAG,wBAAwB,GAAG;IAClE,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CACxB,CAAC;AAkBF,8EAA8E;AAC9E,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,YAAY,CAAC;IAC1C,mBAAmB,CAAC,EAAE,oBAAoB,CAAC;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;CAC7B;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,wBAAwB,QAgBpE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,cAAc,EAAE,0BAA0B,QA4BhF;AAGD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,CA6B5E;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,GAAG,0BAA0B,CAOtF"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { getExtensionRegistration } from "./index.js";
|
|
2
|
+
import { createGlobalStore } from "@egen-civitas/esm-state";
|
|
3
|
+
import { translateFrom } from "@egen-civitas/esm-translations";
|
|
4
|
+
const workspaceRegistrationStore = createGlobalStore('workspaceRegistrations', {
|
|
5
|
+
workspaces: {}
|
|
6
|
+
});
|
|
7
|
+
const workspaceGroupStore = createGlobalStore('workspaceGroups', {
|
|
8
|
+
workspaceGroups: {}
|
|
9
|
+
});
|
|
10
|
+
/**
|
|
11
|
+
* Tells the workspace system about a workspace. This is used by the app shell
|
|
12
|
+
* to register workspaces defined in the `routes.json` file.
|
|
13
|
+
* @internal
|
|
14
|
+
*/ export function registerWorkspace(workspace) {
|
|
15
|
+
workspaceRegistrationStore.setState((state)=>({
|
|
16
|
+
workspaces: {
|
|
17
|
+
...state.workspaces,
|
|
18
|
+
[workspace.name]: {
|
|
19
|
+
...workspace,
|
|
20
|
+
load: workspace.load,
|
|
21
|
+
preferredWindowSize: workspace.preferredWindowSize ?? 'normal',
|
|
22
|
+
type: workspace.type ?? 'form',
|
|
23
|
+
canHide: workspace.canHide ?? false,
|
|
24
|
+
canMaximize: workspace.canMaximize ?? false,
|
|
25
|
+
width: workspace.width ?? 'narrow',
|
|
26
|
+
groups: workspace.groups ?? []
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}));
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Tells the workspace system about a workspace group. This is used by the app shell
|
|
33
|
+
* to register workspace groups defined in the `routes.json` file.
|
|
34
|
+
* @internal
|
|
35
|
+
*/ export function registerWorkspaceGroup(workspaceGroup) {
|
|
36
|
+
workspaceGroupStore.setState((state)=>{
|
|
37
|
+
const group = state.workspaceGroups[workspaceGroup.name];
|
|
38
|
+
if (group) {
|
|
39
|
+
// This condition occurs when a workspace with a `groups` property is registered before
|
|
40
|
+
// the corresponding workspace group. In such cases, the workspace group is registered
|
|
41
|
+
// by the `attachWorkspaceToGroup` function.
|
|
42
|
+
return {
|
|
43
|
+
workspaceGroups: {
|
|
44
|
+
...state.workspaceGroups,
|
|
45
|
+
[workspaceGroup.name]: {
|
|
46
|
+
...group,
|
|
47
|
+
members: Array.from(new Set([
|
|
48
|
+
...group.members,
|
|
49
|
+
...workspaceGroup.members
|
|
50
|
+
]))
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
} else {
|
|
55
|
+
return {
|
|
56
|
+
workspaceGroups: {
|
|
57
|
+
...state.workspaceGroups,
|
|
58
|
+
[workspaceGroup.name]: {
|
|
59
|
+
name: workspaceGroup.name,
|
|
60
|
+
members: workspaceGroup.members
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
const workspaceExtensionWarningsIssued = new Set();
|
|
68
|
+
/**
|
|
69
|
+
* This exists for compatibility with the old way of registering
|
|
70
|
+
* workspaces (as extensions).
|
|
71
|
+
*
|
|
72
|
+
* @param name of the workspace
|
|
73
|
+
*/ export function getWorkspaceRegistration(name) {
|
|
74
|
+
const registeredWorkspaces = workspaceRegistrationStore.getState().workspaces;
|
|
75
|
+
if (registeredWorkspaces[name]) {
|
|
76
|
+
return registeredWorkspaces[name];
|
|
77
|
+
} else {
|
|
78
|
+
const workspaceExtension = getExtensionRegistration(name);
|
|
79
|
+
if (workspaceExtension) {
|
|
80
|
+
if (!workspaceExtensionWarningsIssued.has(name)) {
|
|
81
|
+
console.warn(`The workspace '${name}' is registered as an extension. This is deprecated. Please register it in the "workspaces" section of the routes.json file.`);
|
|
82
|
+
workspaceExtensionWarningsIssued.add(name);
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
name: workspaceExtension.name,
|
|
86
|
+
title: getTitleFromExtension(workspaceExtension),
|
|
87
|
+
moduleName: workspaceExtension.moduleName,
|
|
88
|
+
preferredWindowSize: workspaceExtension.meta?.screenSize ?? 'normal',
|
|
89
|
+
load: workspaceExtension.load,
|
|
90
|
+
type: workspaceExtension.meta?.type ?? 'form',
|
|
91
|
+
canHide: workspaceExtension.meta?.canHide ?? false,
|
|
92
|
+
canMaximize: workspaceExtension.meta?.canMaximize ?? false,
|
|
93
|
+
width: workspaceExtension.meta?.width ?? 'narrow',
|
|
94
|
+
groups: workspaceExtension.meta?.groups ?? []
|
|
95
|
+
};
|
|
96
|
+
} else {
|
|
97
|
+
throw new Error(`No workspace named '${name}' has been registered.`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* This provides the workspace group registration and is also compatible with the
|
|
103
|
+
* old way of registering workspace groups (as extensions), but isn't recommended.
|
|
104
|
+
*
|
|
105
|
+
* @param name of the workspace
|
|
106
|
+
*/ export function getWorkspaceGroupRegistration(name) {
|
|
107
|
+
const registeredWorkspaces = workspaceGroupStore.getState().workspaceGroups;
|
|
108
|
+
if (registeredWorkspaces[name]) {
|
|
109
|
+
return registeredWorkspaces[name];
|
|
110
|
+
} else {
|
|
111
|
+
throw new Error(`No workspace group named '${name}' has been registered.`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function getTitleFromExtension(ext) {
|
|
115
|
+
const title = ext?.meta?.title;
|
|
116
|
+
if (typeof title === 'string') {
|
|
117
|
+
return title;
|
|
118
|
+
} else if (title && typeof title === 'object') {
|
|
119
|
+
return translateFrom(ext.moduleName, title.key, title.default);
|
|
120
|
+
}
|
|
121
|
+
return ext.name;
|
|
122
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { type WorkspaceDefinition2, type WorkspaceGroupDefinition2, type WorkspaceWindowDefinition2 } from '@egen-civitas/esm-globals';
|
|
2
|
+
export interface OpenedWorkspace {
|
|
3
|
+
workspaceName: string;
|
|
4
|
+
props: Record<string, any> | null;
|
|
5
|
+
hasUnsavedChanges: boolean;
|
|
6
|
+
/** Unique identifier for the workspace instance, used to track unique instances of the same workspace */
|
|
7
|
+
uuid: string;
|
|
8
|
+
}
|
|
9
|
+
export interface OpenedWindow {
|
|
10
|
+
windowName: string;
|
|
11
|
+
/** Root workspace at index 0, child workspaces follow */
|
|
12
|
+
openedWorkspaces: Array<OpenedWorkspace>;
|
|
13
|
+
props: Record<string, any> | null;
|
|
14
|
+
maximized: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface OpenedGroup {
|
|
17
|
+
groupName: string;
|
|
18
|
+
props: Record<string, any> | null;
|
|
19
|
+
}
|
|
20
|
+
export interface WorkspaceStoreState2 {
|
|
21
|
+
registeredGroupsByName: Record<string, WorkspaceGroupDefinition2 & {
|
|
22
|
+
moduleName: string;
|
|
23
|
+
}>;
|
|
24
|
+
registeredWindowsByName: Record<string, WorkspaceWindowDefinition2 & {
|
|
25
|
+
moduleName: string;
|
|
26
|
+
}>;
|
|
27
|
+
registeredWorkspacesByName: Record<string, WorkspaceDefinition2 & {
|
|
28
|
+
moduleName: string;
|
|
29
|
+
}>;
|
|
30
|
+
openedGroup: OpenedGroup | null;
|
|
31
|
+
/** Most recently opened window at the end of array. Each element has a unique windowName */
|
|
32
|
+
openedWindows: Array<OpenedWindow>;
|
|
33
|
+
/**
|
|
34
|
+
* While there can be multiple openedWindows, only the most recently opened window can be
|
|
35
|
+
* toggled shown or hidden, the rest are implicitly hidden.
|
|
36
|
+
**/
|
|
37
|
+
isMostRecentlyOpenedWindowHidden: boolean;
|
|
38
|
+
workspaceTitleByWorkspaceName: Record<string, string>;
|
|
39
|
+
}
|
|
40
|
+
export declare const workspace2Store: import("zustand").StoreApi<WorkspaceStoreState2>;
|
|
41
|
+
/**
|
|
42
|
+
* Given a workspace name, return the window that the workspace belongs to
|
|
43
|
+
* @param workspaceName
|
|
44
|
+
* @returns
|
|
45
|
+
*/
|
|
46
|
+
export declare function getWindowByWorkspaceName(workspaceName: string): WorkspaceWindowDefinition2 & {
|
|
47
|
+
moduleName: string;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Given a window name, return the group that the window belongs to
|
|
51
|
+
* @param windowName
|
|
52
|
+
* @returns
|
|
53
|
+
*/
|
|
54
|
+
export declare function getGroupByWindowName(windowName: string): WorkspaceGroupDefinition2 & {
|
|
55
|
+
moduleName: string;
|
|
56
|
+
};
|
|
57
|
+
export declare function getOpenedWindowIndexByWorkspace(workspaceName: string): number;
|
|
58
|
+
export declare function registerWorkspaceGroups2(appName: string, workspaceGroupDefs: Array<WorkspaceGroupDefinition2>): void;
|
|
59
|
+
export declare function registerWorkspaceWindows2(appName: string, workspaceWindowDefs: Array<WorkspaceWindowDefinition2>): void;
|
|
60
|
+
export declare function registerWorkspaces2(moduleName: string, workspaceDefs: Array<WorkspaceDefinition2>): void;
|
|
61
|
+
//# sourceMappingURL=workspaces2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspaces2.d.ts","sourceRoot":"","sources":["../src/workspaces2.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC9B,KAAK,0BAA0B,EAChC,MAAM,2BAA2B,CAAC;AAGnC,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IAClC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,yGAAyG;IACzG,IAAI,EAAE,MAAM,CAAC;CACd;AACD,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,gBAAgB,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC;IACzC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;CACnC;AACD,MAAM,WAAW,oBAAoB;IACnC,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3F,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,0BAA0B,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7F,0BAA0B,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1F,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,4FAA4F;IAC5F,aAAa,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;IAEnC;;;QAGI;IACJ,gCAAgC,EAAE,OAAO,CAAC;IAE1C,6BAA6B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACvD;AAYD,eAAO,MAAM,eAAe,kDAAsE,CAAC;AAEnG;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,aAAa,EAAE,MAAM;gBAhCuB,MAAM;EA6C1F;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM;gBArD4B,MAAM;EAkExF;AAED,wBAAgB,+BAA+B,CAAC,aAAa,EAAE,MAAM,UAKpE;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,KAAK,CAAC,yBAAyB,CAAC,QAgB7G;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,KAAK,CAAC,0BAA0B,CAAC,QAiBhH;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,CAAC,oBAAoB,CAAC,QAiBjG"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { createGlobalStore } from "@egen-civitas/esm-state";
|
|
2
|
+
const initialState = {
|
|
3
|
+
registeredGroupsByName: {},
|
|
4
|
+
registeredWindowsByName: {},
|
|
5
|
+
registeredWorkspacesByName: {},
|
|
6
|
+
openedGroup: null,
|
|
7
|
+
openedWindows: [],
|
|
8
|
+
workspaceTitleByWorkspaceName: {},
|
|
9
|
+
isMostRecentlyOpenedWindowHidden: false
|
|
10
|
+
};
|
|
11
|
+
export const workspace2Store = createGlobalStore('workspace2', initialState);
|
|
12
|
+
/**
|
|
13
|
+
* Given a workspace name, return the window that the workspace belongs to
|
|
14
|
+
* @param workspaceName
|
|
15
|
+
* @returns
|
|
16
|
+
*/ export function getWindowByWorkspaceName(workspaceName) {
|
|
17
|
+
const { registeredWorkspacesByName, registeredWindowsByName } = workspace2Store.getState();
|
|
18
|
+
const workspace = registeredWorkspacesByName[workspaceName];
|
|
19
|
+
if (!workspace) {
|
|
20
|
+
throw new Error(`No workspace found with name: ${workspaceName}`);
|
|
21
|
+
} else {
|
|
22
|
+
const workspaceWindow = registeredWindowsByName[workspace.window];
|
|
23
|
+
if (!workspaceWindow) {
|
|
24
|
+
throw new Error(`No workspace window found with name: ${workspace.window} for workspace: ${workspaceName}`);
|
|
25
|
+
} else {
|
|
26
|
+
return workspaceWindow;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Given a window name, return the group that the window belongs to
|
|
32
|
+
* @param windowName
|
|
33
|
+
* @returns
|
|
34
|
+
*/ export function getGroupByWindowName(windowName) {
|
|
35
|
+
const { registeredGroupsByName, registeredWindowsByName } = workspace2Store.getState();
|
|
36
|
+
const workspaceWindow = registeredWindowsByName[windowName];
|
|
37
|
+
if (!workspaceWindow) {
|
|
38
|
+
throw new Error(`No workspace window found with name: ${windowName}`);
|
|
39
|
+
} else {
|
|
40
|
+
const group = registeredGroupsByName[workspaceWindow.group];
|
|
41
|
+
if (!group) {
|
|
42
|
+
throw new Error(`No workspace group found with name: ${workspaceWindow.group} for window: ${windowName}`);
|
|
43
|
+
} else {
|
|
44
|
+
return group;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export function getOpenedWindowIndexByWorkspace(workspaceName) {
|
|
49
|
+
const { openedWindows } = workspace2Store.getState();
|
|
50
|
+
return openedWindows.findIndex((a)=>a.openedWorkspaces.find((openedWorkspace)=>openedWorkspace.workspaceName === workspaceName));
|
|
51
|
+
}
|
|
52
|
+
export function registerWorkspaceGroups2(appName, workspaceGroupDefs) {
|
|
53
|
+
if (workspaceGroupDefs.length == 0) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const { registeredGroupsByName } = workspace2Store.getState();
|
|
57
|
+
const newRegisteredGroupsByName = {
|
|
58
|
+
...registeredGroupsByName
|
|
59
|
+
};
|
|
60
|
+
for (const workspaceGroupDef of workspaceGroupDefs){
|
|
61
|
+
if (newRegisteredGroupsByName[workspaceGroupDef.name]) {
|
|
62
|
+
throw new Error(`Cannot register workspace group ${workspaceGroupDef.name} more than once`);
|
|
63
|
+
}
|
|
64
|
+
newRegisteredGroupsByName[workspaceGroupDef.name] = {
|
|
65
|
+
...workspaceGroupDef,
|
|
66
|
+
moduleName: appName
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
workspace2Store.setState({
|
|
70
|
+
registeredGroupsByName: newRegisteredGroupsByName
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
export function registerWorkspaceWindows2(appName, workspaceWindowDefs) {
|
|
74
|
+
if (workspaceWindowDefs.length == 0) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const { registeredWindowsByName } = workspace2Store.getState();
|
|
78
|
+
const newRegisteredWindowsByName = {
|
|
79
|
+
...registeredWindowsByName
|
|
80
|
+
};
|
|
81
|
+
for (const windowDef of workspaceWindowDefs){
|
|
82
|
+
if (newRegisteredWindowsByName[windowDef.name]) {
|
|
83
|
+
throw new Error(`Cannot register workspace window ${windowDef.name} more than once`);
|
|
84
|
+
}
|
|
85
|
+
const registeredWindowDef = {
|
|
86
|
+
...windowDef,
|
|
87
|
+
moduleName: appName
|
|
88
|
+
};
|
|
89
|
+
newRegisteredWindowsByName[windowDef.name] = registeredWindowDef;
|
|
90
|
+
}
|
|
91
|
+
workspace2Store.setState({
|
|
92
|
+
registeredWindowsByName: newRegisteredWindowsByName
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
export function registerWorkspaces2(moduleName, workspaceDefs) {
|
|
96
|
+
if (workspaceDefs.length == 0) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const { registeredWorkspacesByName } = workspace2Store.getState();
|
|
100
|
+
const newRegisteredWorkspacesByName = {
|
|
101
|
+
...registeredWorkspacesByName
|
|
102
|
+
};
|
|
103
|
+
for (const workspaceDef of workspaceDefs){
|
|
104
|
+
if (newRegisteredWorkspacesByName[workspaceDef.name]) {
|
|
105
|
+
throw new Error(`Cannot register workspace ${workspaceDef.name} more than once`);
|
|
106
|
+
}
|
|
107
|
+
const workspaceDefWithLoader = {
|
|
108
|
+
...workspaceDef,
|
|
109
|
+
moduleName
|
|
110
|
+
};
|
|
111
|
+
newRegisteredWorkspacesByName[workspaceDef.name] = workspaceDefWithLoader;
|
|
112
|
+
}
|
|
113
|
+
workspace2Store.setState({
|
|
114
|
+
registeredWorkspacesByName: newRegisteredWorkspacesByName
|
|
115
|
+
});
|
|
116
|
+
}
|
package/mock-jest.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { getGlobalStore } from '@egen-civitas/esm-state/mock';
|
|
2
|
+
|
|
3
|
+
export const attach = jest.fn();
|
|
4
|
+
export const detach = jest.fn();
|
|
5
|
+
export const detachAll = jest.fn();
|
|
6
|
+
|
|
7
|
+
export const switchTo = jest.fn();
|
|
8
|
+
|
|
9
|
+
export const getExtensionStore = () => getGlobalStore('extensions', { slots: {} });
|
|
10
|
+
|
|
11
|
+
export const getExtensionInternalStore = () =>
|
|
12
|
+
getGlobalStore('extensions-internal', {
|
|
13
|
+
slots: {},
|
|
14
|
+
extensions: {},
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const mockExtensionRegistry = {};
|
|
18
|
+
|
|
19
|
+
export const getExtensionRegistration = jest.fn((name) => {
|
|
20
|
+
return mockExtensionRegistry[name];
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export const registerExtension = jest.fn((ext) => {
|
|
24
|
+
mockExtensionRegistry[ext.name] = ext;
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export function clearMockExtensionRegistry() {
|
|
28
|
+
Object.keys(mockExtensionRegistry).forEach((key) => {
|
|
29
|
+
delete mockExtensionRegistry[key];
|
|
30
|
+
});
|
|
31
|
+
}
|