glib-web 2.6.0 → 2.6.1
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/action.js +6 -4
- package/actions/panels/scrollTo.js +4 -2
- package/actions/tours/start.js +10 -1
- package/actions/tours/stop.js +7 -0
- package/components/fields/check.vue +1 -5
- package/components/fields/file.vue +31 -8
- package/components/fields/otpField.vue +58 -17
- package/components/fields/radioGroup.vue +1 -5
- package/components/fields/richText.vue +29 -43
- package/components/fields/text.vue +2 -16
- package/components/fields/textarea.vue +7 -1
- package/nav/dialog.vue +78 -15
- package/package.json +1 -1
- package/utils/launch.js +8 -0
- package/utils/public.js +4 -0
- package/utils/queue.js +0 -0
- package/utils/settings.js +7 -0
package/action.js
CHANGED
|
@@ -53,6 +53,7 @@ import ActionCommandsCustom from "./actions/commands/custom";
|
|
|
53
53
|
import ActionCommandsEnqueue from "./actions/commands/enqueue";
|
|
54
54
|
|
|
55
55
|
import ActionToursStart from "./actions/tours/start";
|
|
56
|
+
import ActionToursStop from "./actions/tours/stop";
|
|
56
57
|
|
|
57
58
|
import ActionComponentsUpdate from "./actions/components/update";
|
|
58
59
|
|
|
@@ -110,6 +111,7 @@ const actions = {
|
|
|
110
111
|
"commands/enqueue": ActionCommandsEnqueue,
|
|
111
112
|
|
|
112
113
|
"tours/start": ActionToursStart,
|
|
114
|
+
"tours/stop": ActionToursStop,
|
|
113
115
|
"components/update": ActionComponentsUpdate
|
|
114
116
|
};
|
|
115
117
|
|
|
@@ -170,10 +172,10 @@ export default class Action {
|
|
|
170
172
|
}
|
|
171
173
|
action.execute(spec, component, params);
|
|
172
174
|
} catch (e) {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
175
|
+
GLib.settings.errorHandler(
|
|
176
|
+
new Error(
|
|
177
|
+
`Failed executing command "${actionName}". Error: ${e.message}`
|
|
178
|
+
)
|
|
177
179
|
);
|
|
178
180
|
}
|
|
179
181
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
// Scroll the main body of the current window
|
|
2
2
|
export default class {
|
|
3
|
-
execute(properties) {
|
|
4
|
-
const pageBody =
|
|
3
|
+
execute(properties, component) {
|
|
4
|
+
const pageBody =
|
|
5
|
+
Utils.launch.dialog.closestBody(component) || Utils.history._pageBody;
|
|
6
|
+
|
|
5
7
|
const selector = `#${properties.viewId}`;
|
|
6
8
|
console.log("Scrolling to", selector);
|
|
7
9
|
const element = pageBody.querySelector(selector);
|
package/actions/tours/start.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import Driver from "driver.js";
|
|
2
2
|
import "driver.js/dist/driver.min.css";
|
|
3
3
|
|
|
4
|
+
let driver = null;
|
|
5
|
+
|
|
4
6
|
export default class {
|
|
5
7
|
execute(spec, component) {
|
|
6
|
-
|
|
8
|
+
driver = new Driver(spec.options || {});
|
|
7
9
|
let steps = spec.steps;
|
|
8
10
|
steps
|
|
9
11
|
.filter(value => value.customBehavior)
|
|
@@ -14,4 +16,11 @@ export default class {
|
|
|
14
16
|
driver.defineSteps(steps);
|
|
15
17
|
driver.start(spec.startFrom || 0);
|
|
16
18
|
}
|
|
19
|
+
|
|
20
|
+
static stopTour() {
|
|
21
|
+
if (driver) {
|
|
22
|
+
driver.reset();
|
|
23
|
+
driver = null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
17
26
|
}
|
|
@@ -58,11 +58,7 @@ export default {
|
|
|
58
58
|
);
|
|
59
59
|
}, 100);
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
this.$nextTick(() => {
|
|
63
|
-
GLib.action.execute(onChange, this);
|
|
64
|
-
});
|
|
65
|
-
});
|
|
61
|
+
this.$executeOnChange();
|
|
66
62
|
},
|
|
67
63
|
$internalizeValue(val) {
|
|
68
64
|
if (val == this.spec.checkValue) {
|
|
@@ -2,14 +2,28 @@
|
|
|
2
2
|
<div ref="fileUploadContainer" class="mb-3" :style="$styles()">
|
|
3
3
|
<label class="v-label v-label--active">{{ spec.label }}</label>
|
|
4
4
|
<div class="preview-container">
|
|
5
|
-
<v-avatar
|
|
5
|
+
<v-avatar
|
|
6
|
+
v-if="placeholder.type == 'avatar'"
|
|
7
|
+
:style="genericStyles(placeholder)"
|
|
8
|
+
class="mr-4"
|
|
9
|
+
>
|
|
6
10
|
<img :src="fileImage || placeholder.url" />
|
|
7
11
|
</v-avatar>
|
|
8
|
-
<img
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
<img
|
|
13
|
+
v-else-if="placeholder.type == 'image'"
|
|
14
|
+
class="square-image mr-4"
|
|
15
|
+
:style="genericStyles(placeholder)"
|
|
16
|
+
:src="fileImage || placeholder.url"
|
|
17
|
+
/>
|
|
18
|
+
|
|
19
|
+
<v-text-field
|
|
20
|
+
v-else-if="placeholder.type == 'input'"
|
|
21
|
+
:value="fileTitle"
|
|
22
|
+
outlined
|
|
23
|
+
prominent
|
|
24
|
+
placholder="Upload your file"
|
|
25
|
+
disabled
|
|
26
|
+
/>
|
|
13
27
|
|
|
14
28
|
<span v-else class="mr-4">{{ fileTitle }}</span>
|
|
15
29
|
|
|
@@ -33,7 +47,12 @@
|
|
|
33
47
|
</v-btn>
|
|
34
48
|
</span>
|
|
35
49
|
</div>
|
|
36
|
-
<input
|
|
50
|
+
<input
|
|
51
|
+
ref="directUploadFile"
|
|
52
|
+
style="display: none;"
|
|
53
|
+
type="file"
|
|
54
|
+
@change="uploadFiles"
|
|
55
|
+
/>
|
|
37
56
|
|
|
38
57
|
<!-- <input type="file" :name="spec.name" ref='directUploadFile' @change='uploadFiles' v-show='!uploaded'/> -->
|
|
39
58
|
<v-progress-linear v-if="showProgress" v-model="progress.value" />
|
|
@@ -73,7 +92,7 @@ export default {
|
|
|
73
92
|
};
|
|
74
93
|
},
|
|
75
94
|
computed: {
|
|
76
|
-
showProgress: function
|
|
95
|
+
showProgress: function() {
|
|
77
96
|
return this.progress.value >= 0;
|
|
78
97
|
}
|
|
79
98
|
},
|
|
@@ -129,6 +148,10 @@ export default {
|
|
|
129
148
|
this.uploaded = true;
|
|
130
149
|
this.progress.value = -1;
|
|
131
150
|
this.displayImagePreview(file, blob);
|
|
151
|
+
|
|
152
|
+
// This only works for single uploads. For multi-uploads, we'll need to make sure
|
|
153
|
+
// that all uploads have finished successfully.
|
|
154
|
+
this.$executeOnChange();
|
|
132
155
|
}
|
|
133
156
|
|
|
134
157
|
input.disabled = false;
|
|
@@ -1,18 +1,40 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
3
|
+
<div v-if="spec.type === 'text'">
|
|
4
|
+
<input
|
|
5
|
+
v-for="(digit, index) in digits"
|
|
6
|
+
ref="input"
|
|
7
|
+
:key="index"
|
|
8
|
+
v-model="otp[index]"
|
|
9
|
+
type="text"
|
|
10
|
+
maxlength="1"
|
|
11
|
+
class="otp-input"
|
|
12
|
+
@input="handleInput($event, index)"
|
|
13
|
+
@keydown="handleKeydown($event, index)"
|
|
14
|
+
@paste="handlePaste($event, index)"
|
|
15
|
+
@focus="handleFocus($event, index)"
|
|
16
|
+
@blur="handleBlur($event, index)"
|
|
17
|
+
@click="handleClick($event)"
|
|
18
|
+
/>
|
|
19
|
+
</div>
|
|
20
|
+
<div v-else>
|
|
21
|
+
<input
|
|
22
|
+
v-for="(digit, index) in digits"
|
|
23
|
+
ref="input"
|
|
24
|
+
:key="index"
|
|
25
|
+
v-model="otp[index]"
|
|
26
|
+
type="number"
|
|
27
|
+
oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
|
|
28
|
+
maxlength="1"
|
|
29
|
+
class="otp-input"
|
|
30
|
+
@input="handleInput($event, index)"
|
|
31
|
+
@keydown="handleKeydown($event, index)"
|
|
32
|
+
@paste="handlePaste($event, index)"
|
|
33
|
+
@focus="handleFocus($event, index)"
|
|
34
|
+
@blur="handleBlur($event, index)"
|
|
35
|
+
@click="handleClick($event)"
|
|
36
|
+
/>
|
|
37
|
+
</div>
|
|
16
38
|
<input type="hidden" :name="spec.name" :value="otpValue" />
|
|
17
39
|
</div>
|
|
18
40
|
</template>
|
|
@@ -37,8 +59,8 @@ export default {
|
|
|
37
59
|
},
|
|
38
60
|
methods: {
|
|
39
61
|
$ready() {
|
|
40
|
-
this.digits = this.spec.
|
|
41
|
-
this.otp = Array(this.spec.
|
|
62
|
+
this.digits = this.spec.length;
|
|
63
|
+
this.otp = Array(this.spec.length).fill("");
|
|
42
64
|
},
|
|
43
65
|
handleInput(event, index) {
|
|
44
66
|
if (event.target.value.length === 1) {
|
|
@@ -48,8 +70,12 @@ export default {
|
|
|
48
70
|
handleKeydown(event, index) {
|
|
49
71
|
if (event.key === "Backspace") {
|
|
50
72
|
event.preventDefault();
|
|
51
|
-
this.
|
|
52
|
-
|
|
73
|
+
if (this.otp[index] !== "") {
|
|
74
|
+
this.$set(this.otp, index, "");
|
|
75
|
+
} else {
|
|
76
|
+
this.focusPrevious(index);
|
|
77
|
+
this.$set(this.otp, index - 1, "");
|
|
78
|
+
}
|
|
53
79
|
}
|
|
54
80
|
},
|
|
55
81
|
handlePaste(event, index) {
|
|
@@ -81,6 +107,9 @@ export default {
|
|
|
81
107
|
if (index > 0) {
|
|
82
108
|
this.$refs.input[index - 1].focus();
|
|
83
109
|
}
|
|
110
|
+
},
|
|
111
|
+
handleClick(event) {
|
|
112
|
+
event.target.select();
|
|
84
113
|
}
|
|
85
114
|
}
|
|
86
115
|
};
|
|
@@ -95,4 +124,16 @@ export default {
|
|
|
95
124
|
font-size: 24px;
|
|
96
125
|
margin: 8px;
|
|
97
126
|
}
|
|
127
|
+
|
|
128
|
+
/* Chrome, Safari, Edge, Opera */
|
|
129
|
+
input::-webkit-outer-spin-button,
|
|
130
|
+
input::-webkit-inner-spin-button {
|
|
131
|
+
-webkit-appearance: none;
|
|
132
|
+
margin: 0;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/* Firefox */
|
|
136
|
+
input[type="number"] {
|
|
137
|
+
-moz-appearance: textfield;
|
|
138
|
+
}
|
|
98
139
|
</style>
|
|
@@ -34,11 +34,7 @@ export default {
|
|
|
34
34
|
},
|
|
35
35
|
methods: {
|
|
36
36
|
onChange() {
|
|
37
|
-
|
|
38
|
-
this.$nextTick(() => {
|
|
39
|
-
GLib.action.execute(onChange, this);
|
|
40
|
-
});
|
|
41
|
-
});
|
|
37
|
+
this.$executeOnChange();
|
|
42
38
|
},
|
|
43
39
|
updateValue(variable) {
|
|
44
40
|
if (variable.value) {
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
v-model="richEditorValue"
|
|
15
15
|
:editor-toolbar="customToolbar"
|
|
16
16
|
use-custom-image-handler
|
|
17
|
+
:editor-options="editorSettings"
|
|
17
18
|
@text-change="onRichTextEditorChanged"
|
|
18
19
|
@image-added="uploadImage"
|
|
19
|
-
:editorOptions="editorSettings"
|
|
20
20
|
/>
|
|
21
21
|
<!-- Hide these fields but don't remove them because these are the values that will get submitted. -->
|
|
22
22
|
<div :style="{ display: rawMode ? 'block' : 'none' }">
|
|
@@ -55,7 +55,7 @@ import bus from "../../utils/eventBus";
|
|
|
55
55
|
Quill.register("modules/imageDropAndPaste", QuillImageDropAndPaste);
|
|
56
56
|
|
|
57
57
|
var ImageBlot = Quill.import("formats/image");
|
|
58
|
-
ImageBlot.sanitize = function
|
|
58
|
+
ImageBlot.sanitize = function(url) {
|
|
59
59
|
return url;
|
|
60
60
|
};
|
|
61
61
|
|
|
@@ -69,16 +69,16 @@ class Parser {
|
|
|
69
69
|
turndownService.use(gfm);
|
|
70
70
|
turndownService.addRule("strikethrough", {
|
|
71
71
|
filter: ["del", "s", "strike"],
|
|
72
|
-
replacement: function
|
|
72
|
+
replacement: function(content) {
|
|
73
73
|
return "~~" + content + "~~";
|
|
74
|
-
}
|
|
74
|
+
}
|
|
75
75
|
});
|
|
76
76
|
|
|
77
77
|
turndownService.addRule("codeblock", {
|
|
78
78
|
filter: ["pre"],
|
|
79
|
-
replacement: function
|
|
79
|
+
replacement: function(content) {
|
|
80
80
|
return "```\n" + content + "```";
|
|
81
|
-
}
|
|
81
|
+
}
|
|
82
82
|
});
|
|
83
83
|
return turndownService.turndown(data);
|
|
84
84
|
}
|
|
@@ -125,7 +125,7 @@ class TextEditor {
|
|
|
125
125
|
// replace {{image1}} to real image1 url
|
|
126
126
|
replaceWithRealImage(html) {
|
|
127
127
|
const vm = this.context;
|
|
128
|
-
return html.replace(/\{\{image([0-9]+)\}\}/g, function
|
|
128
|
+
return html.replace(/\{\{image([0-9]+)\}\}/g, function(_, index) {
|
|
129
129
|
const image = vm.spec.images[index - 1];
|
|
130
130
|
if (
|
|
131
131
|
image &&
|
|
@@ -146,7 +146,7 @@ class TextEditor {
|
|
|
146
146
|
const vm = this.context;
|
|
147
147
|
let index = 0;
|
|
148
148
|
vm.imageKeys.clear();
|
|
149
|
-
return html.replace(/src="([^"]+)"|\!\[\]\((.+)\)/g, function
|
|
149
|
+
return html.replace(/src="([^"]+)"|\!\[\]\((.+)\)/g, function(_, g1, g2) {
|
|
150
150
|
var imageValue = g1 || g2;
|
|
151
151
|
// It seems that quill encodes '&' in the URL to '&' which would screw up key matching.
|
|
152
152
|
var decodedValue = imageValue.replace(/&/g, "&");
|
|
@@ -164,28 +164,28 @@ class TextEditor {
|
|
|
164
164
|
export default {
|
|
165
165
|
components: { VueEditor },
|
|
166
166
|
props: {
|
|
167
|
-
spec: { type: Object, required: true }
|
|
167
|
+
spec: { type: Object, required: true }
|
|
168
168
|
},
|
|
169
169
|
data: () => ({
|
|
170
170
|
customToolbar: [
|
|
171
171
|
["bold", "italic", "strike"],
|
|
172
172
|
[{ header: 1 }, { header: 2 }, { header: 3 }],
|
|
173
173
|
[{ list: "ordered" }, { list: "bullet" }],
|
|
174
|
-
["image", "link"]
|
|
174
|
+
["image", "link"]
|
|
175
175
|
],
|
|
176
176
|
editorSettings: {
|
|
177
177
|
modules: {
|
|
178
178
|
imageDropAndPaste: {
|
|
179
179
|
// add an custom image handler
|
|
180
|
-
handler: function
|
|
180
|
+
handler: function(imageDataUrl, type, imageData) {
|
|
181
181
|
bus.$emit("richText/dropOrPaste", {
|
|
182
182
|
file: imageData.toFile(),
|
|
183
183
|
editor: this.quill,
|
|
184
|
-
cursorLocation: this.getIndex()
|
|
184
|
+
cursorLocation: this.getIndex()
|
|
185
185
|
});
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
189
|
},
|
|
190
190
|
richEditorValue: "",
|
|
191
191
|
rawEditorValue: "",
|
|
@@ -197,7 +197,7 @@ export default {
|
|
|
197
197
|
textEditor: null,
|
|
198
198
|
mode: null,
|
|
199
199
|
produce: null,
|
|
200
|
-
accept: null
|
|
200
|
+
accept: null
|
|
201
201
|
}),
|
|
202
202
|
computed: {
|
|
203
203
|
showProgress() {
|
|
@@ -205,7 +205,7 @@ export default {
|
|
|
205
205
|
},
|
|
206
206
|
rawMode() {
|
|
207
207
|
return this.mode == 1;
|
|
208
|
-
}
|
|
208
|
+
}
|
|
209
209
|
},
|
|
210
210
|
watch: {},
|
|
211
211
|
mounted() {
|
|
@@ -235,7 +235,7 @@ export default {
|
|
|
235
235
|
this.produce
|
|
236
236
|
);
|
|
237
237
|
},
|
|
238
|
-
uploadImage: function
|
|
238
|
+
uploadImage: function(file, editor, cursorLocation) {
|
|
239
239
|
let vm = this;
|
|
240
240
|
const uploaderSpec = this.imageUploader;
|
|
241
241
|
// const input = this.$refs.directUploadFile
|
|
@@ -274,48 +274,34 @@ export default {
|
|
|
274
274
|
"html"
|
|
275
275
|
);
|
|
276
276
|
},
|
|
277
|
-
onRichTextEditorChanged: eventFiltering.debounce(function
|
|
277
|
+
onRichTextEditorChanged: eventFiltering.debounce(function() {
|
|
278
278
|
this.producedValue = this.textEditor.producedValue(
|
|
279
279
|
this.richEditorValue,
|
|
280
280
|
"html",
|
|
281
281
|
this.produce
|
|
282
282
|
);
|
|
283
283
|
|
|
284
|
-
this
|
|
284
|
+
this.$executeOnChange();
|
|
285
285
|
}),
|
|
286
|
-
onRawTextEditorChanged: eventFiltering.debounce(function
|
|
286
|
+
onRawTextEditorChanged: eventFiltering.debounce(function() {
|
|
287
287
|
this.producedValue = this.textEditor.producedValue(
|
|
288
288
|
this.rawEditorValue,
|
|
289
289
|
"markdown",
|
|
290
290
|
this.produce
|
|
291
291
|
);
|
|
292
292
|
|
|
293
|
-
this
|
|
293
|
+
this.$executeOnChange();
|
|
294
294
|
}),
|
|
295
|
-
|
|
296
|
-
Utils.type.ifObject(this.spec.onChange, (onChange) => {
|
|
297
|
-
this.$nextTick(() => {
|
|
298
|
-
const params = {
|
|
299
|
-
[this.spec.paramNameForFormData || "formData"]: {
|
|
300
|
-
[this.fieldName]: producedValue,
|
|
301
|
-
},
|
|
302
|
-
};
|
|
303
|
-
|
|
304
|
-
const data = Object.assign({}, onChange, params);
|
|
305
|
-
GLib.action.execute(data, this);
|
|
306
|
-
});
|
|
307
|
-
});
|
|
308
|
-
},
|
|
309
|
-
insertImage: function (file, Editor, cursorLocation, blob) {
|
|
295
|
+
insertImage: function(file, Editor, cursorLocation, blob) {
|
|
310
296
|
let vm = this;
|
|
311
297
|
var reader = new FileReader();
|
|
312
|
-
reader.onload = function
|
|
298
|
+
reader.onload = function(e) {
|
|
313
299
|
// vm.fileUrl = e.target.result;
|
|
314
300
|
if (file.type.indexOf("image") !== -1) {
|
|
315
301
|
var image = new Image();
|
|
316
302
|
image.src = URL.createObjectURL(file);
|
|
317
303
|
|
|
318
|
-
image.onload = function
|
|
304
|
+
image.onload = function() {
|
|
319
305
|
Editor.insertEmbed(cursorLocation, "image", image.src);
|
|
320
306
|
};
|
|
321
307
|
|
|
@@ -326,7 +312,7 @@ export default {
|
|
|
326
312
|
reader.readAsDataURL(file);
|
|
327
313
|
vm.progress.value = -1;
|
|
328
314
|
},
|
|
329
|
-
updateToolbar: function
|
|
315
|
+
updateToolbar: function(wrapper, toolbar, container) {
|
|
330
316
|
if (wrapper.scrollTop >= container.offsetTop) {
|
|
331
317
|
toolbar.classList.add("sticky");
|
|
332
318
|
toolbar.style.top = `${wrapper.offsetTop}px`;
|
|
@@ -339,7 +325,7 @@ export default {
|
|
|
339
325
|
toolbar.style.width = "auto";
|
|
340
326
|
}
|
|
341
327
|
},
|
|
342
|
-
registerScrollEvent: function
|
|
328
|
+
registerScrollEvent: function() {
|
|
343
329
|
const wrapper = document.querySelector(".v-dialog") || window;
|
|
344
330
|
const toolbar = this.$el.querySelector(".ql-toolbar");
|
|
345
331
|
const container = this.$el.querySelector(".ql-container");
|
|
@@ -352,8 +338,8 @@ export default {
|
|
|
352
338
|
this.updateToolbar(wrapper, toolbar, container)
|
|
353
339
|
);
|
|
354
340
|
}
|
|
355
|
-
}
|
|
356
|
-
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
357
343
|
};
|
|
358
344
|
</script>
|
|
359
345
|
|
|
@@ -137,22 +137,8 @@ export default {
|
|
|
137
137
|
return this.$classes().concat("g-text-field--hintless");
|
|
138
138
|
},
|
|
139
139
|
onChange: eventFiltering.debounce(function() {
|
|
140
|
-
this
|
|
141
|
-
}, 300)
|
|
142
|
-
executeActionWithParams() {
|
|
143
|
-
Utils.type.ifObject(this.spec.onChange, onChange => {
|
|
144
|
-
this.$nextTick(() => {
|
|
145
|
-
const params = {
|
|
146
|
-
[this.spec.paramNameForFormData || "formData"]: {
|
|
147
|
-
[this.fieldName]: this.fieldModel
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
const data = Object.assign({}, onChange, params);
|
|
152
|
-
GLib.action.execute(data, this);
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
}
|
|
140
|
+
this.$executeOnChange();
|
|
141
|
+
}, 300)
|
|
156
142
|
}
|
|
157
143
|
};
|
|
158
144
|
</script>
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
:no-resize="$classes().includes('no-resize')"
|
|
17
17
|
validate-on-blur
|
|
18
18
|
@keyup="$onTyping"
|
|
19
|
+
@input="onChange"
|
|
19
20
|
></v-textarea>
|
|
20
21
|
<input
|
|
21
22
|
v-if="spec.readOnly"
|
|
@@ -27,6 +28,8 @@
|
|
|
27
28
|
</template>
|
|
28
29
|
|
|
29
30
|
<script>
|
|
31
|
+
import eventFiltering from "../../utils/eventFiltering";
|
|
32
|
+
|
|
30
33
|
export default {
|
|
31
34
|
props: {
|
|
32
35
|
spec: { type: Object, required: true }
|
|
@@ -45,7 +48,10 @@ export default {
|
|
|
45
48
|
},
|
|
46
49
|
classes() {
|
|
47
50
|
return this.$classes().concat("g-text-field--hintless");
|
|
48
|
-
}
|
|
51
|
+
},
|
|
52
|
+
onChange: eventFiltering.debounce(function() {
|
|
53
|
+
this.$executeOnChange();
|
|
54
|
+
}, 300)
|
|
49
55
|
}
|
|
50
56
|
};
|
|
51
57
|
</script>
|
package/nav/dialog.vue
CHANGED
|
@@ -7,24 +7,34 @@
|
|
|
7
7
|
:sm-and-down="false"
|
|
8
8
|
:persistent="true"
|
|
9
9
|
>
|
|
10
|
-
<v-card>
|
|
11
|
-
<v-card-title v-if="title || showClose" class="text-h5" primary-title>
|
|
12
|
-
|
|
10
|
+
<v-card :style="hamburgerStyles" class="hamburger">
|
|
11
|
+
<!-- <v-card-title v-if="title || showClose" class="text-h5" primary-title> -->
|
|
12
|
+
<div>
|
|
13
|
+
<panels-responsive v-if="header" :spec="header" />
|
|
14
|
+
<div v-if="title" class="dialogs-title theme--light v-subheader">
|
|
15
|
+
{{ title }}
|
|
16
|
+
</div>
|
|
17
|
+
|
|
13
18
|
<v-btn v-if="showClose" text icon class="dialog-close" @click="close">
|
|
14
19
|
<v-icon>close</v-icon>
|
|
15
20
|
</v-btn>
|
|
16
|
-
</
|
|
21
|
+
</div>
|
|
22
|
+
<!-- </v-card-title> -->
|
|
17
23
|
|
|
18
|
-
<
|
|
19
|
-
<
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
<div class="dialogs-body">
|
|
25
|
+
<component :is="containerComponent" :spec="formSpec">
|
|
26
|
+
<div v-if="message" class="dialog-message">
|
|
27
|
+
<common-message :spec="{ message: message }" />
|
|
28
|
+
</div>
|
|
29
|
+
<panels-responsive v-if="body" :spec="body" />
|
|
30
|
+
</component>
|
|
31
|
+
</div>
|
|
24
32
|
|
|
25
|
-
<
|
|
33
|
+
<panels-responsive v-if="footer" :spec="footer" />
|
|
26
34
|
|
|
27
35
|
<v-card-actions v-if="spec.buttons">
|
|
36
|
+
<v-divider></v-divider>
|
|
37
|
+
|
|
28
38
|
<v-spacer></v-spacer>
|
|
29
39
|
|
|
30
40
|
<v-btn
|
|
@@ -36,8 +46,6 @@
|
|
|
36
46
|
>
|
|
37
47
|
{{ button.text }}
|
|
38
48
|
</v-btn>
|
|
39
|
-
|
|
40
|
-
<panels-responsive v-if="footer" :spec="footer" />
|
|
41
49
|
</v-card-actions>
|
|
42
50
|
</v-card>
|
|
43
51
|
</v-dialog>
|
|
@@ -59,9 +67,11 @@ export default {
|
|
|
59
67
|
},
|
|
60
68
|
data: function() {
|
|
61
69
|
return {
|
|
70
|
+
mainHeight: 0,
|
|
62
71
|
title: null,
|
|
63
72
|
message: null,
|
|
64
73
|
body: null,
|
|
74
|
+
header: null,
|
|
65
75
|
footer: null,
|
|
66
76
|
model: null,
|
|
67
77
|
url: null,
|
|
@@ -88,6 +98,12 @@ export default {
|
|
|
88
98
|
} else {
|
|
89
99
|
return false;
|
|
90
100
|
}
|
|
101
|
+
},
|
|
102
|
+
hamburgerStyles() {
|
|
103
|
+
if (this.spec.height == "matchParent") {
|
|
104
|
+
return `height: ${this.mainHeight}px;`;
|
|
105
|
+
}
|
|
106
|
+
return null;
|
|
91
107
|
}
|
|
92
108
|
},
|
|
93
109
|
watch: {
|
|
@@ -98,11 +114,24 @@ export default {
|
|
|
98
114
|
}
|
|
99
115
|
},
|
|
100
116
|
methods: {
|
|
117
|
+
$mounted() {
|
|
118
|
+
window.addEventListener(
|
|
119
|
+
"resize",
|
|
120
|
+
event => {
|
|
121
|
+
this.updateMainHeight();
|
|
122
|
+
},
|
|
123
|
+
true
|
|
124
|
+
);
|
|
125
|
+
},
|
|
101
126
|
$ready() {
|
|
102
127
|
this.$root.vueApp = this.vueApp;
|
|
103
128
|
this.onResize();
|
|
104
129
|
this.show(false);
|
|
105
130
|
this.stack.push(this);
|
|
131
|
+
|
|
132
|
+
this.$nextTick(() => {
|
|
133
|
+
this.updateMainHeight();
|
|
134
|
+
});
|
|
106
135
|
},
|
|
107
136
|
$tearDown() {
|
|
108
137
|
console.log("Dialog destroyed");
|
|
@@ -128,7 +157,6 @@ export default {
|
|
|
128
157
|
onResize() {
|
|
129
158
|
this.isMobile = window.innerWidth < 600;
|
|
130
159
|
},
|
|
131
|
-
|
|
132
160
|
show(reload) {
|
|
133
161
|
const spec = this.spec;
|
|
134
162
|
this.url = spec.url;
|
|
@@ -146,6 +174,7 @@ export default {
|
|
|
146
174
|
this.title = response.title;
|
|
147
175
|
this.message = "";
|
|
148
176
|
this.formSpec = response.fullPageForm;
|
|
177
|
+
this.header = response.header;
|
|
149
178
|
this.body = response.body;
|
|
150
179
|
this.footer = response.footer;
|
|
151
180
|
this.showClose = this.spec.showClose || false;
|
|
@@ -161,12 +190,19 @@ export default {
|
|
|
161
190
|
}
|
|
162
191
|
|
|
163
192
|
this.model = true;
|
|
193
|
+
},
|
|
194
|
+
updateMainHeight() {
|
|
195
|
+
console.debug("Setting body height");
|
|
196
|
+
this.mainHeight = window.innerHeight - 140;
|
|
164
197
|
}
|
|
165
198
|
}
|
|
166
199
|
};
|
|
167
200
|
</script>
|
|
168
201
|
|
|
169
|
-
<style scoped>
|
|
202
|
+
<style lang="scss" scoped>
|
|
203
|
+
.dialogs-title {
|
|
204
|
+
padding: 16px 16px 0px 16px;
|
|
205
|
+
}
|
|
170
206
|
.dialog-message {
|
|
171
207
|
padding: 16px 16px 20px 16px;
|
|
172
208
|
/* white-space: pre-wrap; */
|
|
@@ -179,4 +215,31 @@ export default {
|
|
|
179
215
|
.v-card__text {
|
|
180
216
|
padding: 0 !important;
|
|
181
217
|
}
|
|
218
|
+
.hamburger {
|
|
219
|
+
display: flex;
|
|
220
|
+
flex-direction: column;
|
|
221
|
+
justify-content: space-between;
|
|
222
|
+
height: 100%;
|
|
223
|
+
padding: 0;
|
|
224
|
+
}
|
|
225
|
+
.dialogs-body {
|
|
226
|
+
// height: 100%;
|
|
227
|
+
// overflow-y: overlay;
|
|
228
|
+
overflow-y: auto;
|
|
229
|
+
}
|
|
230
|
+
</style>
|
|
231
|
+
|
|
232
|
+
<style lang="scss">
|
|
233
|
+
.v-dialog {
|
|
234
|
+
// Hide superfluous scrollbar (Edge)
|
|
235
|
+
-ms-overflow-style: none;
|
|
236
|
+
* {
|
|
237
|
+
-ms-overflow-style: initial;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Hide superfluous scrollbar (Webkit)
|
|
241
|
+
&::-webkit-scrollbar {
|
|
242
|
+
display: none;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
182
245
|
</style>
|
package/package.json
CHANGED
package/utils/launch.js
CHANGED
|
@@ -19,6 +19,14 @@ export default class {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
class LaunchDialog {
|
|
22
|
+
static closestBody(component) {
|
|
23
|
+
const dialog = component.$el.closest(".v-dialog");
|
|
24
|
+
if (dialog) {
|
|
25
|
+
return dialog.querySelector(".dialogs-body");
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
|
|
22
30
|
static _initStack() {
|
|
23
31
|
if (!this.stack) {
|
|
24
32
|
this.stack = [];
|
package/utils/public.js
CHANGED
|
@@ -6,6 +6,7 @@ import Form from "./form";
|
|
|
6
6
|
import Component from "./component";
|
|
7
7
|
import Hash from "./hash";
|
|
8
8
|
import Queue from "./queue";
|
|
9
|
+
import Settings from "./settings";
|
|
9
10
|
|
|
10
11
|
const _queue = new Queue();
|
|
11
12
|
|
|
@@ -31,6 +32,9 @@ export default class {
|
|
|
31
32
|
static get Hash() {
|
|
32
33
|
return Hash;
|
|
33
34
|
}
|
|
35
|
+
static get settings() {
|
|
36
|
+
return Settings;
|
|
37
|
+
}
|
|
34
38
|
static get queue() {
|
|
35
39
|
return _queue;
|
|
36
40
|
}
|
package/utils/queue.js
CHANGED
|
File without changes
|
package/utils/settings.js
CHANGED
|
@@ -3,6 +3,9 @@ class MutableSettings {
|
|
|
3
3
|
this.reactive = true;
|
|
4
4
|
this.themes = {};
|
|
5
5
|
this.gtagId = null;
|
|
6
|
+
this.errorHandler = err => {
|
|
7
|
+
console.error(err.message);
|
|
8
|
+
};
|
|
6
9
|
}
|
|
7
10
|
}
|
|
8
11
|
const settings = new MutableSettings();
|
|
@@ -17,6 +20,10 @@ export default class ImmutableSettings {
|
|
|
17
20
|
return settings.themes;
|
|
18
21
|
}
|
|
19
22
|
|
|
23
|
+
static get errorHandler() {
|
|
24
|
+
return settings.errorHandler;
|
|
25
|
+
}
|
|
26
|
+
|
|
20
27
|
static get env() {
|
|
21
28
|
return process.env.NODE_ENV;
|
|
22
29
|
}
|