@nocobase/plugin-flow-engine 2.1.31 → 2.2.0-alpha.10
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/dist/ai/ai-employees/nathan/skills/frontend-developer/tools/getContextApis.js +2 -2
- package/dist/ai/ai-employees/nathan/skills/frontend-developer/tools/getContextEnvs.js +2 -2
- package/dist/ai/ai-employees/nathan/skills/frontend-developer/tools/getContextVars.js +2 -2
- package/dist/ai/ai-employees/nathan/skills/frontend-developer/tools/lintAndTestJS.js +2 -2
- package/dist/ai/ai-employees/nathan/skills/frontend-developer/tools/patchJSCode.js +2 -2
- package/dist/ai/ai-employees/nathan/skills/frontend-developer/tools/readJSCode.js +2 -2
- package/dist/ai/ai-employees/nathan/skills/frontend-developer/tools/writeJSCode.js +2 -2
- package/dist/ai/docs/runjs/context/ai.md +206 -0
- package/dist/externalVersion.js +9 -9
- package/dist/node_modules/@ant-design/icons-svg/package.json +1 -1
- package/dist/node_modules/acorn/package.json +1 -1
- package/dist/node_modules/acorn-jsx/package.json +1 -1
- package/dist/node_modules/acorn-walk/package.json +1 -1
- package/dist/node_modules/ses/package.json +1 -1
- package/dist/node_modules/zod/package.json +1 -1
- package/dist/server/flow-surfaces/authoring-validation.d.ts +3 -1
- package/dist/server/flow-surfaces/authoring-validation.js +30 -10
- package/dist/server/flow-surfaces/blueprint/compile-plan.js +23 -15
- package/dist/server/flow-surfaces/blueprint/normalize-document.js +18 -1
- package/dist/server/flow-surfaces/blueprint/public-types.d.ts +2 -0
- package/dist/server/flow-surfaces/builder.js +24 -4
- package/dist/server/flow-surfaces/constants.d.ts +9 -2
- package/dist/server/flow-surfaces/constants.js +1 -0
- package/dist/server/flow-surfaces/errors.d.ts +2 -2
- package/dist/server/flow-surfaces/errors.js +4 -4
- package/dist/server/flow-surfaces/navigation-targets.d.ts +73 -0
- package/dist/server/flow-surfaces/navigation-targets.js +439 -0
- package/dist/server/flow-surfaces/runjs-authoring/rules.js +0 -2
- package/dist/server/flow-surfaces/runjs-authoring/runtime/constants.d.ts +0 -1
- package/dist/server/flow-surfaces/runjs-authoring/runtime/constants.js +12 -19
- package/dist/server/flow-surfaces/runjs-authoring/runtime/types.d.ts +0 -12
- package/dist/server/flow-surfaces/runjs-authoring/scan/index.d.ts +0 -14
- package/dist/server/flow-surfaces/runjs-authoring/scan/index.js +1 -7
- package/dist/server/flow-surfaces/runjs-authoring/scan/source-patterns.d.ts +0 -14
- package/dist/server/flow-surfaces/runjs-authoring/scan/source-patterns.js +18 -73
- package/dist/server/flow-surfaces/runjs-authoring/types.d.ts +1 -1
- package/dist/server/flow-surfaces/runjs-authoring/validators/index.js +9 -53
- package/dist/server/flow-surfaces/service.d.ts +31 -0
- package/dist/server/flow-surfaces/service.js +749 -53
- package/dist/swagger/flow-surfaces.d.ts +108 -0
- package/dist/swagger/flow-surfaces.js +101 -8
- package/dist/swagger/index.d.ts +108 -0
- package/package.json +2 -2
- package/dist/server/flow-surfaces/runjs-authoring/blocked-global-stop/index.d.ts +0 -10
- package/dist/server/flow-surfaces/runjs-authoring/blocked-global-stop/index.js +0 -40
|
@@ -66,6 +66,7 @@ var import_runtime = require("./planning/runtime");
|
|
|
66
66
|
var import_created_keys = require("./planning/created-keys");
|
|
67
67
|
var import_key_persistence = require("./planning/key-persistence");
|
|
68
68
|
var import_payload_shape = require("./payload-shape");
|
|
69
|
+
var import_navigation_targets = require("./navigation-targets");
|
|
69
70
|
var import_field_semantics = require("./field-semantics");
|
|
70
71
|
var import_field_grid_layout = require("./field-grid-layout");
|
|
71
72
|
var import_authoring_validation = require("./authoring-validation");
|
|
@@ -689,6 +690,7 @@ function assertNoFlowSurfaceIdTitleFieldSettings(value, options = {}) {
|
|
|
689
690
|
};
|
|
690
691
|
visit(value, options.basePath || []);
|
|
691
692
|
}
|
|
693
|
+
const MOBILE_UI_LAYOUT_TYPE = "mobile";
|
|
692
694
|
class FlowSurfacesService {
|
|
693
695
|
constructor(plugin) {
|
|
694
696
|
this.plugin = plugin;
|
|
@@ -709,6 +711,9 @@ class FlowSurfacesService {
|
|
|
709
711
|
(values, options) => this.patchFlowSurfaceModelOptions(values, options)
|
|
710
712
|
);
|
|
711
713
|
}
|
|
714
|
+
get navigationTargets() {
|
|
715
|
+
return new import_navigation_targets.FlowSurfaceNavigationTargetsService(this.db);
|
|
716
|
+
}
|
|
712
717
|
getFlowTemplateRepository(actionName) {
|
|
713
718
|
try {
|
|
714
719
|
const repo = this.db.getRepository("flowModelTemplates");
|
|
@@ -922,12 +927,12 @@ class FlowSurfacesService {
|
|
|
922
927
|
transaction
|
|
923
928
|
});
|
|
924
929
|
}
|
|
925
|
-
async findMenuGroupRoutesByTitle(title, transaction) {
|
|
930
|
+
async findMenuGroupRoutesByTitle(title, transaction, layoutUid, portalUid) {
|
|
926
931
|
const normalizedTitle = String(title || "").trim();
|
|
927
932
|
if (!normalizedTitle) {
|
|
928
933
|
return [];
|
|
929
934
|
}
|
|
930
|
-
|
|
935
|
+
const routes = import_lodash.default.castArray(
|
|
931
936
|
await this.db.getRepository("desktopRoutes").find({
|
|
932
937
|
filter: {
|
|
933
938
|
type: "group",
|
|
@@ -936,6 +941,32 @@ class FlowSurfacesService {
|
|
|
936
941
|
transaction
|
|
937
942
|
})
|
|
938
943
|
);
|
|
944
|
+
const normalizedPortalUid = this.navigationTargets.normalizePortalUid(portalUid);
|
|
945
|
+
if (normalizedPortalUid) {
|
|
946
|
+
const matchedRoutes2 = [];
|
|
947
|
+
for (const route of routes) {
|
|
948
|
+
const routePortalUids = await this.navigationTargets.readRoutePortalUids(
|
|
949
|
+
this.readRouteField(route, "id"),
|
|
950
|
+
transaction
|
|
951
|
+
);
|
|
952
|
+
if (routePortalUids.includes(normalizedPortalUid)) {
|
|
953
|
+
matchedRoutes2.push(route);
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
return matchedRoutes2;
|
|
957
|
+
}
|
|
958
|
+
const layoutUidFilter = await this.resolveDesktopRouteLayoutUidFilter(layoutUid, transaction);
|
|
959
|
+
if (!layoutUidFilter.length || !this.hasDesktopRouteUiLayoutsRelation()) {
|
|
960
|
+
return routes;
|
|
961
|
+
}
|
|
962
|
+
const matchedRoutes = [];
|
|
963
|
+
for (const route of routes) {
|
|
964
|
+
const routeLayoutUids = await this.readDesktopRouteUiLayoutUids(this.readRouteField(route, "id"), transaction);
|
|
965
|
+
if (import_lodash.default.intersection(routeLayoutUids, layoutUidFilter).length) {
|
|
966
|
+
matchedRoutes.push(route);
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
return matchedRoutes;
|
|
939
970
|
}
|
|
940
971
|
routeParentIdMatches(routeParentId, parentId) {
|
|
941
972
|
if (import_lodash.default.isNil(routeParentId) && import_lodash.default.isNil(parentId)) {
|
|
@@ -943,28 +974,58 @@ class FlowSurfacesService {
|
|
|
943
974
|
}
|
|
944
975
|
return String(routeParentId ?? "") === String(parentId ?? "");
|
|
945
976
|
}
|
|
946
|
-
async findMenuGroupRoutesByParentIdAndTitle(parentId, title, transaction) {
|
|
947
|
-
const routes = await this.findMenuGroupRoutesByTitle(title, transaction);
|
|
977
|
+
async findMenuGroupRoutesByParentIdAndTitle(parentId, title, transaction, layoutUid, portalUid) {
|
|
978
|
+
const routes = await this.findMenuGroupRoutesByTitle(title, transaction, layoutUid, portalUid);
|
|
948
979
|
return routes.filter(
|
|
949
980
|
(route) => this.routeParentIdMatches(this.readRouteField(route, "parentId") ?? null, parentId)
|
|
950
981
|
);
|
|
951
982
|
}
|
|
952
|
-
async findFlowPageRoutesByParentIdAndTitle(parentId, title, transaction) {
|
|
983
|
+
async findFlowPageRoutesByParentIdAndTitle(parentId, title, transaction, layoutUid, portalUid) {
|
|
953
984
|
const normalizedTitle = String(title || "").trim();
|
|
954
|
-
|
|
955
|
-
if (!normalizedTitle || !normalizedParentId) {
|
|
985
|
+
if (!normalizedTitle) {
|
|
956
986
|
return [];
|
|
957
987
|
}
|
|
958
|
-
|
|
988
|
+
const routes = import_lodash.default.castArray(
|
|
959
989
|
await this.db.getRepository("desktopRoutes").find({
|
|
960
|
-
filter: {
|
|
990
|
+
filter: (0, import_service_utils.buildDefinedPayload)({
|
|
961
991
|
type: "flowPage",
|
|
962
992
|
title: normalizedTitle,
|
|
963
|
-
parentId:
|
|
964
|
-
},
|
|
993
|
+
parentId: import_lodash.default.isNil(parentId) ? void 0 : String(parentId)
|
|
994
|
+
}),
|
|
965
995
|
transaction
|
|
966
996
|
})
|
|
967
997
|
);
|
|
998
|
+
const normalizedPortalUid = this.navigationTargets.normalizePortalUid(portalUid);
|
|
999
|
+
if (normalizedPortalUid) {
|
|
1000
|
+
const portalMatchedRoutes = [];
|
|
1001
|
+
for (const route of routes) {
|
|
1002
|
+
const routePortalUids = await this.navigationTargets.readRoutePortalUids(
|
|
1003
|
+
this.readRouteField(route, "id"),
|
|
1004
|
+
transaction
|
|
1005
|
+
);
|
|
1006
|
+
if (routePortalUids.includes(normalizedPortalUid)) {
|
|
1007
|
+
portalMatchedRoutes.push(route);
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
return portalMatchedRoutes.filter(
|
|
1011
|
+
(route) => this.routeParentIdMatches(this.readRouteField(route, "parentId") ?? null, parentId)
|
|
1012
|
+
);
|
|
1013
|
+
}
|
|
1014
|
+
const layoutUidFilter = await this.resolveDesktopRouteLayoutUidFilter(layoutUid, transaction);
|
|
1015
|
+
const layoutMatchedRoutes = [];
|
|
1016
|
+
if (!layoutUidFilter.length || !this.hasDesktopRouteUiLayoutsRelation()) {
|
|
1017
|
+
layoutMatchedRoutes.push(...routes);
|
|
1018
|
+
} else {
|
|
1019
|
+
for (const route of routes) {
|
|
1020
|
+
const routeLayoutUids = await this.readDesktopRouteUiLayoutUids(this.readRouteField(route, "id"), transaction);
|
|
1021
|
+
if (import_lodash.default.intersection(routeLayoutUids, layoutUidFilter).length) {
|
|
1022
|
+
layoutMatchedRoutes.push(route);
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
return layoutMatchedRoutes.filter(
|
|
1027
|
+
(route) => this.routeParentIdMatches(this.readRouteField(route, "parentId") ?? null, parentId)
|
|
1028
|
+
);
|
|
968
1029
|
}
|
|
969
1030
|
async assertMenuParentIsGroup(parentMenuRouteId, transaction) {
|
|
970
1031
|
if (import_lodash.default.isNil(parentMenuRouteId)) {
|
|
@@ -1030,6 +1091,380 @@ class FlowSurfacesService {
|
|
|
1030
1091
|
...extras
|
|
1031
1092
|
};
|
|
1032
1093
|
}
|
|
1094
|
+
hasDesktopRouteUiLayoutsRelation() {
|
|
1095
|
+
var _a, _b;
|
|
1096
|
+
try {
|
|
1097
|
+
return !!this.db.getCollection("uiLayouts") && !!((_b = (_a = this.db.getCollection("desktopRoutes")) == null ? void 0 : _a.getField) == null ? void 0 : _b.call(_a, "uiLayouts"));
|
|
1098
|
+
} catch (error) {
|
|
1099
|
+
return false;
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
normalizeDesktopRouteRelationId(routeId) {
|
|
1103
|
+
return import_lodash.default.isNil(routeId) ? void 0 : routeId;
|
|
1104
|
+
}
|
|
1105
|
+
async readDesktopRouteUiLayoutUids(routeId, transaction) {
|
|
1106
|
+
const relationRouteId = this.normalizeDesktopRouteRelationId(routeId);
|
|
1107
|
+
if (import_lodash.default.isUndefined(relationRouteId) || !this.hasDesktopRouteUiLayoutsRelation()) {
|
|
1108
|
+
return [];
|
|
1109
|
+
}
|
|
1110
|
+
const uiLayouts = await this.db.getRepository("desktopRoutes.uiLayouts", relationRouteId).find({
|
|
1111
|
+
fields: ["uid"],
|
|
1112
|
+
transaction
|
|
1113
|
+
});
|
|
1114
|
+
return import_lodash.default.uniq(
|
|
1115
|
+
uiLayouts.map((uiLayout) => {
|
|
1116
|
+
var _a;
|
|
1117
|
+
return String(((_a = uiLayout == null ? void 0 : uiLayout.get) == null ? void 0 : _a.call(uiLayout, "uid")) || (uiLayout == null ? void 0 : uiLayout.uid) || "").trim();
|
|
1118
|
+
}).filter(Boolean)
|
|
1119
|
+
);
|
|
1120
|
+
}
|
|
1121
|
+
async resolveDefaultDesktopRouteUiLayoutUids(transaction) {
|
|
1122
|
+
if (!this.hasDesktopRouteUiLayoutsRelation()) {
|
|
1123
|
+
return [];
|
|
1124
|
+
}
|
|
1125
|
+
const defaultLayout = await this.db.getRepository("uiLayouts").findOne({
|
|
1126
|
+
filter: {
|
|
1127
|
+
uid: import_navigation_targets.DEFAULT_ADMIN_UI_LAYOUT_UID,
|
|
1128
|
+
enabled: true
|
|
1129
|
+
},
|
|
1130
|
+
transaction
|
|
1131
|
+
});
|
|
1132
|
+
return defaultLayout ? [import_navigation_targets.DEFAULT_ADMIN_UI_LAYOUT_UID] : [];
|
|
1133
|
+
}
|
|
1134
|
+
async findDesktopRouteUiLayoutByUid(layoutUid, transaction) {
|
|
1135
|
+
const normalizedLayoutUid = this.normalizeExplicitDesktopRouteLayoutUid(layoutUid);
|
|
1136
|
+
if (!normalizedLayoutUid || !this.hasDesktopRouteUiLayoutsRelation()) {
|
|
1137
|
+
return null;
|
|
1138
|
+
}
|
|
1139
|
+
return this.db.getRepository("uiLayouts").findOne({
|
|
1140
|
+
filter: {
|
|
1141
|
+
uid: normalizedLayoutUid
|
|
1142
|
+
},
|
|
1143
|
+
transaction
|
|
1144
|
+
});
|
|
1145
|
+
}
|
|
1146
|
+
async getDesktopRouteUiLayoutTypeByUid(layoutUid, transaction) {
|
|
1147
|
+
var _a;
|
|
1148
|
+
const uiLayout = await this.findDesktopRouteUiLayoutByUid(layoutUid, transaction);
|
|
1149
|
+
return String(((_a = uiLayout == null ? void 0 : uiLayout.get) == null ? void 0 : _a.call(uiLayout, "layoutType")) || (uiLayout == null ? void 0 : uiLayout.layoutType) || "").trim() || void 0;
|
|
1150
|
+
}
|
|
1151
|
+
async isMobileDesktopRouteUiLayoutUid(layoutUid, transaction) {
|
|
1152
|
+
if (!layoutUid) {
|
|
1153
|
+
return false;
|
|
1154
|
+
}
|
|
1155
|
+
return await this.getDesktopRouteUiLayoutTypeByUid(layoutUid, transaction) === MOBILE_UI_LAYOUT_TYPE;
|
|
1156
|
+
}
|
|
1157
|
+
async resolveInheritedDesktopRouteUiLayoutUids(parentRoute, transaction) {
|
|
1158
|
+
const parentRouteId = this.readRouteField(parentRoute, "id");
|
|
1159
|
+
if (!import_lodash.default.isNil(parentRouteId)) {
|
|
1160
|
+
const parentLayoutUids = await this.readDesktopRouteUiLayoutUids(parentRouteId, transaction);
|
|
1161
|
+
if (parentLayoutUids.length) {
|
|
1162
|
+
return parentLayoutUids;
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
return this.resolveDefaultDesktopRouteUiLayoutUids(transaction);
|
|
1166
|
+
}
|
|
1167
|
+
normalizeExplicitDesktopRouteLayoutUid(value) {
|
|
1168
|
+
const normalized = String(value || "").trim();
|
|
1169
|
+
return normalized || void 0;
|
|
1170
|
+
}
|
|
1171
|
+
normalizeDesktopRouteLayoutUidFilter(value) {
|
|
1172
|
+
return import_lodash.default.uniq(
|
|
1173
|
+
import_lodash.default.castArray(value).map((item) => this.normalizeExplicitDesktopRouteLayoutUid(item)).filter(Boolean)
|
|
1174
|
+
);
|
|
1175
|
+
}
|
|
1176
|
+
async resolveDesktopRouteLayoutUidFilter(value, transaction) {
|
|
1177
|
+
const explicitLayoutUids = this.normalizeDesktopRouteLayoutUidFilter(value);
|
|
1178
|
+
if (explicitLayoutUids.length) {
|
|
1179
|
+
return explicitLayoutUids;
|
|
1180
|
+
}
|
|
1181
|
+
return this.resolveDefaultDesktopRouteUiLayoutUids(transaction);
|
|
1182
|
+
}
|
|
1183
|
+
assertNavigationTargetIsExclusive(actionName, layoutUid, portalUid, paths) {
|
|
1184
|
+
const normalizedLayoutUid = this.normalizeExplicitDesktopRouteLayoutUid(layoutUid);
|
|
1185
|
+
const normalizedPortalUid = this.navigationTargets.normalizePortalUid(portalUid);
|
|
1186
|
+
if (!normalizedLayoutUid || !normalizedPortalUid) {
|
|
1187
|
+
return;
|
|
1188
|
+
}
|
|
1189
|
+
(0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} cannot use layoutUid and portalUid together`, {
|
|
1190
|
+
ruleId: "navigation-target-mutually-exclusive",
|
|
1191
|
+
path: paths.portal,
|
|
1192
|
+
details: {
|
|
1193
|
+
layoutUid: normalizedLayoutUid,
|
|
1194
|
+
portalUid: normalizedPortalUid,
|
|
1195
|
+
layoutPath: paths.layout,
|
|
1196
|
+
portalPath: paths.portal
|
|
1197
|
+
}
|
|
1198
|
+
});
|
|
1199
|
+
}
|
|
1200
|
+
async readDesktopRouteScope(route, transaction) {
|
|
1201
|
+
const routeId = this.readRouteField(route, "id");
|
|
1202
|
+
return {
|
|
1203
|
+
portalUids: await this.navigationTargets.readRoutePortalUids(routeId, transaction),
|
|
1204
|
+
layoutUids: await this.readDesktopRouteUiLayoutUids(routeId, transaction)
|
|
1205
|
+
};
|
|
1206
|
+
}
|
|
1207
|
+
async resolveRequestedDesktopRouteScope(values, parentRoute, actionName, options = {}) {
|
|
1208
|
+
const layoutUid = this.normalizeExplicitDesktopRouteLayoutUid(values.layoutUid);
|
|
1209
|
+
const portalUid = this.navigationTargets.normalizePortalUid(values.portalUid);
|
|
1210
|
+
this.assertNavigationTargetIsExclusive(actionName, layoutUid, portalUid, {
|
|
1211
|
+
layout: "values.layoutUid",
|
|
1212
|
+
portal: "values.portalUid"
|
|
1213
|
+
});
|
|
1214
|
+
if (portalUid) {
|
|
1215
|
+
const portal = await this.navigationTargets.resolvePortal(portalUid, {
|
|
1216
|
+
actionName,
|
|
1217
|
+
path: "values.portalUid",
|
|
1218
|
+
currentRoles: options.currentRoles,
|
|
1219
|
+
transaction: options.transaction
|
|
1220
|
+
});
|
|
1221
|
+
if (parentRoute) {
|
|
1222
|
+
await this.navigationTargets.assertRouteBelongsToPortal(
|
|
1223
|
+
actionName,
|
|
1224
|
+
this.readRouteField(parentRoute, "id"),
|
|
1225
|
+
portal.uid,
|
|
1226
|
+
"values.parentMenuRouteId",
|
|
1227
|
+
options.transaction
|
|
1228
|
+
);
|
|
1229
|
+
}
|
|
1230
|
+
return {
|
|
1231
|
+
portalUids: [portal.uid],
|
|
1232
|
+
layoutUids: [],
|
|
1233
|
+
selectedPortal: portal,
|
|
1234
|
+
layoutType: portal.layoutType
|
|
1235
|
+
};
|
|
1236
|
+
}
|
|
1237
|
+
if (layoutUid) {
|
|
1238
|
+
await this.assertEnabledDesktopRouteUiLayoutUid(layoutUid, actionName, "values.layoutUid", options.transaction);
|
|
1239
|
+
if (parentRoute) {
|
|
1240
|
+
await this.assertDesktopRouteBelongsToUiLayout(
|
|
1241
|
+
actionName,
|
|
1242
|
+
parentRoute,
|
|
1243
|
+
layoutUid,
|
|
1244
|
+
"values.parentMenuRouteId",
|
|
1245
|
+
options.transaction
|
|
1246
|
+
);
|
|
1247
|
+
}
|
|
1248
|
+
return {
|
|
1249
|
+
portalUids: [],
|
|
1250
|
+
layoutUids: [layoutUid],
|
|
1251
|
+
layoutType: await this.getDesktopRouteUiLayoutTypeByUid(layoutUid, options.transaction)
|
|
1252
|
+
};
|
|
1253
|
+
}
|
|
1254
|
+
if (parentRoute) {
|
|
1255
|
+
const inheritedScope = await this.readDesktopRouteScope(parentRoute, options.transaction);
|
|
1256
|
+
if (inheritedScope.portalUids.length > 1) {
|
|
1257
|
+
(0, import_errors.throwBadRequest)(
|
|
1258
|
+
`flowSurfaces ${actionName} parent route belongs to multiple portals; pass values.portalUid explicitly`,
|
|
1259
|
+
{
|
|
1260
|
+
ruleId: "navigation-route-scope-ambiguous",
|
|
1261
|
+
path: "values.parentMenuRouteId",
|
|
1262
|
+
details: {
|
|
1263
|
+
routeId: this.readRouteField(parentRoute, "id"),
|
|
1264
|
+
portalUids: inheritedScope.portalUids
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
);
|
|
1268
|
+
}
|
|
1269
|
+
if (inheritedScope.portalUids.length === 1) {
|
|
1270
|
+
const portal = await this.navigationTargets.resolvePortal(inheritedScope.portalUids[0], {
|
|
1271
|
+
actionName,
|
|
1272
|
+
path: "values.parentMenuRouteId",
|
|
1273
|
+
currentRoles: options.currentRoles,
|
|
1274
|
+
transaction: options.transaction
|
|
1275
|
+
});
|
|
1276
|
+
return {
|
|
1277
|
+
...inheritedScope,
|
|
1278
|
+
selectedPortal: portal,
|
|
1279
|
+
layoutType: portal.layoutType
|
|
1280
|
+
};
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
const layoutUids = await this.resolveInheritedDesktopRouteUiLayoutUids(parentRoute, options.transaction);
|
|
1284
|
+
return {
|
|
1285
|
+
portalUids: [],
|
|
1286
|
+
layoutUids,
|
|
1287
|
+
layoutType: layoutUids.length === 1 ? await this.getDesktopRouteUiLayoutTypeByUid(layoutUids[0], options.transaction) : void 0
|
|
1288
|
+
};
|
|
1289
|
+
}
|
|
1290
|
+
async resolveExistingDesktopRouteScope(values, route, actionName, options = {}) {
|
|
1291
|
+
const layoutUid = this.normalizeExplicitDesktopRouteLayoutUid(values.layoutUid);
|
|
1292
|
+
const portalUid = this.navigationTargets.normalizePortalUid(values.portalUid);
|
|
1293
|
+
this.assertNavigationTargetIsExclusive(actionName, layoutUid, portalUid, {
|
|
1294
|
+
layout: "values.layoutUid",
|
|
1295
|
+
portal: "values.portalUid"
|
|
1296
|
+
});
|
|
1297
|
+
const routeScope = await this.readDesktopRouteScope(route, options.transaction);
|
|
1298
|
+
if (portalUid) {
|
|
1299
|
+
const portal = await this.navigationTargets.resolvePortal(portalUid, {
|
|
1300
|
+
actionName,
|
|
1301
|
+
path: "values.portalUid",
|
|
1302
|
+
currentRoles: options.currentRoles,
|
|
1303
|
+
transaction: options.transaction
|
|
1304
|
+
});
|
|
1305
|
+
await this.navigationTargets.assertRouteBelongsToPortal(
|
|
1306
|
+
actionName,
|
|
1307
|
+
this.readRouteField(route, "id"),
|
|
1308
|
+
portal.uid,
|
|
1309
|
+
"values.menuRouteId",
|
|
1310
|
+
options.transaction
|
|
1311
|
+
);
|
|
1312
|
+
return {
|
|
1313
|
+
...routeScope,
|
|
1314
|
+
selectedPortal: portal,
|
|
1315
|
+
layoutType: portal.layoutType
|
|
1316
|
+
};
|
|
1317
|
+
}
|
|
1318
|
+
if (layoutUid) {
|
|
1319
|
+
await this.assertEnabledDesktopRouteUiLayoutUid(layoutUid, actionName, "values.layoutUid", options.transaction);
|
|
1320
|
+
await this.assertDesktopRouteBelongsToUiLayout(
|
|
1321
|
+
actionName,
|
|
1322
|
+
route,
|
|
1323
|
+
layoutUid,
|
|
1324
|
+
"values.menuRouteId",
|
|
1325
|
+
options.transaction
|
|
1326
|
+
);
|
|
1327
|
+
return {
|
|
1328
|
+
...routeScope,
|
|
1329
|
+
layoutType: await this.getDesktopRouteUiLayoutTypeByUid(layoutUid, options.transaction)
|
|
1330
|
+
};
|
|
1331
|
+
}
|
|
1332
|
+
if (routeScope.portalUids.length > 1) {
|
|
1333
|
+
(0, import_errors.throwBadRequest)(
|
|
1334
|
+
`flowSurfaces ${actionName} menu route belongs to multiple portals; pass values.portalUid explicitly`,
|
|
1335
|
+
{
|
|
1336
|
+
ruleId: "navigation-route-scope-ambiguous",
|
|
1337
|
+
path: "values.menuRouteId",
|
|
1338
|
+
details: {
|
|
1339
|
+
routeId: this.readRouteField(route, "id"),
|
|
1340
|
+
portalUids: routeScope.portalUids
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
);
|
|
1344
|
+
}
|
|
1345
|
+
if (routeScope.portalUids.length === 1) {
|
|
1346
|
+
const portal = await this.navigationTargets.resolvePortal(routeScope.portalUids[0], {
|
|
1347
|
+
actionName,
|
|
1348
|
+
path: "values.menuRouteId",
|
|
1349
|
+
currentRoles: options.currentRoles,
|
|
1350
|
+
transaction: options.transaction
|
|
1351
|
+
});
|
|
1352
|
+
return {
|
|
1353
|
+
...routeScope,
|
|
1354
|
+
selectedPortal: portal,
|
|
1355
|
+
layoutType: portal.layoutType
|
|
1356
|
+
};
|
|
1357
|
+
}
|
|
1358
|
+
const layoutUids = routeScope.layoutUids.length ? routeScope.layoutUids : await this.ensureDesktopRouteUiLayouts(route, options.transaction);
|
|
1359
|
+
return {
|
|
1360
|
+
portalUids: [],
|
|
1361
|
+
layoutUids,
|
|
1362
|
+
layoutType: layoutUids.length === 1 ? await this.getDesktopRouteUiLayoutTypeByUid(layoutUids[0], options.transaction) : void 0
|
|
1363
|
+
};
|
|
1364
|
+
}
|
|
1365
|
+
async attachDesktopRouteScopeToRouteAndChildren(routeId, scope, transaction) {
|
|
1366
|
+
if (scope.layoutUids.length) {
|
|
1367
|
+
await this.attachDesktopRouteUiLayoutsToRouteAndChildren(routeId, scope.layoutUids, transaction);
|
|
1368
|
+
}
|
|
1369
|
+
if (scope.portalUids.length) {
|
|
1370
|
+
await this.navigationTargets.attachRouteTreeToPortals(routeId, scope.portalUids, {
|
|
1371
|
+
portalOnly: scope.layoutUids.length === 0,
|
|
1372
|
+
transaction
|
|
1373
|
+
});
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
async assertEnabledDesktopRouteUiLayoutUid(layoutUid, actionName, path, transaction) {
|
|
1377
|
+
if (!this.hasDesktopRouteUiLayoutsRelation()) {
|
|
1378
|
+
(0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} ${path} requires plugin-ui-layout desktop route relation support`, {
|
|
1379
|
+
ruleId: "navigation-layout-unsupported",
|
|
1380
|
+
path,
|
|
1381
|
+
details: {
|
|
1382
|
+
layoutUid
|
|
1383
|
+
}
|
|
1384
|
+
});
|
|
1385
|
+
}
|
|
1386
|
+
const uiLayout = await this.db.getRepository("uiLayouts").findOne({
|
|
1387
|
+
filter: {
|
|
1388
|
+
uid: layoutUid,
|
|
1389
|
+
enabled: true
|
|
1390
|
+
},
|
|
1391
|
+
transaction
|
|
1392
|
+
});
|
|
1393
|
+
if (!uiLayout) {
|
|
1394
|
+
(0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} ${path} must reference an enabled ui layout`, {
|
|
1395
|
+
ruleId: "navigation-layout-not-found",
|
|
1396
|
+
path,
|
|
1397
|
+
details: {
|
|
1398
|
+
layoutUid
|
|
1399
|
+
}
|
|
1400
|
+
});
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
async assertDesktopRouteBelongsToUiLayout(actionName, route, layoutUid, path, transaction) {
|
|
1404
|
+
const normalizedLayoutUid = this.normalizeExplicitDesktopRouteLayoutUid(layoutUid);
|
|
1405
|
+
if (!normalizedLayoutUid || !route) {
|
|
1406
|
+
return;
|
|
1407
|
+
}
|
|
1408
|
+
const routeId = this.readRouteField(route, "id");
|
|
1409
|
+
const routeLayoutUids = await this.readDesktopRouteUiLayoutUids(routeId, transaction);
|
|
1410
|
+
if (routeLayoutUids.includes(normalizedLayoutUid)) {
|
|
1411
|
+
return;
|
|
1412
|
+
}
|
|
1413
|
+
(0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} ${path} does not belong to ui layout '${normalizedLayoutUid}'`, {
|
|
1414
|
+
ruleId: "navigation-route-layout-mismatch",
|
|
1415
|
+
path,
|
|
1416
|
+
details: {
|
|
1417
|
+
routeId,
|
|
1418
|
+
layoutUid: normalizedLayoutUid,
|
|
1419
|
+
routeLayoutUids
|
|
1420
|
+
}
|
|
1421
|
+
});
|
|
1422
|
+
}
|
|
1423
|
+
async setDesktopRouteUiLayouts(routeId, uiLayoutUids, transaction) {
|
|
1424
|
+
const relationRouteId = this.normalizeDesktopRouteRelationId(routeId);
|
|
1425
|
+
if (import_lodash.default.isUndefined(relationRouteId) || !uiLayoutUids.length || !this.hasDesktopRouteUiLayoutsRelation()) {
|
|
1426
|
+
return;
|
|
1427
|
+
}
|
|
1428
|
+
await this.db.getRepository("desktopRoutes.uiLayouts", relationRouteId).set({
|
|
1429
|
+
tk: uiLayoutUids,
|
|
1430
|
+
transaction
|
|
1431
|
+
});
|
|
1432
|
+
}
|
|
1433
|
+
async attachDesktopRouteUiLayoutsToRouteAndChildren(routeId, uiLayoutUids, transaction) {
|
|
1434
|
+
if (import_lodash.default.isNil(routeId) || !uiLayoutUids.length || !this.hasDesktopRouteUiLayoutsRelation()) {
|
|
1435
|
+
return;
|
|
1436
|
+
}
|
|
1437
|
+
await this.setDesktopRouteUiLayouts(routeId, uiLayoutUids, transaction);
|
|
1438
|
+
const children = await this.db.getRepository("desktopRoutes").find({
|
|
1439
|
+
fields: ["id"],
|
|
1440
|
+
filter: {
|
|
1441
|
+
parentId: routeId
|
|
1442
|
+
},
|
|
1443
|
+
transaction
|
|
1444
|
+
});
|
|
1445
|
+
for (const child of children) {
|
|
1446
|
+
await this.attachDesktopRouteUiLayoutsToRouteAndChildren(
|
|
1447
|
+
this.readRouteField(child, "id"),
|
|
1448
|
+
uiLayoutUids,
|
|
1449
|
+
transaction
|
|
1450
|
+
);
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
async ensureDesktopRouteUiLayouts(route, transaction) {
|
|
1454
|
+
const routeId = this.readRouteField(route, "id");
|
|
1455
|
+
if (import_lodash.default.isNil(routeId) || !this.hasDesktopRouteUiLayoutsRelation()) {
|
|
1456
|
+
return [];
|
|
1457
|
+
}
|
|
1458
|
+
const existingLayoutUids = await this.readDesktopRouteUiLayoutUids(routeId, transaction);
|
|
1459
|
+
if (existingLayoutUids.length) {
|
|
1460
|
+
return existingLayoutUids;
|
|
1461
|
+
}
|
|
1462
|
+
const parentRouteId = this.readRouteField(route, "parentId");
|
|
1463
|
+
const parentRoute = import_lodash.default.isNil(parentRouteId) ? null : await this.findMenuRouteById(parentRouteId, transaction);
|
|
1464
|
+
const inheritedLayoutUids = await this.resolveInheritedDesktopRouteUiLayoutUids(parentRoute, transaction);
|
|
1465
|
+
await this.setDesktopRouteUiLayouts(routeId, inheritedLayoutUids, transaction);
|
|
1466
|
+
return inheritedLayoutUids;
|
|
1467
|
+
}
|
|
1033
1468
|
isValidMenuIconName(value) {
|
|
1034
1469
|
const normalized = String(value || "").trim();
|
|
1035
1470
|
return !!normalized && ANT_DESIGN_ICON_NAMES.has(normalized);
|
|
@@ -1082,11 +1517,19 @@ class FlowSurfacesService {
|
|
|
1082
1517
|
});
|
|
1083
1518
|
}
|
|
1084
1519
|
}
|
|
1085
|
-
async createFlowMenuGroup(values,
|
|
1086
|
-
|
|
1520
|
+
async createFlowMenuGroup(values, options = {}) {
|
|
1521
|
+
var _a;
|
|
1522
|
+
const parentRoute = await this.assertMenuParentIsGroup(values.parentMenuRouteId, options.transaction);
|
|
1087
1523
|
const parentId = this.readRouteField(parentRoute, "id") ?? null;
|
|
1524
|
+
const routeScope = await this.resolveRequestedDesktopRouteScope(values, parentRoute, "createMenu", options);
|
|
1088
1525
|
const title = String(values.title || "").trim();
|
|
1089
|
-
const existingGroups = await this.findMenuGroupRoutesByParentIdAndTitle(
|
|
1526
|
+
const existingGroups = await this.findMenuGroupRoutesByParentIdAndTitle(
|
|
1527
|
+
parentId,
|
|
1528
|
+
title,
|
|
1529
|
+
options.transaction,
|
|
1530
|
+
routeScope.layoutUids,
|
|
1531
|
+
(_a = routeScope.selectedPortal) == null ? void 0 : _a.uid
|
|
1532
|
+
);
|
|
1090
1533
|
if (existingGroups.length === 1) {
|
|
1091
1534
|
return this.buildMenuResult(existingGroups[0]);
|
|
1092
1535
|
}
|
|
@@ -1111,7 +1554,7 @@ class FlowSurfacesService {
|
|
|
1111
1554
|
this.assertVisibleNavigationIcon("createMenu", "values", values);
|
|
1112
1555
|
const schemaUid = values.schemaUid || (0, import_utils.uid)();
|
|
1113
1556
|
const desktopRoutes = this.db.getRepository("desktopRoutes");
|
|
1114
|
-
await desktopRoutes.create({
|
|
1557
|
+
const route = await desktopRoutes.create({
|
|
1115
1558
|
values: {
|
|
1116
1559
|
type: "group",
|
|
1117
1560
|
sort: this.allocateRouteSortValue(),
|
|
@@ -1122,17 +1565,19 @@ class FlowSurfacesService {
|
|
|
1122
1565
|
hideInMenu: !!values.hideInMenu,
|
|
1123
1566
|
parentId
|
|
1124
1567
|
},
|
|
1125
|
-
transaction
|
|
1126
|
-
});
|
|
1127
|
-
const route = await desktopRoutes.findOne({
|
|
1128
|
-
filter: { schemaUid },
|
|
1129
|
-
transaction
|
|
1568
|
+
transaction: options.transaction
|
|
1130
1569
|
});
|
|
1570
|
+
await this.attachDesktopRouteScopeToRouteAndChildren(
|
|
1571
|
+
this.readRouteField(route, "id"),
|
|
1572
|
+
routeScope,
|
|
1573
|
+
options.transaction
|
|
1574
|
+
);
|
|
1131
1575
|
return this.buildMenuResult(route);
|
|
1132
1576
|
}
|
|
1133
|
-
async createFlowMenuItem(values,
|
|
1577
|
+
async createFlowMenuItem(values, options = {}) {
|
|
1134
1578
|
var _a;
|
|
1135
|
-
const parentRoute = await this.assertMenuParentIsGroup(values.parentMenuRouteId, transaction);
|
|
1579
|
+
const parentRoute = await this.assertMenuParentIsGroup(values.parentMenuRouteId, options.transaction);
|
|
1580
|
+
const routeScope = await this.resolveRequestedDesktopRouteScope(values, parentRoute, "createMenu", options);
|
|
1136
1581
|
this.assertVisibleNavigationIcon("createMenu", "values", values);
|
|
1137
1582
|
const pageSchemaUid = values.pageSchemaUid || (0, import_utils.uid)();
|
|
1138
1583
|
const menuSchemaUid = (0, import_utils.uid)();
|
|
@@ -1142,7 +1587,7 @@ class FlowSurfacesService {
|
|
|
1142
1587
|
const title = values.title || pageSchemaUid;
|
|
1143
1588
|
const tabTitle = values.tabTitle || "Untitled";
|
|
1144
1589
|
const desktopRoutes = this.db.getRepository("desktopRoutes");
|
|
1145
|
-
await desktopRoutes.create({
|
|
1590
|
+
const createdRoute = await desktopRoutes.create({
|
|
1146
1591
|
values: {
|
|
1147
1592
|
type: "flowPage",
|
|
1148
1593
|
sort: this.allocateRouteSortValue(),
|
|
@@ -1175,15 +1620,20 @@ class FlowSurfacesService {
|
|
|
1175
1620
|
}
|
|
1176
1621
|
]
|
|
1177
1622
|
},
|
|
1178
|
-
transaction
|
|
1623
|
+
transaction: options.transaction
|
|
1179
1624
|
});
|
|
1625
|
+
await this.attachDesktopRouteScopeToRouteAndChildren(
|
|
1626
|
+
this.readRouteField(createdRoute, "id"),
|
|
1627
|
+
routeScope,
|
|
1628
|
+
options.transaction
|
|
1629
|
+
);
|
|
1180
1630
|
const route = await desktopRoutes.findOne({
|
|
1181
1631
|
filter: { schemaUid: pageSchemaUid },
|
|
1182
1632
|
appends: ["children"],
|
|
1183
|
-
transaction
|
|
1633
|
+
transaction: options.transaction
|
|
1184
1634
|
});
|
|
1185
1635
|
const tabRoute = import_lodash.default.sortBy(import_lodash.default.castArray(((_a = route == null ? void 0 : route.get) == null ? void 0 : _a.call(route, "children")) || []), "sort")[0];
|
|
1186
|
-
await this.ensureFlowRoutePageSchemaShell(pageSchemaUid, transaction);
|
|
1636
|
+
await this.ensureFlowRoutePageSchemaShell(pageSchemaUid, options.transaction);
|
|
1187
1637
|
const pageTree = (0, import_builder.buildPersistedRootPageModel)({
|
|
1188
1638
|
pageUid,
|
|
1189
1639
|
pageTitle: title,
|
|
@@ -1199,7 +1649,7 @@ class FlowSurfacesService {
|
|
|
1199
1649
|
subType: "object",
|
|
1200
1650
|
...pageTree
|
|
1201
1651
|
},
|
|
1202
|
-
{ transaction }
|
|
1652
|
+
{ transaction: options.transaction }
|
|
1203
1653
|
);
|
|
1204
1654
|
return this.buildMenuResult(route, {
|
|
1205
1655
|
pageSchemaUid,
|
|
@@ -1211,7 +1661,16 @@ class FlowSurfacesService {
|
|
|
1211
1661
|
});
|
|
1212
1662
|
}
|
|
1213
1663
|
sanitizePublicCreateMenuValues(values) {
|
|
1214
|
-
return import_lodash.default.pick(values, [
|
|
1664
|
+
return import_lodash.default.pick(values, [
|
|
1665
|
+
"title",
|
|
1666
|
+
"type",
|
|
1667
|
+
"layoutUid",
|
|
1668
|
+
"portalUid",
|
|
1669
|
+
"icon",
|
|
1670
|
+
"tooltip",
|
|
1671
|
+
"hideInMenu",
|
|
1672
|
+
"parentMenuRouteId"
|
|
1673
|
+
]);
|
|
1215
1674
|
}
|
|
1216
1675
|
async loadRouteBackedPageStructure(route, transaction) {
|
|
1217
1676
|
const routeId = this.readRouteField(route, "id");
|
|
@@ -3122,7 +3581,15 @@ class FlowSurfacesService {
|
|
|
3122
3581
|
if (!groupTitle) {
|
|
3123
3582
|
return document;
|
|
3124
3583
|
}
|
|
3125
|
-
const
|
|
3584
|
+
const layoutUid = this.normalizeExplicitDesktopRouteLayoutUid(document.navigation.layoutUid);
|
|
3585
|
+
const portalUid = this.navigationTargets.normalizePortalUid(document.navigation.portalUid);
|
|
3586
|
+
const matchedRoutes = await this.findMenuGroupRoutesByParentIdAndTitle(
|
|
3587
|
+
null,
|
|
3588
|
+
groupTitle,
|
|
3589
|
+
transaction,
|
|
3590
|
+
layoutUid || await this.resolveDefaultDesktopRouteUiLayoutUids(transaction),
|
|
3591
|
+
portalUid
|
|
3592
|
+
);
|
|
3126
3593
|
if (!matchedRoutes.length) {
|
|
3127
3594
|
return document;
|
|
3128
3595
|
}
|
|
@@ -3147,29 +3614,148 @@ class FlowSurfacesService {
|
|
|
3147
3614
|
}
|
|
3148
3615
|
};
|
|
3149
3616
|
}
|
|
3617
|
+
async normalizeApplyBlueprintCreateMobileNavigation(document, options = {}) {
|
|
3618
|
+
var _a, _b;
|
|
3619
|
+
if (document.mode !== "create") {
|
|
3620
|
+
return document;
|
|
3621
|
+
}
|
|
3622
|
+
const layoutUid = this.normalizeExplicitDesktopRouteLayoutUid((_a = document.navigation) == null ? void 0 : _a.layoutUid);
|
|
3623
|
+
const portalUid = this.navigationTargets.normalizePortalUid((_b = document.navigation) == null ? void 0 : _b.portalUid);
|
|
3624
|
+
const layoutType = portalUid ? (await this.navigationTargets.resolvePortal(portalUid, {
|
|
3625
|
+
actionName: "applyBlueprint",
|
|
3626
|
+
path: "values.navigation.portalUid",
|
|
3627
|
+
currentRoles: options.currentRoles,
|
|
3628
|
+
transaction: options.transaction
|
|
3629
|
+
})).layoutType : await this.getDesktopRouteUiLayoutTypeByUid(layoutUid || "", options.transaction);
|
|
3630
|
+
if (layoutType !== MOBILE_UI_LAYOUT_TYPE) {
|
|
3631
|
+
return document;
|
|
3632
|
+
}
|
|
3633
|
+
return {
|
|
3634
|
+
...document,
|
|
3635
|
+
navigation: (0, import_service_utils.buildDefinedPayload)({
|
|
3636
|
+
...document.navigation,
|
|
3637
|
+
layoutUid,
|
|
3638
|
+
portalUid,
|
|
3639
|
+
group: void 0
|
|
3640
|
+
})
|
|
3641
|
+
};
|
|
3642
|
+
}
|
|
3643
|
+
async assertApplyBlueprintCreateNavigationTarget(document, options = {}) {
|
|
3644
|
+
var _a, _b, _c, _d, _e, _f;
|
|
3645
|
+
if (document.mode !== "create") {
|
|
3646
|
+
return;
|
|
3647
|
+
}
|
|
3648
|
+
const layoutUid = this.normalizeExplicitDesktopRouteLayoutUid((_a = document.navigation) == null ? void 0 : _a.layoutUid);
|
|
3649
|
+
const portalUid = this.navigationTargets.normalizePortalUid((_b = document.navigation) == null ? void 0 : _b.portalUid);
|
|
3650
|
+
this.assertNavigationTargetIsExclusive("applyBlueprint", layoutUid, portalUid, {
|
|
3651
|
+
layout: "values.navigation.layoutUid",
|
|
3652
|
+
portal: "values.navigation.portalUid"
|
|
3653
|
+
});
|
|
3654
|
+
if (!layoutUid && !portalUid) {
|
|
3655
|
+
return;
|
|
3656
|
+
}
|
|
3657
|
+
if (portalUid) {
|
|
3658
|
+
const portal = await this.navigationTargets.resolvePortal(portalUid, {
|
|
3659
|
+
actionName: "applyBlueprint",
|
|
3660
|
+
path: "values.navigation.portalUid",
|
|
3661
|
+
currentRoles: options.currentRoles,
|
|
3662
|
+
transaction: options.transaction
|
|
3663
|
+
});
|
|
3664
|
+
if (portal.layoutType === MOBILE_UI_LAYOUT_TYPE) {
|
|
3665
|
+
return;
|
|
3666
|
+
}
|
|
3667
|
+
const groupRouteId2 = (_d = (_c = document.navigation) == null ? void 0 : _c.group) == null ? void 0 : _d.routeId;
|
|
3668
|
+
if (import_lodash.default.isNil(groupRouteId2) || groupRouteId2 === "") {
|
|
3669
|
+
return;
|
|
3670
|
+
}
|
|
3671
|
+
const groupRoute2 = await this.assertMenuParentIsGroup(groupRouteId2, options.transaction);
|
|
3672
|
+
await this.navigationTargets.assertRouteBelongsToPortal(
|
|
3673
|
+
"applyBlueprint",
|
|
3674
|
+
this.readRouteField(groupRoute2, "id"),
|
|
3675
|
+
portal.uid,
|
|
3676
|
+
"values.navigation.group.routeId",
|
|
3677
|
+
options.transaction
|
|
3678
|
+
);
|
|
3679
|
+
return;
|
|
3680
|
+
}
|
|
3681
|
+
await this.assertEnabledDesktopRouteUiLayoutUid(
|
|
3682
|
+
layoutUid,
|
|
3683
|
+
"applyBlueprint",
|
|
3684
|
+
"values.navigation.layoutUid",
|
|
3685
|
+
options.transaction
|
|
3686
|
+
);
|
|
3687
|
+
if (await this.isMobileDesktopRouteUiLayoutUid(layoutUid, options.transaction)) {
|
|
3688
|
+
return;
|
|
3689
|
+
}
|
|
3690
|
+
const groupRouteId = (_f = (_e = document.navigation) == null ? void 0 : _e.group) == null ? void 0 : _f.routeId;
|
|
3691
|
+
if (import_lodash.default.isNil(groupRouteId) || groupRouteId === "") {
|
|
3692
|
+
return;
|
|
3693
|
+
}
|
|
3694
|
+
const groupRoute = await this.assertMenuParentIsGroup(groupRouteId, options.transaction);
|
|
3695
|
+
await this.assertDesktopRouteBelongsToUiLayout(
|
|
3696
|
+
"applyBlueprint",
|
|
3697
|
+
groupRoute,
|
|
3698
|
+
layoutUid,
|
|
3699
|
+
"values.navigation.group.routeId",
|
|
3700
|
+
options.transaction
|
|
3701
|
+
);
|
|
3702
|
+
}
|
|
3150
3703
|
async resolveApplyBlueprintCreatePageIdentity(document, transaction) {
|
|
3151
|
-
var _a, _b, _c, _d, _e;
|
|
3704
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
3152
3705
|
if (document.mode !== "create") {
|
|
3153
3706
|
return document;
|
|
3154
3707
|
}
|
|
3155
3708
|
const groupRouteId = (_b = (_a = document.navigation) == null ? void 0 : _a.group) == null ? void 0 : _b.routeId;
|
|
3156
|
-
const
|
|
3157
|
-
|
|
3709
|
+
const layoutUid = this.normalizeExplicitDesktopRouteLayoutUid((_c = document.navigation) == null ? void 0 : _c.layoutUid);
|
|
3710
|
+
let portalUid = this.navigationTargets.normalizePortalUid((_d = document.navigation) == null ? void 0 : _d.portalUid);
|
|
3711
|
+
const pageTitle = String(((_e = document.page) == null ? void 0 : _e.title) || ((_g = (_f = document.navigation) == null ? void 0 : _f.item) == null ? void 0 : _g.title) || "").trim();
|
|
3712
|
+
const hasGroupRouteId = !import_lodash.default.isNil(groupRouteId) && groupRouteId !== "";
|
|
3713
|
+
if (!pageTitle || !hasGroupRouteId && !layoutUid && !portalUid) {
|
|
3158
3714
|
return document;
|
|
3159
3715
|
}
|
|
3160
|
-
const
|
|
3716
|
+
const groupRoute = hasGroupRouteId ? await this.findMenuRouteById(groupRouteId, transaction) : null;
|
|
3717
|
+
if (!portalUid && groupRoute) {
|
|
3718
|
+
const groupPortalUids = await this.navigationTargets.readRoutePortalUids(
|
|
3719
|
+
this.readRouteField(groupRoute, "id"),
|
|
3720
|
+
transaction
|
|
3721
|
+
);
|
|
3722
|
+
if (groupPortalUids.length > 1) {
|
|
3723
|
+
(0, import_errors.throwBadRequest)(
|
|
3724
|
+
`flowSurfaces applyBlueprint navigation.group.routeId '${groupRouteId}' belongs to multiple portals; pass navigation.portalUid explicitly`,
|
|
3725
|
+
{
|
|
3726
|
+
ruleId: "navigation-route-scope-ambiguous",
|
|
3727
|
+
path: "values.navigation.group.routeId",
|
|
3728
|
+
details: {
|
|
3729
|
+
routeId: groupRouteId,
|
|
3730
|
+
portalUids: groupPortalUids
|
|
3731
|
+
}
|
|
3732
|
+
}
|
|
3733
|
+
);
|
|
3734
|
+
}
|
|
3735
|
+
portalUid = groupPortalUids[0];
|
|
3736
|
+
}
|
|
3737
|
+
const layoutUidFilter = portalUid ? void 0 : layoutUid || (groupRoute ? await this.resolveInheritedDesktopRouteUiLayoutUids(groupRoute, transaction) : void 0);
|
|
3738
|
+
const matchedPages = await this.findFlowPageRoutesByParentIdAndTitle(
|
|
3739
|
+
hasGroupRouteId ? groupRouteId : null,
|
|
3740
|
+
pageTitle,
|
|
3741
|
+
transaction,
|
|
3742
|
+
layoutUidFilter,
|
|
3743
|
+
portalUid
|
|
3744
|
+
);
|
|
3161
3745
|
if (!matchedPages.length) {
|
|
3162
3746
|
return document;
|
|
3163
3747
|
}
|
|
3164
3748
|
if (matchedPages.length > 1) {
|
|
3749
|
+
const locationLabel = hasGroupRouteId ? `under navigation.group.routeId '${groupRouteId}'` : portalUid ? `at the root of portal '${portalUid}'` : `at the root of ui layout '${layoutUid}'`;
|
|
3165
3750
|
(0, import_errors.throwBadRequest)(
|
|
3166
|
-
`flowSurfaces applyBlueprint
|
|
3751
|
+
`flowSurfaces applyBlueprint ${locationLabel} already has ${matchedPages.length} flow pages titled '${pageTitle}'; pass target.pageSchemaUid explicitly before applyBlueprint`
|
|
3167
3752
|
);
|
|
3168
3753
|
}
|
|
3169
3754
|
const pageSchemaUid = String(this.readRouteField(matchedPages[0], "schemaUid") || "").trim();
|
|
3170
3755
|
if (!pageSchemaUid) {
|
|
3756
|
+
const locationLabel = hasGroupRouteId ? `under navigation.group.routeId '${groupRouteId}'` : portalUid ? `at the root of portal '${portalUid}'` : `at the root of ui layout '${layoutUid}'`;
|
|
3171
3757
|
(0, import_errors.throwBadRequest)(
|
|
3172
|
-
`flowSurfaces applyBlueprint existing flow page '${pageTitle}'
|
|
3758
|
+
`flowSurfaces applyBlueprint existing flow page '${pageTitle}' ${locationLabel} is missing schemaUid; pass target.pageSchemaUid explicitly before applyBlueprint`
|
|
3173
3759
|
);
|
|
3174
3760
|
}
|
|
3175
3761
|
return {
|
|
@@ -3181,13 +3767,18 @@ class FlowSurfacesService {
|
|
|
3181
3767
|
navigation: void 0
|
|
3182
3768
|
};
|
|
3183
3769
|
}
|
|
3184
|
-
async prepareApplyBlueprintRequest(values,
|
|
3770
|
+
async prepareApplyBlueprintRequest(values, options = {}, createdKanbanSortFields) {
|
|
3185
3771
|
var _a;
|
|
3186
3772
|
const initialDocument = (0, import_blueprint.prepareFlowSurfaceApplyBlueprintDocument)(values);
|
|
3187
|
-
|
|
3188
|
-
const
|
|
3189
|
-
await this.
|
|
3190
|
-
|
|
3773
|
+
await this.assertApplyBlueprintCreateNavigationTarget(initialDocument, options);
|
|
3774
|
+
const mobileNormalizedDocument = await this.normalizeApplyBlueprintCreateMobileNavigation(initialDocument, options);
|
|
3775
|
+
const groupResolvedDocument = await this.resolveApplyBlueprintCreateNavigationGroup(
|
|
3776
|
+
mobileNormalizedDocument,
|
|
3777
|
+
options.transaction
|
|
3778
|
+
);
|
|
3779
|
+
const document = await this.resolveApplyBlueprintCreatePageIdentity(groupResolvedDocument, options.transaction);
|
|
3780
|
+
await this.prepareApplyBlueprintKanbanBlocks(document, options.transaction, createdKanbanSortFields);
|
|
3781
|
+
const replaceTarget = document.mode === "replace" && document.target ? await this.resolveApplyBlueprintReplaceTargetInfo(document.target.pageSchemaUid, options.transaction) : void 0;
|
|
3191
3782
|
if (document.mode === "replace" && document.tabs.length > 1 && typeof ((_a = document.page) == null ? void 0 : _a.enableTabs) === "undefined" && (replaceTarget == null ? void 0 : replaceTarget.pageEnableTabs) === false) {
|
|
3192
3783
|
(0, import_errors.throwBadRequest)(
|
|
3193
3784
|
`flowSurfaces applyBlueprint replace mode requires page.enableTabs=true when tabs.length > 1 and the current page has enableTabs=false`
|
|
@@ -3837,11 +4428,36 @@ class FlowSurfacesService {
|
|
|
3837
4428
|
}
|
|
3838
4429
|
}
|
|
3839
4430
|
async assertApplyBlueprintAuthoringPayload(values, options = {}) {
|
|
4431
|
+
var _a, _b;
|
|
3840
4432
|
const enabledPackages = await this.resolveEnabledPluginPackages(options);
|
|
4433
|
+
const layoutUid = this.normalizeExplicitDesktopRouteLayoutUid((_a = values == null ? void 0 : values.navigation) == null ? void 0 : _a.layoutUid);
|
|
4434
|
+
const portalUid = this.navigationTargets.normalizePortalUid((_b = values == null ? void 0 : values.navigation) == null ? void 0 : _b.portalUid);
|
|
4435
|
+
this.assertNavigationTargetIsExclusive("applyBlueprint", layoutUid, portalUid, {
|
|
4436
|
+
layout: "values.navigation.layoutUid",
|
|
4437
|
+
portal: "values.navigation.portalUid"
|
|
4438
|
+
});
|
|
4439
|
+
const resolvedPortal = portalUid ? await this.navigationTargets.resolvePortal(portalUid, {
|
|
4440
|
+
actionName: "applyBlueprint",
|
|
4441
|
+
path: "values.navigation.portalUid",
|
|
4442
|
+
currentRoles: options.currentRoles,
|
|
4443
|
+
transaction: options.transaction
|
|
4444
|
+
}) : void 0;
|
|
3841
4445
|
await (0, import_authoring_validation.assertFlowSurfaceAuthoringPayload)("applyBlueprint", values, {
|
|
3842
4446
|
transaction: options.transaction,
|
|
3843
4447
|
enabledPackages,
|
|
3844
|
-
findMenuGroupRoutesByTitle: (title, transaction) => this.findMenuGroupRoutesByTitle(title, transaction),
|
|
4448
|
+
findMenuGroupRoutesByTitle: (title, transaction, targetLayoutUid, targetPortalUid) => this.findMenuGroupRoutesByTitle(title, transaction, targetLayoutUid, targetPortalUid),
|
|
4449
|
+
getUiLayoutTypeByUid: (layoutUid2, transaction) => this.getDesktopRouteUiLayoutTypeByUid(layoutUid2, transaction),
|
|
4450
|
+
getPortalLayoutTypeByUid: async (targetPortalUid, transaction) => {
|
|
4451
|
+
if ((resolvedPortal == null ? void 0 : resolvedPortal.uid) === targetPortalUid) {
|
|
4452
|
+
return resolvedPortal.layoutType;
|
|
4453
|
+
}
|
|
4454
|
+
return (await this.navigationTargets.resolvePortal(targetPortalUid, {
|
|
4455
|
+
actionName: "applyBlueprint",
|
|
4456
|
+
path: "values.navigation.portalUid",
|
|
4457
|
+
currentRoles: options.currentRoles,
|
|
4458
|
+
transaction
|
|
4459
|
+
})).layoutType;
|
|
4460
|
+
},
|
|
3845
4461
|
getCollection: (dataSourceKey, collectionName) => this.getCollection(dataSourceKey || "main", collectionName || "")
|
|
3846
4462
|
});
|
|
3847
4463
|
}
|
|
@@ -3849,7 +4465,7 @@ class FlowSurfacesService {
|
|
|
3849
4465
|
if (options.skipAuthoringValidation !== true) {
|
|
3850
4466
|
await this.assertApplyBlueprintAuthoringPayload(values, options);
|
|
3851
4467
|
}
|
|
3852
|
-
const prepared = await this.prepareApplyBlueprintRequest(values, options
|
|
4468
|
+
const prepared = await this.prepareApplyBlueprintRequest(values, options, createdKanbanSortFields);
|
|
3853
4469
|
const popupTemplateAliasSession = this.createPopupTemplateAliasSession();
|
|
3854
4470
|
const popupTemplateTreeCache = /* @__PURE__ */ new Map();
|
|
3855
4471
|
this.validateApplyBlueprintPopupTemplateAliases(prepared.document, popupTemplateAliasSession);
|
|
@@ -5864,6 +6480,9 @@ class FlowSurfacesService {
|
|
|
5864
6480
|
}
|
|
5865
6481
|
(0, import_errors.throwBadRequest)(`flowSurfaces configure does not support configureOptions on '${(current == null ? void 0 : current.use) || resolved.uid}'`);
|
|
5866
6482
|
}
|
|
6483
|
+
async listNavigationTargets(_values = {}, options = {}) {
|
|
6484
|
+
return this.navigationTargets.listNavigationTargets(options.currentRoles, options.transaction);
|
|
6485
|
+
}
|
|
5867
6486
|
async createMenu(values, options = {}) {
|
|
5868
6487
|
const publicValues = this.sanitizePublicCreateMenuValues(values || {});
|
|
5869
6488
|
const type = publicValues.type === "group" ? "group" : "item";
|
|
@@ -5871,9 +6490,9 @@ class FlowSurfacesService {
|
|
|
5871
6490
|
(0, import_errors.throwBadRequest)("flowSurfaces createMenu requires title");
|
|
5872
6491
|
}
|
|
5873
6492
|
if (type === "group") {
|
|
5874
|
-
return this.createFlowMenuGroup(publicValues, options
|
|
6493
|
+
return this.createFlowMenuGroup(publicValues, options);
|
|
5875
6494
|
}
|
|
5876
|
-
return this.createFlowMenuItem(publicValues, options
|
|
6495
|
+
return this.createFlowMenuItem(publicValues, options);
|
|
5877
6496
|
}
|
|
5878
6497
|
async updateMenu(values, options = {}) {
|
|
5879
6498
|
const menuRouteId = values.menuRouteId;
|
|
@@ -5881,8 +6500,55 @@ class FlowSurfacesService {
|
|
|
5881
6500
|
(0, import_errors.throwBadRequest)("flowSurfaces updateMenu requires menuRouteId");
|
|
5882
6501
|
}
|
|
5883
6502
|
const route = await this.assertMenuRouteUpdatable(menuRouteId, options.transaction);
|
|
5884
|
-
await this.assertMenuParentIsGroup(values.parentMenuRouteId, options.transaction);
|
|
6503
|
+
const nextParentRoute = await this.assertMenuParentIsGroup(values.parentMenuRouteId, options.transaction);
|
|
5885
6504
|
await this.assertMenuParentNotSelfOrDescendant(route, values.parentMenuRouteId, options.transaction);
|
|
6505
|
+
const portalUid = this.navigationTargets.normalizePortalUid(values.portalUid);
|
|
6506
|
+
this.assertNavigationTargetIsExclusive("updateMenu", values.layoutUid, portalUid, {
|
|
6507
|
+
layout: "values.layoutUid",
|
|
6508
|
+
portal: "values.portalUid"
|
|
6509
|
+
});
|
|
6510
|
+
const routeScope = await this.readDesktopRouteScope(route, options.transaction);
|
|
6511
|
+
if (portalUid) {
|
|
6512
|
+
const portal = await this.navigationTargets.resolvePortal(portalUid, {
|
|
6513
|
+
actionName: "updateMenu",
|
|
6514
|
+
path: "values.portalUid",
|
|
6515
|
+
currentRoles: options.currentRoles,
|
|
6516
|
+
transaction: options.transaction
|
|
6517
|
+
});
|
|
6518
|
+
await this.navigationTargets.assertRouteBelongsToPortal(
|
|
6519
|
+
"updateMenu",
|
|
6520
|
+
this.readRouteField(route, "id"),
|
|
6521
|
+
portal.uid,
|
|
6522
|
+
"values.menuRouteId",
|
|
6523
|
+
options.transaction
|
|
6524
|
+
);
|
|
6525
|
+
if (nextParentRoute) {
|
|
6526
|
+
await this.navigationTargets.assertRouteBelongsToPortal(
|
|
6527
|
+
"updateMenu",
|
|
6528
|
+
this.readRouteField(nextParentRoute, "id"),
|
|
6529
|
+
portal.uid,
|
|
6530
|
+
"values.parentMenuRouteId",
|
|
6531
|
+
options.transaction
|
|
6532
|
+
);
|
|
6533
|
+
}
|
|
6534
|
+
}
|
|
6535
|
+
if (Object.prototype.hasOwnProperty.call(values, "parentMenuRouteId") && nextParentRoute) {
|
|
6536
|
+
const parentScope = await this.readDesktopRouteScope(nextParentRoute, options.transaction);
|
|
6537
|
+
const routePortalUids = [...routeScope.portalUids].sort();
|
|
6538
|
+
const parentPortalUids = [...parentScope.portalUids].sort();
|
|
6539
|
+
if (!import_lodash.default.isEqual(routePortalUids, parentPortalUids) && (routePortalUids.length || parentPortalUids.length)) {
|
|
6540
|
+
(0, import_errors.throwBadRequest)(`flowSurfaces updateMenu cannot move a menu route across portal scopes`, {
|
|
6541
|
+
ruleId: "navigation-route-portal-mismatch",
|
|
6542
|
+
path: "values.parentMenuRouteId",
|
|
6543
|
+
details: {
|
|
6544
|
+
routeId: this.readRouteField(route, "id"),
|
|
6545
|
+
routePortalUids,
|
|
6546
|
+
parentRouteId: this.readRouteField(nextParentRoute, "id"),
|
|
6547
|
+
parentPortalUids
|
|
6548
|
+
}
|
|
6549
|
+
});
|
|
6550
|
+
}
|
|
6551
|
+
}
|
|
5886
6552
|
const nextOptions = { ...this.readRouteOptions(route) };
|
|
5887
6553
|
const updateValues = {};
|
|
5888
6554
|
if (Object.prototype.hasOwnProperty.call(values, "title")) {
|
|
@@ -5912,13 +6578,30 @@ class FlowSurfacesService {
|
|
|
5912
6578
|
});
|
|
5913
6579
|
}
|
|
5914
6580
|
const updated = await this.findMenuRouteById(menuRouteId, options.transaction);
|
|
6581
|
+
if (updated && Object.prototype.hasOwnProperty.call(values, "parentMenuRouteId")) {
|
|
6582
|
+
if (routeScope.portalUids.length) {
|
|
6583
|
+
await this.attachDesktopRouteScopeToRouteAndChildren(
|
|
6584
|
+
this.readRouteField(updated, "id"),
|
|
6585
|
+
routeScope,
|
|
6586
|
+
options.transaction
|
|
6587
|
+
);
|
|
6588
|
+
} else {
|
|
6589
|
+
await this.attachDesktopRouteUiLayoutsToRouteAndChildren(
|
|
6590
|
+
this.readRouteField(updated, "id"),
|
|
6591
|
+
await this.resolveInheritedDesktopRouteUiLayoutUids(nextParentRoute, options.transaction),
|
|
6592
|
+
options.transaction
|
|
6593
|
+
);
|
|
6594
|
+
}
|
|
6595
|
+
}
|
|
5915
6596
|
return this.buildMenuResult(updated);
|
|
5916
6597
|
}
|
|
5917
|
-
async initializeFlowPageForRoute(route, values,
|
|
6598
|
+
async initializeFlowPageForRoute(route, values, options = {}) {
|
|
6599
|
+
const transaction = options.transaction;
|
|
5918
6600
|
const routeId = this.readRouteField(route, "id");
|
|
5919
6601
|
const pageSchemaUid = this.readRouteField(route, "schemaUid");
|
|
5920
6602
|
const structure = await this.loadRouteBackedPageStructure(route, transaction);
|
|
5921
6603
|
let tabRoute = structure.tabRoutes[0];
|
|
6604
|
+
const routeScope = await this.resolveExistingDesktopRouteScope(values, route, "createPage", options);
|
|
5922
6605
|
const routeOptions = this.readRouteOptions(route);
|
|
5923
6606
|
if (!routeOptions[FLOW_SURFACE_MENU_BINDABLE_OPTION_KEY]) {
|
|
5924
6607
|
(0, import_errors.throwBadRequest)(`flowSurfaces createPage only accepts a bindable menu route created by createMenu(type="item")`);
|
|
@@ -5940,7 +6623,7 @@ class FlowSurfacesService {
|
|
|
5940
6623
|
const tabSchemaUid2 = values.tabSchemaUid || (0, import_utils.uid)();
|
|
5941
6624
|
const tabSchemaName2 = values.tabSchemaName || (0, import_utils.uid)();
|
|
5942
6625
|
const tabTitle = values.tabTitle || "Untitled";
|
|
5943
|
-
await this.db.getRepository("desktopRoutes").create({
|
|
6626
|
+
tabRoute = await this.db.getRepository("desktopRoutes").create({
|
|
5944
6627
|
values: {
|
|
5945
6628
|
type: "tabs",
|
|
5946
6629
|
sort: this.allocateRouteSortValue(1),
|
|
@@ -5957,10 +6640,11 @@ class FlowSurfacesService {
|
|
|
5957
6640
|
},
|
|
5958
6641
|
transaction
|
|
5959
6642
|
});
|
|
5960
|
-
|
|
5961
|
-
|
|
6643
|
+
await this.attachDesktopRouteScopeToRouteAndChildren(
|
|
6644
|
+
this.readRouteField(tabRoute, "id"),
|
|
6645
|
+
routeScope,
|
|
5962
6646
|
transaction
|
|
5963
|
-
|
|
6647
|
+
);
|
|
5964
6648
|
} else {
|
|
5965
6649
|
await this.db.getRepository("desktopRoutes").update({
|
|
5966
6650
|
filterByTk: String(this.readRouteField(tabRoute, "id")),
|
|
@@ -5984,6 +6668,13 @@ class FlowSurfacesService {
|
|
|
5984
6668
|
transaction
|
|
5985
6669
|
});
|
|
5986
6670
|
}
|
|
6671
|
+
if (tabRoute) {
|
|
6672
|
+
await this.attachDesktopRouteScopeToRouteAndChildren(
|
|
6673
|
+
this.readRouteField(tabRoute, "id"),
|
|
6674
|
+
routeScope,
|
|
6675
|
+
transaction
|
|
6676
|
+
);
|
|
6677
|
+
}
|
|
5987
6678
|
await this.ensureFlowRoutePageSchemaShell(pageSchemaUid, transaction);
|
|
5988
6679
|
await this.db.getRepository("desktopRoutes").update({
|
|
5989
6680
|
filterByTk: String(routeId),
|
|
@@ -6034,11 +6725,11 @@ class FlowSurfacesService {
|
|
|
6034
6725
|
let result;
|
|
6035
6726
|
if (!import_lodash.default.isNil(values.menuRouteId) && values.menuRouteId !== "") {
|
|
6036
6727
|
const route = await this.assertMenuRouteBindable(values.menuRouteId, options.transaction);
|
|
6037
|
-
result = await this.initializeFlowPageForRoute(route, values, options
|
|
6728
|
+
result = await this.initializeFlowPageForRoute(route, values, options);
|
|
6038
6729
|
} else {
|
|
6039
|
-
const createdMenu = await this.createFlowMenuItem(values, options
|
|
6730
|
+
const createdMenu = await this.createFlowMenuItem(values, options);
|
|
6040
6731
|
const route = await this.assertMenuRouteBindable(createdMenu.routeId, options.transaction);
|
|
6041
|
-
result = await this.initializeFlowPageForRoute(route, values, options
|
|
6732
|
+
result = await this.initializeFlowPageForRoute(route, values, options);
|
|
6042
6733
|
}
|
|
6043
6734
|
await this.persistCreatedKeysForAction("createPage", values, result, options.transaction);
|
|
6044
6735
|
return result;
|
|
@@ -6123,6 +6814,11 @@ class FlowSurfacesService {
|
|
|
6123
6814
|
},
|
|
6124
6815
|
transaction: options.transaction
|
|
6125
6816
|
});
|
|
6817
|
+
const pageRouteScope = await this.readDesktopRouteScope(pageRoute, options.transaction);
|
|
6818
|
+
if (!pageRouteScope.portalUids.length && !pageRouteScope.layoutUids.length) {
|
|
6819
|
+
pageRouteScope.layoutUids = await this.ensureDesktopRouteUiLayouts(pageRoute, options.transaction);
|
|
6820
|
+
}
|
|
6821
|
+
await this.attachDesktopRouteScopeToRouteAndChildren(route.get("id"), pageRouteScope, options.transaction);
|
|
6126
6822
|
const gridUid = await this.ensureGridChild(tabSchemaUid, "BlockGridModel", options.transaction);
|
|
6127
6823
|
const result = {
|
|
6128
6824
|
pageUid: pageTarget.uid,
|