@saltcorn/server 0.7.4-beta.3 → 0.8.0-beta.0
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 +43 -22
- package/auth/admin.js +173 -74
- package/auth/routes.js +67 -28
- package/locales/en.json +54 -2
- package/locales/es.json +134 -134
- package/locales/ru.json +32 -5
- package/markup/admin.js +40 -38
- package/markup/forms.js +4 -3
- package/package.json +8 -7
- package/public/diagram_utils.js +530 -0
- package/public/gridedit.js +4 -1
- package/public/jquery-menu-editor.min.js +112 -112
- package/public/saltcorn-common.js +114 -26
- package/public/saltcorn.css +27 -10
- package/public/saltcorn.js +223 -76
- package/restart_watcher.js +1 -0
- package/routes/actions.js +20 -6
- package/routes/admin.js +243 -82
- package/routes/api.js +19 -2
- package/routes/common_lists.js +137 -134
- package/routes/diagram.js +362 -35
- package/routes/fields.js +4 -1
- package/routes/files.js +137 -101
- package/routes/homepage.js +2 -2
- package/routes/infoarch.js +2 -2
- package/routes/list.js +4 -4
- package/routes/page.js +16 -3
- package/routes/pageedit.js +22 -14
- package/routes/scapi.js +1 -1
- package/routes/search.js +1 -1
- package/routes/tables.js +4 -5
- package/routes/tag_entries.js +31 -10
- package/routes/tags.js +36 -32
- package/routes/tenant.js +98 -36
- package/routes/utils.js +72 -20
- package/routes/view.js +0 -1
- package/routes/viewedit.js +55 -22
- package/serve.js +5 -0
- package/tests/admin.test.js +2 -0
- package/tests/auth.test.js +20 -0
- package/tests/files.test.js +11 -20
- package/tests/tenant.test.js +4 -2
package/public/saltcorn.css
CHANGED
|
@@ -299,7 +299,9 @@ section.range-slider input[type="range"]::-moz-focus-outer {
|
|
|
299
299
|
padding: 0.1rem 0.4rem !important;
|
|
300
300
|
}
|
|
301
301
|
|
|
302
|
-
table.table-inner-grid,
|
|
302
|
+
table.table-inner-grid,
|
|
303
|
+
table.table-inner-grid th,
|
|
304
|
+
table.table-inner-grid td {
|
|
303
305
|
border: 1px solid black;
|
|
304
306
|
border-collapse: collapse;
|
|
305
307
|
}
|
|
@@ -307,18 +309,18 @@ table.table-inner-grid, table.table-inner-grid th, table.table-inner-grid td {
|
|
|
307
309
|
/* https://codepen.io/pezmotion/pen/RQERdm */
|
|
308
310
|
|
|
309
311
|
.editStarRating {
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
312
|
+
direction: rtl;
|
|
313
|
+
unicode-bidi: bidi-override;
|
|
314
|
+
color: #ddd;
|
|
313
315
|
}
|
|
314
316
|
.editStarRating input {
|
|
315
|
-
|
|
317
|
+
display: none;
|
|
316
318
|
}
|
|
317
319
|
.editStarRating label:hover,
|
|
318
320
|
.editStarRating label:hover ~ label,
|
|
319
321
|
.editStarRating input:checked + label,
|
|
320
322
|
.editStarRating input:checked + label ~ label {
|
|
321
|
-
|
|
323
|
+
color: #ffc107;
|
|
322
324
|
}
|
|
323
325
|
|
|
324
326
|
.CodeMirror {
|
|
@@ -326,12 +328,12 @@ table.table-inner-grid, table.table-inner-grid th, table.table-inner-grid td {
|
|
|
326
328
|
}
|
|
327
329
|
|
|
328
330
|
/* copied from bootstrap and adjusted to show the arrow on the left */
|
|
329
|
-
.card .card-header-left-collapse[data-bs-toggle=collapse] {
|
|
331
|
+
.card .card-header-left-collapse[data-bs-toggle="collapse"] {
|
|
330
332
|
text-decoration: none;
|
|
331
333
|
position: relative;
|
|
332
334
|
padding: 0.75rem 3.25rem 0.75rem 1.25rem;
|
|
333
335
|
}
|
|
334
|
-
.card .card-header-left-collapse[data-bs-toggle=collapse]::before {
|
|
336
|
+
.card .card-header-left-collapse[data-bs-toggle="collapse"]::before {
|
|
335
337
|
position: absolute;
|
|
336
338
|
left: 0;
|
|
337
339
|
top: 0;
|
|
@@ -341,9 +343,24 @@ table.table-inner-grid, table.table-inner-grid th, table.table-inner-grid td {
|
|
|
341
343
|
font-family: "Font Awesome 5 Free";
|
|
342
344
|
color: #d1d3e2;
|
|
343
345
|
}
|
|
344
|
-
.card .card-header-left-collapse[data-bs-toggle=collapse].collapsed {
|
|
346
|
+
.card .card-header-left-collapse[data-bs-toggle="collapse"].collapsed {
|
|
345
347
|
border-radius: 0.35rem;
|
|
346
348
|
}
|
|
347
|
-
.card .card-header-left-collapse[data-bs-toggle=collapse].collapsed::before {
|
|
349
|
+
.card .card-header-left-collapse[data-bs-toggle="collapse"].collapsed::before {
|
|
348
350
|
content: "\f105";
|
|
349
351
|
}
|
|
352
|
+
|
|
353
|
+
.d-inline-maybe {
|
|
354
|
+
display: inline;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
.w-unset {
|
|
358
|
+
width: unset;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
.preview-text {
|
|
362
|
+
transform: rotate(-30deg);
|
|
363
|
+
z-index: 11;
|
|
364
|
+
margin-left: 30px;
|
|
365
|
+
margin-top: -5px;
|
|
366
|
+
}
|
package/public/saltcorn.js
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
|
-
function sortby(k, desc) {
|
|
2
|
-
set_state_fields({
|
|
1
|
+
function sortby(k, desc, viewIdentifier) {
|
|
2
|
+
set_state_fields({
|
|
3
|
+
[viewIdentifier ? `_${viewIdentifier}_sortby` : "_sortby"]: k,
|
|
4
|
+
[viewIdentifier ? `_${viewIdentifier}_sortdesc` : "_sortdesc"]: desc
|
|
5
|
+
? "on"
|
|
6
|
+
: { unset: true },
|
|
7
|
+
});
|
|
3
8
|
}
|
|
4
|
-
function gopage(n, pagesize, extra = {}) {
|
|
5
|
-
|
|
9
|
+
function gopage(n, pagesize, viewIdentifier, extra = {}) {
|
|
10
|
+
const cfg = {
|
|
11
|
+
...extra,
|
|
12
|
+
[viewIdentifier ? `_${viewIdentifier}_page` : "_page"]: n,
|
|
13
|
+
[viewIdentifier ? `_${viewIdentifier}_pagesize` : "_pagesize"]: pagesize,
|
|
14
|
+
};
|
|
15
|
+
set_state_fields(cfg);
|
|
6
16
|
}
|
|
7
17
|
|
|
8
18
|
if (localStorage.getItem("reload_on_init")) {
|
|
@@ -77,8 +87,21 @@ function check_state_field(that) {
|
|
|
77
87
|
pjax_to(dest.replace("&&", "&").replace("?&", "?"));
|
|
78
88
|
}
|
|
79
89
|
|
|
90
|
+
function invalidate_pagings(href) {
|
|
91
|
+
let newhref = href;
|
|
92
|
+
const queryObj = Object.fromEntries(new URL(newhref).searchParams.entries());
|
|
93
|
+
const toRemove = Object.keys(queryObj).filter((val) => is_paging_param(val));
|
|
94
|
+
for (const k of toRemove) {
|
|
95
|
+
newhref = removeQueryStringParameter(newhref, k);
|
|
96
|
+
}
|
|
97
|
+
return newhref;
|
|
98
|
+
}
|
|
99
|
+
|
|
80
100
|
function set_state_fields(kvs) {
|
|
81
|
-
|
|
101
|
+
let newhref = get_current_state_url();
|
|
102
|
+
if (Object.keys(kvs).some((k) => !is_paging_param(k))) {
|
|
103
|
+
newhref = invalidate_pagings(newhref);
|
|
104
|
+
}
|
|
82
105
|
Object.entries(kvs).forEach((kv) => {
|
|
83
106
|
if (kv[1].unset && kv[1].unset === true)
|
|
84
107
|
newhref = removeQueryStringParameter(newhref, kv[0]);
|
|
@@ -94,14 +117,15 @@ let loadPage = true;
|
|
|
94
117
|
$(function () {
|
|
95
118
|
$(window).bind("popstate", function (event) {
|
|
96
119
|
const ensure_no_final_hash = (s) => (s.endsWith("#") ? s.slice(0, -1) : s);
|
|
97
|
-
|
|
98
|
-
|
|
120
|
+
const newUrl = ensure_no_final_hash(window.location.href);
|
|
121
|
+
if (loadPage && newUrl !== window.location.href)
|
|
122
|
+
window.location.assign(newUrl);
|
|
99
123
|
});
|
|
100
124
|
});
|
|
101
125
|
|
|
102
126
|
function pjax_to(href) {
|
|
103
127
|
let $modal = $("#scmodal");
|
|
104
|
-
const inModal = $modal.length && $modal.hasClass("show")
|
|
128
|
+
const inModal = $modal.length && $modal.hasClass("show");
|
|
105
129
|
let $dest = inModal ? $("#scmodal .modal-body") : $("#page-inner-content");
|
|
106
130
|
|
|
107
131
|
if (!$dest.length) window.location.href = href;
|
|
@@ -126,7 +150,7 @@ function pjax_to(href) {
|
|
|
126
150
|
},
|
|
127
151
|
error: function (res) {
|
|
128
152
|
notifyAlert({ type: "danger", text: res.responseText });
|
|
129
|
-
}
|
|
153
|
+
},
|
|
130
154
|
});
|
|
131
155
|
}
|
|
132
156
|
}
|
|
@@ -135,21 +159,19 @@ function href_to(href) {
|
|
|
135
159
|
window.location.href = href;
|
|
136
160
|
}
|
|
137
161
|
function clear_state(omit_fields_str) {
|
|
138
|
-
let newUrl = get_current_state_url().split("?")[0]
|
|
139
|
-
const hash = get_current_state_url().split("#")[1]
|
|
162
|
+
let newUrl = get_current_state_url().split("?")[0];
|
|
163
|
+
const hash = get_current_state_url().split("#")[1];
|
|
140
164
|
if (omit_fields_str) {
|
|
141
|
-
const omit_fields = omit_fields_str.split(
|
|
142
|
-
let qs = (get_current_state_url().split("?")[1] || "").split("#")[0]
|
|
165
|
+
const omit_fields = omit_fields_str.split(",").map((s) => s.trim());
|
|
166
|
+
let qs = (get_current_state_url().split("?")[1] || "").split("#")[0];
|
|
143
167
|
let params = new URLSearchParams(qs);
|
|
144
|
-
newUrl = newUrl +
|
|
145
|
-
omit_fields.forEach(f => {
|
|
168
|
+
newUrl = newUrl + "?";
|
|
169
|
+
omit_fields.forEach((f) => {
|
|
146
170
|
if (params.get(f))
|
|
147
171
|
newUrl = updateQueryStringParameter(newUrl, f, params.get(f));
|
|
148
|
-
})
|
|
149
|
-
|
|
172
|
+
});
|
|
150
173
|
}
|
|
151
|
-
if (hash)
|
|
152
|
-
newUrl += '#' + hash;
|
|
174
|
+
if (hash) newUrl += "#" + hash;
|
|
153
175
|
|
|
154
176
|
pjax_to(newUrl);
|
|
155
177
|
}
|
|
@@ -170,12 +192,14 @@ function view_post(viewname, route, data, onDone) {
|
|
|
170
192
|
? "application/x-www-form-urlencoded"
|
|
171
193
|
: "application/json",
|
|
172
194
|
data: typeof data === "string" ? data : JSON.stringify(data),
|
|
173
|
-
})
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
195
|
+
})
|
|
196
|
+
.done(function (res) {
|
|
197
|
+
if (onDone) onDone(res);
|
|
198
|
+
ajax_done(res);
|
|
199
|
+
})
|
|
200
|
+
.fail(function (res) {
|
|
201
|
+
notifyAlert({ type: "danger", text: res.responseText });
|
|
202
|
+
});
|
|
179
203
|
}
|
|
180
204
|
var logged_errors = [];
|
|
181
205
|
function globalErrorCatcher(message, source, lineno, colno, error) {
|
|
@@ -254,6 +278,8 @@ function ajax_modal(url, opts = {}) {
|
|
|
254
278
|
|
|
255
279
|
function saveAndContinue(e, k) {
|
|
256
280
|
var form = $(e).closest("form");
|
|
281
|
+
const valres = form[0].reportValidity()
|
|
282
|
+
if (!valres) return;
|
|
257
283
|
submitWithEmptyAction(form[0]);
|
|
258
284
|
var url = form.attr("action");
|
|
259
285
|
var form_data = form.serialize();
|
|
@@ -300,12 +326,47 @@ function applyViewConfig(e, url, k) {
|
|
|
300
326
|
error: function (request) { },
|
|
301
327
|
success: function (res) {
|
|
302
328
|
k && k(res);
|
|
329
|
+
!k && updateViewPreview();
|
|
303
330
|
},
|
|
304
331
|
});
|
|
305
332
|
|
|
306
333
|
return false;
|
|
307
334
|
}
|
|
308
335
|
|
|
336
|
+
function updateViewPreview() {
|
|
337
|
+
const $preview = $("#viewcfg-preview[data-preview-url]");
|
|
338
|
+
if ($preview.length > 0) {
|
|
339
|
+
const url = $preview.attr("data-preview-url");
|
|
340
|
+
$preview.css({ opacity: 0.5 });
|
|
341
|
+
$.ajax(url, {
|
|
342
|
+
type: "POST",
|
|
343
|
+
headers: {
|
|
344
|
+
"CSRF-Token": _sc_globalCsrf,
|
|
345
|
+
},
|
|
346
|
+
|
|
347
|
+
error: function (request) { },
|
|
348
|
+
success: function (res) {
|
|
349
|
+
$preview.css({ opacity: 1.0 });
|
|
350
|
+
|
|
351
|
+
//disable elements in preview
|
|
352
|
+
$preview.html(res);
|
|
353
|
+
$preview.find("a").attr("href", "#");
|
|
354
|
+
$preview
|
|
355
|
+
.find("[onclick], button, a, input, select")
|
|
356
|
+
.attr("onclick", "return false");
|
|
357
|
+
|
|
358
|
+
$preview.find("textarea").attr("disabled", true);
|
|
359
|
+
$preview.find("input").attr("readonly", true);
|
|
360
|
+
|
|
361
|
+
//disable functions preview migght try to call
|
|
362
|
+
set_state_field = () => { }
|
|
363
|
+
set_state_fields = () => { }
|
|
364
|
+
|
|
365
|
+
},
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
309
370
|
function ajaxSubmitForm(e) {
|
|
310
371
|
var form = $(e).closest("form");
|
|
311
372
|
var url = form.attr("action");
|
|
@@ -317,10 +378,11 @@ function ajaxSubmitForm(e) {
|
|
|
317
378
|
data: new FormData(form[0]),
|
|
318
379
|
processData: false,
|
|
319
380
|
contentType: false,
|
|
320
|
-
success: function () {
|
|
381
|
+
success: function (res) {
|
|
321
382
|
var no_reload = $("#scmodal").hasClass("no-submit-reload");
|
|
322
383
|
$("#scmodal").modal("hide");
|
|
323
384
|
if (!no_reload) location.reload();
|
|
385
|
+
else common_done(res);
|
|
324
386
|
},
|
|
325
387
|
error: function (request) {
|
|
326
388
|
var title = request.getResponseHeader("Page-Title");
|
|
@@ -420,6 +482,17 @@ function test_formula(tablename, stored) {
|
|
|
420
482
|
});
|
|
421
483
|
}
|
|
422
484
|
|
|
485
|
+
function create_new_folder(folder) {
|
|
486
|
+
const name = window.prompt("Name of the new folder");
|
|
487
|
+
if (name)
|
|
488
|
+
ajax_post(`/files/new-folder`, {
|
|
489
|
+
data: { name, folder },
|
|
490
|
+
success: (data) => {
|
|
491
|
+
location.reload();
|
|
492
|
+
},
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
|
|
423
496
|
async function fill_formula_btn_click(btn, k) {
|
|
424
497
|
const formula = decodeURIComponent($(btn).attr("data-formula"));
|
|
425
498
|
const free_vars = JSON.parse(
|
|
@@ -444,61 +517,135 @@ async function fill_formula_btn_click(btn, k) {
|
|
|
444
517
|
}
|
|
445
518
|
}
|
|
446
519
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
*/
|
|
459
|
-
|
|
460
|
-
+(function ($) {
|
|
461
|
-
"use strict";
|
|
462
|
-
$.fn.historyTabs = function () {
|
|
463
|
-
var that = this;
|
|
464
|
-
window.addEventListener("popstate", function (event) {
|
|
465
|
-
if (event.state) {
|
|
466
|
-
$(that)
|
|
467
|
-
.filter('[href="' + event.state.url + '"]')
|
|
468
|
-
.tab("show");
|
|
469
|
-
}
|
|
520
|
+
try {
|
|
521
|
+
const val = new Function(
|
|
522
|
+
`{${Object.keys(rec).join(",")}}`,
|
|
523
|
+
"return " + formula
|
|
524
|
+
)(rec);
|
|
525
|
+
$(btn).closest(".input-group").find("input").val(val);
|
|
526
|
+
if (k) k();
|
|
527
|
+
} catch (e) {
|
|
528
|
+
notifyAlert({
|
|
529
|
+
type: "danger",
|
|
530
|
+
text: `Error evaluating fill formula: ${e.message}`,
|
|
470
531
|
});
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
532
|
+
console.error(e);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
function removeSpinner(elementId, orginalHtml) {
|
|
537
|
+
$(`#${elementId}`).html(orginalHtml);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
function poll_mobile_build_finished(outDirName, pollCount, orginalBtnHtml) {
|
|
541
|
+
$.ajax("/admin/build-mobile-app/finished", {
|
|
542
|
+
type: "GET",
|
|
543
|
+
data: { build_dir: outDirName },
|
|
544
|
+
success: function (res) {
|
|
545
|
+
if (!res.finished) {
|
|
546
|
+
if (pollCount >= 50) {
|
|
547
|
+
removeSpinner("buildMobileAppBtnId", orginalBtnHtml);
|
|
548
|
+
notifyAlert({
|
|
549
|
+
type: "danger",
|
|
550
|
+
text: "unable to get the build results",
|
|
551
|
+
});
|
|
483
552
|
} else {
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
window.location.pathname +
|
|
488
|
-
window.location.search +
|
|
489
|
-
$(this).attr("href")
|
|
490
|
-
);
|
|
553
|
+
setTimeout(() => {
|
|
554
|
+
poll_mobile_build_finished(outDirName, ++pollCount, orginalBtnHtml);
|
|
555
|
+
}, 5000);
|
|
491
556
|
}
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
557
|
+
} else {
|
|
558
|
+
href_to(
|
|
559
|
+
`build-mobile-app/result?build_dir_name=${encodeURIComponent(
|
|
560
|
+
outDirName
|
|
561
|
+
)}`
|
|
562
|
+
);
|
|
498
563
|
}
|
|
564
|
+
},
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
function build_mobile_app(button) {
|
|
569
|
+
const form = $(button).closest("form");
|
|
570
|
+
const params = {};
|
|
571
|
+
form.serializeArray().forEach((item) => {
|
|
572
|
+
params[item.name] = item.value;
|
|
573
|
+
});
|
|
574
|
+
ajax_post("/admin/build-mobile-app", {
|
|
575
|
+
data: params,
|
|
576
|
+
success: (data) => {
|
|
577
|
+
if (data.build_dir_name) {
|
|
578
|
+
handleMessages();
|
|
579
|
+
const orginalBtnHtml = $("#buildMobileAppBtnId").html();
|
|
580
|
+
press_store_button(button);
|
|
581
|
+
poll_mobile_build_finished(data.build_dir_name, 0, orginalBtnHtml);
|
|
582
|
+
}
|
|
583
|
+
},
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
(() => {
|
|
588
|
+
const e = document.querySelector("[data-sidebar-toggler]");
|
|
589
|
+
let closed = localStorage.getItem("sidebarClosed") === "true";
|
|
590
|
+
if (e) {
|
|
591
|
+
if (closed) {
|
|
592
|
+
e.dispatchEvent(new Event("click"));
|
|
593
|
+
}
|
|
594
|
+
e.addEventListener("click", () => {
|
|
595
|
+
closed = !closed;
|
|
596
|
+
localStorage.setItem("sidebarClosed", `${closed}`);
|
|
499
597
|
});
|
|
500
|
-
}
|
|
501
|
-
})(
|
|
598
|
+
}
|
|
599
|
+
})()
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
/*
|
|
603
|
+
https://github.com/jeffdavidgreen/bootstrap-html5-history-tabs/blob/master/bootstrap-history-tabs.js
|
|
604
|
+
Copyright (c) 2015 Jeff Green
|
|
605
|
+
*/
|
|
606
|
+
|
|
607
|
+
+ (function ($) {
|
|
608
|
+
"use strict";
|
|
609
|
+
$.fn.historyTabs = function () {
|
|
610
|
+
var that = this;
|
|
611
|
+
window.addEventListener("popstate", function (event) {
|
|
612
|
+
if (event.state) {
|
|
613
|
+
$(that)
|
|
614
|
+
.filter('[href="' + event.state.url + '"]')
|
|
615
|
+
.tab("show");
|
|
616
|
+
}
|
|
617
|
+
});
|
|
618
|
+
return this.each(function (index, element) {
|
|
619
|
+
$(element).on("show.bs.tab", function () {
|
|
620
|
+
var stateObject = { url: $(this).attr("href") };
|
|
621
|
+
|
|
622
|
+
if (window.location.hash && stateObject.url !== window.location.hash) {
|
|
623
|
+
window.history.pushState(
|
|
624
|
+
stateObject,
|
|
625
|
+
document.title,
|
|
626
|
+
window.location.pathname +
|
|
627
|
+
window.location.search +
|
|
628
|
+
$(this).attr("href")
|
|
629
|
+
);
|
|
630
|
+
} else {
|
|
631
|
+
window.history.replaceState(
|
|
632
|
+
stateObject,
|
|
633
|
+
document.title,
|
|
634
|
+
window.location.pathname +
|
|
635
|
+
window.location.search +
|
|
636
|
+
$(this).attr("href")
|
|
637
|
+
);
|
|
638
|
+
}
|
|
639
|
+
});
|
|
640
|
+
if (!window.location.hash && $(element).is(".active")) {
|
|
641
|
+
// Shows the first element if there are no query parameters.
|
|
642
|
+
$(element).tab("show");
|
|
643
|
+
} else if ($(this).attr("href") === window.location.hash) {
|
|
644
|
+
$(element).tab("show");
|
|
645
|
+
}
|
|
646
|
+
});
|
|
647
|
+
};
|
|
648
|
+
})(jQuery);
|
|
502
649
|
|
|
503
650
|
// Copyright (c) 2011 Marcus Ekwall, http://writeless.se/
|
|
504
651
|
// https://github.com/mekwall/jquery-throttle
|
package/restart_watcher.js
CHANGED
package/routes/actions.js
CHANGED
|
@@ -5,7 +5,12 @@
|
|
|
5
5
|
* @subcategory routes
|
|
6
6
|
*/
|
|
7
7
|
const Router = require("express-promise-router");
|
|
8
|
-
const {
|
|
8
|
+
const {
|
|
9
|
+
isAdmin,
|
|
10
|
+
error_catcher,
|
|
11
|
+
get_base_url,
|
|
12
|
+
addOnDoneRedirect,
|
|
13
|
+
} = require("./utils.js");
|
|
9
14
|
const { getState } = require("@saltcorn/data/db/state");
|
|
10
15
|
const Trigger = require("@saltcorn/data/models/trigger");
|
|
11
16
|
const { getTriggerList } = require("./common_lists");
|
|
@@ -87,7 +92,6 @@ router.get(
|
|
|
87
92
|
error_catcher(async (req, res) => {
|
|
88
93
|
const triggers = await Trigger.findAllWithTableName();
|
|
89
94
|
const actions = await getActions();
|
|
90
|
-
const base_url = get_base_url(req);
|
|
91
95
|
send_events_page({
|
|
92
96
|
res,
|
|
93
97
|
req,
|
|
@@ -149,6 +153,7 @@ const triggerForm = async (req, trigger) => {
|
|
|
149
153
|
id = trigger.id;
|
|
150
154
|
form_action = `/actions/edit/${id}`;
|
|
151
155
|
} else form_action = "/actions/new";
|
|
156
|
+
form_action = addOnDoneRedirect(form_action, req);
|
|
152
157
|
const hasChannel = Object.entries(getState().eventTypes)
|
|
153
158
|
.filter(([k, v]) => v.hasChannel)
|
|
154
159
|
.map(([k, v]) => k);
|
|
@@ -323,7 +328,7 @@ router.post(
|
|
|
323
328
|
const tr = await Trigger.create(form.values);
|
|
324
329
|
id = tr.id;
|
|
325
330
|
}
|
|
326
|
-
res.redirect(`/actions/configure/${id}
|
|
331
|
+
res.redirect(addOnDoneRedirect(`/actions/configure/${id}`, req));
|
|
327
332
|
}
|
|
328
333
|
})
|
|
329
334
|
);
|
|
@@ -382,6 +387,11 @@ router.get(
|
|
|
382
387
|
error_catcher(async (req, res) => {
|
|
383
388
|
const { id } = req.params;
|
|
384
389
|
const trigger = await Trigger.findOne({ id });
|
|
390
|
+
if (!trigger) {
|
|
391
|
+
req.flash("warning", req.__("Action not found"));
|
|
392
|
+
res.redirect(`/actions/`);
|
|
393
|
+
return
|
|
394
|
+
}
|
|
385
395
|
const action = getState().actions[trigger.action];
|
|
386
396
|
if (!action) {
|
|
387
397
|
req.flash("warning", req.__("Action not found"));
|
|
@@ -389,7 +399,7 @@ router.get(
|
|
|
389
399
|
} else if (trigger.action === "blocks") {
|
|
390
400
|
const locale = req.getLocale();
|
|
391
401
|
const form = new Form({
|
|
392
|
-
action: `/actions/configure/${id}`,
|
|
402
|
+
action: addOnDoneRedirect(`/actions/configure/${id}`, req),
|
|
393
403
|
fields: action.configFields,
|
|
394
404
|
noSubmitButton: true,
|
|
395
405
|
id: "blocklyForm",
|
|
@@ -464,7 +474,7 @@ router.get(
|
|
|
464
474
|
const cfgFields = await getActionConfigFields(action, table);
|
|
465
475
|
// create form
|
|
466
476
|
const form = new Form({
|
|
467
|
-
action: `/actions/configure/${id}`,
|
|
477
|
+
action: addOnDoneRedirect(`/actions/configure/${id}`, req),
|
|
468
478
|
fields: cfgFields,
|
|
469
479
|
});
|
|
470
480
|
// populate form values
|
|
@@ -522,7 +532,11 @@ router.post(
|
|
|
522
532
|
} else {
|
|
523
533
|
await Trigger.update(trigger.id, { configuration: form.values });
|
|
524
534
|
req.flash("success", "Action configuration saved");
|
|
525
|
-
res.redirect(
|
|
535
|
+
res.redirect(
|
|
536
|
+
req.query.on_done_redirect
|
|
537
|
+
? `/${req.query.on_done_redirect}`
|
|
538
|
+
: "/actions/"
|
|
539
|
+
);
|
|
526
540
|
}
|
|
527
541
|
})
|
|
528
542
|
);
|