@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.
- package/auth/admin.js +1 -1
- package/auth/roleadmin.js +10 -2
- package/help/{Cordova Builder.tmd → Capacitor Builder.tmd } +1 -1
- package/help/Configuration keys.tmd +5 -0
- package/help/index.js +2 -0
- package/load_plugins.js +9 -3
- package/locales/en.json +21 -1
- package/locales/pl.json +19 -2
- package/markup/admin.js +7 -3
- package/package.json +9 -9
- package/public/codemirror.css +33 -0
- package/public/flatpickr-dark.css +795 -0
- package/public/gridedit.js +1 -1
- package/public/mermaid.min.js +1077 -792
- package/public/saltcorn-common.js +76 -42
- package/public/saltcorn.css +7 -4
- package/public/saltcorn.js +56 -21
- package/routes/actions.js +937 -4
- package/routes/admin.js +59 -85
- package/routes/config.js +39 -25
- package/routes/eventlog.js +41 -1
- package/routes/fields.js +8 -2
- package/routes/homepage.js +13 -3
- package/routes/list.js +17 -1
- package/routes/registry.js +45 -3
- package/routes/tables.js +58 -20
- package/routes/tenant.js +53 -3
- package/tests/plugin_install.test.js +10 -10
- package/tests/plugins.test.js +6 -6
- package/wrapper.js +3 -1
|
@@ -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
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
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
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
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
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
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
|
-
|
|
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
|
}
|
package/public/saltcorn.css
CHANGED
|
@@ -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
|
}
|
package/public/saltcorn.js
CHANGED
|
@@ -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.
|
|
905
|
+
!window.capacitorBuilderAvailable &&
|
|
894
906
|
!confirm(
|
|
895
|
-
"Docker is selected but the
|
|
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
|
|
939
|
-
ajax_post("/admin/mobile-app/pull-
|
|
950
|
+
function pull_capacitor_builder() {
|
|
951
|
+
ajax_post("/admin/mobile-app/pull-capacitor-builder", {
|
|
940
952
|
success: () => {
|
|
941
953
|
notifyAlert(
|
|
942
|
-
"Pulling the the
|
|
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
|
|
993
|
-
$.ajax("/admin/mobile-app/check-
|
|
1004
|
+
function check_capacitor_builder() {
|
|
1005
|
+
$.ajax("/admin/mobile-app/check-capacitor-builder", {
|
|
994
1006
|
type: "GET",
|
|
995
1007
|
success: function (res) {
|
|
996
|
-
window.
|
|
997
|
-
if (window.
|
|
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.
|
|
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";
|