@saltcorn/server 1.1.2-beta.14 → 1.1.2-beta.16

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saltcorn/server",
3
- "version": "1.1.2-beta.14",
3
+ "version": "1.1.2-beta.16",
4
4
  "description": "Server app for Saltcorn, open-source no-code platform",
5
5
  "homepage": "https://saltcorn.com",
6
6
  "main": "index.js",
@@ -8,14 +8,14 @@
8
8
  "dependencies": {
9
9
  "@aws-sdk/client-s3": "^3.735.0",
10
10
  "@dr.pogodin/csurf": "^1.14.1",
11
- "@saltcorn/base-plugin": "1.1.2-beta.14",
12
- "@saltcorn/builder": "1.1.2-beta.14",
13
- "@saltcorn/data": "1.1.2-beta.14",
14
- "@saltcorn/admin-models": "1.1.2-beta.14",
15
- "@saltcorn/filemanager": "1.1.2-beta.14",
16
- "@saltcorn/markup": "1.1.2-beta.14",
17
- "@saltcorn/plugins-loader": "1.1.2-beta.14",
18
- "@saltcorn/sbadmin2": "1.1.2-beta.14",
11
+ "@saltcorn/base-plugin": "1.1.2-beta.16",
12
+ "@saltcorn/builder": "1.1.2-beta.16",
13
+ "@saltcorn/data": "1.1.2-beta.16",
14
+ "@saltcorn/admin-models": "1.1.2-beta.16",
15
+ "@saltcorn/filemanager": "1.1.2-beta.16",
16
+ "@saltcorn/markup": "1.1.2-beta.16",
17
+ "@saltcorn/plugins-loader": "1.1.2-beta.16",
18
+ "@saltcorn/sbadmin2": "1.1.2-beta.16",
19
19
  "@socket.io/cluster-adapter": "^0.2.1",
20
20
  "@socket.io/sticky": "^1.0.1",
21
21
  "adm-zip": "0.5.16",
@@ -318,11 +318,11 @@ function apply_showif() {
318
318
  a.label === dynwhere.neutral_label
319
319
  ? -1
320
320
  : b.label === dynwhere.neutral_label
321
- ? 1
322
- : (a.label?.toLowerCase?.() || a.label) >
323
- (b.label?.toLowerCase?.() || b.label)
324
- ? 1
325
- : -1
321
+ ? 1
322
+ : (a.label?.toLowerCase?.() || a.label) >
323
+ (b.label?.toLowerCase?.() || b.label)
324
+ ? 1
325
+ : -1
326
326
  );
327
327
  if (!dynwhere.required)
328
328
  toAppend.unshift({ label: dynwhere.neutral_label || "", value: "" });
@@ -1120,8 +1120,8 @@ function initialize_page() {
1120
1120
  type === "Integer" || type === "Float"
1121
1121
  ? "number"
1122
1122
  : type === "Bool"
1123
- ? "checkbox"
1124
- : "text"
1123
+ ? "checkbox"
1124
+ : "text"
1125
1125
  }" ${
1126
1126
  type === "Float"
1127
1127
  ? `step="${
@@ -1490,10 +1490,10 @@ function buildToast(txt, type, spin) {
1490
1490
  realtype === "success"
1491
1491
  ? "fa-check-circle"
1492
1492
  : realtype === "danger"
1493
- ? "fa-times-circle"
1494
- : realtype === "warning"
1495
- ? "fa-exclamation-triangle"
1496
- : "";
1493
+ ? "fa-times-circle"
1494
+ : realtype === "warning"
1495
+ ? "fa-exclamation-triangle"
1496
+ : "";
1497
1497
  const isNode = getIsNode();
1498
1498
  const rndid = `tab${Math.floor(Math.random() * 16777215).toString(16)}`;
1499
1499
  return {
@@ -1587,7 +1587,11 @@ function press_store_button(clicked, keepOld, disable) {
1587
1587
  $(btn).data("old-text", oldText);
1588
1588
  }
1589
1589
  const width = $(btn).width();
1590
- $(btn).html('<i class="fas fa-spinner fa-spin"></i>').width(width);
1590
+ const height = $(btn).height();
1591
+ $(btn)
1592
+ .html('<i class="fas fa-spinner fa-spin"></i>')
1593
+ .width(width)
1594
+ .height(height);
1591
1595
  setTimeout(() => {
1592
1596
  $(btn).prop("disabled", true);
1593
1597
  }, 50);
@@ -1597,7 +1601,7 @@ function restore_old_button(btnId) {
1597
1601
  const btn = btnId instanceof jQuery ? btnId : $(`#${btnId}`);
1598
1602
  const oldText = $(btn).data("old-text");
1599
1603
  btn.html(oldText);
1600
- btn.css({ width: "" }).prop("disabled", false);
1604
+ btn.css({ width: "", height: "" }).prop("disabled", false);
1601
1605
  btn.removeData("old-text");
1602
1606
  }
1603
1607
 
@@ -2174,6 +2178,34 @@ function restrict_options(selector, restriction) {
2174
2178
  });
2175
2179
  }
2176
2180
 
2181
+ function handle_identical_fields(event) {
2182
+ let form = null;
2183
+ if (event.currentTarget.tagName === "FORM") form = event.currentTarget;
2184
+ else form = $(event.currentTarget).closest("form")[0];
2185
+ if (!form) {
2186
+ console.warn("No form found");
2187
+ } else {
2188
+ const name = event.target.name;
2189
+ const newValue = event.target.value;
2190
+ const tagName = event.target.tagName;
2191
+ const isRadio = event.target.type === "radio";
2192
+ if (tagName === "SELECT" || isRadio) {
2193
+ form.querySelectorAll(`select[name="${name}"]`).forEach((select) => {
2194
+ $(select).val(newValue); //.trigger("change");
2195
+ });
2196
+ form
2197
+ .querySelectorAll(`input[type="radio"][name="${name}"]`)
2198
+ .forEach((input) => {
2199
+ input.checked = input.value === newValue;
2200
+ });
2201
+ } else if (tagName === "INPUT") {
2202
+ form.querySelectorAll(`input[name="${name}"]`).forEach((input) => {
2203
+ input.value = newValue;
2204
+ });
2205
+ }
2206
+ }
2207
+ }
2208
+
2177
2209
  const observer = new IntersectionObserver(
2178
2210
  (entries, observer) => {
2179
2211
  entries.forEach((entry) => {
@@ -693,7 +693,7 @@ function ajax_post(url, args) {
693
693
  },
694
694
  ...(args || {}),
695
695
  })
696
- .done(ajax_done)
696
+ .done((res) => ajax_done(res))
697
697
  .fail((e, ...more) => {
698
698
  if (!checkNetworkError(e))
699
699
  return ajax_done(
@@ -1322,34 +1322,6 @@ function check_delete_unsaved(tablename, script_tag) {
1322
1322
  }
1323
1323
  }
1324
1324
 
1325
- function handle_identical_fields(event) {
1326
- let form = null;
1327
- if (event.currentTarget.tagName === "FORM") form = event.currentTarget;
1328
- else form = $(event.currentTarget).closest("form")[0];
1329
- if (!form) {
1330
- console.warn("No form found");
1331
- } else {
1332
- const name = event.target.name;
1333
- const newValue = event.target.value;
1334
- const tagName = event.target.tagName;
1335
- const isRadio = event.target.type === "radio";
1336
- if (tagName === "SELECT" || isRadio) {
1337
- form.querySelectorAll(`select[name="${name}"]`).forEach((select) => {
1338
- $(select).val(newValue); //.trigger("change");
1339
- });
1340
- form
1341
- .querySelectorAll(`input[type="radio"][name="${name}"]`)
1342
- .forEach((input) => {
1343
- input.checked = input.value === newValue;
1344
- });
1345
- } else if (tagName === "INPUT") {
1346
- form.querySelectorAll(`input[name="${name}"]`).forEach((input) => {
1347
- input.value = newValue;
1348
- });
1349
- }
1350
- }
1351
- }
1352
-
1353
1325
  (() => {
1354
1326
  const e = document.querySelector("[data-sidebar-toggler]");
1355
1327
  let closed = localStorage.getItem("sidebarClosed") === "true";
package/routes/actions.js CHANGED
@@ -15,10 +15,6 @@ const {
15
15
  const { ppVal, jsIdentifierValidator } = require("@saltcorn/data/utils");
16
16
  const { getState } = require("@saltcorn/data/db/state");
17
17
  const Trigger = require("@saltcorn/data/models/trigger");
18
- const View = require("@saltcorn/data/models/view");
19
- const {
20
- getForm,
21
- } = require("@saltcorn/data/base-plugin/viewtemplates/viewable_fields");
22
18
  const FieldRepeat = require("@saltcorn/data/models/fieldrepeat");
23
19
  const { getTriggerList } = require("./common_lists");
24
20
  const TagEntry = require("@saltcorn/data/models/tag_entry");
@@ -29,6 +25,9 @@ const Tag = require("@saltcorn/data/models/tag");
29
25
  const db = require("@saltcorn/data/db");
30
26
  const MarkdownIt = require("markdown-it"),
31
27
  md = new MarkdownIt();
28
+ const {
29
+ getWorkflowStepUserForm,
30
+ } = require("@saltcorn/data/web-mobile-commons");
32
31
 
33
32
  /**
34
33
  * @type {object}
@@ -1690,42 +1689,6 @@ router.post(
1690
1689
  })
1691
1690
  );
1692
1691
 
1693
- const getWorkflowStepUserForm = async (run, trigger, step, req) => {
1694
- if (step.action_name === "EditViewForm") {
1695
- const view = View.findOne({ name: step.configuration.edit_view });
1696
- const table = Table.findOne({ id: view.table_id });
1697
- const form = await getForm(
1698
- table,
1699
- view.name,
1700
- view.configuration.columns,
1701
- view.configuration.layout,
1702
- null,
1703
- req
1704
- );
1705
- await form.fill_fkey_options(false, undefined, req?.user);
1706
- form.action = `/actions/fill-workflow-form/${run.id}`;
1707
- if (run.context[step.configuration.response_variable])
1708
- Object.assign(
1709
- form.values,
1710
- run.context[step.configuration.response_variable]
1711
- );
1712
-
1713
- return form;
1714
- }
1715
-
1716
- let blurb = run.wait_info.output || step.configuration?.form_header || "";
1717
- if (run.wait_info.markdown && run.wait_info.output) blurb = md.render(blurb);
1718
- const form = new Form({
1719
- action: `/actions/fill-workflow-form/${run.id}`,
1720
- submitLabel: run.wait_info.output ? req.__("OK") : req.__("Submit"),
1721
- onSubmit: "press_store_button(this)",
1722
- blurb,
1723
- formStyle: run.wait_info.output || req.xhr ? "vert" : undefined,
1724
- fields: await run.userFormFields(step),
1725
- });
1726
- return form;
1727
- };
1728
-
1729
1692
  router.get(
1730
1693
  "/fill-workflow-form/:id",
1731
1694
  error_catcher(async (req, res) => {
package/routes/admin.js CHANGED
@@ -236,6 +236,7 @@ admin_config_route({
236
236
  id: "testemail",
237
237
  href: "/admin/send-test-email",
238
238
  class: "btn btn-primary",
239
+ onclick: "spin_action_link(this)",
239
240
  },
240
241
  req.__("Send test email")
241
242
  ),
@@ -262,12 +263,14 @@ router.get(
262
263
  html: req.__("Hello from Saltcorn"),
263
264
  };
264
265
  try {
265
- await getMailTransport().sendMail(email);
266
+ const sendres = await getMailTransport().sendMail(email);
267
+ getState().log(6, sendres);
266
268
  req.flash(
267
269
  "success",
268
270
  req.__("Email sent to %s with no errors", req.user.email)
269
271
  );
270
272
  } catch (e) {
273
+ console.error(e);
271
274
  req.flash("error", e.message);
272
275
  }
273
276
 
@@ -384,6 +387,7 @@ router.get(
384
387
  req.csrfToken(),
385
388
  {
386
389
  btnClass: "btn-outline-primary",
390
+ spinner: true,
387
391
  }
388
392
  )
389
393
  ),
@@ -837,7 +841,7 @@ const autoBackupForm = (req) => {
837
841
  label: req.__("Backup now"),
838
842
  id: "btnBackupNow",
839
843
  class: "btn btn-outline-secondary",
840
- onclick: "ajax_post('/admin/auto-backup-now')",
844
+ onclick: "ajax_post('/admin/auto-backup-now');press_store_button(this);",
841
845
  },
842
846
  ],
843
847
  fields: [
package/routes/tables.js CHANGED
@@ -868,7 +868,7 @@ router.get(
868
868
  div(
869
869
  { class: "alert alert-danger", role: "alert" },
870
870
  i({ class: "fas fa-exclamation-triangle" }),
871
- "This table has composite primary keys, or a non-incrementing integer primary key, which are not supported in Saltcorn. A procedure to introduce a single autoincrementing primary key is available.",
871
+ "This table has composite or non-defaulted primary keys, which are not supported in Saltcorn. A procedure to introduce a single autoincrementing primary key is available.",
872
872
  post_btn(
873
873
  `/table/repair-composite-primary/${table.id}`,
874
874
  "Add autoincrementing primary key",
@@ -472,6 +472,18 @@ describe("actions", () => {
472
472
  .set("Cookie", loginCookie)
473
473
  .expect(toRedirect("/actions/"));
474
474
  });
475
+ it("post Never trigger with table", async () => {
476
+ const app = await getApp({ disableCsrf: true });
477
+ const loginCookie = await getAdminLoginCookie();
478
+ await request(app)
479
+ .post("/actions/new")
480
+ .set("Cookie", loginCookie)
481
+ .send("action=run_js_code")
482
+ .send("table_id=2")
483
+ .send("name=NeverTableTrigger")
484
+ .send("when_trigger=Never")
485
+ .expect(302);
486
+ });
475
487
  });
476
488
  describe("localizer", () => {
477
489
  itShouldRedirectUnauthToLogin("/site-structure/localizer");