@saltcorn/server 0.7.2-beta.3 → 0.7.2-beta.6
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 -7
- package/load_plugins.js +10 -3
- package/locales/en.json +13 -2
- package/locales/it.json +2 -1
- package/locales/ru.json +26 -15
- package/markup/admin.js +25 -9
- package/package.json +7 -7
- package/public/saltcorn-common.js +442 -3
- package/public/saltcorn.js +3 -436
- package/routes/admin.js +24 -14
- package/routes/eventlog.js +30 -30
- package/routes/fields.js +6 -0
- package/routes/files.js +7 -20
- package/routes/homepage.js +35 -7
- package/routes/menu.js +11 -7
- package/routes/tables.js +1 -1
- package/routes/tenant.js +13 -10
- package/routes/viewedit.js +1 -1
- package/wrapper.js +55 -12
package/public/saltcorn.js
CHANGED
|
@@ -1,365 +1,14 @@
|
|
|
1
|
-
//https://stackoverflow.com/a/698386
|
|
2
|
-
jQuery.fn.swapWith = function (to) {
|
|
3
|
-
return this.each(function () {
|
|
4
|
-
var copy_to = $(to).clone(true);
|
|
5
|
-
var copy_from = $(this).clone(true);
|
|
6
|
-
$(to).replaceWith(copy_from);
|
|
7
|
-
$(this).replaceWith(copy_to);
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
//avoids hiding in overflow:hidden
|
|
12
|
-
function init_bs5_dropdowns() {
|
|
13
|
-
$("body").on(
|
|
14
|
-
"show.bs.dropdown",
|
|
15
|
-
"table [data-bs-toggle=dropdown]",
|
|
16
|
-
function () {
|
|
17
|
-
let target;
|
|
18
|
-
if (!$("#page-inner-content").length) target = $("body");
|
|
19
|
-
else target = $("#page-inner-content");
|
|
20
|
-
let dropdown = bootstrap.Dropdown.getInstance(this);
|
|
21
|
-
$(dropdown._menu).insertAfter(target);
|
|
22
|
-
}
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
1
|
function sortby(k, desc) {
|
|
26
2
|
set_state_fields({ _sortby: k, _sortdesc: desc ? "on" : { unset: true } });
|
|
27
3
|
}
|
|
28
4
|
function gopage(n, pagesize, extra = {}) {
|
|
29
5
|
set_state_fields({ ...extra, _page: n, _pagesize: pagesize });
|
|
30
6
|
}
|
|
31
|
-
function add_repeater(nm) {
|
|
32
|
-
var es = $("div.form-repeat.repeat-" + nm);
|
|
33
|
-
var e = es.first();
|
|
34
|
-
var newix = es.length;
|
|
35
|
-
var newe = $(e).clone();
|
|
36
|
-
newe.find("[name]").each(function (ix, element) {
|
|
37
|
-
var newnm = (element.name || "").replace("_0", "_" + newix);
|
|
38
|
-
var newid = (element.id || "").replace("_0", "_" + newix);
|
|
39
|
-
$(element).attr("name", newnm).attr("id", newid);
|
|
40
|
-
});
|
|
41
|
-
newe.appendTo($("div.repeats-" + nm));
|
|
42
|
-
}
|
|
43
|
-
// "e.closest('.form-namespace').find('.coltype').val()==='Field';"
|
|
44
|
-
function apply_showif() {
|
|
45
|
-
$("[data-show-if]").each(function (ix, element) {
|
|
46
|
-
var e = $(element);
|
|
47
|
-
try {
|
|
48
|
-
var to_show = new Function(
|
|
49
|
-
"e",
|
|
50
|
-
"return " + decodeURIComponent(e.attr("data-show-if"))
|
|
51
|
-
);
|
|
52
|
-
if (to_show(e))
|
|
53
|
-
e.show()
|
|
54
|
-
.find("input, textarea, button, select")
|
|
55
|
-
.prop("disabled", e.attr("data-disabled") || false);
|
|
56
|
-
else
|
|
57
|
-
e.hide().find("input, textarea, button, select").prop("disabled", true);
|
|
58
|
-
} catch (e) {
|
|
59
|
-
console.error(e);
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
$("[data-calc-options]").each(function (ix, element) {
|
|
63
|
-
var e = $(element);
|
|
64
|
-
var data = JSON.parse(decodeURIComponent(e.attr("data-calc-options")));
|
|
65
|
-
|
|
66
|
-
var val = e
|
|
67
|
-
.closest(".form-namespace")
|
|
68
|
-
.find(`[data-fieldname=${data[0]}]`)
|
|
69
|
-
.val();
|
|
70
|
-
|
|
71
|
-
var options = data[1][val];
|
|
72
|
-
var current = e.attr("data-selected");
|
|
73
|
-
//console.log({ val, options, current, data });
|
|
74
|
-
e.empty();
|
|
75
|
-
(options || []).forEach((o) => {
|
|
76
|
-
if (
|
|
77
|
-
!(o && typeof o.label !== "undefined" && typeof o.value !== "undefined")
|
|
78
|
-
) {
|
|
79
|
-
if (`${current}` === `${o}`)
|
|
80
|
-
e.append($("<option selected>" + o + "</option>"));
|
|
81
|
-
else e.append($("<option>" + o + "</option>"));
|
|
82
|
-
} else {
|
|
83
|
-
e.append(
|
|
84
|
-
$(
|
|
85
|
-
`<option ${
|
|
86
|
-
`${current}` === `${o.value}` ? "selected" : ""
|
|
87
|
-
} value="${o.value}">${o.label}</option>`
|
|
88
|
-
)
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
e.change(function (ec) {
|
|
93
|
-
e.attr("data-selected", ec.target.value);
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
$("[data-source-url]").each(function (ix, element) {
|
|
97
|
-
const e = $(element);
|
|
98
|
-
const rec = get_form_record(e);
|
|
99
|
-
ajax_post_json(e.attr("data-source-url"), rec, {
|
|
100
|
-
success: (data) => {
|
|
101
|
-
e.html(data);
|
|
102
|
-
},
|
|
103
|
-
error: (err) => {
|
|
104
|
-
console.error(err);
|
|
105
|
-
e.html("");
|
|
106
|
-
},
|
|
107
|
-
});
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
function get_form_record(e, select_labels) {
|
|
111
|
-
const rec = {};
|
|
112
|
-
e.closest("form")
|
|
113
|
-
.find("input[name],select[name]")
|
|
114
|
-
.each(function () {
|
|
115
|
-
if (select_labels && $(this).prop("tagName").toLowerCase() === "select")
|
|
116
|
-
rec[$(this).attr("name")] = $(this).find("option:selected").text();
|
|
117
|
-
else if ($(this).prop("type") === "checkbox")
|
|
118
|
-
rec[$(this).attr("name")] = $(this).prop("checked");
|
|
119
|
-
else rec[$(this).attr("name")] = $(this).val();
|
|
120
|
-
});
|
|
121
|
-
return rec;
|
|
122
|
-
}
|
|
123
|
-
function showIfFormulaInputs(e, fml) {
|
|
124
|
-
const rec = get_form_record(e);
|
|
125
|
-
return new Function(`{${Object.keys(rec).join(",")}}`, "return " + fml)(rec);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function rep_del(e) {
|
|
129
|
-
var myrep = $(e).closest(".form-repeat");
|
|
130
|
-
var ix = myrep.index();
|
|
131
|
-
var parent = myrep.parent();
|
|
132
|
-
parent.children().each(function (childix, element) {
|
|
133
|
-
if (childix > ix) {
|
|
134
|
-
reindex(element, childix, childix - 1);
|
|
135
|
-
}
|
|
136
|
-
});
|
|
137
|
-
myrep.remove();
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
function reindex(element, oldix, newix) {
|
|
141
|
-
$(element).html(
|
|
142
|
-
$(element)
|
|
143
|
-
.html()
|
|
144
|
-
.split("_" + oldix)
|
|
145
|
-
.join("_" + newix)
|
|
146
|
-
);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
function get_form_subset_record(e) {
|
|
150
|
-
const rec = {};
|
|
151
|
-
e.find("input[name],select[name]").each(function () {
|
|
152
|
-
rec[$(this).attr("name")] = $(this).val();
|
|
153
|
-
});
|
|
154
|
-
return rec;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
function apply_form_subset_record(e, vals) {
|
|
158
|
-
e.find("input[name],select[name]").each(function () {
|
|
159
|
-
var name = $(this).attr("name");
|
|
160
|
-
if (vals[name]) $(this).val(vals[name]);
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
function reindex_form_record(vals, oldix, newix) {
|
|
165
|
-
const rec = {};
|
|
166
|
-
Object.keys(vals).forEach((k) => {
|
|
167
|
-
const newkey = k.split("_" + oldix).join("_" + newix);
|
|
168
|
-
rec[newkey] = vals[k];
|
|
169
|
-
});
|
|
170
|
-
return rec;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
function rep_up(e) {
|
|
174
|
-
var myrep = $(e).closest(".form-repeat");
|
|
175
|
-
var theform = $(e).closest("form");
|
|
176
|
-
var ix = myrep.index();
|
|
177
|
-
var parent = myrep.parent();
|
|
178
|
-
if (ix > 0) {
|
|
179
|
-
var swap_with = parent.children(".form-repeat").eq(ix - 1);
|
|
180
|
-
var vals1 = reindex_form_record(get_form_subset_record(myrep), ix, ix - 1);
|
|
181
|
-
var vals2 = reindex_form_record(
|
|
182
|
-
get_form_subset_record(swap_with),
|
|
183
|
-
ix - 1,
|
|
184
|
-
ix
|
|
185
|
-
);
|
|
186
|
-
reindex(myrep, ix, ix - 1);
|
|
187
|
-
reindex(swap_with, ix - 1, ix);
|
|
188
|
-
$(myrep).swapWith(swap_with);
|
|
189
|
-
apply_form_subset_record(theform, vals2);
|
|
190
|
-
apply_form_subset_record(theform, vals1);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
function rep_down(e) {
|
|
195
|
-
var myrep = $(e).closest(".form-repeat");
|
|
196
|
-
var theform = $(e).closest("form");
|
|
197
|
-
var ix = myrep.index();
|
|
198
|
-
var parent = myrep.parent();
|
|
199
|
-
var nchildren = parent.children(".form-repeat").length;
|
|
200
|
-
if (ix < nchildren - 1) {
|
|
201
|
-
var swap_with = parent.children(".form-repeat").eq(ix + 1);
|
|
202
|
-
var vals1 = reindex_form_record(get_form_subset_record(myrep), ix, ix + 1);
|
|
203
|
-
var vals2 = reindex_form_record(
|
|
204
|
-
get_form_subset_record(swap_with),
|
|
205
|
-
ix + 1,
|
|
206
|
-
ix
|
|
207
|
-
);
|
|
208
|
-
reindex(myrep, ix, ix + 1);
|
|
209
|
-
reindex(swap_with, ix + 1, ix);
|
|
210
|
-
$(myrep).swapWith(swap_with);
|
|
211
|
-
apply_form_subset_record(theform, vals2);
|
|
212
|
-
apply_form_subset_record(theform, vals1);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
7
|
|
|
216
|
-
function reload_on_init() {
|
|
217
|
-
localStorage.setItem("reload_on_init", true);
|
|
218
|
-
}
|
|
219
8
|
if (localStorage.getItem("reload_on_init")) {
|
|
220
9
|
localStorage.removeItem("reload_on_init");
|
|
221
10
|
location.reload();
|
|
222
11
|
}
|
|
223
|
-
function initialize_page() {
|
|
224
|
-
$(".blur-on-enter-keypress").bind("keyup", function (e) {
|
|
225
|
-
if (e.keyCode === 13) e.target.blur();
|
|
226
|
-
});
|
|
227
|
-
$("form").change(apply_showif);
|
|
228
|
-
apply_showif();
|
|
229
|
-
apply_showif();
|
|
230
|
-
$("[data-inline-edit-dest-url]").each(function () {
|
|
231
|
-
if ($(this).find(".editicon").length === 0) {
|
|
232
|
-
var current = $(this).html();
|
|
233
|
-
$(this).html(
|
|
234
|
-
`<span class="current">${current}</span><i class="editicon fas fa-edit ms-1"></i>`
|
|
235
|
-
);
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
$("[data-inline-edit-dest-url]").click(function () {
|
|
239
|
-
var url = $(this).attr("data-inline-edit-dest-url");
|
|
240
|
-
var current = $(this).children("span.current").html();
|
|
241
|
-
$(this).replaceWith(
|
|
242
|
-
`<form method="post" action="${url}" >
|
|
243
|
-
<input type="hidden" name="_csrf" value="${_sc_globalCsrf}">
|
|
244
|
-
<input type="text" name="value" value="${current}">
|
|
245
|
-
<button type="submit" class="btn btn-sm btn-primary">OK</button>
|
|
246
|
-
</form>`
|
|
247
|
-
);
|
|
248
|
-
});
|
|
249
|
-
function setExplainer(that) {
|
|
250
|
-
var id = $(that).attr("id") + "_explainer";
|
|
251
|
-
|
|
252
|
-
var explainers = JSON.parse(
|
|
253
|
-
decodeURIComponent($(that).attr("data-explainers"))
|
|
254
|
-
);
|
|
255
|
-
var currentVal = explainers[$(that).val()];
|
|
256
|
-
$("#" + id).html(`<strong>${$(that).val()}</strong>: ${currentVal}`);
|
|
257
|
-
if (currentVal) $("#" + id).show();
|
|
258
|
-
else $("#" + id).hide();
|
|
259
|
-
}
|
|
260
|
-
$("[data-explainers]").each(function () {
|
|
261
|
-
var id = $(this).attr("id") + "_explainer";
|
|
262
|
-
if ($("#" + id).length === 0) {
|
|
263
|
-
$(this).after(`<div class="alert alert-info my-2" id="${id}"></div>`);
|
|
264
|
-
setExplainer(this);
|
|
265
|
-
}
|
|
266
|
-
});
|
|
267
|
-
$("[data-explainers]").change(function () {
|
|
268
|
-
setExplainer(this);
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
const codes = [];
|
|
272
|
-
$("textarea.to-code").each(function () {
|
|
273
|
-
codes.push(this);
|
|
274
|
-
});
|
|
275
|
-
if (codes.length > 0)
|
|
276
|
-
enable_codemirror(() => {
|
|
277
|
-
setTimeout(() => {
|
|
278
|
-
codes.forEach((el) => {
|
|
279
|
-
//console.log($(el).attr("mode"), el);
|
|
280
|
-
CodeMirror.fromTextArea(el, {
|
|
281
|
-
lineNumbers: true,
|
|
282
|
-
mode: $(el).attr("mode"),
|
|
283
|
-
});
|
|
284
|
-
});
|
|
285
|
-
}, 100);
|
|
286
|
-
});
|
|
287
|
-
const locale =
|
|
288
|
-
navigator.userLanguage ||
|
|
289
|
-
(navigator.languages &&
|
|
290
|
-
navigator.languages.length &&
|
|
291
|
-
navigator.languages[0]) ||
|
|
292
|
-
navigator.language ||
|
|
293
|
-
navigator.browserLanguage ||
|
|
294
|
-
navigator.systemLanguage ||
|
|
295
|
-
"en";
|
|
296
|
-
window.detected_locale = locale;
|
|
297
|
-
const parse = (s) => JSON.parse(decodeURIComponent(s));
|
|
298
|
-
$("time[locale-time-options]").each(function () {
|
|
299
|
-
var el = $(this);
|
|
300
|
-
var date = new Date(el.attr("datetime"));
|
|
301
|
-
const options = parse(el.attr("locale-time-options"));
|
|
302
|
-
el.text(date.toLocaleTimeString(locale, options));
|
|
303
|
-
});
|
|
304
|
-
$("time[locale-options]").each(function () {
|
|
305
|
-
var el = $(this);
|
|
306
|
-
var date = new Date(el.attr("datetime"));
|
|
307
|
-
const options = parse(el.attr("locale-options"));
|
|
308
|
-
el.text(date.toLocaleString(locale, options));
|
|
309
|
-
});
|
|
310
|
-
$("time[locale-date-options]").each(function () {
|
|
311
|
-
var el = $(this);
|
|
312
|
-
var date = new Date(el.attr("datetime"));
|
|
313
|
-
const options = parse(el.attr("locale-date-options"));
|
|
314
|
-
el.text(date.toLocaleDateString(locale, options));
|
|
315
|
-
});
|
|
316
|
-
$('a[data-bs-toggle="tab"].deeplink').historyTabs();
|
|
317
|
-
init_bs5_dropdowns();
|
|
318
|
-
|
|
319
|
-
// Initialize Sliders - https://stackoverflow.com/a/31083391
|
|
320
|
-
var sliderSections = document.getElementsByClassName("range-slider");
|
|
321
|
-
for (var x = 0; x < sliderSections.length; x++) {
|
|
322
|
-
var sliders = sliderSections[x].getElementsByTagName("input");
|
|
323
|
-
for (var y = 0; y < sliders.length; y++) {
|
|
324
|
-
if (sliders[y].type === "range") {
|
|
325
|
-
sliders[y].oninput = function () {
|
|
326
|
-
// Get slider values
|
|
327
|
-
var parent = this.parentNode;
|
|
328
|
-
var slides = parent.getElementsByTagName("input");
|
|
329
|
-
var slide1 = parseFloat(slides[0].value);
|
|
330
|
-
var slide2 = parseFloat(slides[1].value);
|
|
331
|
-
// Neither slider will clip the other, so make sure we determine which is larger
|
|
332
|
-
if (slide1 > slide2) {
|
|
333
|
-
var tmp = slide2;
|
|
334
|
-
slide2 = slide1;
|
|
335
|
-
slide1 = tmp;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
var displayElement = parent.getElementsByClassName("rangeValues")[0];
|
|
339
|
-
displayElement.innerHTML = slide1 + " - " + slide2;
|
|
340
|
-
};
|
|
341
|
-
// Manually trigger event first time to display values
|
|
342
|
-
sliders[y].oninput();
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
$(initialize_page);
|
|
349
|
-
|
|
350
|
-
function enable_codemirror(f) {
|
|
351
|
-
$("<link/>", {
|
|
352
|
-
rel: "stylesheet",
|
|
353
|
-
type: "text/css",
|
|
354
|
-
href: `/static_assets/${_sc_version_tag}/codemirror.css`,
|
|
355
|
-
}).appendTo("head");
|
|
356
|
-
$.ajax({
|
|
357
|
-
url: `/static_assets/${_sc_version_tag}/codemirror.min.js`,
|
|
358
|
-
dataType: "script",
|
|
359
|
-
cache: true,
|
|
360
|
-
success: f,
|
|
361
|
-
});
|
|
362
|
-
}
|
|
363
12
|
|
|
364
13
|
//https://stackoverflow.com/a/6021027
|
|
365
14
|
function updateQueryStringParameter(uri1, key, value) {
|
|
@@ -474,23 +123,6 @@ function href_to(href) {
|
|
|
474
123
|
function clear_state() {
|
|
475
124
|
pjax_to(window.location.href.split("?")[0]);
|
|
476
125
|
}
|
|
477
|
-
function tristateClick(nm) {
|
|
478
|
-
var current = $(`button#trib${nm}`).html();
|
|
479
|
-
switch (current) {
|
|
480
|
-
case "?":
|
|
481
|
-
$(`button#trib${nm}`).html("T");
|
|
482
|
-
$(`input#input${nm}`).val("on");
|
|
483
|
-
break;
|
|
484
|
-
case "T":
|
|
485
|
-
$(`button#trib${nm}`).html("F");
|
|
486
|
-
$(`input#input${nm}`).val("off");
|
|
487
|
-
break;
|
|
488
|
-
default:
|
|
489
|
-
$(`button#trib${nm}`).html("?");
|
|
490
|
-
$(`input#input${nm}`).val("?");
|
|
491
|
-
break;
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
126
|
|
|
495
127
|
function ajax_done(res) {
|
|
496
128
|
common_done(res);
|
|
@@ -619,43 +251,17 @@ function applyViewConfig(e, url) {
|
|
|
619
251
|
return false;
|
|
620
252
|
}
|
|
621
253
|
|
|
622
|
-
const repeaterCopyValuesToForm = (form, editor) => {
|
|
623
|
-
const vs = JSON.parse(editor.getString());
|
|
624
|
-
const allNames = new Set([]);
|
|
625
|
-
const setVal = (k, ix, v) => {
|
|
626
|
-
const $e = form.find(`input[name="${k}_${ix}"]`);
|
|
627
|
-
if ($e.length) $e.val(v);
|
|
628
|
-
else
|
|
629
|
-
form.append(
|
|
630
|
-
`<input type="hidden" name="${k}_${ix}" value="${v}"></input>`
|
|
631
|
-
);
|
|
632
|
-
};
|
|
633
|
-
vs.forEach((v, ix) => {
|
|
634
|
-
Object.entries(v).forEach(([k, v]) => {
|
|
635
|
-
//console.log(ix, k, typeof v, v)
|
|
636
|
-
allNames.add(k);
|
|
637
|
-
if (typeof v === "boolean") setVal(k, ix, v ? "on" : "");
|
|
638
|
-
else setVal(k, ix, v);
|
|
639
|
-
});
|
|
640
|
-
});
|
|
641
|
-
//delete
|
|
642
|
-
[...allNames].forEach((k) => {
|
|
643
|
-
for (let ix = vs.length; ix < vs.length + 20; ix++) {
|
|
644
|
-
$(`input[name=${k}_${ix}]`).remove();
|
|
645
|
-
}
|
|
646
|
-
});
|
|
647
|
-
};
|
|
648
|
-
|
|
649
254
|
function ajaxSubmitForm(e) {
|
|
650
255
|
var form = $(e).closest("form");
|
|
651
256
|
var url = form.attr("action");
|
|
652
|
-
var form_data = form.serialize();
|
|
653
257
|
$.ajax(url, {
|
|
654
258
|
type: "POST",
|
|
655
259
|
headers: {
|
|
656
260
|
"CSRF-Token": _sc_globalCsrf,
|
|
657
261
|
},
|
|
658
|
-
data:
|
|
262
|
+
data: new FormData(form[0]),
|
|
263
|
+
processData: false,
|
|
264
|
+
contentType: false,
|
|
659
265
|
success: function () {
|
|
660
266
|
var no_reload = $("#scmodal").hasClass("no-submit-reload");
|
|
661
267
|
$("#scmodal").modal("hide");
|
|
@@ -754,26 +360,6 @@ function test_formula(tablename, stored) {
|
|
|
754
360
|
},
|
|
755
361
|
});
|
|
756
362
|
}
|
|
757
|
-
function align_dropdown(id) {
|
|
758
|
-
setTimeout(() => {
|
|
759
|
-
if ($("#dm" + id).hasClass("show")) {
|
|
760
|
-
var inputWidth = $("#search-input-group-" + id).outerWidth();
|
|
761
|
-
$("#dm" + id).css("width", inputWidth);
|
|
762
|
-
var d0pos = $("#search-input-group-" + id).offset();
|
|
763
|
-
$("#dm" + id).offset({ left: d0pos.left });
|
|
764
|
-
$(document).on("click", "#dm" + id, function (e) {
|
|
765
|
-
e.stopPropagation();
|
|
766
|
-
});
|
|
767
|
-
}
|
|
768
|
-
}, 0);
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
function remove_outline(form) {
|
|
772
|
-
$(form)
|
|
773
|
-
.find("button[type=submit]")
|
|
774
|
-
.removeClass("btn-outline-primary")
|
|
775
|
-
.addClass("btn-primary");
|
|
776
|
-
}
|
|
777
363
|
|
|
778
364
|
function init_room(viewname, room_id) {
|
|
779
365
|
const socket = io({ transports: ["websocket"] });
|
|
@@ -843,25 +429,6 @@ async function fill_formula_btn_click(btn, k) {
|
|
|
843
429
|
if (k) k();
|
|
844
430
|
}
|
|
845
431
|
|
|
846
|
-
const columnSummary = (col) => {
|
|
847
|
-
if (!col) return "Unknown";
|
|
848
|
-
switch (col.type) {
|
|
849
|
-
case "Field":
|
|
850
|
-
return `Field ${col.field_name} ${col.fieldview || ""}`;
|
|
851
|
-
case "Link":
|
|
852
|
-
return `Link ${col.link_text}`;
|
|
853
|
-
case "JoinField":
|
|
854
|
-
return `Join ${col.join_field}`;
|
|
855
|
-
case "ViewLink":
|
|
856
|
-
return `View link ${col.view_label || col.view.split(":")[1] || ""}`;
|
|
857
|
-
case "Action":
|
|
858
|
-
return `Action ${col.action_label || col.action_name}`;
|
|
859
|
-
case "Aggregation":
|
|
860
|
-
return `${col.stat} ${col.agg_field} ${col.agg_relation}`;
|
|
861
|
-
default:
|
|
862
|
-
return "Unknown";
|
|
863
|
-
}
|
|
864
|
-
};
|
|
865
432
|
|
|
866
433
|
/*
|
|
867
434
|
https://github.com/jeffdavidgreen/bootstrap-html5-history-tabs/blob/master/bootstrap-history-tabs.js
|
package/routes/admin.js
CHANGED
|
@@ -23,9 +23,6 @@ const {
|
|
|
23
23
|
div,
|
|
24
24
|
a,
|
|
25
25
|
hr,
|
|
26
|
-
form,
|
|
27
|
-
input,
|
|
28
|
-
label,
|
|
29
26
|
i,
|
|
30
27
|
h4,
|
|
31
28
|
table,
|
|
@@ -33,7 +30,6 @@ const {
|
|
|
33
30
|
td,
|
|
34
31
|
th,
|
|
35
32
|
tr,
|
|
36
|
-
button,
|
|
37
33
|
span,
|
|
38
34
|
p,
|
|
39
35
|
code,
|
|
@@ -45,7 +41,7 @@ const {
|
|
|
45
41
|
getState,
|
|
46
42
|
restart_tenant,
|
|
47
43
|
getTenant,
|
|
48
|
-
get_other_domain_tenant,
|
|
44
|
+
//get_other_domain_tenant,
|
|
49
45
|
get_process_init_time,
|
|
50
46
|
} = require("@saltcorn/data/db/state");
|
|
51
47
|
const { loadAllPlugins } = require("../load_plugins");
|
|
@@ -61,7 +57,7 @@ const load_plugins = require("../load_plugins");
|
|
|
61
57
|
const {
|
|
62
58
|
restore_backup,
|
|
63
59
|
send_admin_page,
|
|
64
|
-
send_files_page,
|
|
60
|
+
//send_files_page,
|
|
65
61
|
config_fields_form,
|
|
66
62
|
save_config_from_form,
|
|
67
63
|
flash_restart_if_required,
|
|
@@ -90,8 +86,9 @@ const router = new Router();
|
|
|
90
86
|
module.exports = router;
|
|
91
87
|
|
|
92
88
|
/**
|
|
93
|
-
*
|
|
94
|
-
* @
|
|
89
|
+
* Site identity form
|
|
90
|
+
* @param {object} req -http request
|
|
91
|
+
* @returns {Promise<Form>} form
|
|
95
92
|
*/
|
|
96
93
|
const site_id_form = (req) =>
|
|
97
94
|
config_fields_form({
|
|
@@ -106,13 +103,15 @@ const site_id_form = (req) =>
|
|
|
106
103
|
"page_custom_html",
|
|
107
104
|
"development_mode",
|
|
108
105
|
"log_sql",
|
|
106
|
+
"plugins_store_endpoint",
|
|
107
|
+
"packs_store_endpoint",
|
|
109
108
|
...(getConfigFile() ? ["multitenancy_enabled"] : []),
|
|
110
109
|
],
|
|
111
110
|
action: "/admin",
|
|
112
111
|
submitLabel: req.__("Save"),
|
|
113
112
|
});
|
|
114
113
|
/**
|
|
115
|
-
* Email settings form
|
|
114
|
+
* Email settings form
|
|
116
115
|
* @param {object} req request
|
|
117
116
|
* @returns {Promise<Form>} form
|
|
118
117
|
*/
|
|
@@ -137,6 +136,7 @@ const email_form = async (req) => {
|
|
|
137
136
|
};
|
|
138
137
|
|
|
139
138
|
/**
|
|
139
|
+
* Router get /
|
|
140
140
|
* @name get
|
|
141
141
|
* @function
|
|
142
142
|
* @memberof module:routes/admin~routes/adminRouter
|
|
@@ -145,7 +145,6 @@ router.get(
|
|
|
145
145
|
"/",
|
|
146
146
|
isAdmin,
|
|
147
147
|
error_catcher(async (req, res) => {
|
|
148
|
-
const isRoot = db.getTenantSchema() === db.connectObj.default_schema;
|
|
149
148
|
const form = await site_id_form(req);
|
|
150
149
|
send_admin_page({
|
|
151
150
|
res,
|
|
@@ -527,6 +526,9 @@ router.post(
|
|
|
527
526
|
}
|
|
528
527
|
})
|
|
529
528
|
);
|
|
529
|
+
/**
|
|
530
|
+
* /check-for-updates
|
|
531
|
+
*/
|
|
530
532
|
router.post(
|
|
531
533
|
"/check-for-upgrade",
|
|
532
534
|
isAdmin,
|
|
@@ -548,8 +550,8 @@ router.post(
|
|
|
548
550
|
const fileName = await create_backup();
|
|
549
551
|
res.type("application/zip");
|
|
550
552
|
res.attachment(fileName);
|
|
551
|
-
|
|
552
|
-
|
|
553
|
+
const file = fs.createReadStream(fileName);
|
|
554
|
+
file.on("end", function () {
|
|
553
555
|
fs.unlink(fileName, function () {});
|
|
554
556
|
});
|
|
555
557
|
file.pipe(res);
|
|
@@ -579,8 +581,9 @@ router.post(
|
|
|
579
581
|
);
|
|
580
582
|
|
|
581
583
|
/**
|
|
584
|
+
* Clear All Form
|
|
582
585
|
* @param {object} req
|
|
583
|
-
* @returns {Form}
|
|
586
|
+
* @returns {Form} form
|
|
584
587
|
*/
|
|
585
588
|
const clearAllForm = (req) =>
|
|
586
589
|
new Form({
|
|
@@ -694,6 +697,7 @@ router.post(
|
|
|
694
697
|
try {
|
|
695
698
|
const file_store = db.connectObj.file_store;
|
|
696
699
|
const admin_users = await User.find({ role_id: 1 }, { orderBy: "id" });
|
|
700
|
+
// greenlock logic
|
|
697
701
|
const Greenlock = require("greenlock");
|
|
698
702
|
const greenlock = Greenlock.create({
|
|
699
703
|
packageRoot: path.resolve(__dirname, ".."),
|
|
@@ -709,6 +713,7 @@ router.post(
|
|
|
709
713
|
subject: domain,
|
|
710
714
|
altnames,
|
|
711
715
|
});
|
|
716
|
+
// letsencrypt
|
|
712
717
|
await getState().setConfig("letsencrypt", true);
|
|
713
718
|
req.flash(
|
|
714
719
|
"success",
|
|
@@ -758,7 +763,9 @@ router.get(
|
|
|
758
763
|
});
|
|
759
764
|
})
|
|
760
765
|
);
|
|
761
|
-
|
|
766
|
+
/**
|
|
767
|
+
* /confiuration-check
|
|
768
|
+
*/
|
|
762
769
|
router.get(
|
|
763
770
|
"/configuration-check",
|
|
764
771
|
isAdmin,
|
|
@@ -863,6 +870,7 @@ router.post(
|
|
|
863
870
|
if (form.values.plugins) {
|
|
864
871
|
const ps = await Plugin.find();
|
|
865
872
|
for (const p of ps) {
|
|
873
|
+
// todo configurable list of mandatory plugins
|
|
866
874
|
if (!["base", "sbadmin2"].includes(p.name)) await p.delete();
|
|
867
875
|
}
|
|
868
876
|
await getState().refresh_plugins();
|
|
@@ -902,6 +910,8 @@ router.post(
|
|
|
902
910
|
req.logout();
|
|
903
911
|
req.session = null;
|
|
904
912
|
}
|
|
913
|
+
// todo make configurable - redirect to create first user
|
|
914
|
+
// redirect to create first user
|
|
905
915
|
res.redirect(`/auth/create_first_user`);
|
|
906
916
|
} else {
|
|
907
917
|
req.flash(
|