@heswell/vuu-portal 2.2.3 → 2.2.5
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/195.js +29 -6
- package/README.md +77 -0
- package/config/default-modules.yaml +6 -1
- package/package.json +3 -3
package/195.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MODULE_ADMIN_RPC, executeModuleAdminRpc, managedModuleColumnValues, managedModulePermissionValues, splitNotificationTopics, validateModuleConfig } from "@heswell/module-admin";
|
|
1
|
+
import { MODULE_ADMIN_RPC, deserializeModuleWorkspace, executeModuleAdminRpc, managedModuleColumnValues, managedModulePermissionValues, normalizeModuleWorkspace, splitNotificationTopics, validateModuleConfig } from "@heswell/module-admin";
|
|
2
2
|
import { ConfigFactory, EditSessionRpcHandler, ModuleFactory, NotificationModule, NullProvider, PermissionFilter, Provider, TableDef, VUU_DEFAULT_COLUMNS, ViewPortDef, createConfiguredAuthProviders, createVuuServerApplication, getLogger } from "@heswell/vuu-server";
|
|
3
3
|
import node_fs from "node:fs";
|
|
4
4
|
import node_path from "node:path";
|
|
@@ -32,7 +32,8 @@ function readModules(table) {
|
|
|
32
32
|
mfScope: stringValue(table, row, "mfScope"),
|
|
33
33
|
mfUrl: stringValue(table, row, "mfUrl"),
|
|
34
34
|
...navIcon(table, row),
|
|
35
|
-
...navMetadata(table, row)
|
|
35
|
+
...navMetadata(table, row),
|
|
36
|
+
...workspaceMetadata(table, row)
|
|
36
37
|
};
|
|
37
38
|
});
|
|
38
39
|
}
|
|
@@ -55,6 +56,12 @@ function navMetadata(table, row) {
|
|
|
55
56
|
}
|
|
56
57
|
return metadata;
|
|
57
58
|
}
|
|
59
|
+
function workspaceMetadata(table, row) {
|
|
60
|
+
const workspace = deserializeModuleWorkspace(optionalValue(table, row, "workspace"));
|
|
61
|
+
return workspace ? {
|
|
62
|
+
workspace
|
|
63
|
+
} : {};
|
|
64
|
+
}
|
|
58
65
|
function optionalValue(table, row, column) {
|
|
59
66
|
const index = table.tableDef.columns.findIndex(({ name })=>name === column);
|
|
60
67
|
return -1 === index ? void 0 : row[index];
|
|
@@ -188,6 +195,10 @@ const modulesTable = TableDef({
|
|
|
188
195
|
name: "notificationTopics",
|
|
189
196
|
dataType: "string"
|
|
190
197
|
},
|
|
198
|
+
{
|
|
199
|
+
name: "workspace",
|
|
200
|
+
dataType: "string"
|
|
201
|
+
},
|
|
191
202
|
...VUU_DEFAULT_COLUMNS
|
|
192
203
|
],
|
|
193
204
|
keyField: "id",
|
|
@@ -370,11 +381,17 @@ function readModulesFile(filePath) {
|
|
|
370
381
|
function cloneModules(modules) {
|
|
371
382
|
return modules.map((module)=>Object.fromEntries(Object.entries(module).filter(([, value])=>void 0 !== value).map(([key, value])=>[
|
|
372
383
|
key,
|
|
373
|
-
|
|
374
|
-
...value
|
|
375
|
-
] : value
|
|
384
|
+
cloneValue(value)
|
|
376
385
|
])));
|
|
377
386
|
}
|
|
387
|
+
function cloneValue(value) {
|
|
388
|
+
if (Array.isArray(value)) return value.map(cloneValue);
|
|
389
|
+
if (isRecord(value)) return Object.fromEntries(Object.entries(value).map(([key, item])=>[
|
|
390
|
+
key,
|
|
391
|
+
cloneValue(item)
|
|
392
|
+
]));
|
|
393
|
+
return value;
|
|
394
|
+
}
|
|
378
395
|
const managedModuleKeys = [
|
|
379
396
|
"id",
|
|
380
397
|
"version",
|
|
@@ -396,7 +413,8 @@ const managedModuleKeys = [
|
|
|
396
413
|
const optionalModuleKeys = [
|
|
397
414
|
"navOrder",
|
|
398
415
|
"navBadge",
|
|
399
|
-
"notificationTopics"
|
|
416
|
+
"notificationTopics",
|
|
417
|
+
"workspace"
|
|
400
418
|
];
|
|
401
419
|
const retiredModuleKeys = [
|
|
402
420
|
"vuuConnectionId",
|
|
@@ -424,6 +442,11 @@ function parseManagedModule(value, index) {
|
|
|
424
442
|
for (const key of optionalModuleKeys){
|
|
425
443
|
const fieldValue = value[key];
|
|
426
444
|
if (null == fieldValue) continue;
|
|
445
|
+
if ("workspace" === key) {
|
|
446
|
+
if (!isRecord(fieldValue)) throw new Error(`Modules file entry ${index} field 'workspace' must be an object`);
|
|
447
|
+
module[key] = cloneValue(normalizeModuleWorkspace(fieldValue));
|
|
448
|
+
continue;
|
|
449
|
+
}
|
|
427
450
|
const valid = "navOrder" === key ? "number" == typeof fieldValue : "navBadge" === key ? "string" == typeof fieldValue : Array.isArray(fieldValue) && fieldValue.every((topic)=>"string" == typeof topic);
|
|
428
451
|
if (!valid) {
|
|
429
452
|
const expected = "navOrder" === key ? "a number" : "navBadge" === key ? "a string" : "a list of strings";
|
package/README.md
CHANGED
|
@@ -138,3 +138,80 @@ absolute paths and `~/` paths are also accepted.
|
|
|
138
138
|
start.
|
|
139
139
|
- `vuu.portal.defaultModulesFile` is the seed catalogue. See
|
|
140
140
|
[`default-modules.yaml`](./default-modules.yaml) for the format.
|
|
141
|
+
|
|
142
|
+
## Workspaces and the Panels palette
|
|
143
|
+
|
|
144
|
+
`@vuu-ui/*` 4.0.0-alpha.26 adds named workspaces to the portal UI: a
|
|
145
|
+
**Workspaces** section in the nav with **+ New workspace**, the
|
|
146
|
+
`/workspaces/:id` route, **Reset to default**, and an **Add panel** button that
|
|
147
|
+
opens the **Panels** palette (tabs Modules, Tables and Recent) inline beside
|
|
148
|
+
the workspace grid. Tables › Browse lists the Vuu servers; each server page is
|
|
149
|
+
an unsaved workspace with the Tables palette pinned, which **Save as
|
|
150
|
+
workspace** keeps.
|
|
151
|
+
|
|
152
|
+
This package is the portal *server*. It doesn't render the UI; it supplies the
|
|
153
|
+
module records the palette is built from.
|
|
154
|
+
|
|
155
|
+
### What the server provides
|
|
156
|
+
|
|
157
|
+
A module record with a `workspace` descriptor is listed in the palette's
|
|
158
|
+
Modules tab, grouped by `workspace.paletteGroup`. A module without one isn't.
|
|
159
|
+
See [Workspace metadata](../../docs/requirements/vuu-portal-module-discovery.md#workspace-metadata)
|
|
160
|
+
for the field. In [`default-modules.yaml`](./default-modules.yaml):
|
|
161
|
+
|
|
162
|
+
| Module | `workspace` | Why |
|
|
163
|
+
| --- | --- | --- |
|
|
164
|
+
| `moduleAdmin`, `userAdmin` | `{ paletteGroup: "Admin", defaultSize: { cols: 12, rows: 6 } }` | Standalone pages |
|
|
165
|
+
| `basket-trading` | `{ paletteGroup: "Trading", defaultSize: { cols: 12, rows: 8 } }` | Standalone page |
|
|
166
|
+
| `vuu-table-browser` | none | It is itself a workspace page; its tables are in the palette's Tables tab |
|
|
167
|
+
| `vuu-table-viewer` | none | Nested module; it only works inside the table browser |
|
|
168
|
+
|
|
169
|
+
The seed only applies when `modules.yaml` is first created. To change an
|
|
170
|
+
existing deployment, edit `modules.yaml` or use the module admin
|
|
171
|
+
(`updateModule` with `workspace`, or `workspace: null` to remove a module from
|
|
172
|
+
the palette).
|
|
173
|
+
|
|
174
|
+
### Portal host requirements
|
|
175
|
+
|
|
176
|
+
The host is the `PortalShell` application, for example finos/vuu
|
|
177
|
+
`vuu-ui/portal-examples/portal-host`. See its
|
|
178
|
+
`docs/module-federation-architecture.md`. Workspaces are opt in:
|
|
179
|
+
|
|
180
|
+
```tsx
|
|
181
|
+
import {
|
|
182
|
+
AddPanelButton,
|
|
183
|
+
createPortalComponentRegistries,
|
|
184
|
+
PortalShell,
|
|
185
|
+
type PortalWorkspacesOptions,
|
|
186
|
+
} from "@vuu-ui/core/portal";
|
|
187
|
+
|
|
188
|
+
const { renderers, settingsCodecs } = createPortalComponentRegistries();
|
|
189
|
+
|
|
190
|
+
const workspaces: PortalWorkspacesOptions = {
|
|
191
|
+
componentRenderers: renderers,
|
|
192
|
+
headerActions: <AddPanelButton />,
|
|
193
|
+
settingsCodecs,
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
<PortalShell contextPanel={{ placement: "inline" }} workspaces={workspaces} ...>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
- `PortalShell` renders the single `GridLayoutProvider` above both the palette
|
|
200
|
+
and the workspace. Don't add another one in the host or in a remote.
|
|
201
|
+
- `contextPanel={{ placement: "inline" }}` shows the palette beside the grid
|
|
202
|
+
instead of over it.
|
|
203
|
+
- Module Federation must share these as strict singletons
|
|
204
|
+
(`singleton: true, strictVersion: true`) in the host *and* every remote:
|
|
205
|
+
`react`, `react-dom`, `react-router-dom`, `@vuu-ui/core`,
|
|
206
|
+
`@vuu-ui/core/portal`, `@vuu-ui/grid-layout` and
|
|
207
|
+
`@vuu-ui/vuu-notifications`. A second copy of grid-layout breaks dragging
|
|
208
|
+
from the palette into the workspace; a second React or router breaks
|
|
209
|
+
rendering.
|
|
210
|
+
- Workspaces are saved by `workspaces.persistenceService`. By default that is
|
|
211
|
+
browser local storage, scoped to the `PortalShell` id and the signed-in
|
|
212
|
+
user. Servers added under Tables › Browse are kept in the per-user portal
|
|
213
|
+
state (`servers/manual`). This server doesn't store either.
|
|
214
|
+
|
|
215
|
+
To turn workspaces off, leave the `workspaces` prop off `PortalShell`. To
|
|
216
|
+
keep workspaces but hide a module from the palette, remove its `workspace`
|
|
217
|
+
descriptor.
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
# title: "Manage remote modules"
|
|
13
13
|
# description: "Create new remote module, update existing modules"
|
|
14
14
|
# enabled: true
|
|
15
|
-
# location: "/
|
|
15
|
+
# location: "/Admin/Manage Modules"
|
|
16
16
|
# path: "/modules/admin"
|
|
17
17
|
# mfComponent: "ModuleAdmin"
|
|
18
18
|
# mfScope: "moduleAdmin"
|
|
@@ -23,4 +23,9 @@
|
|
|
23
23
|
# navOrder: 1
|
|
24
24
|
# navBadge: "modules.pending"
|
|
25
25
|
# notificationTopics: ["modules"]
|
|
26
|
+
# # Optional: list the module in the workspace Panels palette.
|
|
27
|
+
# workspace:
|
|
28
|
+
# paletteGroup: "Admin"
|
|
29
|
+
# iconUrl: "" # optional; data:image/... or http(s) URL
|
|
30
|
+
# defaultSize: { cols: 6, rows: 4 } # optional; positive integers
|
|
26
31
|
modules: []
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heswell/vuu-portal",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.5",
|
|
4
4
|
"description": "VUU portal server with remote module discovery",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.js",
|
|
@@ -26,12 +26,12 @@
|
|
|
26
26
|
"author": "heswell",
|
|
27
27
|
"license": "MIT",
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@heswell/module-admin": "^2.
|
|
29
|
+
"@heswell/module-admin": "^2.2.0"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
32
|
"@heswell/vuu-server": "^3.1.0 || ^4.0.0",
|
|
33
33
|
"@heswell/vuu-table": "^1.0.1",
|
|
34
|
-
"@vuu-ui/vuu-protocol-types": "^4.0.0-alpha.
|
|
34
|
+
"@vuu-ui/vuu-protocol-types": "^4.0.0-alpha.26"
|
|
35
35
|
},
|
|
36
36
|
"repository": {
|
|
37
37
|
"type": "git",
|