@saltcorn/data 0.9.5-beta.9 → 0.9.6-beta.0

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 (132) hide show
  1. package/dist/base-plugin/actions.d.ts +87 -41
  2. package/dist/base-plugin/actions.d.ts.map +1 -1
  3. package/dist/base-plugin/actions.js +135 -10
  4. package/dist/base-plugin/actions.js.map +1 -1
  5. package/dist/base-plugin/fieldviews.d.ts.map +1 -1
  6. package/dist/base-plugin/fieldviews.js +2 -10
  7. package/dist/base-plugin/fieldviews.js.map +1 -1
  8. package/dist/base-plugin/fileviews.js +6 -0
  9. package/dist/base-plugin/fileviews.js.map +1 -1
  10. package/dist/base-plugin/index.d.ts +107 -92
  11. package/dist/base-plugin/index.d.ts.map +1 -1
  12. package/dist/base-plugin/types.d.ts +208 -188
  13. package/dist/base-plugin/types.d.ts.map +1 -1
  14. package/dist/base-plugin/types.js +61 -13
  15. package/dist/base-plugin/types.js.map +1 -1
  16. package/dist/base-plugin/viewtemplates/edit.d.ts +1 -1
  17. package/dist/base-plugin/viewtemplates/edit.d.ts.map +1 -1
  18. package/dist/base-plugin/viewtemplates/edit.js +58 -23
  19. package/dist/base-plugin/viewtemplates/edit.js.map +1 -1
  20. package/dist/base-plugin/viewtemplates/feed.d.ts +1 -1
  21. package/dist/base-plugin/viewtemplates/feed.d.ts.map +1 -1
  22. package/dist/base-plugin/viewtemplates/feed.js +27 -11
  23. package/dist/base-plugin/viewtemplates/feed.js.map +1 -1
  24. package/dist/base-plugin/viewtemplates/filter.d.ts.map +1 -1
  25. package/dist/base-plugin/viewtemplates/filter.js +10 -4
  26. package/dist/base-plugin/viewtemplates/filter.js.map +1 -1
  27. package/dist/base-plugin/viewtemplates/list.d.ts.map +1 -1
  28. package/dist/base-plugin/viewtemplates/list.js +105 -5
  29. package/dist/base-plugin/viewtemplates/list.js.map +1 -1
  30. package/dist/base-plugin/viewtemplates/show.d.ts +1 -1
  31. package/dist/base-plugin/viewtemplates/show.d.ts.map +1 -1
  32. package/dist/base-plugin/viewtemplates/show.js +35 -18
  33. package/dist/base-plugin/viewtemplates/show.js.map +1 -1
  34. package/dist/base-plugin/viewtemplates/viewable_fields.d.ts +2 -2
  35. package/dist/base-plugin/viewtemplates/viewable_fields.d.ts.map +1 -1
  36. package/dist/base-plugin/viewtemplates/viewable_fields.js +56 -38
  37. package/dist/base-plugin/viewtemplates/viewable_fields.js.map +1 -1
  38. package/dist/db/state.d.ts +10 -1
  39. package/dist/db/state.d.ts.map +1 -1
  40. package/dist/db/state.js +105 -9
  41. package/dist/db/state.js.map +1 -1
  42. package/dist/models/config.d.ts.map +1 -1
  43. package/dist/models/config.js +58 -1
  44. package/dist/models/config.js.map +1 -1
  45. package/dist/models/email.d.ts +1 -0
  46. package/dist/models/email.d.ts.map +1 -1
  47. package/dist/models/expression.d.ts +3 -3
  48. package/dist/models/expression.d.ts.map +1 -1
  49. package/dist/models/expression.js +69 -17
  50. package/dist/models/expression.js.map +1 -1
  51. package/dist/models/field.d.ts +1 -1
  52. package/dist/models/field.d.ts.map +1 -1
  53. package/dist/models/field.js +18 -13
  54. package/dist/models/field.js.map +1 -1
  55. package/dist/models/fieldrepeat.d.ts.map +1 -1
  56. package/dist/models/fieldrepeat.js +4 -0
  57. package/dist/models/fieldrepeat.js.map +1 -1
  58. package/dist/models/file.d.ts +1 -0
  59. package/dist/models/file.d.ts.map +1 -1
  60. package/dist/models/file.js +6 -2
  61. package/dist/models/file.js.map +1 -1
  62. package/dist/models/form.d.ts +3 -1
  63. package/dist/models/form.d.ts.map +1 -1
  64. package/dist/models/form.js +2 -1
  65. package/dist/models/form.js.map +1 -1
  66. package/dist/models/index.d.ts +2 -2
  67. package/dist/models/index.d.ts.map +1 -1
  68. package/dist/models/page.d.ts.map +1 -1
  69. package/dist/models/page.js +10 -6
  70. package/dist/models/page.js.map +1 -1
  71. package/dist/models/page_group.d.ts.map +1 -1
  72. package/dist/models/page_group.js +1 -1
  73. package/dist/models/page_group.js.map +1 -1
  74. package/dist/models/plugin.d.ts.map +1 -1
  75. package/dist/models/plugin.js +1 -0
  76. package/dist/models/plugin.js.map +1 -1
  77. package/dist/models/random.d.ts.map +1 -1
  78. package/dist/models/random.js +1 -1
  79. package/dist/models/random.js.map +1 -1
  80. package/dist/models/scheduler.d.ts.map +1 -1
  81. package/dist/models/scheduler.js +4 -1
  82. package/dist/models/scheduler.js.map +1 -1
  83. package/dist/models/table.d.ts +16 -0
  84. package/dist/models/table.d.ts.map +1 -1
  85. package/dist/models/table.js +84 -9
  86. package/dist/models/table.js.map +1 -1
  87. package/dist/models/trigger.d.ts.map +1 -1
  88. package/dist/models/trigger.js +12 -1
  89. package/dist/models/trigger.js.map +1 -1
  90. package/dist/models/user.d.ts.map +1 -1
  91. package/dist/models/user.js +10 -0
  92. package/dist/models/user.js.map +1 -1
  93. package/dist/models/view.d.ts.map +1 -1
  94. package/dist/models/view.js +31 -12
  95. package/dist/models/view.js.map +1 -1
  96. package/dist/models/workflow.d.ts +2 -0
  97. package/dist/models/workflow.d.ts.map +1 -1
  98. package/dist/models/workflow.js +8 -0
  99. package/dist/models/workflow.js.map +1 -1
  100. package/dist/plugin-helper.d.ts +1 -0
  101. package/dist/plugin-helper.d.ts.map +1 -1
  102. package/dist/plugin-helper.js +8 -9
  103. package/dist/plugin-helper.js.map +1 -1
  104. package/dist/tests/calc.test.js +123 -1
  105. package/dist/tests/calc.test.js.map +1 -1
  106. package/dist/tests/edit.test.js +2 -2
  107. package/dist/tests/edit.test.js.map +1 -1
  108. package/dist/tests/exact_views.test.js +24 -24
  109. package/dist/tests/exact_views.test.js.map +1 -1
  110. package/dist/tests/file.test.d.ts +2 -0
  111. package/dist/tests/file.test.d.ts.map +1 -0
  112. package/dist/tests/file.test.js +95 -0
  113. package/dist/tests/file.test.js.map +1 -0
  114. package/dist/tests/mocks.d.ts +21 -0
  115. package/dist/tests/mocks.d.ts.map +1 -1
  116. package/dist/tests/mocks.js +35 -2
  117. package/dist/tests/mocks.js.map +1 -1
  118. package/dist/tests/models.test.js +0 -41
  119. package/dist/tests/models.test.js.map +1 -1
  120. package/dist/tests/show.test.js +6 -4
  121. package/dist/tests/show.test.js.map +1 -1
  122. package/dist/tests/table.test.js +161 -0
  123. package/dist/tests/table.test.js.map +1 -1
  124. package/dist/tests/table_history.test.js +39 -0
  125. package/dist/tests/table_history.test.js.map +1 -1
  126. package/dist/tests/view.test.js +2 -2
  127. package/dist/tests/view.test.js.map +1 -1
  128. package/dist/utils.d.ts +8 -3
  129. package/dist/utils.d.ts.map +1 -1
  130. package/dist/utils.js +56 -0
  131. package/dist/utils.js.map +1 -1
  132. package/package.json +8 -8
@@ -337,6 +337,7 @@ export namespace recalculate_stored_fields {
337
337
  options: string[];
338
338
  type?: undefined;
339
339
  showIf?: undefined;
340
+ class?: undefined;
340
341
  } | {
341
342
  name: string;
342
343
  label: string;
@@ -349,9 +350,19 @@ export namespace recalculate_stored_fields {
349
350
  sublabel?: undefined;
350
351
  input_type?: undefined;
351
352
  options?: undefined;
353
+ class?: undefined;
354
+ } | {
355
+ name: string;
356
+ label: string;
357
+ sublabel: string;
358
+ type: string;
359
+ class: string;
360
+ input_type?: undefined;
361
+ options?: undefined;
362
+ showIf?: undefined;
352
363
  })[]>;
353
364
  export { configFields_7 as configFields };
354
- export function run_6({ table, row, configuration }: {
365
+ export function run_6({ table, row, configuration, user }: {
355
366
  configuration: object;
356
367
  }): Promise<void>;
357
368
  export { run_6 as run };
@@ -606,6 +617,9 @@ export namespace toast {
606
617
  export namespace run_js_code {
607
618
  const description_14: string;
608
619
  export { description_14 as description };
620
+ export namespace configFormOptions {
621
+ const formStyle: string;
622
+ }
609
623
  export function configFields_14({ table }: {
610
624
  table: any;
611
625
  }): Promise<({
@@ -649,14 +663,46 @@ export namespace run_js_code {
649
663
  export { configFields_14 as configFields };
650
664
  export { run_code as run };
651
665
  }
652
- export namespace duplicate_row_prefill_edit {
666
+ export namespace run_js_code_in_field {
667
+ const description_15: string;
668
+ export { description_15 as description };
653
669
  export function configFields_15({ table }: {
654
670
  table: any;
655
- }): Promise<any[]>;
671
+ }): Promise<({
672
+ name: string;
673
+ label: string;
674
+ sublabel: string;
675
+ type: string;
676
+ required: boolean;
677
+ attributes: {
678
+ options: any;
679
+ };
680
+ input_type?: undefined;
681
+ options?: undefined;
682
+ } | {
683
+ name: string;
684
+ label: string;
685
+ input_type: string;
686
+ options: string[];
687
+ sublabel?: undefined;
688
+ type?: undefined;
689
+ required?: undefined;
690
+ attributes?: undefined;
691
+ })[]>;
656
692
  export { configFields_15 as configFields };
657
693
  const requireRow_5: boolean;
658
694
  export { requireRow_5 as requireRow };
659
- export function run_13({ row, table, configuration: { viewname, ...flds }, user }: {
695
+ const run_13: base;
696
+ export { run_13 as run };
697
+ }
698
+ export namespace duplicate_row_prefill_edit {
699
+ export function configFields_16({ table }: {
700
+ table: any;
701
+ }): Promise<any[]>;
702
+ export { configFields_16 as configFields };
703
+ const requireRow_6: boolean;
704
+ export { requireRow_6 as requireRow };
705
+ export function run_14({ row, table, configuration: { viewname, ...flds }, user }: {
660
706
  row: any;
661
707
  table: any;
662
708
  configuration: {
@@ -667,12 +713,12 @@ export namespace duplicate_row_prefill_edit {
667
713
  }): Promise<{
668
714
  goto: string;
669
715
  }>;
670
- export { run_13 as run };
716
+ export { run_14 as run };
671
717
  }
672
718
  export namespace set_user_language {
673
- const description_15: string;
674
- export { description_15 as description };
675
- export function configFields_16({ table }: {
719
+ const description_16: string;
720
+ export { description_16 as description };
721
+ export function configFields_17({ table }: {
676
722
  table: any;
677
723
  }): Promise<{
678
724
  name: string;
@@ -685,8 +731,8 @@ export namespace set_user_language {
685
731
  }[];
686
732
  };
687
733
  }[]>;
688
- export { configFields_16 as configFields };
689
- export function run_14({ configuration: { language }, user, req, res }: {
734
+ export { configFields_17 as configFields };
735
+ export function run_15({ configuration: { language }, user, req, res }: {
690
736
  configuration: {
691
737
  language: any;
692
738
  };
@@ -696,12 +742,12 @@ export namespace set_user_language {
696
742
  }): Promise<{
697
743
  reload_page: boolean;
698
744
  }>;
699
- export { run_14 as run };
745
+ export { run_15 as run };
700
746
  }
701
747
  export namespace sync_table_from_external {
702
- const description_16: string;
703
- export { description_16 as description };
704
- export function configFields_17({ table }: {
748
+ const description_17: string;
749
+ export { description_17 as description };
750
+ export function configFields_18({ table }: {
705
751
  table: any;
706
752
  }): Promise<({
707
753
  name: string;
@@ -756,19 +802,19 @@ export namespace sync_table_from_external {
756
802
  attributes?: undefined;
757
803
  default?: undefined;
758
804
  })[]>;
759
- export { configFields_17 as configFields };
760
- export function run_15({ configuration: { row_expr, table_src, table_dest, pk_field, delete_rows, match_field_names, }, user, ...rest }: {
805
+ export { configFields_18 as configFields };
806
+ export function run_16({ configuration: { row_expr, table_src, table_dest, pk_field, delete_rows, match_field_names, }, user, ...rest }: {
761
807
  row: object;
762
808
  configuration: object;
763
809
  user: object;
764
810
  rest: any;
765
811
  }): Promise<boolean | object>;
766
- export { run_15 as run };
812
+ export { run_16 as run };
767
813
  }
768
814
  export namespace reload_embedded_view {
769
- const description_17: string;
770
- export { description_17 as description };
771
- export function configFields_18(): Promise<({
815
+ const description_18: string;
816
+ export { description_18 as description };
817
+ export function configFields_19(): Promise<({
772
818
  name: string;
773
819
  label: string;
774
820
  class: string;
@@ -785,8 +831,8 @@ export namespace reload_embedded_view {
785
831
  required?: undefined;
786
832
  attributes?: undefined;
787
833
  })[]>;
788
- export { configFields_18 as configFields };
789
- export function run_16({ row, user, configuration: { view, new_state_fml } }: {
834
+ export { configFields_19 as configFields };
835
+ export function run_17({ row, user, configuration: { view, new_state_fml } }: {
790
836
  row: any;
791
837
  user: any;
792
838
  configuration: {
@@ -796,31 +842,31 @@ export namespace reload_embedded_view {
796
842
  }): Promise<{
797
843
  eval_js: string;
798
844
  }>;
799
- export { run_16 as run };
845
+ export { run_17 as run };
800
846
  }
801
847
  export namespace sleep {
802
- const description_18: string;
803
- export { description_18 as description };
804
- const configFields_19: {
848
+ const description_19: string;
849
+ export { description_19 as description };
850
+ const configFields_20: {
805
851
  name: string;
806
852
  label: string;
807
853
  type: string;
808
854
  required: boolean;
809
855
  }[];
810
- export { configFields_19 as configFields };
811
- export function run_17({ configuration: { seconds } }: {
856
+ export { configFields_20 as configFields };
857
+ export function run_18({ configuration: { seconds } }: {
812
858
  configuration: {
813
859
  seconds: any;
814
860
  };
815
861
  }): Promise<{
816
862
  eval_js: string;
817
863
  }>;
818
- export { run_17 as run };
864
+ export { run_18 as run };
819
865
  }
820
866
  export namespace notify_user {
821
- const description_19: string;
822
- export { description_19 as description };
823
- export function configFields_20(): ({
867
+ const description_20: string;
868
+ export { description_20 as description };
869
+ export function configFields_21(): ({
824
870
  name: string;
825
871
  label: string;
826
872
  type: string;
@@ -831,18 +877,18 @@ export namespace notify_user {
831
877
  required: boolean;
832
878
  type: string;
833
879
  })[];
834
- export { configFields_20 as configFields };
835
- export function run_18({ row, user, configuration: { title, body, link, user_spec }, }: {
880
+ export { configFields_21 as configFields };
881
+ export function run_19({ row, user, configuration: { title, body, link, user_spec }, }: {
836
882
  row: object;
837
883
  configuration: object;
838
884
  user: object;
839
885
  }): Promise<void>;
840
- export { run_18 as run };
886
+ export { run_19 as run };
841
887
  }
842
888
  export namespace convert_session_to_user {
843
- const description_20: string;
844
- export { description_20 as description };
845
- export function configFields_21({ table }: {
889
+ const description_21: string;
890
+ export { description_21 as description };
891
+ export function configFields_22({ table }: {
846
892
  table: any;
847
893
  }): Promise<({
848
894
  name: string;
@@ -863,8 +909,8 @@ export namespace convert_session_to_user {
863
909
  input_type?: undefined;
864
910
  options?: undefined;
865
911
  })[]>;
866
- export { configFields_21 as configFields };
867
- export function run_19({ row, configuration: { table_name, session_field, user_field }, user, }: {
912
+ export { configFields_22 as configFields };
913
+ export function run_20({ row, configuration: { table_name, session_field, user_field }, user, }: {
868
914
  row: any;
869
915
  configuration: {
870
916
  table_name: any;
@@ -873,7 +919,7 @@ export namespace convert_session_to_user {
873
919
  };
874
920
  user: any;
875
921
  }): Promise<void>;
876
- export { run_19 as run };
922
+ export { run_20 as run };
877
923
  }
878
924
  export {};
879
925
  //# sourceMappingURL=actions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../base-plugin/actions.js"],"names":[],"mappings":"AAyEA;;;;;;;;;GASG;AACH;;;;;;;;;;iBA6EC;;;;;;;;;;;;;;IAuCiB;;;;;;;;;;;;;;;;;;;;;;;;;;;SAqBb;;IAQI;;;;sBAWJ;;;;;;;;;;;;;;;;;;;IA+BI;;;wBAQJ;;;;;;IAca;;;;;;SAeb;;IAUI;;;;;wBA0CJ;;;;;;IAea;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA+Ib;;;IAUI;;;;;wBAqHJ;;;;;;IAea;;;;;;;;SAYb;;;;IAUI;;;;;wBAsBJ;;;;;;IAaa,0CAAQ;;;;IASjB;;;;wBAKJ;;;;;;IAgBa;;;;;;;;;;;;;;;;;;;;;;UAiBb;;IAMI;;sBAgBJ;;;;;;IAea;;;;;;;;;;;;;;;;;;UAmBb;;IAUI;;;;;;kCAiBJ;;;;;;IAca;;;;;;;;;;;;;;;;;;;;;;;;UA0Bb;;;;IAEI;;;;;;;;;qBAkBJ;;;;;;;;;;;;;;;;;;;;;;;;;;IAuCI;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAkBJ;;;;;;;;;;;;;;;;;;;;;;;;;;IA2BI;;;;;;;;;;;;;;;;;;;mBAYJ;;;;;;;;;;;;;;;;;;IAuBI;;;;;;;;;;;;;;OA6BJ;;;;;;;;;;;;;;;;;;;;;;IA2BI;;;;;;;;;;;;;;;;;;;;OAYJ;;;;;;IAea;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA+Eb;;;;;IAQa;;uBAsBb;;;;IAEI;;;;;;;;;;OAUJ;;;;;;IASa;;;;;;;;;;;;SAcb;;IACI;;;;;;;;;OAgBJ;;;;;;IAea;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAyDb;;IASI;;;;;kCAmFJ;;;;;;IAIa;;;;;;;;;;;;;;;;UAkBb;;IACI;;;;;;;;;OAQJ;;;;;;;;;;;;;IAYI;;;;;;OAMJ;;;;;;IAIa;;;;;;;;;;SAsBb;;IAQI;;;;sBAmBJ;;;;;;IAMa;;;;;;;;;;;;;;;;;;;;UA2Cb;;IACI;;;;;;;;sBAeJ"}
1
+ {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../base-plugin/actions.js"],"names":[],"mappings":"AA4EA;;;;;;;;;GASG;AACH;;;;;;;;;;iBAyFC;;;;;;;;;;;;;;IAuCiB;;;;;;;;;;;;;;;;;;;;;;;;;;;SAqBb;;IAQI;;;;sBAWJ;;;;;;;;;;;;;;;;;;;IA+BI;;;wBAQJ;;;;;;IAca;;;;;;SAeb;;IAUI;;;;;wBA0CJ;;;;;;IAea;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA+Ib;;;IAUI;;;;;wBA2IJ;;;;;;IAea;;;;;;;;SAYb;;;;IAUI;;;;;wBAsBJ;;;;;;IAaa,0CAAQ;;;;IASjB;;;;wBAKJ;;;;;;IAgBa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAwBb;;IAMI;;sBAwBJ;;;;;;IAea;;;;;;;;;;;;;;;;;;UAmBb;;IAUI;;;;;;kCAiBJ;;;;;;IAca;;;;;;;;;;;;;;;;;;;;;;;;UA0Bb;;;;IAEI;;;;;;;;;qBAkBJ;;;;;;;;;;;;;;;;;;;;;;;;;;IAwCI;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAoBJ;;;;;;;;;;;;;;;;;;;;;;;;;;IA2BI;;;;;;;;;;;;;;;;;;;mBAYJ;;;;;;;;;;;;;;;;;;IA6BI;;;;;;;;;;;;;;OA+BJ;;;;;;;;;;;;;;;;;;;;;;IA2BI;;;;;;;;;;;;;;;;;;;;OAYJ;;;;;;;;;IAkBa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA+Eb;;;;;;;IAca;;;;;;;;;;;;;;;;;;;;;;UAkCb;;;;;;;;IAoCa;;uBAsBb;;;;IAEI;;;;;;;;;;OAUJ;;;;;;IASa;;;;;;;;;;;;SAcb;;IACI;;;;;;;;;OAgBJ;;;;;;IAea;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAyDb;;IASI;;;;;kCAmFJ;;;;;;IAIa;;;;;;;;;;;;;;;;UAkBb;;IACI;;;;;;;;;OAaJ;;;;;;;;;;;;;IAYI;;;;;;OAMJ;;;;;;IAIa;;;;;;;;;;SAsBb;;IAQI;;;;sBAmBJ;;;;;;IAMa;;;;;;;;;;;;;;;;;;;;UA2Cb;;IACI;;;;;;;;sBAeJ"}
@@ -16,7 +16,7 @@ const User = require("../models/user");
16
16
  const Trigger = require("../models/trigger");
17
17
  const Notification = require("../models/notification");
18
18
  const { getMailTransport, viewToEmailHtml, loadAttachments, getFileAggregations, mjml2html, } = require("../models/email");
19
- const { get_async_expression_function, recalculate_for_stored, eval_expression, } = require("../models/expression");
19
+ const { get_async_expression_function, recalculate_for_stored, eval_expression, freeVariablesInInterpolation, add_free_variables_to_joinfields, freeVariables, } = require("../models/expression");
20
20
  const { div, code, a, span } = require("@saltcorn/markup/tags");
21
21
  const { sleep, getSessionId, urlStringToObject, dollarizeObject, objectToQueryString, interpolate, } = require("../utils");
22
22
  const db = require("../db");
@@ -85,6 +85,17 @@ const run_code = async ({ row, table, channel, configuration: { code, run_where
85
85
  });
86
86
  };
87
87
  }
88
+ const run_js_code = async ({ code, ...restArgs }) => {
89
+ return await run_code({
90
+ row,
91
+ table,
92
+ channel,
93
+ configuration: { code, run_where },
94
+ user,
95
+ ...rest,
96
+ ...restArgs,
97
+ });
98
+ };
88
99
  const emitEvent = (eventType, channel, payload) => Trigger.emitEvent(eventType, channel, user, payload);
89
100
  const fetchJSON = async (...args) => await (await fetch(...args)).json();
90
101
  const sysState = getState();
@@ -100,6 +111,7 @@ const run_code = async ({ row, table, channel, configuration: { code, run_where
100
111
  sleep,
101
112
  fetchJSON,
102
113
  fetch,
114
+ run_js_code,
103
115
  URL,
104
116
  File,
105
117
  User,
@@ -117,7 +129,7 @@ const run_code = async ({ row, table, channel, configuration: { code, run_where
117
129
  request_headers: rest?.req?.headers,
118
130
  request_ip: rest?.req?.ip,
119
131
  ...(row || {}),
120
- ...getState().function_context,
132
+ ...getState().eval_context,
121
133
  ...rest,
122
134
  });
123
135
  return await f();
@@ -435,14 +447,31 @@ module.exports = {
435
447
  */
436
448
  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, }) => {
437
449
  let to_addr;
450
+ let useRow = row;
451
+ const fvs = [
452
+ ...freeVariablesInInterpolation(to_email_fixed),
453
+ ...freeVariablesInInterpolation(cc_email),
454
+ ...(subject_formula ? freeVariables(subject) : []),
455
+ ...freeVariables(only_if),
456
+ ];
457
+ if (fvs.length > 0) {
458
+ const joinFields = {};
459
+ const fields = table.getFields();
460
+ add_free_variables_to_joinfields(new Set(fvs), joinFields, fields);
461
+ useRow = await table.getJoinedRow({
462
+ where: { [table.pk_name]: row[table.pk_name] },
463
+ joinFields,
464
+ forUser: user,
465
+ });
466
+ }
438
467
  if (only_if) {
439
- const bres = eval_expression(only_if, row);
468
+ const bres = eval_expression(only_if, useRow, user, "send_email only if formula");
440
469
  if (!bres)
441
470
  return;
442
471
  }
443
472
  switch (to_email) {
444
473
  case "Fixed":
445
- to_addr = interpolate(to_email_fixed, row, user);
474
+ to_addr = interpolate(to_email_fixed, useRow, user);
446
475
  break;
447
476
  case "User":
448
477
  to_addr = user.email;
@@ -481,10 +510,10 @@ module.exports = {
481
510
  const from = getState().getConfig("email_from");
482
511
  const attachments = await loadAttachments(attachment_path, row, user ? user : { role_id: 100 });
483
512
  const the_subject = subject_formula
484
- ? eval_expression(subject, row)
513
+ ? eval_expression(subject, useRow, user, "send_email subject formula")
485
514
  : subject;
486
515
  getState().log(3, `Sending email from ${from} to ${to_addr} with subject ${the_subject}`);
487
- const cc = cc_email ? interpolate(cc_email, row, user) : undefined;
516
+ const cc = cc_email ? interpolate(cc_email, useRow, user) : undefined;
488
517
  const email = {
489
518
  from,
490
519
  to: to_addr,
@@ -626,6 +655,13 @@ module.exports = {
626
655
  type: "Bool",
627
656
  showIf: table ? { table: table.name } : {},
628
657
  },
658
+ {
659
+ name: "where",
660
+ label: "Recalculate where",
661
+ sublabel: "Where-expression for subset of rows to recalculate",
662
+ type: "String",
663
+ class: "validate-expression",
664
+ },
629
665
  ];
630
666
  },
631
667
  /**
@@ -633,7 +669,7 @@ module.exports = {
633
669
  * @param {object} opts.configuration
634
670
  * @returns {Promise<void>}
635
671
  */
636
- run: async ({ table, row, configuration }) => {
672
+ run: async ({ table, row, configuration, user }) => {
637
673
  const table_for_recalc = Table.findOne({
638
674
  name: configuration.table,
639
675
  });
@@ -644,6 +680,10 @@ module.exports = {
644
680
  row[table.pk_name]) {
645
681
  await table.updateRow({}, row[table.pk_name], undefined, true);
646
682
  }
683
+ else if (configuration.where) {
684
+ const where = eval_expression(configuration.where, row || {}, user, "recalculate_stored_fields where");
685
+ recalculate_for_stored(table_for_recalc, where);
686
+ }
647
687
  else if (table_for_recalc)
648
688
  recalculate_for_stored(table_for_recalc);
649
689
  else
@@ -787,6 +827,7 @@ module.exports = {
787
827
  "Back",
788
828
  "Reload page",
789
829
  "Close modal",
830
+ "Close tab",
790
831
  ],
791
832
  },
792
833
  },
@@ -807,6 +848,8 @@ module.exports = {
807
848
  return { popup: url1 };
808
849
  case "Back":
809
850
  return { eval_js: isNode() ? "history.back()" : "parent.goBack()" };
851
+ case "Close tab":
852
+ return { eval_js: "window.close()" };
810
853
  case "Close modal":
811
854
  return { eval_js: "close_saltcorn_modal()" };
812
855
  case "Reload page":
@@ -869,7 +912,13 @@ module.exports = {
869
912
  type: "String",
870
913
  required: true,
871
914
  attributes: {
872
- options: ["Submit", "Save", "Reset", "Submit with Ajax"],
915
+ options: [
916
+ "Submit",
917
+ "Save",
918
+ "Reset",
919
+ "Submit with Ajax",
920
+ "Ajax Save Form Data",
921
+ ],
873
922
  },
874
923
  },
875
924
  ],
@@ -894,6 +943,8 @@ module.exports = {
894
943
  return { eval_js: jqGet + ".trigger('reset')" };
895
944
  case "Submit with Ajax":
896
945
  return { eval_js: `submitWithAjax(${jqGet})` };
946
+ case "Ajax Save Form Data":
947
+ return { eval_js: `ajaxSubmitForm(${jqGet}, true)` };
897
948
  default:
898
949
  return { eval_js: jqGet + ".submit()" };
899
950
  }
@@ -948,6 +999,9 @@ module.exports = {
948
999
  * @returns {Promise<object[]>}
949
1000
  */
950
1001
  description: "Run arbitrary JavaScript code",
1002
+ configFormOptions: {
1003
+ formStyle: "vert",
1004
+ },
951
1005
  configFields: async ({ table }) => {
952
1006
  const fields = table ? table.getFields().map((f) => f.name) : [];
953
1007
  const vars = [
@@ -1023,6 +1077,77 @@ module.exports = {
1023
1077
  **/
1024
1078
  run: run_code,
1025
1079
  },
1080
+ run_js_code_in_field: {
1081
+ /**
1082
+ * @param {object} opts
1083
+ * @param {object} opts.table
1084
+ * @returns {Promise<object[]>}
1085
+ */
1086
+ description: "Run arbitrary JavaScript code from a String field",
1087
+ configFields: async ({ table }) => {
1088
+ const field_opts = table.fields
1089
+ .filter((f) => f.type?.name === "String")
1090
+ .map((f) => f.name);
1091
+ table.fields.forEach((f) => {
1092
+ if (f.is_fkey && f.type !== "File") {
1093
+ const refTable = Table.findOne({ name: f.reftable_name });
1094
+ if (!refTable)
1095
+ throw new Error(`Unable to find table '${f.reftable_name}`);
1096
+ field_opts.push(...refTable.fields
1097
+ .filter((jf) => jf.type?.name === "String")
1098
+ .map((jf) => `${f.name}.${jf.name}`));
1099
+ }
1100
+ });
1101
+ return [
1102
+ {
1103
+ name: "code_field",
1104
+ label: "Code field",
1105
+ sublabel: "String field that contains the JavaScript code to run",
1106
+ type: "String",
1107
+ required: true,
1108
+ attributes: {
1109
+ options: field_opts,
1110
+ },
1111
+ },
1112
+ {
1113
+ name: "run_where",
1114
+ label: "Run where",
1115
+ input_type: "select",
1116
+ options: ["Server", "Client page"],
1117
+ },
1118
+ ];
1119
+ },
1120
+ requireRow: true,
1121
+ /**
1122
+ * @type {base-plugin/actions~run_code}
1123
+ * @see base-plugin/actions~run_code
1124
+ **/
1125
+ run: async ({ table, configuration: { code_field, run_where }, row, ...rest }) => {
1126
+ let code;
1127
+ if (code_field.includes(".")) {
1128
+ const [ref, target] = code_field.split(".");
1129
+ if (typeof row[ref] === "object")
1130
+ code = row[ref][target];
1131
+ else if (!row[ref])
1132
+ return;
1133
+ else {
1134
+ const keyfield = table.getField(ref);
1135
+ const refTable = Table.findOne({ name: keyfield.reftable_name });
1136
+ const refRow = await refTable.getRow({ id: row[ref] });
1137
+ code = refRow[target];
1138
+ }
1139
+ }
1140
+ else
1141
+ code = row[code_field];
1142
+ code = code || "";
1143
+ return await run_code({
1144
+ ...rest,
1145
+ table,
1146
+ row,
1147
+ configuration: { run_where, code },
1148
+ });
1149
+ },
1150
+ },
1026
1151
  duplicate_row_prefill_edit: {
1027
1152
  configFields: async ({ table }) => {
1028
1153
  const fields = table ? table.getFields() : [];
@@ -1254,7 +1379,7 @@ module.exports = {
1254
1379
  },
1255
1380
  run: async ({ row, user, configuration: { view, new_state_fml } }) => {
1256
1381
  if (new_state_fml) {
1257
- const new_state = eval_expression(new_state_fml, row || {}, user);
1382
+ const new_state = eval_expression(new_state_fml, row || {}, user, "reload_embedded_view new state formula");
1258
1383
  const newqs = objectToQueryString(new_state);
1259
1384
  return {
1260
1385
  eval_js: `reload_embedded_view('${view}', '${newqs}')`,
@@ -1317,7 +1442,7 @@ module.exports = {
1317
1442
  ? { email: user_spec }
1318
1443
  : user_spec === "*"
1319
1444
  ? {}
1320
- : eval_expression(user_spec, row || {});
1445
+ : eval_expression(user_spec, row || {}, user, "Notify user user where");
1321
1446
  const users = await User.find(user_where);
1322
1447
  for (const user of users) {
1323
1448
  await Notification.create({