@saltcorn/server 0.7.3-beta.7 → 0.7.3
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/auth/admin.js +7 -4
- package/locales/en.json +2 -1
- package/markup/admin.js +4 -3
- package/package.json +7 -7
- package/public/saltcorn-common.js +2 -1
- package/public/saltcorn.js +5 -1
- package/routes/admin.js +17 -11
- package/routes/eventlog.js +24 -22
- package/routes/files.js +5 -5
- package/routes/infoarch.js +6 -3
- package/routes/plugins.js +77 -11
- package/routes/search.js +4 -2
- package/routes/tables.js +4 -3
- package/routes/tenant.js +4 -2
- package/routes/viewedit.js +2 -1
package/auth/admin.js
CHANGED
|
@@ -381,7 +381,8 @@ router.post(
|
|
|
381
381
|
} else {
|
|
382
382
|
await save_config_from_form(form);
|
|
383
383
|
req.flash("success", req.__("User settings updated"));
|
|
384
|
-
res.redirect("/useradmin/settings");
|
|
384
|
+
if (!req.xhr) res.redirect("/useradmin/settings");
|
|
385
|
+
else res.json({ success: "ok" });
|
|
385
386
|
}
|
|
386
387
|
})
|
|
387
388
|
);
|
|
@@ -530,7 +531,7 @@ router.get(
|
|
|
530
531
|
send_users_page({
|
|
531
532
|
res,
|
|
532
533
|
req,
|
|
533
|
-
active_sub: "
|
|
534
|
+
active_sub: "SSL",
|
|
534
535
|
contents: {
|
|
535
536
|
type: "card",
|
|
536
537
|
title: req.__("Authentication settings"),
|
|
@@ -556,7 +557,7 @@ router.post(
|
|
|
556
557
|
send_users_page({
|
|
557
558
|
res,
|
|
558
559
|
req,
|
|
559
|
-
active_sub: "
|
|
560
|
+
active_sub: "SSL",
|
|
560
561
|
contents: {
|
|
561
562
|
type: "card",
|
|
562
563
|
title: req.__("Authentication settings"),
|
|
@@ -572,7 +573,9 @@ router.post(
|
|
|
572
573
|
" " +
|
|
573
574
|
a({ href: "/admin/system" }, req.__("Restart here"))
|
|
574
575
|
);
|
|
575
|
-
|
|
576
|
+
if (!req.xhr) {
|
|
577
|
+
res.redirect("/useradmin/ssl");
|
|
578
|
+
} else res.json({ success: "ok" });
|
|
576
579
|
}
|
|
577
580
|
})
|
|
578
581
|
);
|
package/locales/en.json
CHANGED
|
@@ -920,5 +920,6 @@
|
|
|
920
920
|
"Download automated backup": "Download automated backup",
|
|
921
921
|
"Restoring automated backup": "Restoring automated backup",
|
|
922
922
|
"No errors detected during configuration check": "No errors detected during configuration check",
|
|
923
|
-
"%s view - %s on %s": "%s view - %s on %s"
|
|
923
|
+
"%s view - %s on %s": "%s view - %s on %s",
|
|
924
|
+
"Back": "Back"
|
|
924
925
|
}
|
package/markup/admin.js
CHANGED
|
@@ -345,7 +345,7 @@ const flash_restart = (req) => {
|
|
|
345
345
|
* @param {*} opts.formArgs
|
|
346
346
|
* @returns {Promise<Form>}
|
|
347
347
|
*/
|
|
348
|
-
const config_fields_form = async ({ field_names, req, ...formArgs }) => {
|
|
348
|
+
const config_fields_form = async ({ field_names, req, action, ...formArgs }) => {
|
|
349
349
|
const values = {};
|
|
350
350
|
const state = getState();
|
|
351
351
|
const fields = [];
|
|
@@ -396,8 +396,9 @@ const config_fields_form = async ({ field_names, req, ...formArgs }) => {
|
|
|
396
396
|
const form = new Form({
|
|
397
397
|
fields,
|
|
398
398
|
values,
|
|
399
|
-
|
|
400
|
-
|
|
399
|
+
action,
|
|
400
|
+
noSubmitButton: true,
|
|
401
|
+
onChange: `saveAndContinue(this)`,
|
|
401
402
|
...formArgs,
|
|
402
403
|
});
|
|
403
404
|
await form.fill_fkey_options();
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saltcorn/server",
|
|
3
|
-
"version": "0.7.3
|
|
3
|
+
"version": "0.7.3",
|
|
4
4
|
"description": "Server app for Saltcorn, open-source no-code platform",
|
|
5
5
|
"homepage": "https://saltcorn.com",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@saltcorn/base-plugin": "0.7.3
|
|
10
|
-
"@saltcorn/builder": "0.7.3
|
|
11
|
-
"@saltcorn/data": "0.7.3
|
|
12
|
-
"@saltcorn/admin-models": "0.7.3
|
|
13
|
-
"@saltcorn/markup": "0.7.3
|
|
14
|
-
"@saltcorn/sbadmin2": "0.7.3
|
|
9
|
+
"@saltcorn/base-plugin": "0.7.3",
|
|
10
|
+
"@saltcorn/builder": "0.7.3",
|
|
11
|
+
"@saltcorn/data": "0.7.3",
|
|
12
|
+
"@saltcorn/admin-models": "0.7.3",
|
|
13
|
+
"@saltcorn/markup": "0.7.3",
|
|
14
|
+
"@saltcorn/sbadmin2": "0.7.3",
|
|
15
15
|
"@socket.io/cluster-adapter": "^0.1.0",
|
|
16
16
|
"@socket.io/sticky": "^1.0.1",
|
|
17
17
|
"aws-sdk": "^2.1037.0",
|
|
@@ -502,7 +502,7 @@ function common_done(res, isWeb = true) {
|
|
|
502
502
|
}
|
|
503
503
|
}
|
|
504
504
|
|
|
505
|
-
const repeaterCopyValuesToForm = (form, editor) => {
|
|
505
|
+
const repeaterCopyValuesToForm = (form, editor, noTriggerChange) => {
|
|
506
506
|
const vs = JSON.parse(editor.getString());
|
|
507
507
|
|
|
508
508
|
const setVal = (k, ix, v) => {
|
|
@@ -533,6 +533,7 @@ const repeaterCopyValuesToForm = (form, editor) => {
|
|
|
533
533
|
if (typeof ix !== "number" || isNaN(ix)) return;
|
|
534
534
|
if (ix >= vs.length) $(this).remove();
|
|
535
535
|
});
|
|
536
|
+
!noTriggerChange && form.trigger("change");
|
|
536
537
|
};
|
|
537
538
|
function align_dropdown(id) {
|
|
538
539
|
setTimeout(() => {
|
package/public/saltcorn.js
CHANGED
|
@@ -213,6 +213,7 @@ function ajax_modal(url, opts = {}) {
|
|
|
213
213
|
(opts.onOpen || function () {})(res);
|
|
214
214
|
$("#scmodal").on("hidden.bs.modal", function (e) {
|
|
215
215
|
(opts.onClose || function () {})(res);
|
|
216
|
+
$("body").css("overflow", "");
|
|
216
217
|
});
|
|
217
218
|
},
|
|
218
219
|
});
|
|
@@ -248,7 +249,7 @@ function saveAndContinue(e, k) {
|
|
|
248
249
|
return false;
|
|
249
250
|
}
|
|
250
251
|
|
|
251
|
-
function applyViewConfig(e, url) {
|
|
252
|
+
function applyViewConfig(e, url, k) {
|
|
252
253
|
var form = $(e).closest("form");
|
|
253
254
|
var form_data = form.serializeArray();
|
|
254
255
|
const cfg = {};
|
|
@@ -264,6 +265,9 @@ function applyViewConfig(e, url) {
|
|
|
264
265
|
},
|
|
265
266
|
data: JSON.stringify(cfg),
|
|
266
267
|
error: function (request) {},
|
|
268
|
+
success: function (res) {
|
|
269
|
+
k && k(res);
|
|
270
|
+
},
|
|
267
271
|
});
|
|
268
272
|
|
|
269
273
|
return false;
|
package/routes/admin.js
CHANGED
|
@@ -46,6 +46,8 @@ const {
|
|
|
46
46
|
ul,
|
|
47
47
|
li,
|
|
48
48
|
ol,
|
|
49
|
+
script,
|
|
50
|
+
domReady,
|
|
49
51
|
} = require("@saltcorn/markup/tags");
|
|
50
52
|
const db = require("@saltcorn/data/db");
|
|
51
53
|
const {
|
|
@@ -141,10 +143,6 @@ const email_form = async (req) => {
|
|
|
141
143
|
],
|
|
142
144
|
action: "/admin/email",
|
|
143
145
|
});
|
|
144
|
-
form.submitButtonClass = "btn-outline-primary";
|
|
145
|
-
form.submitLabel = req.__("Save");
|
|
146
|
-
form.onChange =
|
|
147
|
-
"remove_outline(this);$('#testemail').attr('href','#').removeClass('btn-primary').addClass('btn-outline-primary')";
|
|
148
146
|
return form;
|
|
149
147
|
};
|
|
150
148
|
|
|
@@ -215,8 +213,10 @@ router.post(
|
|
|
215
213
|
flash_restart_if_required(form, req);
|
|
216
214
|
await save_config_from_form(form);
|
|
217
215
|
|
|
218
|
-
|
|
219
|
-
|
|
216
|
+
if (!req.xhr) {
|
|
217
|
+
req.flash("success", req.__("Site identity settings updated"));
|
|
218
|
+
res.redirect("/admin");
|
|
219
|
+
} else res.json({ success: "ok" });
|
|
220
220
|
}
|
|
221
221
|
})
|
|
222
222
|
);
|
|
@@ -309,7 +309,8 @@ router.post(
|
|
|
309
309
|
} else {
|
|
310
310
|
await save_config_from_form(form);
|
|
311
311
|
req.flash("success", req.__("Email settings updated"));
|
|
312
|
-
res.redirect("/admin/email");
|
|
312
|
+
if (!req.xhr) res.redirect("/admin/email");
|
|
313
|
+
else res.json({ success: "ok" });
|
|
313
314
|
}
|
|
314
315
|
})
|
|
315
316
|
);
|
|
@@ -379,6 +380,11 @@ router.get(
|
|
|
379
380
|
a(
|
|
380
381
|
{ href: "/admin/auto-backup-list" },
|
|
381
382
|
"Restore/download automated backups »"
|
|
383
|
+
),
|
|
384
|
+
script(
|
|
385
|
+
domReady(
|
|
386
|
+
`$('#btnBackupNow').prop('disabled', $('#inputauto_backup_frequency').val()==='Never');`
|
|
387
|
+
)
|
|
382
388
|
)
|
|
383
389
|
),
|
|
384
390
|
}
|
|
@@ -484,9 +490,8 @@ router.get(
|
|
|
484
490
|
const autoBackupForm = (req) =>
|
|
485
491
|
new Form({
|
|
486
492
|
action: "/admin/set-auto-backup",
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
submitLabel: "Save settings",
|
|
493
|
+
onChange: `saveAndContinue(this);$('#btnBackupNow').prop('disabled', $('#inputauto_backup_frequency').val()==='Never');`,
|
|
494
|
+
noSubmitButton: true,
|
|
490
495
|
additionalButtons: [
|
|
491
496
|
{
|
|
492
497
|
label: "Backup now",
|
|
@@ -555,7 +560,8 @@ router.post(
|
|
|
555
560
|
} else {
|
|
556
561
|
await save_config_from_form(form);
|
|
557
562
|
req.flash("success", req.__("Backup settings updated"));
|
|
558
|
-
res.redirect("/admin/backup");
|
|
563
|
+
if (!req.xhr) res.redirect("/admin/backup");
|
|
564
|
+
else res.json({ success: "ok" });
|
|
559
565
|
}
|
|
560
566
|
})
|
|
561
567
|
);
|
package/routes/eventlog.js
CHANGED
|
@@ -73,8 +73,9 @@ const logSettingsForm = async (req) => {
|
|
|
73
73
|
fields.push({
|
|
74
74
|
name: w + "_channel",
|
|
75
75
|
label: w + " channel",
|
|
76
|
-
sublabel:
|
|
77
|
-
|
|
76
|
+
sublabel: req.__(
|
|
77
|
+
"Channels to create events for. Separate by comma; leave blank for all"
|
|
78
|
+
),
|
|
78
79
|
type: "String",
|
|
79
80
|
showIf: { [w]: true },
|
|
80
81
|
});
|
|
@@ -82,8 +83,8 @@ const logSettingsForm = async (req) => {
|
|
|
82
83
|
return new Form({
|
|
83
84
|
action: "/eventlog/settings",
|
|
84
85
|
blurb: req.__("Which events should be logged?"),
|
|
85
|
-
|
|
86
|
-
onChange: "
|
|
86
|
+
noSubmitButton: true,
|
|
87
|
+
onChange: "saveAndContinue(this)",
|
|
87
88
|
fields,
|
|
88
89
|
});
|
|
89
90
|
};
|
|
@@ -169,23 +170,23 @@ router.get(
|
|
|
169
170
|
* @returns {Form}
|
|
170
171
|
*/
|
|
171
172
|
const customEventForm = async (req) => {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
173
|
+
return new Form({
|
|
174
|
+
action: "/eventlog/custom/new",
|
|
175
|
+
submitButtonClass: "btn-outline-primary",
|
|
176
|
+
onChange: "remove_outline(this)",
|
|
177
|
+
fields: [
|
|
178
|
+
{
|
|
179
|
+
name: "name",
|
|
180
|
+
label: req.__("Event Name"),
|
|
181
|
+
type: "String",
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
name: "hasChannel",
|
|
185
|
+
label: req.__("Has channels?"),
|
|
186
|
+
type: "Bool",
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
});
|
|
189
190
|
};
|
|
190
191
|
/**
|
|
191
192
|
* @name get/custom/new
|
|
@@ -297,7 +298,8 @@ router.post(
|
|
|
297
298
|
} else {
|
|
298
299
|
await getState().setConfig("event_log_settings", form.values);
|
|
299
300
|
|
|
300
|
-
res.redirect(`/eventlog/settings`);
|
|
301
|
+
if (!req.xhr) res.redirect(`/eventlog/settings`);
|
|
302
|
+
else res.json({ success: "ok" });
|
|
301
303
|
}
|
|
302
304
|
})
|
|
303
305
|
);
|
package/routes/files.js
CHANGED
|
@@ -378,9 +378,6 @@ const storage_form = async (req) => {
|
|
|
378
378
|
],
|
|
379
379
|
action: "/files/storage",
|
|
380
380
|
});
|
|
381
|
-
form.submitButtonClass = "btn-outline-primary";
|
|
382
|
-
form.submitLabel = req.__("Save");
|
|
383
|
-
form.onChange = "remove_outline(this)";
|
|
384
381
|
return form;
|
|
385
382
|
};
|
|
386
383
|
|
|
@@ -431,8 +428,11 @@ router.post(
|
|
|
431
428
|
});
|
|
432
429
|
} else {
|
|
433
430
|
await save_config_from_form(form);
|
|
434
|
-
|
|
435
|
-
|
|
431
|
+
|
|
432
|
+
if (!req.xhr) {
|
|
433
|
+
req.flash("success", req.__("Storage settings updated"));
|
|
434
|
+
res.redirect("/files/storage");
|
|
435
|
+
} else res.json({ success: "ok" });
|
|
436
436
|
}
|
|
437
437
|
})
|
|
438
438
|
);
|
package/routes/infoarch.js
CHANGED
|
@@ -48,8 +48,8 @@ router.get(
|
|
|
48
48
|
const languageForm = (req) =>
|
|
49
49
|
new Form({
|
|
50
50
|
action: "/site-structure/localizer/save-lang",
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
onChange: "saveAndContinue(this)",
|
|
52
|
+
noSubmitButton: true,
|
|
53
53
|
fields: [
|
|
54
54
|
{
|
|
55
55
|
name: "name",
|
|
@@ -270,7 +270,10 @@ router.post(
|
|
|
270
270
|
...cfgLangs,
|
|
271
271
|
[lang.locale]: lang,
|
|
272
272
|
});
|
|
273
|
-
|
|
273
|
+
|
|
274
|
+
if (!req.xhr)
|
|
275
|
+
res.redirect(`/site-structure/localizer/edit/${lang.locale}`);
|
|
276
|
+
else res.json({ success: "ok" });
|
|
274
277
|
}
|
|
275
278
|
})
|
|
276
279
|
);
|
package/routes/plugins.js
CHANGED
|
@@ -561,12 +561,30 @@ router.get(
|
|
|
561
561
|
}
|
|
562
562
|
const flow = module.configuration_workflow();
|
|
563
563
|
flow.action = `/plugins/configure/${encodeURIComponent(plugin.name)}`;
|
|
564
|
+
flow.autoSave = true;
|
|
565
|
+
flow.saveURL = `/plugins/saveconfig/${encodeURIComponent(plugin.name)}`;
|
|
564
566
|
const wfres = await flow.run(plugin.configuration || {});
|
|
567
|
+
if (module.layout) {
|
|
568
|
+
wfres.renderForm.additionalButtons = [
|
|
569
|
+
...(wfres.renderForm.additionalButtons || []),
|
|
570
|
+
{
|
|
571
|
+
label: "Reload page to see changes",
|
|
572
|
+
id: "btnReloadNow",
|
|
573
|
+
class: "btn btn-outline-secondary",
|
|
574
|
+
onclick: "location.reload()",
|
|
575
|
+
},
|
|
576
|
+
];
|
|
577
|
+
wfres.renderForm.onChange = `${
|
|
578
|
+
wfres.renderForm.onChange || ""
|
|
579
|
+
};$('#btnReloadNow').removeClass('btn-outline-secondary').addClass('btn-secondary')`;
|
|
580
|
+
}
|
|
565
581
|
|
|
566
|
-
res.sendWrap(
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
582
|
+
res.sendWrap(req.__(`Configure %s Plugin`, plugin.name), {
|
|
583
|
+
type: "card",
|
|
584
|
+
class: "mt-0",
|
|
585
|
+
title: req.__(`Configure %s Plugin`, plugin.name),
|
|
586
|
+
contents: renderForm(wfres.renderForm, req.csrfToken()),
|
|
587
|
+
});
|
|
570
588
|
})
|
|
571
589
|
);
|
|
572
590
|
|
|
@@ -588,13 +606,31 @@ router.post(
|
|
|
588
606
|
}
|
|
589
607
|
const flow = module.configuration_workflow();
|
|
590
608
|
flow.action = `/plugins/configure/${encodeURIComponent(plugin.name)}`;
|
|
609
|
+
flow.autoSave = true;
|
|
610
|
+
flow.saveURL = `/plugins/saveconfig/${encodeURIComponent(plugin.name)}`;
|
|
591
611
|
const wfres = await flow.run(req.body);
|
|
592
|
-
if (wfres.renderForm)
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
612
|
+
if (wfres.renderForm) {
|
|
613
|
+
if (module.layout) {
|
|
614
|
+
wfres.renderForm.additionalButtons = [
|
|
615
|
+
...(wfres.renderForm.additionalButtons || []),
|
|
616
|
+
{
|
|
617
|
+
label: "Reload page to see changes",
|
|
618
|
+
id: "btnReloadNow",
|
|
619
|
+
class: "btn btn-outline-secondary",
|
|
620
|
+
onclick: "location.reload()",
|
|
621
|
+
},
|
|
622
|
+
];
|
|
623
|
+
wfres.renderForm.onChange = `${
|
|
624
|
+
wfres.renderForm.onChange || ""
|
|
625
|
+
};$('#btnReloadNow').removeClass('btn-outline-secondary').addClass('btn-secondary')`;
|
|
626
|
+
}
|
|
627
|
+
res.sendWrap(req.__(`Configure %s Plugin`, plugin.name), {
|
|
628
|
+
type: "card",
|
|
629
|
+
class: "mt-0",
|
|
630
|
+
title: req.__(`Configure %s Plugin`, plugin.name),
|
|
631
|
+
contents: renderForm(wfres.renderForm, req.csrfToken()),
|
|
632
|
+
});
|
|
633
|
+
} else {
|
|
598
634
|
plugin.configuration = wfres;
|
|
599
635
|
await plugin.upsert();
|
|
600
636
|
await load_plugins.loadPlugin(plugin);
|
|
@@ -606,12 +642,42 @@ router.post(
|
|
|
606
642
|
refresh_plugin_cfg: plugin.name,
|
|
607
643
|
tenant: db.getTenantSchema(),
|
|
608
644
|
});
|
|
609
|
-
await sleep(500); // Allow other workers to reload this plugin
|
|
645
|
+
if (module.layout) await sleep(500); // Allow other workers to reload this plugin
|
|
610
646
|
res.redirect("/plugins");
|
|
611
647
|
}
|
|
612
648
|
})
|
|
613
649
|
);
|
|
614
650
|
|
|
651
|
+
router.post(
|
|
652
|
+
"/saveconfig/:name",
|
|
653
|
+
isAdmin,
|
|
654
|
+
error_catcher(async (req, res) => {
|
|
655
|
+
const { name } = req.params;
|
|
656
|
+
const plugin = await Plugin.findOne({ name: decodeURIComponent(name) });
|
|
657
|
+
let module = getState().plugins[plugin.name];
|
|
658
|
+
if (!module) {
|
|
659
|
+
module = getState().plugins[getState().plugin_module_names[plugin.name]];
|
|
660
|
+
}
|
|
661
|
+
const flow = module.configuration_workflow();
|
|
662
|
+
const step = await flow.singleStepForm(req.body, req);
|
|
663
|
+
if (step?.renderForm) {
|
|
664
|
+
if (!step.renderForm.hasErrors) {
|
|
665
|
+
plugin.configuration = {
|
|
666
|
+
...plugin.configuration,
|
|
667
|
+
...step.renderForm.values,
|
|
668
|
+
};
|
|
669
|
+
await plugin.upsert();
|
|
670
|
+
await load_plugins.loadPlugin(plugin);
|
|
671
|
+
process.send &&
|
|
672
|
+
process.send({
|
|
673
|
+
refresh_plugin_cfg: plugin.name,
|
|
674
|
+
tenant: db.getTenantSchema(),
|
|
675
|
+
});
|
|
676
|
+
res.json({ success: "ok" });
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
})
|
|
680
|
+
);
|
|
615
681
|
/**
|
|
616
682
|
* @name get/new
|
|
617
683
|
* @function
|
package/routes/search.js
CHANGED
|
@@ -55,7 +55,8 @@ const searchConfigForm = (tables, views, req) => {
|
|
|
55
55
|
);
|
|
56
56
|
return new Form({
|
|
57
57
|
action: "/search/config",
|
|
58
|
-
|
|
58
|
+
noSubmitButton: true,
|
|
59
|
+
onChange: `saveAndContinue(this)`,
|
|
59
60
|
blurb:
|
|
60
61
|
blurb1 +
|
|
61
62
|
(tbls_noviews.length > 0
|
|
@@ -111,7 +112,8 @@ router.post(
|
|
|
111
112
|
|
|
112
113
|
if (result.success) {
|
|
113
114
|
await getState().setConfig("globalSearch", result.success);
|
|
114
|
-
res.redirect("/search/config");
|
|
115
|
+
if (!req.xhr) res.redirect("/search/config");
|
|
116
|
+
else res.json({ success: "ok" });
|
|
115
117
|
} else {
|
|
116
118
|
send_infoarch_page({
|
|
117
119
|
res,
|
package/routes/tables.js
CHANGED
|
@@ -83,8 +83,8 @@ const tableForm = async (table, req) => {
|
|
|
83
83
|
.map((f) => ({ value: f.id, label: f.name }));
|
|
84
84
|
const form = new Form({
|
|
85
85
|
action: "/table",
|
|
86
|
-
|
|
87
|
-
onChange: "
|
|
86
|
+
noSubmitButton: true,
|
|
87
|
+
onChange: "saveAndContinue(this)",
|
|
88
88
|
fields: [
|
|
89
89
|
...(!table.external
|
|
90
90
|
? [
|
|
@@ -910,7 +910,8 @@ router.post(
|
|
|
910
910
|
);
|
|
911
911
|
else if (!hasError) req.flash("success", req.__("Table saved"));
|
|
912
912
|
|
|
913
|
-
res.redirect(`/table/${id}`);
|
|
913
|
+
if (!req.xhr) res.redirect(`/table/${id}`);
|
|
914
|
+
else res.json({ success: "ok" });
|
|
914
915
|
}
|
|
915
916
|
})
|
|
916
917
|
);
|
package/routes/tenant.js
CHANGED
|
@@ -452,8 +452,10 @@ router.post(
|
|
|
452
452
|
} else {
|
|
453
453
|
await save_config_from_form(form);
|
|
454
454
|
|
|
455
|
-
|
|
456
|
-
|
|
455
|
+
if (!req.xhr) {
|
|
456
|
+
req.flash("success", req.__("Tenant settings updated"));
|
|
457
|
+
res.redirect("/tenant/settings");
|
|
458
|
+
} else res.json({ success: "ok" });
|
|
457
459
|
}
|
|
458
460
|
})
|
|
459
461
|
);
|
package/routes/viewedit.js
CHANGED
|
@@ -584,7 +584,7 @@ router.get(
|
|
|
584
584
|
isAdmin,
|
|
585
585
|
error_catcher(async (req, res) => {
|
|
586
586
|
const { name } = req.params;
|
|
587
|
-
|
|
587
|
+
const { step } = req.query;
|
|
588
588
|
const view = await View.findOne({ name });
|
|
589
589
|
if (!view) {
|
|
590
590
|
req.flash("error", `View not found: ${text(name)}`);
|
|
@@ -601,6 +601,7 @@ router.get(
|
|
|
601
601
|
table_id: view.table_id,
|
|
602
602
|
exttable_name: view.exttable_name,
|
|
603
603
|
viewname: name,
|
|
604
|
+
...(step ? { stepName: step } : {}),
|
|
604
605
|
},
|
|
605
606
|
req
|
|
606
607
|
);
|