@saltcorn/server 0.8.0-beta.4 → 0.8.1-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.
- package/app.js +7 -6
- package/auth/admin.js +260 -217
- package/auth/index.js +20 -20
- package/auth/roleadmin.js +2 -9
- package/auth/routes.js +193 -139
- package/auth/testhelp.js +62 -55
- package/fixture_persons.js +1 -1
- package/index.js +22 -22
- package/locales/en.json +13 -1
- package/locales/fr.json +14 -2
- package/locales/ru.json +25 -19
- package/markup/admin.js +22 -15
- package/markup/blockly.js +1 -1
- package/markup/expression_blurb.js +15 -15
- package/markup/forms.js +21 -22
- package/markup/index.js +20 -20
- package/markup/plugin-store.js +4 -4
- package/package.json +8 -8
- package/public/diagram_utils.js +22 -9
- package/public/saltcorn-common.js +128 -68
- package/public/saltcorn.css +6 -0
- package/public/saltcorn.js +68 -20
- package/restart_watcher.js +157 -157
- package/routes/actions.js +4 -11
- package/routes/admin.js +14 -6
- package/routes/api.js +11 -18
- package/routes/common_lists.js +127 -130
- package/routes/delete.js +2 -2
- package/routes/edit.js +1 -1
- package/routes/fields.js +48 -2
- package/routes/files.js +112 -94
- package/routes/homepage.js +1 -1
- package/routes/infoarch.js +1 -1
- package/routes/list.js +6 -5
- package/routes/packs.js +1 -2
- package/routes/pageedit.js +1 -1
- package/routes/tag_entries.js +1 -1
- package/routes/tenant.js +2 -1
- package/routes/utils.js +3 -1
- package/routes/view.js +14 -2
- package/routes/viewedit.js +35 -0
- package/s3storage.js +13 -11
- package/serve.js +35 -31
- package/systemd.js +23 -21
- package/tests/fields.test.js +23 -0
- package/wrapper.js +46 -45
package/public/diagram_utils.js
CHANGED
|
@@ -9,6 +9,8 @@ let tagFilterEnabled = false;
|
|
|
9
9
|
|
|
10
10
|
let activePopper = null;
|
|
11
11
|
|
|
12
|
+
const maxPreviewHeight = "350px";
|
|
13
|
+
|
|
12
14
|
function initMouseOver() {
|
|
13
15
|
cy.on("mouseover", "node", (event) => {
|
|
14
16
|
const node = event.target;
|
|
@@ -41,7 +43,7 @@ function initMouseOver() {
|
|
|
41
43
|
function buildCard(node) {
|
|
42
44
|
const { type, label } = node.data();
|
|
43
45
|
const html = `
|
|
44
|
-
<div class="card" style="width:
|
|
46
|
+
<div class="card" style="width: 20rem;">
|
|
45
47
|
<div class="card-header">
|
|
46
48
|
<h5 class="card-title">${type}</h5>
|
|
47
49
|
<h6 class="card-subtitle text-muted">${label}</h6>
|
|
@@ -49,7 +51,9 @@ function buildCard(node) {
|
|
|
49
51
|
<div class="card-body">
|
|
50
52
|
${buildTagBadges(node)}
|
|
51
53
|
${buildCardBody(node)}
|
|
52
|
-
|
|
54
|
+
<div>
|
|
55
|
+
${type === "page" || type === "view" ? buildPreviewDiv(node) : ""}
|
|
56
|
+
</div>
|
|
53
57
|
${type === "page" || type === "view" ? buildMinRoleSelect(node) : ""}
|
|
54
58
|
</div>
|
|
55
59
|
</div>
|
|
@@ -70,26 +74,35 @@ function buildPreview(node) {
|
|
|
70
74
|
"CSRF-Token": _sc_globalCsrf,
|
|
71
75
|
},
|
|
72
76
|
success: (res) => {
|
|
73
|
-
$(
|
|
77
|
+
$(`[id='${previewId}']`).html(`
|
|
74
78
|
<div
|
|
75
79
|
id="preview_wrapper"
|
|
76
|
-
style="min-height: 70px;"
|
|
80
|
+
style="min-height: 70px; pointer-events: none;"
|
|
77
81
|
>
|
|
78
82
|
${res}
|
|
79
83
|
</div></div></div>`);
|
|
80
|
-
const previewDiv = $(
|
|
84
|
+
const previewDiv = $(`[id='${previewId}']`);
|
|
81
85
|
const pos = previewDiv.position();
|
|
82
86
|
const cssBase = `
|
|
87
|
+
max-height: ${maxPreviewHeight};
|
|
88
|
+
pointer-events: none;
|
|
83
89
|
position: absolute; top: ${pos.top}px; left: ${pos.left}px;
|
|
84
90
|
width: ${previewDiv.width()}px; height: ${previewDiv.height() + 12}px;`;
|
|
85
|
-
|
|
86
|
-
|
|
91
|
+
const previewLabelId = `${previewId}_label`;
|
|
92
|
+
const previewOverlayId = `${previewId}_overlay`;
|
|
93
|
+
$(`[id='${previewLabelId}']`).remove();
|
|
94
|
+
$(`[id='${previewOverlayId}']`).remove();
|
|
95
|
+
$(`[id='${previewId}']`).after(`
|
|
96
|
+
<div
|
|
97
|
+
id="${previewOverlayId}"
|
|
87
98
|
style="${cssBase}
|
|
88
99
|
background-color: black; opacity: 0.1;
|
|
89
100
|
z-index: 10;"
|
|
90
101
|
>
|
|
91
102
|
</div>
|
|
92
|
-
<div
|
|
103
|
+
<div
|
|
104
|
+
id="${previewLabelId}"
|
|
105
|
+
style="${cssBase} opacity: 0.5;">
|
|
93
106
|
<h2 class="preview-text fw-bold text-danger">
|
|
94
107
|
Preview
|
|
95
108
|
</h2>
|
|
@@ -105,7 +118,7 @@ function buildPreview(node) {
|
|
|
105
118
|
function buildPreviewDiv(node) {
|
|
106
119
|
const previewId = `preview_${node.id()}`;
|
|
107
120
|
return `
|
|
108
|
-
<div class="my-2" id="${previewId}" style="min-height: 70px;">
|
|
121
|
+
<div class="my-2" id="${previewId}" style="min-height: 70px; max-height: ${maxPreviewHeight}; overflow: scroll;">
|
|
109
122
|
<div style="opacity: 0.5;">
|
|
110
123
|
<h2>
|
|
111
124
|
<span class="fw-bold text-danger">Preview</span>
|
|
@@ -36,11 +36,11 @@ function add_repeater(nm) {
|
|
|
36
36
|
newe.appendTo($("div.repeats-" + nm));
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
const _apply_showif_plugins = []
|
|
39
|
+
const _apply_showif_plugins = [];
|
|
40
40
|
|
|
41
|
-
const add_apply_showif_plugin = p => {
|
|
42
|
-
_apply_showif_plugins.push(p)
|
|
43
|
-
}
|
|
41
|
+
const add_apply_showif_plugin = (p) => {
|
|
42
|
+
_apply_showif_plugins.push(p);
|
|
43
|
+
};
|
|
44
44
|
function apply_showif() {
|
|
45
45
|
$("[data-show-if]").each(function (ix, element) {
|
|
46
46
|
var e = $(element);
|
|
@@ -92,7 +92,8 @@ function apply_showif() {
|
|
|
92
92
|
} else {
|
|
93
93
|
e.append(
|
|
94
94
|
$(
|
|
95
|
-
`<option ${
|
|
95
|
+
`<option ${
|
|
96
|
+
`${current}` === `${o.value}` ? "selected" : ""
|
|
96
97
|
} value="${o.value}">${o.label}</option>`
|
|
97
98
|
)
|
|
98
99
|
);
|
|
@@ -117,76 +118,127 @@ function apply_showif() {
|
|
|
117
118
|
e.attr("data-selected", ec.target.value);
|
|
118
119
|
});
|
|
119
120
|
|
|
120
|
-
const currentOptionsSet = e.prop(
|
|
121
|
+
const currentOptionsSet = e.prop("data-fetch-options-current-set");
|
|
121
122
|
if (currentOptionsSet === qs) return;
|
|
122
123
|
|
|
123
124
|
const activate = (success, qs) => {
|
|
124
125
|
e.empty();
|
|
125
|
-
e.prop(
|
|
126
|
+
e.prop("data-fetch-options-current-set", qs);
|
|
126
127
|
if (!dynwhere.required) e.append($(`<option></option>`));
|
|
127
128
|
let currentDataOption = undefined;
|
|
128
|
-
const dataOptions = []
|
|
129
|
+
const dataOptions = [];
|
|
129
130
|
success.forEach((r) => {
|
|
130
131
|
const label = dynwhere.label_formula
|
|
131
132
|
? new Function(
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
: r[dynwhere.summary_field]
|
|
136
|
-
const value = r[dynwhere.refname]
|
|
137
|
-
const selected = `${current}` === `${r[dynwhere.refname]}
|
|
133
|
+
`{${Object.keys(r).join(",")}}`,
|
|
134
|
+
"return " + dynwhere.label_formula
|
|
135
|
+
)(r)
|
|
136
|
+
: r[dynwhere.summary_field];
|
|
137
|
+
const value = r[dynwhere.refname];
|
|
138
|
+
const selected = `${current}` === `${r[dynwhere.refname]}`;
|
|
138
139
|
dataOptions.push({ text: label, value });
|
|
139
140
|
if (selected) currentDataOption = value;
|
|
140
|
-
const html = `<option ${
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
);
|
|
141
|
+
const html = `<option ${
|
|
142
|
+
selected ? "selected" : ""
|
|
143
|
+
} value="${value}">${label}</option>`;
|
|
144
|
+
e.append($(html));
|
|
145
145
|
});
|
|
146
|
-
element.dispatchEvent(new Event(
|
|
146
|
+
element.dispatchEvent(new Event("RefreshSelectOptions"));
|
|
147
147
|
if (e.hasClass("selectized") && $().selectize) {
|
|
148
148
|
e.selectize()[0].selectize.clearOptions();
|
|
149
149
|
e.selectize()[0].selectize.addOption(dataOptions);
|
|
150
150
|
if (typeof currentDataOption !== "undefined")
|
|
151
151
|
e.selectize()[0].selectize.setValue(currentDataOption);
|
|
152
|
-
|
|
153
152
|
}
|
|
154
|
-
}
|
|
153
|
+
};
|
|
155
154
|
|
|
156
|
-
const cache = e.prop(
|
|
155
|
+
const cache = e.prop("data-fetch-options-cache") || {};
|
|
157
156
|
if (cache[qs]) {
|
|
158
|
-
activate(cache[qs], qs)
|
|
157
|
+
activate(cache[qs], qs);
|
|
159
158
|
} else
|
|
160
159
|
$.ajax(`/api/${dynwhere.table}?${qs}`).then((resp) => {
|
|
161
160
|
if (resp.success) {
|
|
162
|
-
activate(resp.success, qs)
|
|
163
|
-
const cacheNow = e.prop(
|
|
164
|
-
e.prop(
|
|
161
|
+
activate(resp.success, qs);
|
|
162
|
+
const cacheNow = e.prop("data-fetch-options-cache") || {};
|
|
163
|
+
e.prop("data-fetch-options-cache", {
|
|
164
|
+
...cacheNow,
|
|
165
|
+
[qs]: resp.success,
|
|
166
|
+
});
|
|
165
167
|
}
|
|
166
168
|
});
|
|
167
169
|
});
|
|
168
170
|
|
|
169
171
|
$("[data-source-url]").each(function (ix, element) {
|
|
170
172
|
const e = $(element);
|
|
171
|
-
const
|
|
173
|
+
const rec0 = get_form_record(e);
|
|
174
|
+
|
|
175
|
+
const relevantFieldsStr = e.attr("data-relevant-fields");
|
|
176
|
+
let rec;
|
|
177
|
+
if (relevantFieldsStr) {
|
|
178
|
+
rec = {};
|
|
179
|
+
relevantFieldsStr.split(",").forEach((k) => {
|
|
180
|
+
rec[k] = rec0[k];
|
|
181
|
+
});
|
|
182
|
+
} else rec = rec0;
|
|
183
|
+
const recS = JSON.stringify(rec);
|
|
184
|
+
|
|
185
|
+
const shown = e.prop("data-source-url-current");
|
|
186
|
+
if (shown === recS) return;
|
|
187
|
+
|
|
188
|
+
const cache = e.prop("data-source-url-cache") || {};
|
|
189
|
+
|
|
190
|
+
const activate_onchange_coldef = () => {
|
|
191
|
+
e.closest(".form-namespace")
|
|
192
|
+
.find("input,select, textarea")
|
|
193
|
+
.on("change", (ec) => {
|
|
194
|
+
const $ec = $(ec.target);
|
|
195
|
+
const k = $ec.attr("name");
|
|
196
|
+
if (!k || k === "_columndef") return;
|
|
197
|
+
const v = ec.target.value;
|
|
198
|
+
const $def = e
|
|
199
|
+
.closest(".form-namespace")
|
|
200
|
+
.find("input[name=_columndef]");
|
|
201
|
+
const def = JSON.parse($def.val());
|
|
202
|
+
def[k] = v;
|
|
203
|
+
$def.val(JSON.stringify(def));
|
|
204
|
+
});
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
if (typeof cache[recS] !== "undefined") {
|
|
208
|
+
e.html(cache[recS]);
|
|
209
|
+
activate_onchange_coldef();
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
172
212
|
ajax_post_json(e.attr("data-source-url"), rec, {
|
|
173
213
|
success: (data) => {
|
|
174
214
|
e.html(data);
|
|
215
|
+
const cacheNow = e.prop("data-source-url-cache") || {};
|
|
216
|
+
e.prop("data-source-url-cache", {
|
|
217
|
+
...cacheNow,
|
|
218
|
+
[recS]: data,
|
|
219
|
+
});
|
|
220
|
+
e.prop("data-source-url-current", recS);
|
|
221
|
+
activate_onchange_coldef();
|
|
175
222
|
},
|
|
176
223
|
error: (err) => {
|
|
177
224
|
console.error(err);
|
|
225
|
+
const cacheNow = e.prop("data-source-url-cache") || {};
|
|
226
|
+
e.prop("data-source-url-cache", {
|
|
227
|
+
...cacheNow,
|
|
228
|
+
[recS]: "",
|
|
229
|
+
});
|
|
178
230
|
e.html("");
|
|
179
231
|
},
|
|
180
232
|
});
|
|
181
233
|
});
|
|
182
|
-
_apply_showif_plugins.forEach(p => p())
|
|
234
|
+
_apply_showif_plugins.forEach((p) => p());
|
|
183
235
|
}
|
|
184
236
|
|
|
185
237
|
function splitTargetMatch(elemValue, target, keySpec) {
|
|
186
238
|
if (!elemValue) return false;
|
|
187
|
-
const [fld, keySpec1] = keySpec.split("|_")
|
|
188
|
-
const [sep, pos] = keySpec1.split("_")
|
|
189
|
-
const elemValueShort = elemValue.split(sep)[pos]
|
|
239
|
+
const [fld, keySpec1] = keySpec.split("|_");
|
|
240
|
+
const [sep, pos] = keySpec1.split("_");
|
|
241
|
+
const elemValueShort = elemValue.split(sep)[pos];
|
|
190
242
|
return elemValueShort === target;
|
|
191
243
|
}
|
|
192
244
|
|
|
@@ -195,7 +247,7 @@ function get_form_record(e, select_labels) {
|
|
|
195
247
|
e.closest(".form-namespace")
|
|
196
248
|
.find("input[name],select[name]")
|
|
197
249
|
.each(function () {
|
|
198
|
-
const name = $(this).attr("data-fieldname") || $(this).attr("name")
|
|
250
|
+
const name = $(this).attr("data-fieldname") || $(this).attr("name");
|
|
199
251
|
if (select_labels && $(this).prop("tagName").toLowerCase() === "select")
|
|
200
252
|
rec[name] = $(this).find("option:selected").text();
|
|
201
253
|
else if ($(this).prop("type") === "checkbox")
|
|
@@ -508,14 +560,16 @@ function notifyAlert(note, spin) {
|
|
|
508
560
|
}
|
|
509
561
|
|
|
510
562
|
$("#alerts-area")
|
|
511
|
-
.append(`<div class="alert alert-${type} alert-dismissible fade show ${
|
|
512
|
-
|
|
563
|
+
.append(`<div class="alert alert-${type} alert-dismissible fade show ${
|
|
564
|
+
spin ? "d-flex align-items-center" : ""
|
|
565
|
+
}" role="alert">
|
|
513
566
|
${txt}
|
|
514
|
-
${
|
|
515
|
-
|
|
516
|
-
|
|
567
|
+
${
|
|
568
|
+
spin
|
|
569
|
+
? `<div class="spinner-border ms-auto" role="status" aria-hidden="true"></div>`
|
|
570
|
+
: `<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close">
|
|
517
571
|
</button>`
|
|
518
|
-
|
|
572
|
+
}
|
|
519
573
|
</div>`);
|
|
520
574
|
}
|
|
521
575
|
|
|
@@ -532,8 +586,9 @@ function common_done(res, isWeb = true) {
|
|
|
532
586
|
(isWeb ? location : parent.location).reload(); //TODO notify to cookie if reload or goto
|
|
533
587
|
}
|
|
534
588
|
if (res.download) {
|
|
535
|
-
const dataurl = `data:${
|
|
536
|
-
|
|
589
|
+
const dataurl = `data:${
|
|
590
|
+
res.download.mimetype || "application/octet-stream"
|
|
591
|
+
};base64,${res.download.blob}`;
|
|
537
592
|
fetch(dataurl)
|
|
538
593
|
.then((res) => res.blob())
|
|
539
594
|
.then((blob) => {
|
|
@@ -553,15 +608,19 @@ function common_done(res, isWeb = true) {
|
|
|
553
608
|
else if (res.goto) {
|
|
554
609
|
if (res.target === "_blank") window.open(res.goto, "_blank").focus();
|
|
555
610
|
else {
|
|
556
|
-
const prev = new URL(window.location.href)
|
|
557
|
-
const next = new URL(res.goto, prev.origin)
|
|
611
|
+
const prev = new URL(window.location.href);
|
|
612
|
+
const next = new URL(res.goto, prev.origin);
|
|
558
613
|
window.location.href = res.goto;
|
|
559
|
-
if (
|
|
560
|
-
|
|
614
|
+
if (
|
|
615
|
+
prev.origin === next.origin &&
|
|
616
|
+
prev.pathname === next.pathname &&
|
|
617
|
+
next.hash !== prev.hash
|
|
618
|
+
)
|
|
619
|
+
location.reload();
|
|
561
620
|
}
|
|
562
621
|
}
|
|
563
622
|
if (res.popup) {
|
|
564
|
-
ajax_modal(res.popup)
|
|
623
|
+
ajax_modal(res.popup);
|
|
565
624
|
}
|
|
566
625
|
}
|
|
567
626
|
|
|
@@ -572,7 +631,9 @@ const repeaterCopyValuesToForm = (form, editor, noTriggerChange) => {
|
|
|
572
631
|
const $e = form.find(`input[name="${k}_${ix}"]`);
|
|
573
632
|
if ($e.length) $e.val(v);
|
|
574
633
|
else {
|
|
575
|
-
const $ne = $(
|
|
634
|
+
const $ne = $(
|
|
635
|
+
`<input type="hidden" data-repeater-ix="${ix}" name="${k}_${ix}"></input>`
|
|
636
|
+
);
|
|
576
637
|
$ne.val(v);
|
|
577
638
|
form.append($ne);
|
|
578
639
|
}
|
|
@@ -700,9 +761,9 @@ function room_older(viewname, room_id, btn) {
|
|
|
700
761
|
function init_room(viewname, room_id) {
|
|
701
762
|
const socket = parent?.config?.server_path
|
|
702
763
|
? io(parent.config.server_path, {
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
764
|
+
query: `jwt=${localStorage.getItem("auth_jwt")}`,
|
|
765
|
+
transports: ["websocket"],
|
|
766
|
+
})
|
|
706
767
|
: io({ transports: ["websocket"] });
|
|
707
768
|
|
|
708
769
|
socket.emit("join_room", [viewname, room_id]);
|
|
@@ -735,32 +796,31 @@ function cancel_form(form) {
|
|
|
735
796
|
}
|
|
736
797
|
|
|
737
798
|
function split_paste_handler(e) {
|
|
738
|
-
let clipboardData =
|
|
799
|
+
let clipboardData =
|
|
800
|
+
e.clipboardData || window.clipboardData || e.originalEvent.clipboardData;
|
|
739
801
|
|
|
740
|
-
const lines = clipboardData.getData(
|
|
802
|
+
const lines = clipboardData.getData("text").split(/\r\n/g);
|
|
741
803
|
|
|
742
804
|
// do normal thing if not multiline - do not interfere with ordinary copy paste
|
|
743
805
|
if (lines.length < 2) return;
|
|
744
806
|
e.preventDefault();
|
|
745
|
-
const form = $(e.target).closest(
|
|
807
|
+
const form = $(e.target).closest("form");
|
|
746
808
|
|
|
747
809
|
let matched = false;
|
|
748
810
|
|
|
749
|
-
form
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
if (
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
$elem.val(lines.shift())
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
811
|
+
form
|
|
812
|
+
.find("input:not(:disabled):not([readonly]):not(:hidden)")
|
|
813
|
+
.each(function (ix, element) {
|
|
814
|
+
if (!matched && element === e.target) matched = true;
|
|
815
|
+
if (matched && lines.length > 0) {
|
|
816
|
+
const $elem = $(element);
|
|
817
|
+
if (ix === 0 && $elem.attr("type") !== "number") {
|
|
818
|
+
//const existing = $elem.val()
|
|
819
|
+
//const pasted =
|
|
820
|
+
$elem.val(lines.shift());
|
|
821
|
+
} else $elem.val(lines.shift());
|
|
822
|
+
}
|
|
823
|
+
});
|
|
764
824
|
}
|
|
765
825
|
|
|
766
826
|
function is_paging_param(key) {
|
package/public/saltcorn.css
CHANGED
package/public/saltcorn.js
CHANGED
|
@@ -202,6 +202,19 @@ function view_post(viewname, route, data, onDone) {
|
|
|
202
202
|
});
|
|
203
203
|
}
|
|
204
204
|
let logged_errors = [];
|
|
205
|
+
let error_catcher_enabled = false;
|
|
206
|
+
function enable_error_catcher() {
|
|
207
|
+
if (error_catcher_enabled) return;
|
|
208
|
+
document.addEventListener(
|
|
209
|
+
"DOMContentLoaded",
|
|
210
|
+
function () {
|
|
211
|
+
window.onerror = globalErrorCatcher;
|
|
212
|
+
},
|
|
213
|
+
false
|
|
214
|
+
);
|
|
215
|
+
error_catcher_enabled = true;
|
|
216
|
+
}
|
|
217
|
+
|
|
205
218
|
function globalErrorCatcher(message, source, lineno, colno, error) {
|
|
206
219
|
if (error && error.preventDefault) error.preventDefault();
|
|
207
220
|
if (logged_errors.includes(message)) return;
|
|
@@ -260,16 +273,22 @@ function ajax_modal(url, opts = {}) {
|
|
|
260
273
|
if (opts.submitReload === false) $("#scmodal").addClass("no-submit-reload");
|
|
261
274
|
else $("#scmodal").removeClass("no-submit-reload");
|
|
262
275
|
$.ajax(url, {
|
|
276
|
+
headers: {
|
|
277
|
+
SaltcornModalRequest: "true",
|
|
278
|
+
},
|
|
263
279
|
success: function (res, textStatus, request) {
|
|
264
280
|
var title = request.getResponseHeader("Page-Title");
|
|
281
|
+
var width = request.getResponseHeader("SaltcornModalWidth");
|
|
282
|
+
if (width) $(".modal-dialog").css("max-width", width);
|
|
283
|
+
else $(".modal-dialog").css("max-width", "");
|
|
265
284
|
if (title) $("#scmodal .modal-title").html(decodeURIComponent(title));
|
|
266
285
|
$("#scmodal .modal-body").html(res);
|
|
267
286
|
$("#scmodal").prop("data-modal-state", url);
|
|
268
287
|
new bootstrap.Modal($("#scmodal")).show();
|
|
269
288
|
initialize_page();
|
|
270
|
-
(opts.onOpen || function () {
|
|
289
|
+
(opts.onOpen || function () {})(res);
|
|
271
290
|
$("#scmodal").on("hidden.bs.modal", function (e) {
|
|
272
|
-
(opts.onClose || function () {
|
|
291
|
+
(opts.onClose || function () {})(res);
|
|
273
292
|
$("body").css("overflow", "");
|
|
274
293
|
});
|
|
275
294
|
},
|
|
@@ -278,7 +297,7 @@ function ajax_modal(url, opts = {}) {
|
|
|
278
297
|
|
|
279
298
|
function saveAndContinue(e, k) {
|
|
280
299
|
var form = $(e).closest("form");
|
|
281
|
-
const valres = form[0].reportValidity()
|
|
300
|
+
const valres = form[0].reportValidity();
|
|
282
301
|
if (!valres) return;
|
|
283
302
|
submitWithEmptyAction(form[0]);
|
|
284
303
|
var url = form.attr("action");
|
|
@@ -323,7 +342,7 @@ function applyViewConfig(e, url, k) {
|
|
|
323
342
|
"CSRF-Token": _sc_globalCsrf,
|
|
324
343
|
},
|
|
325
344
|
data: JSON.stringify(cfg),
|
|
326
|
-
error: function (request) {
|
|
345
|
+
error: function (request) {},
|
|
327
346
|
success: function (res) {
|
|
328
347
|
k && k(res);
|
|
329
348
|
!k && updateViewPreview();
|
|
@@ -344,10 +363,14 @@ function updateViewPreview() {
|
|
|
344
363
|
"CSRF-Token": _sc_globalCsrf,
|
|
345
364
|
},
|
|
346
365
|
|
|
347
|
-
error: function (request) {
|
|
366
|
+
error: function (request) {},
|
|
348
367
|
success: function (res) {
|
|
349
368
|
$preview.css({ opacity: 1.0 });
|
|
350
369
|
|
|
370
|
+
//disable functions preview migght try to call
|
|
371
|
+
set_state_field = () => {};
|
|
372
|
+
set_state_fields = () => {};
|
|
373
|
+
|
|
351
374
|
//disable elements in preview
|
|
352
375
|
$preview.html(res);
|
|
353
376
|
$preview.find("a").attr("href", "#");
|
|
@@ -357,11 +380,6 @@ function updateViewPreview() {
|
|
|
357
380
|
|
|
358
381
|
$preview.find("textarea").attr("disabled", true);
|
|
359
382
|
$preview.find("input").attr("readonly", true);
|
|
360
|
-
|
|
361
|
-
//disable functions preview migght try to call
|
|
362
|
-
set_state_field = () => { }
|
|
363
|
-
set_state_fields = () => { }
|
|
364
|
-
|
|
365
383
|
},
|
|
366
384
|
});
|
|
367
385
|
}
|
|
@@ -596,15 +614,13 @@ function build_mobile_app(button) {
|
|
|
596
614
|
localStorage.setItem("sidebarClosed", `${closed}`);
|
|
597
615
|
});
|
|
598
616
|
}
|
|
599
|
-
})()
|
|
600
|
-
|
|
601
|
-
|
|
617
|
+
})() +
|
|
602
618
|
/*
|
|
603
619
|
https://github.com/jeffdavidgreen/bootstrap-html5-history-tabs/blob/master/bootstrap-history-tabs.js
|
|
604
620
|
Copyright (c) 2015 Jeff Green
|
|
605
621
|
*/
|
|
606
622
|
|
|
607
|
-
|
|
623
|
+
(function ($) {
|
|
608
624
|
"use strict";
|
|
609
625
|
$.fn.historyTabs = function () {
|
|
610
626
|
var that = this;
|
|
@@ -619,21 +635,24 @@ function build_mobile_app(button) {
|
|
|
619
635
|
$(element).on("show.bs.tab", function () {
|
|
620
636
|
var stateObject = { url: $(this).attr("href") };
|
|
621
637
|
|
|
622
|
-
if (
|
|
638
|
+
if (
|
|
639
|
+
window.location.hash &&
|
|
640
|
+
stateObject.url !== window.location.hash
|
|
641
|
+
) {
|
|
623
642
|
window.history.pushState(
|
|
624
643
|
stateObject,
|
|
625
644
|
document.title,
|
|
626
645
|
window.location.pathname +
|
|
627
|
-
|
|
628
|
-
|
|
646
|
+
window.location.search +
|
|
647
|
+
$(this).attr("href")
|
|
629
648
|
);
|
|
630
649
|
} else {
|
|
631
650
|
window.history.replaceState(
|
|
632
651
|
stateObject,
|
|
633
652
|
document.title,
|
|
634
653
|
window.location.pathname +
|
|
635
|
-
|
|
636
|
-
|
|
654
|
+
window.location.search +
|
|
655
|
+
$(this).attr("href")
|
|
637
656
|
);
|
|
638
657
|
}
|
|
639
658
|
});
|
|
@@ -649,4 +668,33 @@ function build_mobile_app(button) {
|
|
|
649
668
|
|
|
650
669
|
// Copyright (c) 2011 Marcus Ekwall, http://writeless.se/
|
|
651
670
|
// https://github.com/mekwall/jquery-throttle
|
|
652
|
-
(function (a) {
|
|
671
|
+
(function (a) {
|
|
672
|
+
var b = a.jQuery || a.me || (a.me = {}),
|
|
673
|
+
i = function (e, f, g, h, c, a) {
|
|
674
|
+
f || (f = 100);
|
|
675
|
+
var d = !1,
|
|
676
|
+
j = !1,
|
|
677
|
+
i = typeof g === "function",
|
|
678
|
+
l = function (a, b) {
|
|
679
|
+
d = setTimeout(function () {
|
|
680
|
+
d = !1;
|
|
681
|
+
if (h || c) e.apply(a, b), c && (j = +new Date());
|
|
682
|
+
i && g.apply(a, b);
|
|
683
|
+
}, f);
|
|
684
|
+
},
|
|
685
|
+
k = function () {
|
|
686
|
+
if (!d || a) {
|
|
687
|
+
if (!d && !h && (!c || +new Date() - j > f))
|
|
688
|
+
e.apply(this, arguments), c && (j = +new Date());
|
|
689
|
+
(a || !c) && clearTimeout(d);
|
|
690
|
+
l(this, arguments);
|
|
691
|
+
}
|
|
692
|
+
};
|
|
693
|
+
if (b.guid) k.guid = e.guid = e.guid || b.guid++;
|
|
694
|
+
return k;
|
|
695
|
+
};
|
|
696
|
+
b.throttle = i;
|
|
697
|
+
b.debounce = function (a, b, g, h, c) {
|
|
698
|
+
return i(a, b, g, h, c, !0);
|
|
699
|
+
};
|
|
700
|
+
})(this);
|