@saltcorn/server 0.7.2-beta.0 → 0.7.2-beta.10
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 +64 -9
- package/auth/routes.js +37 -13
- package/load_plugins.js +39 -27
- package/locales/da.json +1 -1
- package/locales/de.json +155 -155
- package/locales/en.json +25 -4
- package/locales/it.json +3 -2
- package/locales/ru.json +73 -28
- package/locales/zh.json +3 -3
- package/markup/admin.js +25 -9
- package/package.json +11 -8
- package/public/saltcorn-common.js +544 -0
- package/public/saltcorn.css +61 -0
- package/public/saltcorn.js +15 -476
- package/restart_watcher.js +1 -1
- package/routes/admin.js +159 -38
- package/routes/api.js +36 -1
- package/routes/edit.js +2 -1
- package/routes/eventlog.js +30 -30
- package/routes/fields.js +18 -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 +10 -1
- package/serve.js +15 -1
- package/tests/admin.test.js +72 -1
- package/tests/clientjs.test.js +1 -0
- package/tests/viewedit.test.js +94 -0
- package/wrapper.js +56 -12
package/public/saltcorn.js
CHANGED
|
@@ -1,332 +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
7
|
|
|
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 (!(o && o.label && o.value)) {
|
|
77
|
-
if (`${current}` === `${o}`)
|
|
78
|
-
e.append($("<option selected>" + o + "</option>"));
|
|
79
|
-
else e.append($("<option>" + o + "</option>"));
|
|
80
|
-
} else {
|
|
81
|
-
e.append(
|
|
82
|
-
$(
|
|
83
|
-
`<option ${
|
|
84
|
-
`${current}` === `${o.value}` ? "selected" : ""
|
|
85
|
-
} value="${o.value}">${o.label}</option>`
|
|
86
|
-
)
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
e.change(function (ec) {
|
|
91
|
-
e.attr("data-selected", ec.target.value);
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
$("[data-source-url]").each(function (ix, element) {
|
|
95
|
-
const e = $(element);
|
|
96
|
-
const rec = get_form_record(e);
|
|
97
|
-
ajax_post_json(e.attr("data-source-url"), rec, {
|
|
98
|
-
success: (data) => {
|
|
99
|
-
e.html(data);
|
|
100
|
-
},
|
|
101
|
-
error: (err) => {
|
|
102
|
-
console.error(err);
|
|
103
|
-
e.html("");
|
|
104
|
-
},
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
function get_form_record(e, select_labels) {
|
|
109
|
-
const rec = {};
|
|
110
|
-
e.closest("form")
|
|
111
|
-
.find("input[name],select[name]")
|
|
112
|
-
.each(function () {
|
|
113
|
-
if (select_labels && $(this).prop("tagName").toLowerCase() === "select")
|
|
114
|
-
rec[$(this).attr("name")] = $(this).find("option:selected").text();
|
|
115
|
-
else if ($(this).prop("type") === "checkbox")
|
|
116
|
-
rec[$(this).attr("name")] = $(this).prop("checked");
|
|
117
|
-
else rec[$(this).attr("name")] = $(this).val();
|
|
118
|
-
});
|
|
119
|
-
return rec;
|
|
120
|
-
}
|
|
121
|
-
function showIfFormulaInputs(e, fml) {
|
|
122
|
-
const rec = get_form_record(e);
|
|
123
|
-
return new Function(`{${Object.keys(rec).join(",")}}`, "return " + fml)(rec);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function rep_del(e) {
|
|
127
|
-
var myrep = $(e).closest(".form-repeat");
|
|
128
|
-
var ix = myrep.index();
|
|
129
|
-
var parent = myrep.parent();
|
|
130
|
-
parent.children().each(function (childix, element) {
|
|
131
|
-
if (childix > ix) {
|
|
132
|
-
reindex(element, childix, childix - 1);
|
|
133
|
-
}
|
|
134
|
-
});
|
|
135
|
-
myrep.remove();
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
function reindex(element, oldix, newix) {
|
|
139
|
-
$(element).html(
|
|
140
|
-
$(element)
|
|
141
|
-
.html()
|
|
142
|
-
.split("_" + oldix)
|
|
143
|
-
.join("_" + newix)
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function get_form_subset_record(e) {
|
|
148
|
-
const rec = {};
|
|
149
|
-
e.find("input[name],select[name]").each(function () {
|
|
150
|
-
rec[$(this).attr("name")] = $(this).val();
|
|
151
|
-
});
|
|
152
|
-
return rec;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
function apply_form_subset_record(e, vals) {
|
|
156
|
-
e.find("input[name],select[name]").each(function () {
|
|
157
|
-
var name = $(this).attr("name");
|
|
158
|
-
if (vals[name]) $(this).val(vals[name]);
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
function reindex_form_record(vals, oldix, newix) {
|
|
163
|
-
const rec = {};
|
|
164
|
-
Object.keys(vals).forEach((k) => {
|
|
165
|
-
const newkey = k.split("_" + oldix).join("_" + newix);
|
|
166
|
-
rec[newkey] = vals[k];
|
|
167
|
-
});
|
|
168
|
-
return rec;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
function rep_up(e) {
|
|
172
|
-
var myrep = $(e).closest(".form-repeat");
|
|
173
|
-
var theform = $(e).closest("form");
|
|
174
|
-
var ix = myrep.index();
|
|
175
|
-
var parent = myrep.parent();
|
|
176
|
-
if (ix > 0) {
|
|
177
|
-
var swap_with = parent.children(".form-repeat").eq(ix - 1);
|
|
178
|
-
var vals1 = reindex_form_record(get_form_subset_record(myrep), ix, ix - 1);
|
|
179
|
-
var vals2 = reindex_form_record(
|
|
180
|
-
get_form_subset_record(swap_with),
|
|
181
|
-
ix - 1,
|
|
182
|
-
ix
|
|
183
|
-
);
|
|
184
|
-
reindex(myrep, ix, ix - 1);
|
|
185
|
-
reindex(swap_with, ix - 1, ix);
|
|
186
|
-
$(myrep).swapWith(swap_with);
|
|
187
|
-
apply_form_subset_record(theform, vals2);
|
|
188
|
-
apply_form_subset_record(theform, vals1);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
function rep_down(e) {
|
|
193
|
-
var myrep = $(e).closest(".form-repeat");
|
|
194
|
-
var theform = $(e).closest("form");
|
|
195
|
-
var ix = myrep.index();
|
|
196
|
-
var parent = myrep.parent();
|
|
197
|
-
var nchildren = parent.children(".form-repeat").length;
|
|
198
|
-
if (ix < nchildren - 1) {
|
|
199
|
-
var swap_with = parent.children(".form-repeat").eq(ix + 1);
|
|
200
|
-
var vals1 = reindex_form_record(get_form_subset_record(myrep), ix, ix + 1);
|
|
201
|
-
var vals2 = reindex_form_record(
|
|
202
|
-
get_form_subset_record(swap_with),
|
|
203
|
-
ix + 1,
|
|
204
|
-
ix
|
|
205
|
-
);
|
|
206
|
-
reindex(myrep, ix, ix + 1);
|
|
207
|
-
reindex(swap_with, ix + 1, ix);
|
|
208
|
-
$(myrep).swapWith(swap_with);
|
|
209
|
-
apply_form_subset_record(theform, vals2);
|
|
210
|
-
apply_form_subset_record(theform, vals1);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
function reload_on_init() {
|
|
215
|
-
localStorage.setItem("reload_on_init", true);
|
|
216
|
-
}
|
|
217
8
|
if (localStorage.getItem("reload_on_init")) {
|
|
218
9
|
localStorage.removeItem("reload_on_init");
|
|
219
10
|
location.reload();
|
|
220
11
|
}
|
|
221
|
-
function initialize_page() {
|
|
222
|
-
$("form").change(apply_showif);
|
|
223
|
-
apply_showif();
|
|
224
|
-
apply_showif();
|
|
225
|
-
$("[data-inline-edit-dest-url]").each(function () {
|
|
226
|
-
if ($(this).find(".editicon").length === 0) {
|
|
227
|
-
var current = $(this).html();
|
|
228
|
-
$(this).html(
|
|
229
|
-
`<span class="current">${current}</span><i class="editicon fas fa-edit ms-1"></i>`
|
|
230
|
-
);
|
|
231
|
-
}
|
|
232
|
-
});
|
|
233
|
-
$("[data-inline-edit-dest-url]").click(function () {
|
|
234
|
-
var url = $(this).attr("data-inline-edit-dest-url");
|
|
235
|
-
var current = $(this).children("span.current").html();
|
|
236
|
-
$(this).replaceWith(
|
|
237
|
-
`<form method="post" action="${url}" >
|
|
238
|
-
<input type="hidden" name="_csrf" value="${_sc_globalCsrf}">
|
|
239
|
-
<input type="text" name="value" value="${current}">
|
|
240
|
-
<button type="submit" class="btn btn-sm btn-primary">OK</button>
|
|
241
|
-
</form>`
|
|
242
|
-
);
|
|
243
|
-
});
|
|
244
|
-
function setExplainer(that) {
|
|
245
|
-
var id = $(that).attr("id") + "_explainer";
|
|
246
|
-
|
|
247
|
-
var explainers = JSON.parse(
|
|
248
|
-
decodeURIComponent($(that).attr("data-explainers"))
|
|
249
|
-
);
|
|
250
|
-
var currentVal = explainers[$(that).val()];
|
|
251
|
-
$("#" + id).html(`<strong>${$(that).val()}</strong>: ${currentVal}`);
|
|
252
|
-
if (currentVal) $("#" + id).show();
|
|
253
|
-
else $("#" + id).hide();
|
|
254
|
-
}
|
|
255
|
-
$("[data-explainers]").each(function () {
|
|
256
|
-
var id = $(this).attr("id") + "_explainer";
|
|
257
|
-
if ($("#" + id).length === 0) {
|
|
258
|
-
$(this).after(`<div class="alert alert-info my-2" id="${id}"></div>`);
|
|
259
|
-
setExplainer(this);
|
|
260
|
-
}
|
|
261
|
-
});
|
|
262
|
-
$("[data-explainers]").change(function () {
|
|
263
|
-
setExplainer(this);
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
const codes = [];
|
|
267
|
-
$("textarea.to-code").each(function () {
|
|
268
|
-
codes.push(this);
|
|
269
|
-
});
|
|
270
|
-
if (codes.length > 0)
|
|
271
|
-
enable_codemirror(() => {
|
|
272
|
-
setTimeout(() => {
|
|
273
|
-
codes.forEach((el) => {
|
|
274
|
-
//console.log($(el).attr("mode"), el);
|
|
275
|
-
CodeMirror.fromTextArea(el, {
|
|
276
|
-
lineNumbers: true,
|
|
277
|
-
mode: $(el).attr("mode"),
|
|
278
|
-
});
|
|
279
|
-
});
|
|
280
|
-
}, 100);
|
|
281
|
-
});
|
|
282
|
-
const locale =
|
|
283
|
-
navigator.userLanguage ||
|
|
284
|
-
(navigator.languages &&
|
|
285
|
-
navigator.languages.length &&
|
|
286
|
-
navigator.languages[0]) ||
|
|
287
|
-
navigator.language ||
|
|
288
|
-
navigator.browserLanguage ||
|
|
289
|
-
navigator.systemLanguage ||
|
|
290
|
-
"en";
|
|
291
|
-
window.detected_locale = locale;
|
|
292
|
-
const parse = (s) => JSON.parse(decodeURIComponent(s));
|
|
293
|
-
$("time[locale-time-options]").each(function () {
|
|
294
|
-
var el = $(this);
|
|
295
|
-
var date = new Date(el.attr("datetime"));
|
|
296
|
-
const options = parse(el.attr("locale-time-options"));
|
|
297
|
-
el.text(date.toLocaleTimeString(locale, options));
|
|
298
|
-
});
|
|
299
|
-
$("time[locale-options]").each(function () {
|
|
300
|
-
var el = $(this);
|
|
301
|
-
var date = new Date(el.attr("datetime"));
|
|
302
|
-
const options = parse(el.attr("locale-options"));
|
|
303
|
-
el.text(date.toLocaleString(locale, options));
|
|
304
|
-
});
|
|
305
|
-
$("time[locale-date-options]").each(function () {
|
|
306
|
-
var el = $(this);
|
|
307
|
-
var date = new Date(el.attr("datetime"));
|
|
308
|
-
const options = parse(el.attr("locale-date-options"));
|
|
309
|
-
el.text(date.toLocaleDateString(locale, options));
|
|
310
|
-
});
|
|
311
|
-
$('a[data-bs-toggle="tab"].deeplink').historyTabs();
|
|
312
|
-
init_bs5_dropdowns();
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
$(initialize_page);
|
|
316
|
-
|
|
317
|
-
function enable_codemirror(f) {
|
|
318
|
-
$("<link/>", {
|
|
319
|
-
rel: "stylesheet",
|
|
320
|
-
type: "text/css",
|
|
321
|
-
href: `/static_assets/${_sc_version_tag}/codemirror.css`,
|
|
322
|
-
}).appendTo("head");
|
|
323
|
-
$.ajax({
|
|
324
|
-
url: `/static_assets/${_sc_version_tag}/codemirror.min.js`,
|
|
325
|
-
dataType: "script",
|
|
326
|
-
cache: true,
|
|
327
|
-
success: f,
|
|
328
|
-
});
|
|
329
|
-
}
|
|
330
12
|
|
|
331
13
|
//https://stackoverflow.com/a/6021027
|
|
332
14
|
function updateQueryStringParameter(uri1, key, value) {
|
|
@@ -441,75 +123,9 @@ function href_to(href) {
|
|
|
441
123
|
function clear_state() {
|
|
442
124
|
pjax_to(window.location.href.split("?")[0]);
|
|
443
125
|
}
|
|
444
|
-
function tristateClick(nm) {
|
|
445
|
-
var current = $(`button#trib${nm}`).html();
|
|
446
|
-
switch (current) {
|
|
447
|
-
case "?":
|
|
448
|
-
$(`button#trib${nm}`).html("T");
|
|
449
|
-
$(`input#input${nm}`).val("on");
|
|
450
|
-
break;
|
|
451
|
-
case "T":
|
|
452
|
-
$(`button#trib${nm}`).html("F");
|
|
453
|
-
$(`input#input${nm}`).val("off");
|
|
454
|
-
break;
|
|
455
|
-
default:
|
|
456
|
-
$(`button#trib${nm}`).html("?");
|
|
457
|
-
$(`input#input${nm}`).val("?");
|
|
458
|
-
break;
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
function notifyAlert(note, spin) {
|
|
463
|
-
if (Array.isArray(note)) {
|
|
464
|
-
note.forEach(notifyAlert);
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
467
|
-
var txt, type;
|
|
468
|
-
if (typeof note == "string") {
|
|
469
|
-
txt = note;
|
|
470
|
-
type = "info";
|
|
471
|
-
} else {
|
|
472
|
-
txt = note.text;
|
|
473
|
-
type = note.type;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
$("#alerts-area")
|
|
477
|
-
.append(`<div class="alert alert-${type} alert-dismissible fade show ${
|
|
478
|
-
spin ? "d-flex align-items-center" : ""
|
|
479
|
-
}" role="alert">
|
|
480
|
-
${txt}
|
|
481
|
-
${
|
|
482
|
-
spin
|
|
483
|
-
? `<div class="spinner-border ms-auto" role="status" aria-hidden="true"></div>`
|
|
484
|
-
: `<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close">
|
|
485
|
-
</button>`
|
|
486
|
-
}
|
|
487
|
-
</div>`);
|
|
488
|
-
}
|
|
489
126
|
|
|
490
127
|
function ajax_done(res) {
|
|
491
|
-
|
|
492
|
-
if (res.error) notifyAlert({ type: "danger", text: res.error });
|
|
493
|
-
if (res.eval_js) eval(res.eval_js);
|
|
494
|
-
if (res.reload_page) location.reload(); //TODO notify to cookie if reload or goto
|
|
495
|
-
if (res.download) {
|
|
496
|
-
const dataurl = `data:${
|
|
497
|
-
res.download.mimetype || "application/octet-stream"
|
|
498
|
-
};base64,${res.download.blob}`;
|
|
499
|
-
fetch(dataurl)
|
|
500
|
-
.then((res) => res.blob())
|
|
501
|
-
.then((blob) => {
|
|
502
|
-
const link = document.createElement("a");
|
|
503
|
-
link.href = window.URL.createObjectURL(blob);
|
|
504
|
-
if (res.download.filename) link.download = res.download.filename;
|
|
505
|
-
else link.target = "_blank";
|
|
506
|
-
link.click();
|
|
507
|
-
});
|
|
508
|
-
}
|
|
509
|
-
if (res.goto) {
|
|
510
|
-
if (res.target === "_blank") window.open(res.goto, "_blank").focus();
|
|
511
|
-
else window.location.href = res.goto;
|
|
512
|
-
}
|
|
128
|
+
common_done(res);
|
|
513
129
|
}
|
|
514
130
|
|
|
515
131
|
function view_post(viewname, route, data, onDone) {
|
|
@@ -546,11 +162,6 @@ function globalErrorCatcher(message, source, lineno, colno, error) {
|
|
|
546
162
|
});
|
|
547
163
|
}
|
|
548
164
|
|
|
549
|
-
function press_store_button(clicked) {
|
|
550
|
-
const width = $(clicked).width();
|
|
551
|
-
$(clicked).html('<i class="fas fa-spinner fa-spin"></i>').width(width);
|
|
552
|
-
}
|
|
553
|
-
|
|
554
165
|
function ajax_modal(url, opts = {}) {
|
|
555
166
|
if ($("#scmodal").length === 0) {
|
|
556
167
|
$("body").append(`<div id="scmodal", class="modal">
|
|
@@ -591,6 +202,7 @@ function ajax_modal(url, opts = {}) {
|
|
|
591
202
|
|
|
592
203
|
function saveAndContinue(e, k) {
|
|
593
204
|
var form = $(e).closest("form");
|
|
205
|
+
submitWithEmptyAction(form[0]);
|
|
594
206
|
var url = form.attr("action");
|
|
595
207
|
var form_data = form.serialize();
|
|
596
208
|
$.ajax(url, {
|
|
@@ -639,36 +251,17 @@ function applyViewConfig(e, url) {
|
|
|
639
251
|
return false;
|
|
640
252
|
}
|
|
641
253
|
|
|
642
|
-
const repeaterCopyValuesToForm = (form, editor) => {
|
|
643
|
-
const vs = JSON.parse(editor.getString());
|
|
644
|
-
//console.log(vs)
|
|
645
|
-
const setVal = (k, ix, v) => {
|
|
646
|
-
const $e = form.find(`input[name="${k}_${ix}"]`);
|
|
647
|
-
if ($e.length) $e.val(v);
|
|
648
|
-
else
|
|
649
|
-
form.append(
|
|
650
|
-
`<input type="hidden" name="${k}_${ix}" value="${v}"></input>`
|
|
651
|
-
);
|
|
652
|
-
};
|
|
653
|
-
vs.forEach((v, ix) => {
|
|
654
|
-
Object.entries(v).forEach(([k, v]) => {
|
|
655
|
-
//console.log(ix, k, typeof v, v)
|
|
656
|
-
if (typeof v === "boolean") setVal(k, ix, v ? "on" : "");
|
|
657
|
-
else setVal(k, ix, v);
|
|
658
|
-
});
|
|
659
|
-
});
|
|
660
|
-
};
|
|
661
|
-
|
|
662
254
|
function ajaxSubmitForm(e) {
|
|
663
255
|
var form = $(e).closest("form");
|
|
664
256
|
var url = form.attr("action");
|
|
665
|
-
var form_data = form.serialize();
|
|
666
257
|
$.ajax(url, {
|
|
667
258
|
type: "POST",
|
|
668
259
|
headers: {
|
|
669
260
|
"CSRF-Token": _sc_globalCsrf,
|
|
670
261
|
},
|
|
671
|
-
data:
|
|
262
|
+
data: new FormData(form[0]),
|
|
263
|
+
processData: false,
|
|
264
|
+
contentType: false,
|
|
672
265
|
success: function () {
|
|
673
266
|
var no_reload = $("#scmodal").hasClass("no-submit-reload");
|
|
674
267
|
$("#scmodal").modal("hide");
|
|
@@ -743,31 +336,16 @@ function make_unique_field(
|
|
|
743
336
|
type: "GET",
|
|
744
337
|
success: function (res) {
|
|
745
338
|
if (res.success) {
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
break;
|
|
757
|
-
}
|
|
758
|
-
};
|
|
759
|
-
const vals = res.success
|
|
760
|
-
.map((o) => o[field_name])
|
|
761
|
-
.filter((s) => s.startsWith(value));
|
|
762
|
-
if (vals.includes(value) || always_append) {
|
|
763
|
-
for (let i = start || 0; i < vals.length + (start || 0) + 2; i++) {
|
|
764
|
-
const newname = `${value}${space ? " " : ""}${gen_char(i)}`;
|
|
765
|
-
if (!vals.includes(newname)) {
|
|
766
|
-
$("#" + id).val(newname);
|
|
767
|
-
return;
|
|
768
|
-
}
|
|
769
|
-
}
|
|
770
|
-
}
|
|
339
|
+
unique_field_from_rows(
|
|
340
|
+
res.success,
|
|
341
|
+
id,
|
|
342
|
+
field_name,
|
|
343
|
+
space,
|
|
344
|
+
start,
|
|
345
|
+
always_append,
|
|
346
|
+
char_type,
|
|
347
|
+
value
|
|
348
|
+
);
|
|
771
349
|
}
|
|
772
350
|
},
|
|
773
351
|
}
|
|
@@ -782,26 +360,6 @@ function test_formula(tablename, stored) {
|
|
|
782
360
|
},
|
|
783
361
|
});
|
|
784
362
|
}
|
|
785
|
-
function align_dropdown(id) {
|
|
786
|
-
setTimeout(() => {
|
|
787
|
-
if ($("#dm" + id).hasClass("show")) {
|
|
788
|
-
var inputWidth = $("#search-input-group-" + id).outerWidth();
|
|
789
|
-
$("#dm" + id).css("width", inputWidth);
|
|
790
|
-
var d0pos = $("#search-input-group-" + id).offset();
|
|
791
|
-
$("#dm" + id).offset({ left: d0pos.left });
|
|
792
|
-
$(document).on("click", "#dm" + id, function (e) {
|
|
793
|
-
e.stopPropagation();
|
|
794
|
-
});
|
|
795
|
-
}
|
|
796
|
-
}, 0);
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
function remove_outline(form) {
|
|
800
|
-
$(form)
|
|
801
|
-
.find("button[type=submit]")
|
|
802
|
-
.removeClass("btn-outline-primary")
|
|
803
|
-
.addClass("btn-primary");
|
|
804
|
-
}
|
|
805
363
|
|
|
806
364
|
function init_room(viewname, room_id) {
|
|
807
365
|
const socket = io({ transports: ["websocket"] });
|
|
@@ -871,25 +429,6 @@ async function fill_formula_btn_click(btn, k) {
|
|
|
871
429
|
if (k) k();
|
|
872
430
|
}
|
|
873
431
|
|
|
874
|
-
const columnSummary = (col) => {
|
|
875
|
-
if (!col) return "Unknown";
|
|
876
|
-
switch (col.type) {
|
|
877
|
-
case "Field":
|
|
878
|
-
return `Field ${col.field_name} ${col.fieldview || ""}`;
|
|
879
|
-
case "Link":
|
|
880
|
-
return `Link ${col.link_text}`;
|
|
881
|
-
case "JoinField":
|
|
882
|
-
return `Join ${col.join_field}`;
|
|
883
|
-
case "ViewLink":
|
|
884
|
-
return `View link ${col.view_label || col.view.split(":")[1] || ""}`;
|
|
885
|
-
case "Action":
|
|
886
|
-
return `Action ${col.action_label || col.action_name}`;
|
|
887
|
-
case "Aggregation":
|
|
888
|
-
return `${col.stat} ${col.agg_field} ${col.agg_relation}`;
|
|
889
|
-
default:
|
|
890
|
-
return "Unknown";
|
|
891
|
-
}
|
|
892
|
-
};
|
|
893
432
|
|
|
894
433
|
/*
|
|
895
434
|
https://github.com/jeffdavidgreen/bootstrap-html5-history-tabs/blob/master/bootstrap-history-tabs.js
|
package/restart_watcher.js
CHANGED
|
@@ -17,6 +17,7 @@ const relevantPackages = [
|
|
|
17
17
|
"db-common",
|
|
18
18
|
"postgres",
|
|
19
19
|
"saltcorn-data",
|
|
20
|
+
"saltcorn-admin-models",
|
|
20
21
|
"saltcorn-markup",
|
|
21
22
|
"saltcorn-sbadmin2",
|
|
22
23
|
"server",
|
|
@@ -28,7 +29,6 @@ const relevantPackages = [
|
|
|
28
29
|
*/
|
|
29
30
|
const excludePatterns = [
|
|
30
31
|
/\/node_modules/,
|
|
31
|
-
/\/public/,
|
|
32
32
|
/\.git/,
|
|
33
33
|
/\.docs/,
|
|
34
34
|
/\.docs/,
|