@nocobase/plugin-multi-portal 3.0.0-alpha.4 → 3.0.0-alpha.6
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 +7 -5
- package/dist/client-v2/499.245037eea4cc7266.js +10 -0
- package/dist/client-v2/556.64742ccddb8fe2f0.js +10 -0
- package/dist/client-v2/index.js +1 -1
- package/dist/client-v2/layoutRegistration.d.ts +1 -5
- package/dist/client-v2/pages/MultiPortalsPage.d.ts +0 -26
- package/dist/constants.d.ts +7 -0
- package/dist/constants.js +27 -2
- package/dist/externalVersion.js +8 -8
- package/dist/locale/en-US.json +18 -14
- package/dist/locale/zh-CN.json +16 -12
- package/dist/node_modules/tar/package.json +1 -1
- package/dist/server/collections/multiPortals.js +2 -11
- package/dist/server/plugin.d.ts +3 -3
- package/dist/server/plugin.js +203 -238
- package/package.json +3 -3
- package/dist/client-v2/499.ef2ff0c022687485.js +0 -10
- package/dist/client-v2/556.37df9197ce5c3452.js +0 -10
package/dist/server/plugin.js
CHANGED
|
@@ -60,9 +60,9 @@ const MULTI_PORTAL_RUNTIME_FIELDS = [
|
|
|
60
60
|
"portalName",
|
|
61
61
|
"routePath",
|
|
62
62
|
"authCheck",
|
|
63
|
-
"enabled"
|
|
63
|
+
"enabled",
|
|
64
|
+
"uiLayoutUid"
|
|
64
65
|
];
|
|
65
|
-
const MULTI_PORTAL_RUNTIME_QUERY_FIELDS = [...MULTI_PORTAL_RUNTIME_FIELDS, "uiLayoutUid"];
|
|
66
66
|
const MULTI_PORTAL_ACCESSIBLE_FIELDS = [
|
|
67
67
|
"uid",
|
|
68
68
|
"title",
|
|
@@ -71,10 +71,9 @@ const MULTI_PORTAL_ACCESSIBLE_FIELDS = [
|
|
|
71
71
|
"portalName",
|
|
72
72
|
"routePath",
|
|
73
73
|
"authCheck",
|
|
74
|
-
"enabled"
|
|
74
|
+
"enabled",
|
|
75
|
+
"uiLayoutUid"
|
|
75
76
|
];
|
|
76
|
-
const MULTI_PORTAL_ACCESSIBLE_QUERY_FIELDS = [...MULTI_PORTAL_ACCESSIBLE_FIELDS, "uiLayoutUid"];
|
|
77
|
-
const MULTI_PORTAL_UI_LAYOUT_RUNTIME_FIELDS = ["layoutType"];
|
|
78
77
|
const DESKTOP_ROUTE_ROLE_PERMISSION_TARGET_FIELDS = ["id", "title", "hidden", "parentId", "options"];
|
|
79
78
|
const UI_LAYOUT_DESKTOP_ROUTE_WRITE_LAYOUT_HANDLER_TAG = "plugin-ui-layout:desktop-route-write-layout";
|
|
80
79
|
const MAIN_APP_NAME = "main";
|
|
@@ -181,7 +180,7 @@ function getDefaultMultiPortalRecord(options = {}) {
|
|
|
181
180
|
authCheck: true,
|
|
182
181
|
enabled: true,
|
|
183
182
|
...options.isDefault ? { isDefault: true } : {},
|
|
184
|
-
uiLayoutUid:
|
|
183
|
+
uiLayoutUid: import_constants.ADMIN_UI_LAYOUT_UID
|
|
185
184
|
};
|
|
186
185
|
}
|
|
187
186
|
function getFreshMultiPortalRecords() {
|
|
@@ -198,7 +197,7 @@ function getFixedLayoutMultiPortalRecords() {
|
|
|
198
197
|
routePath: "/admin",
|
|
199
198
|
authCheck: true,
|
|
200
199
|
enabled: true,
|
|
201
|
-
uiLayoutUid:
|
|
200
|
+
uiLayoutUid: import_constants.ADMIN_UI_LAYOUT_UID
|
|
202
201
|
},
|
|
203
202
|
{
|
|
204
203
|
uid: import_constants.DEFAULT_MOBILE_MULTI_PORTAL_UID,
|
|
@@ -209,7 +208,7 @@ function getFixedLayoutMultiPortalRecords() {
|
|
|
209
208
|
routePath: "/mobile",
|
|
210
209
|
authCheck: true,
|
|
211
210
|
enabled: true,
|
|
212
|
-
uiLayoutUid:
|
|
211
|
+
uiLayoutUid: import_constants.MOBILE_UI_LAYOUT_UID
|
|
213
212
|
}
|
|
214
213
|
];
|
|
215
214
|
}
|
|
@@ -294,6 +293,13 @@ function getPortalDeployBasePath(appName, portalName) {
|
|
|
294
293
|
const portalPath = appName === MAIN_APP_NAME ? `/${PORTAL_CLIENT_PREFIX}/${portalName}/` : `/${PORTAL_CLIENT_PREFIX}/apps/${appName}/${portalName}/`;
|
|
295
294
|
return resolvePortalStoragePublicPath(joinPortalStoragePublicPath(process.env.APP_PUBLIC_PATH || "/", portalPath));
|
|
296
295
|
}
|
|
296
|
+
function getPortalDeployBasePathCandidates(appName, portalName) {
|
|
297
|
+
const expectedBasePaths = [getPortalDeployBasePath(appName, portalName)];
|
|
298
|
+
if (appName !== MAIN_APP_NAME) {
|
|
299
|
+
expectedBasePaths.push(getPortalDeployBasePath(MAIN_APP_NAME, portalName));
|
|
300
|
+
}
|
|
301
|
+
return expectedBasePaths;
|
|
302
|
+
}
|
|
297
303
|
function createPortalDeployUploadMiddleware() {
|
|
298
304
|
const storage = import_utils.koaMulter.diskStorage({
|
|
299
305
|
destination: import_os.default.tmpdir(),
|
|
@@ -436,80 +442,13 @@ async function resolvePortalTemplate(templateSource, logPath) {
|
|
|
436
442
|
return downloadPortalTemplatePackage(templateSource, logPath);
|
|
437
443
|
}
|
|
438
444
|
async function copyPortalTemplate(sourceDir, targetDir) {
|
|
439
|
-
const ignoredSegments = /* @__PURE__ */ new Set([".git", "node_modules", ".DS_Store"]);
|
|
445
|
+
const ignoredSegments = /* @__PURE__ */ new Set([".git", "node_modules", ".DS_Store", ".env", ".env.local"]);
|
|
440
446
|
await import_fs.default.promises.mkdir(import_path.default.dirname(targetDir), { recursive: true });
|
|
441
447
|
await import_fs.default.promises.cp(sourceDir, targetDir, {
|
|
442
448
|
recursive: true,
|
|
443
449
|
filter: (source) => !import_path.default.relative(sourceDir, source).split(import_path.default.sep).some((segment) => segment.startsWith("._") || ignoredSegments.has(segment))
|
|
444
450
|
});
|
|
445
451
|
}
|
|
446
|
-
function getPortalStorageConfig(options) {
|
|
447
|
-
const sourceOptions = isRecordLike(options) ? options : {};
|
|
448
|
-
const sourceStorage = trimString(sourceOptions.sourceStorage);
|
|
449
|
-
if (sourceStorage !== "git") {
|
|
450
|
-
return { sourceStorage: "nocobase" };
|
|
451
|
-
}
|
|
452
|
-
const gitOptions = isRecordLike(sourceOptions.git) ? sourceOptions.git : {};
|
|
453
|
-
return {
|
|
454
|
-
sourceStorage,
|
|
455
|
-
git: {
|
|
456
|
-
repo: trimString(gitOptions.repo),
|
|
457
|
-
branch: trimString(gitOptions.branch) || "main",
|
|
458
|
-
path: trimString(gitOptions.path) || "."
|
|
459
|
-
}
|
|
460
|
-
};
|
|
461
|
-
}
|
|
462
|
-
function upsertPortalEnvContent(content, values) {
|
|
463
|
-
const nextValues = { ...values };
|
|
464
|
-
const lines = content ? content.replace(/\r\n/g, "\n").split("\n") : [];
|
|
465
|
-
const result = [];
|
|
466
|
-
for (const line of lines) {
|
|
467
|
-
if (!line && result.length === lines.length - 1) {
|
|
468
|
-
continue;
|
|
469
|
-
}
|
|
470
|
-
const match = line.match(/^(\s*)([A-Za-z_][A-Za-z0-9_]*)\s*=/);
|
|
471
|
-
const key = match == null ? void 0 : match[2];
|
|
472
|
-
if (key && Object.prototype.hasOwnProperty.call(nextValues, key)) {
|
|
473
|
-
result.push(`${key}=${nextValues[key]}`);
|
|
474
|
-
delete nextValues[key];
|
|
475
|
-
continue;
|
|
476
|
-
}
|
|
477
|
-
result.push(line);
|
|
478
|
-
}
|
|
479
|
-
for (const [key, value] of Object.entries(nextValues)) {
|
|
480
|
-
result.push(`${key}=${value}`);
|
|
481
|
-
}
|
|
482
|
-
return `${result.join("\n").replace(/\n*$/, "")}
|
|
483
|
-
`;
|
|
484
|
-
}
|
|
485
|
-
async function upsertPortalEnvFile(filePath, values) {
|
|
486
|
-
let content = "";
|
|
487
|
-
try {
|
|
488
|
-
content = await import_fs.default.promises.readFile(filePath, "utf-8");
|
|
489
|
-
} catch {
|
|
490
|
-
content = "";
|
|
491
|
-
}
|
|
492
|
-
await import_fs.default.promises.writeFile(filePath, upsertPortalEnvContent(content, values), "utf-8");
|
|
493
|
-
}
|
|
494
|
-
async function ensurePortalStorageConfigFiles(portalDir, item) {
|
|
495
|
-
const apiUrl = getPortalStorageApiUrl(item.appName);
|
|
496
|
-
const portalBase = getPortalDeployBasePath(item.appName, item.portalName);
|
|
497
|
-
await import_fs.default.promises.mkdir(portalDir, { recursive: true });
|
|
498
|
-
await upsertPortalEnvFile(import_path.default.join(portalDir, ".env"), {
|
|
499
|
-
NOCOBASE_API_URL: resolvePortalStorageEnvApiUrl(apiUrl),
|
|
500
|
-
NOCOBASE_PORTAL_BASE: portalBase
|
|
501
|
-
});
|
|
502
|
-
await upsertPortalEnvFile(import_path.default.join(portalDir, ".env.local"), {
|
|
503
|
-
NOCOBASE_API_URL: apiUrl,
|
|
504
|
-
NOCOBASE_PORTAL_BASE: portalBase
|
|
505
|
-
});
|
|
506
|
-
await import_fs.default.promises.writeFile(
|
|
507
|
-
import_path.default.join(portalDir, "portal.config.json"),
|
|
508
|
-
`${JSON.stringify(item.config, null, 2)}
|
|
509
|
-
`,
|
|
510
|
-
"utf-8"
|
|
511
|
-
);
|
|
512
|
-
}
|
|
513
452
|
function sanitizePortalStorageNodeOptions(value) {
|
|
514
453
|
return trimString(value).split(/\s+/).filter((option) => option !== "--preserve-symlinks" && option !== "--preserve-symlinks-main").join(" ");
|
|
515
454
|
}
|
|
@@ -620,9 +559,9 @@ function validatePortalDeployBasePath(appName, portalName, basePath) {
|
|
|
620
559
|
if (normalizedBasePath.includes("..")) {
|
|
621
560
|
throw new Error('basePath cannot contain ".."');
|
|
622
561
|
}
|
|
623
|
-
const
|
|
624
|
-
if (normalizedBasePath
|
|
625
|
-
throw new Error(`basePath must be ${
|
|
562
|
+
const expectedBasePaths = getPortalDeployBasePathCandidates(appName, portalName);
|
|
563
|
+
if (!expectedBasePaths.includes(normalizedBasePath)) {
|
|
564
|
+
throw new Error(`basePath must be ${expectedBasePaths.join(" or ")}`);
|
|
626
565
|
}
|
|
627
566
|
}
|
|
628
567
|
function isPortalDeployTarEntry(entry) {
|
|
@@ -860,19 +799,11 @@ function collectDesktopRouteIds(record) {
|
|
|
860
799
|
}
|
|
861
800
|
return uniqueDesktopRouteIds(routeIds);
|
|
862
801
|
}
|
|
863
|
-
function pickMultiPortalUiLayoutRuntimeFields(record) {
|
|
864
|
-
const result = {};
|
|
865
|
-
for (const field of MULTI_PORTAL_UI_LAYOUT_RUNTIME_FIELDS) {
|
|
866
|
-
result[field] = getRecordField(record, field);
|
|
867
|
-
}
|
|
868
|
-
return result;
|
|
869
|
-
}
|
|
870
802
|
function pickMultiPortalRuntimeFields(record) {
|
|
871
803
|
const result = {};
|
|
872
804
|
for (const field of MULTI_PORTAL_RUNTIME_FIELDS) {
|
|
873
805
|
result[field] = getRecordField(record, field);
|
|
874
806
|
}
|
|
875
|
-
result.uiLayout = pickMultiPortalUiLayoutRuntimeFields(getRecordField(record, "uiLayout"));
|
|
876
807
|
return result;
|
|
877
808
|
}
|
|
878
809
|
function pickMultiPortalAccessibleFields(record) {
|
|
@@ -880,7 +811,6 @@ function pickMultiPortalAccessibleFields(record) {
|
|
|
880
811
|
for (const field of MULTI_PORTAL_ACCESSIBLE_FIELDS) {
|
|
881
812
|
result[field] = getRecordField(record, field) ?? null;
|
|
882
813
|
}
|
|
883
|
-
result.uiLayout = pickMultiPortalUiLayoutRuntimeFields(getRecordField(record, "uiLayout"));
|
|
884
814
|
return result;
|
|
885
815
|
}
|
|
886
816
|
function getExplicitRequestedLayoutUid(layout) {
|
|
@@ -1130,14 +1060,27 @@ async function seedHistoricalMultiPortals(db) {
|
|
|
1130
1060
|
}
|
|
1131
1061
|
await repairFixedLayoutMultiPortalRecords(db);
|
|
1132
1062
|
}
|
|
1133
|
-
async function
|
|
1063
|
+
async function validateMultiPortalUiLayoutUidWrite(ctx, next) {
|
|
1064
|
+
var _a;
|
|
1134
1065
|
const targets = await getMultiPortalWriteTargets(ctx, ["uiLayoutUid"]);
|
|
1066
|
+
const actionName = (_a = ctx.action) == null ? void 0 : _a.actionName;
|
|
1067
|
+
const createsWhenMissing = actionName === "create" || actionName === "firstOrCreate" || actionName === "updateOrCreate";
|
|
1135
1068
|
for (const { existing, values } of targets) {
|
|
1136
|
-
|
|
1069
|
+
const hasUiLayoutUid = Object.prototype.hasOwnProperty.call(values, "uiLayoutUid");
|
|
1070
|
+
if (!existing && createsWhenMissing && !hasUiLayoutUid) {
|
|
1071
|
+
ctx.throw(400, `Portal UI layout must be one of: ${import_constants.MULTI_PORTAL_UI_LAYOUT_UIDS.join(", ")}`);
|
|
1072
|
+
return;
|
|
1073
|
+
}
|
|
1074
|
+
if (!hasUiLayoutUid) {
|
|
1137
1075
|
continue;
|
|
1138
1076
|
}
|
|
1139
|
-
if (
|
|
1140
|
-
ctx.throw(400,
|
|
1077
|
+
if (!(0, import_constants.isMultiPortalUiLayoutUid)(values.uiLayoutUid)) {
|
|
1078
|
+
ctx.throw(400, `Portal UI layout must be one of: ${import_constants.MULTI_PORTAL_UI_LAYOUT_UIDS.join(", ")}`);
|
|
1079
|
+
return;
|
|
1080
|
+
}
|
|
1081
|
+
const existingUiLayoutUid = existing == null ? void 0 : existing.get("uiLayoutUid");
|
|
1082
|
+
if (existing && existingUiLayoutUid !== values.uiLayoutUid) {
|
|
1083
|
+
ctx.throw(400, "Portal UI layout cannot be changed");
|
|
1141
1084
|
return;
|
|
1142
1085
|
}
|
|
1143
1086
|
}
|
|
@@ -1165,20 +1108,8 @@ async function findRequestedMultiPortal(ctx, transaction) {
|
|
|
1165
1108
|
ctx.throw(400, `Portal '${portalUid}' does not support desktop routes`);
|
|
1166
1109
|
}
|
|
1167
1110
|
const uiLayoutUid = portal.get("uiLayoutUid");
|
|
1168
|
-
if (
|
|
1169
|
-
ctx.throw(400, `Portal '${portalUid}' has
|
|
1170
|
-
}
|
|
1171
|
-
const uiLayout = await ctx.db.getRepository("uiLayouts").findOne({
|
|
1172
|
-
filter: {
|
|
1173
|
-
uid: uiLayoutUid,
|
|
1174
|
-
enabled: true
|
|
1175
|
-
},
|
|
1176
|
-
fields: ["uid"],
|
|
1177
|
-
...transaction ? { lock: transaction.LOCK.UPDATE } : {},
|
|
1178
|
-
transaction
|
|
1179
|
-
});
|
|
1180
|
-
if (!uiLayout) {
|
|
1181
|
-
ctx.throw(400, `Portal '${portalUid}' has no enabled backing UI layout`);
|
|
1111
|
+
if (!(0, import_constants.isMultiPortalUiLayoutUid)(uiLayoutUid)) {
|
|
1112
|
+
ctx.throw(400, `Portal '${portalUid}' has an unsupported UI layout UID`);
|
|
1182
1113
|
}
|
|
1183
1114
|
const usesLayoutPermissions = (0, import_constants.isDefaultLayoutMultiPortalUid)(portalUid);
|
|
1184
1115
|
return {
|
|
@@ -1363,7 +1294,7 @@ async function removeRouteIdsWithUnauthorizedAncestors(ctx, routeIds) {
|
|
|
1363
1294
|
}
|
|
1364
1295
|
}
|
|
1365
1296
|
}
|
|
1366
|
-
async function getMultiPortalAccessibleRouteIds(ctx,
|
|
1297
|
+
async function getMultiPortalAccessibleRouteIds(ctx, portalContext) {
|
|
1367
1298
|
const currentRoles = getCurrentRoles(ctx);
|
|
1368
1299
|
if (currentRoles.includes("root")) {
|
|
1369
1300
|
return;
|
|
@@ -1371,11 +1302,11 @@ async function getMultiPortalAccessibleRouteIds(ctx, multiPortalUid) {
|
|
|
1371
1302
|
if (!currentRoles.length) {
|
|
1372
1303
|
return /* @__PURE__ */ new Set();
|
|
1373
1304
|
}
|
|
1374
|
-
const routePermissions = await ctx.db.getRepository("rolesMultiPortalDesktopRoutes").find({
|
|
1305
|
+
const routePermissions = await ctx.db.getRepository(portalContext.relation === "uiLayouts" ? "rolesDesktopRoutes" : "rolesMultiPortalDesktopRoutes").find({
|
|
1375
1306
|
fields: ["desktopRouteId"],
|
|
1376
1307
|
filter: {
|
|
1377
1308
|
roleName: currentRoles,
|
|
1378
|
-
multiPortalUid
|
|
1309
|
+
...portalContext.relation === "multiPortals" ? { multiPortalUid: portalContext.portalUid } : {}
|
|
1379
1310
|
}
|
|
1380
1311
|
});
|
|
1381
1312
|
const routeIds = /* @__PURE__ */ new Set();
|
|
@@ -1391,7 +1322,7 @@ async function getMultiPortalAccessibleRouteIds(ctx, multiPortalUid) {
|
|
|
1391
1322
|
const portalRoutes = await ctx.db.getRepository("desktopRoutes").find({
|
|
1392
1323
|
fields: ["id"],
|
|
1393
1324
|
filter: {
|
|
1394
|
-
...
|
|
1325
|
+
...portalContext.filter,
|
|
1395
1326
|
id: Array.from(routeIds)
|
|
1396
1327
|
}
|
|
1397
1328
|
});
|
|
@@ -1421,9 +1352,107 @@ function setDesktopRouteChildren(route, children) {
|
|
|
1421
1352
|
const maybeModel = route;
|
|
1422
1353
|
if (typeof maybeModel.setDataValue === "function") {
|
|
1423
1354
|
maybeModel.setDataValue("children", children);
|
|
1355
|
+
} else {
|
|
1356
|
+
maybeModel.children = children;
|
|
1357
|
+
}
|
|
1358
|
+
if (!maybeModel._options) {
|
|
1359
|
+
return;
|
|
1360
|
+
}
|
|
1361
|
+
if (!maybeModel._options.includeNames) {
|
|
1362
|
+
maybeModel._options.includeNames = ["children"];
|
|
1424
1363
|
return;
|
|
1425
1364
|
}
|
|
1426
|
-
|
|
1365
|
+
if (!maybeModel._options.includeNames.includes("children")) {
|
|
1366
|
+
maybeModel._options.includeNames.push("children");
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1369
|
+
function getDesktopRouteId(route) {
|
|
1370
|
+
const id = getRecordField(route, "id");
|
|
1371
|
+
return id === null || id === void 0 ? void 0 : String(id);
|
|
1372
|
+
}
|
|
1373
|
+
function getDesktopRouteParentId(route) {
|
|
1374
|
+
const parentId = getRecordField(route, "parentId");
|
|
1375
|
+
return parentId === null || parentId === void 0 ? void 0 : String(parentId);
|
|
1376
|
+
}
|
|
1377
|
+
function collectDesktopRouteStringIds(routes, routeIds) {
|
|
1378
|
+
for (const route of routes) {
|
|
1379
|
+
const routeId = getDesktopRouteId(route);
|
|
1380
|
+
if (routeId) {
|
|
1381
|
+
routeIds.add(routeId);
|
|
1382
|
+
}
|
|
1383
|
+
const children = getRecordField(route, "children");
|
|
1384
|
+
if (Array.isArray(children)) {
|
|
1385
|
+
collectDesktopRouteStringIds(children, routeIds);
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
function removeNestedRootDesktopRoutes(routes) {
|
|
1390
|
+
if (!Array.isArray(routes)) {
|
|
1391
|
+
return [];
|
|
1392
|
+
}
|
|
1393
|
+
const routeIds = /* @__PURE__ */ new Set();
|
|
1394
|
+
collectDesktopRouteStringIds(routes, routeIds);
|
|
1395
|
+
return routes.filter((route) => {
|
|
1396
|
+
const parentId = getDesktopRouteParentId(route);
|
|
1397
|
+
return !parentId || !routeIds.has(parentId);
|
|
1398
|
+
});
|
|
1399
|
+
}
|
|
1400
|
+
function buildAccessibleDesktopRouteTreeWithAncestors(routes, accessibleRouteIds) {
|
|
1401
|
+
const routeById = /* @__PURE__ */ new Map();
|
|
1402
|
+
const childrenByParentId = /* @__PURE__ */ new Map();
|
|
1403
|
+
const roots = [];
|
|
1404
|
+
for (const route of routes) {
|
|
1405
|
+
const routeId = getDesktopRouteId(route);
|
|
1406
|
+
if (!routeId) {
|
|
1407
|
+
continue;
|
|
1408
|
+
}
|
|
1409
|
+
setDesktopRouteChildren(route, void 0);
|
|
1410
|
+
routeById.set(routeId, route);
|
|
1411
|
+
}
|
|
1412
|
+
for (const route of routes) {
|
|
1413
|
+
const routeId = getDesktopRouteId(route);
|
|
1414
|
+
if (!routeId || !routeById.has(routeId)) {
|
|
1415
|
+
continue;
|
|
1416
|
+
}
|
|
1417
|
+
const parentId = getDesktopRouteParentId(route);
|
|
1418
|
+
if (!parentId || !routeById.has(parentId)) {
|
|
1419
|
+
roots.push(route);
|
|
1420
|
+
continue;
|
|
1421
|
+
}
|
|
1422
|
+
const children = childrenByParentId.get(parentId) ?? [];
|
|
1423
|
+
children.push(route);
|
|
1424
|
+
childrenByParentId.set(parentId, children);
|
|
1425
|
+
}
|
|
1426
|
+
const visitRoute = (route, visitingRouteIds) => {
|
|
1427
|
+
const routeId = getDesktopRouteId(route);
|
|
1428
|
+
if (!routeId || visitingRouteIds.has(routeId)) {
|
|
1429
|
+
return void 0;
|
|
1430
|
+
}
|
|
1431
|
+
visitingRouteIds.add(routeId);
|
|
1432
|
+
const visibleChildren = (childrenByParentId.get(routeId) ?? []).map((child) => visitRoute(child, visitingRouteIds)).filter((child) => child !== void 0);
|
|
1433
|
+
visitingRouteIds.delete(routeId);
|
|
1434
|
+
if (!accessibleRouteIds.has(routeId) && visibleChildren.length === 0) {
|
|
1435
|
+
return void 0;
|
|
1436
|
+
}
|
|
1437
|
+
setDesktopRouteChildren(route, visibleChildren.length ? visibleChildren : void 0);
|
|
1438
|
+
return route;
|
|
1439
|
+
};
|
|
1440
|
+
return roots.map((route) => visitRoute(route, /* @__PURE__ */ new Set())).filter((route) => route !== void 0);
|
|
1441
|
+
}
|
|
1442
|
+
async function includeDesktopRouteAncestorsForListAccessible(ctx, routes, portalFilter) {
|
|
1443
|
+
if (!Array.isArray(routes)) {
|
|
1444
|
+
return routes;
|
|
1445
|
+
}
|
|
1446
|
+
const accessibleRouteIds = /* @__PURE__ */ new Set();
|
|
1447
|
+
collectDesktopRouteStringIds(routes, accessibleRouteIds);
|
|
1448
|
+
if (!accessibleRouteIds.size) {
|
|
1449
|
+
return routes;
|
|
1450
|
+
}
|
|
1451
|
+
const portalRoutes = await ctx.db.getRepository("desktopRoutes").find({
|
|
1452
|
+
sort: "sort",
|
|
1453
|
+
filter: portalFilter
|
|
1454
|
+
});
|
|
1455
|
+
return buildAccessibleDesktopRouteTreeWithAncestors(portalRoutes, accessibleRouteIds);
|
|
1427
1456
|
}
|
|
1428
1457
|
function removeDesktopRoutesByIds(routes, routeIds) {
|
|
1429
1458
|
return routes.map((route) => {
|
|
@@ -1490,23 +1519,26 @@ async function removeMultiPortalOwnedRouteFromGetResponse(ctx) {
|
|
|
1490
1519
|
ctx.body = void 0;
|
|
1491
1520
|
}
|
|
1492
1521
|
async function replaceListAccessibleRoutesWithPortalScopedRoutes(ctx, portalContext) {
|
|
1493
|
-
const routeIds = await getMultiPortalAccessibleRouteIds(ctx, portalContext
|
|
1522
|
+
const routeIds = await getMultiPortalAccessibleRouteIds(ctx, portalContext);
|
|
1494
1523
|
if (routeIds && routeIds.size === 0) {
|
|
1495
1524
|
ctx.body = [];
|
|
1496
1525
|
return;
|
|
1497
1526
|
}
|
|
1498
|
-
|
|
1527
|
+
const routes = await ctx.db.getRepository("desktopRoutes").find({
|
|
1499
1528
|
tree: true,
|
|
1500
1529
|
sort: "sort",
|
|
1501
1530
|
filter: {
|
|
1502
|
-
...
|
|
1531
|
+
...portalContext.filter,
|
|
1503
1532
|
...routeIds ? { id: Array.from(routeIds) } : {}
|
|
1504
1533
|
}
|
|
1505
1534
|
});
|
|
1535
|
+
ctx.body = removeNestedRootDesktopRoutes(
|
|
1536
|
+
await includeDesktopRouteAncestorsForListAccessible(ctx, routes, portalContext.filter)
|
|
1537
|
+
);
|
|
1506
1538
|
}
|
|
1507
1539
|
async function replaceGetAccessibleRouteWithPortalScopedRoute(ctx, portalContext) {
|
|
1508
1540
|
var _a;
|
|
1509
|
-
const routeIds = await getMultiPortalAccessibleRouteIds(ctx, portalContext
|
|
1541
|
+
const routeIds = await getMultiPortalAccessibleRouteIds(ctx, portalContext);
|
|
1510
1542
|
if (routeIds && routeIds.size === 0) {
|
|
1511
1543
|
ctx.status = 204;
|
|
1512
1544
|
ctx.body = void 0;
|
|
@@ -1516,7 +1548,7 @@ async function replaceGetAccessibleRouteWithPortalScopedRoute(ctx, portalContext
|
|
|
1516
1548
|
sort: "sort",
|
|
1517
1549
|
filterByTk: (_a = ctx.action) == null ? void 0 : _a.params.filterByTk,
|
|
1518
1550
|
filter: {
|
|
1519
|
-
...
|
|
1551
|
+
...portalContext.filter,
|
|
1520
1552
|
...routeIds ? { id: Array.from(routeIds) } : {}
|
|
1521
1553
|
}
|
|
1522
1554
|
});
|
|
@@ -1553,13 +1585,10 @@ async function addMultiPortalListAccessibleGuard(ctx, next) {
|
|
|
1553
1585
|
return;
|
|
1554
1586
|
}
|
|
1555
1587
|
await next();
|
|
1556
|
-
if (
|
|
1588
|
+
if (portalContext) {
|
|
1557
1589
|
await replaceListAccessibleRoutesWithPortalScopedRoutes(ctx, portalContext);
|
|
1558
1590
|
return;
|
|
1559
1591
|
}
|
|
1560
|
-
if ((portalContext == null ? void 0 : portalContext.relation) === "uiLayouts") {
|
|
1561
|
-
return;
|
|
1562
|
-
}
|
|
1563
1592
|
await removeMultiPortalOwnedRoutesFromListResponse(ctx);
|
|
1564
1593
|
}
|
|
1565
1594
|
async function addMultiPortalGetAccessibleGuard(ctx, next) {
|
|
@@ -1570,17 +1599,13 @@ async function addMultiPortalGetAccessibleGuard(ctx, next) {
|
|
|
1570
1599
|
return;
|
|
1571
1600
|
}
|
|
1572
1601
|
await next();
|
|
1573
|
-
if (
|
|
1602
|
+
if (portalContext) {
|
|
1574
1603
|
await replaceGetAccessibleRouteWithPortalScopedRoute(ctx, portalContext);
|
|
1575
1604
|
return;
|
|
1576
1605
|
}
|
|
1577
|
-
if ((portalContext == null ? void 0 : portalContext.relation) === "uiLayouts") {
|
|
1578
|
-
return;
|
|
1579
|
-
}
|
|
1580
1606
|
await removeMultiPortalOwnedRouteFromGetResponse(ctx);
|
|
1581
1607
|
}
|
|
1582
1608
|
async function mapMultiPortalLayoutToUiLayoutForRolePermissionTargets(ctx, next) {
|
|
1583
|
-
var _a;
|
|
1584
1609
|
const portalRequest = await findRequestedMultiPortal(ctx);
|
|
1585
1610
|
if (portalRequest.requested && !portalRequest.portal) {
|
|
1586
1611
|
ctx.status = 200;
|
|
@@ -1588,22 +1613,19 @@ async function mapMultiPortalLayoutToUiLayoutForRolePermissionTargets(ctx, next)
|
|
|
1588
1613
|
return;
|
|
1589
1614
|
}
|
|
1590
1615
|
const scope = portalRequest.scope;
|
|
1591
|
-
if (
|
|
1592
|
-
if ((_a = ctx.action) == null ? void 0 : _a.params) {
|
|
1593
|
-
ctx.action.params.layout = scope.uiLayoutUid;
|
|
1594
|
-
}
|
|
1595
|
-
await next();
|
|
1596
|
-
return;
|
|
1597
|
-
}
|
|
1598
|
-
if ((scope == null ? void 0 : scope.relation) === "multiPortals") {
|
|
1616
|
+
if (scope) {
|
|
1599
1617
|
const routes = await ctx.db.getRepository("desktopRoutes").find({
|
|
1600
|
-
tree: true,
|
|
1601
1618
|
sort: "sort",
|
|
1602
1619
|
filter: scope.filter,
|
|
1603
1620
|
fields: [...DESKTOP_ROUTE_ROLE_PERMISSION_TARGET_FIELDS]
|
|
1604
1621
|
});
|
|
1622
|
+
const routeIds = /* @__PURE__ */ new Set();
|
|
1623
|
+
collectDesktopRouteStringIds(routes, routeIds);
|
|
1624
|
+
const routeTree = buildAccessibleDesktopRouteTreeWithAncestors(routes, routeIds);
|
|
1605
1625
|
ctx.status = 200;
|
|
1606
|
-
ctx.body =
|
|
1626
|
+
ctx.body = removeNestedRootDesktopRoutes(routeTree).map(
|
|
1627
|
+
(route) => pickDesktopRouteRolePermissionTargetFields(route)
|
|
1628
|
+
);
|
|
1607
1629
|
return;
|
|
1608
1630
|
}
|
|
1609
1631
|
await next();
|
|
@@ -2191,10 +2213,11 @@ async function listEnabledMultiPortals(ctx, next) {
|
|
|
2191
2213
|
const records = await ctx.db.getRepository("multiPortals").find({
|
|
2192
2214
|
filter: {
|
|
2193
2215
|
enabled: true,
|
|
2194
|
-
|
|
2216
|
+
uiLayoutUid: {
|
|
2217
|
+
$in: [...import_constants.MULTI_PORTAL_UI_LAYOUT_UIDS]
|
|
2218
|
+
}
|
|
2195
2219
|
},
|
|
2196
|
-
fields: [...
|
|
2197
|
-
appends: ["uiLayout"],
|
|
2220
|
+
fields: [...MULTI_PORTAL_RUNTIME_FIELDS],
|
|
2198
2221
|
sort: ["uid"]
|
|
2199
2222
|
});
|
|
2200
2223
|
ctx.body = records.map((record) => pickMultiPortalRuntimeFields(record));
|
|
@@ -2222,7 +2245,6 @@ async function findEnabledDefaultMultiPortal(ctx, transaction) {
|
|
|
2222
2245
|
isDefault: true
|
|
2223
2246
|
},
|
|
2224
2247
|
fields: [...DEFAULT_MULTI_PORTAL_RESPONSE_FIELDS, "uiLayoutUid"],
|
|
2225
|
-
appends: ["uiLayout"],
|
|
2226
2248
|
transaction
|
|
2227
2249
|
});
|
|
2228
2250
|
if (!record) {
|
|
@@ -2232,11 +2254,8 @@ async function findEnabledDefaultMultiPortal(ctx, transaction) {
|
|
|
2232
2254
|
if (!portalType) {
|
|
2233
2255
|
return null;
|
|
2234
2256
|
}
|
|
2235
|
-
if (
|
|
2236
|
-
|
|
2237
|
-
if (!uiLayout || uiLayout.get("enabled") !== true) {
|
|
2238
|
-
return null;
|
|
2239
|
-
}
|
|
2257
|
+
if (!(0, import_constants.isMultiPortalUiLayoutUid)(record.get("uiLayoutUid"))) {
|
|
2258
|
+
return null;
|
|
2240
2259
|
}
|
|
2241
2260
|
return record;
|
|
2242
2261
|
}
|
|
@@ -2274,21 +2293,9 @@ async function setDefaultMultiPortal(ctx, next) {
|
|
|
2274
2293
|
ctx.throw(400, ctx.t("Unsupported Portal type cannot be set as default", { ns: import_constants.NAMESPACE }));
|
|
2275
2294
|
return null;
|
|
2276
2295
|
}
|
|
2277
|
-
if (
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
filter: {
|
|
2281
|
-
uid: uiLayoutUid,
|
|
2282
|
-
enabled: true
|
|
2283
|
-
},
|
|
2284
|
-
fields: ["uid"],
|
|
2285
|
-
lock: transaction.LOCK.UPDATE,
|
|
2286
|
-
transaction
|
|
2287
|
-
}) : null;
|
|
2288
|
-
if (!uiLayout) {
|
|
2289
|
-
ctx.throw(400, ctx.t("Portal layout must be enabled before setting it as default", { ns: import_constants.NAMESPACE }));
|
|
2290
|
-
return null;
|
|
2291
|
-
}
|
|
2296
|
+
if (!(0, import_constants.isMultiPortalUiLayoutUid)(target.get("uiLayoutUid"))) {
|
|
2297
|
+
ctx.throw(400, ctx.t("Portal device configuration is invalid", { ns: import_constants.NAMESPACE }));
|
|
2298
|
+
return null;
|
|
2292
2299
|
}
|
|
2293
2300
|
await repository.update({
|
|
2294
2301
|
filter: { isDefault: true },
|
|
@@ -2314,10 +2321,11 @@ async function listAccessibleMultiPortals(ctx, next) {
|
|
|
2314
2321
|
const records = await ctx.db.getRepository("multiPortals").find({
|
|
2315
2322
|
filter: {
|
|
2316
2323
|
enabled: true,
|
|
2317
|
-
|
|
2324
|
+
uiLayoutUid: {
|
|
2325
|
+
$in: [...import_constants.MULTI_PORTAL_UI_LAYOUT_UIDS]
|
|
2326
|
+
}
|
|
2318
2327
|
},
|
|
2319
|
-
fields: [...
|
|
2320
|
-
appends: ["uiLayout"],
|
|
2328
|
+
fields: [...MULTI_PORTAL_ACCESSIBLE_FIELDS],
|
|
2321
2329
|
sort: ["uid"]
|
|
2322
2330
|
});
|
|
2323
2331
|
const accessiblePortalUidSet = Array.isArray(accessiblePortalUids) ? new Set(accessiblePortalUids) : void 0;
|
|
@@ -2461,6 +2469,9 @@ class PluginMultiPortalServer extends import_server.Plugin {
|
|
|
2461
2469
|
getAppName() {
|
|
2462
2470
|
return this.app.name || MAIN_APP_NAME;
|
|
2463
2471
|
}
|
|
2472
|
+
getCurrentStorageAppName() {
|
|
2473
|
+
return normalizePortalStorageName(this.getAppName()) || MAIN_APP_NAME;
|
|
2474
|
+
}
|
|
2464
2475
|
getMultiPortalStorageItem(multiPortal, previous = false) {
|
|
2465
2476
|
const record = multiPortal;
|
|
2466
2477
|
const readField = (field) => previous && typeof record.previous === "function" ? record.previous(field) : getRecordField(record, field);
|
|
@@ -2475,8 +2486,7 @@ class PluginMultiPortalServer extends import_server.Plugin {
|
|
|
2475
2486
|
return {
|
|
2476
2487
|
appName: this.getAppName(),
|
|
2477
2488
|
portalName,
|
|
2478
|
-
enabled: readField("enabled") === true
|
|
2479
|
-
config: getPortalStorageConfig(readField("options"))
|
|
2489
|
+
enabled: readField("enabled") === true
|
|
2480
2490
|
};
|
|
2481
2491
|
}
|
|
2482
2492
|
warnPortalStorageSyncFailed(error) {
|
|
@@ -2549,8 +2559,6 @@ class PluginMultiPortalServer extends import_server.Plugin {
|
|
|
2549
2559
|
await copyPortalTemplate(template.dir, portalDir);
|
|
2550
2560
|
await appendPortalStorageLog(logPath, `Default portal template copied to ${portalDir}.`);
|
|
2551
2561
|
}
|
|
2552
|
-
await ensurePortalStorageConfigFiles(portalDir, item);
|
|
2553
|
-
await appendPortalStorageLog(logPath, `Portal configuration files updated in ${portalDir}.`);
|
|
2554
2562
|
if (item.enabled) {
|
|
2555
2563
|
this.logPortalBuildHtml(item, "requested", "storage directory was initialized");
|
|
2556
2564
|
await buildPortalStorageItem(portalDir, item);
|
|
@@ -2558,8 +2566,6 @@ class PluginMultiPortalServer extends import_server.Plugin {
|
|
|
2558
2566
|
return;
|
|
2559
2567
|
}
|
|
2560
2568
|
this.logPortalBuildHtml(item, "skipped", "the portal is disabled");
|
|
2561
|
-
await this.removePortalStorageIndexHtml(item);
|
|
2562
|
-
await appendPortalStorageLog(logPath, `Portal index.html removed for ${item.appName}/${item.portalName}.`);
|
|
2563
2569
|
} catch (error) {
|
|
2564
2570
|
await appendPortalStorageLog(
|
|
2565
2571
|
logPath,
|
|
@@ -2584,7 +2590,6 @@ class PluginMultiPortalServer extends import_server.Plugin {
|
|
|
2584
2590
|
await this.schedulePortalTemplateCopyAndBuild(item, template, portalDir);
|
|
2585
2591
|
return;
|
|
2586
2592
|
}
|
|
2587
|
-
await ensurePortalStorageConfigFiles(portalDir, item);
|
|
2588
2593
|
if (item.enabled) {
|
|
2589
2594
|
const hasPortalIndex = await pathExists(portalIndex);
|
|
2590
2595
|
if (options.forceBuild || !hasPortalIndex) {
|
|
@@ -2601,14 +2606,12 @@ class PluginMultiPortalServer extends import_server.Plugin {
|
|
|
2601
2606
|
return;
|
|
2602
2607
|
}
|
|
2603
2608
|
this.logPortalBuildHtml(item, "skipped", "the portal is disabled");
|
|
2604
|
-
await this.removePortalStorageIndexHtml(item);
|
|
2605
|
-
await appendPortalStorageLog(logPath, `Portal index.html removed for ${item.appName}/${item.portalName}.`);
|
|
2606
2609
|
}
|
|
2607
2610
|
async syncMultiPortalStorageItem(multiPortal, options, syncPrevious = false, forceBuild = false) {
|
|
2608
2611
|
const currentItem = this.getMultiPortalStorageItem(multiPortal);
|
|
2609
2612
|
const previousItem = syncPrevious ? this.getMultiPortalStorageItem(multiPortal, true) : null;
|
|
2610
2613
|
await this.runPortalStorageTask(async () => {
|
|
2611
|
-
if (previousItem && (!currentItem || previousItem.appName !== currentItem.appName || previousItem.portalName !== currentItem.portalName
|
|
2614
|
+
if (previousItem && (!currentItem || previousItem.appName !== currentItem.appName || previousItem.portalName !== currentItem.portalName)) {
|
|
2612
2615
|
await this.removePortalStorageIndexHtml(previousItem);
|
|
2613
2616
|
}
|
|
2614
2617
|
if (currentItem) {
|
|
@@ -2655,12 +2658,12 @@ class PluginMultiPortalServer extends import_server.Plugin {
|
|
|
2655
2658
|
await next();
|
|
2656
2659
|
}
|
|
2657
2660
|
async deployPortalDist(ctx, next) {
|
|
2658
|
-
var _a, _b, _c
|
|
2661
|
+
var _a, _b, _c;
|
|
2659
2662
|
const deployCtx = ctx;
|
|
2660
|
-
const appName =
|
|
2661
|
-
const portalName = normalizePortalStorageName((
|
|
2662
|
-
const basePath = trimString((
|
|
2663
|
-
const filePath = trimString((
|
|
2663
|
+
const appName = this.getCurrentStorageAppName();
|
|
2664
|
+
const portalName = normalizePortalStorageName((_a = deployCtx.request.body) == null ? void 0 : _a.portal);
|
|
2665
|
+
const basePath = trimString((_b = deployCtx.request.body) == null ? void 0 : _b.basePath);
|
|
2666
|
+
const filePath = trimString((_c = deployCtx.request.file) == null ? void 0 : _c.path);
|
|
2664
2667
|
try {
|
|
2665
2668
|
if (!isValidPortalDeploySegment(appName)) {
|
|
2666
2669
|
throw new Error("Invalid app");
|
|
@@ -2697,9 +2700,9 @@ class PluginMultiPortalServer extends import_server.Plugin {
|
|
|
2697
2700
|
}
|
|
2698
2701
|
}
|
|
2699
2702
|
async pullPortalSource(ctx, next) {
|
|
2700
|
-
var _a
|
|
2701
|
-
const appName =
|
|
2702
|
-
const portalName = normalizePortalStorageName((
|
|
2703
|
+
var _a;
|
|
2704
|
+
const appName = this.getCurrentStorageAppName();
|
|
2705
|
+
const portalName = normalizePortalStorageName((_a = ctx.action.params.values) == null ? void 0 : _a.portal);
|
|
2703
2706
|
try {
|
|
2704
2707
|
if (!isValidPortalDeploySegment(appName)) {
|
|
2705
2708
|
throw new Error("Invalid app");
|
|
@@ -2719,11 +2722,11 @@ class PluginMultiPortalServer extends import_server.Plugin {
|
|
|
2719
2722
|
}
|
|
2720
2723
|
}
|
|
2721
2724
|
async pushPortalSource(ctx, next) {
|
|
2722
|
-
var _a, _b
|
|
2725
|
+
var _a, _b;
|
|
2723
2726
|
const sourceCtx = ctx;
|
|
2724
|
-
const appName =
|
|
2725
|
-
const portalName = normalizePortalStorageName((
|
|
2726
|
-
const filePath = trimString((
|
|
2727
|
+
const appName = this.getCurrentStorageAppName();
|
|
2728
|
+
const portalName = normalizePortalStorageName((_a = sourceCtx.request.body) == null ? void 0 : _a.portal);
|
|
2729
|
+
const filePath = trimString((_b = sourceCtx.request.file) == null ? void 0 : _b.path);
|
|
2727
2730
|
try {
|
|
2728
2731
|
if (!isValidPortalDeploySegment(appName)) {
|
|
2729
2732
|
throw new Error("Invalid app");
|
|
@@ -2777,38 +2780,20 @@ class PluginMultiPortalServer extends import_server.Plugin {
|
|
|
2777
2780
|
const records = await this.db.getRepository("multiPortals").find({
|
|
2778
2781
|
filter: {
|
|
2779
2782
|
enabled: true,
|
|
2780
|
-
|
|
2783
|
+
uiLayoutUid: {
|
|
2784
|
+
$in: [...import_constants.MULTI_PORTAL_UI_LAYOUT_UIDS]
|
|
2785
|
+
}
|
|
2781
2786
|
},
|
|
2782
|
-
fields: [...
|
|
2783
|
-
appends: ["uiLayout"],
|
|
2787
|
+
fields: [...MULTI_PORTAL_ACCESSIBLE_FIELDS],
|
|
2784
2788
|
sort: ["uid"],
|
|
2785
2789
|
transaction: options == null ? void 0 : options.transaction
|
|
2786
2790
|
});
|
|
2787
|
-
return records.
|
|
2788
|
-
const
|
|
2789
|
-
|
|
2790
|
-
const uid = typeof portal.uid === "string" ? portal.uid : "";
|
|
2791
|
-
const title = typeof portal.title === "string" ? portal.title : "";
|
|
2792
|
-
return {
|
|
2793
|
-
uid,
|
|
2794
|
-
title,
|
|
2795
|
-
icon: typeof portal.icon === "string" ? portal.icon : null,
|
|
2796
|
-
portalType: typeof portal.portalType === "string" ? portal.portalType : null,
|
|
2797
|
-
routePath: String(portal.routePath || ""),
|
|
2798
|
-
layout: typeof (uiLayout == null ? void 0 : uiLayout.layoutType) === "string" ? uiLayout.layoutType : null
|
|
2799
|
-
};
|
|
2800
|
-
});
|
|
2801
|
-
}
|
|
2802
|
-
async getUiLayout(uid, options) {
|
|
2803
|
-
if (typeof uid !== "string" || !uid) {
|
|
2804
|
-
return null;
|
|
2805
|
-
}
|
|
2806
|
-
return this.db.getRepository("uiLayouts").findOne({
|
|
2807
|
-
filterByTk: uid,
|
|
2808
|
-
transaction: options == null ? void 0 : options.transaction
|
|
2791
|
+
return records.flatMap((record) => {
|
|
2792
|
+
const item = this.toAppPortalManifestItem(record);
|
|
2793
|
+
return item ? [item] : [];
|
|
2809
2794
|
});
|
|
2810
2795
|
}
|
|
2811
|
-
|
|
2796
|
+
toAppPortalManifestItem(multiPortal) {
|
|
2812
2797
|
const uid = getRecordField(multiPortal, "uid");
|
|
2813
2798
|
const title = getRecordField(multiPortal, "title");
|
|
2814
2799
|
const portalType = getRecordField(multiPortal, "portalType");
|
|
@@ -2818,19 +2803,18 @@ class PluginMultiPortalServer extends import_server.Plugin {
|
|
|
2818
2803
|
return null;
|
|
2819
2804
|
}
|
|
2820
2805
|
const uiLayoutUid = getRecordField(multiPortal, "uiLayoutUid");
|
|
2821
|
-
const
|
|
2822
|
-
if (!
|
|
2806
|
+
const layout = (0, import_constants.getMultiPortalLayoutType)(uiLayoutUid);
|
|
2807
|
+
if (!layout) {
|
|
2823
2808
|
return null;
|
|
2824
2809
|
}
|
|
2825
2810
|
const icon = getRecordField(multiPortal, "icon");
|
|
2826
|
-
const layoutType = getRecordField(uiLayout, "layoutType");
|
|
2827
2811
|
return {
|
|
2828
2812
|
uid,
|
|
2829
2813
|
title,
|
|
2830
2814
|
icon: typeof icon === "string" ? icon : null,
|
|
2831
2815
|
portalType: typeof portalType === "string" ? portalType : null,
|
|
2832
2816
|
routePath,
|
|
2833
|
-
layout
|
|
2817
|
+
layout
|
|
2834
2818
|
};
|
|
2835
2819
|
}
|
|
2836
2820
|
async setAppManifestItem(item, options) {
|
|
@@ -2873,30 +2857,13 @@ class PluginMultiPortalServer extends import_server.Plugin {
|
|
|
2873
2857
|
if (typeof uid !== "string" || !uid) {
|
|
2874
2858
|
return;
|
|
2875
2859
|
}
|
|
2876
|
-
const item =
|
|
2860
|
+
const item = this.toAppPortalManifestItem(multiPortal);
|
|
2877
2861
|
if (item) {
|
|
2878
2862
|
await this.setAppManifestItem(item, options);
|
|
2879
2863
|
return;
|
|
2880
2864
|
}
|
|
2881
2865
|
await this.removeAppManifestItem(uid, options);
|
|
2882
2866
|
}
|
|
2883
|
-
async publishUiLayoutManifestItems(uiLayout, options) {
|
|
2884
|
-
const uiLayoutUid = getRecordField(uiLayout, "uid");
|
|
2885
|
-
if (typeof uiLayoutUid !== "string" || !uiLayoutUid) {
|
|
2886
|
-
return;
|
|
2887
|
-
}
|
|
2888
|
-
const records = await this.db.getRepository("multiPortals").find({
|
|
2889
|
-
filter: {
|
|
2890
|
-
uiLayoutUid
|
|
2891
|
-
},
|
|
2892
|
-
fields: [...MULTI_PORTAL_ACCESSIBLE_QUERY_FIELDS],
|
|
2893
|
-
transaction: options == null ? void 0 : options.transaction
|
|
2894
|
-
});
|
|
2895
|
-
for (const record of records) {
|
|
2896
|
-
record.set("uiLayout", uiLayout);
|
|
2897
|
-
await this.publishAppManifestItem(record, options);
|
|
2898
|
-
}
|
|
2899
|
-
}
|
|
2900
2867
|
async reconcilePortalStorage(options) {
|
|
2901
2868
|
const records = await this.db.getRepository("multiPortals").find({
|
|
2902
2869
|
filter: {
|
|
@@ -2960,15 +2927,16 @@ class PluginMultiPortalServer extends import_server.Plugin {
|
|
|
2960
2927
|
mapMultiPortalLayoutToUiLayoutForRolePermissionTargets
|
|
2961
2928
|
);
|
|
2962
2929
|
this.app.resourceManager.registerPreActionHandler("multiPortals:create", preventDirectDefaultPortalMutation);
|
|
2930
|
+
this.app.resourceManager.registerPreActionHandler("multiPortals:create", validateMultiPortalUiLayoutUidWrite);
|
|
2963
2931
|
this.app.resourceManager.registerPreActionHandler("multiPortals:create", captureSkipCreatePortalDirectory);
|
|
2964
2932
|
this.app.resourceManager.registerPreActionHandler("multiPortals:create", normalizeMultiPortalSlugValues);
|
|
2965
2933
|
this.app.resourceManager.registerPreActionHandler("multiPortals:update", preventDirectDefaultPortalMutation);
|
|
2966
|
-
this.app.resourceManager.registerPreActionHandler("multiPortals:update",
|
|
2934
|
+
this.app.resourceManager.registerPreActionHandler("multiPortals:update", validateMultiPortalUiLayoutUidWrite);
|
|
2967
2935
|
this.app.resourceManager.registerPreActionHandler("multiPortals:update", normalizeMultiPortalSlugValues);
|
|
2968
2936
|
this.app.resourceManager.registerPreActionHandler("multiPortals:firstOrCreate", preventDirectDefaultPortalMutation);
|
|
2969
2937
|
this.app.resourceManager.registerPreActionHandler(
|
|
2970
2938
|
"multiPortals:firstOrCreate",
|
|
2971
|
-
|
|
2939
|
+
validateMultiPortalUiLayoutUidWrite
|
|
2972
2940
|
);
|
|
2973
2941
|
this.app.resourceManager.registerPreActionHandler("multiPortals:firstOrCreate", captureSkipCreatePortalDirectory);
|
|
2974
2942
|
this.app.resourceManager.registerPreActionHandler("multiPortals:firstOrCreate", normalizeMultiPortalSlugValues);
|
|
@@ -2978,7 +2946,7 @@ class PluginMultiPortalServer extends import_server.Plugin {
|
|
|
2978
2946
|
);
|
|
2979
2947
|
this.app.resourceManager.registerPreActionHandler(
|
|
2980
2948
|
"multiPortals:updateOrCreate",
|
|
2981
|
-
|
|
2949
|
+
validateMultiPortalUiLayoutUidWrite
|
|
2982
2950
|
);
|
|
2983
2951
|
this.app.resourceManager.registerPreActionHandler("multiPortals:updateOrCreate", captureSkipCreatePortalDirectory);
|
|
2984
2952
|
this.app.resourceManager.registerPreActionHandler("multiPortals:updateOrCreate", normalizeMultiPortalSlugValues);
|
|
@@ -3063,9 +3031,6 @@ class PluginMultiPortalServer extends import_server.Plugin {
|
|
|
3063
3031
|
}
|
|
3064
3032
|
await this.removeMultiPortalStorageItem(multiPortal, options);
|
|
3065
3033
|
});
|
|
3066
|
-
this.app.db.on("uiLayouts.afterUpdate", async (uiLayout, options) => {
|
|
3067
|
-
await this.publishUiLayoutManifestItems(uiLayout, options);
|
|
3068
|
-
});
|
|
3069
3034
|
}
|
|
3070
3035
|
async install() {
|
|
3071
3036
|
const version = await this.app.version.get();
|