@saltcorn/server 1.1.1-beta.5 → 1.1.1-beta.7
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/CHANGELOG.md +6 -0
- package/auth/admin.js +8 -0
- package/locales/en.json +16 -1
- package/markup/admin.js +8 -3
- package/markup/blockly.js +4 -4
- package/package.json +9 -9
- package/public/blockly/blockly_compressed.js +2016 -0
- package/public/blockly/blockly_compressed.js.map +1 -0
- package/public/blockly/blocks_compressed.js +212 -0
- package/public/blockly/blocks_compressed.js.map +1 -0
- package/public/blockly/javascript_compressed.js +121 -0
- package/public/blockly/javascript_compressed.js.map +1 -0
- package/public/blockly/msg/ab.js +440 -0
- package/public/blockly/msg/ace.js +440 -0
- package/public/blockly/msg/af.js +440 -0
- package/public/blockly/msg/am.js +440 -0
- package/public/blockly/msg/ar.js +440 -0
- package/public/blockly/msg/ast.js +440 -0
- package/public/blockly/msg/az.js +440 -0
- package/public/blockly/msg/ba.js +440 -0
- package/public/blockly/msg/bcc.js +440 -0
- package/public/blockly/msg/be-tarask.js +440 -0
- package/public/blockly/msg/be.js +440 -0
- package/public/blockly/msg/bg.js +440 -0
- package/public/blockly/msg/bn.js +440 -0
- package/public/blockly/msg/br.js +440 -0
- package/public/blockly/msg/bs.js +440 -0
- package/public/blockly/msg/ca.js +440 -0
- package/public/blockly/msg/cdo.js +440 -0
- package/public/blockly/msg/cs.js +440 -0
- package/public/blockly/msg/da.js +440 -0
- package/public/blockly/msg/de.js +440 -0
- package/public/blockly/msg/diq.js +440 -0
- package/public/blockly/msg/dty.js +440 -0
- package/public/blockly/msg/ee.js +440 -0
- package/public/blockly/msg/el.js +440 -0
- package/public/blockly/msg/en-gb.js +440 -0
- package/public/blockly/msg/en.js +440 -0
- package/public/blockly/msg/eo.js +440 -0
- package/public/blockly/msg/es.js +440 -0
- package/public/blockly/msg/et.js +440 -0
- package/public/blockly/msg/eu.js +440 -0
- package/public/blockly/msg/fa.js +440 -0
- package/public/blockly/msg/fi.js +440 -0
- package/public/blockly/msg/fo.js +440 -0
- package/public/blockly/msg/fr.js +440 -0
- package/public/blockly/msg/frr.js +440 -0
- package/public/blockly/msg/gl.js +440 -0
- package/public/blockly/msg/gn.js +440 -0
- package/public/blockly/msg/gor.js +440 -0
- package/public/blockly/msg/ha.js +440 -0
- package/public/blockly/msg/hak.js +440 -0
- package/public/blockly/msg/he.js +440 -0
- package/public/blockly/msg/hi.js +440 -0
- package/public/blockly/msg/hr.js +440 -0
- package/public/blockly/msg/hrx.js +440 -0
- package/public/blockly/msg/hu.js +440 -0
- package/public/blockly/msg/hy.js +440 -0
- package/public/blockly/msg/ia.js +440 -0
- package/public/blockly/msg/id.js +440 -0
- package/public/blockly/msg/ig.js +440 -0
- package/public/blockly/msg/inh.js +440 -0
- package/public/blockly/msg/is.js +440 -0
- package/public/blockly/msg/it.js +440 -0
- package/public/blockly/msg/ja.js +440 -0
- package/public/blockly/msg/ka.js +440 -0
- package/public/blockly/msg/kab.js +440 -0
- package/public/blockly/msg/kbd-cyrl.js +440 -0
- package/public/blockly/msg/km.js +440 -0
- package/public/blockly/msg/kn.js +440 -0
- package/public/blockly/msg/ko.js +440 -0
- package/public/blockly/msg/ksh.js +440 -0
- package/public/blockly/msg/ku-latn.js +440 -0
- package/public/blockly/msg/ky.js +440 -0
- package/public/blockly/msg/la.js +440 -0
- package/public/blockly/msg/lb.js +440 -0
- package/public/blockly/msg/lki.js +440 -0
- package/public/blockly/msg/lo.js +440 -0
- package/public/blockly/msg/lrc.js +440 -0
- package/public/blockly/msg/lt.js +440 -0
- package/public/blockly/msg/lv.js +440 -0
- package/public/blockly/msg/mg.js +440 -0
- package/public/blockly/msg/mk.js +440 -0
- package/public/blockly/msg/ml.js +440 -0
- package/public/blockly/msg/mnw.js +440 -0
- package/public/blockly/msg/ms.js +440 -0
- package/public/blockly/msg/msg.d.ts +444 -0
- package/public/blockly/msg/my.js +440 -0
- package/public/blockly/msg/mzn.js +440 -0
- package/public/blockly/msg/nb.js +440 -0
- package/public/blockly/msg/ne.js +440 -0
- package/public/blockly/msg/nl.js +440 -0
- package/public/blockly/msg/oc.js +440 -0
- package/public/blockly/msg/olo.js +440 -0
- package/public/blockly/msg/pa.js +440 -0
- package/public/blockly/msg/pl.js +440 -0
- package/public/blockly/msg/pms.js +440 -0
- package/public/blockly/msg/ps.js +440 -0
- package/public/blockly/msg/pt-br.js +440 -0
- package/public/blockly/msg/pt.js +440 -0
- package/public/blockly/msg/ro.js +440 -0
- package/public/blockly/msg/ru.js +440 -0
- package/public/blockly/msg/sc.js +440 -0
- package/public/blockly/msg/sco.js +440 -0
- package/public/blockly/msg/sd.js +440 -0
- package/public/blockly/msg/shn.js +440 -0
- package/public/blockly/msg/si.js +440 -0
- package/public/blockly/msg/sk.js +440 -0
- package/public/blockly/msg/skr-arab.js +440 -0
- package/public/blockly/msg/sl.js +440 -0
- package/public/blockly/msg/smn.js +440 -0
- package/public/blockly/msg/sq.js +440 -0
- package/public/blockly/msg/sr-latn.js +440 -0
- package/public/blockly/msg/sr.js +440 -0
- package/public/blockly/msg/sv.js +440 -0
- package/public/blockly/msg/sw.js +440 -0
- package/public/blockly/msg/ta.js +440 -0
- package/public/blockly/msg/tcy.js +440 -0
- package/public/blockly/msg/te.js +440 -0
- package/public/blockly/msg/th.js +440 -0
- package/public/blockly/msg/ti.js +440 -0
- package/public/blockly/msg/tl.js +440 -0
- package/public/blockly/msg/tlh.js +440 -0
- package/public/blockly/msg/tr.js +440 -0
- package/public/blockly/msg/ug-arab.js +440 -0
- package/public/blockly/msg/uk.js +440 -0
- package/public/blockly/msg/ur.js +440 -0
- package/public/blockly/msg/uz.js +440 -0
- package/public/blockly/msg/vi.js +440 -0
- package/public/blockly/msg/xmf.js +440 -0
- package/public/blockly/msg/yo.js +440 -0
- package/public/blockly/msg/yue.js +440 -0
- package/public/blockly/msg/zgh.js +440 -0
- package/public/blockly/msg/zh-hans.js +440 -0
- package/public/blockly/msg/zh-hant.js +440 -0
- package/public/saltcorn-common.js +8 -1
- package/public/saltcorn.js +12 -0
- package/routes/actions.js +32 -25
- package/routes/admin.js +90 -63
- package/routes/common_lists.js +46 -24
- package/routes/fields.js +31 -9
- package/routes/list.js +17 -4
- package/routes/notifications.js +27 -20
- package/routes/pageedit.js +14 -13
- package/routes/plugins.js +0 -32
- package/routes/tables.js +173 -92
- package/routes/utils.js +27 -0
- package/routes/view.js +2 -1
- package/routes/viewedit.js +14 -13
- package/serve.js +52 -1
- package/tests/api.test.js +0 -18
- package/tests/plugins.test.js +2 -2
- package/wrapper.js +80 -42
package/routes/viewedit.js
CHANGED
|
@@ -19,6 +19,7 @@ const {
|
|
|
19
19
|
addOnDoneRedirect,
|
|
20
20
|
is_relative_url,
|
|
21
21
|
setTenant,
|
|
22
|
+
isAdminOrHasConfigMinRole,
|
|
22
23
|
} = require("./utils.js");
|
|
23
24
|
const { setTableRefs, viewsList } = require("./common_lists");
|
|
24
25
|
const Form = require("@saltcorn/data/models/form");
|
|
@@ -56,7 +57,7 @@ module.exports = router;
|
|
|
56
57
|
*/
|
|
57
58
|
router.get(
|
|
58
59
|
"/",
|
|
59
|
-
|
|
60
|
+
isAdminOrHasConfigMinRole("min_role_edit_views"),
|
|
60
61
|
error_catcher(async (req, res) => {
|
|
61
62
|
let orderBy = "name";
|
|
62
63
|
if (req.query._sortby === "viewtemplate") orderBy = "viewtemplate";
|
|
@@ -353,7 +354,7 @@ const viewForm = async (req, tableOptions, roles, pages, values) => {
|
|
|
353
354
|
*/
|
|
354
355
|
router.get(
|
|
355
356
|
"/edit/:viewname",
|
|
356
|
-
|
|
357
|
+
isAdminOrHasConfigMinRole("min_role_edit_views"),
|
|
357
358
|
error_catcher(async (req, res) => {
|
|
358
359
|
const { viewname } = req.params;
|
|
359
360
|
|
|
@@ -446,7 +447,7 @@ router.get(
|
|
|
446
447
|
*/
|
|
447
448
|
router.get(
|
|
448
449
|
"/new",
|
|
449
|
-
|
|
450
|
+
isAdminOrHasConfigMinRole("min_role_edit_views"),
|
|
450
451
|
error_catcher(async (req, res) => {
|
|
451
452
|
const tables = await Table.find_with_external();
|
|
452
453
|
const tableOptions = tables.map((t) => t.name);
|
|
@@ -484,7 +485,7 @@ router.get(
|
|
|
484
485
|
*/
|
|
485
486
|
router.post(
|
|
486
487
|
"/save",
|
|
487
|
-
|
|
488
|
+
isAdminOrHasConfigMinRole("min_role_edit_views"),
|
|
488
489
|
error_catcher(async (req, res) => {
|
|
489
490
|
const tables = await Table.find_with_external();
|
|
490
491
|
const tableOptions = tables.map((t) => t.name);
|
|
@@ -671,7 +672,7 @@ const respondWorkflow = (view, wf, wfres, req, res, table) => {
|
|
|
671
672
|
*/
|
|
672
673
|
router.get(
|
|
673
674
|
"/config/:name",
|
|
674
|
-
|
|
675
|
+
isAdminOrHasConfigMinRole("min_role_edit_views"),
|
|
675
676
|
error_catcher(async (req, res) => {
|
|
676
677
|
req.socket.on("close", () => {
|
|
677
678
|
File.destroyDirCache();
|
|
@@ -719,7 +720,7 @@ router.get(
|
|
|
719
720
|
*/
|
|
720
721
|
router.post(
|
|
721
722
|
"/config/:name",
|
|
722
|
-
|
|
723
|
+
isAdminOrHasConfigMinRole("min_role_edit_views"),
|
|
723
724
|
setTenant,
|
|
724
725
|
error_catcher(async (req, res) => {
|
|
725
726
|
const { name } = req.params;
|
|
@@ -760,7 +761,7 @@ router.post(
|
|
|
760
761
|
*/
|
|
761
762
|
router.post(
|
|
762
763
|
"/add-to-menu/:viewname",
|
|
763
|
-
|
|
764
|
+
isAdminOrHasConfigMinRole("min_role_edit_views"),
|
|
764
765
|
error_catcher(async (req, res) => {
|
|
765
766
|
const { viewname } = req.params;
|
|
766
767
|
const view = await View.findOne({ name: viewname });
|
|
@@ -795,7 +796,7 @@ router.post(
|
|
|
795
796
|
*/
|
|
796
797
|
router.post(
|
|
797
798
|
"/clone/:id",
|
|
798
|
-
|
|
799
|
+
isAdminOrHasConfigMinRole("min_role_edit_views"),
|
|
799
800
|
error_catcher(async (req, res) => {
|
|
800
801
|
const { id } = req.params;
|
|
801
802
|
const view = await View.findOne({ id });
|
|
@@ -825,7 +826,7 @@ router.post(
|
|
|
825
826
|
*/
|
|
826
827
|
router.post(
|
|
827
828
|
"/delete/:id",
|
|
828
|
-
|
|
829
|
+
isAdminOrHasConfigMinRole("min_role_edit_views"),
|
|
829
830
|
error_catcher(async (req, res) => {
|
|
830
831
|
const { id } = req.params;
|
|
831
832
|
await View.delete({ id });
|
|
@@ -847,7 +848,7 @@ router.post(
|
|
|
847
848
|
*/
|
|
848
849
|
router.post(
|
|
849
850
|
"/savebuilder/:id",
|
|
850
|
-
|
|
851
|
+
isAdminOrHasConfigMinRole("min_role_edit_views"),
|
|
851
852
|
error_catcher(async (req, res) => {
|
|
852
853
|
const { id } = req.params;
|
|
853
854
|
|
|
@@ -874,7 +875,7 @@ router.post(
|
|
|
874
875
|
*/
|
|
875
876
|
router.post(
|
|
876
877
|
"/saveconfig/:viewname",
|
|
877
|
-
|
|
878
|
+
isAdminOrHasConfigMinRole("min_role_edit_views"),
|
|
878
879
|
setTenant,
|
|
879
880
|
error_catcher(async (req, res) => {
|
|
880
881
|
const { viewname } = req.params;
|
|
@@ -922,7 +923,7 @@ router.post(
|
|
|
922
923
|
*/
|
|
923
924
|
router.post(
|
|
924
925
|
"/setrole/:id",
|
|
925
|
-
|
|
926
|
+
isAdminOrHasConfigMinRole("min_role_edit_views"),
|
|
926
927
|
error_catcher(async (req, res) => {
|
|
927
928
|
const { id } = req.params;
|
|
928
929
|
const role = req.body.role;
|
|
@@ -952,7 +953,7 @@ router.post(
|
|
|
952
953
|
|
|
953
954
|
router.post(
|
|
954
955
|
"/test/inserter",
|
|
955
|
-
|
|
956
|
+
isAdminOrHasConfigMinRole("min_role_edit_views"),
|
|
956
957
|
error_catcher(async (req, res) => {
|
|
957
958
|
const view = await View.create(req.body);
|
|
958
959
|
res.json({ view });
|
package/serve.js
CHANGED
|
@@ -50,7 +50,9 @@ const {
|
|
|
50
50
|
} = require("@saltcorn/admin-models/models/tenant");
|
|
51
51
|
const { auto_backup_now } = require("@saltcorn/admin-models/models/backup");
|
|
52
52
|
const Snapshot = require("@saltcorn/admin-models/models/snapshot");
|
|
53
|
-
const { writeFileSync } = require("fs");
|
|
53
|
+
const { writeFileSync, rmdirSync, readFileSync } = require("fs");
|
|
54
|
+
const { pathExistsSync } = require("fs-extra");
|
|
55
|
+
const envPaths = require("env-paths");
|
|
54
56
|
|
|
55
57
|
const take_snapshot = async () => {
|
|
56
58
|
return await Snapshot.take_if_changed();
|
|
@@ -88,6 +90,54 @@ const ensureEnginesCache = async () => {
|
|
|
88
90
|
}
|
|
89
91
|
};
|
|
90
92
|
|
|
93
|
+
/**
|
|
94
|
+
* validate all plugins folders and remove invalid entries
|
|
95
|
+
* A folder is invalid when it has dependencies but not node_modules directory
|
|
96
|
+
*/
|
|
97
|
+
const ensurePluginsFolder = async () => {
|
|
98
|
+
const rootFolder = envPaths("saltcorn", { suffix: "plugins" }).data;
|
|
99
|
+
const staticDeps = ["@saltcorn/markup", "@saltcorn/data", "jest"];
|
|
100
|
+
const allPluginFolders = new Set();
|
|
101
|
+
await eachTenant(async () => {
|
|
102
|
+
const allPlugins = (await Plugin.find()).filter(
|
|
103
|
+
(p) => !["base", "sbadmin2"].includes(p.name)
|
|
104
|
+
);
|
|
105
|
+
for (const plugin of allPlugins) {
|
|
106
|
+
const tokens =
|
|
107
|
+
plugin.source === "npm"
|
|
108
|
+
? plugin.location.split("/")
|
|
109
|
+
: plugin.name.split("/");
|
|
110
|
+
const pluginDir = path.join(
|
|
111
|
+
rootFolder,
|
|
112
|
+
plugin.source === "git" ? "git_plugins" : "plugins_folder",
|
|
113
|
+
...tokens
|
|
114
|
+
);
|
|
115
|
+
allPluginFolders.add(pluginDir);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
for (const folder of allPluginFolders) {
|
|
119
|
+
try {
|
|
120
|
+
if (pathExistsSync(folder)) {
|
|
121
|
+
const packageJson = JSON.parse(
|
|
122
|
+
readFileSync(path.join(folder, "package.json"))
|
|
123
|
+
);
|
|
124
|
+
if (
|
|
125
|
+
(Object.keys(packageJson.dependencies || {}).some(
|
|
126
|
+
(d) => !staticDeps.includes(d)
|
|
127
|
+
) ||
|
|
128
|
+
Object.keys(packageJson.devDependencies || {}).some(
|
|
129
|
+
(d) => !staticDeps.includes(d)
|
|
130
|
+
)) &&
|
|
131
|
+
!pathExistsSync(path.join(folder, "node_modules"))
|
|
132
|
+
)
|
|
133
|
+
rmdirSync(folder, { recursive: true });
|
|
134
|
+
}
|
|
135
|
+
} catch (e) {
|
|
136
|
+
console.log(`Error checking plugin folder: ${e.message || e}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
91
141
|
// helpful https://gist.github.com/jpoehls/2232358
|
|
92
142
|
/**
|
|
93
143
|
* @param {object} opts
|
|
@@ -236,6 +286,7 @@ module.exports =
|
|
|
236
286
|
if (cluster.isMaster) {
|
|
237
287
|
ensureJwtSecret();
|
|
238
288
|
await ensureEnginesCache();
|
|
289
|
+
await ensurePluginsFolder();
|
|
239
290
|
}
|
|
240
291
|
process.on("unhandledRejection", (reason, p) => {
|
|
241
292
|
console.error(reason, "Unhandled Rejection at Promise");
|
package/tests/api.test.js
CHANGED
|
@@ -512,8 +512,6 @@ describe("API action", () => {
|
|
|
512
512
|
|
|
513
513
|
describe("test share handler", () => {
|
|
514
514
|
beforeAll(async () => {
|
|
515
|
-
await getState().setConfig("pwa_share_to_enabled", true);
|
|
516
|
-
|
|
517
515
|
const sharedData = await Table.create("shared_data");
|
|
518
516
|
await Field.create({
|
|
519
517
|
table: sharedData,
|
|
@@ -562,22 +560,6 @@ describe("test share handler", () => {
|
|
|
562
560
|
expect(row).toBeDefined();
|
|
563
561
|
});
|
|
564
562
|
|
|
565
|
-
it("pwa_disabled as admin", async () => {
|
|
566
|
-
const app = await getApp({ disableCsrf: true });
|
|
567
|
-
const loginCookie = await getAdminLoginCookie();
|
|
568
|
-
await getState().setConfig("pwa_share_to_enabled", false);
|
|
569
|
-
await request(app)
|
|
570
|
-
.post("/notifications/share-handler")
|
|
571
|
-
.set("Cookie", loginCookie)
|
|
572
|
-
.send({ title: "pwa_disabled_as_admin" })
|
|
573
|
-
.expect(toRedirect("/"));
|
|
574
|
-
await sleep(1000);
|
|
575
|
-
const sharedData = Table.findOne({ name: "shared_data" });
|
|
576
|
-
const rows = await sharedData.getRows({});
|
|
577
|
-
const row = rows.find((r) => r.title === "pwa_disabled_as_admin");
|
|
578
|
-
expect(row).toBeUndefined();
|
|
579
|
-
});
|
|
580
|
-
|
|
581
563
|
it("does not share as public", async () => {
|
|
582
564
|
const app = await getApp({ disableCsrf: true });
|
|
583
565
|
await request(app)
|
package/tests/plugins.test.js
CHANGED
|
@@ -92,7 +92,7 @@ describe("Plugin Endpoints", () => {
|
|
|
92
92
|
.expect(toInclude("testfilecontents"));
|
|
93
93
|
await request(app)
|
|
94
94
|
.get(
|
|
95
|
-
"/plugins/
|
|
95
|
+
"/plugins/public/sbadmin2@9.9.9/sb-admin-2.min.css"
|
|
96
96
|
)
|
|
97
97
|
.expect(toInclude("Start Bootstrap"));
|
|
98
98
|
|
|
@@ -102,7 +102,7 @@ describe("Plugin Endpoints", () => {
|
|
|
102
102
|
.expect(toRedirect("/plugins"));
|
|
103
103
|
await request(app)
|
|
104
104
|
.get(
|
|
105
|
-
"/plugins/
|
|
105
|
+
"/plugins/public/sbadmin2@9.9.9/sb-admin-2.min.css"
|
|
106
106
|
)
|
|
107
107
|
.expect(toInclude("Start Bootstrap"));
|
|
108
108
|
});
|
package/wrapper.js
CHANGED
|
@@ -89,52 +89,90 @@ const get_menu = (req) => {
|
|
|
89
89
|
];
|
|
90
90
|
// const schema = db.getTenantSchema();
|
|
91
91
|
// Admin role id (todo move to common constants)
|
|
92
|
+
|
|
93
|
+
const canEditTables = state.getConfig("min_role_edit_tables", 1) >= role;
|
|
94
|
+
const canInspectTables =
|
|
95
|
+
state.getConfig("min_role_inspect_tables", 1) >= role;
|
|
96
|
+
const canEditViews = state.getConfig("min_role_edit_views", 1) >= role;
|
|
97
|
+
const canEditPages = state.getConfig("min_role_edit_pages", 1) >= role;
|
|
98
|
+
const canEditTriggers = state.getConfig("min_role_edit_triggers", 1) >= role;
|
|
92
99
|
const isAdmin = role === 1;
|
|
100
|
+
const hasAdmin =
|
|
101
|
+
isAdmin ||
|
|
102
|
+
canEditTables ||
|
|
103
|
+
canInspectTables ||
|
|
104
|
+
canEditPages ||
|
|
105
|
+
canEditViews ||
|
|
106
|
+
canEditTriggers;
|
|
93
107
|
/*
|
|
94
108
|
* Admin Menu items
|
|
95
109
|
*
|
|
96
110
|
*/
|
|
97
|
-
const adminItems = [
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
111
|
+
const adminItems = [];
|
|
112
|
+
if (hasAdmin) {
|
|
113
|
+
if (isAdmin || canInspectTables || canEditTables)
|
|
114
|
+
adminItems.push({
|
|
115
|
+
link: "/table",
|
|
116
|
+
icon: "fas fa-table",
|
|
117
|
+
label: req.__("Tables"),
|
|
118
|
+
});
|
|
119
|
+
if (isAdmin || canEditViews)
|
|
120
|
+
adminItems.push({
|
|
121
|
+
link: "/viewedit",
|
|
122
|
+
icon: "far fa-eye",
|
|
123
|
+
label: req.__("Views"),
|
|
124
|
+
});
|
|
125
|
+
if (isAdmin || canEditPages)
|
|
126
|
+
adminItems.push({
|
|
127
|
+
link: "/pageedit",
|
|
128
|
+
icon: "far fa-file",
|
|
129
|
+
label: req.__("Pages"),
|
|
130
|
+
});
|
|
131
|
+
if (canEditTriggers && !isAdmin)
|
|
132
|
+
adminItems.push({
|
|
133
|
+
link: "/actions",
|
|
134
|
+
altlinks: ["/events", "/eventlog", "/crashlog"],
|
|
135
|
+
icon: "fas fa-calendar-check",
|
|
136
|
+
label: req.__("Triggers"),
|
|
137
|
+
});
|
|
138
|
+
if (isAdmin)
|
|
139
|
+
adminItems.push({
|
|
140
|
+
label: req.__("Settings"),
|
|
141
|
+
icon: "fas fa-wrench",
|
|
142
|
+
subitems: [
|
|
143
|
+
{
|
|
144
|
+
link: "/admin",
|
|
145
|
+
icon: "fas fa-tools",
|
|
146
|
+
label: req.__("About application"),
|
|
147
|
+
},
|
|
148
|
+
{ link: "/plugins", icon: "fas fa-cubes", label: req.__("Modules") },
|
|
149
|
+
{
|
|
150
|
+
link: "/useradmin",
|
|
151
|
+
icon: "fas fa-users-cog",
|
|
152
|
+
altlinks: ["/roleadmin"],
|
|
153
|
+
label: req.__("Users and security"),
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
link: "/site-structure",
|
|
157
|
+
altlinks: [
|
|
158
|
+
"/menu",
|
|
159
|
+
"/search/config",
|
|
160
|
+
"/library/list",
|
|
161
|
+
"/tenant/list",
|
|
162
|
+
],
|
|
163
|
+
icon: "fas fa-compass",
|
|
164
|
+
label: req.__("Site structure"),
|
|
165
|
+
},
|
|
166
|
+
{ link: "/files", icon: "far fa-images", label: req.__("Files") },
|
|
167
|
+
{
|
|
168
|
+
link: "/events",
|
|
169
|
+
altlinks: ["/actions", "/eventlog", "/crashlog"],
|
|
170
|
+
icon: "fas fa-calendar-check",
|
|
171
|
+
label: req.__("Events"),
|
|
172
|
+
},
|
|
173
|
+
],
|
|
174
|
+
});
|
|
175
|
+
}
|
|
138
176
|
|
|
139
177
|
// return menu
|
|
140
178
|
return [
|
|
@@ -142,7 +180,7 @@ const get_menu = (req) => {
|
|
|
142
180
|
section: req.__("Menu"),
|
|
143
181
|
items: extra_menu,
|
|
144
182
|
},
|
|
145
|
-
|
|
183
|
+
hasAdmin && {
|
|
146
184
|
section: req.__("Admin"),
|
|
147
185
|
items: adminItems,
|
|
148
186
|
},
|