@saltcorn/server 0.8.5-beta.3 → 0.8.5-beta.5
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/auth/admin.js +23 -2
- package/auth/testhelp.js +15 -0
- package/locales/da.json +3 -1
- package/locales/en.json +26 -1
- package/locales/pl.json +17 -1
- package/markup/admin.js +15 -6
- package/package.json +8 -8
- package/public/saltcorn-common.js +30 -1
- package/public/saltcorn.css +27 -0
- package/public/saltcorn.js +3 -0
- package/public/serviceworker.js +1 -0
- package/public/vis-network.min.js +49 -0
- package/routes/admin.js +110 -219
- package/routes/api.js +66 -10
- package/routes/common_lists.js +1 -0
- package/routes/fields.js +11 -1
- package/routes/index.js +2 -0
- package/routes/list.js +8 -5
- package/routes/notifications.js +136 -0
- package/routes/plugins.js +47 -16
- package/routes/tables.js +160 -23
- package/routes/tenant.js +4 -0
- package/routes/utils.js +64 -1
- package/tests/api.test.js +2 -2
- package/tests/crud.test.js +53 -0
- package/tests/plugins.test.js +1 -1
- package/tests/table.test.js +17 -0
- package/wrapper.js +40 -3
package/auth/admin.js
CHANGED
|
@@ -23,7 +23,16 @@ const {
|
|
|
23
23
|
const { isAdmin, error_catcher } = require("../routes/utils");
|
|
24
24
|
const { send_reset_email } = require("./resetpw");
|
|
25
25
|
const { getState } = require("@saltcorn/data/db/state");
|
|
26
|
-
const {
|
|
26
|
+
const {
|
|
27
|
+
a,
|
|
28
|
+
div,
|
|
29
|
+
span,
|
|
30
|
+
code,
|
|
31
|
+
h5,
|
|
32
|
+
i,
|
|
33
|
+
p,
|
|
34
|
+
input,
|
|
35
|
+
} = require("@saltcorn/markup/tags");
|
|
27
36
|
const Table = require("@saltcorn/data/models/table");
|
|
28
37
|
const {
|
|
29
38
|
send_users_page,
|
|
@@ -243,6 +252,18 @@ router.get(
|
|
|
243
252
|
type: "card",
|
|
244
253
|
title: req.__("Users"),
|
|
245
254
|
contents: [
|
|
255
|
+
div(
|
|
256
|
+
{ class: "row mb-3" },
|
|
257
|
+
div(
|
|
258
|
+
{ class: "col-sm-6 offset-sm-3" },
|
|
259
|
+
input({
|
|
260
|
+
class: "form-control",
|
|
261
|
+
type: "search",
|
|
262
|
+
"data-filter-table": "table.user-admin",
|
|
263
|
+
placeholder: "🔍 Search",
|
|
264
|
+
})
|
|
265
|
+
)
|
|
266
|
+
),
|
|
246
267
|
mkTable(
|
|
247
268
|
[
|
|
248
269
|
{ label: req.__("ID"), key: "id" },
|
|
@@ -273,7 +294,7 @@ router.get(
|
|
|
273
294
|
},
|
|
274
295
|
],
|
|
275
296
|
users,
|
|
276
|
-
{ hover: true }
|
|
297
|
+
{ hover: true, class: "user-admin" }
|
|
277
298
|
),
|
|
278
299
|
link(`/useradmin/new`, req.__("Create user")),
|
|
279
300
|
],
|
package/auth/testhelp.js
CHANGED
|
@@ -128,6 +128,20 @@ const getStaffLoginCookie = async () => {
|
|
|
128
128
|
return resToLoginCookie(res);
|
|
129
129
|
};
|
|
130
130
|
|
|
131
|
+
/**
|
|
132
|
+
*
|
|
133
|
+
* @returns {Promise<void>}
|
|
134
|
+
*/
|
|
135
|
+
const getUserLoginCookie = async () => {
|
|
136
|
+
const app = await getApp({ disableCsrf: true });
|
|
137
|
+
const res = await request(app)
|
|
138
|
+
.post("/auth/login/")
|
|
139
|
+
.send("email=user@foo.com")
|
|
140
|
+
.send("password=GFeggwrwq45fjn");
|
|
141
|
+
if (res.statusCode !== 302) console.log(res.text);
|
|
142
|
+
return resToLoginCookie(res);
|
|
143
|
+
};
|
|
144
|
+
|
|
131
145
|
/**
|
|
132
146
|
*
|
|
133
147
|
* @returns {Promise<void>}
|
|
@@ -235,6 +249,7 @@ const notAuthorized = (res) => {
|
|
|
235
249
|
module.exports = {
|
|
236
250
|
getStaffLoginCookie,
|
|
237
251
|
getAdminLoginCookie,
|
|
252
|
+
getUserLoginCookie,
|
|
238
253
|
itShouldRedirectUnauthToLogin,
|
|
239
254
|
toRedirect,
|
|
240
255
|
toInclude,
|
package/locales/da.json
CHANGED
|
@@ -704,5 +704,7 @@
|
|
|
704
704
|
"Tables organise data by fields and rows.": "Tables organise data by fields and rows.",
|
|
705
705
|
"Views display data from tables. A view is a view pattern applied to a table, with configuration.": "Views display data from tables. A view is a view pattern applied to a table, with configuration.",
|
|
706
706
|
"No views": "No views",
|
|
707
|
-
"No pages": "No pages"
|
|
707
|
+
"No pages": "No pages",
|
|
708
|
+
"Welcome to Saltcorn!": "Welcome to Saltcorn!",
|
|
709
|
+
"Notifications": "Notifications"
|
|
708
710
|
}
|
package/locales/en.json
CHANGED
|
@@ -1119,5 +1119,30 @@
|
|
|
1119
1119
|
"Choose the field to be indexed. This make searching the table faster.": "Choose the field to be indexed. This make searching the table faster.",
|
|
1120
1120
|
"Disk usage": "Disk usage",
|
|
1121
1121
|
"CPU usage": "CPU usage",
|
|
1122
|
-
"Mem usage": "Mem usage"
|
|
1122
|
+
"Mem usage": "Mem usage",
|
|
1123
|
+
"The field that will be shown to the user when choosing a value": "The field that will be shown to the user when choosing a value",
|
|
1124
|
+
"String value must match regular expression": "String value must match regular expression",
|
|
1125
|
+
"Modules up-to-date. Please restart server": "Modules up-to-date. Please restart server",
|
|
1126
|
+
"Install git plugins": "Install git plugins",
|
|
1127
|
+
"Set available npm modules": "Set available npm modules",
|
|
1128
|
+
"Only store modules can be installed on tenant instances": "Only store modules can be installed on tenant instances",
|
|
1129
|
+
"Unsafe modules": "Unsafe modules",
|
|
1130
|
+
"Notifications": "Notifications",
|
|
1131
|
+
"No notifications": "No notifications",
|
|
1132
|
+
"In user menu": "In user menu",
|
|
1133
|
+
"Show notifications in the user menu": "Show notifications in the user menu",
|
|
1134
|
+
"Notification settings": "Notification settings",
|
|
1135
|
+
"PWA": "PWA",
|
|
1136
|
+
"Progressive Web Application": "Progressive Web Application",
|
|
1137
|
+
"Display": "Display",
|
|
1138
|
+
"Progressive Web Application enabled": "Progressive Web Application enabled",
|
|
1139
|
+
"Saltcorn test email": "Saltcorn test email",
|
|
1140
|
+
"Hello from Saltcorn": "Hello from Saltcorn",
|
|
1141
|
+
"Set colors": "Set colors",
|
|
1142
|
+
"Theme color": "Theme color",
|
|
1143
|
+
"Background color": "Background color",
|
|
1144
|
+
"Table provider": "Table provider",
|
|
1145
|
+
"Database table": "Database table",
|
|
1146
|
+
"Configure provider": "Configure provider",
|
|
1147
|
+
"In scope:": "In scope:"
|
|
1123
1148
|
}
|
package/locales/pl.json
CHANGED
|
@@ -1106,5 +1106,21 @@
|
|
|
1106
1106
|
"Clear": "Wyczyść",
|
|
1107
1107
|
"Restore a snapshot": "Przywróć snapshot",
|
|
1108
1108
|
"Snapshot restored": "Snapshot przywrócony",
|
|
1109
|
-
"Configuration check report": "Raport sprawdzenia konfiguracji"
|
|
1109
|
+
"Configuration check report": "Raport sprawdzenia konfiguracji",
|
|
1110
|
+
"Re-run": "Uruchom ponownie",
|
|
1111
|
+
"Add constraint:": "Dodaj ograniczenie:",
|
|
1112
|
+
"Index": "Index",
|
|
1113
|
+
"Add constraint: ": "Dodaj ograniczenie: ",
|
|
1114
|
+
"Choose the field to be indexed": "Wybierz pole do indeksacji",
|
|
1115
|
+
"Constraint formula": "Formuła ograniczenia",
|
|
1116
|
+
"Formula must evaluate to true for valid rows. In scope: ": "Formuła musi być prawdziwa dla uwierzytelnienia wierszy. W zakresie: ",
|
|
1117
|
+
"Add %s constraint to %s": "Dodaj %s ograniczenie do %s",
|
|
1118
|
+
"What": "Co",
|
|
1119
|
+
"Choose the field to be indexed. This make searching the table faster.": "Wybierz pola, jakie mają być indeksowane. To przyspieszy wyszukiwanie w tabeli.",
|
|
1120
|
+
"Disk usage": "Zużycie dysku",
|
|
1121
|
+
"CPU usage": "Zużycie procesora",
|
|
1122
|
+
"Mem usage": "Zużycie pamięci",
|
|
1123
|
+
"The field that will be shown to the user when choosing a value": "Pole jakie będzie pokazane użytkownikowi przy wyborze wartości",
|
|
1124
|
+
"String value must match regular expression": "Wartość ciągu musi odpowiadać wyrażeniu regularnemu",
|
|
1125
|
+
"Modules up-to-date. Please restart server": "Moduły zaktualizowane. Proszę zresetować serwer"
|
|
1110
1126
|
}
|
package/markup/admin.js
CHANGED
|
@@ -315,6 +315,7 @@ const send_admin_page = (args) => {
|
|
|
315
315
|
{ text: "System", href: "/admin/system" },
|
|
316
316
|
{ text: "Mobile app", href: "/admin/build-mobile-app" },
|
|
317
317
|
{ text: "Development", href: "/admin/dev" },
|
|
318
|
+
{ text: "Notifications", href: "/admin/notifications" },
|
|
318
319
|
],
|
|
319
320
|
...args,
|
|
320
321
|
});
|
|
@@ -343,7 +344,7 @@ const viewAttributes = async (key) => {
|
|
|
343
344
|
* @param {*} req
|
|
344
345
|
* @returns {void}
|
|
345
346
|
*/
|
|
346
|
-
const
|
|
347
|
+
const check_if_restart_required = (cfgForm, req) => {
|
|
347
348
|
let restart = false;
|
|
348
349
|
cfgForm.fields.forEach((f) => {
|
|
349
350
|
if (configTypes[f.name]?.restart_required) {
|
|
@@ -351,7 +352,7 @@ const flash_restart_if_required = (cfgForm, req) => {
|
|
|
351
352
|
if (current !== cfgForm.values[f.name]) restart = true;
|
|
352
353
|
}
|
|
353
354
|
});
|
|
354
|
-
|
|
355
|
+
return restart;
|
|
355
356
|
};
|
|
356
357
|
|
|
357
358
|
/**
|
|
@@ -396,14 +397,21 @@ const config_fields_form = async ({
|
|
|
396
397
|
const tens = await db.select("_sc_tenants");
|
|
397
398
|
return { options: tens.map((t) => t.subdomain) };
|
|
398
399
|
};
|
|
399
|
-
for (const
|
|
400
|
-
if (typeof
|
|
400
|
+
for (const name0 of field_names) {
|
|
401
|
+
if (typeof name0 === "object" && name0.section_header) {
|
|
401
402
|
fields.push({
|
|
402
403
|
input_type: "section_header",
|
|
403
|
-
label:
|
|
404
|
+
label: name0.section_header,
|
|
404
405
|
});
|
|
405
406
|
continue;
|
|
406
407
|
}
|
|
408
|
+
let name, showIf;
|
|
409
|
+
if (typeof name0 === "object" && name0.name) {
|
|
410
|
+
name = name0.name;
|
|
411
|
+
showIf = name0.showIf;
|
|
412
|
+
} else {
|
|
413
|
+
name = name0;
|
|
414
|
+
}
|
|
407
415
|
values[name] = state.getConfig(name);
|
|
408
416
|
// console.log(`config field name: %s`,name);
|
|
409
417
|
if (configTypes[name].root_only && tenant !== db.connectObj.default_schema)
|
|
@@ -427,6 +435,7 @@ const config_fields_form = async ({
|
|
|
427
435
|
? undefined
|
|
428
436
|
: configTypes[name].type,
|
|
429
437
|
input_type: configTypes[name].input_type,
|
|
438
|
+
showIf,
|
|
430
439
|
attributes: isView
|
|
431
440
|
? await viewAttributes(name)
|
|
432
441
|
: isRole
|
|
@@ -553,7 +562,7 @@ module.exports = {
|
|
|
553
562
|
send_admin_page,
|
|
554
563
|
send_files_page,
|
|
555
564
|
save_config_from_form,
|
|
556
|
-
|
|
565
|
+
check_if_restart_required,
|
|
557
566
|
flash_restart,
|
|
558
567
|
send_tags_page,
|
|
559
568
|
};
|
package/package.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saltcorn/server",
|
|
3
|
-
"version": "0.8.5-beta.
|
|
3
|
+
"version": "0.8.5-beta.5",
|
|
4
4
|
"description": "Server app for Saltcorn, open-source no-code platform",
|
|
5
5
|
"homepage": "https://saltcorn.com",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@saltcorn/base-plugin": "0.8.5-beta.
|
|
10
|
-
"@saltcorn/builder": "0.8.5-beta.
|
|
11
|
-
"@saltcorn/data": "0.8.5-beta.
|
|
12
|
-
"@saltcorn/admin-models": "0.8.5-beta.
|
|
13
|
-
"@saltcorn/filemanager": "0.8.5-beta.
|
|
14
|
-
"@saltcorn/markup": "0.8.5-beta.
|
|
15
|
-
"@saltcorn/sbadmin2": "0.8.5-beta.
|
|
9
|
+
"@saltcorn/base-plugin": "0.8.5-beta.5",
|
|
10
|
+
"@saltcorn/builder": "0.8.5-beta.5",
|
|
11
|
+
"@saltcorn/data": "0.8.5-beta.5",
|
|
12
|
+
"@saltcorn/admin-models": "0.8.5-beta.5",
|
|
13
|
+
"@saltcorn/filemanager": "0.8.5-beta.5",
|
|
14
|
+
"@saltcorn/markup": "0.8.5-beta.5",
|
|
15
|
+
"@saltcorn/sbadmin2": "0.8.5-beta.5",
|
|
16
16
|
"@socket.io/cluster-adapter": "^0.2.1",
|
|
17
17
|
"@socket.io/sticky": "^1.0.1",
|
|
18
18
|
"adm-zip": "0.5.10",
|
|
@@ -167,7 +167,16 @@ function apply_showif() {
|
|
|
167
167
|
}
|
|
168
168
|
});
|
|
169
169
|
});
|
|
170
|
-
|
|
170
|
+
$("[data-filter-table]").each(function (ix, element) {
|
|
171
|
+
const e = $(element);
|
|
172
|
+
const target = $(e.attr("data-filter-table"));
|
|
173
|
+
$(e).on("keyup", function () {
|
|
174
|
+
const value = $(this).val().toLowerCase();
|
|
175
|
+
target.find("tr").filter(function () {
|
|
176
|
+
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1);
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
});
|
|
171
180
|
$("[data-source-url]").each(function (ix, element) {
|
|
172
181
|
const e = $(element);
|
|
173
182
|
const rec0 = get_form_record(e);
|
|
@@ -1045,3 +1054,23 @@ function split_paste_handler(e) {
|
|
|
1045
1054
|
function is_paging_param(key) {
|
|
1046
1055
|
return key.endsWith("_page") || key.endsWith("_pagesize");
|
|
1047
1056
|
}
|
|
1057
|
+
function check_saltcorn_notifications() {
|
|
1058
|
+
$.ajax(`/notifications/count-unread`).then((resp) => {
|
|
1059
|
+
if (resp.success) {
|
|
1060
|
+
const n = resp.success;
|
|
1061
|
+
const menu_item = $(`a.notify-menu-item`);
|
|
1062
|
+
|
|
1063
|
+
menu_item.html(
|
|
1064
|
+
`<i class="fa-fw mr-05 fas fa-bell"></i>Notifications (${n})`
|
|
1065
|
+
);
|
|
1066
|
+
$(".user-nav-section").html(
|
|
1067
|
+
`<i class="fa-fw mr-05 fas fa-user"></i>User (${n})`
|
|
1068
|
+
);
|
|
1069
|
+
$(".user-nav-section-with-span").html(
|
|
1070
|
+
`<i class="fa-fw mr-05 fas fa-user"></i><span>User (${n})</span>`
|
|
1071
|
+
);
|
|
1072
|
+
window.update_theme_notification_count &&
|
|
1073
|
+
window.update_theme_notification_count(n);
|
|
1074
|
+
}
|
|
1075
|
+
});
|
|
1076
|
+
}
|
package/public/saltcorn.css
CHANGED
|
@@ -375,3 +375,30 @@ table.table-inner-grid td {
|
|
|
375
375
|
margin-bottom: 0 !important;
|
|
376
376
|
text-decoration: underline;
|
|
377
377
|
}
|
|
378
|
+
|
|
379
|
+
@supports (zoom: 2) {
|
|
380
|
+
input[type="radio"].large,
|
|
381
|
+
input[type="checkbox"].large {
|
|
382
|
+
zoom: 2;
|
|
383
|
+
}
|
|
384
|
+
input[type="radio"].medium,
|
|
385
|
+
input[type="checkbox"].medium {
|
|
386
|
+
zoom: 1.5;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
@supports not (zoom: 2) {
|
|
390
|
+
input[type="radio"].large,
|
|
391
|
+
input[type="checkbox"].large {
|
|
392
|
+
transform: scale(2);
|
|
393
|
+
margin: 15px;
|
|
394
|
+
}
|
|
395
|
+
input[type="radio"].medium,
|
|
396
|
+
input[type="checkbox"].medium {
|
|
397
|
+
transform: scale(1.5);
|
|
398
|
+
margin: 8px;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
div.unread-notify {
|
|
403
|
+
border-left: 4px solid green;
|
|
404
|
+
}
|
package/public/saltcorn.js
CHANGED
|
@@ -326,6 +326,9 @@ function saveAndContinue(e, k) {
|
|
|
326
326
|
`<input type="hidden" class="form-control " name="id" value="${res.id}">`
|
|
327
327
|
);
|
|
328
328
|
}
|
|
329
|
+
if (res.notify) {
|
|
330
|
+
notifyAlert(res.notify);
|
|
331
|
+
}
|
|
329
332
|
},
|
|
330
333
|
error: function (request) {
|
|
331
334
|
var ct = request.getResponseHeader("content-type") || "";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// do nothing so far
|