@saltcorn/data 1.1.0-beta.13 → 1.1.0-beta.14

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.
Files changed (78) hide show
  1. package/dist/base-plugin/actions.d.ts +102 -9
  2. package/dist/base-plugin/actions.d.ts.map +1 -1
  3. package/dist/base-plugin/actions.js +181 -28
  4. package/dist/base-plugin/actions.js.map +1 -1
  5. package/dist/base-plugin/index.d.ts +123 -122
  6. package/dist/base-plugin/index.d.ts.map +1 -1
  7. package/dist/base-plugin/viewtemplates/edit.d.ts +4 -3
  8. package/dist/base-plugin/viewtemplates/edit.d.ts.map +1 -1
  9. package/dist/base-plugin/viewtemplates/edit.js +25 -4
  10. package/dist/base-plugin/viewtemplates/edit.js.map +1 -1
  11. package/dist/base-plugin/viewtemplates/viewable_fields.d.ts.map +1 -1
  12. package/dist/base-plugin/viewtemplates/viewable_fields.js +5 -1
  13. package/dist/base-plugin/viewtemplates/viewable_fields.js.map +1 -1
  14. package/dist/db/state.d.ts +1 -0
  15. package/dist/db/state.d.ts.map +1 -1
  16. package/dist/db/state.js +1 -0
  17. package/dist/db/state.js.map +1 -1
  18. package/dist/migrations/202412051957.d.ts +3 -0
  19. package/dist/migrations/202412051957.d.ts.map +1 -0
  20. package/dist/migrations/202412051957.js +48 -0
  21. package/dist/migrations/202412051957.js.map +1 -0
  22. package/dist/migrations/202412111526.d.ts +3 -0
  23. package/dist/migrations/202412111526.d.ts.map +1 -0
  24. package/dist/migrations/202412111526.js +38 -0
  25. package/dist/migrations/202412111526.js.map +1 -0
  26. package/dist/models/config.d.ts.map +1 -1
  27. package/dist/models/config.js +17 -7
  28. package/dist/models/config.js.map +1 -1
  29. package/dist/models/field.d.ts.map +1 -1
  30. package/dist/models/field.js +22 -4
  31. package/dist/models/field.js.map +1 -1
  32. package/dist/models/form.d.ts.map +1 -1
  33. package/dist/models/form.js +5 -1
  34. package/dist/models/form.js.map +1 -1
  35. package/dist/models/page.d.ts.map +1 -1
  36. package/dist/models/page.js +3 -1
  37. package/dist/models/page.js.map +1 -1
  38. package/dist/models/scheduler.d.ts.map +1 -1
  39. package/dist/models/scheduler.js +4 -0
  40. package/dist/models/scheduler.js.map +1 -1
  41. package/dist/models/table.d.ts +1 -0
  42. package/dist/models/table.d.ts.map +1 -1
  43. package/dist/models/table.js +18 -0
  44. package/dist/models/table.js.map +1 -1
  45. package/dist/models/trigger.d.ts +5 -1
  46. package/dist/models/trigger.d.ts.map +1 -1
  47. package/dist/models/trigger.js +38 -7
  48. package/dist/models/trigger.js.map +1 -1
  49. package/dist/models/workflow_run.d.ts +77 -0
  50. package/dist/models/workflow_run.d.ts.map +1 -0
  51. package/dist/models/workflow_run.js +342 -0
  52. package/dist/models/workflow_run.js.map +1 -0
  53. package/dist/models/workflow_step.d.ts +58 -0
  54. package/dist/models/workflow_step.d.ts.map +1 -0
  55. package/dist/models/workflow_step.js +144 -0
  56. package/dist/models/workflow_step.js.map +1 -0
  57. package/dist/models/workflow_trace.d.ts +57 -0
  58. package/dist/models/workflow_trace.d.ts.map +1 -0
  59. package/dist/models/workflow_trace.js +90 -0
  60. package/dist/models/workflow_trace.js.map +1 -0
  61. package/dist/plugin-helper.d.ts +0 -1
  62. package/dist/plugin-helper.d.ts.map +1 -1
  63. package/dist/plugin-helper.js +3 -2
  64. package/dist/plugin-helper.js.map +1 -1
  65. package/dist/tests/actions.test.js.map +1 -1
  66. package/dist/tests/field.test.js +47 -0
  67. package/dist/tests/field.test.js.map +1 -1
  68. package/dist/tests/workflow.test.js +3 -0
  69. package/dist/tests/workflow.test.js.map +1 -1
  70. package/dist/tests/workflow_run.test.d.ts +2 -0
  71. package/dist/tests/workflow_run.test.d.ts.map +1 -0
  72. package/dist/tests/workflow_run.test.js +109 -0
  73. package/dist/tests/workflow_run.test.js.map +1 -0
  74. package/dist/utils.d.ts +1 -0
  75. package/dist/utils.d.ts.map +1 -1
  76. package/dist/utils.js +9 -1
  77. package/dist/utils.js.map +1 -1
  78. package/package.json +8 -8
@@ -22,6 +22,7 @@ declare function run_code({ row, table, channel, configuration: { code, run_wher
22
22
  export namespace blocks {
23
23
  export const disableInBuilder: boolean;
24
24
  export const disableInList: boolean;
25
+ export const disableInWorkflow: boolean;
25
26
  export const description: string;
26
27
  export const configFields: {
27
28
  name: string;
@@ -73,8 +74,9 @@ export namespace emit_event {
73
74
  export namespace webhook {
74
75
  const description_2: string;
75
76
  export { description_2 as description };
76
- export function configFields_2({ table }: {
77
+ export function configFields_2({ table, mode }: {
77
78
  table: any;
79
+ mode: any;
78
80
  }): Promise<({
79
81
  name: string;
80
82
  label: string;
@@ -119,7 +121,7 @@ export namespace webhook {
119
121
  showIf?: undefined;
120
122
  })[]>;
121
123
  export { configFields_2 as configFields };
122
- export function run_1({ row, user, table, configuration: { url, body, authorization, response_field, method }, }: {
124
+ export function run_1({ row, user, table, configuration: { url, body, authorization, response_field, response_var, method, }, }: {
123
125
  url: string;
124
126
  body: object;
125
127
  }): Promise<object>;
@@ -149,9 +151,31 @@ export namespace find_or_create_dm_room {
149
151
  export namespace send_email {
150
152
  const description_4: string;
151
153
  export { description_4 as description };
152
- export function configFields_4({ table }: {
154
+ export function configFields_4({ table, mode }: {
153
155
  table: any;
156
+ mode: any;
154
157
  }): Promise<({
158
+ name: string;
159
+ label: string;
160
+ sublabel: string;
161
+ type: string;
162
+ required?: undefined;
163
+ fieldview?: undefined;
164
+ } | {
165
+ name: string;
166
+ label: string;
167
+ sublabel: string;
168
+ type: string;
169
+ required: boolean;
170
+ fieldview?: undefined;
171
+ } | {
172
+ name: string;
173
+ label: string;
174
+ type: string;
175
+ fieldview: string;
176
+ required: boolean;
177
+ sublabel?: undefined;
178
+ })[] | ({
155
179
  name: string;
156
180
  label: string;
157
181
  type: string;
@@ -316,7 +340,7 @@ export namespace send_email {
316
340
  })[]>;
317
341
  export { configFields_4 as configFields };
318
342
  export const requireRow: boolean;
319
- export function run_3({ row, table, configuration: { body_type, body_field, viewname, subject, subject_formula, to_email, to_email_field, to_email_fixed, cc_email, only_if, attachment_path, disable_notify, confirm_field, }, user, }: {
343
+ export function run_3({ row, table, configuration: { body_type, body_field, viewname, subject, subject_formula, to_email, to_email_field, to_email_fixed, cc_email, only_if, attachment_path, disable_notify, confirm_field, body, }, user, mode, }: {
320
344
  row: object;
321
345
  table: object;
322
346
  configuration: object;
@@ -339,6 +363,8 @@ export namespace insert_joined_row {
339
363
  options: any;
340
364
  }[]>;
341
365
  export { configFields_5 as configFields };
366
+ const disableInWorkflow_1: boolean;
367
+ export { disableInWorkflow_1 as disableInWorkflow };
342
368
  const requireRow_1: boolean;
343
369
  export { requireRow_1 as requireRow };
344
370
  export function run_4({ row, table, configuration: { joined_table }, user }: {
@@ -356,6 +382,8 @@ export namespace duplicate_row {
356
382
  export { description_6 as description };
357
383
  export function configFields_6(): never[];
358
384
  export { configFields_6 as configFields };
385
+ const disableInWorkflow_2: boolean;
386
+ export { disableInWorkflow_2 as disableInWorkflow };
359
387
  const requireRow_2: boolean;
360
388
  export { requireRow_2 as requireRow };
361
389
  export function run_5({ row, table, user }: {
@@ -415,8 +443,8 @@ export namespace recalculate_stored_fields {
415
443
  export namespace insert_any_row {
416
444
  const description_8: string;
417
445
  export { description_8 as description };
418
- export function configFields_8({ table }: {
419
- table: any;
446
+ export function configFields_8({ mode }: {
447
+ mode: any;
420
448
  }): Promise<({
421
449
  name: string;
422
450
  label: string;
@@ -433,6 +461,14 @@ export namespace insert_any_row {
433
461
  fieldview: string;
434
462
  input_type?: undefined;
435
463
  options?: undefined;
464
+ } | {
465
+ name: string;
466
+ label: string;
467
+ sublabel: string;
468
+ type: string;
469
+ input_type?: undefined;
470
+ options?: undefined;
471
+ fieldview?: undefined;
436
472
  })[]>;
437
473
  export { configFields_8 as configFields };
438
474
  export function run_7({ row, table, configuration, user, referrer, ...rest }: {
@@ -460,9 +496,24 @@ export namespace modify_row {
460
496
  attributes: {
461
497
  mode: string;
462
498
  options?: undefined;
499
+ showIf?: undefined;
463
500
  };
464
501
  type?: undefined;
465
502
  required?: undefined;
503
+ showIf?: undefined;
504
+ } | {
505
+ name: string;
506
+ label: string;
507
+ type: string;
508
+ required: boolean;
509
+ attributes: {
510
+ options: string[];
511
+ mode?: undefined;
512
+ showIf?: undefined;
513
+ };
514
+ sublabel?: undefined;
515
+ input_type?: undefined;
516
+ showIf?: undefined;
466
517
  } | {
467
518
  name: string;
468
519
  label: string;
@@ -470,21 +521,38 @@ export namespace modify_row {
470
521
  required: boolean;
471
522
  attributes: {
472
523
  options: string[];
524
+ showIf: {
525
+ where: string;
526
+ };
473
527
  mode?: undefined;
474
528
  };
475
529
  sublabel?: undefined;
476
530
  input_type?: undefined;
531
+ showIf?: undefined;
532
+ } | {
533
+ name: string;
534
+ label: string;
535
+ type: string;
536
+ required: boolean;
537
+ showIf: {
538
+ where: string;
539
+ };
540
+ sublabel?: undefined;
541
+ input_type?: undefined;
542
+ attributes?: undefined;
477
543
  })[]>;
478
544
  export { configFields_9 as configFields };
479
545
  const requireRow_3: boolean;
480
546
  export { requireRow_3 as requireRow };
481
- export function run_8({ row, table, configuration: { row_expr, where }, user, ...rest }: {
547
+ export function run_8({ row, table, configuration: { row_expr, where, select_table, query }, user, ...rest }: {
482
548
  [x: string]: any;
483
549
  row: any;
484
550
  table: any;
485
551
  configuration: {
486
552
  row_expr: any;
487
553
  where: any;
554
+ select_table: any;
555
+ query: any;
488
556
  };
489
557
  user: any;
490
558
  }): Promise<any>;
@@ -608,6 +676,8 @@ export namespace navigate {
608
676
  export namespace step_control_flow {
609
677
  const description_12: string;
610
678
  export { description_12 as description };
679
+ const disableInWorkflow_3: boolean;
680
+ export { disableInWorkflow_3 as disableInWorkflow };
611
681
  const configFields_12: ({
612
682
  name: string;
613
683
  label: string;
@@ -745,6 +815,7 @@ export namespace run_js_code {
745
815
  input_type: string;
746
816
  attributes: {
747
817
  mode: string;
818
+ secondColHoriz?: undefined;
748
819
  };
749
820
  class: string;
750
821
  validator(s: any): any;
@@ -762,8 +833,11 @@ export namespace run_js_code {
762
833
  showIf: {
763
834
  run_where: string;
764
835
  };
836
+ attributes: {
837
+ secondColHoriz: boolean;
838
+ mode?: undefined;
839
+ };
765
840
  name?: undefined;
766
- attributes?: undefined;
767
841
  class?: undefined;
768
842
  options?: undefined;
769
843
  } | {
@@ -785,9 +859,26 @@ export namespace run_js_code {
785
859
  export namespace run_js_code_in_field {
786
860
  const description_16: string;
787
861
  export { description_16 as description };
788
- export function configFields_16({ table }: {
862
+ export function configFields_16({ table, mode }: {
789
863
  table: any;
864
+ mode: any;
790
865
  }): Promise<({
866
+ name: string;
867
+ label: string;
868
+ sublabel: string;
869
+ type: string;
870
+ required: boolean;
871
+ input_type?: undefined;
872
+ options?: undefined;
873
+ } | {
874
+ name: string;
875
+ label: string;
876
+ input_type: string;
877
+ options: string[];
878
+ sublabel?: undefined;
879
+ type?: undefined;
880
+ required?: undefined;
881
+ })[] | ({
791
882
  name: string;
792
883
  label: string;
793
884
  sublabel: string;
@@ -821,6 +912,8 @@ export namespace duplicate_row_prefill_edit {
821
912
  table: any;
822
913
  }): Promise<any[]>;
823
914
  export { configFields_17 as configFields };
915
+ const disableInWorkflow_4: boolean;
916
+ export { disableInWorkflow_4 as disableInWorkflow };
824
917
  const requireRow_6: boolean;
825
918
  export { requireRow_6 as requireRow };
826
919
  export function run_15({ row, table, configuration: { viewname, ...flds }, user }: {
@@ -1 +1 @@
1
- {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../base-plugin/actions.js"],"names":[],"mappings":"AA4EA;;;;;;;;;GASG;AACH;;;;;;;;;;iBAyFC;;;;;;;;;;;;;;;IAwCiB;;;;;;;;;;;;;;;;;;;;;;;;;;;SAqBb;;IAQI;;;;sBAWJ;;;;;;;IAWa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAgDb;;IAOI;;;wBA6CJ;;;;;;IAca;;;;;;SAeb;;IAUI;;;;;wBA0CJ;;;;;;;;IAgBa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA+Ib;;;IAUI;;;;;wBA2IJ;;;;;;;;IAgBa;;;;;;;;SAYb;;;;IAUI;;;;;wBAsBJ;;;;;;;;IAca,0CAAQ;;;;IASjB;;;;wBAKJ;;;;;;;;IAiBa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAwBb;;IAMI;;sBAwBJ;;;;;;;;IAgBa;;;;;;;;;;;;;;;;;;UAmBb;;IAUI;;;;;;kCAiBJ;;;;;;;;IAea;;;;;;;;;;;;;;;;;;;;;;;;;UA6Bb;;;;IAEI;;;;;;;;;qBAkBJ;;;;;;;;IAWa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA2Bb;;IACI;;;;;;;;;;sBAsBJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAyCI;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAoBJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA4BI;;;;;;;;;;;;;;;;;;;mBAYJ;;;;;;;;;;;;;;;;;;;;IA8BI;;;;;;;;;;;;;;;OA+BJ;;;;;;;;;;;;;;;;;;;;;;;;IA4BI;;;;;;;;;;;;;;;;;;;;OAYJ;;;;;;;;;;;IAmBa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA+Eb;;;;;;;;;IAea;;;;;;;;;;;;;;;;;;;;;;UAkCb;;;;;;;;;;IAqCa;;uBAsBb;;;;IAEI;;;;;;;;;;OAUJ;;;;;;;;IAUa;;;;;;;;;;;;SAcb;;IACI;;;;;;;;;OAgBJ;;;;;;;;IAgBa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA6Db;;IASI;;;;;kCAmFJ;;;;;;;;IAKa;;;;;;;;;;;;;;;;;;;;;;;;;;UAyBb;;IACI;;;;;;;;;;OAkBJ;;;;;;;;;;;;;;;IAaI;;;;;;OAMJ;;;;;;;;IAKa;;;;;;;;;;SAsBb;;IAQI;;;;sBA8BJ;;;;;;;;IAOa;;;;;;;;;;;;;;;;;;;;UA2Cb;;IACI;;;;;;;;sBAeJ;;;;;;;;IAMa,2CAAQ;;IACjB;;;;;;;;OAKJ"}
1
+ {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../base-plugin/actions.js"],"names":[],"mappings":"AA4EA;;;;;;;;;GASG;AACH;;;;;;;;;;iBAyFC;;;;;;;;;;;;;;;;IAyCiB;;;;;;;;;;;;;;;;;;;;;;;;;;;SAqBb;;IAQI;;;;sBAWJ;;;;;;;IAWa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA0Db;;IAOI;;;wBA0DJ;;;;;;IAca;;;;;;SAeb;;IAUI;;;;;wBA0CJ;;;;;;;;IAgBa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA8Lb;;;IAUI;;;;;wBA8JJ;;;;;;;;IAgBa;;;;;;;;SAYb;;;;;;IAWI;;;;;wBAsBJ;;;;;;;;IAca,0CAAQ;;;;;;IAUjB;;;;wBAKJ;;;;;;;;IAiBa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAwBb;;IAMI;;sBAwBJ;;;;;;;;IAgBa;;;;;;;;;;;;;;;;;;;;;;;;;;UA8Bb;;IAUI;;;;;;kCAoBJ;;;;;;;;IAUa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAuDb;;;;IAEI;;;;;;;;;;;qBA0CJ;;;;;;;;IAWa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA+Bb;;IACI;;;;;;;;;;sBAsBJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAyCI;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAwBJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA6BI;;;;;;;;;;;;;;;;;;;mBAYJ;;;;;;;;;;;;;;;;;;;;IA8BI;;;;;;;;;;;;;;;OA+BJ;;;;;;;;;;;;;;;;;;;;;;;;IA4BI;;;;;;;;;;;;;;;;;;;;OAYJ;;;;;;;;;;;IAmBa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAiFb;;;;;;;;;IAea;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAmDb;;;;;;;;;;IAsCa;;uBAsBb;;;;;;IAGI;;;;;;;;;;OAUJ;;;;;;;;IAUa;;;;;;;;;;;;SAcb;;IACI;;;;;;;;;OAgBJ;;;;;;;;IAgBa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA6Db;;IASI;;;;;kCAmFJ;;;;;;;;IAKa;;;;;;;;;;;;;;;;;;;;;;;;;;UAyBb;;IACI;;;;;;;;;;OAkBJ;;;;;;;;;;;;;;;IAaI;;;;;;OAMJ;;;;;;;;IAKa;;;;;;;;;;SAsBb;;IAQI;;;;sBA8BJ;;;;;;;;IAOa;;;;;;;;;;;;;;;;;;;;UA2Cb;;IACI;;;;;;;;sBAeJ;;;;;;;;IAMa,2CAAQ;;IACjB;;;;;;;;OAKJ"}
@@ -143,6 +143,7 @@ module.exports = {
143
143
  blocks: {
144
144
  disableInBuilder: true,
145
145
  disableInList: true,
146
+ disableInWorkflow: true,
146
147
  description: "Build action with drag and drop steps similar to Scratch",
147
148
  configFields: [
148
149
  {
@@ -212,7 +213,7 @@ module.exports = {
212
213
  */
213
214
  webhook: {
214
215
  description: "Make an outbound HTTP POST request",
215
- configFields: async ({ table }) => {
216
+ configFields: async ({ table, mode }) => {
216
217
  let field_opts = [];
217
218
  if (table) {
218
219
  field_opts = table.fields
@@ -257,6 +258,16 @@ module.exports = {
257
258
  },
258
259
  ]
259
260
  : []),
261
+ ...(mode === "workflow"
262
+ ? [
263
+ {
264
+ name: "response_var",
265
+ label: "Response variable",
266
+ sublabel: "Variable in the context to fill with the response",
267
+ type: "String",
268
+ },
269
+ ]
270
+ : []),
260
271
  ];
261
272
  },
262
273
  /**
@@ -265,7 +276,7 @@ module.exports = {
265
276
  * @param {object} opts.body
266
277
  * @returns {Promise<object>}
267
278
  */
268
- run: async ({ row, user, table, configuration: { url, body, authorization, response_field, method }, }) => {
279
+ run: async ({ row, user, table, configuration: { url, body, authorization, response_field, response_var, method, }, }) => {
269
280
  let url1 = interpolate(url, row, user);
270
281
  const fetchOpts = {
271
282
  method: (method || "post").toLowerCase(),
@@ -289,10 +300,16 @@ module.exports = {
289
300
  if (authorization)
290
301
  fetchOpts.headers.Authorization = interpolate(authorization, row, user);
291
302
  const response = await fetch(url1, fetchOpts);
292
- if (table && row && response_field) {
303
+ const contentType = response.headers.get("content-type");
304
+ const isJSON = contentType && contentType.indexOf("application/json") !== -1;
305
+ if (response_var) {
306
+ const parsedResponse = isJSON
307
+ ? await response.json()
308
+ : await response.text();
309
+ return { [response_var]: parsedResponse };
310
+ }
311
+ else if (table && row && response_field) {
293
312
  const field = table.getField(response_field);
294
- const contentType = response.headers.get("content-type");
295
- const isJSON = contentType && contentType.indexOf("application/json") !== -1;
296
313
  const parsedResponse = isJSON
297
314
  ? await response.json()
298
315
  : await response.text();
@@ -381,7 +398,50 @@ module.exports = {
381
398
  * @returns {Promise<object[]>}
382
399
  */
383
400
  description: "Send an email, based on a chosen view for this table",
384
- configFields: async ({ table }) => {
401
+ configFields: async ({ table, mode }) => {
402
+ if (mode === "workflow") {
403
+ return [
404
+ {
405
+ name: "to_email",
406
+ label: "To",
407
+ sublabel: "To addresses, comma separated, <code>{{ }}</code> interpolations usable",
408
+ type: "String",
409
+ },
410
+ {
411
+ name: "cc_email",
412
+ label: "cc",
413
+ sublabel: "cc addresses, comma separated, <code>{{ }}</code> interpolations usable",
414
+ type: "String",
415
+ },
416
+ {
417
+ name: "subject",
418
+ label: "Subject",
419
+ sublabel: "Subject of email, <code>{{ }}</code> interpolations usable",
420
+ type: "String",
421
+ required: true,
422
+ },
423
+ {
424
+ name: "body",
425
+ label: "Body",
426
+ type: "String",
427
+ fieldview: "textarea",
428
+ required: true,
429
+ },
430
+ /* {
431
+ name: "attachment_paths",
432
+ label: "Attachments",
433
+ sublabel:
434
+ "Comma-separated list of files to attach. <code>{{ }}</code> interpolations usable",
435
+ type: "String",
436
+ },*/
437
+ {
438
+ name: "confirm_field",
439
+ label: "Send confirmation variable",
440
+ type: "String",
441
+ sublabel: "Bool variable set in context indicate successful sending of email message",
442
+ },
443
+ ];
444
+ }
385
445
  if (!table)
386
446
  return [];
387
447
  const views = await View.find_table_views_where(table, ({ viewtemplate }) => viewtemplate?.runMany || viewtemplate?.renderRows);
@@ -512,7 +572,24 @@ module.exports = {
512
572
  * @param {object} opts.user
513
573
  * @returns {Promise<object>}
514
574
  */
515
- run: async ({ row, table, configuration: { body_type, body_field, viewname, subject, subject_formula, to_email, to_email_field, to_email_fixed, cc_email, only_if, attachment_path, disable_notify, confirm_field, }, user, }) => {
575
+ run: async ({ row, table, configuration: { body_type, body_field, viewname, subject, subject_formula, to_email, to_email_field, to_email_fixed, cc_email, only_if, attachment_path, disable_notify, confirm_field, body, }, user, mode, }) => {
576
+ const from = getState().getConfig("email_from");
577
+ if (mode === "workflow") {
578
+ const email = {
579
+ from,
580
+ to: interpolate(to_email, row, user),
581
+ cc: interpolate(cc_email, row, user),
582
+ subject: interpolate(subject, row, user),
583
+ html: interpolate(body, row, user),
584
+ // attachments,
585
+ };
586
+ const sendres = await getMailTransport().sendMail(email);
587
+ getState().log(5, `send_email result: ${JSON.stringify(sendres)}`);
588
+ if (confirm_field)
589
+ return { [confirm_field]: sendres.accepted.length > 0 };
590
+ else
591
+ return;
592
+ }
516
593
  let to_addr;
517
594
  let useRow = row;
518
595
  const fvs = [
@@ -574,7 +651,6 @@ module.exports = {
574
651
  const view = await View.findOne({ name: viewname });
575
652
  setBody.html = await viewToEmailHtml(view, { id: row[table.pk_name] });
576
653
  }
577
- const from = getState().getConfig("email_from");
578
654
  const attachments = await loadAttachments(attachment_path, row, user ? user : { role_id: 100 });
579
655
  const the_subject = subject_formula
580
656
  ? eval_expression(subject, useRow, user, "send_email subject formula")
@@ -641,6 +717,7 @@ module.exports = {
641
717
  },
642
718
  ];
643
719
  },
720
+ disableInWorkflow: true,
644
721
  requireRow: true,
645
722
  /**
646
723
  * @param {object} opts
@@ -681,6 +758,7 @@ module.exports = {
681
758
  */
682
759
  description: "Duplicate the current row",
683
760
  configFields: () => [],
761
+ disableInWorkflow: true,
684
762
  requireRow: true,
685
763
  /**
686
764
  * @param {object} opts
@@ -773,7 +851,7 @@ module.exports = {
773
851
  * @returns {Promise<object[]>}
774
852
  */
775
853
  description: "insert a row into any table, using a formula expression",
776
- configFields: async ({ table }) => {
854
+ configFields: async ({ mode }) => {
777
855
  const tables = await Table.find({}, { cached: true });
778
856
  return [
779
857
  {
@@ -790,6 +868,16 @@ module.exports = {
790
868
  type: "String",
791
869
  fieldview: "textarea",
792
870
  },
871
+ ...(mode === "workflow"
872
+ ? [
873
+ {
874
+ name: "id_variable",
875
+ label: "ID variable",
876
+ sublabel: "Variable in the context to fill with the created ID value",
877
+ type: "String",
878
+ },
879
+ ]
880
+ : []),
793
881
  ];
794
882
  },
795
883
  /**
@@ -803,7 +891,7 @@ module.exports = {
803
891
  */
804
892
  run: async ({ row, table, configuration, user, referrer, ...rest }) => {
805
893
  const state = urlStringToObject(referrer);
806
- const f = get_async_expression_function(configuration.row_expr, table?.fields || [], {
894
+ const f = get_async_expression_function(configuration.row_expr, table?.fields || Object.keys(row).map((k) => ({ name: k })), {
807
895
  user,
808
896
  console,
809
897
  session_id: rest.req && getSessionId(rest.req),
@@ -814,6 +902,8 @@ module.exports = {
814
902
  const res = await table_for_insert.tryInsertRow(calcrow, user);
815
903
  if (res.error)
816
904
  return res;
905
+ else if (configuration.id_variable)
906
+ return { [configuration.id_variable]: res.success };
817
907
  else
818
908
  return true;
819
909
  },
@@ -825,11 +915,6 @@ module.exports = {
825
915
  * @subcategory actions
826
916
  */
827
917
  modify_row: {
828
- /**
829
- * @param {object} opts
830
- * @param {*} opts.table
831
- * @returns {Promise<object[]>}
832
- */
833
918
  description: "Modify the triggering row",
834
919
  configFields: async ({ mode, when_trigger }) => {
835
920
  return [
@@ -840,7 +925,10 @@ module.exports = {
840
925
  input_type: "code",
841
926
  attributes: { mode: "application/javascript" },
842
927
  },
843
- ...(mode === "edit" || mode === "filter" || when_trigger === "Validate"
928
+ ...(mode === "edit" ||
929
+ mode === "filter" ||
930
+ when_trigger === "Validate" ||
931
+ mode === "workflow"
844
932
  ? [
845
933
  {
846
934
  name: "where",
@@ -852,22 +940,59 @@ module.exports = {
852
940
  ? ["Row"]
853
941
  : mode === "filter"
854
942
  ? ["Filter state"]
855
- : ["Form", "Database"],
943
+ : mode === "workflow"
944
+ ? ["Database", "Active edit view"]
945
+ : ["Form", "Database"],
856
946
  },
857
947
  },
858
948
  ]
859
949
  : []),
950
+ ...(mode === "workflow"
951
+ ? [
952
+ {
953
+ name: "select_table",
954
+ label: "Table",
955
+ type: "String",
956
+ required: true,
957
+ attributes: {
958
+ options: (await Table.find()).map((t) => t.name),
959
+ showIf: { where: "Database" },
960
+ },
961
+ },
962
+ {
963
+ name: "query",
964
+ label: "Query object",
965
+ type: "String",
966
+ required: true,
967
+ showIf: { where: "Database" },
968
+ },
969
+ ]
970
+ : []),
860
971
  ];
861
972
  },
862
973
  requireRow: true,
863
- run: async ({ row, table, configuration: { row_expr, where }, user, ...rest }) => {
864
- const f = get_async_expression_function(row_expr, table.fields, {
974
+ run: async ({ row, table, configuration: { row_expr, where, select_table, query }, user, ...rest }) => {
975
+ const f = get_async_expression_function(row_expr, table?.fields || Object.keys(row).map((k) => ({ name: k })), {
865
976
  row: row || {},
866
977
  user,
867
978
  });
868
979
  const calcrow = await f(row, user);
869
- if (where === "Form" || where === "Filter state" || where === "Row")
980
+ if (where === "Form" ||
981
+ where === "Filter state" ||
982
+ where === "Row" ||
983
+ where === "Active edit view")
870
984
  return { set_fields: calcrow };
985
+ if (select_table && query) {
986
+ //get table
987
+ const table = Table.findOne(select_table);
988
+ // evaluate query
989
+ const q = eval_expression(query, row, user, "Query expression in modify_row step");
990
+ const rows = await table.getRows(q);
991
+ for (const row of rows) {
992
+ await table.updateRow(calcrow, row[table.pk_name]);
993
+ }
994
+ return;
995
+ }
871
996
  const res = await table.tryUpdateRow(calcrow, row[table.pk_name], user);
872
997
  if (res.error)
873
998
  return res;
@@ -886,11 +1011,15 @@ module.exports = {
886
1011
  configFields: async ({ mode, when_trigger }) => {
887
1012
  const tables = await Table.find({}, { cached: true });
888
1013
  return [
889
- {
890
- name: "delete_triggering_row",
891
- label: "Delete triggering row",
892
- type: "Bool",
893
- },
1014
+ ...(mode === "workflow"
1015
+ ? []
1016
+ : [
1017
+ {
1018
+ name: "delete_triggering_row",
1019
+ label: "Delete triggering row",
1020
+ type: "Bool",
1021
+ },
1022
+ ]),
894
1023
  {
895
1024
  name: "table_name",
896
1025
  label: "Table",
@@ -969,7 +1098,11 @@ module.exports = {
969
1098
  case "Popup modal":
970
1099
  return { popup: url1 };
971
1100
  case "Back":
972
- return { eval_js: isWeb(req) ? "history.back()" : "parent.goBack()" };
1101
+ return {
1102
+ eval_js: isWeb(req)
1103
+ ? "history.back()"
1104
+ : "parent.saltcorn.mobileApp.navigation.goBack()",
1105
+ };
973
1106
  case "Close tab":
974
1107
  return { eval_js: "window.close()" };
975
1108
  case "Close modal":
@@ -989,6 +1122,7 @@ module.exports = {
989
1122
  * @returns {Promise<object[]>}
990
1123
  */
991
1124
  description: "Step control flow",
1125
+ disableInWorkflow: true,
992
1126
  configFields: [
993
1127
  {
994
1128
  name: "control_action",
@@ -1179,6 +1313,7 @@ module.exports = {
1179
1313
  topic: "JavaScript action code",
1180
1314
  },
1181
1315
  showIf: { run_where: "Server" },
1316
+ attributes: { secondColHoriz: true },
1182
1317
  },
1183
1318
  {
1184
1319
  input_type: "section_header",
@@ -1188,6 +1323,7 @@ module.exports = {
1188
1323
  topic: "JavaScript action code",
1189
1324
  },
1190
1325
  showIf: { run_where: "Client page" },
1326
+ attributes: { secondColHoriz: true },
1191
1327
  },
1192
1328
  {
1193
1329
  name: "run_where",
@@ -1211,7 +1347,23 @@ module.exports = {
1211
1347
  * @returns {Promise<object[]>}
1212
1348
  */
1213
1349
  description: "Run arbitrary JavaScript code from a String field",
1214
- configFields: async ({ table }) => {
1350
+ configFields: async ({ table, mode }) => {
1351
+ if (mode === "workflow")
1352
+ return [
1353
+ {
1354
+ name: "code_field",
1355
+ label: "Code field",
1356
+ sublabel: "String variable in context contains the JavaScript code to run",
1357
+ type: "String",
1358
+ required: true,
1359
+ },
1360
+ {
1361
+ name: "run_where",
1362
+ label: "Run where",
1363
+ input_type: "select",
1364
+ options: ["Server", "Client page"],
1365
+ },
1366
+ ];
1215
1367
  const field_opts = table.fields
1216
1368
  .filter((f) => f.type?.name === "String")
1217
1369
  .map((f) => f.name);
@@ -1249,7 +1401,7 @@ module.exports = {
1249
1401
  * @type {base-plugin/actions~run_code}
1250
1402
  * @see base-plugin/actions~run_code
1251
1403
  **/
1252
- run: async ({ table, configuration: { code_field, run_where }, row, ...rest }) => {
1404
+ run: async ({ table, configuration: { code_field, run_where }, row, mode, ...rest }) => {
1253
1405
  let code;
1254
1406
  if (code_field.includes(".")) {
1255
1407
  const [ref, target] = code_field.split(".");
@@ -1296,6 +1448,7 @@ module.exports = {
1296
1448
  ...fldOpts,
1297
1449
  ];
1298
1450
  },
1451
+ disableInWorkflow: true,
1299
1452
  requireRow: true,
1300
1453
  run: async ({ row, table, configuration: { viewname, ...flds }, user }) => {
1301
1454
  const qs = Object.entries(flds)