glib-web 3.18.0 → 3.19.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/README.md +11 -3
- package/action.js +14 -11
- package/actions/components/findClosest.js +6 -0
- package/actions/components/replace.js +11 -0
- package/actions/components/set.js +15 -0
- package/actions/fields/focus.js +10 -3
- package/components/_responsive.vue +3 -0
- package/components/charts/series.js +14 -2
- package/components/component.vue +3 -0
- package/components/composable/dirtyState.js +2 -2
- package/components/fields/_patternText.vue +5 -5
- package/components/fields/_select.vue +8 -1
- package/components/fields/file.vue +0 -2
- package/components/fields/multiUpload.vue +17 -9
- package/components/label.vue +1 -1
- package/components/mixins/generic.js +6 -3
- package/components/mixins/styles.js +15 -2
- package/extensions/string.js +4 -0
- package/index.js +0 -3
- package/nav/dialog.vue +1 -1
- package/package.json +1 -1
- package/utils/settings.js +1 -1
- package/actions/labels/set.js +0 -16
- package/components/mixins/dataset.js +0 -10
package/README.md
CHANGED
|
@@ -22,11 +22,19 @@
|
|
|
22
22
|
- `yarn link glib-web`
|
|
23
23
|
- `bin/vite dev`
|
|
24
24
|
|
|
25
|
-
## Clean up to fix strange errors when running vite dev
|
|
25
|
+
## Clean up to fix strange errors (e.g. tiny-emitter error) when running vite dev
|
|
26
26
|
|
|
27
27
|
- Stop vite server
|
|
28
|
-
|
|
29
|
-
-
|
|
28
|
+
|
|
29
|
+
- On your glib-web-npm's directory:
|
|
30
|
+
- `rm -rf node_modules`
|
|
31
|
+
- `yarn install`
|
|
32
|
+
|
|
33
|
+
- On your project's directory:
|
|
34
|
+
- `rm -rf node_modules`
|
|
35
|
+
- `yarn install`
|
|
36
|
+
- `bin/vite clobber`
|
|
37
|
+
- `bin/vite dev`
|
|
30
38
|
|
|
31
39
|
## Prepare for publishing
|
|
32
40
|
|
package/action.js
CHANGED
|
@@ -2,10 +2,6 @@ import TypeUtils from "./utils/type";
|
|
|
2
2
|
|
|
3
3
|
import ActionsRunMultiple from "./actions/runMultiple";
|
|
4
4
|
|
|
5
|
-
import ActionsFormsSubmit from "./actions/forms/submit";
|
|
6
|
-
import ActionsFieldsReset from "./actions/fields/reset";
|
|
7
|
-
import ActionsFieldsFocus from "./actions/fields/focus";
|
|
8
|
-
|
|
9
5
|
import ActionsHttpGetV1 from "./actions/http/get";
|
|
10
6
|
import ActionsHttpPostV1 from "./actions/http/post";
|
|
11
7
|
import ActionsHttpPatchV1 from "./actions/http/patch";
|
|
@@ -61,10 +57,15 @@ const ActionToursStop = import("./actions/tours/stop");
|
|
|
61
57
|
import ActionPopoversOpen from "./actions/popovers/open";
|
|
62
58
|
import ActionPopoversClose from "./actions/popovers/close";
|
|
63
59
|
|
|
60
|
+
import ActionsFormsSubmit from "./actions/forms/submit";
|
|
61
|
+
import ActionsFieldsReset from "./actions/fields/reset";
|
|
62
|
+
import ActionsFieldsFocus from "./actions/fields/focus";
|
|
63
|
+
|
|
64
64
|
import ActionComponentsUpdate from "./actions/components/update";
|
|
65
65
|
import ActionComponentsFind from "./actions/components/find";
|
|
66
|
-
|
|
67
|
-
import
|
|
66
|
+
import ActionComponentsFindClosest from "./actions/components/findClosest";
|
|
67
|
+
import ActionComponentsReplace from "./actions/components/replace";
|
|
68
|
+
import ActionComponentsSet from "./actions/components/set";
|
|
68
69
|
|
|
69
70
|
import ActionListsAppend from "./actions/lists/append";
|
|
70
71
|
|
|
@@ -73,10 +74,6 @@ import { vueApp } from "./store";
|
|
|
73
74
|
const actions = {
|
|
74
75
|
runMultiple: ActionsRunMultiple,
|
|
75
76
|
|
|
76
|
-
"forms/submit": ActionsFormsSubmit,
|
|
77
|
-
"fields/reset": ActionsFieldsReset,
|
|
78
|
-
"fields/focus": ActionsFieldsFocus,
|
|
79
|
-
|
|
80
77
|
"http/get": ActionsHttpGetV1,
|
|
81
78
|
"http/post": ActionsHttpPostV1,
|
|
82
79
|
"http/patch": ActionsHttpPatchV1,
|
|
@@ -131,10 +128,16 @@ const actions = {
|
|
|
131
128
|
"popovers/open": ActionPopoversOpen,
|
|
132
129
|
"popovers/close": ActionPopoversClose,
|
|
133
130
|
|
|
131
|
+
"forms/submit": ActionsFormsSubmit,
|
|
132
|
+
"fields/reset": ActionsFieldsReset,
|
|
133
|
+
"fields/focus": ActionsFieldsFocus,
|
|
134
|
+
|
|
134
135
|
"components/update": ActionComponentsUpdate,
|
|
135
136
|
"components/find": ActionComponentsFind,
|
|
137
|
+
"components/findClosest": ActionComponentsFindClosest,
|
|
138
|
+
"components/replace": ActionComponentsReplace,
|
|
139
|
+
"components/set": ActionComponentsSet,
|
|
136
140
|
|
|
137
|
-
"labels/set": ActionLabelsSet,
|
|
138
141
|
"lists/append": ActionListsAppend
|
|
139
142
|
};
|
|
140
143
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Experimental
|
|
2
|
+
export default class {
|
|
3
|
+
execute(spec, component) {
|
|
4
|
+
const target = GLib.component.findById(spec.targetId);
|
|
5
|
+
if (target) {
|
|
6
|
+
Object.assign(target.spec, spec.newView);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
Action.execute(properties.onReplace, targetComponent);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export default class {
|
|
2
|
+
execute(spec, component) {
|
|
3
|
+
let targetComponent = component;
|
|
4
|
+
|
|
5
|
+
if (spec.targetId) {
|
|
6
|
+
targetComponent = GLib.component.findById(spec.targetId);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
Utils.type.ifObject(spec.data, (data) => {
|
|
10
|
+
targetComponent.action_merge(data)
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
GLib.action.execute(spec.onSet, targetComponent);
|
|
14
|
+
}
|
|
15
|
+
}
|
package/actions/fields/focus.js
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
export default class {
|
|
2
|
-
execute(
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
execute(spec, component) {
|
|
3
|
+
let targetComponent = component;
|
|
4
|
+
|
|
5
|
+
if (spec.targetId) {
|
|
6
|
+
targetComponent = GLib.component.findById(spec.targetId);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
targetComponent.action_focus();
|
|
10
|
+
|
|
11
|
+
Action.execute(spec.onFocus, targetComponent);
|
|
5
12
|
}
|
|
6
13
|
}
|
|
@@ -56,6 +56,9 @@ export default {
|
|
|
56
56
|
return item.view == "panels/column-v1";
|
|
57
57
|
},
|
|
58
58
|
viewKey(item, index) {
|
|
59
|
+
// force update if child is charts
|
|
60
|
+
if (item.view.toString().startsWith('charts/')) return item;
|
|
61
|
+
|
|
59
62
|
return index;
|
|
60
63
|
|
|
61
64
|
// return `view${index}_${item.view}`;
|
|
@@ -55,16 +55,28 @@ function useChart({ dataSeries, spec, multiple = true }) {
|
|
|
55
55
|
options.plugins.datalabels = datalabels;
|
|
56
56
|
options.plugins.datalabels.formatter = (value, context) => {
|
|
57
57
|
const type = datalabels.formatType || 'value';
|
|
58
|
+
let val = null;
|
|
58
59
|
|
|
59
60
|
switch (type) {
|
|
60
61
|
case 'label':
|
|
61
|
-
|
|
62
|
+
val = context.chart.data.labels[context.dataIndex];
|
|
62
63
|
break;
|
|
63
64
|
|
|
64
65
|
case 'value':
|
|
65
|
-
|
|
66
|
+
val = `${spec.prefix || ''}${value}${spec.suffix || ''}`;
|
|
66
67
|
break;
|
|
67
68
|
}
|
|
69
|
+
|
|
70
|
+
const { dataIndex, datasetIndex } = context;
|
|
71
|
+
const dataset = dataSeries[datasetIndex];
|
|
72
|
+
if (multiple && Array.isArray(dataset.points) && dataset.points[dataIndex].label) {
|
|
73
|
+
val = dataset.points[dataIndex].label;
|
|
74
|
+
}
|
|
75
|
+
if (!multiple && dataSeries[dataIndex].label) {
|
|
76
|
+
val = dataSeries[dataIndex].label;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return val;
|
|
68
80
|
};
|
|
69
81
|
}
|
|
70
82
|
if (centerLabel) {
|
package/components/component.vue
CHANGED
|
@@ -12,8 +12,8 @@ export function useDirtyState() {
|
|
|
12
12
|
ctx().isFormDirty = false;
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
-
const updateDirtyState = (val, oldVal, spec) => {
|
|
16
|
-
if (!spec.disableDirtyCheck && val != oldVal && val !=
|
|
15
|
+
const updateDirtyState = (val, oldVal, initValue, spec) => {
|
|
16
|
+
if (!spec.disableDirtyCheck && val != oldVal && val != initValue) {
|
|
17
17
|
ctx().isFormDirty = true;
|
|
18
18
|
}
|
|
19
19
|
};
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
<div :style="$styles()" :class="classes()">
|
|
3
3
|
<!-- See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date for why we need to use `pattern` -->
|
|
4
4
|
<v-text-field v-model="fieldModel" :name="fieldName" :label="spec.label" :hint="spec.hint" :type="type"
|
|
5
|
-
:readonly="spec.readOnly" :disabled="inputDisabled" :min="$sanitizeValue(spec.min)"
|
|
6
|
-
:pattern="pattern" :rules="$validation()" :style="$styles()"
|
|
5
|
+
:readonly="spec.readOnly" :disabled="inputDisabled" :min="$sanitizeValue(spec.min)"
|
|
6
|
+
:max="$sanitizeValue(spec.max)" :pattern="pattern" :rules="$validation()" :style="$styles()"
|
|
7
7
|
:density="$classes().includes('compact') ? 'compact' : 'default'" clearable @change="onChange" :variant="variant"
|
|
8
8
|
validate-on="blur" persistent-placeholder />
|
|
9
9
|
</div>
|
|
@@ -24,14 +24,14 @@ export default {
|
|
|
24
24
|
if (Utils.type.isString(val)) {
|
|
25
25
|
return new Date(val).getTime() / 1000;
|
|
26
26
|
}
|
|
27
|
-
return
|
|
27
|
+
return val;
|
|
28
28
|
},
|
|
29
29
|
$externalizeValue(val) {
|
|
30
30
|
if (Utils.type.isNumber(val)) {
|
|
31
31
|
const date = new Date(val * 1000);
|
|
32
|
-
return
|
|
32
|
+
return date.toISOString();
|
|
33
33
|
}
|
|
34
|
-
return
|
|
34
|
+
return val;
|
|
35
35
|
},
|
|
36
36
|
$sanitizeValue(val) {
|
|
37
37
|
if (val) {
|
|
@@ -20,6 +20,13 @@
|
|
|
20
20
|
</v-list-item>
|
|
21
21
|
</template>
|
|
22
22
|
|
|
23
|
+
<template v-slot:prepend-item v-if="spec.header">
|
|
24
|
+
<common-responsive :spec="spec.header" />
|
|
25
|
+
</template>
|
|
26
|
+
|
|
27
|
+
<template v-slot:append-item v-if="spec.footer">
|
|
28
|
+
<common-responsive :spec="spec.footer" />
|
|
29
|
+
</template>
|
|
23
30
|
</v-autocomplete>
|
|
24
31
|
|
|
25
32
|
<input v-for="(item, index) in values" :key="index" type="hidden" :disabled="inputDisabled" :name="fieldName"
|
|
@@ -63,7 +70,7 @@ export default {
|
|
|
63
70
|
return determineDensity(this.spec.styleClasses);
|
|
64
71
|
},
|
|
65
72
|
label() {
|
|
66
|
-
if (this.focused) {
|
|
73
|
+
if (this.focused && this.spec.hint) {
|
|
67
74
|
return `${this.spec.label} ${this.spec.hint}`
|
|
68
75
|
}
|
|
69
76
|
return this.spec.label
|
|
@@ -26,8 +26,9 @@
|
|
|
26
26
|
<div class="status">
|
|
27
27
|
<v-icon class="icon">{{ file[1].isImage() ? 'photo_library' : 'description' }}</v-icon>
|
|
28
28
|
<div class="progress">
|
|
29
|
-
<
|
|
30
|
-
|
|
29
|
+
<div class="label"><span>{{ `${file[1].name}` }}</span><span v-if="file[1].message"
|
|
30
|
+
style="font-size: 0.75em">{{
|
|
31
|
+
file[1].message }}</span></div>
|
|
31
32
|
<div class="background" v-show="file[1].progress.value > 0">
|
|
32
33
|
<div class="value" :style="{ width: `${file[1].progress.value}%` }"></div>
|
|
33
34
|
</div>
|
|
@@ -96,12 +97,16 @@
|
|
|
96
97
|
|
|
97
98
|
.progress {
|
|
98
99
|
display: flex;
|
|
99
|
-
|
|
100
|
+
flex-grow: 1;
|
|
100
101
|
flex-direction: column;
|
|
101
102
|
justify-content: space-between;
|
|
102
103
|
|
|
103
104
|
.label {
|
|
104
105
|
/* mb-1 */
|
|
106
|
+
display: flex;
|
|
107
|
+
align-items: center;
|
|
108
|
+
justify-content: space-between;
|
|
109
|
+
flex-wrap: nowrap;
|
|
105
110
|
margin-bottom: 4px;
|
|
106
111
|
}
|
|
107
112
|
|
|
@@ -239,6 +244,9 @@ export default defineComponent({
|
|
|
239
244
|
const container = ref(null);
|
|
240
245
|
const icon = ref(null);
|
|
241
246
|
|
|
247
|
+
const responseMessages = spec.responseMessages;
|
|
248
|
+
const uploadTitle = spec.uploadTitle || 'File added';
|
|
249
|
+
|
|
242
250
|
let files = ref({});
|
|
243
251
|
if (spec.files && spec.files.length > 0) {
|
|
244
252
|
files = ref(spec.files.reduce((prev, curr) => {
|
|
@@ -308,11 +316,14 @@ export default defineComponent({
|
|
|
308
316
|
if (!error) {
|
|
309
317
|
Object.assign(files.value[key], {
|
|
310
318
|
status: 'completed',
|
|
311
|
-
signedId: blob.signed_id
|
|
319
|
+
signedId: blob.signed_id,
|
|
320
|
+
message: responseMessages['200']
|
|
312
321
|
});
|
|
313
322
|
} else {
|
|
323
|
+
const message = responseMessages[error.slice(-3) || 'else'];
|
|
314
324
|
Object.assign(files.value[key], {
|
|
315
|
-
status: 'failed'
|
|
325
|
+
status: 'failed',
|
|
326
|
+
message: message
|
|
316
327
|
});
|
|
317
328
|
}
|
|
318
329
|
});
|
|
@@ -366,9 +377,6 @@ export default defineComponent({
|
|
|
366
377
|
fileSelect.value.click();
|
|
367
378
|
}
|
|
368
379
|
|
|
369
|
-
const uploadFailedText = spec.uploadFailedText || '(UPLOAD FAILED)';
|
|
370
|
-
const uploadTitle = spec.uploadTitle || 'File added';
|
|
371
|
-
|
|
372
380
|
return {
|
|
373
381
|
files,
|
|
374
382
|
fileSelect,
|
|
@@ -380,7 +388,7 @@ export default defineComponent({
|
|
|
380
388
|
handleClick,
|
|
381
389
|
handleRemoveFile,
|
|
382
390
|
showUploadedFile,
|
|
383
|
-
|
|
391
|
+
responseMessages,
|
|
384
392
|
uploadTitle
|
|
385
393
|
};
|
|
386
394
|
}
|
package/components/label.vue
CHANGED
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
methods: {
|
|
5
5
|
$componentName() { // Can be overridden
|
|
6
6
|
if (this.spec) {
|
|
7
|
-
return this.spec.view;
|
|
7
|
+
return this.spec.view?.replace('-v1', '');
|
|
8
8
|
}
|
|
9
9
|
},
|
|
10
10
|
$closest(name) {
|
|
@@ -12,8 +12,8 @@ export default {
|
|
|
12
12
|
while (parent != null) {
|
|
13
13
|
if (
|
|
14
14
|
(Utils.type.isObject(parent.spec) || Utils.type.isObject(parent.formSpec)) &&
|
|
15
|
-
parent.$componentName() == name
|
|
16
|
-
|
|
15
|
+
parent.$componentName() == name &&
|
|
16
|
+
parent.$registryEnabled()
|
|
17
17
|
) {
|
|
18
18
|
return parent;
|
|
19
19
|
}
|
|
@@ -78,6 +78,9 @@ export default {
|
|
|
78
78
|
Utils.ws.handleResponse(payload.onResponse, this);
|
|
79
79
|
});
|
|
80
80
|
}
|
|
81
|
+
},
|
|
82
|
+
action_merge(mergedSpec) {
|
|
83
|
+
Object.assign(this.spec, mergedSpec);
|
|
81
84
|
}
|
|
82
85
|
}
|
|
83
86
|
};
|
|
@@ -49,7 +49,8 @@ export default {
|
|
|
49
49
|
|
|
50
50
|
Object.assign(fieldModels, { [this.fieldName]: this.$internalizeValue(val) });
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
const initValue = this.$sanitizeValue(this.$externalizeValue(this.spec.value));
|
|
53
|
+
updateDirtyState(val, oldVal, initValue, this.spec);
|
|
53
54
|
},
|
|
54
55
|
spec: {
|
|
55
56
|
handler(spec, oldSpec) {
|
|
@@ -101,17 +102,29 @@ export default {
|
|
|
101
102
|
this._watchers.push(watcher1);
|
|
102
103
|
}
|
|
103
104
|
|
|
104
|
-
if (this.spec && (this.spec.showIf || this.spec.loadIf)) {
|
|
105
|
+
if (this.spec && (this.spec.showIf || this.spec.loadIf) && this.$jsonLogicEnabled()) {
|
|
105
106
|
watcher2 = watchFieldModels(this.spec.showIf || this.spec.loadIf, (value) => {
|
|
107
|
+
const oldValue = this._show;
|
|
108
|
+
|
|
106
109
|
if (value) {
|
|
107
110
|
this._show = true;
|
|
108
111
|
} else {
|
|
109
112
|
this._show = false;
|
|
110
113
|
}
|
|
114
|
+
|
|
115
|
+
if (oldValue != value) {
|
|
116
|
+
this.$nextTick(() => {
|
|
117
|
+
// Call either onIfTrue or onIfFalse.
|
|
118
|
+
Action.execute(this.spec[`onIf${value.toString().capitalize()}`], this);
|
|
119
|
+
});
|
|
120
|
+
}
|
|
111
121
|
});
|
|
112
122
|
this._watchers.push(watcher2);
|
|
113
123
|
}
|
|
114
124
|
},
|
|
125
|
+
$jsonLogicEnabled() {
|
|
126
|
+
return true;
|
|
127
|
+
},
|
|
115
128
|
// TODO: Deprecated
|
|
116
129
|
genericStyles(spec) {
|
|
117
130
|
return this.$styles(spec);
|
package/extensions/string.js
CHANGED
package/index.js
CHANGED
|
@@ -80,9 +80,6 @@ Vue.mixin(stylesMixin);
|
|
|
80
80
|
import scrollingMixin from "./components/mixins/scrolling.js";
|
|
81
81
|
Vue.mixin(scrollingMixin);
|
|
82
82
|
|
|
83
|
-
import datasetMixins from "./components/mixins/dataset.js";
|
|
84
|
-
Vue.mixin(datasetMixins);
|
|
85
|
-
|
|
86
83
|
Vue.config.globalProperties.extension = {};
|
|
87
84
|
import extension from "./components/mixins/extension.js";
|
|
88
85
|
Vue.mixin(extension);
|
package/nav/dialog.vue
CHANGED
package/package.json
CHANGED
package/utils/settings.js
CHANGED
|
@@ -6,7 +6,7 @@ class MutableSettings {
|
|
|
6
6
|
this.themes = {};
|
|
7
7
|
this.gtagId = null;
|
|
8
8
|
this.errorHandler = (err, message) => {
|
|
9
|
-
console.error(message || err.message);
|
|
9
|
+
console.error(message || err.message, err);
|
|
10
10
|
};
|
|
11
11
|
this.headerAugmenter = (_url, _method) => {
|
|
12
12
|
// Set a custom augmenter to add custom HTTP headers.
|
package/actions/labels/set.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import Action from "../../action";
|
|
2
|
-
|
|
3
|
-
export default class {
|
|
4
|
-
execute(properties, component) {
|
|
5
|
-
let targetComponent = component;
|
|
6
|
-
if (properties.targetId) {
|
|
7
|
-
targetComponent = GLib.component.findById(properties.targetId);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
targetComponent.text = properties.text;
|
|
11
|
-
|
|
12
|
-
if (properties.onSet) {
|
|
13
|
-
Action.execute(properties.onSet, targetComponent);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
}
|