@saltcorn/server 1.0.0-beta.9 → 1.0.0-rc.2
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 +4 -7
- package/auth/admin.js +1 -0
- package/auth/routes.js +4 -1
- package/help/Aggregation where formula.tmd +11 -0
- package/help/Calculated fields.tmd +28 -0
- package/help/Date format.tmd +55 -0
- package/help/Protected fields.tmd +4 -0
- package/help/Snapshots.tmd +19 -0
- package/help/Table history.tmd +42 -0
- package/help/index.js +2 -0
- package/load_plugins.js +89 -8
- package/locales/en.json +13 -1
- package/locales/pl.json +407 -85
- package/package.json +11 -11
- package/public/gridedit.js +3 -1
- package/public/saltcorn-builder.css +0 -7
- package/public/saltcorn-common.js +195 -100
- package/public/saltcorn.css +17 -0
- package/public/saltcorn.js +76 -17
- package/routes/actions.js +19 -25
- package/routes/admin.js +256 -54
- package/routes/delete.js +4 -1
- package/routes/eventlog.js +2 -1
- package/routes/fields.js +21 -5
- package/routes/files.js +3 -0
- package/routes/infoarch.js +40 -2
- package/routes/list.js +1 -1
- package/routes/menu.js +3 -0
- package/routes/pageedit.js +9 -2
- package/routes/plugins.js +118 -23
- package/routes/scapi.js +19 -0
- package/routes/search.js +6 -1
- package/routes/sync.js +2 -1
- package/routes/tables.js +14 -4
- package/routes/viewedit.js +7 -4
- package/serve.js +17 -3
- package/tests/fields.test.js +32 -0
- package/tests/plugin_install.test.js +235 -0
- package/tests/plugins.test.js +140 -0
package/package.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saltcorn/server",
|
|
3
|
-
"version": "1.0.0-
|
|
3
|
+
"version": "1.0.0-rc.2",
|
|
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
9
|
"@aws-sdk/client-s3": "^3.451.0",
|
|
10
|
-
"@saltcorn/base-plugin": "1.0.0-
|
|
11
|
-
"@saltcorn/builder": "1.0.0-
|
|
12
|
-
"@saltcorn/data": "1.0.0-
|
|
13
|
-
"@saltcorn/admin-models": "1.0.0-
|
|
14
|
-
"@saltcorn/filemanager": "1.0.0-
|
|
15
|
-
"@saltcorn/markup": "1.0.0-
|
|
16
|
-
"@saltcorn/plugins-loader": "1.0.0-
|
|
17
|
-
"@saltcorn/sbadmin2": "1.0.0-
|
|
10
|
+
"@saltcorn/base-plugin": "1.0.0-rc.2",
|
|
11
|
+
"@saltcorn/builder": "1.0.0-rc.2",
|
|
12
|
+
"@saltcorn/data": "1.0.0-rc.2",
|
|
13
|
+
"@saltcorn/admin-models": "1.0.0-rc.2",
|
|
14
|
+
"@saltcorn/filemanager": "1.0.0-rc.2",
|
|
15
|
+
"@saltcorn/markup": "1.0.0-rc.2",
|
|
16
|
+
"@saltcorn/plugins-loader": "1.0.0-rc.2",
|
|
17
|
+
"@saltcorn/sbadmin2": "1.0.0-rc.2",
|
|
18
18
|
"@socket.io/cluster-adapter": "^0.2.1",
|
|
19
19
|
"@socket.io/sticky": "^1.0.1",
|
|
20
20
|
"adm-zip": "0.5.10",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"node-fetch": "2.6.9",
|
|
47
47
|
"node-watch": "^0.7.2",
|
|
48
48
|
"notp": "2.0.3",
|
|
49
|
-
"npm-registry-fetch": "
|
|
49
|
+
"npm-registry-fetch": "17.1.0",
|
|
50
50
|
"passport": "^0.6.0",
|
|
51
51
|
"passport-custom": "^1.1.1",
|
|
52
52
|
"passport-http-bearer": "^1.0.1",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"pg": "^8.2.1",
|
|
56
56
|
"pluralize": "^8.0.0",
|
|
57
57
|
"qrcode": "1.5.1",
|
|
58
|
-
"resize-with-sharp-or-jimp": "0.1.
|
|
58
|
+
"resize-with-sharp-or-jimp": "0.1.8",
|
|
59
59
|
"semver": "^7.6.0",
|
|
60
60
|
"socket.io": "4.6.0",
|
|
61
61
|
"systeminformation": "^5.21.7",
|
package/public/gridedit.js
CHANGED
|
@@ -87,7 +87,9 @@ function isoDateFormatter(cell, formatterParams, onRendered) {
|
|
|
87
87
|
if (formatterParams && formatterParams.format)
|
|
88
88
|
return dayjs(val).format(formatterParams.format);
|
|
89
89
|
|
|
90
|
-
return new Date(val).toLocaleDateString(window.detected_locale || "en"
|
|
90
|
+
return new Date(val).toLocaleDateString(window.detected_locale || "en", {
|
|
91
|
+
timeZone: "UTC",
|
|
92
|
+
});
|
|
91
93
|
}
|
|
92
94
|
function colorFormatter(cell, formatterParams, onRendered) {
|
|
93
95
|
const val = cell.getValue();
|
|
@@ -525,10 +525,3 @@ div.componets-and-library-accordion {
|
|
|
525
525
|
.toolbox-card:nth-child(2) {
|
|
526
526
|
margin-bottom: 0px;
|
|
527
527
|
}
|
|
528
|
-
#builder-main-canvas {
|
|
529
|
-
height: calc(100dvh - 50px) !important;
|
|
530
|
-
min-height: 600px;
|
|
531
|
-
}
|
|
532
|
-
#builder-main-canvas.h-100 {
|
|
533
|
-
height: 100% !important;
|
|
534
|
-
}
|
|
@@ -18,7 +18,7 @@ function monospace_block_click(e) {
|
|
|
18
18
|
function copy_monospace_block(e) {
|
|
19
19
|
let e1 = $(e).next("pre");
|
|
20
20
|
let e2 = $(e1).next("pre");
|
|
21
|
-
if (!e2.length) return navigator.clipboard.writeText($(
|
|
21
|
+
if (!e2.length) return navigator.clipboard.writeText($(e1).text());
|
|
22
22
|
const e1t = e1.text();
|
|
23
23
|
const e2t = e2.text();
|
|
24
24
|
if (e1t.length > e2t.length) return navigator.clipboard.writeText(e1t);
|
|
@@ -63,14 +63,20 @@ function reset_nearest_form(that) {
|
|
|
63
63
|
|
|
64
64
|
function add_repeater(nm) {
|
|
65
65
|
var es = $("div.form-repeat.repeat-" + nm);
|
|
66
|
-
|
|
66
|
+
const ncopy = es.length - 1;
|
|
67
|
+
var e = es.last();
|
|
67
68
|
var newix = es.length;
|
|
68
69
|
var newe = $(e).clone();
|
|
69
70
|
newe.find("[name]").each(function (ix, element) {
|
|
70
71
|
if ($(element).hasClass("omit-repeater-clone")) $(element).remove();
|
|
71
|
-
|
|
72
|
-
var
|
|
72
|
+
const oldnm = element.name || "";
|
|
73
|
+
var newnm = (element.name || "").replace("_" + ncopy, "_" + newix);
|
|
74
|
+
var newid = (element.id || "").replace("_" + ncopy, "_" + newix);
|
|
73
75
|
$(element).attr("name", newnm).attr("id", newid);
|
|
76
|
+
if (element.tagName === "SELECT") {
|
|
77
|
+
const original = document.getElementsByName(oldnm)[0];
|
|
78
|
+
if (original) element.selectedIndex = original.selectedIndex;
|
|
79
|
+
}
|
|
74
80
|
});
|
|
75
81
|
newe.appendTo($("div.repeats-" + nm));
|
|
76
82
|
newe.find("[data-on-cloned]").each(function (ix, element) {
|
|
@@ -80,6 +86,27 @@ function add_repeater(nm) {
|
|
|
80
86
|
});
|
|
81
87
|
}
|
|
82
88
|
|
|
89
|
+
function rep_del(e) {
|
|
90
|
+
var myrep = $(e).closest(".form-repeat");
|
|
91
|
+
var ix = myrep.index();
|
|
92
|
+
var parent = myrep.parent();
|
|
93
|
+
myrep.remove();
|
|
94
|
+
parent.children().each(function (childix, element) {
|
|
95
|
+
if (childix > ix) {
|
|
96
|
+
reindex(element, childix, childix - 1);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function reindex(element, oldix, newix) {
|
|
102
|
+
$(element).html(
|
|
103
|
+
$(element)
|
|
104
|
+
.html()
|
|
105
|
+
.split("_" + oldix + '"')
|
|
106
|
+
.join("_" + newix + '"')
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
83
110
|
const _apply_showif_plugins = [];
|
|
84
111
|
|
|
85
112
|
const add_apply_showif_plugin = (p) => {
|
|
@@ -115,16 +142,18 @@ function apply_showif() {
|
|
|
115
142
|
}
|
|
116
143
|
if (!e.data("data-closest-form-ns"))
|
|
117
144
|
e.data("data-closest-form-ns", e.closest(".form-namespace"));
|
|
118
|
-
if (to_show(e))
|
|
119
|
-
e.show(
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
)
|
|
127
|
-
|
|
145
|
+
if (to_show(e)) {
|
|
146
|
+
e.find("input, textarea, button, select, [data-show-if]").prop(
|
|
147
|
+
"disabled",
|
|
148
|
+
e.attr("data-disabled") || false
|
|
149
|
+
);
|
|
150
|
+
element.style.display = "";
|
|
151
|
+
} else {
|
|
152
|
+
e.find(
|
|
153
|
+
"input:enabled, textarea:enabled, button:enabled, select:enabled, [data-show-if]:not([disabled])"
|
|
154
|
+
).prop("disabled", true);
|
|
155
|
+
element.style.setProperty("display", "none", "important");
|
|
156
|
+
}
|
|
128
157
|
} catch (e) {
|
|
129
158
|
console.error(e);
|
|
130
159
|
}
|
|
@@ -155,8 +184,21 @@ function apply_showif() {
|
|
|
155
184
|
var current = e.attr("data-selected") || e.val();
|
|
156
185
|
//console.log({ field: e.attr("name"), target: data[0], val, current });
|
|
157
186
|
e.empty();
|
|
187
|
+
//TODO clean repetition in following cose
|
|
158
188
|
(options || []).forEach((o) => {
|
|
159
|
-
if (
|
|
189
|
+
if (o && o.optgroup) {
|
|
190
|
+
const opts = o.options
|
|
191
|
+
.map(
|
|
192
|
+
(innero) =>
|
|
193
|
+
`<option ${
|
|
194
|
+
`${current}` === `${innero.value || innero}` ? "selected " : ""
|
|
195
|
+
}value="${innero.value || innero}">${
|
|
196
|
+
innero.label || innero
|
|
197
|
+
}</option>`
|
|
198
|
+
)
|
|
199
|
+
.join("");
|
|
200
|
+
e.append($(`<optgroup label="${o.label}">` + opts + "</optgroup>"));
|
|
201
|
+
} else if (
|
|
160
202
|
!(o && typeof o.label !== "undefined" && typeof o.value !== "undefined")
|
|
161
203
|
) {
|
|
162
204
|
if (`${current}` === `${o}`)
|
|
@@ -303,25 +345,27 @@ function apply_showif() {
|
|
|
303
345
|
...cache,
|
|
304
346
|
[qs]: "fetching",
|
|
305
347
|
});
|
|
306
|
-
$.ajax(`/api/${dynwhere.table}?${qs}`)
|
|
307
|
-
|
|
308
|
-
if (
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
348
|
+
$.ajax(`/api/${dynwhere.table}?${qs}`)
|
|
349
|
+
.then((resp) => {
|
|
350
|
+
if (resp.success) {
|
|
351
|
+
if (window._sc_loglevel > 4)
|
|
352
|
+
console.log("dynwhere fetch", qs, resp.success);
|
|
353
|
+
|
|
354
|
+
activate(resp.success, qs);
|
|
355
|
+
const cacheNow = e.prop("data-fetch-options-cache") || {};
|
|
356
|
+
e.prop("data-fetch-options-cache", {
|
|
357
|
+
...cacheNow,
|
|
358
|
+
[qs]: resp.success,
|
|
359
|
+
});
|
|
360
|
+
} else {
|
|
361
|
+
const cacheNow = e.prop("data-fetch-options-cache") || {};
|
|
362
|
+
e.prop("data-fetch-options-cache", {
|
|
363
|
+
...cacheNow,
|
|
364
|
+
[qs]: undefined,
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
})
|
|
368
|
+
.fail(checkNetworkError);
|
|
325
369
|
}
|
|
326
370
|
});
|
|
327
371
|
$("[data-filter-table]").each(function (ix, element) {
|
|
@@ -530,6 +574,7 @@ function get_form_record(e_in, select_labels) {
|
|
|
530
574
|
$(e_in).prop("data-join-values", jvs);
|
|
531
575
|
apply_showif();
|
|
532
576
|
},
|
|
577
|
+
error: checkNetworkError,
|
|
533
578
|
});
|
|
534
579
|
}
|
|
535
580
|
$(e_in).prop("data-join-key-values", keyVals);
|
|
@@ -558,27 +603,6 @@ function showIfFormulaInputs(e, fml) {
|
|
|
558
603
|
}
|
|
559
604
|
}
|
|
560
605
|
|
|
561
|
-
function rep_del(e) {
|
|
562
|
-
var myrep = $(e).closest(".form-repeat");
|
|
563
|
-
var ix = myrep.index();
|
|
564
|
-
var parent = myrep.parent();
|
|
565
|
-
parent.children().each(function (childix, element) {
|
|
566
|
-
if (childix > ix) {
|
|
567
|
-
reindex(element, childix, childix - 1);
|
|
568
|
-
}
|
|
569
|
-
});
|
|
570
|
-
myrep.remove();
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
function reindex(element, oldix, newix) {
|
|
574
|
-
$(element).html(
|
|
575
|
-
$(element)
|
|
576
|
-
.html()
|
|
577
|
-
.split("_" + oldix)
|
|
578
|
-
.join("_" + newix)
|
|
579
|
-
);
|
|
580
|
-
}
|
|
581
|
-
|
|
582
606
|
function get_form_subset_record(e) {
|
|
583
607
|
const rec = {};
|
|
584
608
|
e.find("input[name],select[name]").each(function () {
|
|
@@ -740,6 +764,42 @@ function doMobileTransforms() {
|
|
|
740
764
|
}
|
|
741
765
|
});
|
|
742
766
|
|
|
767
|
+
$("[mobile-youtube-video]").each(function () {
|
|
768
|
+
const jThis = $(this);
|
|
769
|
+
const src = jThis.attr("src");
|
|
770
|
+
if (src) {
|
|
771
|
+
const rndid = `m-video-${Math.floor(Math.random() * 16777215).toString(
|
|
772
|
+
16
|
|
773
|
+
)}`;
|
|
774
|
+
const url = new URL(src);
|
|
775
|
+
const path = url.pathname;
|
|
776
|
+
const imageId = path.split("/").pop();
|
|
777
|
+
const thumbnailContainer = document.createElement("div");
|
|
778
|
+
thumbnailContainer.className = "mobile-thumbnail-container";
|
|
779
|
+
thumbnailContainer.id = rndid;
|
|
780
|
+
const img = document.createElement("img");
|
|
781
|
+
img.src = `https://img.youtube.com/vi/${imageId}/0.jpg`;
|
|
782
|
+
img.style = "width: 100%; max-width: 600px;";
|
|
783
|
+
img.id = rndid;
|
|
784
|
+
img.setAttribute(
|
|
785
|
+
"onclick",
|
|
786
|
+
`openInAppBrowser('${src.replace(
|
|
787
|
+
"com/embed",
|
|
788
|
+
"com/watch"
|
|
789
|
+
)}', '${rndid}')`
|
|
790
|
+
);
|
|
791
|
+
thumbnailContainer.appendChild(img);
|
|
792
|
+
const spinner = document.createElement("div");
|
|
793
|
+
spinner.className = "mobile-thumbnail-spinner-overlay";
|
|
794
|
+
const spinnerInner = document.createElement("div");
|
|
795
|
+
spinnerInner.className = "d-none spinner-border text-light";
|
|
796
|
+
spinnerInner.setAttribute("role", "status");
|
|
797
|
+
spinner.appendChild(spinnerInner);
|
|
798
|
+
thumbnailContainer.appendChild(spinner);
|
|
799
|
+
jThis.replaceWith(thumbnailContainer);
|
|
800
|
+
}
|
|
801
|
+
});
|
|
802
|
+
|
|
743
803
|
$("button").each(function () {
|
|
744
804
|
for (const [k, v] of Object.entries({ onclick: replacers.onclick })) {
|
|
745
805
|
for ({ web, mobile } of v) replaceAttr(this, k, v.web, v.mobile);
|
|
@@ -894,31 +954,33 @@ function initialize_page() {
|
|
|
894
954
|
})
|
|
895
955
|
);
|
|
896
956
|
const doAjaxOptionsFetch = (tblName, target) => {
|
|
897
|
-
$.ajax(`/api/${tblName}`)
|
|
898
|
-
|
|
899
|
-
resp.success
|
|
900
|
-
a
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
(
|
|
905
|
-
|
|
906
|
-
r.id
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
957
|
+
$.ajax(`/api/${tblName}`)
|
|
958
|
+
.then((resp) => {
|
|
959
|
+
if (resp.success) {
|
|
960
|
+
resp.success.sort((a, b) =>
|
|
961
|
+
a[target]?.toLowerCase?.() > b[target]?.toLowerCase?.() ? 1 : -1
|
|
962
|
+
);
|
|
963
|
+
|
|
964
|
+
const selopts = resp.success.map(
|
|
965
|
+
(r) =>
|
|
966
|
+
`<option ${current == r.id ? `selected ` : ``}value="${
|
|
967
|
+
r.id
|
|
968
|
+
}">${escapeHtml(r[target])}</option>`
|
|
969
|
+
);
|
|
970
|
+
$(this).replaceWith(
|
|
971
|
+
`<form method="post" action="${url}" ${
|
|
972
|
+
ajax ? `onsubmit="inline_ajax_submit(event, '${opts}')"` : ""
|
|
973
|
+
}>
|
|
913
974
|
<input type="hidden" name="_csrf" value="${_sc_globalCsrf}">
|
|
914
975
|
<select name="${key}" value="${current}">${selopts}
|
|
915
976
|
</select>
|
|
916
977
|
<button type="submit" class="btn btn-sm btn-primary">OK</button>
|
|
917
978
|
<button onclick="cancel_inline_edit(event, '${opts}')" type="button" class="btn btn-sm btn-danger"><i class="fas fa-times"></i></button>
|
|
918
979
|
</form>`
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
980
|
+
);
|
|
981
|
+
}
|
|
982
|
+
})
|
|
983
|
+
.fail(checkNetworkError);
|
|
922
984
|
};
|
|
923
985
|
if (type === "JSON" && schema && schema.type.startsWith("Key to ")) {
|
|
924
986
|
const tblName = schema.type.replace("Key to ", "");
|
|
@@ -1097,7 +1159,8 @@ function initialize_page() {
|
|
|
1097
1159
|
initialize_page();
|
|
1098
1160
|
},
|
|
1099
1161
|
error: function (res) {
|
|
1100
|
-
|
|
1162
|
+
if (!checkNetworkError(res))
|
|
1163
|
+
notifyAlert({ type: "danger", text: res.responseText });
|
|
1101
1164
|
if ($e.html() === "Loading...") $e.html("");
|
|
1102
1165
|
},
|
|
1103
1166
|
});
|
|
@@ -1172,9 +1235,10 @@ function inline_ajax_submit(e, opts1) {
|
|
|
1172
1235
|
inline_submit_success(e, form, opts);
|
|
1173
1236
|
},
|
|
1174
1237
|
error: function (e) {
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1238
|
+
if (!checkNetworkError(e))
|
|
1239
|
+
ajax_done(
|
|
1240
|
+
e.responseJSON || { error: "Unknown error: " + e.responseText }
|
|
1241
|
+
);
|
|
1178
1242
|
},
|
|
1179
1243
|
});
|
|
1180
1244
|
}
|
|
@@ -1217,6 +1281,7 @@ function enable_codemirror(f) {
|
|
|
1217
1281
|
dataType: "script",
|
|
1218
1282
|
cache: true,
|
|
1219
1283
|
success: f,
|
|
1284
|
+
error: checkNetworkError,
|
|
1220
1285
|
});
|
|
1221
1286
|
}
|
|
1222
1287
|
function tristateClick(e, required) {
|
|
@@ -1336,10 +1401,14 @@ function notifyAlert(note, spin) {
|
|
|
1336
1401
|
if (typeof note == "string") {
|
|
1337
1402
|
txt = note;
|
|
1338
1403
|
type = "info";
|
|
1339
|
-
} else {
|
|
1404
|
+
} else if (note.text) {
|
|
1340
1405
|
txt = note.text;
|
|
1341
|
-
type = note.type;
|
|
1406
|
+
type = note.type || "info";
|
|
1407
|
+
} else {
|
|
1408
|
+
type = "info";
|
|
1409
|
+
txt = JSON.stringify(note, null, 2);
|
|
1342
1410
|
}
|
|
1411
|
+
|
|
1343
1412
|
const { id, html } = buildToast(txt, type, spin);
|
|
1344
1413
|
let $modal = $("#scmodal");
|
|
1345
1414
|
if ($modal.length && $modal.hasClass("show"))
|
|
@@ -1524,7 +1593,8 @@ function reloadEmbeddedEditOwnViews(form, id) {
|
|
|
1524
1593
|
initialize_page();
|
|
1525
1594
|
},
|
|
1526
1595
|
error: function (res) {
|
|
1527
|
-
|
|
1596
|
+
if (!checkNetworkError(res))
|
|
1597
|
+
notifyAlert({ type: "danger", text: res.responseText });
|
|
1528
1598
|
},
|
|
1529
1599
|
});
|
|
1530
1600
|
});
|
|
@@ -1757,24 +1827,26 @@ function is_paging_param(key) {
|
|
|
1757
1827
|
return key.endsWith("_page") || key.endsWith("_pagesize");
|
|
1758
1828
|
}
|
|
1759
1829
|
function check_saltcorn_notifications() {
|
|
1760
|
-
$.ajax(`/notifications/count-unread`)
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
window.update_theme_notification_count
|
|
1776
|
-
|
|
1777
|
-
|
|
1830
|
+
$.ajax(`/notifications/count-unread`)
|
|
1831
|
+
.then((resp) => {
|
|
1832
|
+
if (resp.success) {
|
|
1833
|
+
const n = resp.success;
|
|
1834
|
+
const menu_item = $(`a.notify-menu-item`);
|
|
1835
|
+
|
|
1836
|
+
menu_item.html(
|
|
1837
|
+
`<i class="fa-fw mr-05 fas fa-bell"></i>Notifications (${n})`
|
|
1838
|
+
);
|
|
1839
|
+
$(".user-nav-section").html(
|
|
1840
|
+
`<i class="fa-fw mr-05 fas fa-user"></i>User (${n})`
|
|
1841
|
+
);
|
|
1842
|
+
$(".user-nav-section-with-span").html(
|
|
1843
|
+
`<i class="fa-fw mr-05 fas fa-user"></i><span>User (${n})</span>`
|
|
1844
|
+
);
|
|
1845
|
+
window.update_theme_notification_count &&
|
|
1846
|
+
window.update_theme_notification_count(n);
|
|
1847
|
+
}
|
|
1848
|
+
})
|
|
1849
|
+
.fail(checkNetworkError);
|
|
1778
1850
|
}
|
|
1779
1851
|
|
|
1780
1852
|
function disable_inactive_tab_inputs(id) {
|
|
@@ -1834,6 +1906,8 @@ function close_saltcorn_modal() {
|
|
|
1834
1906
|
}
|
|
1835
1907
|
}
|
|
1836
1908
|
|
|
1909
|
+
let _sc_currently_reloading;
|
|
1910
|
+
|
|
1837
1911
|
function reload_embedded_view(viewname, new_query_string) {
|
|
1838
1912
|
const isNode = getIsNode();
|
|
1839
1913
|
const updater = ($e, res) => {
|
|
@@ -1861,16 +1935,21 @@ function reload_embedded_view(viewname, new_query_string) {
|
|
|
1861
1935
|
url = url.split("?")[0] + "?" + new_query_string;
|
|
1862
1936
|
}
|
|
1863
1937
|
if (isNode) {
|
|
1938
|
+
if (url === _sc_currently_reloading) return;
|
|
1939
|
+
_sc_currently_reloading = url;
|
|
1864
1940
|
$.ajax(url, {
|
|
1865
1941
|
headers: {
|
|
1866
1942
|
pjaxpageload: "true",
|
|
1867
1943
|
localizedstate: "true", //no admin bar
|
|
1868
1944
|
},
|
|
1869
1945
|
success: function (res, textStatus, request) {
|
|
1946
|
+
_sc_currently_reloading = null;
|
|
1870
1947
|
updater($e, res);
|
|
1871
1948
|
},
|
|
1872
1949
|
error: function (res) {
|
|
1873
|
-
|
|
1950
|
+
_sc_currently_reloading = null;
|
|
1951
|
+
if (!checkNetworkError(res))
|
|
1952
|
+
notifyAlert({ type: "danger", text: res.responseText });
|
|
1874
1953
|
},
|
|
1875
1954
|
});
|
|
1876
1955
|
} else {
|
|
@@ -1880,3 +1959,19 @@ function reload_embedded_view(viewname, new_query_string) {
|
|
|
1880
1959
|
}
|
|
1881
1960
|
});
|
|
1882
1961
|
}
|
|
1962
|
+
|
|
1963
|
+
function update_time_of_week(nm) {
|
|
1964
|
+
return function () {
|
|
1965
|
+
const day = $(`#input${nm}__day`).val();
|
|
1966
|
+
const flat = document.querySelector(`#input${nm}__time`)._flatpickr;
|
|
1967
|
+
|
|
1968
|
+
const time = flat.selectedDates?.[0];
|
|
1969
|
+
let s;
|
|
1970
|
+
if (time) {
|
|
1971
|
+
const m = time.getMinutes();
|
|
1972
|
+
|
|
1973
|
+
s = `${day} ${time.getHours()} ${m < 10 ? `0${m}` : m}`;
|
|
1974
|
+
} else s = day;
|
|
1975
|
+
$(`#inputh${nm}`).val(s).trigger("change");
|
|
1976
|
+
};
|
|
1977
|
+
}
|
package/public/saltcorn.css
CHANGED
|
@@ -590,3 +590,20 @@ button.monospace-copy-btn {
|
|
|
590
590
|
.custom-file-label {
|
|
591
591
|
margin-left: 10px;
|
|
592
592
|
}
|
|
593
|
+
|
|
594
|
+
.mobile-thumbnail-container {
|
|
595
|
+
position: relative;
|
|
596
|
+
display: inline-block;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
.mobile-thumbnail-spinner-overlay {
|
|
600
|
+
position: absolute;
|
|
601
|
+
top: 50%;
|
|
602
|
+
left: 50%;
|
|
603
|
+
transform: translate(-50%, -50%);
|
|
604
|
+
z-index: 10;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
.mobile-thumbnail-container img {
|
|
608
|
+
display: block;
|
|
609
|
+
}
|