@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.
@@ -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.__("Request fluid layout from theme for a wider display for this page"),
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
@@ -711,6 +711,7 @@ const attribBadges = (f) => {
711
711
  "table",
712
712
  "agg_field",
713
713
  "agg_relation",
714
+ "calc_joinfields"
714
715
  ].includes(k)
715
716
  )
716
717
  return;
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
- add_edit_bar({
143
- role,
144
- title: view.name,
145
- what: req.__("View"),
146
- url: `/viewedit/edit/${encodeURIComponent(view.name)}`,
147
- cfgUrl: `/viewedit/config/${encodeURIComponent(view.name)}`,
148
- contents,
149
- req,
150
- view,
151
- viewtemplate: view.viewtemplate,
152
- table: view.table_id || view.exttable_name,
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
  })
@@ -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 =
@@ -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(