@finema/core 3.14.2 → 3.14.4

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/dist/module.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finema/core",
3
- "version": "3.14.2",
3
+ "version": "3.14.4",
4
4
  "configKey": "core",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
package/dist/module.mjs CHANGED
@@ -4,7 +4,7 @@ import * as lodash from 'lodash-es';
4
4
  import * as theme from '../dist/runtime/theme/index.js';
5
5
 
6
6
  const name = "@finema/core";
7
- const version = "3.14.2";
7
+ const version = "3.14.4";
8
8
 
9
9
  const nuxtAppOptions = {
10
10
  head: {
@@ -6,6 +6,9 @@ interface FileUploadItem {
6
6
  progress: number;
7
7
  value?: IFileValue;
8
8
  error?: string;
9
+ uploadLoader?: any;
10
+ percentRef?: any;
11
+ cleanupWatchers?: (() => void)[];
9
12
  }
10
13
  interface Props {
11
14
  theme: any;
@@ -6,6 +6,9 @@ interface FileUploadItem {
6
6
  progress: number;
7
7
  value?: IFileValue;
8
8
  error?: string;
9
+ uploadLoader?: any;
10
+ percentRef?: any;
11
+ cleanupWatchers?: (() => void)[];
9
12
  }
10
13
  interface Props {
11
14
  theme: any;
@@ -1,7 +1,7 @@
1
1
  import { useDropZone, useFileDialog } from "@vueuse/core";
2
2
  import { useWatchTrue } from "#core/composables/useWatch";
3
3
  import PreviewModal from "./PreviewModal.vue";
4
- import { computed, ref, useOverlay } from "#imports";
4
+ import { computed, ref, useOverlay, useAppConfig } from "#imports";
5
5
  import { useUploadLoader } from "#core/composables/useUpload";
6
6
  import { useFileAllocate, useFileProgress } from "#core/helpers/componentHelper";
7
7
  import { StringHelper } from "#core/utils/StringHelper";
@@ -18,6 +18,7 @@ export const useUploadImageState = (props, emits, onChange, setErrors, value, ac
18
18
  const previewModal = overlay.create(PreviewModal);
19
19
  const selectedFile = ref();
20
20
  const fileAllocate = useFileAllocate(selectedFile, props);
21
+ const appConfig = useAppConfig();
21
22
  const {
22
23
  percent,
23
24
  onDownloadProgress,
@@ -48,32 +49,56 @@ export const useUploadImageState = (props, emits, onChange, setErrors, value, ac
48
49
  } = img;
49
50
  const dimensions = props.dimensions;
50
51
  if (dimensions.width !== void 0 && width !== dimensions.width) {
51
- 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)`);
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
+ }
52
57
  resolve(false);
53
58
  return;
54
59
  }
55
60
  if (dimensions.height !== void 0 && height !== dimensions.height) {
56
- 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)`);
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
+ }
57
66
  resolve(false);
58
67
  return;
59
68
  }
60
69
  if (dimensions.minWidth !== void 0 && width < dimensions.minWidth) {
61
- 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)`);
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
+ }
62
75
  resolve(false);
63
76
  return;
64
77
  }
65
78
  if (dimensions.minHeight !== void 0 && height < dimensions.minHeight) {
66
- 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)`);
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
+ }
67
84
  resolve(false);
68
85
  return;
69
86
  }
70
87
  if (dimensions.maxWidth !== void 0 && width > dimensions.maxWidth) {
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\u0E40\u0E01\u0E34\u0E19 ${dimensions.maxWidth}px (\u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19: ${width}px)`);
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
+ }
72
93
  resolve(false);
73
94
  return;
74
95
  }
75
96
  if (dimensions.maxHeight !== void 0 && height > dimensions.maxHeight) {
76
- 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)`);
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
+ }
77
102
  resolve(false);
78
103
  return;
79
104
  }
@@ -82,7 +107,11 @@ export const useUploadImageState = (props, emits, onChange, setErrors, value, ac
82
107
  const tolerance = dimensions.aspectRatioTolerance ?? 0.01;
83
108
  const expectedRatio = dimensions.aspectRatio;
84
109
  if (Math.abs(actualRatio - expectedRatio) > tolerance) {
85
- 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)})`);
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
+ }
86
115
  resolve(false);
87
116
  return;
88
117
  }
@@ -92,7 +121,11 @@ export const useUploadImageState = (props, emits, onChange, setErrors, value, ac
92
121
  };
93
122
  img.onerror = () => {
94
123
  URL.revokeObjectURL(url);
95
- setErrors("\u0E44\u0E21\u0E48\u0E2A\u0E32\u0E21\u0E32\u0E23\u0E16\u0E42\u0E2B\u0E25\u0E14\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E44\u0E14\u0E49");
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
+ }
96
129
  resolve(false);
97
130
  };
98
131
  img.src = url;
@@ -117,7 +150,11 @@ export const useUploadImageState = (props, emits, onChange, setErrors, value, ac
117
150
  return file.type === acceptedType;
118
151
  });
119
152
  if (!isValidFileType) {
120
- 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(", ") + ")");
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
+ }
121
158
  return false;
122
159
  }
123
160
  }
@@ -125,9 +162,17 @@ export const useUploadImageState = (props, emits, onChange, setErrors, value, ac
125
162
  const maxSizeBytes = (fileAllocate.acceptFileSizeKb.value || 0) * 1024;
126
163
  if (file.size > maxSizeBytes) {
127
164
  if (fileAllocate.isAcceptFileUseMb.value) {
128
- setErrors(`\u0E02\u0E19\u0E32\u0E14\u0E44\u0E1F\u0E25\u0E4C\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${fileAllocate.acceptFileSizeMb.value} MB`);
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
+ }
129
170
  } else {
130
- setErrors(`\u0E02\u0E19\u0E32\u0E14\u0E44\u0E1F\u0E25\u0E4C\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${fileAllocate.acceptFileSizeKb.value} KB`);
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
+ }
131
176
  }
132
177
  return false;
133
178
  }
@@ -232,7 +277,11 @@ export const useUploadImageState = (props, emits, onChange, setErrors, value, ac
232
277
  useWatchTrue(
233
278
  () => upload.status.value.isError,
234
279
  () => {
235
- setErrors("\u0E1E\u0E1A\u0E02\u0E49\u0E2D\u0E1C\u0E34\u0E14\u0E1E\u0E25\u0E32\u0E14: " + StringHelper.getError(upload.status.value.errorData));
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
+ }
236
285
  }
237
286
  );
238
287
  return {
@@ -1,7 +1,6 @@
1
- import type { Ref, TemplateRef } from 'vue';
1
+ import type { TemplateRef } from 'vue';
2
2
  import type { IUploadDropzoneAutoMultipleProps } from '../InputUploadDropzoneAutoMultiple/types.js';
3
3
  import type { IFileValue } from '#core/components/Form/types';
4
- import { useUploadLoader } from '#core/composables/useUpload';
5
4
  export declare enum UploadState {
6
5
  EMPTY = "empty",
7
6
  UPLOADING = "uploading",
@@ -14,11 +13,12 @@ export interface FileUploadItem {
14
13
  progress: number;
15
14
  value?: IFileValue;
16
15
  error?: string;
17
- uploadLoader?: ReturnType<typeof useUploadLoader>;
18
- percentRef?: Ref<number>;
16
+ uploadLoader?: any;
17
+ percentRef?: any;
18
+ cleanupWatchers?: (() => void)[];
19
19
  }
20
20
  export declare const useUploadStateMultiple: (props: IUploadDropzoneAutoMultipleProps, emits: any, onChange: (value: IFileValue[] | undefined) => void, setErrors: (error: string) => void, value: any, acceptedFileTypes: any, wrapperProps: any, dropzoneRef: TemplateRef<HTMLDivElement | undefined>) => {
21
- fileItems: Ref<{
21
+ fileItems: import("vue").Ref<{
22
22
  file: {
23
23
  readonly lastModified: number;
24
24
  readonly name: string;
@@ -56,16 +56,9 @@ export declare const useUploadStateMultiple: (props: IUploadDropzoneAutoMultiple
56
56
  id?: string | undefined;
57
57
  } | undefined;
58
58
  error?: string | undefined;
59
- uploadLoader?: {
60
- status: import("#imports").IStatus;
61
- data: any;
62
- options: import("#imports").IAPIOptions;
63
- run: (payload?: import("../../../helpers/apiObjectHelper.js").IObjectRunLoaderOptions<any, any> | undefined) => Promise<void>;
64
- clear: () => void;
65
- setLoading: () => void;
66
- setData: (data: any) => void;
67
- } | undefined;
68
- percentRef?: number | undefined;
59
+ uploadLoader?: any;
60
+ percentRef?: any;
61
+ cleanupWatchers?: (() => void)[] | undefined;
69
62
  }[], FileUploadItem[] | {
70
63
  file: {
71
64
  readonly lastModified: number;
@@ -104,16 +97,9 @@ export declare const useUploadStateMultiple: (props: IUploadDropzoneAutoMultiple
104
97
  id?: string | undefined;
105
98
  } | undefined;
106
99
  error?: string | undefined;
107
- uploadLoader?: {
108
- status: import("#imports").IStatus;
109
- data: any;
110
- options: import("#imports").IAPIOptions;
111
- run: (payload?: import("../../../helpers/apiObjectHelper.js").IObjectRunLoaderOptions<any, any> | undefined) => Promise<void>;
112
- clear: () => void;
113
- setLoading: () => void;
114
- setData: (data: any) => void;
115
- } | undefined;
116
- percentRef?: number | undefined;
100
+ uploadLoader?: any;
101
+ percentRef?: any;
102
+ cleanupWatchers?: (() => void)[] | undefined;
117
103
  }[]>;
118
104
  isEmpty: import("vue").ComputedRef<boolean>;
119
105
  hasUploading: import("vue").ComputedRef<boolean>;
@@ -98,7 +98,7 @@ export const useUploadStateMultiple = (props, emits, onChange, setErrors, value,
98
98
  size: Number(_get(uploadLoader.data.value, props.responseSize) || fileItem.file.size),
99
99
  id: _get(uploadLoader.data.value, props.responseID)
100
100
  };
101
- fileItems.value.splice(index, 1);
101
+ fileItems.value = fileItems.value.filter((_, i) => i !== index);
102
102
  onChange([fileValue, ...ArrayHelper.toArray(value.value)]);
103
103
  emits("success", fileValue);
104
104
  stopProgressWatch();
@@ -123,6 +123,9 @@ export const useUploadStateMultiple = (props, emits, onChange, setErrors, value,
123
123
  }
124
124
  }
125
125
  );
126
+ updateFileItem(index, {
127
+ cleanupWatchers: [stopProgressWatch, stopSuccessWatch, stopErrorWatch]
128
+ });
126
129
  return uploadLoader;
127
130
  };
128
131
  const processFile = (file) => {
@@ -187,6 +190,10 @@ export const useUploadStateMultiple = (props, emits, onChange, setErrors, value,
187
190
  fileDialog.open();
188
191
  };
189
192
  const handleDeleteFile = (index) => {
193
+ const fileItem = fileItems.value[index];
194
+ if (fileItem?.cleanupWatchers) {
195
+ fileItem.cleanupWatchers.forEach((cleanup) => cleanup());
196
+ }
190
197
  fileItems.value.splice(index, 1);
191
198
  if (fileItems.value.length === 0) {
192
199
  setErrors("");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finema/core",
3
- "version": "3.14.2",
3
+ "version": "3.14.4",
4
4
  "repository": "https://gitlab.finema.co/finema/ui-kit",
5
5
  "license": "MIT",
6
6
  "author": "Finema Dev Core Team",