@saltcorn/server 0.6.1-beta.0 → 0.6.1
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/app.js +7 -0
- package/auth/admin.js +120 -5
- package/auth/index.js +7 -0
- package/auth/resetpw.js +22 -0
- package/auth/roleadmin.js +52 -0
- package/auth/routes.js +211 -2
- package/auth/testhelp.js +69 -0
- package/errors.js +14 -1
- package/fixture_persons.js +14 -0
- package/index.js +6 -0
- package/load_plugins.js +4 -3
- package/locales/en.json +7 -1
- package/markup/admin.js +97 -1
- package/markup/blockly.js +15 -0
- package/markup/expression_blurb.js +45 -0
- package/markup/forms.js +24 -0
- package/markup/index.js +7 -0
- package/markup/plugin-store.js +36 -0
- package/package.json +6 -6
- package/public/saltcorn-builder.css +1 -0
- package/public/saltcorn.js +5 -1
- package/routes/actions.js +53 -1
- package/routes/admin.js +97 -1
- package/routes/api.js +45 -10
- package/routes/config.js +18 -0
- package/routes/crashlog.js +31 -0
- package/routes/delete.js +19 -0
- package/routes/edit.js +19 -0
- package/routes/eventlog.js +65 -1
- package/routes/events.js +19 -0
- package/routes/fields.js +88 -0
- package/routes/files.js +62 -0
- package/routes/homepage.js +175 -80
- package/routes/index.js +7 -1
- package/routes/infoarch.js +56 -0
- package/routes/library.js +32 -0
- package/routes/list.js +28 -1
- package/routes/menu.js +45 -0
- package/routes/packs.js +53 -0
- package/routes/page.js +26 -0
- package/routes/pageedit.js +129 -3
- package/routes/plugins.js +156 -5
- package/routes/scapi.js +79 -23
- package/routes/search.js +51 -0
- package/routes/settings.js +27 -0
- package/routes/tables.js +148 -19
- package/routes/tenant.js +123 -31
- package/routes/utils.js +60 -1
- package/routes/view.js +37 -0
- package/routes/viewedit.js +114 -1
- package/serve.js +138 -88
- package/systemd.js +18 -1
- package/wrapper.js +4 -0
package/routes/fields.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
*
|
|
3
3
|
* Field Router
|
|
4
|
+
* @category server
|
|
5
|
+
* @module routes/fields
|
|
6
|
+
* @subcategory routes
|
|
4
7
|
*/
|
|
5
8
|
|
|
6
9
|
const Router = require("express-promise-router");
|
|
@@ -23,9 +26,25 @@ const { setTenant, isAdmin, error_catcher } = require("./utils.js");
|
|
|
23
26
|
const expressionBlurb = require("../markup/expression_blurb");
|
|
24
27
|
const { readState } = require("@saltcorn/data/plugin-helper");
|
|
25
28
|
const { wizardCardTitle } = require("../markup/forms.js");
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @type {object}
|
|
32
|
+
* @const
|
|
33
|
+
* @namespace fieldsRouter
|
|
34
|
+
* @category server
|
|
35
|
+
* @subcategory routes
|
|
36
|
+
*/
|
|
26
37
|
const router = new Router();
|
|
27
38
|
module.exports = router;
|
|
28
39
|
|
|
40
|
+
/**
|
|
41
|
+
* @param {object} req
|
|
42
|
+
* @param {*} fkey_opts
|
|
43
|
+
* @param {*} existing_names
|
|
44
|
+
* @param {*} id
|
|
45
|
+
* @param {*} hasData
|
|
46
|
+
* @returns {Promise<Form>}
|
|
47
|
+
*/
|
|
29
48
|
const fieldForm = async (req, fkey_opts, existing_names, id, hasData) => {
|
|
30
49
|
let isPrimary = false;
|
|
31
50
|
let primaryTypes = Object.entries(getState().types)
|
|
@@ -116,22 +135,41 @@ const fieldForm = async (req, fkey_opts, existing_names, id, hasData) => {
|
|
|
116
135
|
],
|
|
117
136
|
});
|
|
118
137
|
};
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* @param {string} ctxType
|
|
141
|
+
* @returns {object}
|
|
142
|
+
*/
|
|
119
143
|
const calcFieldType = (ctxType) =>
|
|
120
144
|
ctxType.startsWith("Key to")
|
|
121
145
|
? { type: "Key", reftable_name: ctxType.replace("Key to ", "") }
|
|
122
146
|
: { type: ctxType };
|
|
123
147
|
|
|
148
|
+
/**
|
|
149
|
+
* @param {*} attrs
|
|
150
|
+
* @param {object} req
|
|
151
|
+
* @returns {*}
|
|
152
|
+
*/
|
|
124
153
|
const translateAttributes = (attrs, req) =>
|
|
125
154
|
Array.isArray(attrs)
|
|
126
155
|
? attrs.map((attr) => translateAttribute(attr, req))
|
|
127
156
|
: attrs;
|
|
128
157
|
|
|
158
|
+
/**
|
|
159
|
+
* @param {*} attr
|
|
160
|
+
* @param {*} req
|
|
161
|
+
* @returns {object}
|
|
162
|
+
*/
|
|
129
163
|
const translateAttribute = (attr, req) => {
|
|
130
164
|
const res = { ...attr };
|
|
131
165
|
if (res.sublabel) res.sublabel = req.__(res.sublabel);
|
|
132
166
|
return res;
|
|
133
167
|
};
|
|
134
168
|
|
|
169
|
+
/**
|
|
170
|
+
* @param {*} req
|
|
171
|
+
* @returns {Workflow}
|
|
172
|
+
*/
|
|
135
173
|
const fieldFlow = (req) =>
|
|
136
174
|
new Workflow({
|
|
137
175
|
action: "/field",
|
|
@@ -372,6 +410,13 @@ const fieldFlow = (req) =>
|
|
|
372
410
|
},
|
|
373
411
|
],
|
|
374
412
|
});
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* @name get/:id
|
|
416
|
+
* @function
|
|
417
|
+
* @memberof module:routes/fields~fieldsRouter
|
|
418
|
+
* @function
|
|
419
|
+
*/
|
|
375
420
|
router.get(
|
|
376
421
|
"/:id",
|
|
377
422
|
setTenant,
|
|
@@ -419,6 +464,12 @@ router.get(
|
|
|
419
464
|
})
|
|
420
465
|
);
|
|
421
466
|
|
|
467
|
+
/**
|
|
468
|
+
* @name get/new/:table_id
|
|
469
|
+
* @function
|
|
470
|
+
* @memberof module:routes/fields~fieldsRouter
|
|
471
|
+
* @function
|
|
472
|
+
*/
|
|
422
473
|
router.get(
|
|
423
474
|
"/new/:table_id",
|
|
424
475
|
setTenant,
|
|
@@ -450,6 +501,12 @@ router.get(
|
|
|
450
501
|
})
|
|
451
502
|
);
|
|
452
503
|
|
|
504
|
+
/**
|
|
505
|
+
* @name post/delete/:id
|
|
506
|
+
* @function
|
|
507
|
+
* @memberof module:routes/fields~fieldsRouter
|
|
508
|
+
* @function
|
|
509
|
+
*/
|
|
453
510
|
router.post(
|
|
454
511
|
"/delete/:id",
|
|
455
512
|
setTenant,
|
|
@@ -470,6 +527,12 @@ router.post(
|
|
|
470
527
|
})
|
|
471
528
|
);
|
|
472
529
|
|
|
530
|
+
/**
|
|
531
|
+
* @name post
|
|
532
|
+
* @function
|
|
533
|
+
* @memberof module:routes/fields~fieldsRouter
|
|
534
|
+
* @function
|
|
535
|
+
*/
|
|
473
536
|
router.post(
|
|
474
537
|
"/",
|
|
475
538
|
setTenant,
|
|
@@ -513,6 +576,12 @@ router.post(
|
|
|
513
576
|
})
|
|
514
577
|
);
|
|
515
578
|
|
|
579
|
+
/**
|
|
580
|
+
* @name post/test-formula
|
|
581
|
+
* @function
|
|
582
|
+
* @memberof module:routes/fields~fieldsRouter
|
|
583
|
+
* @function
|
|
584
|
+
*/
|
|
516
585
|
router.post(
|
|
517
586
|
"/test-formula",
|
|
518
587
|
setTenant,
|
|
@@ -544,6 +613,13 @@ router.post(
|
|
|
544
613
|
}
|
|
545
614
|
})
|
|
546
615
|
);
|
|
616
|
+
|
|
617
|
+
/**
|
|
618
|
+
* @name post/show-calculated/:tableName/:fieldName/:fieldview
|
|
619
|
+
* @function
|
|
620
|
+
* @memberof module:routes/fields~fieldsRouter
|
|
621
|
+
* @function
|
|
622
|
+
*/
|
|
547
623
|
router.post(
|
|
548
624
|
"/show-calculated/:tableName/:fieldName/:fieldview",
|
|
549
625
|
setTenant,
|
|
@@ -573,6 +649,12 @@ router.post(
|
|
|
573
649
|
})
|
|
574
650
|
);
|
|
575
651
|
|
|
652
|
+
/**
|
|
653
|
+
* @name post/preview/:tableName/:fieldName/:fieldview
|
|
654
|
+
* @function
|
|
655
|
+
* @memberof module:routes/fields~fieldsRouter
|
|
656
|
+
* @function
|
|
657
|
+
*/
|
|
576
658
|
router.post(
|
|
577
659
|
"/preview/:tableName/:fieldName/:fieldview",
|
|
578
660
|
setTenant,
|
|
@@ -632,6 +714,12 @@ router.post(
|
|
|
632
714
|
})
|
|
633
715
|
);
|
|
634
716
|
|
|
717
|
+
/**
|
|
718
|
+
* @name post/preview/:tableName/:fieldName/
|
|
719
|
+
* @function
|
|
720
|
+
* @memberof module:routes/fields~fieldsRouter
|
|
721
|
+
* @function
|
|
722
|
+
*/
|
|
635
723
|
router.post(
|
|
636
724
|
"/preview/:tableName/:fieldName/",
|
|
637
725
|
setTenant,
|
package/routes/files.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @category server
|
|
3
|
+
* @module routes/files
|
|
4
|
+
* @subcategory routes
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
const Router = require("express-promise-router");
|
|
2
8
|
const File = require("@saltcorn/data/models/file");
|
|
3
9
|
const User = require("@saltcorn/data/models/user");
|
|
@@ -32,9 +38,22 @@ const { csrfField } = require("./utils");
|
|
|
32
38
|
const { editRoleForm, fileUploadForm } = require("../markup/forms.js");
|
|
33
39
|
const { strictParseInt } = require("@saltcorn/data/plugin-helper");
|
|
34
40
|
|
|
41
|
+
/**
|
|
42
|
+
* @type {object}
|
|
43
|
+
* @const
|
|
44
|
+
* @namespace filesRouter
|
|
45
|
+
* @category server
|
|
46
|
+
* @subcategory routes
|
|
47
|
+
*/
|
|
35
48
|
const router = new Router();
|
|
36
49
|
module.exports = router;
|
|
37
50
|
|
|
51
|
+
/**
|
|
52
|
+
* @param {*} file
|
|
53
|
+
* @param {*} roles
|
|
54
|
+
* @param {*} req
|
|
55
|
+
* @returns {Form}
|
|
56
|
+
*/
|
|
38
57
|
const editFileRoleForm = (file, roles, req) =>
|
|
39
58
|
editRoleForm({
|
|
40
59
|
url: `/files/setrole/${file.id}`,
|
|
@@ -43,6 +62,12 @@ const editFileRoleForm = (file, roles, req) =>
|
|
|
43
62
|
req,
|
|
44
63
|
});
|
|
45
64
|
|
|
65
|
+
/**
|
|
66
|
+
* @name get
|
|
67
|
+
* @function
|
|
68
|
+
* @memberof module:routes/files~filesRouter
|
|
69
|
+
* @function
|
|
70
|
+
*/
|
|
46
71
|
router.get(
|
|
47
72
|
"/",
|
|
48
73
|
setTenant,
|
|
@@ -104,6 +129,12 @@ router.get(
|
|
|
104
129
|
})
|
|
105
130
|
);
|
|
106
131
|
|
|
132
|
+
/**
|
|
133
|
+
* @name get/download/:id
|
|
134
|
+
* @function
|
|
135
|
+
* @memberof module:routes/files~filesRouter
|
|
136
|
+
* @function
|
|
137
|
+
*/
|
|
107
138
|
router.get(
|
|
108
139
|
"/download/:id",
|
|
109
140
|
setTenant,
|
|
@@ -122,6 +153,12 @@ router.get(
|
|
|
122
153
|
})
|
|
123
154
|
);
|
|
124
155
|
|
|
156
|
+
/**
|
|
157
|
+
* @name get/serve/:id
|
|
158
|
+
* @function
|
|
159
|
+
* @memberof module:routes/files~filesRouter
|
|
160
|
+
* @function
|
|
161
|
+
*/
|
|
125
162
|
router.get(
|
|
126
163
|
"/serve/:id",
|
|
127
164
|
setTenant,
|
|
@@ -152,6 +189,12 @@ router.get(
|
|
|
152
189
|
})
|
|
153
190
|
);
|
|
154
191
|
|
|
192
|
+
/**
|
|
193
|
+
* @name post/setrole/:id
|
|
194
|
+
* @function
|
|
195
|
+
* @memberof module:routes/files~filesRouter
|
|
196
|
+
* @function
|
|
197
|
+
*/
|
|
155
198
|
router.post(
|
|
156
199
|
"/setrole/:id",
|
|
157
200
|
setTenant,
|
|
@@ -173,6 +216,13 @@ router.post(
|
|
|
173
216
|
res.redirect("/files");
|
|
174
217
|
})
|
|
175
218
|
);
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* @name post/setname/:id
|
|
222
|
+
* @function
|
|
223
|
+
* @memberof module:routes/files~filesRouter
|
|
224
|
+
* @function
|
|
225
|
+
*/
|
|
176
226
|
router.post(
|
|
177
227
|
"/setname/:id",
|
|
178
228
|
setTenant,
|
|
@@ -186,6 +236,12 @@ router.post(
|
|
|
186
236
|
})
|
|
187
237
|
);
|
|
188
238
|
|
|
239
|
+
/**
|
|
240
|
+
* @name post/upload
|
|
241
|
+
* @function
|
|
242
|
+
* @memberof module:routes/files~filesRouter
|
|
243
|
+
* @function
|
|
244
|
+
*/
|
|
189
245
|
router.post(
|
|
190
246
|
"/upload",
|
|
191
247
|
setTenant,
|
|
@@ -233,6 +289,12 @@ router.post(
|
|
|
233
289
|
})
|
|
234
290
|
);
|
|
235
291
|
|
|
292
|
+
/**
|
|
293
|
+
* @name post/delete/:id
|
|
294
|
+
* @function
|
|
295
|
+
* @memberof module:routes/files~filesRouter
|
|
296
|
+
* @function
|
|
297
|
+
*/
|
|
236
298
|
router.post(
|
|
237
299
|
"/delete/:id",
|
|
238
300
|
setTenant,
|
package/routes/homepage.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @category server
|
|
3
|
+
* @module routes/homepage
|
|
4
|
+
* @subcategory routes
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
const { getState } = require("@saltcorn/data/db/state");
|
|
2
8
|
const db = require("@saltcorn/data/db");
|
|
3
9
|
const View = require("@saltcorn/data/models/view");
|
|
@@ -14,6 +20,11 @@ const packagejson = require("../package.json");
|
|
|
14
20
|
const Trigger = require("@saltcorn/data/models/trigger");
|
|
15
21
|
const { fileUploadForm } = require("../markup/forms");
|
|
16
22
|
|
|
23
|
+
/**
|
|
24
|
+
* @param {*} tables
|
|
25
|
+
* @param {object} req
|
|
26
|
+
* @returns {Table}
|
|
27
|
+
*/
|
|
17
28
|
const tableTable = (tables, req) =>
|
|
18
29
|
mkTable(
|
|
19
30
|
[
|
|
@@ -26,6 +37,11 @@ const tableTable = (tables, req) =>
|
|
|
26
37
|
tables
|
|
27
38
|
);
|
|
28
39
|
|
|
40
|
+
/**
|
|
41
|
+
* @param {*} tables
|
|
42
|
+
* @param {object} req
|
|
43
|
+
* @returns {object}
|
|
44
|
+
*/
|
|
29
45
|
const tableCard = (tables, req) => ({
|
|
30
46
|
type: "card",
|
|
31
47
|
class: "welcome-page-entity-list",
|
|
@@ -50,6 +66,11 @@ const tableCard = (tables, req) => ({
|
|
|
50
66
|
),
|
|
51
67
|
});
|
|
52
68
|
|
|
69
|
+
/**
|
|
70
|
+
* @param {*} views
|
|
71
|
+
* @param {object} req
|
|
72
|
+
* @returns {Table}
|
|
73
|
+
*/
|
|
53
74
|
const viewTable = (views, req) =>
|
|
54
75
|
mkTable(
|
|
55
76
|
[
|
|
@@ -66,6 +87,11 @@ const viewTable = (views, req) =>
|
|
|
66
87
|
views
|
|
67
88
|
);
|
|
68
89
|
|
|
90
|
+
/**
|
|
91
|
+
* @param {*} views
|
|
92
|
+
* @param {object} req
|
|
93
|
+
* @returns {object}
|
|
94
|
+
*/
|
|
69
95
|
const viewCard = (views, req) => ({
|
|
70
96
|
type: "card",
|
|
71
97
|
title: link("/viewedit", req.__("Views")),
|
|
@@ -91,6 +117,12 @@ const viewCard = (views, req) => ({
|
|
|
91
117
|
)
|
|
92
118
|
),
|
|
93
119
|
});
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* @param {*} pages
|
|
123
|
+
* @param {object} req
|
|
124
|
+
* @returns {Table}
|
|
125
|
+
*/
|
|
94
126
|
const pageTable = (pages, req) =>
|
|
95
127
|
mkTable(
|
|
96
128
|
[
|
|
@@ -106,6 +138,12 @@ const pageTable = (pages, req) =>
|
|
|
106
138
|
],
|
|
107
139
|
pages
|
|
108
140
|
);
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @param {*} pages
|
|
144
|
+
* @param {object} req
|
|
145
|
+
* @returns {object}
|
|
146
|
+
*/
|
|
109
147
|
const pageCard = (pages, req) => ({
|
|
110
148
|
type: "card",
|
|
111
149
|
title: link("/pageedit", req.__("Pages")),
|
|
@@ -133,8 +171,12 @@ const pageCard = (pages, req) => ({
|
|
|
133
171
|
),
|
|
134
172
|
});
|
|
135
173
|
|
|
174
|
+
/**
|
|
175
|
+
* @param {object} req
|
|
176
|
+
* @returns {Promise<div>}
|
|
177
|
+
*/
|
|
136
178
|
const filesTab = async (req) => {
|
|
137
|
-
const files = await File.find({}, { orderBy: "filename" });
|
|
179
|
+
const files = await File.find({}, { orderBy: "filename", cached: true });
|
|
138
180
|
return div(
|
|
139
181
|
files.length == 0
|
|
140
182
|
? p(req.__("No files"))
|
|
@@ -152,13 +194,12 @@ const filesTab = async (req) => {
|
|
|
152
194
|
fileUploadForm(req)
|
|
153
195
|
);
|
|
154
196
|
};
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
});
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* @param {object} req
|
|
200
|
+
* @returns {Promise<div>}
|
|
201
|
+
*/
|
|
202
|
+
const usersTab = async (req, users, roleMap) => {
|
|
162
203
|
return div(
|
|
163
204
|
mkTable(
|
|
164
205
|
[
|
|
@@ -172,15 +213,19 @@ const usersTab = async (req) => {
|
|
|
172
213
|
users
|
|
173
214
|
),
|
|
174
215
|
a(
|
|
175
|
-
{ href: `/useradmin/new`, class: "btn btn-secondary" },
|
|
216
|
+
{ href: `/useradmin/new`, class: "btn btn-secondary my-3" },
|
|
176
217
|
req.__("Create user")
|
|
177
218
|
)
|
|
178
219
|
);
|
|
179
220
|
};
|
|
180
|
-
const actionsTab = async (req) => {
|
|
181
|
-
const triggers = await Trigger.findAllWithTableName();
|
|
182
221
|
|
|
222
|
+
/**
|
|
223
|
+
* @param {object} req
|
|
224
|
+
* @returns {Promise<div>}
|
|
225
|
+
*/
|
|
226
|
+
const actionsTab = async (req, triggers) => {
|
|
183
227
|
return div(
|
|
228
|
+
{ class: "pb-3" },
|
|
184
229
|
triggers.length <= 1 &&
|
|
185
230
|
p(
|
|
186
231
|
{ class: "mt-2 pr-2" },
|
|
@@ -207,21 +252,91 @@ const actionsTab = async (req) => {
|
|
|
207
252
|
triggers
|
|
208
253
|
),
|
|
209
254
|
a(
|
|
210
|
-
{ href: "/actions/new", class: "btn btn-secondary
|
|
255
|
+
{ href: "/actions/new", class: "btn btn-secondary my-3" },
|
|
211
256
|
req.__("Add trigger")
|
|
212
257
|
)
|
|
213
258
|
);
|
|
214
259
|
};
|
|
260
|
+
const packTab = (req, packlist) =>
|
|
261
|
+
div(
|
|
262
|
+
{ class: "pb-3 pt-2 pr-4" },
|
|
263
|
+
p(req.__("Instead of building, get up and running in no time with packs")),
|
|
264
|
+
p(
|
|
265
|
+
{ class: "font-italic" },
|
|
266
|
+
req.__(
|
|
267
|
+
"Packs are collections of tables, views and plugins that give you a full application which you can then edit to suit your needs."
|
|
268
|
+
)
|
|
269
|
+
),
|
|
270
|
+
mkTable(
|
|
271
|
+
[
|
|
272
|
+
{ label: req.__("Name"), key: "name" },
|
|
273
|
+
{
|
|
274
|
+
label: req.__("Description"),
|
|
275
|
+
key: "description",
|
|
276
|
+
},
|
|
277
|
+
],
|
|
278
|
+
packlist,
|
|
279
|
+
{ noHeader: true }
|
|
280
|
+
),
|
|
281
|
+
a(
|
|
282
|
+
{ href: `/plugins?set=packs`, class: "btn btn-primary" },
|
|
283
|
+
req.__("Go to pack store »")
|
|
284
|
+
)
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
const helpCard = (req) =>
|
|
288
|
+
div(
|
|
289
|
+
{ class: "pb-3 pt-2 pr-4" },
|
|
290
|
+
p(req.__("Confused?")),
|
|
291
|
+
p(
|
|
292
|
+
req.__(
|
|
293
|
+
"The Wiki contains the documentation and tutorials on installing and using Saltcorn"
|
|
294
|
+
)
|
|
295
|
+
),
|
|
296
|
+
a(
|
|
297
|
+
{
|
|
298
|
+
href: `https://wiki.saltcorn.com/`,
|
|
299
|
+
class: "btn btn-primary",
|
|
300
|
+
},
|
|
301
|
+
req.__("Go to Wiki »")
|
|
302
|
+
),
|
|
303
|
+
p(req.__("The YouTube channel has some video tutorials")),
|
|
304
|
+
a(
|
|
305
|
+
{
|
|
306
|
+
href: `https://www.youtube.com/channel/UCBOpAcH8ep7ESbuocxcq0KQ`,
|
|
307
|
+
class: "btn btn-secondary",
|
|
308
|
+
},
|
|
309
|
+
req.__("Go to YouTube »")
|
|
310
|
+
),
|
|
311
|
+
div(
|
|
312
|
+
{ class: "mt-3" },
|
|
313
|
+
a(
|
|
314
|
+
{ href: `https://blog.saltcorn.com/` },
|
|
315
|
+
req.__("What's new? Read the blog »")
|
|
316
|
+
)
|
|
317
|
+
)
|
|
318
|
+
);
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* @param {object} req
|
|
322
|
+
* @returns {Promise<object>}
|
|
323
|
+
*/
|
|
215
324
|
const welcome_page = async (req) => {
|
|
216
325
|
const packs_available = await fetch_available_packs();
|
|
217
326
|
const packlist = [
|
|
218
327
|
...packs_available.slice(0, 5),
|
|
219
328
|
{ name: req.__("More..."), description: "" },
|
|
220
329
|
];
|
|
221
|
-
const tables = await Table.find({}, {
|
|
222
|
-
const views = await View.find({});
|
|
223
|
-
const pages = await Page.find({});
|
|
224
|
-
|
|
330
|
+
const tables = await Table.find({}, { cached: true });
|
|
331
|
+
const views = await View.find({}, { cached: true });
|
|
332
|
+
const pages = await Page.find({}, { cached: true });
|
|
333
|
+
const triggers = await Trigger.findAllWithTableName();
|
|
334
|
+
const users = await User.find({}, { orderBy: "id" });
|
|
335
|
+
const roles = await User.get_roles();
|
|
336
|
+
let roleMap = {};
|
|
337
|
+
roles.forEach((r) => {
|
|
338
|
+
roleMap[r.id] = r.role;
|
|
339
|
+
});
|
|
225
340
|
return {
|
|
226
341
|
above: [
|
|
227
342
|
{
|
|
@@ -236,75 +351,37 @@ const welcome_page = async (req) => {
|
|
|
236
351
|
{
|
|
237
352
|
type: "card",
|
|
238
353
|
//title: req.__("Install pack"),
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
{ label: req.__("Name"), key: "name" },
|
|
255
|
-
{
|
|
256
|
-
label: req.__("Description"),
|
|
257
|
-
key: "description",
|
|
258
|
-
},
|
|
259
|
-
],
|
|
260
|
-
packlist,
|
|
261
|
-
{ noHeader: true }
|
|
262
|
-
),
|
|
263
|
-
a(
|
|
264
|
-
{ href: `/plugins?set=packs`, class: "btn btn-primary" },
|
|
265
|
-
req.__("Go to pack store »")
|
|
266
|
-
)
|
|
267
|
-
),
|
|
268
|
-
Triggers: await actionsTab(req),
|
|
269
|
-
Files: await filesTab(req),
|
|
270
|
-
},
|
|
354
|
+
bodyClass: "py-0 pr-0",
|
|
355
|
+
class: "welcome-page-entity-list",
|
|
356
|
+
|
|
357
|
+
tabContents:
|
|
358
|
+
triggers.length > 0
|
|
359
|
+
? {
|
|
360
|
+
Triggers: await actionsTab(req, triggers),
|
|
361
|
+
Files: await filesTab(req),
|
|
362
|
+
Packs: packTab(req, packlist),
|
|
363
|
+
}
|
|
364
|
+
: {
|
|
365
|
+
Packs: packTab(req, packlist),
|
|
366
|
+
Triggers: await actionsTab(req, triggers),
|
|
367
|
+
Files: await filesTab(req),
|
|
368
|
+
},
|
|
271
369
|
},
|
|
272
370
|
{
|
|
273
371
|
type: "card",
|
|
274
372
|
//title: req.__("Learn"),
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
class: "btn btn-primary",
|
|
287
|
-
},
|
|
288
|
-
req.__("Go to Wiki »")
|
|
289
|
-
),
|
|
290
|
-
p(req.__("The YouTube channel has some video tutorials")),
|
|
291
|
-
a(
|
|
292
|
-
{
|
|
293
|
-
href: `https://www.youtube.com/channel/UCBOpAcH8ep7ESbuocxcq0KQ`,
|
|
294
|
-
class: "btn btn-secondary",
|
|
373
|
+
bodyClass: "py-0 pr-0",
|
|
374
|
+
class: "welcome-page-entity-list",
|
|
375
|
+
tabContents:
|
|
376
|
+
users.length > 4
|
|
377
|
+
? {
|
|
378
|
+
Users: await usersTab(req, users, roleMap),
|
|
379
|
+
Help: helpCard(req),
|
|
380
|
+
}
|
|
381
|
+
: {
|
|
382
|
+
Help: helpCard(req),
|
|
383
|
+
Users: await usersTab(req, users, roleMap),
|
|
295
384
|
},
|
|
296
|
-
req.__("Go to YouTube »")
|
|
297
|
-
),
|
|
298
|
-
div(
|
|
299
|
-
{ class: "mt-3" },
|
|
300
|
-
a(
|
|
301
|
-
{ href: `https://blog.saltcorn.com/` },
|
|
302
|
-
req.__("What's new? Read the blog »")
|
|
303
|
-
)
|
|
304
|
-
)
|
|
305
|
-
),
|
|
306
|
-
Users: await usersTab(req),
|
|
307
|
-
},
|
|
308
385
|
},
|
|
309
386
|
],
|
|
310
387
|
},
|
|
@@ -312,6 +389,11 @@ const welcome_page = async (req) => {
|
|
|
312
389
|
};
|
|
313
390
|
};
|
|
314
391
|
|
|
392
|
+
/**
|
|
393
|
+
* @param {object} req
|
|
394
|
+
* @param {object} res
|
|
395
|
+
* @returns {Promise<void>}
|
|
396
|
+
*/
|
|
315
397
|
const no_views_logged_in = async (req, res) => {
|
|
316
398
|
const role = req.isAuthenticated() ? req.user.role_id : 10;
|
|
317
399
|
if (role > 1 || req.user.tenant !== db.getTenantSchema())
|
|
@@ -337,6 +419,12 @@ const no_views_logged_in = async (req, res) => {
|
|
|
337
419
|
}
|
|
338
420
|
};
|
|
339
421
|
|
|
422
|
+
/**
|
|
423
|
+
* @param {number} role_id
|
|
424
|
+
* @param {object} res
|
|
425
|
+
* @param {object} req
|
|
426
|
+
* @returns {Promise<boolean>}
|
|
427
|
+
*/
|
|
340
428
|
const get_config_response = async (role_id, res, req) => {
|
|
341
429
|
const modernCfg = getState().getConfig("home_page_by_role", false);
|
|
342
430
|
const legacy_role = { 10: "public", 8: "user", 4: "staff", 1: "admin" }[
|
|
@@ -360,6 +448,13 @@ const get_config_response = async (role_id, res, req) => {
|
|
|
360
448
|
return true;
|
|
361
449
|
}
|
|
362
450
|
};
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Function assigned to 'module.exports'.
|
|
454
|
+
* @param {object} req
|
|
455
|
+
* @param {object} res
|
|
456
|
+
* @returns {Promise<void>}
|
|
457
|
+
*/
|
|
363
458
|
module.exports = async (req, res) => {
|
|
364
459
|
const isAuth = req.isAuthenticated();
|
|
365
460
|
const role_id = req.user ? req.user.role_id : 10;
|
package/routes/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Index is Main Router of App
|
|
3
|
-
* @
|
|
3
|
+
* @category server
|
|
4
|
+
* @module routes/index
|
|
5
|
+
* @subcategory routes
|
|
4
6
|
*/
|
|
5
7
|
const table = require("./tables");
|
|
6
8
|
const field = require("./fields");
|
|
@@ -32,6 +34,10 @@ const useradmin = require("../auth/admin");
|
|
|
32
34
|
const roleadmin = require("../auth/roleadmin");
|
|
33
35
|
const scapi = require("./scapi");
|
|
34
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Function assigned to 'module.exports'
|
|
39
|
+
* @returns {void}
|
|
40
|
+
*/
|
|
35
41
|
module.exports = (app) => {
|
|
36
42
|
app.use("/table", table);
|
|
37
43
|
app.use("/field", field);
|