@saltcorn/server 0.7.1-beta.3 → 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 +29 -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 +14 -9
- package/public/jquery-menu-editor.min.js +5 -0
- package/public/saltcorn-common.js +544 -0
- package/public/saltcorn.css +70 -0
- package/public/saltcorn.js +40 -456
- 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 +57 -19
- package/routes/homepage.js +35 -7
- package/routes/menu.js +11 -7
- package/routes/plugins.js +4 -4
- package/routes/tables.js +1 -1
- package/routes/tenant.js +13 -10
- package/routes/viewedit.js +55 -1
- package/serve.js +15 -1
- package/tests/admin.test.js +72 -1
- package/tests/clientjs.test.js +1 -0
- package/tests/plugins.test.js +2 -2
- package/tests/view.test.js +1 -1
- 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
|
-
|
|
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
7
|
|
|
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">
|
|
@@ -567,6 +178,10 @@ function ajax_modal(url, opts = {}) {
|
|
|
567
178
|
</div>
|
|
568
179
|
</div>
|
|
569
180
|
</div>`);
|
|
181
|
+
} else if ($("#scmodal").hasClass("show")) {
|
|
182
|
+
var myModalEl = document.getElementById("scmodal");
|
|
183
|
+
var modal = bootstrap.Modal.getInstance(myModalEl);
|
|
184
|
+
modal.dispose();
|
|
570
185
|
}
|
|
571
186
|
if (opts.submitReload === false) $("#scmodal").addClass("no-submit-reload");
|
|
572
187
|
else $("#scmodal").removeClass("no-submit-reload");
|
|
@@ -587,6 +202,7 @@ function ajax_modal(url, opts = {}) {
|
|
|
587
202
|
|
|
588
203
|
function saveAndContinue(e, k) {
|
|
589
204
|
var form = $(e).closest("form");
|
|
205
|
+
submitWithEmptyAction(form[0]);
|
|
590
206
|
var url = form.attr("action");
|
|
591
207
|
var form_data = form.serialize();
|
|
592
208
|
$.ajax(url, {
|
|
@@ -614,16 +230,38 @@ function saveAndContinue(e, k) {
|
|
|
614
230
|
return false;
|
|
615
231
|
}
|
|
616
232
|
|
|
233
|
+
function applyViewConfig(e, url) {
|
|
234
|
+
var form = $(e).closest("form");
|
|
235
|
+
var form_data = form.serializeArray();
|
|
236
|
+
const cfg = {};
|
|
237
|
+
form_data.forEach((item) => {
|
|
238
|
+
cfg[item.name] = item.value;
|
|
239
|
+
});
|
|
240
|
+
$.ajax(url, {
|
|
241
|
+
type: "POST",
|
|
242
|
+
dataType: "json",
|
|
243
|
+
contentType: "application/json",
|
|
244
|
+
headers: {
|
|
245
|
+
"CSRF-Token": _sc_globalCsrf,
|
|
246
|
+
},
|
|
247
|
+
data: JSON.stringify(cfg),
|
|
248
|
+
error: function (request) {},
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
|
|
617
254
|
function ajaxSubmitForm(e) {
|
|
618
255
|
var form = $(e).closest("form");
|
|
619
256
|
var url = form.attr("action");
|
|
620
|
-
var form_data = form.serialize();
|
|
621
257
|
$.ajax(url, {
|
|
622
258
|
type: "POST",
|
|
623
259
|
headers: {
|
|
624
260
|
"CSRF-Token": _sc_globalCsrf,
|
|
625
261
|
},
|
|
626
|
-
data:
|
|
262
|
+
data: new FormData(form[0]),
|
|
263
|
+
processData: false,
|
|
264
|
+
contentType: false,
|
|
627
265
|
success: function () {
|
|
628
266
|
var no_reload = $("#scmodal").hasClass("no-submit-reload");
|
|
629
267
|
$("#scmodal").modal("hide");
|
|
@@ -698,31 +336,16 @@ function make_unique_field(
|
|
|
698
336
|
type: "GET",
|
|
699
337
|
success: function (res) {
|
|
700
338
|
if (res.success) {
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
break;
|
|
712
|
-
}
|
|
713
|
-
};
|
|
714
|
-
const vals = res.success
|
|
715
|
-
.map((o) => o[field_name])
|
|
716
|
-
.filter((s) => s.startsWith(value));
|
|
717
|
-
if (vals.includes(value) || always_append) {
|
|
718
|
-
for (let i = start || 0; i < vals.length + (start || 0) + 2; i++) {
|
|
719
|
-
const newname = `${value}${space ? " " : ""}${gen_char(i)}`;
|
|
720
|
-
if (!vals.includes(newname)) {
|
|
721
|
-
$("#" + id).val(newname);
|
|
722
|
-
return;
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
}
|
|
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
|
+
);
|
|
726
349
|
}
|
|
727
350
|
},
|
|
728
351
|
}
|
|
@@ -737,26 +360,6 @@ function test_formula(tablename, stored) {
|
|
|
737
360
|
},
|
|
738
361
|
});
|
|
739
362
|
}
|
|
740
|
-
function align_dropdown(id) {
|
|
741
|
-
setTimeout(() => {
|
|
742
|
-
if ($("#dm" + id).hasClass("show")) {
|
|
743
|
-
var inputWidth = $("#search-input-group-" + id).outerWidth();
|
|
744
|
-
$("#dm" + id).css("width", inputWidth);
|
|
745
|
-
var d0pos = $("#search-input-group-" + id).offset();
|
|
746
|
-
$("#dm" + id).offset({ left: d0pos.left });
|
|
747
|
-
$(document).on("click", "#dm" + id, function (e) {
|
|
748
|
-
e.stopPropagation();
|
|
749
|
-
});
|
|
750
|
-
}
|
|
751
|
-
}, 0);
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
function remove_outline(form) {
|
|
755
|
-
$(form)
|
|
756
|
-
.find("button[type=submit]")
|
|
757
|
-
.removeClass("btn-outline-primary")
|
|
758
|
-
.addClass("btn-primary");
|
|
759
|
-
}
|
|
760
363
|
|
|
761
364
|
function init_room(viewname, room_id) {
|
|
762
365
|
const socket = io({ transports: ["websocket"] });
|
|
@@ -826,25 +429,6 @@ async function fill_formula_btn_click(btn, k) {
|
|
|
826
429
|
if (k) k();
|
|
827
430
|
}
|
|
828
431
|
|
|
829
|
-
const columnSummary = (col) => {
|
|
830
|
-
if (!col) return "Unknown";
|
|
831
|
-
switch (col.type) {
|
|
832
|
-
case "Field":
|
|
833
|
-
return `Field ${col.field_name} ${col.fieldview}`;
|
|
834
|
-
case "Link":
|
|
835
|
-
return `Link ${col.link_text}`;
|
|
836
|
-
case "JoinField":
|
|
837
|
-
return `Join ${col.join_field}`;
|
|
838
|
-
case "ViewLink":
|
|
839
|
-
return `View ${col.view_label || col.view.split(":")[1] || ""}`;
|
|
840
|
-
case "Action":
|
|
841
|
-
return `Action ${col.action_label || col.action_name}`;
|
|
842
|
-
case "Aggregation":
|
|
843
|
-
return `${col.stat} ${col.agg_field} ${col.agg_relation}`;
|
|
844
|
-
default:
|
|
845
|
-
return "Unknown";
|
|
846
|
-
}
|
|
847
|
-
};
|
|
848
432
|
|
|
849
433
|
/*
|
|
850
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/,
|