quasar-ui-danx 0.3.0 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/danx.es.js +2670 -2652
- package/dist/danx.es.js.map +1 -1
- package/dist/danx.umd.js +5 -5
- package/dist/danx.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/ActionTable/Filters/FilterListToggle.vue +5 -1
- package/src/components/ActionTable/Form/Fields/MultiFileField.vue +2 -2
- package/src/components/ActionTable/Form/Fields/SelectField.vue +1 -1
- package/src/components/ActionTable/Form/Fields/SingleFileField.vue +2 -2
- package/src/components/ActionTable/Form/RenderedForm.vue +37 -22
- package/src/components/Utility/Tools/RenderVnode.vue +4 -2
- package/src/config/index.ts +2 -7
- package/src/helpers/FileUpload.ts +18 -20
- package/src/helpers/multiFileUpload.ts +16 -16
- package/src/helpers/singleFileUpload.ts +22 -16
@@ -21,7 +21,7 @@
|
|
21
21
|
<a
|
22
22
|
v-if="uploadedFiles.length > 0"
|
23
23
|
class="ml-3 text-red-900"
|
24
|
-
@click="
|
24
|
+
@click="clearUploadedFiles"
|
25
25
|
>Clear</a>
|
26
26
|
<input
|
27
27
|
ref="file"
|
@@ -81,7 +81,7 @@ const props = defineProps({
|
|
81
81
|
readonly: Boolean
|
82
82
|
});
|
83
83
|
|
84
|
-
const { onComplete, onDrop, onFilesSelected, uploadedFiles,
|
84
|
+
const { onComplete, onDrop, onFilesSelected, uploadedFiles, clearUploadedFiles, onRemove } = useMultiFileUpload();
|
85
85
|
onMounted(() => {
|
86
86
|
if (props.modelValue) {
|
87
87
|
uploadedFiles.value = props.modelValue;
|
@@ -234,7 +234,7 @@ function resolveSelectionLabel(option) {
|
|
234
234
|
* @returns {string|*|string}
|
235
235
|
*/
|
236
236
|
function resolveValue(option) {
|
237
|
-
if (typeof option === "string") {
|
237
|
+
if (!option || typeof option === "string") {
|
238
238
|
return option;
|
239
239
|
}
|
240
240
|
let value = option.value;
|
@@ -21,7 +21,7 @@
|
|
21
21
|
<a
|
22
22
|
v-if="uploadedFile"
|
23
23
|
class="ml-3 text-red-900"
|
24
|
-
@click="
|
24
|
+
@click="clearUploadedFile"
|
25
25
|
>Clear</a>
|
26
26
|
<input
|
27
27
|
ref="file"
|
@@ -67,7 +67,7 @@ const props = defineProps({
|
|
67
67
|
disable: Boolean,
|
68
68
|
readonly: Boolean
|
69
69
|
});
|
70
|
-
const { onComplete, onDrop, onFileSelected, uploadedFile,
|
70
|
+
const { onComplete, onDrop, onFileSelected, uploadedFile, clearUploadedFile } = useSingleFileUpload();
|
71
71
|
onComplete(() => emit("update:model-value", uploadedFile.value));
|
72
72
|
|
73
73
|
onMounted(() => {
|
@@ -7,10 +7,11 @@
|
|
7
7
|
:key="name"
|
8
8
|
:name="name"
|
9
9
|
class="p-0"
|
10
|
+
content-class="w-full"
|
10
11
|
>
|
11
|
-
<div class="flex flex-nowrap items-center text-sm">
|
12
|
-
<div>{{ name }}</div>
|
13
|
-
<
|
12
|
+
<div class="flex flex-nowrap items-center text-sm w-full">
|
13
|
+
<div class="flex-grow">{{ name || "1" }}</div>
|
14
|
+
<div v-if="!disable && !readonly && canModifyVariations" class="flex flex-nowrap items-center mr-2">
|
14
15
|
<a
|
15
16
|
@click="() => (variationToEdit = name) && (newVariationName = name)"
|
16
17
|
class="ml-1 p-1 hover:opacity-100 opacity-20 hover:bg-blue-200 rounded"
|
@@ -24,7 +25,7 @@
|
|
24
25
|
>
|
25
26
|
<RemoveIcon class="w-3 text-red-900" />
|
26
27
|
</a>
|
27
|
-
</
|
28
|
+
</div>
|
28
29
|
</div>
|
29
30
|
</QTab>
|
30
31
|
<QTab
|
@@ -60,10 +61,10 @@
|
|
60
61
|
/>
|
61
62
|
</div>
|
62
63
|
<ConfirmDialog
|
63
|
-
v-if="variationToEdit"
|
64
|
+
v-if="variationToEdit !== false"
|
64
65
|
title="Change variation name"
|
65
66
|
@confirm="onChangeVariationName"
|
66
|
-
@close="variationToEdit =
|
67
|
+
@close="variationToEdit = false"
|
67
68
|
>
|
68
69
|
<TextField
|
69
70
|
v-model="newVariationName"
|
@@ -115,7 +116,8 @@ const props = defineProps({
|
|
115
116
|
showName: Boolean,
|
116
117
|
disable: Boolean,
|
117
118
|
readonly: Boolean,
|
118
|
-
saving: Boolean
|
119
|
+
saving: Boolean,
|
120
|
+
canModifyVariations: Boolean
|
119
121
|
});
|
120
122
|
|
121
123
|
const FORM_FIELD_MAP = {
|
@@ -138,14 +140,19 @@ const mappedFields = props.form.fields.map((field) => ({
|
|
138
140
|
}));
|
139
141
|
|
140
142
|
const variationNames = computed(() => {
|
141
|
-
|
143
|
+
const names = [...new Set(props.values.map(v => v.variation))].sort();
|
144
|
+
// Always guarantee that we show the default variation
|
145
|
+
if (names.length === 0) {
|
146
|
+
names.push("");
|
147
|
+
}
|
148
|
+
return names;
|
142
149
|
});
|
143
150
|
|
144
|
-
const currentVariation = ref(variationNames.value[0] || "
|
151
|
+
const currentVariation = ref(variationNames.value[0] || "");
|
145
152
|
const newVariationName = ref("");
|
146
|
-
const variationToEdit = ref(
|
153
|
+
const variationToEdit = ref(false);
|
147
154
|
const variationToDelete = ref("");
|
148
|
-
const canAddVariation = computed(() =>
|
155
|
+
const canAddVariation = computed(() => props.canModifyVariations && !props.readonly && !props.disable && variationNames.value.length < props.form.variations);
|
149
156
|
|
150
157
|
function getFieldResponse(name) {
|
151
158
|
if (!props.values) return undefined;
|
@@ -158,26 +165,32 @@ function onInput(name, value) {
|
|
158
165
|
const fieldResponse = getFieldResponse(name);
|
159
166
|
const newFieldResponse = {
|
160
167
|
name,
|
161
|
-
variation: currentVariation.value,
|
168
|
+
variation: currentVariation.value || "",
|
162
169
|
value
|
163
170
|
};
|
164
171
|
const newValues = replace(props.values, fieldResponse, newFieldResponse, true);
|
165
172
|
emit("update:values", newValues);
|
166
173
|
}
|
167
174
|
|
175
|
+
function createVariation(variation) {
|
176
|
+
return props.form.fields.map((field) => ({
|
177
|
+
variation,
|
178
|
+
name: field.name,
|
179
|
+
value: field.type === "BOOLEAN" ? false : null
|
180
|
+
}));
|
181
|
+
}
|
182
|
+
|
168
183
|
function onAddVariation() {
|
169
184
|
if (props.saving) return;
|
185
|
+
let newValues = [...props.values];
|
170
186
|
|
187
|
+
if (newValues.length === 0) {
|
188
|
+
newValues = createVariation("");
|
189
|
+
}
|
171
190
|
const previousName = variationNames.value[variationNames.value.length - 1];
|
172
|
-
const newName = incrementName(previousName
|
173
|
-
|
174
|
-
|
175
|
-
variation: newName,
|
176
|
-
name: field.name,
|
177
|
-
value: field.type === "BOOLEAN" ? false : null
|
178
|
-
}));
|
179
|
-
const newValues = [...props.values, ...newVariation];
|
180
|
-
emit("update:values", newValues);
|
191
|
+
const newName = incrementName(!previousName ? "1" : previousName);
|
192
|
+
const newVariation = createVariation(newName);
|
193
|
+
emit("update:values", [...newValues, ...newVariation]);
|
181
194
|
currentVariation.value = newName;
|
182
195
|
}
|
183
196
|
|
@@ -196,11 +209,13 @@ function onChangeVariationName() {
|
|
196
209
|
emit("update:values", newValues);
|
197
210
|
|
198
211
|
currentVariation.value = newVariationName.value;
|
199
|
-
variationToEdit.value =
|
212
|
+
variationToEdit.value = false;
|
200
213
|
newVariationName.value = "";
|
201
214
|
}
|
202
215
|
|
203
216
|
function onRemoveVariation(name) {
|
217
|
+
if (!name) return;
|
218
|
+
|
204
219
|
const newValues = props.values.filter((v) => v.variation !== name);
|
205
220
|
emit("update:values", newValues);
|
206
221
|
|
@@ -1,10 +1,12 @@
|
|
1
1
|
<script>
|
2
|
+
import { isRef, isVNode } from "vue";
|
3
|
+
|
2
4
|
const RenderVnode = (props) => {
|
3
|
-
if (props.vnode
|
5
|
+
if (isVNode(props.vnode)) {
|
4
6
|
return props.vnode;
|
5
7
|
}
|
6
8
|
|
7
|
-
if (props.vnode
|
9
|
+
if (isRef(props.vnode)) {
|
8
10
|
return props.vnode.value;
|
9
11
|
}
|
10
12
|
|
package/src/config/index.ts
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
import { QNotifyCreateOptions } from "quasar";
|
2
|
-
|
3
|
-
export interface DanxFileUploadOptions {
|
4
|
-
directory?: string;
|
5
|
-
presignedUploadUrl?: Function | null;
|
6
|
-
uploadCompletedUrl?: Function | null;
|
7
|
-
}
|
2
|
+
import { FileUploadOptions } from "../helpers";
|
8
3
|
|
9
4
|
export interface DanxOptions {
|
10
|
-
fileUpload:
|
5
|
+
fileUpload: FileUploadOptions;
|
11
6
|
flashMessages: {
|
12
7
|
default: QNotifyCreateOptions;
|
13
8
|
success: QNotifyCreateOptions;
|
@@ -5,8 +5,8 @@ import { FlashMessages } from "./FlashMessages";
|
|
5
5
|
|
6
6
|
export type FileUploadOptions = {
|
7
7
|
directory?: string,
|
8
|
-
presignedUploadUrl?:
|
9
|
-
uploadCompletedUrl?:
|
8
|
+
presignedUploadUrl?: Function | null;
|
9
|
+
uploadCompletedUrl?: Function | null;
|
10
10
|
};
|
11
11
|
|
12
12
|
export type UploadedFile = {
|
@@ -16,23 +16,21 @@ export type UploadedFile = {
|
|
16
16
|
type: string,
|
17
17
|
progress: number,
|
18
18
|
location: string,
|
19
|
-
blobUrl: string
|
19
|
+
blobUrl: string,
|
20
|
+
url: string,
|
20
21
|
}
|
21
22
|
|
22
23
|
export class FileUpload {
|
23
24
|
files: UploadedFile[] = [];
|
24
|
-
fileUploads = [];
|
25
|
-
onErrorCb = null;
|
26
|
-
onProgressCb = null;
|
27
|
-
onCompleteCb = null;
|
28
|
-
onAllCompleteCb = null;
|
29
|
-
options: FileUploadOptions = {};
|
30
|
-
|
31
|
-
constructor(files: UploadedFile[] | UploadedFile, options: FileUploadOptions = {}) {
|
32
|
-
|
33
|
-
files = [files];
|
34
|
-
}
|
35
|
-
this.files = files;
|
25
|
+
fileUploads: UploadedFile[] = [];
|
26
|
+
onErrorCb: Function | null = null;
|
27
|
+
onProgressCb: Function | null = null;
|
28
|
+
onCompleteCb: Function | null = null;
|
29
|
+
onAllCompleteCb: Function | null = null;
|
30
|
+
options: FileUploadOptions | null = {};
|
31
|
+
|
32
|
+
constructor(files: UploadedFile[] | UploadedFile, options: FileUploadOptions | null = {}) {
|
33
|
+
this.files = !Array.isArray(files) && !(files instanceof FileList) ? [files] : files;
|
36
34
|
this.fileUploads = [];
|
37
35
|
this.onErrorCb = null;
|
38
36
|
this.onProgressCb = null;
|
@@ -81,7 +79,7 @@ export class FileUpload {
|
|
81
79
|
/**
|
82
80
|
* Callback for when all files have been uploaded
|
83
81
|
*/
|
84
|
-
onAllComplete(cb) {
|
82
|
+
onAllComplete(cb: Function) {
|
85
83
|
this.onAllCompleteCb = cb;
|
86
84
|
return this;
|
87
85
|
}
|
@@ -91,7 +89,7 @@ export class FileUpload {
|
|
91
89
|
* @param cb
|
92
90
|
* @returns {FileUpload}
|
93
91
|
*/
|
94
|
-
onComplete(cb) {
|
92
|
+
onComplete(cb: Function) {
|
95
93
|
this.onCompleteCb = cb;
|
96
94
|
return this;
|
97
95
|
}
|
@@ -101,7 +99,7 @@ export class FileUpload {
|
|
101
99
|
* @param cb
|
102
100
|
* @returns {FileUpload}
|
103
101
|
*/
|
104
|
-
onProgress(cb) {
|
102
|
+
onProgress(cb: Function) {
|
105
103
|
this.onProgressCb = cb;
|
106
104
|
return this;
|
107
105
|
}
|
@@ -111,7 +109,7 @@ export class FileUpload {
|
|
111
109
|
* @param cb
|
112
110
|
* @returns {FileUpload}
|
113
111
|
*/
|
114
|
-
onError(cb) {
|
112
|
+
onError(cb: Function) {
|
115
113
|
this.onErrorCb = cb;
|
116
114
|
return this;
|
117
115
|
}
|
@@ -122,7 +120,7 @@ export class FileUpload {
|
|
122
120
|
* @param file
|
123
121
|
* @param error
|
124
122
|
*/
|
125
|
-
errorHandler(e, file, error = null) {
|
123
|
+
errorHandler(e: InputEvent, file: UploadedFile, error = null) {
|
126
124
|
if (this.onErrorCb) {
|
127
125
|
this.onErrorCb({ e, file, error });
|
128
126
|
}
|
@@ -1,17 +1,17 @@
|
|
1
|
-
import { ref } from "vue";
|
2
|
-
import { FileUpload, FileUploadOptions } from "./FileUpload";
|
1
|
+
import { Ref, ref } from "vue";
|
2
|
+
import { FileUpload, FileUploadOptions, UploadedFile } from "./FileUpload";
|
3
3
|
|
4
4
|
export function useMultiFileUpload(options: FileUploadOptions) {
|
5
|
-
const uploadedFiles = ref([]);
|
6
|
-
const onCompleteCb = ref(null);
|
7
|
-
const onFilesChangeCb = ref(null);
|
8
|
-
const onFilesSelected = (e) => {
|
5
|
+
const uploadedFiles: Ref<UploadedFile[]> = ref([]);
|
6
|
+
const onCompleteCb: Ref<Function | null> = ref(null);
|
7
|
+
const onFilesChangeCb: Ref<Function | null> = ref(null);
|
8
|
+
const onFilesSelected = (e: any) => {
|
9
9
|
uploadedFiles.value = [...uploadedFiles.value, ...e.target.files];
|
10
10
|
new FileUpload(e.target.files, options)
|
11
|
-
.onProgress(({ file }) => {
|
11
|
+
.onProgress(({ file }: { file: UploadedFile }) => {
|
12
12
|
updateFileInList(file);
|
13
13
|
})
|
14
|
-
.onComplete(({ file, uploadedFile }) => {
|
14
|
+
.onComplete(({ file, uploadedFile }: { file: UploadedFile, uploadedFile: UploadedFile }) => {
|
15
15
|
updateFileInList(file, uploadedFile);
|
16
16
|
})
|
17
17
|
.onAllComplete(() => {
|
@@ -21,7 +21,7 @@ export function useMultiFileUpload(options: FileUploadOptions) {
|
|
21
21
|
.upload();
|
22
22
|
};
|
23
23
|
|
24
|
-
function updateFileInList(file, replace = null) {
|
24
|
+
function updateFileInList(file: UploadedFile, replace: UploadedFile | null = null) {
|
25
25
|
const index = uploadedFiles.value.findIndex(f => f.id === file.id);
|
26
26
|
if (index !== -1) {
|
27
27
|
uploadedFiles.value.splice(index, 1, replace || file);
|
@@ -29,25 +29,25 @@ export function useMultiFileUpload(options: FileUploadOptions) {
|
|
29
29
|
onFilesChangeCb.value && onFilesChangeCb.value(uploadedFiles.value);
|
30
30
|
}
|
31
31
|
|
32
|
-
const onDrop = (e) => {
|
33
|
-
onFilesSelected({ target: { files: e.dataTransfer
|
32
|
+
const onDrop = (e: InputEvent) => {
|
33
|
+
onFilesSelected({ target: { files: e.dataTransfer?.files } });
|
34
34
|
};
|
35
35
|
|
36
|
-
const onFilesChange = (cb) => {
|
36
|
+
const onFilesChange = (cb: Function) => {
|
37
37
|
onFilesChangeCb.value = cb;
|
38
38
|
};
|
39
39
|
|
40
|
-
const onComplete = (cb) => {
|
40
|
+
const onComplete = (cb: Function) => {
|
41
41
|
onCompleteCb.value = cb;
|
42
42
|
};
|
43
43
|
|
44
|
-
const
|
44
|
+
const clearUploadedFiles = () => {
|
45
45
|
uploadedFiles.value = [];
|
46
46
|
onFilesChangeCb.value && onFilesChangeCb.value(uploadedFiles.value);
|
47
47
|
onCompleteCb.value && onCompleteCb.value();
|
48
48
|
};
|
49
49
|
|
50
|
-
const onRemove = (file) => {
|
50
|
+
const onRemove = (file: UploadedFile) => {
|
51
51
|
const index = uploadedFiles.value.findIndex(f => f.id === file.id);
|
52
52
|
if (index !== -1) {
|
53
53
|
uploadedFiles.value.splice(index, 1);
|
@@ -57,7 +57,7 @@ export function useMultiFileUpload(options: FileUploadOptions) {
|
|
57
57
|
};
|
58
58
|
|
59
59
|
return {
|
60
|
-
|
60
|
+
clearUploadedFiles,
|
61
61
|
onRemove,
|
62
62
|
onComplete,
|
63
63
|
onFilesChange,
|
@@ -1,19 +1,24 @@
|
|
1
|
-
import { computed, ref } from "vue";
|
2
|
-
import { FileUpload, FileUploadOptions } from "./FileUpload";
|
1
|
+
import { computed, Ref, ref } from "vue";
|
2
|
+
import { FileUpload, FileUploadOptions, UploadedFile } from "./FileUpload";
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
interface FileUploadCallbackParams {
|
5
|
+
file: UploadedFile;
|
6
|
+
uploadedFile: UploadedFile;
|
7
|
+
}
|
8
|
+
|
9
|
+
export function useSingleFileUpload(options: FileUploadOptions | null = null) {
|
10
|
+
const uploadedFile: Ref<UploadedFile | null> = ref(null);
|
11
|
+
const onCompleteCb: Ref<Function | null> = ref(null);
|
12
|
+
const onFileChangeCb: Ref<Function | null> = ref(null);
|
8
13
|
|
9
|
-
const onFileSelected = (e) => {
|
14
|
+
const onFileSelected = (e: any) => {
|
10
15
|
uploadedFile.value = null;
|
11
|
-
new FileUpload(e.target
|
12
|
-
.onProgress(({ file }) => {
|
16
|
+
new FileUpload(e.target?.files[0], options)
|
17
|
+
.onProgress(({ file }: FileUploadCallbackParams) => {
|
13
18
|
uploadedFile.value = file;
|
14
19
|
onFileChangeCb.value && onFileChangeCb.value(uploadedFile.value);
|
15
20
|
})
|
16
|
-
.onComplete(({ uploadedFile: completedFile }) => {
|
21
|
+
.onComplete(({ uploadedFile: completedFile }: FileUploadCallbackParams) => {
|
17
22
|
uploadedFile.value = completedFile;
|
18
23
|
onCompleteCb.value && onCompleteCb.value(uploadedFile.value);
|
19
24
|
onFileChangeCb.value && onFileChangeCb.value(uploadedFile.value);
|
@@ -21,30 +26,31 @@ export function useSingleFileUpload(options: FileUploadOptions = null) {
|
|
21
26
|
.upload();
|
22
27
|
};
|
23
28
|
|
24
|
-
const onDrop = (e) => {
|
25
|
-
onFileSelected({ target: { files: e.dataTransfer
|
29
|
+
const onDrop = (e: InputEvent) => {
|
30
|
+
onFileSelected({ target: { files: e.dataTransfer?.files } });
|
26
31
|
};
|
27
32
|
|
28
33
|
const isFileUploaded = computed(() => {
|
29
34
|
return uploadedFile.value && uploadedFile.value.url;
|
30
35
|
});
|
31
36
|
|
32
|
-
const onFileChange = (cb) => {
|
37
|
+
const onFileChange = (cb: Function) => {
|
33
38
|
onFileChangeCb.value = cb;
|
34
39
|
};
|
35
40
|
|
36
|
-
const onComplete = (cb) => {
|
41
|
+
const onComplete = (cb: Function) => {
|
37
42
|
onCompleteCb.value = cb;
|
38
43
|
};
|
39
44
|
|
40
|
-
const
|
45
|
+
const clearUploadedFile = () => {
|
41
46
|
uploadedFile.value = null;
|
42
47
|
onFileChangeCb.value && onFileChangeCb.value(uploadedFile.value);
|
48
|
+
onCompleteCb.value && onCompleteCb.value(uploadedFile.value);
|
43
49
|
};
|
44
50
|
|
45
51
|
return {
|
46
52
|
isFileUploaded,
|
47
|
-
|
53
|
+
clearUploadedFile,
|
48
54
|
onComplete,
|
49
55
|
onFileChange,
|
50
56
|
onDrop,
|