glib-web 3.24.4 → 3.25.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 +12 -0
- package/actions/components/replace.js +1 -1
- package/actions/components/replaceChildren.js +15 -0
- package/actions/cookies/save.js +10 -0
- package/actions/logics/set.js +40 -0
- package/actions/windows/close.js +1 -1
- package/actions/windows/closeWithOpen.js +9 -0
- package/app.vue +24 -1
- package/components/charts/series.js +89 -1
- package/components/fields/multiUpload.vue +1 -4
- package/components/mixins/events.js +4 -3
- package/components/panels/carousel.vue +5 -0
- package/package.json +1 -1
package/action.js
CHANGED
|
@@ -29,6 +29,7 @@ import ActionsWindowsOpen from "./actions/windows/open";
|
|
|
29
29
|
import ActionsWindowsOpenWeb from "./actions/windows/openWeb";
|
|
30
30
|
import ActionsWindowsReload from "./actions/windows/reload";
|
|
31
31
|
import ActionsWindowsCloseWithReload from "./actions/windows/closeWithReload";
|
|
32
|
+
import ActionsWindowsCloseWithOpen from "./actions/windows/closeWithOpen";
|
|
32
33
|
import ActionsWindowsRefreshState from "./actions/windows/refreshState";
|
|
33
34
|
import ActionsWindowsPrint from "./actions/windows/print";
|
|
34
35
|
|
|
@@ -45,6 +46,8 @@ import ActionsAuthSaveCsrfToken from "./actions/auth/saveCsrfToken";
|
|
|
45
46
|
import ActionsAuthRestart from "./actions/auth/restart";
|
|
46
47
|
import ActionsCreditCard from "./actions/auth/creditCard";
|
|
47
48
|
|
|
49
|
+
import ActionsCookiesSave from "./actions/cookies/save";
|
|
50
|
+
|
|
48
51
|
import ActionsAnalyticsLogEvent from "./actions/analytics/logEvent";
|
|
49
52
|
|
|
50
53
|
import ActionCommandsCopy from "./actions/commands/copy";
|
|
@@ -67,8 +70,11 @@ import ActionComponentsUpdate from "./actions/components/update";
|
|
|
67
70
|
import ActionComponentsFind from "./actions/components/find";
|
|
68
71
|
import ActionComponentsFindClosest from "./actions/components/findClosest";
|
|
69
72
|
import ActionComponentsReplace from "./actions/components/replace";
|
|
73
|
+
import ActionComponentsReplaceChildren from "./actions/components/replaceChildren";
|
|
70
74
|
import ActionComponentsSet from "./actions/components/set";
|
|
71
75
|
|
|
76
|
+
import ActionLogicsSet from "./actions/logics/set";
|
|
77
|
+
|
|
72
78
|
import ActionListsAppend from "./actions/lists/append";
|
|
73
79
|
|
|
74
80
|
import { dialogs, vueApp } from "./store";
|
|
@@ -103,6 +109,7 @@ const actions = {
|
|
|
103
109
|
"windows/openWeb": ActionsWindowsOpenWeb,
|
|
104
110
|
"windows/reload": ActionsWindowsReload,
|
|
105
111
|
"windows/closeWithReload": ActionsWindowsCloseWithReload,
|
|
112
|
+
"windows/closeWithOpen": ActionsWindowsCloseWithOpen,
|
|
106
113
|
"windows/refreshState": ActionsWindowsRefreshState,
|
|
107
114
|
"windows/print": ActionsWindowsPrint,
|
|
108
115
|
|
|
@@ -119,6 +126,8 @@ const actions = {
|
|
|
119
126
|
"auth/restart": ActionsAuthRestart,
|
|
120
127
|
"auth/creditCard": ActionsCreditCard,
|
|
121
128
|
|
|
129
|
+
"cookies/save": ActionsCookiesSave,
|
|
130
|
+
|
|
122
131
|
"analytics/logEvent": ActionsAnalyticsLogEvent,
|
|
123
132
|
|
|
124
133
|
"commands/copy": ActionCommandsCopy,
|
|
@@ -140,8 +149,11 @@ const actions = {
|
|
|
140
149
|
"components/find": ActionComponentsFind,
|
|
141
150
|
"components/findClosest": ActionComponentsFindClosest,
|
|
142
151
|
"components/replace": ActionComponentsReplace,
|
|
152
|
+
"components/replaceChildren": ActionComponentsReplaceChildren,
|
|
143
153
|
"components/set": ActionComponentsSet,
|
|
144
154
|
|
|
155
|
+
"logics/set": ActionLogicsSet,
|
|
156
|
+
|
|
145
157
|
"lists/append": ActionListsAppend
|
|
146
158
|
};
|
|
147
159
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { nextTick } from "vue";
|
|
2
|
+
|
|
3
|
+
// Experimental
|
|
4
|
+
export default class {
|
|
5
|
+
execute(spec, component) {
|
|
6
|
+
const target = GLib.component.findById(spec.targetId) || component;
|
|
7
|
+
if (target) {
|
|
8
|
+
Object.assign(target.spec.childViews, spec.childViews);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
nextTick(() => {
|
|
12
|
+
Action.execute(spec.onReplace, target);
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export default class {
|
|
2
|
+
execute(spec, component) {
|
|
3
|
+
const key = spec.key;
|
|
4
|
+
const value = spec.value;
|
|
5
|
+
if (Utils.type.isNotNull(key) && Utils.type.isNotNull(value)) {
|
|
6
|
+
document.cookie = `${key}=${value}`;
|
|
7
|
+
Action.execute(spec.onSave, component);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import jsonLogic from 'json-logic-js';
|
|
2
|
+
|
|
3
|
+
const subscript = function(a, b) {
|
|
4
|
+
if (a) {
|
|
5
|
+
if (b) { // This is expected when the dependent field doesn't have a value
|
|
6
|
+
return a[b];
|
|
7
|
+
} else {
|
|
8
|
+
console.info('Null subscript')
|
|
9
|
+
}
|
|
10
|
+
} else {
|
|
11
|
+
console.error('Left hand operator not found')
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
jsonLogic.add_operation("[]", subscript);
|
|
15
|
+
|
|
16
|
+
// Ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing
|
|
17
|
+
const nullishCoalescing = function(a, b) {
|
|
18
|
+
return a ?? b;
|
|
19
|
+
}
|
|
20
|
+
jsonLogic.add_operation("??", nullishCoalescing);
|
|
21
|
+
|
|
22
|
+
export default class {
|
|
23
|
+
execute(spec, component) {
|
|
24
|
+
let targetComponent = component;
|
|
25
|
+
|
|
26
|
+
if (spec.targetId) {
|
|
27
|
+
targetComponent = GLib.component.findById(spec.targetId);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
Utils.type.ifObject(spec.conditionalData, (properties) => {
|
|
31
|
+
const data = {}
|
|
32
|
+
for (const key in properties) {
|
|
33
|
+
data[key] = jsonLogic.apply(properties[key], spec.variables);
|
|
34
|
+
}
|
|
35
|
+
targetComponent.action_merge(data);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
GLib.action.execute(spec.onSet, targetComponent);
|
|
39
|
+
}
|
|
40
|
+
}
|
package/actions/windows/close.js
CHANGED
package/app.vue
CHANGED
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
</div>
|
|
15
15
|
|
|
16
16
|
<div id="page_body" class="pages-body body-wrapper">
|
|
17
|
-
<panels-responsive :spec="
|
|
17
|
+
<panels-responsive class="body-header" :spec="bodyHeader" />
|
|
18
|
+
<panels-responsive class="body-content" :spec="body" />
|
|
19
|
+
<panels-responsive class="body-footer" :spec="bodyFooter" />
|
|
18
20
|
</div>
|
|
19
21
|
|
|
20
22
|
<div class="pages-footer">
|
|
@@ -72,6 +74,9 @@ export default {
|
|
|
72
74
|
footer() {
|
|
73
75
|
return this.page.footer || {};
|
|
74
76
|
},
|
|
77
|
+
bodyFooter() {
|
|
78
|
+
return this.page.bodyFooter || {};
|
|
79
|
+
},
|
|
75
80
|
containerComponent() {
|
|
76
81
|
if (this.formSpec) {
|
|
77
82
|
this.name = "panels-form";
|
|
@@ -214,6 +219,24 @@ body,
|
|
|
214
219
|
height: 100%;
|
|
215
220
|
}
|
|
216
221
|
|
|
222
|
+
.pages-body {
|
|
223
|
+
display: flex;
|
|
224
|
+
flex-direction: column;
|
|
225
|
+
|
|
226
|
+
.body-header {
|
|
227
|
+
display: block;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.body-content {
|
|
231
|
+
flex: 1 0 auto;
|
|
232
|
+
display: block;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.body-footer {
|
|
236
|
+
display: block;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
217
240
|
/******/
|
|
218
241
|
|
|
219
242
|
/*** panels/scrollTo support ***/
|
|
@@ -2,6 +2,7 @@ import { Chart, Colors } from "chart.js";
|
|
|
2
2
|
import chartDataLabels from 'chartjs-plugin-datalabels';
|
|
3
3
|
import doughnutLabel from 'chartjs-plugin-doughnutlabel-v3';
|
|
4
4
|
import { Vue } from "../..";
|
|
5
|
+
import { computePosition, flip, offset } from '@floating-ui/dom';
|
|
5
6
|
|
|
6
7
|
import 'chartkick/chart.js';
|
|
7
8
|
|
|
@@ -30,9 +31,89 @@ const multipleDataSeries = (dataSeries) => {
|
|
|
30
31
|
|
|
31
32
|
const singleDataSeries = (dataSeries) => dataSeries.reduce((prev, curr) => Object.assign(prev, { [curr.title]: curr.value }), {});
|
|
32
33
|
|
|
34
|
+
const getOrCreateTooltip = (chart) => {
|
|
35
|
+
let tooltipEl = chart.canvas.parentNode.querySelector('#_glib-chart-tooltip');
|
|
36
|
+
let referenceEl = chart.canvas.parentNode.querySelector('#_glib-chart-reference');
|
|
37
|
+
|
|
38
|
+
if (!tooltipEl) {
|
|
39
|
+
tooltipEl = document.createElement('div');
|
|
40
|
+
tooltipEl.id = '_glib-chart-tooltip';
|
|
41
|
+
tooltipEl.style.opacity = 1;
|
|
42
|
+
tooltipEl.style.pointerEvents = 'none';
|
|
43
|
+
tooltipEl.style.position = 'absolute';
|
|
44
|
+
tooltipEl.style.transition = 'all .1s ease';
|
|
45
|
+
tooltipEl.style.lineHeight = 1;
|
|
46
|
+
|
|
47
|
+
chart.canvas.parentNode.appendChild(tooltipEl);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (!referenceEl) {
|
|
51
|
+
referenceEl = document.createElement('div');
|
|
52
|
+
referenceEl.id = '_glib-chart-reference';
|
|
53
|
+
referenceEl.style.position = 'absolute';
|
|
54
|
+
referenceEl.style.width = '1px';
|
|
55
|
+
referenceEl.style.height = '1px';
|
|
56
|
+
referenceEl.style.opacity = 0;
|
|
57
|
+
|
|
58
|
+
chart.canvas.parentNode.appendChild(referenceEl);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return { tooltipEl, referenceEl };
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const externalTooltipHandler = (multiple, dataSeries) => {
|
|
65
|
+
return (context) => {
|
|
66
|
+
const tooltipData = getData(multiple, dataSeries, context.tooltip.dataPoints[0]);
|
|
67
|
+
|
|
68
|
+
if (!tooltipData) return;
|
|
69
|
+
|
|
70
|
+
const innerHTML = tooltipData.tooltip;
|
|
71
|
+
|
|
72
|
+
// Tooltip Element
|
|
73
|
+
const { chart, tooltip } = context;
|
|
74
|
+
const { tooltipEl, referenceEl } = getOrCreateTooltip(chart);
|
|
75
|
+
|
|
76
|
+
// Hide if no tooltip
|
|
77
|
+
if (tooltip.opacity === 0) {
|
|
78
|
+
tooltipEl.style.opacity = 0;
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (tooltip.body) {
|
|
83
|
+
tooltipEl.innerHTML = innerHTML;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const position = chart.canvas.getBoundingClientRect();
|
|
87
|
+
|
|
88
|
+
referenceEl.style.left = position.left + tooltip.caretX + 'px';
|
|
89
|
+
referenceEl.style.top = position.top + tooltip.caretY + 'px';
|
|
90
|
+
computePosition(referenceEl, tooltipEl, { placement: 'right', middleware: [flip(), offset(8)] })
|
|
91
|
+
.then(({ x, y }) => {
|
|
92
|
+
tooltipEl.style.left = x + 'px';
|
|
93
|
+
tooltipEl.style.top = y + 'px';
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Display, position, and set styles for font
|
|
97
|
+
tooltipEl.style.opacity = 1;
|
|
98
|
+
tooltipEl.style.font = tooltip.options.bodyFont.string;
|
|
99
|
+
tooltipEl.style.padding = tooltip.options.padding + 'px ' + tooltip.options.padding + 'px';
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const getData = (multiple, dataSeries, context) => {
|
|
104
|
+
const { dataIndex, datasetIndex } = context;
|
|
105
|
+
const dataset = dataSeries[datasetIndex];
|
|
106
|
+
if (multiple && Array.isArray(dataset.points) && dataset.points[dataIndex]) {
|
|
107
|
+
return dataset.points[dataIndex];
|
|
108
|
+
}
|
|
109
|
+
if (!multiple && dataSeries[dataIndex]) {
|
|
110
|
+
return dataSeries[dataIndex];
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
33
114
|
function useChart({ dataSeries, spec, multiple = true }) {
|
|
34
115
|
const isDonut = [spec.styleClasses].flat().includes('donut');
|
|
35
|
-
const { datalabels, centerLabel } = spec.plugins || {};
|
|
116
|
+
const { datalabels, centerLabel, customTooltip } = spec.plugins || {};
|
|
36
117
|
const legend = spec.legend || { display: true };
|
|
37
118
|
|
|
38
119
|
let series = null;
|
|
@@ -85,6 +166,13 @@ function useChart({ dataSeries, spec, multiple = true }) {
|
|
|
85
166
|
};
|
|
86
167
|
}
|
|
87
168
|
|
|
169
|
+
if (customTooltip) {
|
|
170
|
+
options.plugins.tooltip = {
|
|
171
|
+
enabled: false,
|
|
172
|
+
external: externalTooltipHandler(multiple, dataSeries)
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
88
176
|
return { series, colors, options };
|
|
89
177
|
}
|
|
90
178
|
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<p v-if="props.spec.hint" class="subtitle">{{ props.spec.hint }}</p>
|
|
11
11
|
</div>
|
|
12
12
|
|
|
13
|
-
<input v-for="(file, index) in
|
|
13
|
+
<input v-for="(file, index) in files" type="hidden" :name="props.spec.name" :value="file.signedId"
|
|
14
14
|
:disabled="inputDisabled" :key="`hidden-${index}`">
|
|
15
15
|
</div>
|
|
16
16
|
|
|
@@ -246,8 +246,6 @@ export default defineComponent({
|
|
|
246
246
|
return Object.keys(files.value).length > 0;
|
|
247
247
|
});
|
|
248
248
|
|
|
249
|
-
const completedFiles = computed(() => Object.values(files.value).filter((value) => value.status == 'completed'));
|
|
250
|
-
|
|
251
249
|
function handleDrop(e) {
|
|
252
250
|
e.preventDefault();
|
|
253
251
|
uploadFiles(
|
|
@@ -325,7 +323,6 @@ export default defineComponent({
|
|
|
325
323
|
handleClick,
|
|
326
324
|
handleRemoveFile,
|
|
327
325
|
showUploadedFile,
|
|
328
|
-
completedFiles,
|
|
329
326
|
responseMessages,
|
|
330
327
|
uploadTitle,
|
|
331
328
|
props
|
|
@@ -212,14 +212,15 @@ export default {
|
|
|
212
212
|
this.$nextTick(() => {
|
|
213
213
|
const value = newValue || this.fieldModel;
|
|
214
214
|
const formData = {
|
|
215
|
-
[this.fieldName]: value
|
|
215
|
+
[this.spec.paramNameForFieldName || this.fieldName]: value
|
|
216
216
|
};
|
|
217
217
|
const params = this.spec.paramNameForFormData
|
|
218
218
|
? {
|
|
219
|
-
[this.spec.paramNameForFormData]: formData
|
|
219
|
+
[this.spec.paramNameForFormData || formData]: formData
|
|
220
220
|
}
|
|
221
221
|
: formData;
|
|
222
|
-
|
|
222
|
+
|
|
223
|
+
const data = merge({}, onChange, params);
|
|
223
224
|
GLib.action.execute(data, this);
|
|
224
225
|
});
|
|
225
226
|
});
|
|
@@ -46,15 +46,20 @@ export default {
|
|
|
46
46
|
break;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
const containerHeight = this.spec.height;
|
|
49
50
|
const chunkSize = 12 / colSize;
|
|
50
51
|
const panels = []
|
|
51
52
|
for (let i = 0; i < childViews.length; i += chunkSize) {
|
|
52
53
|
const chunk = childViews.slice(i, i + chunkSize);
|
|
53
54
|
panels.push({
|
|
54
55
|
view: 'panels/responsive',
|
|
56
|
+
height: containerHeight ? containerHeight - 100 : null,
|
|
57
|
+
// backgroundColor: '#ff0000',
|
|
55
58
|
childViews: chunk.map((panel) => {
|
|
56
59
|
return {
|
|
57
60
|
view: 'panels/column',
|
|
61
|
+
// backgroundColor: '#00ff00',
|
|
62
|
+
height: 'matchParent',
|
|
58
63
|
[breakpoint]: { cols: colSize },
|
|
59
64
|
childViews: [panel]
|
|
60
65
|
}
|