@saltcorn/server 1.1.1-beta.1 → 1.1.1-beta.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/CHANGELOG.md +83 -5
- package/auth/testhelp.js +6 -0
- package/help/Event types.tmd +2 -0
- package/locales/en.json +7 -1
- package/package.json +9 -9
- package/public/saltcorn-common.js +30 -0
- package/public/saltcorn.css +141 -0
- package/public/saltcorn.js +87 -17
- package/routes/actions.js +86 -11
- package/routes/admin.js +281 -48
- package/routes/api.js +19 -8
- package/routes/fields.js +9 -0
- package/routes/menu.js +1 -0
- package/routes/notifications.js +20 -12
- package/routes/page.js +2 -2
- package/routes/pageedit.js +35 -1
- package/routes/tables.js +1 -0
- package/routes/utils.js +4 -0
- package/routes/view.js +14 -12
- package/routes/viewedit.js +26 -0
- package/tests/clientjs.test.js +22 -0
package/routes/pageedit.js
CHANGED
|
@@ -146,7 +146,9 @@ const pagePropertiesForm = async (req, isNew) => {
|
|
|
146
146
|
{
|
|
147
147
|
name: "request_fluid_layout",
|
|
148
148
|
label: req.__("Fluid layout"),
|
|
149
|
-
sublabel: req.__(
|
|
149
|
+
sublabel: req.__(
|
|
150
|
+
"Request fluid layout from theme for a wider display for this page"
|
|
151
|
+
),
|
|
150
152
|
type: "Bool",
|
|
151
153
|
},
|
|
152
154
|
],
|
|
@@ -256,6 +258,7 @@ const pageBuilderData = async (req, context) => {
|
|
|
256
258
|
next_button_label: "Done",
|
|
257
259
|
fonts: getState().fonts,
|
|
258
260
|
tables: [],
|
|
261
|
+
keyframes: getState().keyframes,
|
|
259
262
|
};
|
|
260
263
|
};
|
|
261
264
|
|
|
@@ -503,12 +506,21 @@ router.post(
|
|
|
503
506
|
pageRow.layout = {};
|
|
504
507
|
}
|
|
505
508
|
await Page.update(+id, pageRow);
|
|
509
|
+
Trigger.emitEvent("AppChange", `Page ${dbPage.name}`, req.user, {
|
|
510
|
+
entity_type: "Page",
|
|
511
|
+
entity_name: dbPage.name,
|
|
512
|
+
});
|
|
506
513
|
if (req.xhr) res.json({ success: "ok" });
|
|
507
514
|
else res.redirect(`/pageedit/`);
|
|
508
515
|
} else {
|
|
509
516
|
if (!pageRow.layout) pageRow.layout = {};
|
|
510
517
|
if (!pageRow.fixed_states) pageRow.fixed_states = {};
|
|
511
518
|
await Page.create(pageRow);
|
|
519
|
+
Trigger.emitEvent("AppChange", `Page ${pageRow.name}`, req.user, {
|
|
520
|
+
entity_type: "Page",
|
|
521
|
+
entity_name: pageRow.name,
|
|
522
|
+
});
|
|
523
|
+
|
|
512
524
|
if (!html_file)
|
|
513
525
|
res.redirect(
|
|
514
526
|
addOnDoneRedirect(`/pageedit/edit/${pageRow.name}`, req)
|
|
@@ -679,6 +691,10 @@ router.post(
|
|
|
679
691
|
await Page.update(page.id, {
|
|
680
692
|
layout: decodeURIComponent(req.body.layout),
|
|
681
693
|
});
|
|
694
|
+
Trigger.emitEvent("AppChange", `Page ${page.name}`, req.user, {
|
|
695
|
+
entity_type: "Page",
|
|
696
|
+
entity_name: page.name,
|
|
697
|
+
});
|
|
682
698
|
req.flash("success", req.__(`Page %s saved`, pagename));
|
|
683
699
|
res.redirect(redirectTarget);
|
|
684
700
|
} else if (req.body.code) {
|
|
@@ -687,6 +703,10 @@ router.post(
|
|
|
687
703
|
const file = await File.findOne(page.html_file);
|
|
688
704
|
if (!file) throw new Error(req.__("File not found"));
|
|
689
705
|
await fsp.writeFile(file.location, req.body.code);
|
|
706
|
+
Trigger.emitEvent("AppChange", `Page ${page.name}`, req.user, {
|
|
707
|
+
entity_type: "Page",
|
|
708
|
+
entity_name: page.name,
|
|
709
|
+
});
|
|
690
710
|
if (!req.xhr) {
|
|
691
711
|
req.flash("success", req.__(`Page %s saved`, pagename));
|
|
692
712
|
res.redirect(redirectTarget);
|
|
@@ -723,6 +743,11 @@ router.post(
|
|
|
723
743
|
|
|
724
744
|
if (id && req.body.layout) {
|
|
725
745
|
await Page.update(+id, { layout: req.body.layout });
|
|
746
|
+
const page = await Page.findOne({ id });
|
|
747
|
+
Trigger.emitEvent("AppChange", `Page ${page.name}`, req.user, {
|
|
748
|
+
entity_type: "Page",
|
|
749
|
+
entity_name: page.name,
|
|
750
|
+
});
|
|
726
751
|
res.json({
|
|
727
752
|
success: "ok",
|
|
728
753
|
});
|
|
@@ -744,6 +769,10 @@ router.post(
|
|
|
744
769
|
error_catcher(async (req, res) => {
|
|
745
770
|
const { id } = req.params;
|
|
746
771
|
const page = await Page.findOne({ id });
|
|
772
|
+
Trigger.emitEvent("AppChange", `Page ${page.name}`, req.user, {
|
|
773
|
+
entity_type: "Page",
|
|
774
|
+
entity_name: page.name,
|
|
775
|
+
});
|
|
747
776
|
await page.delete();
|
|
748
777
|
req.flash("success", req.__(`Page deleted`));
|
|
749
778
|
res.redirect(`/pageedit`);
|
|
@@ -796,6 +825,7 @@ router.post(
|
|
|
796
825
|
min_role: page.min_role,
|
|
797
826
|
pagename: page.name,
|
|
798
827
|
});
|
|
828
|
+
Trigger.emitEvent("AppChange", `Menu`, req.user, {});
|
|
799
829
|
req.flash(
|
|
800
830
|
"success",
|
|
801
831
|
req.__(
|
|
@@ -820,6 +850,10 @@ router.post(
|
|
|
820
850
|
const { id } = req.params;
|
|
821
851
|
const page = await Page.findOne({ id });
|
|
822
852
|
const newpage = await page.clone();
|
|
853
|
+
Trigger.emitEvent("AppChange", `Page ${newpage.name}`, req.user, {
|
|
854
|
+
entity_type: "Page",
|
|
855
|
+
entity_name: newpage.name,
|
|
856
|
+
});
|
|
823
857
|
req.flash(
|
|
824
858
|
"success",
|
|
825
859
|
req.__("Page %s duplicated as %s", page.name, newpage.name)
|
package/routes/tables.js
CHANGED
package/routes/utils.js
CHANGED
|
@@ -23,6 +23,7 @@ const Crash = require("@saltcorn/data/models/crash");
|
|
|
23
23
|
const File = require("@saltcorn/data/models/file");
|
|
24
24
|
const User = require("@saltcorn/data/models/user");
|
|
25
25
|
const Page = require("@saltcorn/data/models/page");
|
|
26
|
+
const Trigger = require("@saltcorn/data/models/trigger");
|
|
26
27
|
const si = require("systeminformation");
|
|
27
28
|
const {
|
|
28
29
|
config_fields_form,
|
|
@@ -426,6 +427,9 @@ const admin_config_route = ({
|
|
|
426
427
|
const restart_required = check_if_restart_required(form, req);
|
|
427
428
|
|
|
428
429
|
await save_config_from_form(form);
|
|
430
|
+
Trigger.emitEvent("AppChange", `Config`, req.user, {
|
|
431
|
+
config_keys: Object.keys(form.values),
|
|
432
|
+
});
|
|
429
433
|
if (!req.xhr) {
|
|
430
434
|
if (restart_required) {
|
|
431
435
|
flash_restart(req);
|
package/routes/view.js
CHANGED
|
@@ -139,18 +139,20 @@ router.get(
|
|
|
139
139
|
: contents0;
|
|
140
140
|
res.sendWrap(
|
|
141
141
|
title,
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
142
|
+
!req.smr
|
|
143
|
+
? add_edit_bar({
|
|
144
|
+
role,
|
|
145
|
+
title: view.name,
|
|
146
|
+
what: req.__("View"),
|
|
147
|
+
url: `/viewedit/edit/${encodeURIComponent(view.name)}`,
|
|
148
|
+
cfgUrl: `/viewedit/config/${encodeURIComponent(view.name)}`,
|
|
149
|
+
contents,
|
|
150
|
+
req,
|
|
151
|
+
view,
|
|
152
|
+
viewtemplate: view.viewtemplate,
|
|
153
|
+
table: view.table_id || view.exttable_name,
|
|
154
|
+
})
|
|
155
|
+
: contents
|
|
154
156
|
);
|
|
155
157
|
}
|
|
156
158
|
})
|
package/routes/viewedit.js
CHANGED
|
@@ -27,6 +27,7 @@ const Table = require("@saltcorn/data/models/table");
|
|
|
27
27
|
const View = require("@saltcorn/data/models/view");
|
|
28
28
|
const Workflow = require("@saltcorn/data/models/workflow");
|
|
29
29
|
const User = require("@saltcorn/data/models/user");
|
|
30
|
+
const Trigger = require("@saltcorn/data/models/trigger");
|
|
30
31
|
const Page = require("@saltcorn/data/models/page");
|
|
31
32
|
const File = require("@saltcorn/data/models/file");
|
|
32
33
|
const Tag = require("@saltcorn/data/models/tag");
|
|
@@ -551,6 +552,10 @@ router.post(
|
|
|
551
552
|
//console.log(v);
|
|
552
553
|
await View.create(v);
|
|
553
554
|
}
|
|
555
|
+
Trigger.emitEvent("AppChange", `View ${v.name}`, req.user, {
|
|
556
|
+
entity_type: "View",
|
|
557
|
+
entity_name: v.name,
|
|
558
|
+
});
|
|
554
559
|
if (req.xhr) res.json({ success: "ok" });
|
|
555
560
|
else
|
|
556
561
|
res.redirect(
|
|
@@ -733,6 +738,10 @@ router.post(
|
|
|
733
738
|
};
|
|
734
739
|
else newcfg = { ...view.configuration, ...context };
|
|
735
740
|
await View.update({ configuration: newcfg }, view.id);
|
|
741
|
+
Trigger.emitEvent("AppChange", `View ${view.name}`, req.user, {
|
|
742
|
+
entity_type: "View",
|
|
743
|
+
entity_name: view.name,
|
|
744
|
+
});
|
|
736
745
|
};
|
|
737
746
|
const wfres = await configFlow.run(req.body, req);
|
|
738
747
|
|
|
@@ -761,6 +770,7 @@ router.post(
|
|
|
761
770
|
min_role: view.min_role,
|
|
762
771
|
viewname: view.name,
|
|
763
772
|
});
|
|
773
|
+
Trigger.emitEvent("AppChange", `Menu`, req.user, {});
|
|
764
774
|
req.flash(
|
|
765
775
|
"success",
|
|
766
776
|
req.__(
|
|
@@ -790,6 +800,10 @@ router.post(
|
|
|
790
800
|
const { id } = req.params;
|
|
791
801
|
const view = await View.findOne({ id });
|
|
792
802
|
const newview = await view.clone();
|
|
803
|
+
Trigger.emitEvent("AppChange", `View ${newview.name}`, req.user, {
|
|
804
|
+
entity_type: "View",
|
|
805
|
+
entity_name: newview.name,
|
|
806
|
+
});
|
|
793
807
|
req.flash(
|
|
794
808
|
"success",
|
|
795
809
|
req.__("View %s duplicated as %s", view.name, newview.name)
|
|
@@ -841,6 +855,10 @@ router.post(
|
|
|
841
855
|
const exview = await View.findOne({ id });
|
|
842
856
|
let newcfg = { ...exview.configuration, ...req.body };
|
|
843
857
|
await View.update({ configuration: newcfg }, +id);
|
|
858
|
+
Trigger.emitEvent("AppChange", `View ${exview.name}`, req.user, {
|
|
859
|
+
entity_type: "View",
|
|
860
|
+
entity_name: exview.name,
|
|
861
|
+
});
|
|
844
862
|
res.json({ success: "ok" });
|
|
845
863
|
} else {
|
|
846
864
|
res.json({ error: req.__("Unable to save: No view") });
|
|
@@ -879,6 +897,10 @@ router.post(
|
|
|
879
897
|
};
|
|
880
898
|
else newcfg = { ...view.configuration, ...step.renderForm.values };
|
|
881
899
|
await View.update({ configuration: newcfg }, view.id);
|
|
900
|
+
Trigger.emitEvent("AppChange", `View ${view.name}`, req.user, {
|
|
901
|
+
entity_type: "View",
|
|
902
|
+
entity_name: view.name,
|
|
903
|
+
});
|
|
882
904
|
res.json({ success: "ok" });
|
|
883
905
|
} else {
|
|
884
906
|
res.json({ error: step.renderForm.errorSummary });
|
|
@@ -906,6 +928,10 @@ router.post(
|
|
|
906
928
|
const role = req.body.role;
|
|
907
929
|
await View.update({ min_role: role }, +id);
|
|
908
930
|
const view = await View.findOne({ id });
|
|
931
|
+
Trigger.emitEvent("AppChange", `View ${view.name}`, req.user, {
|
|
932
|
+
entity_type: "View",
|
|
933
|
+
entity_name: view.name,
|
|
934
|
+
});
|
|
909
935
|
const roles = await User.get_roles();
|
|
910
936
|
const roleRow = roles.find((r) => r.id === +role);
|
|
911
937
|
const message =
|
package/tests/clientjs.test.js
CHANGED
|
@@ -13,6 +13,13 @@ const load_script = (fnm) => {
|
|
|
13
13
|
document.body.appendChild(scriptEl);
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
+
class IntersectionObserver {
|
|
17
|
+
constructor() {}
|
|
18
|
+
observe() {}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
window.IntersectionObserver = IntersectionObserver;
|
|
22
|
+
|
|
16
23
|
load_script("jquery-3.6.0.min.js");
|
|
17
24
|
load_script("saltcorn-common.js");
|
|
18
25
|
load_script("saltcorn.js");
|
|
@@ -90,6 +97,21 @@ test("updateQueryStringParameter hash", () => {
|
|
|
90
97
|
"/foo?name=Bar#Baz"
|
|
91
98
|
);
|
|
92
99
|
});
|
|
100
|
+
test("addQueryStringParameter", () => {
|
|
101
|
+
expect(addQueryStringParameter("/foo", "age", 43)).toBe("/foo?age=43");
|
|
102
|
+
expect(addQueryStringParameter("/foo?age=43", "age", 44)).toBe(
|
|
103
|
+
"/foo?age=43&age=44"
|
|
104
|
+
);
|
|
105
|
+
expect(addQueryStringParameter("/foo?age=43", "age", 43)).toBe("/foo?age=43");
|
|
106
|
+
});
|
|
107
|
+
test("addQueryStringParameter hash", () => {
|
|
108
|
+
expect(addQueryStringParameter("/foo#baz", "age", 43)).toBe(
|
|
109
|
+
"/foo?age=43#baz"
|
|
110
|
+
);
|
|
111
|
+
expect(addQueryStringParameter("/foo?age=43#baz", "age", 44)).toBe(
|
|
112
|
+
"/foo?age=43&age=44#baz"
|
|
113
|
+
);
|
|
114
|
+
});
|
|
93
115
|
test("unique_field_from_rows test", () => {
|
|
94
116
|
$("body").append(`<input id="mkuniq6" value="bar"></div>`);
|
|
95
117
|
unique_field_from_rows(
|