@saltcorn/server 1.1.0-beta.2 → 1.1.0-beta.20

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.
@@ -40,6 +40,19 @@ $(window).resize(() => {
40
40
  setScreenInfoCookie();
41
41
  });
42
42
 
43
+ function get_current_state_url(e) {
44
+ const localizer = e ? $(e).closest("[data-sc-local-state]") : [];
45
+ let $modal = $("#scmodal");
46
+ if (localizer.length) {
47
+ const localState = localizer.attr("data-sc-local-state") || "";
48
+ return localState;
49
+ } else if ($modal.length === 0 || !$modal.hasClass("show"))
50
+ return getIsNode()
51
+ ? window.location.href
52
+ : parent.saltcorn.mobileApp.navigation.currentUrl();
53
+ else return $modal.prop("data-modal-state");
54
+ }
55
+
43
56
  //avoids hiding in overflow:hidden
44
57
  function init_bs5_dropdowns() {
45
58
  $("body").on(
@@ -704,7 +717,7 @@ function doMobileTransforms() {
704
717
  href: [
705
718
  {
706
719
  web: "javascript:history.back()",
707
- mobile: "javascript:parent.goBack()",
720
+ mobile: "javascript:parent.saltcorn.mobileApp.navigation.goBack()",
708
721
  },
709
722
  {
710
723
  web: "javascript:ajax_modal",
@@ -714,7 +727,7 @@ function doMobileTransforms() {
714
727
  onclick: [
715
728
  {
716
729
  web: "history.back()",
717
- mobile: "parent.goBack()",
730
+ mobile: "parent.saltcorn.mobileApp.navigation.goBack()",
718
731
  },
719
732
  {
720
733
  web: "ajax_modal",
@@ -727,6 +740,22 @@ function doMobileTransforms() {
727
740
  ],
728
741
  };
729
742
 
743
+ // change /plugins or plugins to sc_plugins
744
+ // capacitor reserves the plugins prefix for cordova plugins
745
+ const normalisePluginsPrefix = (path) => {
746
+ if (path.startsWith("/plugins/") || path.startsWith("plugins/"))
747
+ return path.replace(/\/?plugins\//, "sc_plugins/");
748
+ return path;
749
+ };
750
+ $("link").each(function () {
751
+ const path = $(this).attr("href");
752
+ if (path) $(this).attr("href", normalisePluginsPrefix(path));
753
+ });
754
+ $("script").each(function () {
755
+ const path = $(this).attr("src");
756
+ if (path) $(this).attr("src", normalisePluginsPrefix(path));
757
+ });
758
+
730
759
  $("a").each(function () {
731
760
  let path = $(this).attr("href") || "";
732
761
  if (path.startsWith("http")) {
@@ -807,48 +836,46 @@ function doMobileTransforms() {
807
836
  });
808
837
 
809
838
  $("[mobile-img-path]").each(async function () {
810
- if (parent.loadEncodedFile) {
811
- const fileId = $(this).attr("mobile-img-path");
812
- const base64Encoded = await parent.loadEncodedFile(fileId);
813
- this.src = base64Encoded;
814
- }
839
+ const fileId = $(this).attr("mobile-img-path");
840
+ const base64Encoded =
841
+ await parent.saltcorn.mobileApp.common.loadEncodedFile(fileId);
842
+ this.src = base64Encoded;
815
843
  });
816
844
 
817
845
  $("[mobile-bg-img-path]").each(async function () {
818
- if (parent.loadEncodedFile) {
819
- const fileId = $(this).attr("mobile-bg-img-path");
820
- if (fileId) {
821
- const base64Encoded = await parent.loadEncodedFile(fileId);
822
- this.style.backgroundImage = `url("${base64Encoded}")`;
823
- }
846
+ const fileId = $(this).attr("mobile-bg-img-path");
847
+ if (fileId) {
848
+ const base64Encoded =
849
+ await parent.saltcorn.mobileApp.common.loadEncodedFile(fileId);
850
+ this.style.backgroundImage = `url("${base64Encoded}")`;
824
851
  }
825
852
  });
826
853
 
827
854
  $("img:not([mobile-img-path]):not([mobile-bg-img-path])").each(
828
855
  async function () {
829
- if (parent.loadEncodedFile) {
830
- const jThis = $(this);
831
- const src = jThis.attr("src");
832
- if (src?.includes("/files/serve/")) {
833
- const tokens = src.split("/files/serve/");
834
- if (tokens.length > 1) {
835
- const fileId = tokens[1];
836
- const base64Encoded = await parent.loadEncodedFile(fileId);
837
- this.src = base64Encoded;
838
- }
839
- } else if (src?.includes("/files/resize/")) {
840
- const tokens = src.split("/files/resize/");
841
- if (tokens.length > 1) {
842
- const idAndDims = tokens[1].split("/");
843
- const width = idAndDims[0];
844
- const height = idAndDims.length > 2 ? idAndDims[1] : undefined;
845
- const fileId = idAndDims[idAndDims.length - 1];
846
- const style = { width: `${width || 50}px` };
847
- if (height > 0) style.height = `${height}px`;
848
- const base64Encoded = await parent.loadEncodedFile(fileId);
849
- this.src = base64Encoded;
850
- jThis.css(style);
851
- }
856
+ const jThis = $(this);
857
+ const src = jThis.attr("src");
858
+ if (src?.includes("/files/serve/")) {
859
+ const tokens = src.split("/files/serve/");
860
+ if (tokens.length > 1) {
861
+ const fileId = tokens[1];
862
+ const base64Encoded =
863
+ await parent.saltcorn.mobileApp.common.loadEncodedFile(fileId);
864
+ this.src = base64Encoded;
865
+ }
866
+ } else if (src?.includes("/files/resize/")) {
867
+ const tokens = src.split("/files/resize/");
868
+ if (tokens.length > 1) {
869
+ const idAndDims = tokens[1].split("/");
870
+ const width = idAndDims[0];
871
+ const height = idAndDims.length > 2 ? idAndDims[1] : undefined;
872
+ const fileId = idAndDims[idAndDims.length - 1];
873
+ const style = { width: `${width || 50}px` };
874
+ if (height > 0) style.height = `${height}px`;
875
+ const base64Encoded =
876
+ await parent.saltcorn.mobileApp.common.loadEncodedFile(fileId);
877
+ this.src = base64Encoded;
878
+ jThis.css(style);
852
879
  }
853
880
  }
854
881
  }
@@ -1064,11 +1091,12 @@ function initialize_page() {
1064
1091
  codes.forEach((el) => {
1065
1092
  //console.log($(el).attr("mode"), el);
1066
1093
  if ($(el).hasClass("codemirror-enabled")) return;
1067
-
1068
- const cm = CodeMirror.fromTextArea(el, {
1094
+ const cmOpts = {
1069
1095
  lineNumbers: true,
1070
1096
  mode: $(el).attr("mode"),
1071
- });
1097
+ };
1098
+ if (_sc_lightmode === "dark") cmOpts.theme = "blackboard";
1099
+ const cm = CodeMirror.fromTextArea(el, cmOpts);
1072
1100
  $(el).addClass("codemirror-enabled");
1073
1101
  cm.on(
1074
1102
  "change",
@@ -1139,11 +1167,13 @@ function initialize_page() {
1139
1167
  }
1140
1168
  }
1141
1169
  }
1170
+
1142
1171
  setTimeout(() => {
1143
1172
  $("#toasts-area")
1144
1173
  .find(".show[rendered='server-side'][type='success']")
1145
1174
  .removeClass("show");
1146
1175
  }, 5000);
1176
+
1147
1177
  $(".lazy-accoordion").on("show.bs.collapse", function (e) {
1148
1178
  const $e = $(e.target).find("[data-sc-view-source]");
1149
1179
  if ($.trim($e.html()) == "") {
@@ -1550,14 +1580,15 @@ async function common_done(res, viewnameOrElem, isWeb = true) {
1550
1580
  });
1551
1581
  }
1552
1582
  if (res.eval_js) await handle(res.eval_js, eval_it);
1553
- else if (res.goto) {
1583
+ /// TODO got and resume_workflow - use localStorage
1584
+ if (res.goto) {
1554
1585
  if (!isWeb) {
1555
1586
  const next = new URL(res.goto, "http://localhost");
1556
1587
  const pathname = next.pathname;
1557
1588
  if (pathname.startsWith("/view/") || pathname.startsWith("/page/")) {
1558
1589
  const route = `get${pathname}${next.search ? "?" + next.search : ""}`;
1559
- await parent.handleRoute(route);
1560
- } else parent.cordova.InAppBrowser.open(res.goto, "_system");
1590
+ await parent.saltcorn.mobileApp.navigation.handleRoute(route);
1591
+ } else parent.cordova.InAppBrowser.open(res.goto, "_system"); // TODO
1561
1592
  } else if (res.target === "_blank") window.open(res.goto, "_blank").focus();
1562
1593
  else {
1563
1594
  const prev = new URL(window.location.href);
@@ -1572,6 +1603,9 @@ async function common_done(res, viewnameOrElem, isWeb = true) {
1572
1603
  location.reload();
1573
1604
  }
1574
1605
  }
1606
+ if (res.resume_workflow) {
1607
+ ajax_post_json(`/actions/resume-workflow/${res.resume_workflow}`, {});
1608
+ }
1575
1609
  if (res.reload_page) {
1576
1610
  (isWeb ? location : parent).reload(); //TODO notify to cookie if reload or goto
1577
1611
  }
@@ -85,18 +85,15 @@ div[data-inline-edit-dest-url]:hover .editicon {
85
85
  border-left: none;
86
86
  border-color: #95a5a6;
87
87
  padding-left: 0.3rem;
88
- background-color: #ffffff;
89
88
  }
90
89
 
91
90
  .search-bar input[type="search"] {
92
91
  border-color: #95a5a6;
93
92
  padding-left: 0.3rem;
94
- background-color: #ffffff;
95
93
  }
96
94
 
97
95
  .search-bar button.search-bar {
98
96
  border-color: #95a5a6;
99
- background-color: #ffffff;
100
97
  border-left: 1px solid #95a5a6 !important;
101
98
  border-top: 1px solid #95a5a6 !important;
102
99
  border-bottom: 1px solid #95a5a6 !important;
@@ -358,7 +355,7 @@ table.table-inner-grid td {
358
355
  }
359
356
 
360
357
  .w-unset {
361
- width: unset;
358
+ width: unset !important;
362
359
  }
363
360
 
364
361
  .preview-text {
@@ -610,4 +607,10 @@ button.monospace-copy-btn {
610
607
 
611
608
  i[class^="unicode-"], i[class*=" unicode-"] {
612
609
  font-style: normal;
610
+ }
611
+
612
+ .tabulator.table-dark:not(.thead-light) .tabulator-footer, .tabulator.table-dark:not(.thead-light) .tabulator-footer .tabulator-col {
613
+ background-color: #212529;
614
+ border-color: #32383e;
615
+ color: #fff;
613
616
  }
@@ -84,17 +84,6 @@ function removeQueryStringParameter(uri1, key) {
84
84
  return uri + hash;
85
85
  }
86
86
 
87
- function get_current_state_url(e) {
88
- const localizer = e ? $(e).closest("[data-sc-local-state]") : [];
89
- let $modal = $("#scmodal");
90
- if (localizer.length) {
91
- const localState = localizer.attr("data-sc-local-state") || "";
92
- return localState;
93
- } else if ($modal.length === 0 || !$modal.hasClass("show"))
94
- return window.location.href;
95
- else return $modal.prop("data-modal-state");
96
- }
97
-
98
87
  function select_id(id, e) {
99
88
  pjax_to(updateQueryStringParameter(get_current_state_url(e), "id", id), e);
100
89
  }
@@ -423,6 +412,27 @@ function saveAndContinueAsync(e) {
423
412
  });
424
413
  }
425
414
 
415
+ function saveAndContinueIfValid(e, k, event) {
416
+ //wait for applyShowIf
417
+ setTimeout(() => {
418
+ if (
419
+ event &&
420
+ event.target &&
421
+ event.target.classList &&
422
+ event.target.classList.contains("no-form-change")
423
+ )
424
+ return;
425
+ var form = $(e).closest("form");
426
+
427
+ if (form[0].checkValidity?.() === false) {
428
+ form[0].reportValidity();
429
+ return;
430
+ }
431
+
432
+ saveAndContinue(e, k, event);
433
+ });
434
+ }
435
+
426
436
  function saveAndContinue(e, k, event) {
427
437
  if (
428
438
  event &&
@@ -432,6 +442,7 @@ function saveAndContinue(e, k, event) {
432
442
  )
433
443
  return;
434
444
  var form = $(e).closest("form");
445
+
435
446
  let focusedEl = null;
436
447
  if (!event || !event.srcElement) {
437
448
  const el = form.find("select[sc-received-focus]")[0];
@@ -460,6 +471,7 @@ function saveAndContinue(e, k, event) {
460
471
  data: form_data,
461
472
  success: function (res) {
462
473
  ajax_indicator(false);
474
+ form.removeAttr("data-unsaved-changes");
463
475
  form.parent().find(".full-form-error").text("");
464
476
  if (res.id && form.find("input[name=id")) {
465
477
  form.append(
@@ -890,9 +902,9 @@ function build_mobile_app(button) {
890
902
 
891
903
  if (
892
904
  params.useDocker &&
893
- !window.cordovaBuilderAvailable &&
905
+ !window.capacitorBuilderAvailable &&
894
906
  !confirm(
895
- "Docker is selected but the Cordova builder seems not to be installed. " +
907
+ "Docker is selected but the Capacitor builder seems not to be installed. " +
896
908
  "Do you really want to continue?"
897
909
  )
898
910
  ) {
@@ -935,11 +947,11 @@ function build_mobile_app(button) {
935
947
  });
936
948
  }
937
949
 
938
- function pull_cordova_builder() {
939
- ajax_post("/admin/mobile-app/pull-cordova-builder", {
950
+ function pull_capacitor_builder() {
951
+ ajax_post("/admin/mobile-app/pull-capacitor-builder", {
940
952
  success: () => {
941
953
  notifyAlert(
942
- "Pulling the the cordova-builder. " +
954
+ "Pulling the the capacitor-builder. " +
943
955
  "To see the progress, open the logs viewer with the System logging verbosity set to 'All'."
944
956
  );
945
957
  },
@@ -989,12 +1001,12 @@ function check_xcodebuild() {
989
1001
  });
990
1002
  }
991
1003
 
992
- function check_cordova_builder() {
993
- $.ajax("/admin/mobile-app/check-cordova-builder", {
1004
+ function check_capacitor_builder() {
1005
+ $.ajax("/admin/mobile-app/check-capacitor-builder", {
994
1006
  type: "GET",
995
1007
  success: function (res) {
996
- window.cordovaBuilderAvailable = !!res.installed;
997
- if (window.cordovaBuilderAvailable) {
1008
+ window.capacitorBuilderAvailable = !!res.installed;
1009
+ if (window.capacitorBuilderAvailable) {
998
1010
  $("#dockerBuilderStatusId").html(
999
1011
  `<span>
1000
1012
  installed<i class="ps-2 fas fa-check text-success"></i>
@@ -1088,7 +1100,7 @@ function toggle_tbl_sync() {
1088
1100
  function toggle_android_platform() {
1089
1101
  if ($("#androidCheckboxId")[0].checked === true) {
1090
1102
  $("#dockerCheckboxId").attr("hidden", false);
1091
- $("#dockerCheckboxId").attr("checked", window.cordovaBuilderAvailable);
1103
+ $("#dockerCheckboxId").attr("checked", window.capacitorBuilderAvailable);
1092
1104
  $("#dockerLabelId").removeClass("d-none");
1093
1105
  } else {
1094
1106
  $("#dockerCheckboxId").attr("hidden", true);
@@ -1189,6 +1201,29 @@ function installPWA() {
1189
1201
  }
1190
1202
  }
1191
1203
 
1204
+ function check_unsaved_form(event, script_tag) {
1205
+ const form = $(script_tag).parent().find("form");
1206
+ if (form.attr("data-unsaved-changes")) {
1207
+ event.preventDefault();
1208
+ event.returnValue = true;
1209
+ }
1210
+ }
1211
+ function check_delete_unsaved(tablename, script_tag) {
1212
+ const form = $(script_tag).parent().find("form");
1213
+ if (form.length && !form.attr("data-form-changed")) {
1214
+ //delete row
1215
+ const rec = get_form_record(form);
1216
+
1217
+ $.ajax({
1218
+ url: `/api/${tablename}/${rec.id}`,
1219
+ type: "DELETE",
1220
+ headers: {
1221
+ "CSRF-Token": _sc_globalCsrf,
1222
+ },
1223
+ });
1224
+ }
1225
+ }
1226
+
1192
1227
  (() => {
1193
1228
  const e = document.querySelector("[data-sidebar-toggler]");
1194
1229
  let closed = localStorage.getItem("sidebarClosed") === "true";