@finema/core 3.22.0 → 3.24.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 +22 -2
- package/dist/module.d.mts +2 -0
- package/dist/module.json +2 -2
- package/dist/module.mjs +18 -15
- package/dist/runtime/components/App.vue +1 -1
- package/dist/runtime/components/DevToolsWindow/index.vue +24 -26
- package/dist/runtime/components/Dialog/index.d.vue.ts +1 -4
- package/dist/runtime/components/Dialog/index.vue +17 -17
- package/dist/runtime/components/Dialog/index.vue.d.ts +1 -4
- package/dist/runtime/components/Empty.d.vue.ts +1 -2
- package/dist/runtime/components/Empty.vue +19 -11
- package/dist/runtime/components/Empty.vue.d.ts +1 -2
- package/dist/runtime/components/FlexDeck/index.vue +21 -23
- package/dist/runtime/components/Form/FieldWrapper.vue +1 -1
- package/dist/runtime/components/Form/Fields.d.vue.ts +1 -1
- package/dist/runtime/components/Form/Fields.vue +26 -20
- package/dist/runtime/components/Form/Fields.vue.d.ts +1 -1
- package/dist/runtime/components/Form/InputCheckbox/index.vue +3 -6
- package/dist/runtime/components/Form/InputCheckboxGroup/index.vue +3 -6
- package/dist/runtime/components/Form/InputComponent/index.vue +2 -1
- package/dist/runtime/components/Form/InputCurrency/index.vue +11 -11
- package/dist/runtime/components/Form/InputDateTime/date_time_field.types.d.ts +3 -1
- package/dist/runtime/components/Form/InputDateTime/index.vue +12 -17
- package/dist/runtime/components/Form/InputDateTimeRange/date_range_time_field.types.d.ts +1 -1
- package/dist/runtime/components/Form/InputDateTimeRange/index.vue +28 -20
- package/dist/runtime/components/Form/InputMonth/index.vue +14 -12
- package/dist/runtime/components/Form/InputMonth/types.d.ts +1 -1
- package/dist/runtime/components/Form/InputNumber/index.vue +3 -6
- package/dist/runtime/components/Form/InputRadio/index.vue +3 -6
- package/dist/runtime/components/Form/InputRating/index.vue +3 -6
- package/dist/runtime/components/Form/InputSearch/index.vue +6 -7
- package/dist/runtime/components/Form/InputSelect/index.vue +6 -15
- package/dist/runtime/components/Form/InputSelectMultiple/index.vue +7 -18
- package/dist/runtime/components/Form/InputTags/index.vue +3 -6
- package/dist/runtime/components/Form/InputText/index.vue +41 -51
- package/dist/runtime/components/Form/InputTextarea/index.vue +3 -6
- package/dist/runtime/components/Form/InputTime/index.vue +32 -27
- package/dist/runtime/components/Form/InputTime/types.d.ts +1 -1
- package/dist/runtime/components/Form/InputToggle/index.vue +3 -5
- package/dist/runtime/components/Form/InputUploadDropzone/index.d.vue.ts +1 -4
- package/dist/runtime/components/Form/InputUploadDropzone/index.vue +25 -23
- package/dist/runtime/components/Form/InputUploadDropzone/index.vue.d.ts +1 -4
- package/dist/runtime/components/Form/InputUploadDropzone/types.d.ts +2 -2
- package/dist/runtime/components/Form/InputUploadDropzoneAuto/index.d.vue.ts +0 -5
- package/dist/runtime/components/Form/InputUploadDropzoneAuto/index.vue +22 -23
- package/dist/runtime/components/Form/InputUploadDropzoneAuto/index.vue.d.ts +0 -5
- package/dist/runtime/components/Form/InputUploadDropzoneAuto/types.d.ts +3 -3
- package/dist/runtime/components/Form/InputUploadDropzoneAutoMultiple/index.d.vue.ts +0 -5
- package/dist/runtime/components/Form/InputUploadDropzoneAutoMultiple/index.vue +26 -24
- package/dist/runtime/components/Form/InputUploadDropzoneAutoMultiple/index.vue.d.ts +0 -5
- package/dist/runtime/components/Form/InputUploadDropzoneAutoMultiple/types.d.ts +3 -3
- package/dist/runtime/components/Form/InputUploadImageAuto/index.d.vue.ts +1 -6
- package/dist/runtime/components/Form/InputUploadImageAuto/index.vue +22 -23
- package/dist/runtime/components/Form/InputUploadImageAuto/index.vue.d.ts +1 -6
- package/dist/runtime/components/Form/InputUploadImageAuto/types.d.ts +3 -3
- package/dist/runtime/components/Form/InputWYSIWYG/EditorImagePasteExtension.js +7 -6
- package/dist/runtime/components/Form/InputWYSIWYG/EditorImageUploadExtension.js +13 -12
- package/dist/runtime/components/Form/InputWYSIWYG/EditorImageUploadNode.vue +3 -1
- package/dist/runtime/components/Form/InputWYSIWYG/EditorLinkPopover.vue +20 -22
- package/dist/runtime/components/Form/InputWYSIWYG/index.vue +140 -118
- package/dist/runtime/components/Form/fileState/EmptyState.vue +1 -1
- package/dist/runtime/components/Form/fileState/FailedState.vue +4 -2
- package/dist/runtime/components/Form/fileState/MultipleFilesState.d.vue.ts +4 -4
- package/dist/runtime/components/Form/fileState/MultipleFilesState.vue +5 -5
- package/dist/runtime/components/Form/fileState/MultipleFilesState.vue.d.ts +4 -4
- package/dist/runtime/components/Form/fileState/SuccessState.d.vue.ts +2 -2
- package/dist/runtime/components/Form/fileState/SuccessState.vue +8 -13
- package/dist/runtime/components/Form/fileState/SuccessState.vue.d.ts +2 -2
- package/dist/runtime/components/Form/fileState/useFilePicker.d.ts +34 -0
- package/dist/runtime/components/Form/fileState/useFilePicker.js +48 -0
- package/dist/runtime/components/Form/fileState/useFileState.d.ts +7 -9
- package/dist/runtime/components/Form/fileState/useFileState.js +32 -120
- package/dist/runtime/components/Form/fileState/useUploadImageState.d.ts +7 -8
- package/dist/runtime/components/Form/fileState/useUploadImageState.js +27 -301
- package/dist/runtime/components/Form/fileState/useUploadState.d.ts +11 -7
- package/dist/runtime/components/Form/fileState/useUploadState.js +52 -136
- package/dist/runtime/components/Form/fileState/useUploadStateMultiple.d.ts +12 -18
- package/dist/runtime/components/Form/fileState/useUploadStateMultiple.js +88 -226
- package/dist/runtime/components/Form/types.d.ts +2 -0
- package/dist/runtime/components/Image.vue +4 -10
- package/dist/runtime/components/Loader.d.vue.ts +2 -1
- package/dist/runtime/components/Loader.vue +10 -7
- package/dist/runtime/components/Loader.vue.d.ts +2 -1
- package/dist/runtime/components/Log/LogItem.vue +1 -3
- package/dist/runtime/components/Log/index.vue +1 -3
- package/dist/runtime/components/Table/Base.d.vue.ts +15 -1
- package/dist/runtime/components/Table/Base.vue +9 -29
- package/dist/runtime/components/Table/Base.vue.d.ts +15 -1
- package/dist/runtime/components/Table/ColumnText.d.vue.ts +2 -3
- package/dist/runtime/components/Table/ColumnText.vue +1 -1
- package/dist/runtime/components/Table/ColumnText.vue.d.ts +2 -3
- package/dist/runtime/components/Table/Pagination.vue +19 -22
- package/dist/runtime/components/Table/index.d.vue.ts +1 -1
- package/dist/runtime/components/Table/index.vue +5 -7
- package/dist/runtime/components/Table/index.vue.d.ts +1 -1
- package/dist/runtime/composables/loaderList.d.ts +2 -1
- package/dist/runtime/composables/loaderList.js +3 -4
- package/dist/runtime/composables/loaderObject.d.ts +2 -1
- package/dist/runtime/composables/loaderObject.js +2 -1
- package/dist/runtime/composables/loaderPage.js +223 -350
- package/dist/runtime/composables/useConfig.js +4 -3
- package/dist/runtime/composables/useDialog.js +3 -1
- package/dist/runtime/composables/useForm.d.ts +2 -2
- package/dist/runtime/composables/useForm.js +2 -4
- package/dist/runtime/composables/useMessages.d.ts +10 -0
- package/dist/runtime/composables/useMessages.js +10 -0
- package/dist/runtime/composables/useTable.js +2 -14
- package/dist/runtime/helpers/apiBaseHelper.js +6 -24
- package/dist/runtime/helpers/apiListHelper.js +2 -5
- package/dist/runtime/helpers/apiObjectHelper.js +2 -5
- package/dist/runtime/helpers/apiPageHelper.d.ts +0 -1
- package/dist/runtime/helpers/apiPageHelper.js +19 -38
- package/dist/runtime/helpers/componentHelper.js +2 -6
- package/dist/runtime/helpers/uploadCore.d.ts +54 -0
- package/dist/runtime/helpers/uploadCore.js +81 -0
- package/dist/runtime/i18n/valibot.d.ts +5 -68
- package/dist/runtime/i18n/valibot.js +33 -29
- package/dist/runtime/locale/en.d.ts +2 -0
- package/dist/runtime/locale/en.js +42 -0
- package/dist/runtime/locale/index.d.ts +7 -0
- package/dist/runtime/locale/index.js +5 -0
- package/dist/runtime/locale/th.d.ts +43 -0
- package/dist/runtime/locale/th.js +42 -0
- package/dist/runtime/server/tsconfig.json +1 -1
- package/dist/runtime/styles/main.css +1 -1
- package/dist/runtime/utils/ParamHelper.js +1 -1
- package/dist/runtime/utils/StringHelper.js +1 -4
- package/dist/runtime/utils/TimeHelper.js +2 -2
- package/dist/runtime/utils/lodash.js +2 -2
- package/package.json +57 -36
|
@@ -1,306 +1,32 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
UploadState2["ERROR"] = "error";
|
|
14
|
-
return UploadState2;
|
|
15
|
-
})(UploadState || {});
|
|
16
|
-
export const useUploadImageState = (props, emits, onChange, setErrors, value, acceptedFileTypes, wrapperProps, dropzoneRef) => {
|
|
17
|
-
const overlay = useOverlay();
|
|
18
|
-
const previewModal = overlay.create(PreviewModal);
|
|
19
|
-
const selectedFile = ref();
|
|
20
|
-
const fileAllocate = useFileAllocate(selectedFile, props);
|
|
21
|
-
const appConfig = useAppConfig();
|
|
22
|
-
const {
|
|
23
|
-
percent,
|
|
24
|
-
onDownloadProgress,
|
|
25
|
-
onUploadProgress
|
|
26
|
-
} = useFileProgress();
|
|
27
|
-
const request = {
|
|
28
|
-
requestOptions: {
|
|
29
|
-
...props.requestOptions,
|
|
30
|
-
onDownloadProgress,
|
|
31
|
-
onUploadProgress
|
|
32
|
-
},
|
|
33
|
-
pathURL: props.uploadPathURL
|
|
34
|
-
};
|
|
35
|
-
const upload = useUploadLoader(request);
|
|
36
|
-
const validateImageDimensions = (file) => {
|
|
37
|
-
return new Promise((resolve) => {
|
|
38
|
-
if (!props.dimensions) {
|
|
39
|
-
resolve(true);
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
const img = new Image();
|
|
43
|
-
const url = URL.createObjectURL(file);
|
|
44
|
-
img.onload = () => {
|
|
45
|
-
URL.revokeObjectURL(url);
|
|
46
|
-
const {
|
|
47
|
-
width,
|
|
48
|
-
height
|
|
49
|
-
} = img;
|
|
50
|
-
const dimensions = props.dimensions;
|
|
51
|
-
if (dimensions.width !== void 0 && width !== dimensions.width) {
|
|
52
|
-
if (appConfig.core?.locale === "th") {
|
|
53
|
-
setErrors(`\u0E04\u0E27\u0E32\u0E21\u0E01\u0E27\u0E49\u0E32\u0E07\u0E02\u0E2D\u0E07\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E15\u0E49\u0E2D\u0E07\u0E40\u0E1B\u0E47\u0E19 ${dimensions.width}px (\u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19: ${width}px)`);
|
|
54
|
-
} else {
|
|
55
|
-
setErrors(`Image width must be ${dimensions.width}px (current: ${width}px)`);
|
|
56
|
-
}
|
|
57
|
-
resolve(false);
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
if (dimensions.height !== void 0 && height !== dimensions.height) {
|
|
61
|
-
if (appConfig.core?.locale === "th") {
|
|
62
|
-
setErrors(`\u0E04\u0E27\u0E32\u0E21\u0E2A\u0E39\u0E07\u0E02\u0E2D\u0E07\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E15\u0E49\u0E2D\u0E07\u0E40\u0E1B\u0E47\u0E19 ${dimensions.height}px (\u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19: ${height}px)`);
|
|
63
|
-
} else {
|
|
64
|
-
setErrors(`Image height must be ${dimensions.height}px (current: ${height}px)`);
|
|
65
|
-
}
|
|
66
|
-
resolve(false);
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
if (dimensions.minWidth !== void 0 && width < dimensions.minWidth) {
|
|
70
|
-
if (appConfig.core?.locale === "th") {
|
|
71
|
-
setErrors(`\u0E04\u0E27\u0E32\u0E21\u0E01\u0E27\u0E49\u0E32\u0E07\u0E02\u0E2D\u0E07\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E19\u0E49\u0E2D\u0E22\u0E01\u0E27\u0E48\u0E32 ${dimensions.minWidth}px (\u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19: ${width}px)`);
|
|
72
|
-
} else {
|
|
73
|
-
setErrors(`Image width must be at least ${dimensions.minWidth}px (current: ${width}px)`);
|
|
74
|
-
}
|
|
75
|
-
resolve(false);
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
if (dimensions.minHeight !== void 0 && height < dimensions.minHeight) {
|
|
79
|
-
if (appConfig.core?.locale === "th") {
|
|
80
|
-
setErrors(`\u0E04\u0E27\u0E32\u0E21\u0E2A\u0E39\u0E07\u0E02\u0E2D\u0E07\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E19\u0E49\u0E2D\u0E22\u0E01\u0E27\u0E48\u0E32 ${dimensions.minHeight}px (\u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19: ${height}px)`);
|
|
81
|
-
} else {
|
|
82
|
-
setErrors(`Image height must be at least ${dimensions.minHeight}px (current: ${height}px)`);
|
|
83
|
-
}
|
|
84
|
-
resolve(false);
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
if (dimensions.maxWidth !== void 0 && width > dimensions.maxWidth) {
|
|
88
|
-
if (appConfig.core?.locale === "th") {
|
|
89
|
-
setErrors(`\u0E04\u0E27\u0E32\u0E21\u0E01\u0E27\u0E49\u0E32\u0E07\u0E02\u0E2D\u0E07\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${dimensions.maxWidth}px (\u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19: ${width}px)`);
|
|
90
|
-
} else {
|
|
91
|
-
setErrors(`Image width must not exceed ${dimensions.maxWidth}px (current: ${width}px)`);
|
|
92
|
-
}
|
|
93
|
-
resolve(false);
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
if (dimensions.maxHeight !== void 0 && height > dimensions.maxHeight) {
|
|
97
|
-
if (appConfig.core?.locale === "th") {
|
|
98
|
-
setErrors(`\u0E04\u0E27\u0E32\u0E21\u0E2A\u0E39\u0E07\u0E02\u0E2D\u0E07\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${dimensions.maxHeight}px (\u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19: ${height}px)`);
|
|
99
|
-
} else {
|
|
100
|
-
setErrors(`Image height must not exceed ${dimensions.maxHeight}px (current: ${height}px)`);
|
|
101
|
-
}
|
|
102
|
-
resolve(false);
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
if (dimensions.aspectRatio !== void 0) {
|
|
106
|
-
const actualRatio = width / height;
|
|
107
|
-
const tolerance = dimensions.aspectRatioTolerance ?? 0.01;
|
|
108
|
-
const expectedRatio = dimensions.aspectRatio;
|
|
109
|
-
if (Math.abs(actualRatio - expectedRatio) > tolerance) {
|
|
110
|
-
if (appConfig.core?.locale === "th") {
|
|
111
|
-
setErrors(`\u0E2D\u0E31\u0E15\u0E23\u0E32\u0E2A\u0E48\u0E27\u0E19\u0E02\u0E2D\u0E07\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07 (\u0E15\u0E49\u0E2D\u0E07\u0E01\u0E32\u0E23: ${expectedRatio.toFixed(2)}, \u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19: ${actualRatio.toFixed(2)})`);
|
|
112
|
-
} else {
|
|
113
|
-
setErrors(`Image aspect ratio is incorrect (expected: ${expectedRatio.toFixed(2)}, current: ${actualRatio.toFixed(2)})`);
|
|
114
|
-
}
|
|
115
|
-
resolve(false);
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
setErrors("");
|
|
120
|
-
resolve(true);
|
|
121
|
-
};
|
|
122
|
-
img.onerror = () => {
|
|
123
|
-
URL.revokeObjectURL(url);
|
|
124
|
-
if (appConfig.core?.locale === "th") {
|
|
125
|
-
setErrors("\u0E44\u0E21\u0E48\u0E2A\u0E32\u0E21\u0E32\u0E23\u0E16\u0E42\u0E2B\u0E25\u0E14\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E44\u0E14\u0E49");
|
|
126
|
-
} else {
|
|
127
|
-
setErrors("Failed to load image");
|
|
128
|
-
}
|
|
129
|
-
resolve(false);
|
|
130
|
-
};
|
|
131
|
-
img.src = url;
|
|
132
|
-
});
|
|
133
|
-
};
|
|
134
|
-
const validateFile = async (file) => {
|
|
135
|
-
if (props.accept && fileAllocate.acceptFile.value) {
|
|
136
|
-
const acceptedTypes = fileAllocate.acceptFile.value;
|
|
137
|
-
const acceptedTypesList = acceptedTypes.split(",").map((type) => type.trim());
|
|
138
|
-
const fileExtension = file.name.toLowerCase().split(".").pop();
|
|
139
|
-
const isValidFileType = acceptedTypesList.some((acceptedType) => {
|
|
140
|
-
if (acceptedType.startsWith(".")) {
|
|
141
|
-
const extension = acceptedType.slice(1).toLowerCase();
|
|
142
|
-
return fileExtension === extension;
|
|
143
|
-
} else if (!acceptedType.includes("/") && !acceptedType.includes("*")) {
|
|
144
|
-
return fileExtension === acceptedType.toLowerCase();
|
|
145
|
-
}
|
|
146
|
-
if (acceptedType.endsWith("/*")) {
|
|
147
|
-
const baseType = acceptedType.slice(0, -2);
|
|
148
|
-
return file.type.startsWith(baseType + "/");
|
|
149
|
-
}
|
|
150
|
-
return file.type === acceptedType;
|
|
151
|
-
});
|
|
152
|
-
if (!isValidFileType) {
|
|
153
|
-
if (appConfig.core?.locale === "th") {
|
|
154
|
-
setErrors("\u0E1B\u0E23\u0E30\u0E40\u0E20\u0E17\u0E44\u0E1F\u0E25\u0E4C\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07 (\u0E23\u0E2D\u0E07\u0E23\u0E31\u0E1A\u0E40\u0E09\u0E1E\u0E32\u0E30 " + acceptedTypesList.join(", ") + ")");
|
|
155
|
-
} else {
|
|
156
|
-
setErrors("Invalid file type (only " + acceptedTypesList.join(", ") + " are allowed)");
|
|
157
|
-
}
|
|
158
|
-
return false;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
if (props.maxSize) {
|
|
162
|
-
const maxSizeBytes = (fileAllocate.acceptFileSizeKb.value || 0) * 1024;
|
|
163
|
-
if (file.size > maxSizeBytes) {
|
|
164
|
-
if (fileAllocate.isAcceptFileUseMb.value) {
|
|
165
|
-
if (appConfig.core?.locale === "th") {
|
|
166
|
-
setErrors(`\u0E02\u0E19\u0E32\u0E14\u0E44\u0E1F\u0E25\u0E4C\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${fileAllocate.acceptFileSizeMb.value} MB`);
|
|
167
|
-
} else {
|
|
168
|
-
setErrors(`File size must not exceed ${fileAllocate.acceptFileSizeMb.value} MB`);
|
|
169
|
-
}
|
|
170
|
-
} else {
|
|
171
|
-
if (appConfig.core?.locale === "th") {
|
|
172
|
-
setErrors(`\u0E02\u0E19\u0E32\u0E14\u0E44\u0E1F\u0E25\u0E4C\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${fileAllocate.acceptFileSizeKb.value} KB`);
|
|
173
|
-
} else {
|
|
174
|
-
setErrors(`File size must not exceed ${fileAllocate.acceptFileSizeKb.value} KB`);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
return false;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
const isDimensionsValid = await validateImageDimensions(file);
|
|
181
|
-
if (!isDimensionsValid) {
|
|
182
|
-
return false;
|
|
183
|
-
}
|
|
184
|
-
setErrors("");
|
|
185
|
-
return true;
|
|
186
|
-
};
|
|
187
|
-
const processFile = async (file) => {
|
|
188
|
-
const isValid = await validateFile(file);
|
|
189
|
-
if (!isValid) return;
|
|
190
|
-
selectedFile.value = file;
|
|
191
|
-
emits("change", file);
|
|
192
|
-
const formData = new FormData();
|
|
193
|
-
formData.append(props.bodyKey, file);
|
|
194
|
-
upload.run({
|
|
195
|
-
data: formData
|
|
1
|
+
import { UploadState, useUploadState } from "./useUploadState.js";
|
|
2
|
+
import { validateDimensions } from "#core/helpers/uploadCore";
|
|
3
|
+
import { useCoreMessages } from "#core/composables/useMessages";
|
|
4
|
+
export { UploadState };
|
|
5
|
+
const readImageSize = (file) => new Promise((resolve) => {
|
|
6
|
+
const image = new Image();
|
|
7
|
+
const url = URL.createObjectURL(file);
|
|
8
|
+
image.onload = () => {
|
|
9
|
+
URL.revokeObjectURL(url);
|
|
10
|
+
resolve({
|
|
11
|
+
width: image.width,
|
|
12
|
+
height: image.height
|
|
196
13
|
});
|
|
197
14
|
};
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
15
|
+
image.onerror = () => {
|
|
16
|
+
URL.revokeObjectURL(url);
|
|
17
|
+
resolve(void 0);
|
|
18
|
+
};
|
|
19
|
+
image.src = url;
|
|
20
|
+
});
|
|
21
|
+
export const useUploadImageState = (context) => {
|
|
22
|
+
const { messages } = useCoreMessages();
|
|
23
|
+
return useUploadState(context, {
|
|
24
|
+
defaultAccept: "image/*",
|
|
25
|
+
validateExtra: async (file) => {
|
|
26
|
+
if (!context.props.dimensions) return;
|
|
27
|
+
const size = await readImageSize(file);
|
|
28
|
+
if (!size) return messages.value.upload.imageLoadFailed;
|
|
29
|
+
return validateDimensions(size, context.props.dimensions, messages.value.upload);
|
|
203
30
|
}
|
|
204
|
-
};
|
|
205
|
-
const fileDialog = useFileDialog({
|
|
206
|
-
accept: acceptedFileTypes.value || "image/*",
|
|
207
|
-
directory: false,
|
|
208
|
-
multiple: false
|
|
209
|
-
});
|
|
210
|
-
const dropzone = useDropZone(dropzoneRef, {
|
|
211
|
-
onDrop: handleFileDrop,
|
|
212
|
-
multiple: false,
|
|
213
|
-
preventDefaultForUnhandled: false
|
|
214
31
|
});
|
|
215
|
-
const currentState = computed(() => {
|
|
216
|
-
if (value.value) return "success" /* SUCCESS */;
|
|
217
|
-
if (selectedFile.value && upload.status.value.isLoading) return "uploading" /* UPLOADING */;
|
|
218
|
-
if (selectedFile.value && upload.status.value.isError) return "error" /* ERROR */;
|
|
219
|
-
return "empty" /* EMPTY */;
|
|
220
|
-
});
|
|
221
|
-
const isEmpty = computed(() => currentState.value === "empty" /* EMPTY */);
|
|
222
|
-
const isUploading = computed(() => currentState.value === "uploading" /* UPLOADING */);
|
|
223
|
-
const isSuccess = computed(() => currentState.value === "success" /* SUCCESS */);
|
|
224
|
-
const isError = computed(() => currentState.value === "error" /* ERROR */);
|
|
225
|
-
const handleInputChange = (event) => {
|
|
226
|
-
if (wrapperProps.value.disabled || wrapperProps.value.readonly) return;
|
|
227
|
-
const file = event.target.files?.[0];
|
|
228
|
-
if (file) {
|
|
229
|
-
processFile(file);
|
|
230
|
-
}
|
|
231
|
-
};
|
|
232
|
-
fileDialog.onChange((files) => {
|
|
233
|
-
const file = files?.[0];
|
|
234
|
-
if (file) {
|
|
235
|
-
processFile(file);
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
const handleOpenFile = () => {
|
|
239
|
-
if (wrapperProps.value.disabled || wrapperProps.value.readonly) return;
|
|
240
|
-
fileDialog.open();
|
|
241
|
-
};
|
|
242
|
-
const handleDeleteFile = () => {
|
|
243
|
-
fileDialog.reset();
|
|
244
|
-
upload.clear();
|
|
245
|
-
selectedFile.value = void 0;
|
|
246
|
-
onChange(void 0);
|
|
247
|
-
emits("delete");
|
|
248
|
-
};
|
|
249
|
-
const handleRetryUpload = () => {
|
|
250
|
-
if (selectedFile.value) {
|
|
251
|
-
const formData = new FormData();
|
|
252
|
-
formData.append(props.bodyKey, selectedFile.value);
|
|
253
|
-
upload.run(formData);
|
|
254
|
-
}
|
|
255
|
-
};
|
|
256
|
-
const handlePreview = () => {
|
|
257
|
-
previewModal.open({
|
|
258
|
-
value: value.value
|
|
259
|
-
});
|
|
260
|
-
};
|
|
261
|
-
useWatchTrue(
|
|
262
|
-
() => upload.status.value.isSuccess,
|
|
263
|
-
() => {
|
|
264
|
-
if (upload.data.value) {
|
|
265
|
-
const fileValue = {
|
|
266
|
-
url: _get(upload.data.value, props.responseURL),
|
|
267
|
-
path: _get(upload.data.value, props.responsePath),
|
|
268
|
-
name: _get(upload.data.value, props.responseName) || selectedFile.value?.name,
|
|
269
|
-
size: Number(_get(upload.data.value, props.responseSize) || selectedFile.value?.size),
|
|
270
|
-
id: _get(upload.data.value, props.responseID)
|
|
271
|
-
};
|
|
272
|
-
value.value = fileValue;
|
|
273
|
-
emits("success", fileValue);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
);
|
|
277
|
-
useWatchTrue(
|
|
278
|
-
() => upload.status.value.isError,
|
|
279
|
-
() => {
|
|
280
|
-
if (appConfig.core?.locale === "th") {
|
|
281
|
-
setErrors("\u0E1E\u0E1A\u0E02\u0E49\u0E2D\u0E1C\u0E34\u0E14\u0E1E\u0E25\u0E32\u0E14: " + StringHelper.getError(upload.status.value.errorData));
|
|
282
|
-
} else {
|
|
283
|
-
setErrors("An error occurred: " + StringHelper.getError(upload.status.value.errorData));
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
);
|
|
287
|
-
return {
|
|
288
|
-
// State
|
|
289
|
-
currentState,
|
|
290
|
-
isEmpty,
|
|
291
|
-
isUploading,
|
|
292
|
-
isSuccess,
|
|
293
|
-
isError,
|
|
294
|
-
selectedFile,
|
|
295
|
-
// Upload utilities
|
|
296
|
-
upload,
|
|
297
|
-
dropzone,
|
|
298
|
-
percent,
|
|
299
|
-
// Handlers
|
|
300
|
-
handleInputChange,
|
|
301
|
-
handleOpenFile,
|
|
302
|
-
handleDeleteFile,
|
|
303
|
-
handleRetryUpload,
|
|
304
|
-
handlePreview
|
|
305
|
-
};
|
|
306
32
|
};
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
import type { TemplateRef } from 'vue';
|
|
2
1
|
import type { IUploadDropzoneAutoProps } from '../InputUploadDropzoneAuto/types.js';
|
|
2
|
+
import { type IUploadFieldContext } from './useFilePicker.js';
|
|
3
|
+
import { UploadState } from '#core/helpers/uploadCore';
|
|
3
4
|
import type { IFileValue } from '#core/components/Form/types';
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
export { UploadState };
|
|
6
|
+
interface IUploadStateOptions {
|
|
7
|
+
defaultAccept?: string;
|
|
8
|
+
/** Extra check after type and size pass; resolves to an error message, or undefined when the file is fine */
|
|
9
|
+
validateExtra?: (file: File) => Promise<string | undefined>;
|
|
9
10
|
}
|
|
10
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Uploads the picked file right away and stores the file reference returned by the API as the field value
|
|
13
|
+
*/
|
|
14
|
+
export declare const useUploadState: (context: IUploadFieldContext<IUploadDropzoneAutoProps, IFileValue>, options?: IUploadStateOptions) => {
|
|
11
15
|
currentState: import("vue").ComputedRef<UploadState>;
|
|
12
16
|
isEmpty: import("vue").ComputedRef<boolean>;
|
|
13
17
|
isUploading: import("vue").ComputedRef<boolean>;
|
|
@@ -1,167 +1,83 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
1
|
+
import { useFilePicker } from "./useFilePicker.js";
|
|
2
|
+
import { toFileValue, toUploadFormData, UploadState, validateFile } from "#core/helpers/uploadCore";
|
|
3
|
+
import { useWatchTrue } from "#core/composables/useWatch";
|
|
4
|
+
import { useCoreMessages } from "#core/composables/useMessages";
|
|
5
5
|
import { useUploadLoader } from "#core/composables/useUpload";
|
|
6
|
-
import {
|
|
6
|
+
import { useFileProgress } from "#core/helpers/componentHelper";
|
|
7
7
|
import { StringHelper } from "#core/utils/StringHelper";
|
|
8
|
-
import {
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
UploadState2["ERROR"] = "error";
|
|
14
|
-
return UploadState2;
|
|
15
|
-
})(UploadState || {});
|
|
16
|
-
export const useUploadState = (props, emits, onChange, setErrors, value, acceptedFileTypes, wrapperProps, dropzoneRef) => {
|
|
17
|
-
const overlay = useOverlay();
|
|
18
|
-
const previewModal = overlay.create(PreviewModal);
|
|
8
|
+
import { computed, ref } from "#imports";
|
|
9
|
+
export { UploadState };
|
|
10
|
+
export const useUploadState = (context, options = {}) => {
|
|
11
|
+
const { props, emits, onChange, setErrors, value } = context;
|
|
12
|
+
const { messages, format } = useCoreMessages();
|
|
19
13
|
const selectedFile = ref();
|
|
20
|
-
const
|
|
21
|
-
const {
|
|
22
|
-
percent,
|
|
23
|
-
onDownloadProgress,
|
|
24
|
-
onUploadProgress
|
|
25
|
-
} = useFileProgress();
|
|
26
|
-
const request = {
|
|
14
|
+
const { percent, onDownloadProgress, onUploadProgress } = useFileProgress();
|
|
15
|
+
const upload = useUploadLoader({
|
|
27
16
|
requestOptions: {
|
|
28
17
|
...props.requestOptions,
|
|
29
18
|
onDownloadProgress,
|
|
30
19
|
onUploadProgress
|
|
31
20
|
},
|
|
32
21
|
pathURL: props.uploadPathURL
|
|
33
|
-
};
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
if (
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
return fileExtension === acceptedType.toLowerCase();
|
|
46
|
-
}
|
|
47
|
-
if (acceptedType.endsWith("/*")) {
|
|
48
|
-
const baseType = acceptedType.slice(0, -2);
|
|
49
|
-
return file.type.startsWith(baseType + "/");
|
|
50
|
-
}
|
|
51
|
-
return file.type === acceptedType;
|
|
52
|
-
});
|
|
53
|
-
if (!isValidFileType) {
|
|
54
|
-
setErrors("\u0E1B\u0E23\u0E30\u0E40\u0E20\u0E17\u0E44\u0E1F\u0E25\u0E4C\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07 (\u0E23\u0E2D\u0E07\u0E23\u0E31\u0E1A\u0E40\u0E09\u0E1E\u0E32\u0E30 " + acceptedTypesList.join(", ") + ")");
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
if (props.maxSize) {
|
|
59
|
-
const maxSizeBytes = (fileAllocate.acceptFileSizeKb.value || 0) * 1024;
|
|
60
|
-
if (file.size > maxSizeBytes) {
|
|
61
|
-
if (fileAllocate.isAcceptFileUseMb.value) {
|
|
62
|
-
setErrors(`\u0E02\u0E19\u0E32\u0E14\u0E44\u0E1F\u0E25\u0E4C\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${fileAllocate.acceptFileSizeMb.value} MB`);
|
|
63
|
-
} else {
|
|
64
|
-
setErrors(`\u0E02\u0E19\u0E32\u0E14\u0E44\u0E1F\u0E25\u0E4C\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${fileAllocate.acceptFileSizeKb.value} KB`);
|
|
65
|
-
}
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
setErrors("");
|
|
70
|
-
return true;
|
|
71
|
-
};
|
|
72
|
-
const processFile = (file) => {
|
|
73
|
-
if (!validateFile(file)) return;
|
|
74
|
-
selectedFile.value = file;
|
|
75
|
-
emits("change", file);
|
|
76
|
-
const formData = new FormData();
|
|
77
|
-
formData.append(props.bodyKey, file);
|
|
22
|
+
});
|
|
23
|
+
const currentState = computed(() => {
|
|
24
|
+
if (value.value) return UploadState.SUCCESS;
|
|
25
|
+
if (selectedFile.value && upload.status.value.isLoading) return UploadState.UPLOADING;
|
|
26
|
+
if (selectedFile.value && upload.status.value.isError) return UploadState.ERROR;
|
|
27
|
+
return UploadState.EMPTY;
|
|
28
|
+
});
|
|
29
|
+
const isEmpty = computed(() => currentState.value === UploadState.EMPTY);
|
|
30
|
+
const isUploading = computed(() => currentState.value === UploadState.UPLOADING);
|
|
31
|
+
const isSuccess = computed(() => currentState.value === UploadState.SUCCESS);
|
|
32
|
+
const isError = computed(() => currentState.value === UploadState.ERROR);
|
|
33
|
+
const startUpload = (file) => {
|
|
78
34
|
upload.run({
|
|
79
|
-
data:
|
|
35
|
+
data: toUploadFormData(props.bodyKey, file)
|
|
80
36
|
});
|
|
81
37
|
};
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if (
|
|
86
|
-
|
|
87
|
-
|
|
38
|
+
const processFile = async (file) => {
|
|
39
|
+
const error = validateFile(file, props, messages.value.upload) ?? await options.validateExtra?.(file);
|
|
40
|
+
setErrors(error ?? "");
|
|
41
|
+
if (error) return;
|
|
42
|
+
selectedFile.value = file;
|
|
43
|
+
emits("change", file);
|
|
44
|
+
startUpload(file);
|
|
88
45
|
};
|
|
89
|
-
const
|
|
90
|
-
accept: acceptedFileTypes.value || "",
|
|
91
|
-
directory: false,
|
|
92
|
-
multiple: false
|
|
93
|
-
});
|
|
94
|
-
const dropzone = useDropZone(dropzoneRef, {
|
|
95
|
-
onDrop: handleFileDrop,
|
|
96
|
-
// dataTypes: typeof props.accept === 'string' ? [props.accept] : props.accept,
|
|
46
|
+
const picker = useFilePicker(context, {
|
|
97
47
|
multiple: false,
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if (selectedFile.value && upload.status.value.isLoading) return "uploading" /* UPLOADING */;
|
|
103
|
-
if (selectedFile.value && upload.status.value.isError) return "error" /* ERROR */;
|
|
104
|
-
return "empty" /* EMPTY */;
|
|
105
|
-
});
|
|
106
|
-
const isEmpty = computed(() => currentState.value === "empty" /* EMPTY */);
|
|
107
|
-
const isUploading = computed(() => currentState.value === "uploading" /* UPLOADING */);
|
|
108
|
-
const isSuccess = computed(() => currentState.value === "success" /* SUCCESS */);
|
|
109
|
-
const isError = computed(() => currentState.value === "error" /* ERROR */);
|
|
110
|
-
const handleInputChange = (event) => {
|
|
111
|
-
if (wrapperProps.value.disabled || wrapperProps.value.readonly) return;
|
|
112
|
-
const file = event.target.files?.[0];
|
|
113
|
-
if (file) {
|
|
114
|
-
processFile(file);
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
fileDialog.onChange((files) => {
|
|
118
|
-
if (files?.length) {
|
|
119
|
-
processFile(files[0]);
|
|
48
|
+
defaultAccept: options.defaultAccept,
|
|
49
|
+
canDrop: () => isEmpty.value,
|
|
50
|
+
onFiles: async ([file]) => {
|
|
51
|
+
if (file) await processFile(file);
|
|
120
52
|
}
|
|
121
53
|
});
|
|
122
|
-
const handleOpenFile = () => {
|
|
123
|
-
if (wrapperProps.value.disabled || wrapperProps.value.readonly) return;
|
|
124
|
-
fileDialog.open();
|
|
125
|
-
};
|
|
126
54
|
const handleDeleteFile = () => {
|
|
127
|
-
fileDialog.reset();
|
|
55
|
+
picker.fileDialog.reset();
|
|
128
56
|
upload.clear();
|
|
129
57
|
selectedFile.value = void 0;
|
|
130
58
|
onChange(void 0);
|
|
131
59
|
emits("delete");
|
|
132
60
|
};
|
|
133
61
|
const handleRetryUpload = () => {
|
|
134
|
-
if (selectedFile.value)
|
|
135
|
-
const formData = new FormData();
|
|
136
|
-
formData.append(props.bodyKey, selectedFile.value);
|
|
137
|
-
upload.run(formData);
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
const handlePreview = () => {
|
|
141
|
-
previewModal.open({
|
|
142
|
-
value: value.value
|
|
143
|
-
});
|
|
62
|
+
if (selectedFile.value) startUpload(selectedFile.value);
|
|
144
63
|
};
|
|
145
64
|
useWatchTrue(
|
|
146
65
|
() => upload.status.value.isSuccess,
|
|
147
66
|
() => {
|
|
148
|
-
if (upload.data.value)
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
name: _get(upload.data.value, props.responseName) || selectedFile.value?.name,
|
|
153
|
-
size: Number(_get(upload.data.value, props.responseSize) || selectedFile.value?.size),
|
|
154
|
-
id: _get(upload.data.value, props.responseID)
|
|
155
|
-
};
|
|
156
|
-
value.value = fileValue;
|
|
157
|
-
emits("success", fileValue);
|
|
158
|
-
}
|
|
67
|
+
if (!upload.data.value) return;
|
|
68
|
+
const fileValue = toFileValue(upload.data.value, props, selectedFile.value);
|
|
69
|
+
value.value = fileValue;
|
|
70
|
+
emits("success", fileValue);
|
|
159
71
|
}
|
|
160
72
|
);
|
|
161
73
|
useWatchTrue(
|
|
162
74
|
() => upload.status.value.isError,
|
|
163
75
|
() => {
|
|
164
|
-
setErrors(
|
|
76
|
+
setErrors(
|
|
77
|
+
format(messages.value.upload.error, {
|
|
78
|
+
message: StringHelper.getError(upload.status.value.errorData, messages.value.common.somethingWentWrong)
|
|
79
|
+
})
|
|
80
|
+
);
|
|
165
81
|
}
|
|
166
82
|
);
|
|
167
83
|
return {
|
|
@@ -174,13 +90,13 @@ export const useUploadState = (props, emits, onChange, setErrors, value, accepte
|
|
|
174
90
|
selectedFile,
|
|
175
91
|
// Upload utilities
|
|
176
92
|
upload,
|
|
177
|
-
dropzone,
|
|
93
|
+
dropzone: picker.dropzone,
|
|
178
94
|
percent,
|
|
179
95
|
// Handlers
|
|
180
|
-
handleInputChange,
|
|
181
|
-
handleOpenFile,
|
|
96
|
+
handleInputChange: picker.handleInputChange,
|
|
97
|
+
handleOpenFile: picker.handleOpenFile,
|
|
182
98
|
handleDeleteFile,
|
|
183
99
|
handleRetryUpload,
|
|
184
|
-
handlePreview
|
|
100
|
+
handlePreview: () => picker.openPreview(value.value)
|
|
185
101
|
};
|
|
186
102
|
};
|
|
@@ -1,24 +1,23 @@
|
|
|
1
|
-
import type { TemplateRef } from 'vue';
|
|
2
1
|
import type { IUploadDropzoneAutoMultipleProps } from '../InputUploadDropzoneAutoMultiple/types.js';
|
|
2
|
+
import { type IUploadFieldContext } from './useFilePicker.js';
|
|
3
|
+
import { UploadState } from '#core/helpers/uploadCore';
|
|
3
4
|
import type { IFileValue } from '#core/components/Form/types';
|
|
4
|
-
export
|
|
5
|
-
EMPTY = "empty",
|
|
6
|
-
UPLOADING = "uploading",
|
|
7
|
-
SUCCESS = "success",
|
|
8
|
-
ERROR = "error"
|
|
9
|
-
}
|
|
5
|
+
export { UploadState };
|
|
10
6
|
export interface FileUploadItem {
|
|
7
|
+
id: number;
|
|
11
8
|
file: File;
|
|
12
9
|
state: UploadState;
|
|
13
10
|
progress: number;
|
|
14
11
|
value?: IFileValue;
|
|
15
12
|
error?: string;
|
|
16
|
-
uploadLoader?: any;
|
|
17
|
-
percentRef?: any;
|
|
18
|
-
cleanupWatchers?: (() => void)[];
|
|
19
13
|
}
|
|
20
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Uploads every picked file right away. Finished files move into the field value (newest first);
|
|
16
|
+
* `fileItems` only holds the ones still uploading or failed.
|
|
17
|
+
*/
|
|
18
|
+
export declare const useUploadStateMultiple: (context: IUploadFieldContext<IUploadDropzoneAutoMultipleProps, IFileValue[]>) => {
|
|
21
19
|
fileItems: import("vue").Ref<{
|
|
20
|
+
id: number;
|
|
22
21
|
file: {
|
|
23
22
|
readonly lastModified: number;
|
|
24
23
|
readonly name: string;
|
|
@@ -56,10 +55,8 @@ export declare const useUploadStateMultiple: (props: IUploadDropzoneAutoMultiple
|
|
|
56
55
|
id?: string | undefined;
|
|
57
56
|
} | undefined;
|
|
58
57
|
error?: string | undefined;
|
|
59
|
-
uploadLoader?: any;
|
|
60
|
-
percentRef?: any;
|
|
61
|
-
cleanupWatchers?: (() => void)[] | undefined;
|
|
62
58
|
}[], FileUploadItem[] | {
|
|
59
|
+
id: number;
|
|
63
60
|
file: {
|
|
64
61
|
readonly lastModified: number;
|
|
65
62
|
readonly name: string;
|
|
@@ -97,9 +94,6 @@ export declare const useUploadStateMultiple: (props: IUploadDropzoneAutoMultiple
|
|
|
97
94
|
id?: string | undefined;
|
|
98
95
|
} | undefined;
|
|
99
96
|
error?: string | undefined;
|
|
100
|
-
uploadLoader?: any;
|
|
101
|
-
percentRef?: any;
|
|
102
|
-
cleanupWatchers?: (() => void)[] | undefined;
|
|
103
97
|
}[]>;
|
|
104
98
|
isEmpty: import("vue").ComputedRef<boolean>;
|
|
105
99
|
hasUploading: import("vue").ComputedRef<boolean>;
|
|
@@ -108,5 +102,5 @@ export declare const useUploadStateMultiple: (props: IUploadDropzoneAutoMultiple
|
|
|
108
102
|
handleOpenFile: () => void;
|
|
109
103
|
handleDeleteFile: (index: number) => void;
|
|
110
104
|
handleRetryUpload: (index: number) => Promise<void>;
|
|
111
|
-
handlePreview: (fileValue: IFileValue) => void;
|
|
105
|
+
handlePreview: (fileValue: IFileValue | File) => void;
|
|
112
106
|
};
|