@saltcorn/server 0.8.0-beta.0 → 0.8.0-beta.1

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/locales/en.json CHANGED
@@ -960,7 +960,7 @@
960
960
  "Remove From Tag": "Remove From Tag",
961
961
  "Add tables": "Add tables",
962
962
  "Add views": "Add views",
963
- "Add tages": "Add tages",
963
+ "Add tags": "Add tags",
964
964
  "Trigger": "Trigger",
965
965
  "Add %s to tag": "Add %s to tag",
966
966
  "Tag %s deleted": "Tag %s deleted",
@@ -1035,5 +1035,17 @@
1035
1035
  "Provide your own create warning text if need": "Provide your own create warning text if need",
1036
1036
  "Specify some description for tenant if need": "Specify some description for tenant if need",
1037
1037
  "Created": "Created",
1038
- "First user E-mail": "First user E-mail"
1039
- }
1038
+ "First user E-mail": "First user E-mail",
1039
+ "HTTP settings": "HTTP settings",
1040
+ "HTTP": "HTTP",
1041
+ "Login and Signup": "Login and Signup",
1042
+ "Rights": "Rights",
1043
+ "Rights settings": "Rights settings",
1044
+ "Database name": "Database name",
1045
+ "Database schema": "Database schema",
1046
+ "<p>You have views with a role to access lower than the table role to read, \n with no table ownership. In the next version of Saltcorn, this may cause a\n denial of access. Users will need to have table read access to any data displayed.</p> \n Views potentially affected: %s": "<p>You have views with a role to access lower than the table role to read, \n with no table ownership. In the next version of Saltcorn, this may cause a\n denial of access. Users will need to have table read access to any data displayed.</p> \n Views potentially affected: %s",
1047
+ "If the parent row is deleted, do this to the child rows.": "If the parent row is deleted, do this to the child rows.",
1048
+ "On delete": "On delete",
1049
+ "Database name": "Database name",
1050
+ "Database schema": "Database schema"
1051
+ }
package/locales/it.json CHANGED
@@ -479,5 +479,10 @@
479
479
  "Two-factor authentication": "Two-factor authentication",
480
480
  "Two-factor authentication is disabled": "Two-factor authentication is disabled",
481
481
  "Enable TWA": "Enable TWA",
482
- "Modules": "Modules"
482
+ "Modules": "Modules",
483
+ "Login and Signup": "Login and Signup",
484
+ "Table access": "Table access",
485
+ "HTTP": "HTTP",
486
+ "Rights": "Rights",
487
+ "Table access": "Table access"
483
488
  }
package/locales/ru.json CHANGED
@@ -676,7 +676,7 @@
676
676
  "No triggers": "Нет триггеров",
677
677
  "No files": "Нет файлов",
678
678
  "Home Timezone": "Домашняя Timezone",
679
- "2FA policy": "2FA policy",
679
+ "2FA policy": "Политика 2FA",
680
680
  "Role to generate API keys": "Роль для API keys",
681
681
  "User should have this role or higher to generate API keys in their user settings": "Минимальная роль для генерации API key",
682
682
  "Cookie duration (hours)": "Срок действия Cookie (в часах)",
@@ -835,7 +835,7 @@
835
835
  "Add tables": "Добавить таблицы",
836
836
  "Add views": "Добавить представления",
837
837
  "Remove From Tag": "Удалить из тега",
838
- "Add tages": "Добавить теги",
838
+ "Add tags": "Добавить теги",
839
839
  "Trigger": "Триггер",
840
840
  "Tag": "Тег",
841
841
  "Download snapshots": "Скачать снепшоты",
@@ -898,7 +898,7 @@
898
898
  "Discover tables that are already in the Database, but not known to Saltcorn": "Обнаружить таблицы, уже созданные в Базе Данных, но пока не подключенные к Saltcorn",
899
899
  "Users already present": "Пользователи уже созданы",
900
900
  "Database type": "Тип БД",
901
- "Database name": "Database name",
901
+ "Database name": "Название БД",
902
902
  "Database host": "Хост БД",
903
903
  "Database port": "Порт БД",
904
904
  "Database schema": "Схема БД",
@@ -909,5 +909,15 @@
909
909
  "Development settings": "Настройки для разработчиков",
910
910
  "Creator email": "Email создателя",
911
911
  "Created": "Создано",
912
- "Views display data from tables. A view is a view pattern applied to a table, with configuration.": "Представления отображают данные из таблиц. Представление - это конфигурируемый визуальный паттерн, применяемый к таблице."
912
+ "Views display data from tables. A view is a view pattern applied to a table, with configuration.": "Представления отображают данные из таблиц. Представление - это конфигурируемый визуальный паттерн, применяемый к таблице.",
913
+ "HTTP settings": "Настройки HTTP",
914
+ "HTTP": "HTTP",
915
+ "Rights settings": "Настройки прав",
916
+ "Login and Signup": "Авторизация и Регистрация",
917
+ "Rights": "Права",
918
+ "<p>You have views with a role to access lower than the table role to read, \n with no table ownership. In the next version of Saltcorn, this may cause a\n denial of access. Users will need to have table read access to any data displayed.</p> \n Views potentially affected: %s": "<p>Найдены представления с ролью доступа ниже уровня роли для чтения из соответствующей таблицы, без указания владельца таблицы. В следующих версиях Saltcorn это может привести к запрету на доступ. Пользователи должны будут иметь права на чтение, чтобы данные были отображены. </p> \n Потенциально затронутые представления: %s</p>",
919
+ "File not found": "Файл не найден",
920
+ "Permissions settings": "Настройки разрешений",
921
+ "Permissions": "Разрешения",
922
+ "Permissions settings updated": "Настройки разрешений обновлены"
913
923
  }
package/markup/admin.js CHANGED
@@ -223,9 +223,11 @@ const send_users_page = (args) => {
223
223
  sub_sections: [
224
224
  { text: "Users", href: "/useradmin" },
225
225
  { text: "Roles", href: "/roleadmin" },
226
- { text: "Settings", href: "/useradmin/settings" },
226
+ { text: "Login and Signup", href: "/useradmin/settings" },
227
227
  { text: "Table access", href: "/useradmin/table-access" },
228
228
  ...(isRoot ? [{ text: "SSL", href: "/useradmin/ssl" }] : []),
229
+ { text: "HTTP", href: "/useradmin/http" },
230
+ { text: "Permissions", href: "/useradmin/permissions" },
229
231
  ],
230
232
  ...args,
231
233
  });
@@ -282,7 +284,7 @@ const send_events_page = (args) => {
282
284
  * @returns {void}
283
285
  */
284
286
  const send_admin_page = (args) => {
285
- const isRoot = db.getTenantSchema() === db.connectObj.default_schema;
287
+ //const isRoot = db.getTenantSchema() === db.connectObj.default_schema;
286
288
  return send_settings_page({
287
289
  main_section: "About application",
288
290
  main_section_href: "/admin",
@@ -436,7 +438,7 @@ const save_config_from_form = async (form) => {
436
438
 
437
439
  /**
438
440
  * Get Base Domain
439
- * @returns {string} base domain
441
+ * @returns {string|null} base domain
440
442
  */
441
443
  const getBaseDomain = () => {
442
444
  const base_url = getState().getConfig("base_url");
@@ -457,7 +459,7 @@ const hostname_matches_baseurl = (req, domain) => domain === req.hostname;
457
459
 
458
460
  /**
459
461
  * @param {string} domain
460
- * @returns {string[]}
462
+ * @returns {string[]|boolean}
461
463
  */
462
464
  const is_hsts_tld = (domain) => {
463
465
  if (!domain) return false;
package/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@saltcorn/server",
3
- "version": "0.8.0-beta.0",
3
+ "version": "0.8.0-beta.1",
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.8.0-beta.0",
10
- "@saltcorn/builder": "0.8.0-beta.0",
11
- "@saltcorn/data": "0.8.0-beta.0",
12
- "@saltcorn/admin-models": "0.8.0-beta.0",
13
- "@saltcorn/filemanager": "0.7.4",
14
- "@saltcorn/markup": "0.8.0-beta.0",
15
- "@saltcorn/sbadmin2": "0.8.0-beta.0",
9
+ "@saltcorn/base-plugin": "0.8.0-beta.1",
10
+ "@saltcorn/builder": "0.8.0-beta.1",
11
+ "@saltcorn/data": "0.8.0-beta.1",
12
+ "@saltcorn/admin-models": "0.8.0-beta.1",
13
+ "@saltcorn/filemanager": "0.8.0-beta.1",
14
+ "@saltcorn/markup": "0.8.0-beta.1",
15
+ "@saltcorn/sbadmin2": "0.8.0-beta.1",
16
16
  "@socket.io/cluster-adapter": "^0.1.0",
17
17
  "@socket.io/sticky": "^1.0.1",
18
18
  "aws-sdk": "^2.1037.0",
package/public/blockly.js CHANGED
@@ -1,3 +1,4 @@
1
+ // todo replace var with let / const
1
2
  function activate_blockly({ events, actions, tables }) {
2
3
  // https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#arpfmx
3
4
 
@@ -21,8 +22,7 @@ function activate_blockly({ events, actions, tables }) {
21
22
  Blockly.JavaScript.ORDER_ATOMIC
22
23
  );
23
24
  // TODO: Assemble JavaScript into code variable.
24
- var code = `console.log(${value_string});\n`;
25
- return code;
25
+ return `console.log(${value_string});\n`;
26
26
  };
27
27
 
28
28
  Blockly.Blocks["emit_event"] = {
@@ -58,9 +58,7 @@ function activate_blockly({ events, actions, tables }) {
58
58
  Blockly.JavaScript.ORDER_ATOMIC
59
59
  );
60
60
  // TODO: Assemble JavaScript into code variable.
61
- var code = `emitEvent("${dropdown_event}", ${value_channel}, ${value_payload});\n`;
62
-
63
- return code;
61
+ return `emitEvent("${dropdown_event}", ${value_channel}, ${value_payload});\n`;
64
62
  };
65
63
 
66
64
  Blockly.Blocks["row"] = {
@@ -75,7 +73,7 @@ function activate_blockly({ events, actions, tables }) {
75
73
 
76
74
  Blockly.JavaScript["row"] = function (block) {
77
75
  // TODO: Assemble JavaScript into code variable.
78
- var code = "row";
76
+ const code = "row";
79
77
  // TODO: Change ORDER_NONE to the correct strength.
80
78
  return [code, Blockly.JavaScript.ORDER_NONE];
81
79
  };
@@ -91,7 +89,7 @@ function activate_blockly({ events, actions, tables }) {
91
89
  };
92
90
  Blockly.JavaScript["current_channel"] = function (block) {
93
91
  // TODO: Assemble JavaScript into code variable.
94
- var code = "channel";
92
+ const code = "channel";
95
93
  // TODO: Change ORDER_NONE to the correct strength.
96
94
  return [code, Blockly.JavaScript.ORDER_NONE];
97
95
  };
@@ -106,7 +104,7 @@ function activate_blockly({ events, actions, tables }) {
106
104
  };
107
105
  Blockly.JavaScript["empty"] = function (block) {
108
106
  // TODO: Assemble JavaScript into code variable.
109
- var code = "{}";
107
+ const code = "{}";
110
108
  // TODO: Change ORDER_NONE to the correct strength.
111
109
  return [code, Blockly.JavaScript.ORDER_NONE];
112
110
  };
@@ -170,8 +168,7 @@ function activate_blockly({ events, actions, tables }) {
170
168
  Blockly.JavaScript.ORDER_ATOMIC
171
169
  );
172
170
  // TODO: Assemble JavaScript into code variable.
173
- var code = `${value_row}.${text_key}=${value_value};\n`;
174
- return code;
171
+ return `${value_row}.${text_key}=${value_value};\n`;
175
172
  };
176
173
  Blockly.Blocks["insert_table"] = {
177
174
  init: function () {
@@ -196,8 +193,7 @@ function activate_blockly({ events, actions, tables }) {
196
193
  Blockly.JavaScript.ORDER_ATOMIC
197
194
  );
198
195
  // TODO: Assemble JavaScript into code variable.
199
- var code = `await Table.findOne({name: '${dropdown_table}'})\n .tryInsertRow(${value_row});\n`;
200
- return code;
196
+ return `await Table.findOne({name: '${dropdown_table}'})\n .tryInsertRow(${value_row});\n`;
201
197
  };
202
198
  Blockly.Blocks["query_table"] = {
203
199
  init: function () {
@@ -281,8 +277,7 @@ function activate_blockly({ events, actions, tables }) {
281
277
  Blockly.JavaScript.ORDER_ATOMIC
282
278
  );
283
279
  // TODO: Assemble JavaScript into code variable.
284
- var code = `await Table.findOne({name: '${dropdown_table}'})\n .deleteRows({id: ${value_id}});\n`;
285
- return code;
280
+ return `await Table.findOne({name: '${dropdown_table}'})\n .deleteRows({id: ${value_id}});\n`;
286
281
  };
287
282
 
288
283
  Blockly.Blocks["delete_table_where"] = {
@@ -309,9 +304,7 @@ function activate_blockly({ events, actions, tables }) {
309
304
  Blockly.JavaScript.ORDER_ATOMIC
310
305
  );
311
306
  // TODO: Assemble JavaScript into code variable.
312
- var code = `await Table.findOne({name: '${dropdown_table}'})\n .deleteRows(${value_where});\n`;
313
-
314
- return code;
307
+ return `await Table.findOne({name: '${dropdown_table}'})\n .deleteRows(${value_where});\n`;
315
308
  };
316
309
  Blockly.Blocks["update_table"] = {
317
310
  init: function () {
@@ -342,8 +335,7 @@ function activate_blockly({ events, actions, tables }) {
342
335
  Blockly.JavaScript.ORDER_ATOMIC
343
336
  );
344
337
  // TODO: Assemble JavaScript into code variable.
345
- var code = `await Table.findOne({name: '${dropdown_table}'})\n .tryUpdateRow(${value_row}, ${value_id});\n`;
346
- return code;
338
+ return `await Table.findOne({name: '${dropdown_table}'})\n .tryUpdateRow(${value_row}, ${value_id});\n`;
347
339
  };
348
340
 
349
341
  Blockly.Blocks["sleep"] = {
@@ -363,10 +355,9 @@ function activate_blockly({ events, actions, tables }) {
363
355
  },
364
356
  };
365
357
  Blockly.JavaScript["sleep"] = function (block) {
366
- var number_sleep_ms = block.getFieldValue("SLEEP_MS");
358
+ const number_sleep_ms = block.getFieldValue("SLEEP_MS");
367
359
  // TODO: Assemble JavaScript into code variable.
368
- var code = `await sleep(${number_sleep_ms});\n`;
369
- return code;
360
+ return `await sleep(${number_sleep_ms});\n`;
370
361
  };
371
362
 
372
363
  Blockly.Blocks["http_request"] = {
@@ -439,7 +430,7 @@ function activate_blockly({ events, actions, tables }) {
439
430
  "POPUP",
440
431
  Blockly.JavaScript.ORDER_ATOMIC
441
432
  );
442
- var checkbox_reload = block.getFieldValue("RELOAD") == "TRUE";
433
+ var checkbox_reload = block.getFieldValue("RELOAD") === "TRUE";
443
434
  var value_notify = Blockly.JavaScript.valueToCode(
444
435
  block,
445
436
  "NOTIFY",
@@ -451,8 +442,7 @@ function activate_blockly({ events, actions, tables }) {
451
442
  if (value_popup) s += `popup: ${value_popup},`;
452
443
  if (value_notify) s += `notify: ${value_notify},`;
453
444
  if (checkbox_reload) s += `reload_page: true,`;
454
- var code = `return {${s}};\n`;
455
- return code;
445
+ return `return {${s}};\n`;
456
446
  };
457
447
  Blockly.Blocks["push_to_list"] = {
458
448
  init: function () {
@@ -480,8 +470,7 @@ function activate_blockly({ events, actions, tables }) {
480
470
  Blockly.JavaScript.ORDER_ATOMIC
481
471
  );
482
472
  // TODO: Assemble JavaScript into code variable.
483
- var code = `${value_list}.push(${value_name});\n`;
484
- return code;
473
+ return `${value_list}.push(${value_name});\n`;
485
474
  };
486
475
  if (actions.length > 0) {
487
476
  Blockly.Blocks["action"] = {
@@ -501,12 +490,11 @@ function activate_blockly({ events, actions, tables }) {
501
490
  };
502
491
 
503
492
  Blockly.JavaScript["action"] = function (block) {
504
- var dropdown_name = block.getFieldValue("NAME");
493
+ const dropdown_name = block.getFieldValue("NAME");
505
494
  // TODO: Assemble JavaScript into code variable.
506
- var code = dropdown_name.includes(" ")
495
+ return dropdown_name.includes(" ")
507
496
  ? `Actions['${dropdown_name}']();\n`
508
497
  : `Actions.${dropdown_name}();\n`;
509
- return code;
510
498
  };
511
499
  }
512
500
  Blockly.Blocks["unit_row"] = {
@@ -577,7 +565,7 @@ function activate_blockly({ events, actions, tables }) {
577
565
  $("#blocklyForm").submit();
578
566
  });
579
567
  function myUpdateFunction(event) {
580
- var code = Blockly.JavaScript.workspaceToCode(workspace);
568
+ const code = Blockly.JavaScript.workspaceToCode(workspace);
581
569
  $("#blockly_js_output").html(code);
582
570
  }
583
571
  workspace.addChangeListener(myUpdateFunction);
package/routes/actions.js CHANGED
@@ -8,7 +8,6 @@ const Router = require("express-promise-router");
8
8
  const {
9
9
  isAdmin,
10
10
  error_catcher,
11
- get_base_url,
12
11
  addOnDoneRedirect,
13
12
  } = require("./utils.js");
14
13
  const { getState } = require("@saltcorn/data/db/state");
@@ -25,17 +24,9 @@ const { getTriggerList } = require("./common_lists");
25
24
  const router = new Router();
26
25
  module.exports = router;
27
26
  const {
28
- mkTable,
29
27
  renderForm,
30
28
  link,
31
- // post_btn,
32
- // settingsDropdown,
33
- // post_dropdown_item,
34
- post_delete_btn,
35
- localeDateTime,
36
- // localeDateTime,
37
29
  } = require("@saltcorn/markup");
38
- const actions = require("@saltcorn/data/base-plugin/actions");
39
30
  const Form = require("@saltcorn/data/models/form");
40
31
  const {
41
32
  div,
@@ -52,14 +43,11 @@ const {
52
43
  h6,
53
44
  pre,
54
45
  text,
55
- hr,
56
46
  } = require("@saltcorn/markup/tags");
57
47
  const Table = require("@saltcorn/data/models/table");
58
48
  const { getActionConfigFields } = require("@saltcorn/data/plugin-helper");
59
49
  const { send_events_page } = require("../markup/admin.js");
60
- const EventLog = require("@saltcorn/data/models/eventlog");
61
50
  const User = require("@saltcorn/data/models/user");
62
- const form = require("@saltcorn/markup/form");
63
51
  const {
64
52
  blocklyImportScripts,
65
53
  blocklyToolbox,
@@ -587,7 +575,7 @@ router.get(
587
575
  };
588
576
  let table, row;
589
577
  if (trigger.table_id) {
590
- table = await Table.findOne(trigger.table_id);
578
+ table = await Table.findOne( { id: trigger.table_id } );
591
579
  row = await table.getRow({});
592
580
  }
593
581
  try {
package/routes/delete.js CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  const Router = require("express-promise-router");
8
8
 
9
- const { loggedIn, error_catcher } = require("./utils.js");
9
+ const { error_catcher } = require("./utils.js");
10
10
  const Table = require("@saltcorn/data/models/table");
11
11
 
12
12
  /**
@@ -28,17 +28,18 @@ module.exports = router;
28
28
  * @function
29
29
  */
30
30
  router.post(
31
- "/:name/:id",
31
+ "/:tableName/:id",
32
32
  error_catcher(async (req, res) => {
33
- const { name, id } = req.params;
33
+ const { tableName, id } = req.params;
34
34
  const { redirect } = req.query;
35
- const table = await Table.findOne({ name });
35
+ // todo check that works after where change
36
+ const table = await Table.findOne({ name : tableName });
36
37
  const role = req.user && req.user.id ? req.user.role_id : 10;
37
38
  try {
38
39
  if (role <= table.min_role_write) await table.deleteRows({ id });
39
40
  else if (table.ownership_field_id && req.user) {
40
41
  const row = await table.getRow({ id });
41
- if (row && (await table.is_owner(req.user, row)))
42
+ if (row && (table.is_owner(req.user, row)))
42
43
  await table.deleteRows({ id });
43
44
  else req.flash("error", req.__("Not authorized"));
44
45
  } else
package/routes/edit.js CHANGED
@@ -6,14 +6,8 @@
6
6
 
7
7
  const Router = require("express-promise-router");
8
8
 
9
- const Field = require("@saltcorn/data/models/field");
10
- const File = require("@saltcorn/data/models/file");
11
- const Form = require("@saltcorn/data/models/form");
12
- const { loggedIn, error_catcher } = require("./utils.js");
9
+ const { error_catcher } = require("./utils.js");
13
10
  const Table = require("@saltcorn/data/models/table");
14
- const pluralize = require("pluralize");
15
-
16
- const { renderForm } = require("@saltcorn/markup");
17
11
 
18
12
  /**
19
13
  * @type {object}
@@ -32,11 +26,12 @@ module.exports = router;
32
26
  * @function
33
27
  */
34
28
  router.post(
35
- "/toggle/:name/:id/:field_name",
29
+ "/toggle/:tableName/:id/:field_name",
36
30
  error_catcher(async (req, res) => {
37
- const { name, id, field_name } = req.params;
31
+ const { tableName, id, field_name } = req.params;
38
32
  const { redirect } = req.query;
39
- const table = await Table.findOne({ name });
33
+ // todo check that works after where change
34
+ const table = await Table.findOne({ name : tableName });
40
35
  const role = req.user && req.user.id ? req.user.role_id : 10;
41
36
  if (role <= table.min_role_write) await table.toggleBool(+id, field_name);
42
37
  else
package/routes/fields.js CHANGED
@@ -25,7 +25,10 @@ const db = require("@saltcorn/data/db");
25
25
 
26
26
  const { isAdmin, error_catcher } = require("./utils.js");
27
27
  const expressionBlurb = require("../markup/expression_blurb");
28
- const { readState, add_free_variables_to_joinfields } = require("@saltcorn/data/plugin-helper");
28
+ const {
29
+ readState,
30
+ add_free_variables_to_joinfields,
31
+ } = require("@saltcorn/data/plugin-helper");
29
32
  const { wizardCardTitle } = require("../markup/forms.js");
30
33
  const FieldRepeat = require("@saltcorn/data/models/fieldrepeat");
31
34
  const { applyAsync } = require("@saltcorn/data/utils");
@@ -185,6 +188,7 @@ const fieldFlow = (req) =>
185
188
  attributes.summary_field = context.summary_field;
186
189
  attributes.include_fts = context.include_fts;
187
190
  attributes.on_delete_cascade = context.on_delete_cascade;
191
+ attributes.on_delete = context.on_delete;
188
192
  const {
189
193
  table_id,
190
194
  name,
@@ -350,12 +354,13 @@ const fieldFlow = (req) =>
350
354
  // todo sublabel
351
355
  input_type: "custom_html",
352
356
  attributes: {
353
- html: `<button type="button" id="test_formula_btn" onclick="test_formula('${table.name
354
- }', ${JSON.stringify(
355
- context.stored
356
- )})" class="btn btn-outline-secondary">${req.__(
357
- "Test"
358
- )}</button>
357
+ html: `<button type="button" id="test_formula_btn" onclick="test_formula('${
358
+ table.name
359
+ }', ${JSON.stringify(
360
+ context.stored
361
+ )})" class="btn btn-outline-secondary">${req.__(
362
+ "Test"
363
+ )}</button>
359
364
  <div id="test_formula_output"></div>`,
360
365
  },
361
366
  }),
@@ -400,13 +405,32 @@ const fieldFlow = (req) =>
400
405
  type: "Bool",
401
406
  showIf: { summary_field: textfields },
402
407
  }),
403
- new Field({
408
+ /*new Field({
404
409
  name: "on_delete_cascade",
405
410
  label: req.__("On delete cascade"),
406
411
  type: "Bool",
407
412
  sublabel: req.__(
408
413
  "If the parent row is deleted, automatically delete the child rows."
409
414
  ),
415
+ }),*/
416
+ new Field({
417
+ name: "on_delete",
418
+ label: req.__("On delete"),
419
+ input_type: "select",
420
+ options: ["Fail", "Cascade", "Set null"],
421
+ required: true,
422
+ attributes: {
423
+ explainers: {
424
+ Fail: "Prevent any deletion of parent rows",
425
+ Cascade:
426
+ "If the parent row is deleted, automatically delete the child rows.",
427
+ "Set null":
428
+ "If the parent row is deleted, set key fields on child rows to null",
429
+ },
430
+ },
431
+ sublabel: req.__(
432
+ "If the parent row is deleted, do this to the child rows."
433
+ ),
410
434
  }),
411
435
  ],
412
436
  });
@@ -622,14 +646,17 @@ router.post(
622
646
  const { formula, tablename, stored } = req.body;
623
647
  const table = await Table.findOne({ name: tablename });
624
648
  const fields = await table.getFields();
625
- const freeVars = freeVariables(formula)
626
- const joinFields = {}
627
- if (stored)
628
- add_free_variables_to_joinfields(freeVars, joinFields, fields)
629
- const rows = await table.getJoinedRows({ joinFields, orderBy: "RANDOM()", limit: 1 });
649
+ const freeVars = freeVariables(formula);
650
+ const joinFields = {};
651
+ if (stored) add_free_variables_to_joinfields(freeVars, joinFields, fields);
652
+ const rows = await table.getJoinedRows({
653
+ joinFields,
654
+ orderBy: "RANDOM()",
655
+ limit: 1,
656
+ });
630
657
  if (rows.length < 1) {
631
658
  res.send("No rows in table");
632
- return
659
+ return;
633
660
  }
634
661
  let result;
635
662
  try {
@@ -641,7 +668,8 @@ router.post(
641
668
  result = f(rows[0]);
642
669
  }
643
670
  res.send(
644
- `Result of running on row with id=${rows[0].id
671
+ `Result of running on row with id=${
672
+ rows[0].id
645
673
  } is: <pre>${JSON.stringify(result)}</pre>`
646
674
  );
647
675
  } catch (e) {
@@ -671,10 +699,9 @@ router.post(
671
699
  const fields = await table.getFields();
672
700
  let row = { ...req.body };
673
701
  if (!row || Object.keys(row).length === 0) {
674
- const { id } = req.query
675
- if (id) row = await table.getRow({ id })
676
- } else
677
- readState(row, fields);
702
+ const { id } = req.query;
703
+ if (id) row = await table.getRow({ id });
704
+ } else readState(row, fields);
678
705
 
679
706
  if (fieldName.includes(".")) {
680
707
  //join field
@@ -694,12 +721,18 @@ router.post(
694
721
  const refRow = await reftable.getRow(q);
695
722
  let fv;
696
723
  if (targetField.type === "Key") {
697
- fv = getState().keyFieldviews[fieldview]
724
+ fv = getState().keyFieldviews[fieldview];
698
725
  if (!fv) {
699
- const reftable2 = Table.findOne({ name: targetField.reftable_name })
700
- const refRow2 = await reftable2.getRow({ [reftable2.pk_name]: refRow[kpath[1]] })
726
+ const reftable2 = Table.findOne({
727
+ name: targetField.reftable_name,
728
+ });
729
+ const refRow2 = await reftable2.getRow({
730
+ [reftable2.pk_name]: refRow[kpath[1]],
731
+ });
701
732
  if (refRow2) {
702
- res.send(text(`${refRow2[targetField.attributes.summary_field]}`));
733
+ res.send(
734
+ text(`${refRow2[targetField.attributes.summary_field]}`)
735
+ );
703
736
  } else {
704
737
  res.send("");
705
738
  }
@@ -711,7 +744,6 @@ router.post(
711
744
  fv =
712
745
  targetField.type.fieldviews.show ||
713
746
  targetField.type.fieldviews.as_text;
714
-
715
747
  }
716
748
 
717
749
  const configuration = req.query;
@@ -756,7 +788,7 @@ router.post(
756
788
  let result;
757
789
  try {
758
790
  if (!field.calculated) {
759
- result = row[field.name]
791
+ result = row[field.name];
760
792
  } else if (field.stored) {
761
793
  const f = get_async_expression_function(formula, fields);
762
794
  result = await f(row);
@@ -765,8 +797,7 @@ router.post(
765
797
  result = f(row);
766
798
  }
767
799
  const fv = field.type.fieldviews[fieldview];
768
- if (!fv)
769
- res.send(text(result));
800
+ if (!fv) res.send(text(result));
770
801
  else res.send(fv.run(result));
771
802
  } catch (e) {
772
803
  return res.status(400).send(`Error: ${e.message}`);
@@ -819,8 +850,8 @@ router.post(
819
850
  field.type === "Key"
820
851
  ? getState().keyFieldviews
821
852
  : field.type === "File"
822
- ? getState().fileviews
823
- : field.type.fieldviews;
853
+ ? getState().fileviews
854
+ : field.type.fieldviews;
824
855
  if (!field.type || !fieldviews) {
825
856
  res.send("");
826
857
  return;