@finema/core 3.14.1 → 3.14.3

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.
Files changed (78) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +1 -1
  3. package/dist/runtime/components/FlexDeck/index.vue +79 -79
  4. package/dist/runtime/components/Form/FieldWrapper.vue +13 -13
  5. package/dist/runtime/components/Form/Fields.vue +13 -13
  6. package/dist/runtime/components/Form/InputCheckbox/index.d.vue.ts +1 -5
  7. package/dist/runtime/components/Form/InputCheckbox/index.vue +18 -18
  8. package/dist/runtime/components/Form/InputCheckbox/index.vue.d.ts +1 -5
  9. package/dist/runtime/components/Form/InputCheckboxGroup/index.d.vue.ts +1 -5
  10. package/dist/runtime/components/Form/InputCheckboxGroup/index.vue +21 -21
  11. package/dist/runtime/components/Form/InputCheckboxGroup/index.vue.d.ts +1 -5
  12. package/dist/runtime/components/Form/InputCurrency/index.d.vue.ts +1 -5
  13. package/dist/runtime/components/Form/InputCurrency/index.vue +49 -49
  14. package/dist/runtime/components/Form/InputCurrency/index.vue.d.ts +1 -5
  15. package/dist/runtime/components/Form/InputDateTime/index.d.vue.ts +1 -5
  16. package/dist/runtime/components/Form/InputDateTime/index.vue +155 -155
  17. package/dist/runtime/components/Form/InputDateTime/index.vue.d.ts +1 -5
  18. package/dist/runtime/components/Form/InputDateTimeRange/index.d.vue.ts +1 -5
  19. package/dist/runtime/components/Form/InputDateTimeRange/index.vue +56 -56
  20. package/dist/runtime/components/Form/InputDateTimeRange/index.vue.d.ts +1 -5
  21. package/dist/runtime/components/Form/InputMonth/index.d.vue.ts +1 -5
  22. package/dist/runtime/components/Form/InputMonth/index.vue.d.ts +1 -5
  23. package/dist/runtime/components/Form/InputNumber/index.d.vue.ts +1 -5
  24. package/dist/runtime/components/Form/InputNumber/index.vue +20 -20
  25. package/dist/runtime/components/Form/InputNumber/index.vue.d.ts +1 -5
  26. package/dist/runtime/components/Form/InputSearch/index.d.vue.ts +1 -9
  27. package/dist/runtime/components/Form/InputSearch/index.vue.d.ts +1 -9
  28. package/dist/runtime/components/Form/InputSelect/index.d.vue.ts +1 -7
  29. package/dist/runtime/components/Form/InputSelect/index.vue +46 -46
  30. package/dist/runtime/components/Form/InputSelect/index.vue.d.ts +1 -7
  31. package/dist/runtime/components/Form/InputSelectMultiple/index.d.vue.ts +1 -7
  32. package/dist/runtime/components/Form/InputSelectMultiple/index.vue +62 -62
  33. package/dist/runtime/components/Form/InputSelectMultiple/index.vue.d.ts +1 -7
  34. package/dist/runtime/components/Form/InputTags/index.d.vue.ts +1 -11
  35. package/dist/runtime/components/Form/InputTags/index.vue +54 -54
  36. package/dist/runtime/components/Form/InputTags/index.vue.d.ts +1 -11
  37. package/dist/runtime/components/Form/InputText/index.d.vue.ts +1 -7
  38. package/dist/runtime/components/Form/InputText/index.vue +85 -85
  39. package/dist/runtime/components/Form/InputText/index.vue.d.ts +1 -7
  40. package/dist/runtime/components/Form/InputTextarea/index.d.vue.ts +1 -5
  41. package/dist/runtime/components/Form/InputTextarea/index.vue +18 -18
  42. package/dist/runtime/components/Form/InputTextarea/index.vue.d.ts +1 -5
  43. package/dist/runtime/components/Form/InputTime/index.d.vue.ts +1 -5
  44. package/dist/runtime/components/Form/InputTime/index.vue +38 -38
  45. package/dist/runtime/components/Form/InputTime/index.vue.d.ts +1 -5
  46. package/dist/runtime/components/Form/InputToggle/index.d.vue.ts +1 -5
  47. package/dist/runtime/components/Form/InputToggle/index.vue +17 -17
  48. package/dist/runtime/components/Form/InputToggle/index.vue.d.ts +1 -5
  49. package/dist/runtime/components/Form/InputUploadDropzone/index.vue +30 -30
  50. package/dist/runtime/components/Form/InputUploadDropzoneAuto/index.vue +50 -50
  51. package/dist/runtime/components/Form/InputUploadDropzoneAutoMultiple/index.vue +50 -50
  52. package/dist/runtime/components/Form/InputUploadImageAuto/index.vue +50 -50
  53. package/dist/runtime/components/Form/InputWYSIWYG/EditorImageUploadNode.vue +18 -18
  54. package/dist/runtime/components/Form/InputWYSIWYG/EditorLinkPopover.vue +65 -65
  55. package/dist/runtime/components/Form/InputWYSIWYG/README.md +96 -96
  56. package/dist/runtime/components/Form/InputWYSIWYG/index.vue +41 -41
  57. package/dist/runtime/components/Form/fileState/EmptyState.vue +21 -21
  58. package/dist/runtime/components/Form/fileState/FailedState.vue +33 -33
  59. package/dist/runtime/components/Form/fileState/LoadingState.vue +24 -24
  60. package/dist/runtime/components/Form/fileState/MultipleFilesState.vue +75 -75
  61. package/dist/runtime/components/Form/fileState/PreviewModal.vue +23 -23
  62. package/dist/runtime/components/Form/fileState/useUploadImageState.js +62 -13
  63. package/dist/runtime/components/Form/index.vue +5 -5
  64. package/dist/runtime/components/Image.vue +28 -28
  65. package/dist/runtime/components/Log/index.vue +17 -17
  66. package/dist/runtime/components/Table/Base.d.vue.ts +2 -8
  67. package/dist/runtime/components/Table/Base.vue.d.ts +2 -8
  68. package/dist/runtime/components/Table/ColumnDate.vue +1 -1
  69. package/dist/runtime/components/Table/ColumnDateTime.vue +1 -1
  70. package/dist/runtime/components/Table/ColumnImage.vue +4 -4
  71. package/dist/runtime/components/Table/ColumnText.vue +10 -10
  72. package/dist/runtime/components/Table/Pagination.vue +59 -56
  73. package/dist/runtime/components/Table/Simple.vue +16 -16
  74. package/dist/runtime/components/Table/index.vue +30 -30
  75. package/dist/runtime/server/tsconfig.json +3 -3
  76. package/dist/runtime/theme/table.d.ts +1 -0
  77. package/dist/runtime/theme/table.js +4 -3
  78. package/package.json +2 -2
@@ -1,79 +1,79 @@
1
1
  <template>
2
- <div :class="theme.multipleFilesWrapper()">
3
- <div
4
- v-for="(item, index) in fileItems"
5
- :key="index"
6
- :class="theme.fileItemWrapper()"
7
- >
8
- <!-- Uploading State -->
9
- <div
10
- v-if="item.state === UploadState.UPLOADING"
11
- :class="theme.uploadingItemWrapper()"
12
- >
13
- <div :class="theme.uploadingIconWrapper()">
14
- <Icon
15
- :name="icons.filePreviewIcon"
16
- :class="theme.uploadingIconClass()"
17
- />
18
- </div>
19
- <div :class="theme.uploadingTextWrapper()">
20
- <h1 class="truncate font-bold">
21
- {{ item.file.name }}
22
- </h1>
23
- <div class="flex items-center gap-2">
24
- <div :class="theme.progressBarWrapper()">
25
- <div
26
- :class="theme.progressBarFill()"
27
- :style="{ width: `${item.progress}%` }"
28
- />
29
- </div>
30
- <p class="text-sm text-gray-400">
31
- {{ item.progress }}%
32
- </p>
33
- </div>
34
- </div>
35
- </div>
36
-
37
- <!-- Error State -->
38
- <div
39
- v-else-if="item.state === UploadState.ERROR"
40
- :class="theme.errorItemWrapper()"
41
- >
42
- <div :class="theme.errorIconWrapper()">
43
- <Icon
44
- :name="icons.errorIcon"
45
- :class="theme.errorIconClass()"
46
- />
47
- </div>
48
- <div :class="theme.errorTextWrapper()">
49
- <h1 class="truncate font-bold">
50
- {{ item.file.name }}
51
- </h1>
52
- <p class="text-error-500 text-sm">
53
- {{ item.error || uploadFailedLabel }}
54
- </p>
55
- </div>
56
- <div :class="theme.errorActionWrapper()">
57
- <Button
58
- variant="link"
59
- :icon="icons.actionRetryIcon"
60
- :class="theme.actionRetryBtnClass()"
61
- color="primary"
62
- @click="$emit('retry', index)"
63
- >
64
- {{ retryLabel }}
65
- </Button>
66
- <Icon
67
- v-if="!disabled && !readonly"
68
- :name="icons.actionDeleteIcon"
69
- :class="theme.actionIconClass()"
70
- title="ลบไฟล์"
71
- @click="$emit('delete', index)"
72
- />
73
- </div>
74
- </div>
75
- </div>
76
- </div>
2
+ <div :class="theme.multipleFilesWrapper()">
3
+ <div
4
+ v-for="(item, index) in fileItems"
5
+ :key="index"
6
+ :class="theme.fileItemWrapper()"
7
+ >
8
+ <!-- Uploading State -->
9
+ <div
10
+ v-if="item.state === UploadState.UPLOADING"
11
+ :class="theme.uploadingItemWrapper()"
12
+ >
13
+ <div :class="theme.uploadingIconWrapper()">
14
+ <Icon
15
+ :name="icons.filePreviewIcon"
16
+ :class="theme.uploadingIconClass()"
17
+ />
18
+ </div>
19
+ <div :class="theme.uploadingTextWrapper()">
20
+ <h1 class="truncate font-bold">
21
+ {{ item.file.name }}
22
+ </h1>
23
+ <div class="flex items-center gap-2">
24
+ <div :class="theme.progressBarWrapper()">
25
+ <div
26
+ :class="theme.progressBarFill()"
27
+ :style="{ width: `${item.progress}%` }"
28
+ />
29
+ </div>
30
+ <p class="text-sm text-gray-400">
31
+ {{ item.progress }}%
32
+ </p>
33
+ </div>
34
+ </div>
35
+ </div>
36
+
37
+ <!-- Error State -->
38
+ <div
39
+ v-else-if="item.state === UploadState.ERROR"
40
+ :class="theme.errorItemWrapper()"
41
+ >
42
+ <div :class="theme.errorIconWrapper()">
43
+ <Icon
44
+ :name="icons.errorIcon"
45
+ :class="theme.errorIconClass()"
46
+ />
47
+ </div>
48
+ <div :class="theme.errorTextWrapper()">
49
+ <h1 class="truncate font-bold">
50
+ {{ item.file.name }}
51
+ </h1>
52
+ <p class="text-error-500 text-sm">
53
+ {{ item.error || uploadFailedLabel }}
54
+ </p>
55
+ </div>
56
+ <div :class="theme.errorActionWrapper()">
57
+ <Button
58
+ variant="link"
59
+ :icon="icons.actionRetryIcon"
60
+ :class="theme.actionRetryBtnClass()"
61
+ color="primary"
62
+ @click="$emit('retry', index)"
63
+ >
64
+ {{ retryLabel }}
65
+ </Button>
66
+ <Icon
67
+ v-if="!disabled && !readonly"
68
+ :name="icons.actionDeleteIcon"
69
+ :class="theme.actionIconClass()"
70
+ title="ลบไฟล์"
71
+ @click="$emit('delete', index)"
72
+ />
73
+ </div>
74
+ </div>
75
+ </div>
76
+ </div>
77
77
  </template>
78
78
 
79
79
  <script setup>
@@ -1,29 +1,29 @@
1
1
  <template>
2
- <Modal
3
- :close="{ onClick: () => emits('close', false) }"
4
- :dismissible="false"
5
- :title="value?.name"
2
+ <Modal
3
+ :close="{ onClick: () => emits('close', false) }"
4
+ :dismissible="false"
5
+ :title="value?.name"
6
6
  :ui="{
7
7
  content: 'max-w-3xl'
8
- }"
9
- >
10
- <template #body>
11
- <div class="flex justify-center">
12
- <img
13
- v-if="value && isImageFromPath(value.path)"
14
- :src="value.url"
15
- alt="img-preview"
16
- class="max-h-96 max-w-full rounded-lg"
17
- />
18
- <video
19
- v-else-if="value && isVideoFromPath(value.path)"
20
- :src="value.url"
21
- controls
22
- class="max-h-96 max-w-full"
23
- />
24
- </div>
25
- </template>
26
- </Modal>
8
+ }"
9
+ >
10
+ <template #body>
11
+ <div class="flex justify-center">
12
+ <img
13
+ v-if="value && isImageFromPath(value.path)"
14
+ :src="value.url"
15
+ alt="img-preview"
16
+ class="max-h-96 max-w-full rounded-lg"
17
+ />
18
+ <video
19
+ v-else-if="value && isVideoFromPath(value.path)"
20
+ :src="value.url"
21
+ controls
22
+ class="max-h-96 max-w-full"
23
+ />
24
+ </div>
25
+ </template>
26
+ </Modal>
27
27
  </template>
28
28
 
29
29
  <script setup>
@@ -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,5 +1,5 @@
1
- <template>
2
- <form class="form">
3
- <slot />
4
- </form>
5
- </template>
1
+ <template>
2
+ <form class="form">
3
+ <slot />
4
+ </form>
5
+ </template>
@@ -1,32 +1,32 @@
1
1
  <template>
2
- <UseImage v-bind="$props">
3
- <template #loading>
4
- <slot name="loading">
5
- <div
6
- class="flex h-full w-full items-center justify-center"
7
- >
8
- <Loader
9
- :loading="true"
10
- />
11
- </div>
12
- </slot>
13
- </template>
14
-
15
- <template #error>
16
- <slot name="error">
17
- <div
18
- class="flex h-full w-full items-center justify-center"
19
- >
20
- <p class="text-error-400">
21
- <Icon
22
- name="i-heroicons:exclamation-circle-solid"
23
- class="text-error-400 size-8"
24
- />
25
- </p>
26
- </div>
27
- </slot>
28
- </template>
29
- </UseImage>
2
+ <UseImage v-bind="$props">
3
+ <template #loading>
4
+ <slot name="loading">
5
+ <div
6
+ class="flex h-full w-full items-center justify-center"
7
+ >
8
+ <Loader
9
+ :loading="true"
10
+ />
11
+ </div>
12
+ </slot>
13
+ </template>
14
+
15
+ <template #error>
16
+ <slot name="error">
17
+ <div
18
+ class="flex h-full w-full items-center justify-center"
19
+ >
20
+ <p class="text-error-400">
21
+ <Icon
22
+ name="i-heroicons:exclamation-circle-solid"
23
+ class="text-error-400 size-8"
24
+ />
25
+ </p>
26
+ </div>
27
+ </slot>
28
+ </template>
29
+ </UseImage>
30
30
  </template>
31
31
 
32
32
  <script setup>
@@ -1,21 +1,21 @@
1
1
  <template>
2
- <DevOnly>
3
- <TeleportSafe
4
- to="#dev-logs"
5
- >
6
- <LogItem
7
- v-if="typeof data !== 'undefined'"
8
- :data="data"
9
- :title="title"
10
- />
11
- <LogItem
12
- v-for="(item, index) in dataItems"
13
- :key="index"
14
- :data="item"
15
- :title="`${title} #${index + 1}`"
16
- />
17
- </TeleportSafe>
18
- </DevOnly>
2
+ <DevOnly>
3
+ <TeleportSafe
4
+ to="#dev-logs"
5
+ >
6
+ <LogItem
7
+ v-if="typeof data !== 'undefined'"
8
+ :data="data"
9
+ :title="title"
10
+ />
11
+ <LogItem
12
+ v-for="(item, index) in dataItems"
13
+ :key="index"
14
+ :data="item"
15
+ :title="`${title} #${index + 1}`"
16
+ />
17
+ </TeleportSafe>
18
+ </DevOnly>
19
19
  </template>
20
20
 
21
21
  <script setup>
@@ -4,7 +4,7 @@ type __VLS_Props = {
4
4
  options: ITableOptions<any> & ISimpleTableOptions<any>;
5
5
  ui?: (typeof tableTheme)['slots'];
6
6
  };
7
- declare var __VLS_22: {}, __VLS_29: {}, __VLS_31: {}, __VLS_45: string | number, __VLS_46: any;
7
+ declare var __VLS_22: {}, __VLS_29: {}, __VLS_31: {}, __VLS_45: any, __VLS_46: any;
8
8
  type __VLS_Slots = {} & {
9
9
  [K in NonNullable<typeof __VLS_45>]?: (props: typeof __VLS_46) => any;
10
10
  } & {
@@ -14,13 +14,7 @@ type __VLS_Slots = {} & {
14
14
  } & {
15
15
  error?: (props: typeof __VLS_31) => any;
16
16
  };
17
- declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
18
- search: (...args: any[]) => void;
19
- pageChange: (...args: any[]) => void;
20
- }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
21
- onSearch?: ((...args: any[]) => any) | undefined;
22
- onPageChange?: ((...args: any[]) => any) | undefined;
23
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
17
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, any, string, import("vue").PublicProps, any, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
24
18
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
25
19
  declare const _default: typeof __VLS_export;
26
20
  export default _default;
@@ -4,7 +4,7 @@ type __VLS_Props = {
4
4
  options: ITableOptions<any> & ISimpleTableOptions<any>;
5
5
  ui?: (typeof tableTheme)['slots'];
6
6
  };
7
- declare var __VLS_22: {}, __VLS_29: {}, __VLS_31: {}, __VLS_45: string | number, __VLS_46: any;
7
+ declare var __VLS_22: {}, __VLS_29: {}, __VLS_31: {}, __VLS_45: any, __VLS_46: any;
8
8
  type __VLS_Slots = {} & {
9
9
  [K in NonNullable<typeof __VLS_45>]?: (props: typeof __VLS_46) => any;
10
10
  } & {
@@ -14,13 +14,7 @@ type __VLS_Slots = {} & {
14
14
  } & {
15
15
  error?: (props: typeof __VLS_31) => any;
16
16
  };
17
- declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
18
- search: (...args: any[]) => void;
19
- pageChange: (...args: any[]) => void;
20
- }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
21
- onSearch?: ((...args: any[]) => any) | undefined;
22
- onPageChange?: ((...args: any[]) => any) | undefined;
23
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
17
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, any, string, import("vue").PublicProps, any, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
24
18
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
25
19
  declare const _default: typeof __VLS_export;
26
20
  export default _default;
@@ -1,5 +1,5 @@
1
1
  <template>
2
- {{ getValue || "-" }}
2
+ {{ getValue || "-" }}
3
3
  </template>
4
4
 
5
5
  <script setup>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- {{ getValue || "-" }}
2
+ {{ getValue || "-" }}
3
3
  </template>
4
4
 
5
5
  <script setup>
@@ -1,8 +1,8 @@
1
1
  <template>
2
- <Image
3
- class="h-12 rounded"
4
- :src="getValue"
5
- />
2
+ <Image
3
+ class="h-12 rounded"
4
+ :src="getValue"
5
+ />
6
6
  </template>
7
7
 
8
8
  <script setup>
@@ -1,14 +1,14 @@
1
1
  <template>
2
- <NuxtLink
3
- v-if="column.meta?.link"
4
- v-bind="column.meta.link"
5
- >
6
- {{ getValue }}
7
- </NuxtLink>
8
-
9
- <span v-else>
10
- {{ getValue }}
11
- </span>
2
+ <NuxtLink
3
+ v-if="column.meta?.link"
4
+ v-bind="column.meta.link"
5
+ >
6
+ {{ getValue }}
7
+ </NuxtLink>
8
+
9
+ <span v-else>
10
+ {{ getValue }}
11
+ </span>
12
12
  </template>
13
13
 
14
14
  <script setup>