glib-web 4.6.0 → 4.8.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/action.js +0 -3
- package/actions/cookies/save.js +2 -0
- package/actions/fields/focus.js +2 -1
- package/actions/files/upload.js +14 -11
- package/actions/http/patch.js +0 -2
- package/actions/http/post.js +0 -3
- package/actions/http/put.js +0 -4
- package/actions/logics/set.js +1 -0
- package/components/_button.vue +2 -2
- package/components/_dropdownMenu.vue +6 -6
- package/components/_icon.vue +8 -3
- package/components/_internal_button.vue +4 -5
- package/components/_tooltip.vue +8 -23
- package/components/avatar.vue +4 -3
- package/components/banners/select.vue +3 -11
- package/components/component.vue +1 -1
- package/components/composable/file.js +40 -1
- package/components/composable/tree.js +10 -7
- package/components/composable/upload.js +2 -3
- package/components/composable/upload_delegator.js +5 -1
- package/components/fields/_patternText.vue +2 -2
- package/components/fields/_select.vue +8 -1
- package/components/fields/check/_featured.vue +3 -3
- package/components/fields/check/_thumbnail.vue +2 -2
- package/components/fields/dynamicSelect.vue +4 -4
- package/components/fields/file.vue +2 -1
- package/components/fields/multiUpload.vue +73 -34
- package/components/fields/newRichText.vue +2 -1
- package/components/fields/phone.vue +1 -1
- package/components/fields/radioGroup.vue +0 -7
- package/components/fields/richText.vue +2 -1
- package/components/fields/selectAsset/doc-1.png +0 -0
- package/components/fields/selectAsset/pdf-1.png +0 -0
- package/components/fields/selectAsset/pic-1.png +0 -0
- package/components/fields/submit.vue +8 -2
- package/components/fields/text.vue +1 -1
- package/components/fields/textarea.vue +1 -1
- package/components/helper.js +11 -0
- package/components/mixins/events.js +0 -4
- package/components/mixins/styles.js +9 -9
- package/components/panels/form.vue +1 -6
- package/components/panels/tree/standard.vue +6 -3
- package/components/panels/tree.vue +10 -4
- package/cypress/e2e/glib-web/display.cy.ts +3 -0
- package/cypress/e2e/glib-web/form.cy.ts +3 -0
- package/nav/appBar.vue +3 -3
- package/nav/dialog.vue +0 -5
- package/nav/layout.vue +2 -2
- package/package.json +1 -1
- package/templates/_menu.vue +1 -1
- package/templates/editable.vue +5 -6
- package/templates/thumbnail.vue +5 -6
- package/utils/glibDirectUpload.js +0 -40
- package/utils/http.js +1 -21
- package/actions/http/modifyFormData.js +0 -7
package/action.js
CHANGED
package/actions/cookies/save.js
CHANGED
package/actions/fields/focus.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { nextTick } from "vue";
|
|
2
2
|
import Action from "../../action";
|
|
3
|
+
import { realComponent } from "../../components/helper";
|
|
3
4
|
|
|
4
5
|
export default class {
|
|
5
6
|
execute(spec, component) {
|
|
6
|
-
let targetComponent = GLib.component.findById(spec.targetId);
|
|
7
|
+
let targetComponent = realComponent(GLib.component.findById(spec.targetId));
|
|
7
8
|
|
|
8
9
|
if (!targetComponent) {
|
|
9
10
|
console.warn("Component ID not found", spec.targetId);
|
package/actions/files/upload.js
CHANGED
|
@@ -4,17 +4,10 @@ import { useFilesState } from "../../components/composable/file";
|
|
|
4
4
|
import Action from "../../action";
|
|
5
5
|
|
|
6
6
|
export default class {
|
|
7
|
-
execute(spec, component
|
|
7
|
+
execute(spec, component) {
|
|
8
8
|
const files = ref({});
|
|
9
|
-
const droppedFiles =
|
|
9
|
+
const droppedFiles = spec.files;
|
|
10
10
|
const container = ref(component.$el);
|
|
11
|
-
const context = params.data;
|
|
12
|
-
|
|
13
|
-
// if drop item is not file
|
|
14
|
-
if (droppedFiles.length <= 0) {
|
|
15
|
-
Action.execute(spec.onFinished, {}, { glib: { context } });
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
11
|
|
|
19
12
|
setBusyWhenUploading({ files });
|
|
20
13
|
// if drop item is file
|
|
@@ -24,8 +17,18 @@ export default class {
|
|
|
24
17
|
if (spec.onFinished) {
|
|
25
18
|
watch(uploaded, (val) => {
|
|
26
19
|
const signedIds = Object.values(files.value).map((f) => f.signedId);
|
|
27
|
-
const obj =
|
|
28
|
-
|
|
20
|
+
const obj = {
|
|
21
|
+
[spec.paramNameForFormData || 'formData']: {
|
|
22
|
+
[spec.paramNameForFiles || 'files']: signedIds,
|
|
23
|
+
[spec.paramNameForContext || 'context']: spec.context,
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
const data = Object.assign(
|
|
27
|
+
{},
|
|
28
|
+
spec.onFinished,
|
|
29
|
+
obj
|
|
30
|
+
);
|
|
31
|
+
if (val) Action.execute(data, component);
|
|
29
32
|
});
|
|
30
33
|
}
|
|
31
34
|
}
|
package/actions/http/patch.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import modifyFormData from "./modifyFormData";
|
|
2
1
|
|
|
3
2
|
export default class {
|
|
4
3
|
execute(properties, controller, params) {
|
|
5
|
-
modifyFormData(properties, params);
|
|
6
4
|
|
|
7
5
|
GLib.http.execute(properties, "PATCH", controller, response =>
|
|
8
6
|
GLib.action.handleResponse(response, controller)
|
package/actions/http/post.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import modifyFormData from "./modifyFormData";
|
|
2
|
-
|
|
3
1
|
export default class {
|
|
4
2
|
execute(properties, controller, params) {
|
|
5
|
-
modifyFormData(properties, params);
|
|
6
3
|
|
|
7
4
|
GLib.http.execute(properties, "POST", controller, response =>
|
|
8
5
|
GLib.action.handleResponse(response, controller)
|
package/actions/http/put.js
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
import modifyFormData from "./modifyFormData";
|
|
2
|
-
|
|
3
1
|
export default class {
|
|
4
2
|
execute(properties, controller, params) {
|
|
5
|
-
modifyFormData(properties, params);
|
|
6
|
-
|
|
7
3
|
GLib.http.execute(properties, "PUT", controller, response =>
|
|
8
4
|
GLib.action.handleResponse(response, controller)
|
|
9
5
|
);
|
package/actions/logics/set.js
CHANGED
|
@@ -25,6 +25,7 @@ export default class {
|
|
|
25
25
|
execute(spec, component) {
|
|
26
26
|
let targetComponent;
|
|
27
27
|
|
|
28
|
+
// TODO: add comment
|
|
28
29
|
const dynamicGroupEntry = component.$closest("fields/internalDynamicGroupEntry");
|
|
29
30
|
const targetIds = spec.targetId ? [spec.targetId] : spec.targetIds;
|
|
30
31
|
if (targetIds.length > 0) {
|
package/components/_button.vue
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<common-badge v-if="spec.badge" :spec="spec">
|
|
3
|
-
<internal-button :spec="spec"
|
|
3
|
+
<internal-button :spec="spec" />
|
|
4
4
|
</common-badge>
|
|
5
|
-
<internal-button v-else :spec="spec"
|
|
5
|
+
<internal-button v-else :spec="spec" />
|
|
6
6
|
</template>
|
|
7
7
|
|
|
8
8
|
<script>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-menu left bottom>
|
|
3
3
|
<template v-slot:activator="{ props }">
|
|
4
|
-
<v-btn :size="size" :variant="variant" :icon="iconStyling" :text="textStyling || null" v-bind="props"
|
|
5
|
-
@click.stop.prevent="">
|
|
4
|
+
<v-btn :size="size" :variant="variant" :icon="iconStyling" :text="textStyling || null" v-bind="props"
|
|
5
|
+
style="color: inherit;" @click.stop.prevent="">
|
|
6
6
|
<span v-if="spec.icon" :class="[textStyling ? 'padder' : '']"><common-icon :spec="spec.icon || {}" /></span>
|
|
7
7
|
{{ spec.text }}
|
|
8
8
|
</v-btn>
|
|
@@ -10,14 +10,14 @@
|
|
|
10
10
|
|
|
11
11
|
<v-list>
|
|
12
12
|
<v-list-item v-for="(childItem, childIndex) in spec.childButtons" :key="childIndex">
|
|
13
|
-
<common-button :spec="buttonSpec(childItem)"
|
|
13
|
+
<common-button :spec="buttonSpec(childItem)" />
|
|
14
14
|
</v-list-item>
|
|
15
15
|
</v-list>
|
|
16
16
|
</v-menu>
|
|
17
17
|
</template>
|
|
18
18
|
|
|
19
19
|
<script>
|
|
20
|
-
import { determineColor, determineDensity, determineVariant, determineSize } from '../utils/constant'
|
|
20
|
+
import { determineColor, determineDensity, determineVariant, determineSize } from '../utils/constant';
|
|
21
21
|
|
|
22
22
|
export default {
|
|
23
23
|
props: {
|
|
@@ -31,10 +31,10 @@ export default {
|
|
|
31
31
|
},
|
|
32
32
|
computed: {
|
|
33
33
|
size() {
|
|
34
|
-
return determineSize(this.spec.styleClasses)
|
|
34
|
+
return determineSize(this.spec.styleClasses);
|
|
35
35
|
},
|
|
36
36
|
variant() {
|
|
37
|
-
return determineVariant(this.spec.styleClasses, 'elevated')
|
|
37
|
+
return determineVariant(this.spec.styleClasses, 'elevated');
|
|
38
38
|
}
|
|
39
39
|
},
|
|
40
40
|
methods: {
|
package/components/_icon.vue
CHANGED
|
@@ -5,12 +5,17 @@
|
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<script>
|
|
8
|
+
import { vueApp } from "../store";
|
|
8
9
|
import { determineColor } from '../utils/constant';
|
|
10
|
+
import { computed } from "vue";
|
|
9
11
|
|
|
10
12
|
export default {
|
|
11
13
|
props: {
|
|
12
|
-
spec: { type: Object, required: true }
|
|
13
|
-
|
|
14
|
+
spec: { type: Object, required: true }
|
|
15
|
+
},
|
|
16
|
+
setup() {
|
|
17
|
+
const isBusy = computed(() => vueApp.isBusy);
|
|
18
|
+
return { isBusy };
|
|
14
19
|
},
|
|
15
20
|
data() {
|
|
16
21
|
return {
|
|
@@ -31,7 +36,7 @@ export default {
|
|
|
31
36
|
return this.$classes();
|
|
32
37
|
},
|
|
33
38
|
value() {
|
|
34
|
-
return this.isBusy
|
|
39
|
+
return this.isBusy ? "autorenew" : this.name;
|
|
35
40
|
},
|
|
36
41
|
},
|
|
37
42
|
watch: {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<!-- Use `click.prevent` to prevent bubbling when clicking a dropdown button that is
|
|
3
3
|
located in a list row that has href. -->
|
|
4
|
-
<v-btn :type="type" :disabled="
|
|
5
|
-
:
|
|
6
|
-
:
|
|
7
|
-
|
|
4
|
+
<v-btn :type="type" :disabled="isBusy || spec.disabled" :style="styles()" :class="$classes()" :href="$href()"
|
|
5
|
+
:rel="$rel()" :variant="variant" :rounded="$classes().includes('rounded') || null" :density="density" :size="size"
|
|
6
|
+
:color="color" :active="$classesInclude('active')" :icon="$classes().includes('icon') ? $vuetify : null"
|
|
7
|
+
@click.prevent="
|
|
8
8
|
type == 'submit' ? $dispatchEvent('forms/submit') : $onClick()
|
|
9
9
|
">
|
|
10
10
|
<!-- <span v-if="spec.icon"><common-icon :spec="spec.icon || {}" /></span> -->
|
|
@@ -24,7 +24,6 @@ export default {
|
|
|
24
24
|
props: {
|
|
25
25
|
spec: { type: Object, required: true },
|
|
26
26
|
type: { type: String, default: "button" },
|
|
27
|
-
disabled: { type: Boolean },
|
|
28
27
|
hideTextOnXs: { type: Boolean },
|
|
29
28
|
eventHandlers: { type: Object, default: null }
|
|
30
29
|
},
|
package/components/_tooltip.vue
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-menu v-if="spec.childButtons" left bottom>
|
|
3
3
|
<template v-slot:activator="{ on: onMenu }">
|
|
4
|
-
<v-tooltip
|
|
5
|
-
:
|
|
6
|
-
:
|
|
7
|
-
:right="tooltipPositionMatches('right')"
|
|
8
|
-
:bottom="tooltipPositionMatches('bottom')"
|
|
9
|
-
:left="tooltipPositionMatches('left')"
|
|
10
|
-
>
|
|
4
|
+
<v-tooltip :disabled="tooltip.disabled" :top="tooltipPositionMatches('top')"
|
|
5
|
+
:right="tooltipPositionMatches('right')" :bottom="tooltipPositionMatches('bottom')"
|
|
6
|
+
:left="tooltipPositionMatches('left')">
|
|
11
7
|
<template v-slot:activator="{ on: onTooltip }">
|
|
12
8
|
<slot name="activator" :on="{ ...onMenu, ...onTooltip }" />
|
|
13
9
|
</template>
|
|
@@ -16,25 +12,14 @@
|
|
|
16
12
|
</template>
|
|
17
13
|
|
|
18
14
|
<v-list>
|
|
19
|
-
<v-list-item
|
|
20
|
-
|
|
21
|
-
:key="childIndex"
|
|
22
|
-
>
|
|
23
|
-
<common-button
|
|
24
|
-
:spec="buttonSpec(childItem)"
|
|
25
|
-
:disabled="childItem.disabled || $isBusy"
|
|
26
|
-
/>
|
|
15
|
+
<v-list-item v-for="(childItem, childIndex) in spec.childButtons" :key="childIndex">
|
|
16
|
+
<common-button :spec="buttonSpec(childItem)" :disabled="childItem.disabled" />
|
|
27
17
|
</v-list-item>
|
|
28
18
|
</v-list>
|
|
29
19
|
</v-menu>
|
|
30
|
-
<v-tooltip
|
|
31
|
-
|
|
32
|
-
:
|
|
33
|
-
:top="tooltipPositionMatches('top')"
|
|
34
|
-
:right="tooltipPositionMatches('right')"
|
|
35
|
-
:bottom="tooltipPositionMatches('bottom')"
|
|
36
|
-
:left="tooltipPositionMatches('left')"
|
|
37
|
-
>
|
|
20
|
+
<v-tooltip v-else :disabled="tooltip.disabled" :top="tooltipPositionMatches('top')"
|
|
21
|
+
:right="tooltipPositionMatches('right')" :bottom="tooltipPositionMatches('bottom')"
|
|
22
|
+
:left="tooltipPositionMatches('left')">
|
|
38
23
|
<template v-slot:activator="{ on: onTooltip }">
|
|
39
24
|
<slot name="activator" :on="{ ...onTooltip }" />
|
|
40
25
|
</template>
|
package/components/avatar.vue
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<common-badge :spec="spec">
|
|
3
|
-
<v-avatar :size="spec.size">
|
|
3
|
+
<v-avatar :size="spec.size" :color="spec.backgroundColor || 'surface-variant'" :class="$classes()">
|
|
4
|
+
<p v-if="spec.initials" :style="{ color: spec.initials.color || 'white' }">{{ spec.initials.text }}</p>
|
|
4
5
|
<!-- Use `img` instead of `v-img` otherwise the rounded border will not work. -->
|
|
5
6
|
<!-- <img :style="$styles()" :src="spec.url || spec.base64Data" @click="$onClick()" /> -->
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
<v-img :style="$styles()" :class="$classes()" :src="spec.url || spec.base64Data" @click="$onClick()"
|
|
8
|
+
v-else></v-img>
|
|
8
9
|
</v-avatar>
|
|
9
10
|
</common-badge>
|
|
10
11
|
</template>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
<v-banner :style="$styles()" :class="$classes()">
|
|
4
4
|
<template v-if="spec.icon" v-slot:prepend>
|
|
5
5
|
<common-icon slot="icon" :spec="spec.icon" />
|
|
@@ -12,19 +12,11 @@
|
|
|
12
12
|
|
|
13
13
|
<template v-slot:actions>
|
|
14
14
|
<template v-for="(item, index) in spec.buttons">
|
|
15
|
-
<common-dropdownMenu v-if="item.childButtons" :key="'left-' + index" :spec="item"
|
|
16
|
-
<common-button v-else :key="index" :spec="buttonSpec(item)" :
|
|
15
|
+
<common-dropdownMenu v-if="item.childButtons" :key="'left-' + index" :spec="item" />
|
|
16
|
+
<common-button v-else :key="index" :spec="buttonSpec(item)" :hide-text-on-xs="true" />
|
|
17
17
|
</template>
|
|
18
18
|
</template>
|
|
19
|
-
|
|
20
|
-
<!-- <v-banner-actions>
|
|
21
|
-
<template v-for="(item, index) in spec.buttons">
|
|
22
|
-
<common-dropdownMenu v-if="item.childButtons" :key="'left-' + index" :spec="item" :disabled="$isBusy" />
|
|
23
|
-
<common-button v-else :key="index" :spec="buttonSpec(item)" :disabled="$isBusy" :hide-text-on-xs="true" />
|
|
24
|
-
</template>
|
|
25
|
-
</v-banner-actions> -->
|
|
26
19
|
</v-banner>
|
|
27
|
-
<!-- </div> -->
|
|
28
20
|
</template>
|
|
29
21
|
|
|
30
22
|
<script>
|
package/components/component.vue
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
|
|
25
25
|
<component :draggable="!!spec.dragData" ref="delegate" v-else-if="name" :is="name" :id="spec.id" :spec="spec"
|
|
26
26
|
@[menter]="handlePopover(spec.onMouseEnter)" @[mleave]="handlePopover(spec.onMouseLeave)"
|
|
27
|
-
@[dstart()]="handleDragStart" />
|
|
27
|
+
@[dstart()]="handleDragStart" :key="spec.key" />
|
|
28
28
|
<div v-else>Unsupported view: {{ spec.view }}</div>
|
|
29
29
|
</Suspense>
|
|
30
30
|
</template>
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { computed } from "vue";
|
|
2
|
+
import Type from "../../utils/type";
|
|
3
|
+
import mimeType from "../../utils/mime_type";
|
|
4
|
+
import { showError } from "./alert";
|
|
2
5
|
|
|
3
6
|
function useFileUtils() {
|
|
4
7
|
const makeKey = () => Math.random().toString(36).slice(2, 7);
|
|
@@ -13,6 +16,7 @@ function useFileUtils() {
|
|
|
13
16
|
this._url = options.url;
|
|
14
17
|
this._type = options.type;
|
|
15
18
|
this.el = options.el;
|
|
19
|
+
this.size = options.size;
|
|
16
20
|
}
|
|
17
21
|
|
|
18
22
|
isImage() {
|
|
@@ -87,4 +91,39 @@ function useFilesState(files) {
|
|
|
87
91
|
return { uploading, uploaded, uploadingFileLength, uploadedFileLength };
|
|
88
92
|
}
|
|
89
93
|
|
|
90
|
-
|
|
94
|
+
function validateFile(accepts, file) {
|
|
95
|
+
const MB_SIZE = 1000;
|
|
96
|
+
if (Type.isObject(accepts)) {
|
|
97
|
+
let validFileType = false;
|
|
98
|
+
[accepts.fileType].flat().forEach(key => {
|
|
99
|
+
const acceptsRegex = new RegExp(mimeType[key]);
|
|
100
|
+
if (!mimeType[key]) {
|
|
101
|
+
console.error(`Mime type not found: ${key}`);
|
|
102
|
+
}
|
|
103
|
+
if (acceptsRegex.test(file.type)) {
|
|
104
|
+
validFileType = true;
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
if (!validFileType) {
|
|
109
|
+
alert(accepts.fileTypeErrorText || "Invalid file type");
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (accepts.maxFileSize) {
|
|
114
|
+
if (file.size > accepts.maxFileSize * MB_SIZE) {
|
|
115
|
+
// support for old version, maxFileSizeErrorText is type of Object not String
|
|
116
|
+
if (typeof accepts.maxFileSizeErrorText == 'string') {
|
|
117
|
+
alert(accepts.maxFileSizeErrorText || "File too big");
|
|
118
|
+
} else {
|
|
119
|
+
showError({ body: accepts.maxFileSizeErrorText.body, button: accepts.maxFileSizeErrorText.button });
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export { useFileUtils, useFilesState, validateFile };
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import { inject, ref, watch } from "vue";
|
|
1
|
+
import { getCurrentInstance, inject, ref, watch } from "vue";
|
|
2
2
|
import Action from "../../action";
|
|
3
3
|
|
|
4
4
|
function useGlibTreeNode(props) {
|
|
5
5
|
const node = ref(props.node);
|
|
6
|
+
|
|
7
|
+
// variable from tree.vue
|
|
6
8
|
const dropBox = inject('dropBox');
|
|
7
9
|
const selected = inject('selected');
|
|
8
10
|
const currTreeNode = inject('currTreeNode');
|
|
11
|
+
const instance = getCurrentInstance();
|
|
9
12
|
|
|
10
13
|
watch(selected, (val) => {
|
|
11
14
|
selectIfIdMatch(val);
|
|
@@ -26,7 +29,7 @@ function useGlibTreeNode(props) {
|
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
function handleClick(node) {
|
|
29
|
-
Action.execute(node.onClick,
|
|
32
|
+
Action.execute(node.onClick, instance.ctx);
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
function handleDragOver(e, node) {
|
|
@@ -48,16 +51,16 @@ function useGlibTreeNode(props) {
|
|
|
48
51
|
|
|
49
52
|
dropBox.value = {};
|
|
50
53
|
|
|
51
|
-
const
|
|
54
|
+
const context = {};
|
|
52
55
|
const files = e.dataTransfer.files;
|
|
53
56
|
|
|
54
57
|
if (files.length <= 0) {
|
|
55
|
-
const
|
|
56
|
-
Object.assign(
|
|
58
|
+
const obj = JSON.parse(e.dataTransfer.getData('text'));
|
|
59
|
+
Object.assign(context, obj, node.dropData);
|
|
57
60
|
} else {
|
|
58
|
-
Object.assign(
|
|
61
|
+
Object.assign(context, node.dropData);
|
|
59
62
|
}
|
|
60
|
-
dropBox.value = {
|
|
63
|
+
dropBox.value = { context, files };
|
|
61
64
|
}
|
|
62
65
|
|
|
63
66
|
return { node, handleClick, handleDragOver, handleDragLeave, handleDrop };
|
|
@@ -2,7 +2,7 @@ import { watch } from 'vue';
|
|
|
2
2
|
import { triggerOnChange } from "./form";
|
|
3
3
|
import Uploader from "../../utils/glibDirectUpload";
|
|
4
4
|
import { vueApp } from "../../store";
|
|
5
|
-
import { useFilesState, useFileUtils } from "./file";
|
|
5
|
+
import { useFilesState, useFileUtils, validateFile } from "./file";
|
|
6
6
|
|
|
7
7
|
function submitOnAllUploaded({ url, formData, files }) {
|
|
8
8
|
const { uploaded } = useFilesState(files);
|
|
@@ -68,8 +68,7 @@ function uploadOneFile({ files, key, spec, container, onAfterUploaded }) {
|
|
|
68
68
|
};
|
|
69
69
|
|
|
70
70
|
// validate per file, skip if invalid
|
|
71
|
-
if (!
|
|
72
|
-
console.log(accepts)
|
|
71
|
+
if (!validateFile(accepts, files.value[key].el)) {
|
|
73
72
|
delete files.value[key];
|
|
74
73
|
return;
|
|
75
74
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { vueApp } from "../../store";
|
|
2
|
-
import { useFileUtils } from "./file";
|
|
2
|
+
import { useFileUtils, validateFile } from "./file";
|
|
3
3
|
|
|
4
4
|
const { makeKey } = useFileUtils();
|
|
5
5
|
|
|
@@ -11,6 +11,10 @@ function uploadFiles(obj) {
|
|
|
11
11
|
files: Array.from(droppedFiles).reduce((prev, curr) => {
|
|
12
12
|
prev[makeKey()] = curr;
|
|
13
13
|
|
|
14
|
+
if (!validateFile(spec.accepts, curr)) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
14
18
|
return prev;
|
|
15
19
|
}, {}),
|
|
16
20
|
spec: spec
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<v-text-field :color="gcolor" v-model="fieldModel" :name="fieldName" :label="spec.label" :hint="spec.hint"
|
|
5
5
|
:type="type" :readonly="spec.readOnly" :disabled="inputDisabled" :min="$sanitizeValue(spec.min)"
|
|
6
6
|
:max="$sanitizeValue(spec.max)" :pattern="pattern" :rules="$validation()" :style="$styles()"
|
|
7
|
-
:density="$classes().includes('compact') ? 'compact' : 'default'" clearable @change="onChange"
|
|
8
|
-
validate-on="blur" persistent-placeholder />
|
|
7
|
+
:density="$classes().includes('compact') ? 'compact' : 'default'" :clearable="spec.clearable" @change="onChange"
|
|
8
|
+
:variant="variant" validate-on="blur" persistent-placeholder />
|
|
9
9
|
</div>
|
|
10
10
|
</template>
|
|
11
11
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div ref="container" :style="$styles()" :class="$classes()" v-if="loadIf">
|
|
3
3
|
<component :is="compName" :color="gcolor" v-model="fieldModel" :label="label" :items="normalizedOptions"
|
|
4
|
-
:chips="spec.multiple" :multiple="spec.multiple" :readonly="spec.readOnly" :clearable="
|
|
4
|
+
:chips="spec.multiple" :multiple="spec.multiple" :readonly="spec.readOnly" :clearable="spec.clearable"
|
|
5
5
|
:placeholder="spec.placeholder" :rules="rules" persistent-hint :append-icon="append.icon" validate-on="blur"
|
|
6
6
|
item-title='text' :variant="variant" :closable-chips="spec.multiple" :density="density" persistent-placeholder
|
|
7
7
|
@update:modelValue="onChange" @focus="focused = true" @blur="focused = false">
|
|
@@ -126,3 +126,10 @@ export default {
|
|
|
126
126
|
}
|
|
127
127
|
};
|
|
128
128
|
</script>
|
|
129
|
+
|
|
130
|
+
<style scoped>
|
|
131
|
+
/*This is to ensure that the text does not get clipped by the clear icon.*/
|
|
132
|
+
::v-deep .v-autocomplete__selection {
|
|
133
|
+
display: block;
|
|
134
|
+
}
|
|
135
|
+
</style>
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
<div :class="checked ? 'thumbnail-checked' : 'thumbnail-check'" @click="handleClick">
|
|
3
3
|
<v-checkbox :color="gcolor" v-model="fieldModel" :name="fieldName" :readonly="spec.readOnly"
|
|
4
4
|
:disabled="inputDisabled" :true-icon="spec.onIcon" :false-icon="spec.offIcon" :value="spec.value"
|
|
5
|
-
:true-value="spec.checkValue" :false-value="uncheckValue" hide-details
|
|
6
|
-
:
|
|
5
|
+
:true-value="spec.checkValue" :false-value="spec.uncheckValue" hide-details :rules="$validation()"
|
|
6
|
+
:multiple="false">
|
|
7
7
|
<div class="thumbnail-content-wrapper">
|
|
8
8
|
<div class="thumbnail-check-img">
|
|
9
9
|
<img :src="spec.image.url" alt="" :width="spec.image.width" :height="spec.image.height" />
|
|
@@ -30,7 +30,7 @@ export default {
|
|
|
30
30
|
},
|
|
31
31
|
methods: {
|
|
32
32
|
handleClick() {
|
|
33
|
-
this.checked = !this.checked
|
|
33
|
+
this.checked = !this.checked;
|
|
34
34
|
},
|
|
35
35
|
}
|
|
36
36
|
};
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
<div class="checkbox-container">
|
|
3
3
|
<v-checkbox :color="gcolor" v-model="fieldModel" :name="fieldName" :readonly="spec.readOnly"
|
|
4
4
|
:disabled="inputDisabled" :true-icon="spec.onIcon" :false-icon="spec.offIcon" :value="spec.value"
|
|
5
|
-
:true-value="spec.checkValue" :false-value="uncheckValue" hide-details
|
|
6
|
-
:
|
|
5
|
+
:true-value="spec.checkValue" :false-value="spec.uncheckValue" hide-details :rules="$validation()"
|
|
6
|
+
:multiple="false"></v-checkbox>
|
|
7
7
|
<div class="checkbox-icon">
|
|
8
8
|
<img :src="spec.image.url" :width="spec.image.width" :height="spec.image.height" alt="img" />
|
|
9
9
|
</div>
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div :style="$styles()" v-if="loadIf">
|
|
3
|
-
<v-autocomplete ref="autocomplete" v-model="model" :items="allItems" :
|
|
4
|
-
:
|
|
5
|
-
:
|
|
3
|
+
<v-autocomplete ref="autocomplete" v-model="model" :items="allItems" :v-model:search-input="search"
|
|
4
|
+
:label="spec.label" hide-no-data hide-selected no-filter return-object :chips="true" :deletable-chips="true"
|
|
5
|
+
:multiple="spec.multiple">
|
|
6
6
|
<template v-slot:item="data">
|
|
7
7
|
{{ data.item.title }} - {{ data.item.subtitle }}
|
|
8
8
|
</template>
|
|
9
9
|
|
|
10
|
-
<!-- <v-list-item v-if="
|
|
10
|
+
<!-- <v-list-item v-if="nextPageUrl" slot="append-item" class="load-more">
|
|
11
11
|
<v-list-item-content class="text-content" @click="loadMore">
|
|
12
12
|
<v-list-item-title>Load More</v-list-item-title>
|
|
13
13
|
</v-list-item-content>
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
|
|
35
35
|
<script>
|
|
36
36
|
import Uploader from "../../utils/glibDirectUpload";
|
|
37
|
+
import { validateFile } from "../composable/file";
|
|
37
38
|
|
|
38
39
|
export default {
|
|
39
40
|
props: {
|
|
@@ -109,7 +110,7 @@ export default {
|
|
|
109
110
|
);
|
|
110
111
|
|
|
111
112
|
const input = this.inputElement;
|
|
112
|
-
if (
|
|
113
|
+
if (validateFile(this.spec.accepts, file)) {
|
|
113
114
|
this.$dispatchEvent("forms/setBusy", { value: true });
|
|
114
115
|
|
|
115
116
|
// TODO: Delete
|