glib-web 2.6.2 → 2.6.4
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 -2
- package/actions/fields/focus.js +6 -0
- package/actions/fields/reset.js +12 -0
- package/actions/forms/submit.js +3 -6
- package/app.vue +11 -10
- package/components/_chip.vue +8 -1
- package/components/fields/check.vue +10 -8
- package/components/fields/file.vue +12 -10
- package/components/fields/radioGroup.vue +6 -4
- package/components/fields/text.vue +4 -0
- package/components/mixins/events.js +15 -6
- package/components/mixins/styles.js +3 -0
- package/components/panels/custom.vue +11 -6
- package/components/panels/horizontal.vue +2 -0
- package/components/panels/list.vue +1 -31
- package/components/panels/responsive.vue +1 -0
- package/extensions/string.js +4 -0
- package/package.json +1 -1
- package/utils/component.js +25 -5
package/action.js
CHANGED
|
@@ -2,7 +2,9 @@ import TypeUtils from "./utils/type";
|
|
|
2
2
|
|
|
3
3
|
import ActionsRunMultiple from "./actions/runMultiple";
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import ActionsFormsSubmit from "./actions/forms/submit";
|
|
6
|
+
import ActionsFieldsReset from "./actions/fields/reset";
|
|
7
|
+
import ActionsFieldsFocus from "./actions/fields/focus";
|
|
6
8
|
|
|
7
9
|
import ActionsHttpGetV1 from "./actions/http/get";
|
|
8
10
|
import ActionsHttpPostV1 from "./actions/http/post";
|
|
@@ -60,7 +62,9 @@ import ActionComponentsUpdate from "./actions/components/update";
|
|
|
60
62
|
const actions = {
|
|
61
63
|
runMultiple: ActionsRunMultiple,
|
|
62
64
|
|
|
63
|
-
"forms/submit":
|
|
65
|
+
"forms/submit": ActionsFormsSubmit,
|
|
66
|
+
"fields/reset": ActionsFieldsReset,
|
|
67
|
+
"fields/focus": ActionsFieldsFocus,
|
|
64
68
|
|
|
65
69
|
"http/get": ActionsHttpGetV1,
|
|
66
70
|
"http/post": ActionsHttpPostV1,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import Vue from "vue";
|
|
2
|
+
|
|
3
|
+
export default class {
|
|
4
|
+
execute(properties, component) {
|
|
5
|
+
const target = GLib.component.findById(properties.targetId);
|
|
6
|
+
target.action_resetValue();
|
|
7
|
+
|
|
8
|
+
Vue.nextTick(() => {
|
|
9
|
+
GLib.action.execute(properties["onReset"], component);
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
}
|
package/actions/forms/submit.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
export default class {
|
|
2
2
|
execute(properties, component) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
});
|
|
7
|
-
}, 500)
|
|
8
|
-
|
|
3
|
+
component.$dispatchEvent("forms/directSubmit", {
|
|
4
|
+
url: properties.overrideUrl
|
|
5
|
+
})
|
|
9
6
|
}
|
|
10
7
|
}
|
package/app.vue
CHANGED
|
@@ -114,16 +114,17 @@ export default {
|
|
|
114
114
|
this.$wsInitPhoenixSocket(this.page.phoenixSocket);
|
|
115
115
|
this.$wsInitActionCable(this.page.actionCable);
|
|
116
116
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
|
|
117
|
+
// TODO: Remove gtag dependency
|
|
118
|
+
// if (this.$gtag) {
|
|
119
|
+
// if (!Utils.settings.isDev) {
|
|
120
|
+
// console.log(`Tracking analytics: ${window.location}`);
|
|
121
|
+
// this.$gtag.pageview({
|
|
122
|
+
// page_location: window.location
|
|
123
|
+
// });
|
|
124
|
+
// }
|
|
125
|
+
// } else {
|
|
126
|
+
// console.warn("Analytics not setup. Set `settings.gtagId`.");
|
|
127
|
+
// }
|
|
127
128
|
|
|
128
129
|
// Use setTimeout() to wait until page is rendered. Don't use nextTick() because
|
|
129
130
|
// it would execute much earlier (before all components finish initializing).
|
package/components/_chip.vue
CHANGED
|
@@ -7,12 +7,19 @@
|
|
|
7
7
|
:style="genericStyles()"
|
|
8
8
|
:class="$classes()"
|
|
9
9
|
:href="$href()"
|
|
10
|
+
:small="$classes().includes('small')"
|
|
10
11
|
@click="$onClick()"
|
|
11
12
|
v-on="on"
|
|
12
13
|
>
|
|
13
14
|
{{ spec.text }}
|
|
14
15
|
</v-chip>
|
|
15
|
-
<v-chip
|
|
16
|
+
<v-chip
|
|
17
|
+
v-else
|
|
18
|
+
:style="genericStyles()"
|
|
19
|
+
:class="$classes()"
|
|
20
|
+
:small="$classes().includes('small')"
|
|
21
|
+
v-on="on"
|
|
22
|
+
>
|
|
16
23
|
{{ spec.text }}
|
|
17
24
|
</v-chip>
|
|
18
25
|
</common-badge>
|
|
@@ -20,12 +20,12 @@
|
|
|
20
20
|
<script>
|
|
21
21
|
export default {
|
|
22
22
|
props: {
|
|
23
|
-
spec: { type: Object, required: true }
|
|
23
|
+
spec: { type: Object, required: true },
|
|
24
24
|
},
|
|
25
25
|
data() {
|
|
26
26
|
return {
|
|
27
27
|
groupName: null,
|
|
28
|
-
fieldType: null
|
|
28
|
+
fieldType: null,
|
|
29
29
|
};
|
|
30
30
|
},
|
|
31
31
|
methods: {
|
|
@@ -35,7 +35,7 @@ export default {
|
|
|
35
35
|
let groupName = null;
|
|
36
36
|
this.$type.ifObject(
|
|
37
37
|
this.groupElement,
|
|
38
|
-
val => (groupName = val.getAttribute("name"))
|
|
38
|
+
(val) => (groupName = val.getAttribute("name"))
|
|
39
39
|
);
|
|
40
40
|
|
|
41
41
|
this.fieldName = this.spec.name || groupName;
|
|
@@ -44,7 +44,7 @@ export default {
|
|
|
44
44
|
? this.spec.checkValue
|
|
45
45
|
: this.spec.value;
|
|
46
46
|
|
|
47
|
-
Utils.type.ifArray(this.spec.styleClasses, classes => {
|
|
47
|
+
Utils.type.ifArray(this.spec.styleClasses, (classes) => {
|
|
48
48
|
if (classes.remove("switch")) {
|
|
49
49
|
this.fieldType = "switch";
|
|
50
50
|
}
|
|
@@ -53,20 +53,22 @@ export default {
|
|
|
53
53
|
changed(event) {
|
|
54
54
|
// Execute later to ensure the checkbox's checked state has been updated.
|
|
55
55
|
setTimeout(() => {
|
|
56
|
-
this.$type.ifObject(this.groupElement, val =>
|
|
56
|
+
this.$type.ifObject(this.groupElement, (val) =>
|
|
57
57
|
val.dispatchEvent(new Event("change"))
|
|
58
58
|
);
|
|
59
59
|
}, 100);
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
setTimeout(() => {
|
|
62
|
+
this.$executeOnChange();
|
|
63
|
+
}, 500);
|
|
62
64
|
},
|
|
63
65
|
$internalizeValue(val) {
|
|
64
66
|
if (val == this.spec.checkValue) {
|
|
65
67
|
return val;
|
|
66
68
|
}
|
|
67
69
|
return this.spec.uncheckValue;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
+
},
|
|
71
|
+
},
|
|
70
72
|
};
|
|
71
73
|
</script>
|
|
72
74
|
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
</div>
|
|
50
50
|
<input
|
|
51
51
|
ref="directUploadFile"
|
|
52
|
-
style="display: none
|
|
52
|
+
style="display: none"
|
|
53
53
|
type="file"
|
|
54
54
|
@change="uploadFiles"
|
|
55
55
|
/>
|
|
@@ -78,7 +78,7 @@ import Uploader from "../../utils/uploader";
|
|
|
78
78
|
|
|
79
79
|
export default {
|
|
80
80
|
props: {
|
|
81
|
-
spec: { type: Object, required: true }
|
|
81
|
+
spec: { type: Object, required: true },
|
|
82
82
|
},
|
|
83
83
|
data() {
|
|
84
84
|
return {
|
|
@@ -88,13 +88,13 @@ export default {
|
|
|
88
88
|
fileImage: null,
|
|
89
89
|
fileValue: null,
|
|
90
90
|
inputElement: null,
|
|
91
|
-
placeholder: {}
|
|
91
|
+
placeholder: {},
|
|
92
92
|
};
|
|
93
93
|
},
|
|
94
94
|
computed: {
|
|
95
|
-
showProgress: function() {
|
|
95
|
+
showProgress: function () {
|
|
96
96
|
return this.progress.value >= 0;
|
|
97
|
-
}
|
|
97
|
+
},
|
|
98
98
|
},
|
|
99
99
|
methods: {
|
|
100
100
|
$ready() {
|
|
@@ -119,7 +119,7 @@ export default {
|
|
|
119
119
|
},
|
|
120
120
|
displayImagePreview(file, blob) {
|
|
121
121
|
let reader = new FileReader();
|
|
122
|
-
reader.onload = e => {
|
|
122
|
+
reader.onload = (e) => {
|
|
123
123
|
this.fileTitle = file.name;
|
|
124
124
|
this.fileImage = e.target.result;
|
|
125
125
|
this.fileValue = blob.signed_id;
|
|
@@ -151,7 +151,9 @@ export default {
|
|
|
151
151
|
|
|
152
152
|
// This only works for single uploads. For multi-uploads, we'll need to make sure
|
|
153
153
|
// that all uploads have finished successfully.
|
|
154
|
-
|
|
154
|
+
setTimeout(() => {
|
|
155
|
+
this.$executeOnChange();
|
|
156
|
+
}, 500);
|
|
155
157
|
}
|
|
156
158
|
|
|
157
159
|
input.disabled = false;
|
|
@@ -165,15 +167,15 @@ export default {
|
|
|
165
167
|
}
|
|
166
168
|
},
|
|
167
169
|
uploadFiles(e) {
|
|
168
|
-
Array.from(e.target.files).forEach(file => this.uploadFile(file));
|
|
169
|
-
}
|
|
170
|
+
Array.from(e.target.files).forEach((file) => this.uploadFile(file));
|
|
171
|
+
},
|
|
170
172
|
// toggleDisplayProgressIndicator() {
|
|
171
173
|
// this.showProgress = !this.showProgress
|
|
172
174
|
// },
|
|
173
175
|
// updateProgressIndicator(e) {
|
|
174
176
|
// this.valueProgress = e.detail.progress
|
|
175
177
|
// }
|
|
176
|
-
}
|
|
178
|
+
},
|
|
177
179
|
};
|
|
178
180
|
</script>
|
|
179
181
|
|
|
@@ -30,11 +30,13 @@
|
|
|
30
30
|
<script>
|
|
31
31
|
export default {
|
|
32
32
|
props: {
|
|
33
|
-
spec: { type: Object, required: true }
|
|
33
|
+
spec: { type: Object, required: true },
|
|
34
34
|
},
|
|
35
35
|
methods: {
|
|
36
36
|
onChange() {
|
|
37
|
-
|
|
37
|
+
setTimeout(() => {
|
|
38
|
+
this.$executeOnChange();
|
|
39
|
+
}, 500);
|
|
38
40
|
},
|
|
39
41
|
updateValue(variable) {
|
|
40
42
|
if (variable.value) {
|
|
@@ -50,8 +52,8 @@ export default {
|
|
|
50
52
|
} else {
|
|
51
53
|
return "";
|
|
52
54
|
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
+
},
|
|
56
|
+
},
|
|
55
57
|
};
|
|
56
58
|
</script>
|
|
57
59
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div :style="$styles()" :class="classes()">
|
|
3
3
|
<v-text-field
|
|
4
|
+
ref="field"
|
|
4
5
|
v-model="fieldModel"
|
|
5
6
|
:label="spec.label"
|
|
6
7
|
:name="fieldName"
|
|
@@ -136,6 +137,9 @@ export default {
|
|
|
136
137
|
classes() {
|
|
137
138
|
return this.$classes().concat("g-text-field--hintless");
|
|
138
139
|
},
|
|
140
|
+
action_focus() {
|
|
141
|
+
this.$refs.field.focus();
|
|
142
|
+
},
|
|
139
143
|
onChange: eventFiltering.debounce(function() {
|
|
140
144
|
this.$executeOnChange();
|
|
141
145
|
}, 300)
|
|
@@ -166,17 +166,26 @@ export default {
|
|
|
166
166
|
// this._linkFieldModels();
|
|
167
167
|
this.$ready();
|
|
168
168
|
},
|
|
169
|
-
$recursiveUpdate() {
|
|
169
|
+
async $recursiveUpdate() {
|
|
170
170
|
this.$update();
|
|
171
171
|
this.$forceUpdate();
|
|
172
172
|
|
|
173
|
-
// Execute on next tick to ensure that the
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
173
|
+
// Execute on next tick to ensure that the children have received the updated spec.
|
|
174
|
+
// Important: The nextTick() needs to be used in each of the recursion.
|
|
175
|
+
await this.$nextTick();
|
|
176
|
+
|
|
177
|
+
this.$children.find(child => {
|
|
178
|
+
child.$recursiveUpdate();
|
|
178
179
|
});
|
|
179
180
|
},
|
|
181
|
+
// _recursiveUpdate() {
|
|
182
|
+
// this.$update();
|
|
183
|
+
// this.$forceUpdate();
|
|
184
|
+
|
|
185
|
+
// this.$children.find(child => {
|
|
186
|
+
// child._recursiveUpdate();
|
|
187
|
+
// });
|
|
188
|
+
// },
|
|
180
189
|
$dispatchEvent(name, data) {
|
|
181
190
|
const event = new Event(name, { bubbles: true });
|
|
182
191
|
|
|
@@ -205,6 +205,9 @@ export default {
|
|
|
205
205
|
this.fieldModel = this._sanitizeValue(this.spec.value);
|
|
206
206
|
}
|
|
207
207
|
},
|
|
208
|
+
action_resetValue() {
|
|
209
|
+
this.fieldModel = this._sanitizeValue(this.spec.value);
|
|
210
|
+
},
|
|
208
211
|
$classes(spec, defaultViewName) {
|
|
209
212
|
const properties = Object.assign(
|
|
210
213
|
{ view: defaultViewName },
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
methods because those methods use `spec` attributes, which will force $ready() to be called.
|
|
13
13
|
-->
|
|
14
14
|
<component
|
|
15
|
+
ref="ccomp"
|
|
15
16
|
:is="template"
|
|
16
17
|
v-if="customData"
|
|
17
18
|
:name="spec.template"
|
|
@@ -29,14 +30,14 @@ export default {
|
|
|
29
30
|
components: {
|
|
30
31
|
"template-thumbnail": ThumbnailTemplate,
|
|
31
32
|
"template-featured": FeaturedTemplate,
|
|
32
|
-
"template-unsupported": UnsupportedTemplate
|
|
33
|
+
"template-unsupported": UnsupportedTemplate,
|
|
33
34
|
},
|
|
34
35
|
props: {
|
|
35
|
-
spec: { type: Object, required: true }
|
|
36
|
+
spec: { type: Object, required: true },
|
|
36
37
|
},
|
|
37
38
|
data() {
|
|
38
39
|
return {
|
|
39
|
-
customData: null
|
|
40
|
+
customData: null,
|
|
40
41
|
};
|
|
41
42
|
},
|
|
42
43
|
computed: {
|
|
@@ -51,16 +52,20 @@ export default {
|
|
|
51
52
|
}
|
|
52
53
|
return "template-unsupported";
|
|
53
54
|
}
|
|
54
|
-
}
|
|
55
|
+
},
|
|
55
56
|
},
|
|
56
57
|
methods: {
|
|
57
58
|
$ready() {
|
|
58
59
|
const onClick = this.spec.onClick ? { onClick: this.spec.onClick } : {};
|
|
59
60
|
this.customData = Object.assign(onClick, this.spec.data);
|
|
61
|
+
// Fix an issue where the panel doesn't get updated
|
|
62
|
+
if (this.$refs.ccomp) {
|
|
63
|
+
this.$refs.ccomp.$forceUpdate();
|
|
64
|
+
}
|
|
60
65
|
},
|
|
61
66
|
$registryEnabled() {
|
|
62
67
|
return false;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
68
|
+
},
|
|
69
|
+
},
|
|
65
70
|
};
|
|
66
71
|
</script>
|
|
@@ -29,9 +29,11 @@
|
|
|
29
29
|
>
|
|
30
30
|
<!-- Using `item.id` as key is important to make sure the item gets updated
|
|
31
31
|
when dragging ends. -->
|
|
32
|
+
<!-- Use `display: contents` so this div doesn't intefere with the child's sizing behaviour. -->
|
|
32
33
|
<div
|
|
33
34
|
v-for="(item, index) in childViews"
|
|
34
35
|
:key="item.id || index"
|
|
36
|
+
style="display: contents;"
|
|
35
37
|
:data-dragItemId="item.id"
|
|
36
38
|
>
|
|
37
39
|
<glib-component :spec="item" />
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<v-list
|
|
3
|
-
:two-line="twoLine"
|
|
4
|
-
:three-line="threeLine"
|
|
5
|
-
class="py-0"
|
|
6
|
-
:class="$classes()"
|
|
7
|
-
:style="$styles()"
|
|
8
|
-
>
|
|
2
|
+
<v-list class="py-0" :class="$classes()" :style="$styles()">
|
|
9
3
|
<div ref="topAnchor">
|
|
10
4
|
<div v-if="prevPageUrl" class="py-3 px-4">
|
|
11
5
|
Loading...
|
|
@@ -88,30 +82,6 @@ export default {
|
|
|
88
82
|
dragSupport: null
|
|
89
83
|
};
|
|
90
84
|
},
|
|
91
|
-
computed: {
|
|
92
|
-
twoLine() {
|
|
93
|
-
for (const section of this.sections) {
|
|
94
|
-
const rows = section.rows || [];
|
|
95
|
-
for (const row of rows) {
|
|
96
|
-
if (row.subtitle) {
|
|
97
|
-
return true;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
return false;
|
|
102
|
-
},
|
|
103
|
-
threeLine() {
|
|
104
|
-
for (const section of this.sections) {
|
|
105
|
-
const rows = section.rows || [];
|
|
106
|
-
for (const row of rows) {
|
|
107
|
-
if (row.subsubtitle) {
|
|
108
|
-
return true;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
},
|
|
115
85
|
methods: {
|
|
116
86
|
$ready() {
|
|
117
87
|
this.sections = this.spec.sections || [];
|
package/extensions/string.js
CHANGED
package/package.json
CHANGED
package/utils/component.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
+
import Vue from "vue";
|
|
2
|
+
|
|
1
3
|
export default class {
|
|
2
4
|
static get _registry() {
|
|
3
5
|
return window.vueApp.registeredComponents;
|
|
4
6
|
}
|
|
5
7
|
|
|
6
8
|
static findById(id) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
return this._registry[id];
|
|
10
|
+
// const component = this._registry[id];
|
|
11
|
+
// if (component) {
|
|
12
|
+
// return component;
|
|
13
|
+
// }
|
|
14
|
+
// console.error("Component not found: " + id);
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
// static clearRegistry() {
|
|
@@ -37,4 +40,21 @@ export default class {
|
|
|
37
40
|
static vueName(component) {
|
|
38
41
|
return component.$options._componentTag;
|
|
39
42
|
}
|
|
43
|
+
|
|
44
|
+
static async preserveScroll(promise) {
|
|
45
|
+
const pageBody = this.$pageBody;
|
|
46
|
+
const originalTop = pageBody.scrollTop;
|
|
47
|
+
const originalLeft = pageBody.scrollLeft;
|
|
48
|
+
|
|
49
|
+
await promise;
|
|
50
|
+
|
|
51
|
+
Vue.nextTick(() => {
|
|
52
|
+
pageBody.scrollTop = originalTop;
|
|
53
|
+
pageBody.scrollLeft = originalLeft;
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
static get $pageBody() {
|
|
58
|
+
return document.getElementById("page_body");
|
|
59
|
+
}
|
|
40
60
|
}
|