@nocobase/plugin-multi-portal 3.0.0-alpha.2 → 3.0.0-alpha.4
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/client-v2/556.37df9197ce5c3452.js +10 -0
- package/dist/client-v2/RootLanding.d.ts +4 -5
- package/dist/client-v2/index.js +1 -1
- package/dist/client-v2/layoutRegistration.d.ts +2 -1
- package/dist/client-v2/pages/MultiPortalsPage.d.ts +10 -1
- package/dist/client-v2/routeUrl.d.ts +1 -0
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +3 -0
- package/dist/externalVersion.js +9 -9
- package/dist/locale/en-US.json +14 -1
- package/dist/locale/zh-CN.json +14 -1
- package/dist/node_modules/tar/package.json +1 -1
- package/dist/server/collections/multiPortals.js +10 -0
- package/dist/server/plugin.d.ts +1 -1
- package/dist/server/plugin.js +180 -57
- package/dist/swagger/index.d.ts +152 -0
- package/dist/swagger/index.js +142 -0
- package/package.json +3 -3
- package/dist/client-v2/556.5faf86d4f8faef40.js +0 -10
package/dist/locale/zh-CN.json
CHANGED
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"Routes permissions": "路由权限",
|
|
34
34
|
"Multi-portal": "门户管理",
|
|
35
35
|
"Mobile": "移动端",
|
|
36
|
+
"More": "更多",
|
|
36
37
|
"New portals are allowed to be accessed by default": "新建门户默认允许访问",
|
|
37
38
|
"New routes are allowed to be accessed by default": "新建路由默认允许访问",
|
|
38
39
|
"Must start with /. For example: /portal.": "必须以 / 开头,例如 /门户。",
|
|
@@ -57,6 +58,7 @@
|
|
|
57
58
|
"No-code portal": "无代码门户",
|
|
58
59
|
"Portal manager": "门户管理",
|
|
59
60
|
"Portal name": "门户名称",
|
|
61
|
+
"Portal name \"{{portalName}}\" already exists": "门户名称“{{portalName}}”已存在",
|
|
60
62
|
"Portal name can only contain lowercase letters, numbers, hyphens, and underscores": "门户名称只能包含小写英文字母、数字、连字符和下划线",
|
|
61
63
|
"Portals": "门户",
|
|
62
64
|
"Refresh": "刷新",
|
|
@@ -70,6 +72,7 @@
|
|
|
70
72
|
"Source storage": "源码存储",
|
|
71
73
|
"Submit": "提交",
|
|
72
74
|
"Target portal": "目标门户",
|
|
75
|
+
"The default portal cannot be disabled": "默认门户不能停用,请先把默认设置给其他门户。",
|
|
73
76
|
"The corresponding portal directory will also be deleted.": "对应的门户目录也会被删除。",
|
|
74
77
|
"This entry is currently unavailable. Please check the application status.": "当前不可用,请检查应用状态。",
|
|
75
78
|
"This entry is no longer available. Please remove this button.": "该入口当前不可用,请移除此按钮。",
|
|
@@ -119,6 +122,16 @@
|
|
|
119
122
|
"No-code": "无代码模式",
|
|
120
123
|
"AI": "AI 模式",
|
|
121
124
|
"Default": "默认",
|
|
125
|
+
"Default portal": "默认门户",
|
|
126
|
+
"Set as default": "设为默认",
|
|
127
|
+
"Default portal updated successfully": "默认门户更新成功",
|
|
128
|
+
"Users enter this portal by default when they open the application without specifying one.": "用户未指定门户访问应用时,将默认进入此门户。",
|
|
129
|
+
"Use multiPortals:setDefault to update the default Portal": "请使用 multiPortals:setDefault 更新默认门户",
|
|
130
|
+
"filterByTk is required": "filterByTk 为必填项",
|
|
131
|
+
"Portal not found": "门户不存在",
|
|
132
|
+
"Disabled Portal cannot be set as default": "已禁用的门户不能设为默认",
|
|
133
|
+
"Portal layout must be enabled before setting it as default": "设为默认门户前必须先启用该门户布局",
|
|
134
|
+
"Unsupported Portal type cannot be set as default": "不支持的门户类型不能设为默认",
|
|
122
135
|
"No portals yet": "还没有门户",
|
|
123
136
|
"Each portal is a standalone front end with its own routes and menus.": "每个门户是一套独立的前台,有自己的路由和菜单。",
|
|
124
137
|
"Cover": "封面",
|
|
@@ -126,7 +139,7 @@
|
|
|
126
139
|
"Replace cover": "更换封面",
|
|
127
140
|
"Used as the cover placeholder when no cover is uploaded.": "没有上传封面时,用它作为封面占位。",
|
|
128
141
|
"Used in the access path.": "用于访问路径。",
|
|
129
|
-
"Shown on the portal card.
|
|
142
|
+
"Shown on the portal card.": "显示在门户卡片上。",
|
|
130
143
|
"Device": "设备",
|
|
131
144
|
"No-code portals render with the components of this device; AI portals use it for grouping.": "无代码门户按此选择组件形态;AI 门户用它做归类。",
|
|
132
145
|
"The title and name below are filled in from the repository name.": "下面的标题和名称会按仓库名自动填写。"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"author":"Isaac Z. Schlueter","name":"tar","description":"tar for node","version":"7.5.15","repository":{"type":"git","url":"https://github.com/isaacs/node-tar.git"},"scripts":{"genparse":"node scripts/generate-parse-fixtures.js","snap":"tap","test":"tap","pretest":"npm run prepare","presnap":"npm run prepare","prepare":"tshy && bash scripts/build.sh","preversion":"npm test","postversion":"npm publish","prepublishOnly":"git push origin --follow-tags","format":"prettier --write . --log-level warn","typedoc":"typedoc --tsconfig .tshy/esm.json ./src/*.ts","lint":"oxlint --fix src test","postsnap":"npm run lint","postlint":"npm run format"},"dependencies":{"@isaacs/fs-minipass":"^4.0.0","chownr":"^3.0.0","minipass":"^7.1.2","minizlib":"^3.1.0","yallist":"^5.0.0"},"devDependencies":{"@types/node":"^25.5.0","chmodr":"^2.0.2","end-of-stream":"^1.4.3","esbuild":"^0.27.4","events-to-array":"^2.0.3","mutate-fs":"^2.1.1","nock":"^13.5.4","oxlint":"^1.57.0","oxlint-tsgolint":"^0.17.3","prettier":"^3.8.1","rimraf":"^6.1.2","tap":"^21.6.2","tshy":"^3.3.2","typedoc":"^0.28.18"},"license":"BlueOak-1.0.0","engines":{"node":">=18"},"files":["dist"],"tshy":{"exports":{"./package.json":"./package.json",".":{"import":{"types":"./dist/esm/index.d.ts","default":"./dist/esm/index.min.js"},"require":{"types":"./dist/commonjs/index.d.ts","default":"./dist/commonjs/index.min.js"}},"./raw":"./src/index.ts","./c":"./src/create.ts","./create":"./src/create.ts","./replace":"./src/create.ts","./r":"./src/create.ts","./list":"./src/list.ts","./t":"./src/list.ts","./update":"./src/update.ts","./u":"./src/update.ts","./extract":"./src/extract.ts","./x":"./src/extract.ts","./pack":"./src/pack.ts","./unpack":"./src/unpack.ts","./parse":"./src/parse.ts","./read-entry":"./src/read-entry.ts","./write-entry":"./src/write-entry.ts","./header":"./src/header.ts","./pax":"./src/pax.ts","./types":"./src/types.ts"}},"exports":{"./package.json":"./package.json",".":{"import":{"types":"./dist/esm/index.d.ts","default":"./dist/esm/index.min.js"},"require":{"types":"./dist/commonjs/index.d.ts","default":"./dist/commonjs/index.min.js"}},"./raw":{"import":{"types":"./dist/esm/index.d.ts","default":"./dist/esm/index.js"},"require":{"types":"./dist/commonjs/index.d.ts","default":"./dist/commonjs/index.js"}},"./c":{"import":{"types":"./dist/esm/create.d.ts","default":"./dist/esm/create.js"},"require":{"types":"./dist/commonjs/create.d.ts","default":"./dist/commonjs/create.js"}},"./create":{"import":{"types":"./dist/esm/create.d.ts","default":"./dist/esm/create.js"},"require":{"types":"./dist/commonjs/create.d.ts","default":"./dist/commonjs/create.js"}},"./replace":{"import":{"types":"./dist/esm/create.d.ts","default":"./dist/esm/create.js"},"require":{"types":"./dist/commonjs/create.d.ts","default":"./dist/commonjs/create.js"}},"./r":{"import":{"types":"./dist/esm/create.d.ts","default":"./dist/esm/create.js"},"require":{"types":"./dist/commonjs/create.d.ts","default":"./dist/commonjs/create.js"}},"./list":{"import":{"types":"./dist/esm/list.d.ts","default":"./dist/esm/list.js"},"require":{"types":"./dist/commonjs/list.d.ts","default":"./dist/commonjs/list.js"}},"./t":{"import":{"types":"./dist/esm/list.d.ts","default":"./dist/esm/list.js"},"require":{"types":"./dist/commonjs/list.d.ts","default":"./dist/commonjs/list.js"}},"./update":{"import":{"types":"./dist/esm/update.d.ts","default":"./dist/esm/update.js"},"require":{"types":"./dist/commonjs/update.d.ts","default":"./dist/commonjs/update.js"}},"./u":{"import":{"types":"./dist/esm/update.d.ts","default":"./dist/esm/update.js"},"require":{"types":"./dist/commonjs/update.d.ts","default":"./dist/commonjs/update.js"}},"./extract":{"import":{"types":"./dist/esm/extract.d.ts","default":"./dist/esm/extract.js"},"require":{"types":"./dist/commonjs/extract.d.ts","default":"./dist/commonjs/extract.js"}},"./x":{"import":{"types":"./dist/esm/extract.d.ts","default":"./dist/esm/extract.js"},"require":{"types":"./dist/commonjs/extract.d.ts","default":"./dist/commonjs/extract.js"}},"./pack":{"import":{"types":"./dist/esm/pack.d.ts","default":"./dist/esm/pack.js"},"require":{"types":"./dist/commonjs/pack.d.ts","default":"./dist/commonjs/pack.js"}},"./unpack":{"import":{"types":"./dist/esm/unpack.d.ts","default":"./dist/esm/unpack.js"},"require":{"types":"./dist/commonjs/unpack.d.ts","default":"./dist/commonjs/unpack.js"}},"./parse":{"import":{"types":"./dist/esm/parse.d.ts","default":"./dist/esm/parse.js"},"require":{"types":"./dist/commonjs/parse.d.ts","default":"./dist/commonjs/parse.js"}},"./read-entry":{"import":{"types":"./dist/esm/read-entry.d.ts","default":"./dist/esm/read-entry.js"},"require":{"types":"./dist/commonjs/read-entry.d.ts","default":"./dist/commonjs/read-entry.js"}},"./write-entry":{"import":{"types":"./dist/esm/write-entry.d.ts","default":"./dist/esm/write-entry.js"},"require":{"types":"./dist/commonjs/write-entry.d.ts","default":"./dist/commonjs/write-entry.js"}},"./header":{"import":{"types":"./dist/esm/header.d.ts","default":"./dist/esm/header.js"},"require":{"types":"./dist/commonjs/header.d.ts","default":"./dist/commonjs/header.js"}},"./pax":{"import":{"types":"./dist/esm/pax.d.ts","default":"./dist/esm/pax.js"},"require":{"types":"./dist/commonjs/pax.d.ts","default":"./dist/commonjs/pax.js"}},"./types":{"import":{"types":"./dist/esm/types.d.ts","default":"./dist/esm/types.js"},"require":{"types":"./dist/commonjs/types.d.ts","default":"./dist/commonjs/types.js"}}},"type":"module","main":"./dist/commonjs/index.min.js","types":"./dist/commonjs/index.d.ts","module":"./dist/esm/index.min.js","_lastModified":"2026-07-
|
|
1
|
+
{"author":"Isaac Z. Schlueter","name":"tar","description":"tar for node","version":"7.5.15","repository":{"type":"git","url":"https://github.com/isaacs/node-tar.git"},"scripts":{"genparse":"node scripts/generate-parse-fixtures.js","snap":"tap","test":"tap","pretest":"npm run prepare","presnap":"npm run prepare","prepare":"tshy && bash scripts/build.sh","preversion":"npm test","postversion":"npm publish","prepublishOnly":"git push origin --follow-tags","format":"prettier --write . --log-level warn","typedoc":"typedoc --tsconfig .tshy/esm.json ./src/*.ts","lint":"oxlint --fix src test","postsnap":"npm run lint","postlint":"npm run format"},"dependencies":{"@isaacs/fs-minipass":"^4.0.0","chownr":"^3.0.0","minipass":"^7.1.2","minizlib":"^3.1.0","yallist":"^5.0.0"},"devDependencies":{"@types/node":"^25.5.0","chmodr":"^2.0.2","end-of-stream":"^1.4.3","esbuild":"^0.27.4","events-to-array":"^2.0.3","mutate-fs":"^2.1.1","nock":"^13.5.4","oxlint":"^1.57.0","oxlint-tsgolint":"^0.17.3","prettier":"^3.8.1","rimraf":"^6.1.2","tap":"^21.6.2","tshy":"^3.3.2","typedoc":"^0.28.18"},"license":"BlueOak-1.0.0","engines":{"node":">=18"},"files":["dist"],"tshy":{"exports":{"./package.json":"./package.json",".":{"import":{"types":"./dist/esm/index.d.ts","default":"./dist/esm/index.min.js"},"require":{"types":"./dist/commonjs/index.d.ts","default":"./dist/commonjs/index.min.js"}},"./raw":"./src/index.ts","./c":"./src/create.ts","./create":"./src/create.ts","./replace":"./src/create.ts","./r":"./src/create.ts","./list":"./src/list.ts","./t":"./src/list.ts","./update":"./src/update.ts","./u":"./src/update.ts","./extract":"./src/extract.ts","./x":"./src/extract.ts","./pack":"./src/pack.ts","./unpack":"./src/unpack.ts","./parse":"./src/parse.ts","./read-entry":"./src/read-entry.ts","./write-entry":"./src/write-entry.ts","./header":"./src/header.ts","./pax":"./src/pax.ts","./types":"./src/types.ts"}},"exports":{"./package.json":"./package.json",".":{"import":{"types":"./dist/esm/index.d.ts","default":"./dist/esm/index.min.js"},"require":{"types":"./dist/commonjs/index.d.ts","default":"./dist/commonjs/index.min.js"}},"./raw":{"import":{"types":"./dist/esm/index.d.ts","default":"./dist/esm/index.js"},"require":{"types":"./dist/commonjs/index.d.ts","default":"./dist/commonjs/index.js"}},"./c":{"import":{"types":"./dist/esm/create.d.ts","default":"./dist/esm/create.js"},"require":{"types":"./dist/commonjs/create.d.ts","default":"./dist/commonjs/create.js"}},"./create":{"import":{"types":"./dist/esm/create.d.ts","default":"./dist/esm/create.js"},"require":{"types":"./dist/commonjs/create.d.ts","default":"./dist/commonjs/create.js"}},"./replace":{"import":{"types":"./dist/esm/create.d.ts","default":"./dist/esm/create.js"},"require":{"types":"./dist/commonjs/create.d.ts","default":"./dist/commonjs/create.js"}},"./r":{"import":{"types":"./dist/esm/create.d.ts","default":"./dist/esm/create.js"},"require":{"types":"./dist/commonjs/create.d.ts","default":"./dist/commonjs/create.js"}},"./list":{"import":{"types":"./dist/esm/list.d.ts","default":"./dist/esm/list.js"},"require":{"types":"./dist/commonjs/list.d.ts","default":"./dist/commonjs/list.js"}},"./t":{"import":{"types":"./dist/esm/list.d.ts","default":"./dist/esm/list.js"},"require":{"types":"./dist/commonjs/list.d.ts","default":"./dist/commonjs/list.js"}},"./update":{"import":{"types":"./dist/esm/update.d.ts","default":"./dist/esm/update.js"},"require":{"types":"./dist/commonjs/update.d.ts","default":"./dist/commonjs/update.js"}},"./u":{"import":{"types":"./dist/esm/update.d.ts","default":"./dist/esm/update.js"},"require":{"types":"./dist/commonjs/update.d.ts","default":"./dist/commonjs/update.js"}},"./extract":{"import":{"types":"./dist/esm/extract.d.ts","default":"./dist/esm/extract.js"},"require":{"types":"./dist/commonjs/extract.d.ts","default":"./dist/commonjs/extract.js"}},"./x":{"import":{"types":"./dist/esm/extract.d.ts","default":"./dist/esm/extract.js"},"require":{"types":"./dist/commonjs/extract.d.ts","default":"./dist/commonjs/extract.js"}},"./pack":{"import":{"types":"./dist/esm/pack.d.ts","default":"./dist/esm/pack.js"},"require":{"types":"./dist/commonjs/pack.d.ts","default":"./dist/commonjs/pack.js"}},"./unpack":{"import":{"types":"./dist/esm/unpack.d.ts","default":"./dist/esm/unpack.js"},"require":{"types":"./dist/commonjs/unpack.d.ts","default":"./dist/commonjs/unpack.js"}},"./parse":{"import":{"types":"./dist/esm/parse.d.ts","default":"./dist/esm/parse.js"},"require":{"types":"./dist/commonjs/parse.d.ts","default":"./dist/commonjs/parse.js"}},"./read-entry":{"import":{"types":"./dist/esm/read-entry.d.ts","default":"./dist/esm/read-entry.js"},"require":{"types":"./dist/commonjs/read-entry.d.ts","default":"./dist/commonjs/read-entry.js"}},"./write-entry":{"import":{"types":"./dist/esm/write-entry.d.ts","default":"./dist/esm/write-entry.js"},"require":{"types":"./dist/commonjs/write-entry.d.ts","default":"./dist/commonjs/write-entry.js"}},"./header":{"import":{"types":"./dist/esm/header.d.ts","default":"./dist/esm/header.js"},"require":{"types":"./dist/commonjs/header.d.ts","default":"./dist/commonjs/header.js"}},"./pax":{"import":{"types":"./dist/esm/pax.d.ts","default":"./dist/esm/pax.js"},"require":{"types":"./dist/commonjs/pax.d.ts","default":"./dist/commonjs/pax.js"}},"./types":{"import":{"types":"./dist/esm/types.d.ts","default":"./dist/esm/types.js"},"require":{"types":"./dist/commonjs/types.d.ts","default":"./dist/commonjs/types.js"}}},"type":"module","main":"./dist/commonjs/index.min.js","types":"./dist/commonjs/index.d.ts","module":"./dist/esm/index.min.js","_lastModified":"2026-07-31T14:20:49.707Z"}
|
|
@@ -40,6 +40,10 @@ var multiPortals_default = (0, import_database.defineCollection)({
|
|
|
40
40
|
{
|
|
41
41
|
type: "UNIQUE",
|
|
42
42
|
fields: ["portalName"]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
type: "UNIQUE",
|
|
46
|
+
fields: ["isDefault"]
|
|
43
47
|
}
|
|
44
48
|
],
|
|
45
49
|
fields: [
|
|
@@ -89,6 +93,12 @@ var multiPortals_default = (0, import_database.defineCollection)({
|
|
|
89
93
|
defaultValue: true,
|
|
90
94
|
allowNull: false
|
|
91
95
|
},
|
|
96
|
+
{
|
|
97
|
+
name: "isDefault",
|
|
98
|
+
type: "boolean",
|
|
99
|
+
defaultValue: null,
|
|
100
|
+
allowNull: true
|
|
101
|
+
},
|
|
92
102
|
{
|
|
93
103
|
name: "options",
|
|
94
104
|
type: "json",
|
package/dist/server/plugin.d.ts
CHANGED
|
@@ -31,7 +31,7 @@ export declare class PluginMultiPortalServer extends Plugin {
|
|
|
31
31
|
private logPortalBuildHtml;
|
|
32
32
|
private getPortalStorageTaskKey;
|
|
33
33
|
private runPortalStorageTask;
|
|
34
|
-
private
|
|
34
|
+
private removePortalStorageIndexHtml;
|
|
35
35
|
private waitForPortalStorageTasks;
|
|
36
36
|
private schedulePortalTemplateCopyAndBuild;
|
|
37
37
|
private ensurePortalStorageItem;
|
package/dist/server/plugin.js
CHANGED
|
@@ -100,6 +100,7 @@ const MULTI_PORTAL_MANAGEMENT_ACTIONS = [
|
|
|
100
100
|
"multiPortals:create",
|
|
101
101
|
"multiPortals:update",
|
|
102
102
|
"multiPortals:firstOrCreate",
|
|
103
|
+
"multiPortals:setDefault",
|
|
103
104
|
"multiPortals:destroy",
|
|
104
105
|
"multiPortals:deploy",
|
|
105
106
|
"multiPortals:pullSource",
|
|
@@ -168,7 +169,7 @@ function formatInitPortalTitle(portalName) {
|
|
|
168
169
|
const title = portalName.split(/[-_]/).filter(Boolean).map((segment) => `${segment.charAt(0).toUpperCase()}${segment.slice(1)}`).join(" ");
|
|
169
170
|
return title || portalName;
|
|
170
171
|
}
|
|
171
|
-
function getDefaultMultiPortalRecord() {
|
|
172
|
+
function getDefaultMultiPortalRecord(options = {}) {
|
|
172
173
|
const portalName = getInitPortalName();
|
|
173
174
|
return {
|
|
174
175
|
uid: DEFAULT_MULTI_PORTAL_UID,
|
|
@@ -179,11 +180,12 @@ function getDefaultMultiPortalRecord() {
|
|
|
179
180
|
routePath: `/${portalName}`,
|
|
180
181
|
authCheck: true,
|
|
181
182
|
enabled: true,
|
|
183
|
+
...options.isDefault ? { isDefault: true } : {},
|
|
182
184
|
uiLayoutUid: "admin-layout-model"
|
|
183
185
|
};
|
|
184
186
|
}
|
|
185
187
|
function getFreshMultiPortalRecords() {
|
|
186
|
-
return [getDefaultMultiPortalRecord()];
|
|
188
|
+
return [getDefaultMultiPortalRecord({ isDefault: true })];
|
|
187
189
|
}
|
|
188
190
|
function getFixedLayoutMultiPortalRecords() {
|
|
189
191
|
return [
|
|
@@ -597,12 +599,14 @@ async function buildPortalStorageItem(portalDir, item) {
|
|
|
597
599
|
const buildEnv = getPortalStorageCommandEnv({
|
|
598
600
|
NOCOBASE_API_URL: getPortalStorageApiUrl(item.appName),
|
|
599
601
|
NOCOBASE_PORTAL_BASE: getPortalDeployBasePath(item.appName, item.portalName),
|
|
602
|
+
SKIP_YARN_COREPACK_CHECK: "1",
|
|
603
|
+
COREPACK_ENABLE_STRICT: "0",
|
|
600
604
|
COREPACK_ENABLE_PROJECT_SPEC: "0"
|
|
601
605
|
});
|
|
602
606
|
await appendPortalStorageLog(logPath, `Building portal ${item.appName}/${item.portalName}.`);
|
|
603
607
|
await appendPortalStorageLog(
|
|
604
608
|
logPath,
|
|
605
|
-
`Build environment: NOCOBASE_API_URL=${buildEnv.NOCOBASE_API_URL || ""} NOCOBASE_PORTAL_BASE=${buildEnv.NOCOBASE_PORTAL_BASE || ""} APP_PUBLIC_PATH=${buildEnv.APP_PUBLIC_PATH || ""}`
|
|
609
|
+
`Build environment: NOCOBASE_API_URL=${buildEnv.NOCOBASE_API_URL || ""} NOCOBASE_PORTAL_BASE=${buildEnv.NOCOBASE_PORTAL_BASE || ""} APP_PUBLIC_PATH=${buildEnv.APP_PUBLIC_PATH || ""} SKIP_YARN_COREPACK_CHECK=${buildEnv.SKIP_YARN_COREPACK_CHECK || ""} COREPACK_ENABLE_STRICT=${buildEnv.COREPACK_ENABLE_STRICT || ""} COREPACK_ENABLE_PROJECT_SPEC=${buildEnv.COREPACK_ENABLE_PROJECT_SPEC || ""}`
|
|
606
610
|
);
|
|
607
611
|
await runPortalStorageCommandOnce("yarn", ["build:html"], {
|
|
608
612
|
cwd: portalDir,
|
|
@@ -1033,6 +1037,37 @@ async function normalizeMultiPortalSlugValues(ctx, next) {
|
|
|
1033
1037
|
values.portalName = slug;
|
|
1034
1038
|
values.routePath = `/${slug}`;
|
|
1035
1039
|
}
|
|
1040
|
+
const repository = ctx.db.getRepository("multiPortals");
|
|
1041
|
+
const pendingPortalNames = /* @__PURE__ */ new Set();
|
|
1042
|
+
const targets = await getMultiPortalWriteTargets(ctx, ["uid"]);
|
|
1043
|
+
for (const { existing, values } of targets) {
|
|
1044
|
+
const portalName = values.portalName;
|
|
1045
|
+
if (typeof portalName !== "string" || !portalName) {
|
|
1046
|
+
continue;
|
|
1047
|
+
}
|
|
1048
|
+
if (pendingPortalNames.has(portalName)) {
|
|
1049
|
+
ctx.throw(409, ctx.t('Portal name "{{portalName}}" already exists', { ns: import_constants.NAMESPACE, portalName }));
|
|
1050
|
+
return;
|
|
1051
|
+
}
|
|
1052
|
+
pendingPortalNames.add(portalName);
|
|
1053
|
+
const conflict = await repository.findOne({
|
|
1054
|
+
filter: { portalName },
|
|
1055
|
+
fields: ["uid"]
|
|
1056
|
+
});
|
|
1057
|
+
if (conflict && conflict.get("uid") !== (existing == null ? void 0 : existing.get("uid"))) {
|
|
1058
|
+
ctx.throw(409, ctx.t('Portal name "{{portalName}}" already exists', { ns: import_constants.NAMESPACE, portalName }));
|
|
1059
|
+
return;
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
await next();
|
|
1063
|
+
}
|
|
1064
|
+
async function preventDirectDefaultPortalMutation(ctx, next) {
|
|
1065
|
+
for (const values of getMultiPortalWriteRecords(ctx)) {
|
|
1066
|
+
if (Object.prototype.hasOwnProperty.call(values, "isDefault")) {
|
|
1067
|
+
ctx.throw(400, ctx.t("Use multiPortals:setDefault to update the default Portal", { ns: import_constants.NAMESPACE }));
|
|
1068
|
+
return;
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1036
1071
|
await next();
|
|
1037
1072
|
}
|
|
1038
1073
|
function isUniqueConstraintViolation(error) {
|
|
@@ -1095,39 +1130,6 @@ async function seedHistoricalMultiPortals(db) {
|
|
|
1095
1130
|
}
|
|
1096
1131
|
await repairFixedLayoutMultiPortalRecords(db);
|
|
1097
1132
|
}
|
|
1098
|
-
async function preventUiLayoutRouteNameConflict(ctx, next) {
|
|
1099
|
-
const targets = await getMultiPortalWriteTargets(ctx, ["uid", "portalName", "uiLayoutUid"]);
|
|
1100
|
-
for (const { existing, values } of targets) {
|
|
1101
|
-
const existingUid = trimString(existing == null ? void 0 : existing.get("uid"));
|
|
1102
|
-
const uid = trimString(values.uid ?? existingUid);
|
|
1103
|
-
const portalName = trimString(values.portalName ?? (existing == null ? void 0 : existing.get("portalName")));
|
|
1104
|
-
const uiLayoutUid = trimString(values.uiLayoutUid ?? (existing == null ? void 0 : existing.get("uiLayoutUid")));
|
|
1105
|
-
const fixedPortal = getFixedLayoutMultiPortalRecord(existingUid) || getFixedLayoutMultiPortalRecord(uid);
|
|
1106
|
-
const canonicalPortal = (fixedPortal == null ? void 0 : fixedPortal.uid) === uid && (!existingUid || fixedPortal.uid === existingUid) && fixedPortal.portalName === portalName && fixedPortal.uiLayoutUid === uiLayoutUid;
|
|
1107
|
-
if (fixedPortal && !canonicalPortal) {
|
|
1108
|
-
ctx.throw(400, "Reserved Portal UID must match its canonical route and UI layout");
|
|
1109
|
-
return;
|
|
1110
|
-
}
|
|
1111
|
-
if (!portalName) {
|
|
1112
|
-
continue;
|
|
1113
|
-
}
|
|
1114
|
-
if (portalName === "admin" || portalName === "mobile") {
|
|
1115
|
-
continue;
|
|
1116
|
-
}
|
|
1117
|
-
const existingInitPortal = (existing == null ? void 0 : existing.get("uid")) === DEFAULT_MULTI_PORTAL_UID && existing.get("portalName") === portalName;
|
|
1118
|
-
const uiLayout = await ctx.db.getRepository("uiLayouts").findOne({
|
|
1119
|
-
filter: {
|
|
1120
|
-
routeName: portalName
|
|
1121
|
-
},
|
|
1122
|
-
fields: ["uid"]
|
|
1123
|
-
});
|
|
1124
|
-
if (uiLayout && !existingInitPortal) {
|
|
1125
|
-
ctx.throw(400, "Portal route name conflicts with an existing UI layout");
|
|
1126
|
-
return;
|
|
1127
|
-
}
|
|
1128
|
-
}
|
|
1129
|
-
await next();
|
|
1130
|
-
}
|
|
1131
1133
|
async function preventMultiPortalBackingLayoutChange(ctx, next) {
|
|
1132
1134
|
const targets = await getMultiPortalWriteTargets(ctx, ["uiLayoutUid"]);
|
|
1133
1135
|
for (const { existing, values } of targets) {
|
|
@@ -1242,7 +1244,6 @@ async function assertDesktopRouteParentsBelongToScope(ctx, scope, values = ((_a)
|
|
|
1242
1244
|
id: parentIds,
|
|
1243
1245
|
...scope.filter
|
|
1244
1246
|
},
|
|
1245
|
-
...transaction ? { lock: transaction.LOCK.UPDATE } : {},
|
|
1246
1247
|
transaction
|
|
1247
1248
|
});
|
|
1248
1249
|
if (new Set(normalizeDesktopRouteTargetIds(parents)).size !== new Set(parentIds.map(String)).size) {
|
|
@@ -1276,7 +1277,6 @@ async function assertDesktopRouteUpsertMatchesBelongToScope(ctx, scope, values =
|
|
|
1276
1277
|
...filter,
|
|
1277
1278
|
...scope.filter
|
|
1278
1279
|
},
|
|
1279
|
-
...transaction ? { lock: transaction.LOCK.UPDATE } : {},
|
|
1280
1280
|
transaction
|
|
1281
1281
|
});
|
|
1282
1282
|
const allMatchIds = normalizeDesktopRouteTargetIds(allMatches);
|
|
@@ -1691,7 +1691,7 @@ async function findDesktopRouteMutationTargets(ctx, scopeFilter, transaction, se
|
|
|
1691
1691
|
...filter ?? {},
|
|
1692
1692
|
...scopeFilter ?? {}
|
|
1693
1693
|
},
|
|
1694
|
-
...transaction ? { lock: transaction.LOCK.UPDATE } : {},
|
|
1694
|
+
...transaction && !scopeFilter ? { lock: transaction.LOCK.UPDATE } : {},
|
|
1695
1695
|
transaction
|
|
1696
1696
|
});
|
|
1697
1697
|
}
|
|
@@ -1843,7 +1843,6 @@ async function guardDesktopRouteMoveScope(ctx, next) {
|
|
|
1843
1843
|
id: routeIds,
|
|
1844
1844
|
...scope.filter
|
|
1845
1845
|
},
|
|
1846
|
-
lock: transaction.LOCK.UPDATE,
|
|
1847
1846
|
transaction
|
|
1848
1847
|
});
|
|
1849
1848
|
if (normalizeDesktopRouteTargetIds(allRoutes).join(",") !== normalizeDesktopRouteTargetIds(scopedRoutes).join(",") || scopedRoutes.length !== routeIds.length) {
|
|
@@ -1873,7 +1872,6 @@ async function guardDesktopRouteMoveScope(ctx, next) {
|
|
|
1873
1872
|
id: parentIds,
|
|
1874
1873
|
...scope.filter
|
|
1875
1874
|
},
|
|
1876
|
-
lock: transaction.LOCK.UPDATE,
|
|
1877
1875
|
transaction
|
|
1878
1876
|
});
|
|
1879
1877
|
if (normalizeDesktopRouteTargetIds(parents).join(",") !== parentIds.map(String).sort().join(",")) {
|
|
@@ -1921,7 +1919,6 @@ async function guardDesktopRouteMoveScope(ctx, next) {
|
|
|
1921
1919
|
$gte: targetSort
|
|
1922
1920
|
}
|
|
1923
1921
|
},
|
|
1924
|
-
lock: transaction.LOCK.UPDATE,
|
|
1925
1922
|
transaction
|
|
1926
1923
|
});
|
|
1927
1924
|
const affectedRouteIds = affectedRoutes.map((route) => route.get("id"));
|
|
@@ -2019,7 +2016,7 @@ async function findDesktopRouteDestroyRoots(ctx, transaction, scopeFilter) {
|
|
|
2019
2016
|
...scopeFilter ?? {},
|
|
2020
2017
|
...filterByTk.length ? { id: filterByTk } : {}
|
|
2021
2018
|
},
|
|
2022
|
-
lock: transaction.LOCK.UPDATE,
|
|
2019
|
+
...scopeFilter ? {} : { lock: transaction.LOCK.UPDATE },
|
|
2023
2020
|
transaction
|
|
2024
2021
|
});
|
|
2025
2022
|
return collectDesktopRouteIds(records);
|
|
@@ -2085,13 +2082,20 @@ async function detachDesktopRouteTreeOwner(ctx, routeIds, scope, transaction) {
|
|
|
2085
2082
|
}
|
|
2086
2083
|
async function detachOwnerAndFindDestroyRoots(ctx, routeIds, scope, transaction) {
|
|
2087
2084
|
var _a;
|
|
2085
|
+
await ctx.db.getRepository("desktopRoutes").find({
|
|
2086
|
+
fields: ["id"],
|
|
2087
|
+
filter: {
|
|
2088
|
+
id: routeIds
|
|
2089
|
+
},
|
|
2090
|
+
lock: transaction.LOCK.UPDATE,
|
|
2091
|
+
transaction
|
|
2092
|
+
});
|
|
2088
2093
|
const routes = await ctx.db.getRepository("desktopRoutes").find({
|
|
2089
2094
|
fields: ["id", "parentId"],
|
|
2090
2095
|
appends: ["multiPortals", "uiLayouts"],
|
|
2091
2096
|
filter: {
|
|
2092
2097
|
id: routeIds
|
|
2093
2098
|
},
|
|
2094
|
-
lock: transaction.LOCK.UPDATE,
|
|
2095
2099
|
transaction
|
|
2096
2100
|
});
|
|
2097
2101
|
const routesById = new Map(routes.map((route) => [String(route.get("id")), route]));
|
|
@@ -2196,6 +2200,115 @@ async function listEnabledMultiPortals(ctx, next) {
|
|
|
2196
2200
|
ctx.body = records.map((record) => pickMultiPortalRuntimeFields(record));
|
|
2197
2201
|
await next();
|
|
2198
2202
|
}
|
|
2203
|
+
const DEFAULT_MULTI_PORTAL_RESPONSE_FIELDS = ["uid", "portalType", "routePath"];
|
|
2204
|
+
function getDefaultMultiPortalType(record) {
|
|
2205
|
+
const portalType = record.get("portalType");
|
|
2206
|
+
if (portalType === null || portalType === void 0) {
|
|
2207
|
+
return "no-code";
|
|
2208
|
+
}
|
|
2209
|
+
return typeof portalType === "string" && isInitPortalType(portalType) ? portalType : null;
|
|
2210
|
+
}
|
|
2211
|
+
function pickDefaultMultiPortalFields(record) {
|
|
2212
|
+
return {
|
|
2213
|
+
uid: String(record.get("uid")),
|
|
2214
|
+
portalType: getDefaultMultiPortalType(record) || "no-code",
|
|
2215
|
+
routePath: String(record.get("routePath"))
|
|
2216
|
+
};
|
|
2217
|
+
}
|
|
2218
|
+
async function findEnabledDefaultMultiPortal(ctx, transaction) {
|
|
2219
|
+
const record = await ctx.db.getRepository("multiPortals").findOne({
|
|
2220
|
+
filter: {
|
|
2221
|
+
enabled: true,
|
|
2222
|
+
isDefault: true
|
|
2223
|
+
},
|
|
2224
|
+
fields: [...DEFAULT_MULTI_PORTAL_RESPONSE_FIELDS, "uiLayoutUid"],
|
|
2225
|
+
appends: ["uiLayout"],
|
|
2226
|
+
transaction
|
|
2227
|
+
});
|
|
2228
|
+
if (!record) {
|
|
2229
|
+
return null;
|
|
2230
|
+
}
|
|
2231
|
+
const portalType = getDefaultMultiPortalType(record);
|
|
2232
|
+
if (!portalType) {
|
|
2233
|
+
return null;
|
|
2234
|
+
}
|
|
2235
|
+
if (portalType === "no-code") {
|
|
2236
|
+
const uiLayout = record.get("uiLayout");
|
|
2237
|
+
if (!uiLayout || uiLayout.get("enabled") !== true) {
|
|
2238
|
+
return null;
|
|
2239
|
+
}
|
|
2240
|
+
}
|
|
2241
|
+
return record;
|
|
2242
|
+
}
|
|
2243
|
+
async function getDefaultMultiPortal(ctx, next) {
|
|
2244
|
+
const record = await findEnabledDefaultMultiPortal(ctx);
|
|
2245
|
+
ctx.body = record ? pickDefaultMultiPortalFields(record) : null;
|
|
2246
|
+
ctx.status = 200;
|
|
2247
|
+
await next();
|
|
2248
|
+
}
|
|
2249
|
+
async function setDefaultMultiPortal(ctx, next) {
|
|
2250
|
+
var _a;
|
|
2251
|
+
const filterByTk = (_a = ctx.action) == null ? void 0 : _a.params.filterByTk;
|
|
2252
|
+
if (filterByTk === void 0 || filterByTk === null || filterByTk === "") {
|
|
2253
|
+
ctx.throw(400, ctx.t("filterByTk is required", { ns: import_constants.NAMESPACE }));
|
|
2254
|
+
return;
|
|
2255
|
+
}
|
|
2256
|
+
const repository = ctx.db.getRepository("multiPortals");
|
|
2257
|
+
const updated = await ctx.db.sequelize.transaction(async (transaction) => {
|
|
2258
|
+
const target = await repository.findOne({
|
|
2259
|
+
filterByTk,
|
|
2260
|
+
fields: [...DEFAULT_MULTI_PORTAL_RESPONSE_FIELDS, "enabled", "uiLayoutUid"],
|
|
2261
|
+
lock: transaction.LOCK.UPDATE,
|
|
2262
|
+
transaction
|
|
2263
|
+
});
|
|
2264
|
+
if (!target) {
|
|
2265
|
+
ctx.throw(404, ctx.t("Portal not found", { ns: import_constants.NAMESPACE }));
|
|
2266
|
+
return null;
|
|
2267
|
+
}
|
|
2268
|
+
if (target.get("enabled") !== true) {
|
|
2269
|
+
ctx.throw(400, ctx.t("Disabled Portal cannot be set as default", { ns: import_constants.NAMESPACE }));
|
|
2270
|
+
return null;
|
|
2271
|
+
}
|
|
2272
|
+
const portalType = getDefaultMultiPortalType(target);
|
|
2273
|
+
if (!portalType) {
|
|
2274
|
+
ctx.throw(400, ctx.t("Unsupported Portal type cannot be set as default", { ns: import_constants.NAMESPACE }));
|
|
2275
|
+
return null;
|
|
2276
|
+
}
|
|
2277
|
+
if (portalType === "no-code") {
|
|
2278
|
+
const uiLayoutUid = target.get("uiLayoutUid");
|
|
2279
|
+
const uiLayout = typeof uiLayoutUid === "string" && uiLayoutUid ? await ctx.db.getRepository("uiLayouts").findOne({
|
|
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
|
+
}
|
|
2292
|
+
}
|
|
2293
|
+
await repository.update({
|
|
2294
|
+
filter: { isDefault: true },
|
|
2295
|
+
values: { isDefault: null },
|
|
2296
|
+
transaction
|
|
2297
|
+
});
|
|
2298
|
+
await repository.update({
|
|
2299
|
+
filterByTk,
|
|
2300
|
+
values: { isDefault: true },
|
|
2301
|
+
transaction
|
|
2302
|
+
});
|
|
2303
|
+
return repository.findOne({
|
|
2304
|
+
filterByTk,
|
|
2305
|
+
fields: [...DEFAULT_MULTI_PORTAL_RESPONSE_FIELDS],
|
|
2306
|
+
transaction
|
|
2307
|
+
});
|
|
2308
|
+
});
|
|
2309
|
+
ctx.body = updated ? pickDefaultMultiPortalFields(updated) : null;
|
|
2310
|
+
await next();
|
|
2311
|
+
}
|
|
2199
2312
|
async function listAccessibleMultiPortals(ctx, next) {
|
|
2200
2313
|
const accessiblePortalUids = await listCurrentRoleAccessibleMultiPortalUids(ctx);
|
|
2201
2314
|
const records = await ctx.db.getRepository("multiPortals").find({
|
|
@@ -2399,10 +2512,9 @@ class PluginMultiPortalServer extends import_server.Plugin {
|
|
|
2399
2512
|
}
|
|
2400
2513
|
await run();
|
|
2401
2514
|
}
|
|
2402
|
-
async
|
|
2403
|
-
await import_fs.default.promises.rm((0, import_utils.storagePathJoin)("portals", item.appName, item.portalName, "dist"), {
|
|
2404
|
-
force: true
|
|
2405
|
-
recursive: true
|
|
2515
|
+
async removePortalStorageIndexHtml(item) {
|
|
2516
|
+
await import_fs.default.promises.rm((0, import_utils.storagePathJoin)("portals", item.appName, item.portalName, "dist", "index.html"), {
|
|
2517
|
+
force: true
|
|
2406
2518
|
});
|
|
2407
2519
|
}
|
|
2408
2520
|
waitForPortalStorageTasks() {
|
|
@@ -2446,8 +2558,8 @@ class PluginMultiPortalServer extends import_server.Plugin {
|
|
|
2446
2558
|
return;
|
|
2447
2559
|
}
|
|
2448
2560
|
this.logPortalBuildHtml(item, "skipped", "the portal is disabled");
|
|
2449
|
-
await this.
|
|
2450
|
-
await appendPortalStorageLog(logPath, `Portal
|
|
2561
|
+
await this.removePortalStorageIndexHtml(item);
|
|
2562
|
+
await appendPortalStorageLog(logPath, `Portal index.html removed for ${item.appName}/${item.portalName}.`);
|
|
2451
2563
|
} catch (error) {
|
|
2452
2564
|
await appendPortalStorageLog(
|
|
2453
2565
|
logPath,
|
|
@@ -2489,15 +2601,15 @@ class PluginMultiPortalServer extends import_server.Plugin {
|
|
|
2489
2601
|
return;
|
|
2490
2602
|
}
|
|
2491
2603
|
this.logPortalBuildHtml(item, "skipped", "the portal is disabled");
|
|
2492
|
-
await this.
|
|
2493
|
-
await appendPortalStorageLog(logPath, `Portal
|
|
2604
|
+
await this.removePortalStorageIndexHtml(item);
|
|
2605
|
+
await appendPortalStorageLog(logPath, `Portal index.html removed for ${item.appName}/${item.portalName}.`);
|
|
2494
2606
|
}
|
|
2495
2607
|
async syncMultiPortalStorageItem(multiPortal, options, syncPrevious = false, forceBuild = false) {
|
|
2496
2608
|
const currentItem = this.getMultiPortalStorageItem(multiPortal);
|
|
2497
2609
|
const previousItem = syncPrevious ? this.getMultiPortalStorageItem(multiPortal, true) : null;
|
|
2498
2610
|
await this.runPortalStorageTask(async () => {
|
|
2499
2611
|
if (previousItem && (!currentItem || previousItem.appName !== currentItem.appName || previousItem.portalName !== currentItem.portalName || !currentItem.enabled)) {
|
|
2500
|
-
await this.
|
|
2612
|
+
await this.removePortalStorageIndexHtml(previousItem);
|
|
2501
2613
|
}
|
|
2502
2614
|
if (currentItem) {
|
|
2503
2615
|
await this.ensurePortalStorageItem(currentItem, { forceBuild });
|
|
@@ -2847,26 +2959,29 @@ class PluginMultiPortalServer extends import_server.Plugin {
|
|
|
2847
2959
|
"desktopRoutes:listRolePermissionTargets",
|
|
2848
2960
|
mapMultiPortalLayoutToUiLayoutForRolePermissionTargets
|
|
2849
2961
|
);
|
|
2962
|
+
this.app.resourceManager.registerPreActionHandler("multiPortals:create", preventDirectDefaultPortalMutation);
|
|
2850
2963
|
this.app.resourceManager.registerPreActionHandler("multiPortals:create", captureSkipCreatePortalDirectory);
|
|
2851
2964
|
this.app.resourceManager.registerPreActionHandler("multiPortals:create", normalizeMultiPortalSlugValues);
|
|
2852
|
-
this.app.resourceManager.registerPreActionHandler("multiPortals:
|
|
2965
|
+
this.app.resourceManager.registerPreActionHandler("multiPortals:update", preventDirectDefaultPortalMutation);
|
|
2853
2966
|
this.app.resourceManager.registerPreActionHandler("multiPortals:update", preventMultiPortalBackingLayoutChange);
|
|
2854
2967
|
this.app.resourceManager.registerPreActionHandler("multiPortals:update", normalizeMultiPortalSlugValues);
|
|
2855
|
-
this.app.resourceManager.registerPreActionHandler("multiPortals:
|
|
2968
|
+
this.app.resourceManager.registerPreActionHandler("multiPortals:firstOrCreate", preventDirectDefaultPortalMutation);
|
|
2856
2969
|
this.app.resourceManager.registerPreActionHandler(
|
|
2857
2970
|
"multiPortals:firstOrCreate",
|
|
2858
2971
|
preventMultiPortalBackingLayoutChange
|
|
2859
2972
|
);
|
|
2860
2973
|
this.app.resourceManager.registerPreActionHandler("multiPortals:firstOrCreate", captureSkipCreatePortalDirectory);
|
|
2861
2974
|
this.app.resourceManager.registerPreActionHandler("multiPortals:firstOrCreate", normalizeMultiPortalSlugValues);
|
|
2862
|
-
this.app.resourceManager.registerPreActionHandler(
|
|
2975
|
+
this.app.resourceManager.registerPreActionHandler(
|
|
2976
|
+
"multiPortals:updateOrCreate",
|
|
2977
|
+
preventDirectDefaultPortalMutation
|
|
2978
|
+
);
|
|
2863
2979
|
this.app.resourceManager.registerPreActionHandler(
|
|
2864
2980
|
"multiPortals:updateOrCreate",
|
|
2865
2981
|
preventMultiPortalBackingLayoutChange
|
|
2866
2982
|
);
|
|
2867
2983
|
this.app.resourceManager.registerPreActionHandler("multiPortals:updateOrCreate", captureSkipCreatePortalDirectory);
|
|
2868
2984
|
this.app.resourceManager.registerPreActionHandler("multiPortals:updateOrCreate", normalizeMultiPortalSlugValues);
|
|
2869
|
-
this.app.resourceManager.registerPreActionHandler("multiPortals:updateOrCreate", preventUiLayoutRouteNameConflict);
|
|
2870
2985
|
this.app.resourceManager.registerPreActionHandler("desktopRoutes:create", addDesktopRouteCreateMultiPortal, {
|
|
2871
2986
|
after: UI_LAYOUT_DESKTOP_ROUTE_WRITE_LAYOUT_HANDLER_TAG
|
|
2872
2987
|
});
|
|
@@ -2891,12 +3006,15 @@ class PluginMultiPortalServer extends import_server.Plugin {
|
|
|
2891
3006
|
actions: ROLE_MULTI_PORTAL_PERMISSION_ACTIONS
|
|
2892
3007
|
});
|
|
2893
3008
|
this.app.acl.allow("multiPortals", "listEnabled", "public");
|
|
3009
|
+
this.app.acl.allow("multiPortals", "getDefault", "public");
|
|
2894
3010
|
this.app.acl.allow("multiPortals", "listAccessible", "loggedIn");
|
|
2895
3011
|
this.app.resourceManager.use(createPortalDeployUploadMiddleware(), {
|
|
2896
3012
|
tag: "multiPortalDeployUpload",
|
|
2897
3013
|
after: "acl"
|
|
2898
3014
|
});
|
|
2899
3015
|
this.app.resourceManager.registerActionHandler("multiPortals:listEnabled", listEnabledMultiPortals);
|
|
3016
|
+
this.app.resourceManager.registerActionHandler("multiPortals:getDefault", getDefaultMultiPortal);
|
|
3017
|
+
this.app.resourceManager.registerActionHandler("multiPortals:setDefault", setDefaultMultiPortal);
|
|
2900
3018
|
this.app.resourceManager.registerActionHandler("multiPortals:listAccessible", listAccessibleMultiPortals);
|
|
2901
3019
|
this.app.resourceManager.registerActionHandler("multiPortals:deploy", async (ctx, next) => {
|
|
2902
3020
|
await this.deployPortalDist(ctx, next);
|
|
@@ -2921,6 +3039,11 @@ class PluginMultiPortalServer extends import_server.Plugin {
|
|
|
2921
3039
|
(0, import_ensureDefaultRoleMultiPortalAccess.applyDefaultRoleMultiPortalAccess)(role);
|
|
2922
3040
|
});
|
|
2923
3041
|
this.app.db.on("desktopRoutes.afterCreate", reconcileCreatedDesktopRoutePermissions);
|
|
3042
|
+
this.app.db.on("multiPortals.beforeUpdate", (multiPortal) => {
|
|
3043
|
+
if (multiPortal.get("enabled") === false && multiPortal.get("isDefault") === true) {
|
|
3044
|
+
multiPortal.set("isDefault", null);
|
|
3045
|
+
}
|
|
3046
|
+
});
|
|
2924
3047
|
this.app.db.on("multiPortals.afterCreate", async (multiPortal, options) => {
|
|
2925
3048
|
await grantDefaultAccessToNewMultiPortal(this.app.db, multiPortal, options);
|
|
2926
3049
|
await this.publishAppManifestItem(multiPortal, options);
|