glib-web 4.33.2 → 4.34.3
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.vue +13 -6
- package/components/fields/_select.vue +14 -3
- package/components/fields/richText.vue +5 -10
- package/components/fields/richText2.vue +8 -1
- package/components/mixins/styles.js +0 -6
- package/components/panels/form.vue +3 -1
- package/components/popover.vue +7 -0
- package/nav/appBar.vue +3 -2
- package/nav/dialog.vue +12 -6
- package/nav/drawer.vue +3 -0
- package/nav/drawerButton.vue +3 -1
- package/package.json +6 -6
- package/store.js +2 -1
- package/utils/eventBus.js +6 -4
package/app.vue
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
<v-container v-if="vueApp.loading" :fluid="page.template == 'fullWidth'" :class="containerClasses">
|
|
28
28
|
<glib-component v-for="(loaderView, index) in vueApp.loaderViews" :key="index"
|
|
29
29
|
:spec="loaderView"></glib-component>
|
|
30
|
-
</v-container
|
|
30
|
+
</v-container>
|
|
31
31
|
</v-main>
|
|
32
32
|
|
|
33
33
|
</component>
|
|
@@ -57,7 +57,7 @@ import FormPanel from "./components/panels/form.vue";
|
|
|
57
57
|
import { isRerender, vueApp } from "./store";
|
|
58
58
|
import { useSocket } from "./components/composable/socket";
|
|
59
59
|
import { usePasteable } from "./components/composable/pasteable";
|
|
60
|
-
import { computed,
|
|
60
|
+
import { computed, onBeforeUnmount, onMounted, ref } from "vue";
|
|
61
61
|
import { TOOLTIP_ID } from "./constant";
|
|
62
62
|
import { watchGlibEvent } from "./store";
|
|
63
63
|
import { htmlElement } from "./components/helper";
|
|
@@ -71,12 +71,19 @@ export default {
|
|
|
71
71
|
const tooltipId = TOOLTIP_ID;
|
|
72
72
|
const appRef = ref(null);
|
|
73
73
|
|
|
74
|
+
const handler = (event) => {
|
|
75
|
+
const { dirty } = event.detail;
|
|
76
|
+
vueApp.isFormDirty = dirty;
|
|
77
|
+
};
|
|
78
|
+
|
|
74
79
|
onMounted(() => {
|
|
75
80
|
const el = htmlElement(appRef.value);
|
|
76
|
-
el.addEventListener('dirtyupdate',
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
81
|
+
el.addEventListener('dirtyupdate', handler);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
onBeforeUnmount(() => {
|
|
85
|
+
const el = htmlElement(appRef.value);
|
|
86
|
+
el.removeEventListener('dirtyupdate', handler);
|
|
80
87
|
});
|
|
81
88
|
|
|
82
89
|
return { vueApp, tooltipId, appRef };
|
|
@@ -43,9 +43,7 @@
|
|
|
43
43
|
</template>
|
|
44
44
|
|
|
45
45
|
<template v-slot:append-item v-if="spec.footer">
|
|
46
|
-
<
|
|
47
|
-
<common-responsive :spec="spec.footer" />
|
|
48
|
-
</div>
|
|
46
|
+
<common-responsive :spec="footer" />
|
|
49
47
|
</template>
|
|
50
48
|
|
|
51
49
|
<template v-slot:prepend-inner v-if="spec.leftIcon">
|
|
@@ -98,6 +96,12 @@ export default {
|
|
|
98
96
|
compName() {
|
|
99
97
|
return this.spec.searchable ? 'v-autocomplete' : 'v-select';
|
|
100
98
|
},
|
|
99
|
+
footer() {
|
|
100
|
+
const styleClasses = ['fields-select-footer'];
|
|
101
|
+
styleClasses.push([this.spec.footer.styleClasses].flat());
|
|
102
|
+
|
|
103
|
+
return Object.assign({}, this.spec.footer, { styleClasses });
|
|
104
|
+
},
|
|
101
105
|
normalizedOptions() {
|
|
102
106
|
return this.spec.options.map(i => {
|
|
103
107
|
switch (i.type) {
|
|
@@ -180,6 +184,13 @@ export default {
|
|
|
180
184
|
width: 100%;
|
|
181
185
|
}
|
|
182
186
|
}
|
|
187
|
+
|
|
188
|
+
.sticky-footer {
|
|
189
|
+
position: sticky;
|
|
190
|
+
bottom: -8px;
|
|
191
|
+
background: white;
|
|
192
|
+
z-index: 1;
|
|
193
|
+
}
|
|
183
194
|
</style>
|
|
184
195
|
|
|
185
196
|
<style scoped>
|
|
@@ -221,16 +221,6 @@ export default {
|
|
|
221
221
|
[{ list: "ordered" }, { list: "bullet" }],
|
|
222
222
|
["link"],
|
|
223
223
|
],
|
|
224
|
-
// ImageDropAndPaste: {
|
|
225
|
-
// // add an custom image handler
|
|
226
|
-
// handler: function (imageDataUrl, type, imageData) {
|
|
227
|
-
// bus.$emit("richText/dropOrPaste", {
|
|
228
|
-
// file: imageData.toFile(),
|
|
229
|
-
// editor: quill,
|
|
230
|
-
// cursorLocation: this.getIndex(),
|
|
231
|
-
// });
|
|
232
|
-
// },
|
|
233
|
-
// }
|
|
234
224
|
}
|
|
235
225
|
});
|
|
236
226
|
|
|
@@ -245,6 +235,11 @@ export default {
|
|
|
245
235
|
);
|
|
246
236
|
}
|
|
247
237
|
},
|
|
238
|
+
unmounted() {
|
|
239
|
+
if (this.spec.imageUploader) {
|
|
240
|
+
bus.$off("richText/dropOrPaste");
|
|
241
|
+
}
|
|
242
|
+
},
|
|
248
243
|
methods: {
|
|
249
244
|
uploadImage: function (file, editor, cursorLocation) {
|
|
250
245
|
if (!this.imageUploader) return;
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
</template>
|
|
12
12
|
|
|
13
13
|
<script>
|
|
14
|
-
import { computed, defineComponent, getCurrentInstance, nextTick, onMounted, ref } from "vue";
|
|
14
|
+
import { computed, defineComponent, getCurrentInstance, nextTick, onBeforeUnmount, onMounted, ref } from "vue";
|
|
15
15
|
import Quill from "quill";
|
|
16
16
|
import "quill/dist/quill.snow.css";
|
|
17
17
|
import 'quill-mention/dist/quill.mention.css';
|
|
@@ -272,6 +272,13 @@ export default defineComponent({
|
|
|
272
272
|
}
|
|
273
273
|
});
|
|
274
274
|
|
|
275
|
+
onBeforeUnmount(() => {
|
|
276
|
+
if (imageUploader) {
|
|
277
|
+
quill.root.removeEventListener('paste', handlePaste, false);
|
|
278
|
+
quill.root.removeEventListener('drop', handleDrop, false);
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
|
|
275
282
|
return { producedValue, editor, files, rawTextProps };
|
|
276
283
|
}
|
|
277
284
|
});
|
|
@@ -135,7 +135,9 @@ export default {
|
|
|
135
135
|
const onChange = this.spec.onChange || this.spec.onChangeAndLoad;
|
|
136
136
|
this.formCtx = { form: this.$refs.form };
|
|
137
137
|
const onChangeHandler = () => {
|
|
138
|
-
this.$refs.form
|
|
138
|
+
if (this.$refs.form) {
|
|
139
|
+
this.$refs.form.resetValidation();
|
|
140
|
+
}
|
|
139
141
|
this.formCtx = { form: this.$refs.form };
|
|
140
142
|
if (onChange) this.$executeOnChange();
|
|
141
143
|
};
|
package/components/popover.vue
CHANGED
|
@@ -56,6 +56,13 @@ export default {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
},
|
|
59
|
+
$tearDown() {
|
|
60
|
+
bus.$off(`popover/close-${this.spec.key}`);
|
|
61
|
+
if (!this.spec.persistent) {
|
|
62
|
+
document.removeEventListener('click', this.handleClose);
|
|
63
|
+
window.removeEventListener('resize', () => this.close());
|
|
64
|
+
}
|
|
65
|
+
},
|
|
59
66
|
handleClose(event) {
|
|
60
67
|
let element = null;
|
|
61
68
|
if (this.$refs.container) {
|
package/nav/appBar.vue
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<panels-responsive v-if="navBar.logo" :spec="navBar.logo" />
|
|
10
10
|
<v-app-bar-title v-else-if="navBar.showTitle">{{
|
|
11
11
|
page.title
|
|
12
|
-
|
|
12
|
+
}}</v-app-bar-title>
|
|
13
13
|
</div>
|
|
14
14
|
<span style="padding-left: 10px;" v-if="navBar.showBreakpoint">
|
|
15
15
|
<common-chip :spec="chipSpec" />
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
<script>
|
|
37
37
|
import ViewsAvatar from "../components/avatar.vue";
|
|
38
38
|
import { vueApp } from "../store";
|
|
39
|
+
import eventBus from "../utils/eventBus";
|
|
39
40
|
|
|
40
41
|
export default {
|
|
41
42
|
components: {
|
|
@@ -123,7 +124,7 @@ export default {
|
|
|
123
124
|
});
|
|
124
125
|
},
|
|
125
126
|
triggerDrawer() {
|
|
126
|
-
|
|
127
|
+
eventBus.$emit("drawers/toggle");
|
|
127
128
|
},
|
|
128
129
|
// viewSourceEnabled: function () {
|
|
129
130
|
// // return process.env.NODE_ENV === "development";
|
package/nav/dialog.vue
CHANGED
|
@@ -47,7 +47,7 @@ import Http from "../utils/http";
|
|
|
47
47
|
import Action from "../action";
|
|
48
48
|
import FormPanel from "../components/panels/form.vue";
|
|
49
49
|
import { confirmDirty, dialogs } from "../store";
|
|
50
|
-
import { onMounted, ref } from "vue";
|
|
50
|
+
import { onBeforeUnmount, onMounted, ref } from "vue";
|
|
51
51
|
import { usePasteable } from "../components/composable/pasteable";
|
|
52
52
|
import { strandom } from "../components/helper.js";
|
|
53
53
|
|
|
@@ -58,14 +58,20 @@ export default {
|
|
|
58
58
|
usePasteable(filePaster);
|
|
59
59
|
|
|
60
60
|
const isFormDirty = ref(false);
|
|
61
|
+
const handler = (event) => {
|
|
62
|
+
const { dirty } = event.detail;
|
|
63
|
+
isFormDirty.value = dirty;
|
|
64
|
+
event.stopPropagation();
|
|
65
|
+
};
|
|
61
66
|
|
|
62
67
|
onMounted(() => {
|
|
63
68
|
const el = document.getElementById('__glib_dialog_body');
|
|
64
|
-
el.addEventListener('dirtyupdate',
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
el.addEventListener('dirtyupdate', handler);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
onBeforeUnmount(() => {
|
|
73
|
+
const el = document.getElementById('__glib_dialog_body');
|
|
74
|
+
el.removeEventListener('dirtyupdate', handler);
|
|
69
75
|
});
|
|
70
76
|
|
|
71
77
|
return { filePaster, isFormDirty };
|
package/nav/drawer.vue
CHANGED
package/nav/drawerButton.vue
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<script>
|
|
8
|
+
import eventBus from "../utils/eventBus";
|
|
9
|
+
|
|
8
10
|
export default {
|
|
9
11
|
props: {
|
|
10
12
|
spec: { type: Object, required: true }
|
|
@@ -12,7 +14,7 @@ export default {
|
|
|
12
14
|
methods: {
|
|
13
15
|
performAction(event) {
|
|
14
16
|
// this.$el.dispatchEvent(new Event("drawers/clickButton", { bubbles: true }))
|
|
15
|
-
|
|
17
|
+
eventBus.$emit("drawers/clickButton", {});
|
|
16
18
|
this.$onClick(event);
|
|
17
19
|
},
|
|
18
20
|
buttonSpec(item) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "glib-web",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.34.3",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -11,13 +11,14 @@
|
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@floating-ui/dom": "^1.2.8",
|
|
13
13
|
"@googlemaps/markerclusterer": "^2.5.0",
|
|
14
|
-
"@rails/actioncable": "
|
|
15
|
-
"@rails/activestorage": "
|
|
14
|
+
"@rails/actioncable": ">= 8.0.0",
|
|
15
|
+
"@rails/activestorage": ">= 8.0.0",
|
|
16
16
|
"awesome-phonenumber": "2.15.0",
|
|
17
17
|
"chart.js": "^4.3.1",
|
|
18
18
|
"chartjs-plugin-datalabels": "^2.2.0",
|
|
19
19
|
"chartjs-plugin-doughnutlabel-v3": "^1.2.0",
|
|
20
20
|
"driver.js": "^1.3.1",
|
|
21
|
+
"eventemitter2": "^6.4.9",
|
|
21
22
|
"flag-icons": "^7.2.3",
|
|
22
23
|
"json-logic-js": "^2.0.0",
|
|
23
24
|
"lodash.merge": "^4.6.2",
|
|
@@ -31,15 +32,14 @@
|
|
|
31
32
|
"push.js": "^1.0.12",
|
|
32
33
|
"quill": "2.0.3",
|
|
33
34
|
"quill-mention": "^6.0.2",
|
|
34
|
-
"tiny-emitter": "^2.1.0",
|
|
35
35
|
"turndown": "^7.1.1",
|
|
36
36
|
"turndown-plugin-gfm": "^1.0.2",
|
|
37
37
|
"v-phone-input": "^4.2.2",
|
|
38
|
-
"vue": "3.
|
|
38
|
+
"vue": "3.5.15",
|
|
39
39
|
"vue-chartkick": "^1.1.0",
|
|
40
40
|
"vue-social-sharing": "^4.0.0-alpha4",
|
|
41
41
|
"vuedraggable": "^4.1.0",
|
|
42
|
-
"vuetify": "
|
|
42
|
+
"vuetify": "3.8.6"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@types/chart.js": "^2.9.34",
|
package/store.js
CHANGED
|
@@ -55,7 +55,6 @@ export function confirmDirty() {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
function glibEventHandler(e, closeAllFloating = true) {
|
|
58
|
-
|
|
59
58
|
if (closeAllFloating) {
|
|
60
59
|
closeAllDialog();
|
|
61
60
|
closeAllPopover();
|
|
@@ -78,6 +77,8 @@ function glibEventHandler(e, closeAllFloating = true) {
|
|
|
78
77
|
// Clear after we go past dirty prompt.
|
|
79
78
|
GLib.component.clearData();
|
|
80
79
|
|
|
80
|
+
eventBus.$removeAllListener();
|
|
81
|
+
|
|
81
82
|
const { onUnload } = jsonView.page;
|
|
82
83
|
if (onUnload) {
|
|
83
84
|
Action.execute(onUnload, {});
|
package/utils/eventBus.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
// eventBus.js
|
|
2
|
-
import
|
|
2
|
+
import EventEmitter2 from "eventemitter2";
|
|
3
3
|
|
|
4
|
-
const emitter = new
|
|
4
|
+
const emitter = new EventEmitter2({ delimiter: '-', maxListeners: 0 });
|
|
5
5
|
|
|
6
6
|
export default {
|
|
7
7
|
$on: (...args) => emitter.on(...args),
|
|
8
8
|
$once: (...args) => emitter.once(...args),
|
|
9
9
|
$off: (...args) => emitter.off(...args),
|
|
10
|
-
$emit: (...args) => emitter.emit(...args)
|
|
11
|
-
|
|
10
|
+
$emit: (...args) => emitter.emit(...args),
|
|
11
|
+
$removeAllListener: (...args) => emitter.removeAllListeners(...args),
|
|
12
|
+
currentListenerCount: () => emitter.listeners().length
|
|
13
|
+
};
|