tantee-nuxt-commons 0.0.168 → 0.0.170

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
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": "^3.0.0"
6
6
  },
7
- "version": "0.0.168",
7
+ "version": "0.0.170",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "0.8.4",
10
10
  "unbuild": "2.0.0"
@@ -317,5 +317,5 @@ defineExpose({
317
317
  />
318
318
  </template>
319
319
  <style>
320
- .form-data-dirty,.form-data-dirty:not(.v-input--error) *{color:color-mix(in srgb,currentColor 70%,rgb(var(--v-theme-primary)))!important;text-shadow:0 0 .02em currentColor}
320
+ .form-data-dirty:not(.v-input--error) :not(.v-chip):not(.v-chip *){color:color-mix(in srgb,currentColor 70%,rgb(var(--v-theme-primary)))!important;text-shadow:0 0 .02em currentColor}
321
321
  </style>
@@ -2,7 +2,7 @@
2
2
  import { VueSignaturePad } from 'vue-signature-pad'
3
3
  import { VInput } from 'vuetify/components/VInput'
4
4
  import { ref, computed, withDefaults, defineProps, defineExpose, watch } from 'vue'
5
- import { useAssetFile, type Base64Asset } from '../../composables/assetFile'
5
+ import { useAssetFile, type Base64Asset, type Base64File } from '../../composables/assetFile'
6
6
 
7
7
  interface SignatureProps extends /* @vue-ignore */ InstanceType<typeof VInput['$props']> {
8
8
  title?: string
@@ -44,14 +44,7 @@ const imageDataUrl = computed(() => {
44
44
  const val = normalized.value
45
45
  if (!val?.base64String) return null
46
46
 
47
- const base = val.base64String.trim()
48
-
49
- if (base.startsWith("data:")) {
50
- return base
51
- }
52
-
53
- const mime = (val as Base64File).fileType || "image/png"
54
- return `data:${mime};base64,${base}`
47
+ return useAssetFile().ensureDataUrl(val.base64String.trim(),(val as Base64File).fileType || "image/png")
55
48
  })
56
49
 
57
50
 
@@ -2,7 +2,8 @@
2
2
  import { ref, watch } from 'vue'
3
3
  import { isEqual } from 'lodash-es'
4
4
  import { useAlert } from '../../../composables/alert'
5
- import { useAssetFile, type Base64Image, type Base64Asset } from '../../../composables/assetFile'
5
+ import {useAssetFile, type Base64Image, type Base64Asset, type Base64File} from '../../../composables/assetFile'
6
+ import {useRuntimeConfig} from "#imports";
6
7
 
7
8
  const emit = defineEmits<{
8
9
  (e: 'update:modelValue', value: Base64Image[]): void
@@ -17,11 +18,13 @@ interface Props {
17
18
  label?: string
18
19
  accept?: string
19
20
  autoHydrate?: boolean
21
+ maxFileSize?: number
20
22
  }
21
23
  const props = withDefaults(defineProps<Props>(), {
22
24
  modelValue: () => [] as Base64Image[],
23
25
  accept: '.jpg,.jpeg,.png,.webp,.gif,.bmp,.tiff,.tif',
24
26
  autoHydrate: false,
27
+ maxFileSize: 10,
25
28
  })
26
29
 
27
30
  /** Internal state (always Base64Image[]) */
@@ -35,7 +38,7 @@ const dataUpdate = ref<Base64Image>({ imageData: {}, imageTitle: '', imageProps:
35
38
 
36
39
  /** Fullscreen preview */
37
40
  const dialogImageFullScreen = ref(false)
38
- const imageFullScreen = ref({ title: '', image: '' })
41
+ const imageFullScreen = ref<{title: string,image: string|undefined}>({ title: '', image: '' })
39
42
 
40
43
  /** ---------- Stable keys + guards ---------- */
41
44
  let internalSync = false
@@ -90,23 +93,29 @@ const setDataUpdate = (img: Base64Image) => {
90
93
  dialogUpdate.value = true
91
94
  }
92
95
 
93
- const checkDuplicationName = (name: string) =>
94
- images.value.some(({ imageTitle }) => isEqual(imageTitle, name))
96
+ const checkDuplicationName = (name: string) => images.value.some(({ imageTitle }) => isEqual(imageTitle, name))
95
97
 
96
98
  const isImageDataUrl = (dataUrl: string) => /^data:image\//i.test(dataUrl)
97
99
 
100
+ const imageSrcFromImageData = (imageData: Base64Image) => {
101
+ let assetUrl = useRuntimeConfig().public.ASSET_URL as string
102
+ if (imageData?.imageData?.base64String) return useAssetFile().ensureDataUrl(imageData?.imageData?.base64String.trim(),(imageData?.imageData as Base64File).fileType || "image/png")
103
+ if (imageData?.imageData?.id) return (assetUrl || '/asset').replace(/\/+$/, '') +"/"+imageData?.imageData?.id
104
+ return undefined
105
+ }
106
+
98
107
  /** File → Base64Image using composable */
99
108
  const fileToBase64Image = async (file: File): Promise<Base64Image | null> => {
100
109
  try {
101
- const b64 = await fileToBase64(file)
102
- const dataUrl = b64.base64String || ''
110
+ const base64 = await fileToBase64(file,props.maxFileSize)
111
+ const dataUrl = base64.base64String || ''
103
112
  if (!isImageDataUrl(dataUrl)) {
104
- alert?.addAlert({ message: `ไฟล์ "${b64.fileName}" ไม่ใช่ไฟล์รูปภาพที่รองรับ`, alertType: 'error' })
113
+ alert?.addAlert({ message: `File "${base64.fileName}" is not supported image type.`, alertType: 'error' })
105
114
  return null
106
115
  }
107
116
  return {
108
117
  imageData: { base64String: dataUrl } as Base64Asset,
109
- imageTitle: b64.fileName,
118
+ imageTitle: base64.fileName,
110
119
  imageProps: {},
111
120
  }
112
121
  } catch (e: any) {
@@ -116,7 +125,7 @@ const fileToBase64Image = async (file: File): Promise<Base64Image | null> => {
116
125
  }
117
126
 
118
127
  /** Handle upload button update */
119
- const update = async () => {
128
+ const uploadImageFile = async () => {
120
129
  const duplicated: string[] = []
121
130
  for (const file of uploadImages.value) {
122
131
  if (checkDuplicationName(file.name)) {
@@ -128,7 +137,7 @@ const update = async () => {
128
137
  }
129
138
  uploadImages.value = []
130
139
  if (duplicated.length) {
131
- alert?.addAlert({ message: `ไม่สามารถอัพโหลดไฟล์ ${duplicated.join(', ')}`, alertType: 'error' })
140
+ alert?.addAlert({ message: `File(s) are duplicated. ${duplicated.join(', ')}`, alertType: 'error' })
132
141
  }
133
142
  }
134
143
 
@@ -139,7 +148,7 @@ const modelData = ref()
139
148
  const captureImage = (payload: any, cb: FormDialogCallback) => {
140
149
  const dataUrl: string = payload?.imageCapture ?? ''
141
150
  if (!dataUrl || !isImageDataUrl(dataUrl)) {
142
- alert?.addAlert({ message: 'รูปภาพไม่ถูกต้อง', alertType: 'error' })
151
+ alert?.addAlert({ message: 'Invalid image.', alertType: 'error' })
143
152
  return
144
153
  }
145
154
  addImage({
@@ -154,7 +163,7 @@ const captureImage = (payload: any, cb: FormDialogCallback) => {
154
163
  const openImageFullScreen = (img: Base64Image) => {
155
164
  dialogImageFullScreen.value = true
156
165
  imageFullScreen.value.title = img.imageTitle ?? ''
157
- imageFullScreen.value.image = img.imageData?.base64String ?? ''
166
+ imageFullScreen.value.image = imageSrcFromImageData(img)
158
167
  }
159
168
 
160
169
  /** ---------- Watchers (signature-based) ---------- */
@@ -217,7 +226,7 @@ watch(
217
226
  icon-only
218
227
  multiple
219
228
  variant="text"
220
- @update:model-value="update"
229
+ @update:model-value="uploadImageFile"
221
230
  />
222
231
  <v-btn color="primary" icon @click="dialog = true">
223
232
  <v-icon>mdi mdi-camera-plus</v-icon>
@@ -238,16 +247,16 @@ watch(
238
247
  <v-btn icon @click="remove(index)">
239
248
  <v-icon>mdi mdi-delete-outline</v-icon>
240
249
  </v-btn>
241
- <v-btn color="primary" icon @click="setDataUpdate(image)">
250
+ <v-btn color="primary" icon @click="setDataUpdate(image)" v-if="!image.imageData?.id">
242
251
  <v-icon>mdi mdi-image-edit-outline</v-icon>
243
252
  </v-btn>
244
253
  </VToolbarItems>
245
254
  </VToolbar>
246
255
 
247
256
  <v-img
248
- :src="image.imageData?.base64String"
257
+ :src="imageSrcFromImageData(image)"
249
258
  height="250"
250
- @click="() => { props.readonly ? openImageFullScreen(image) : setDataUpdate(image) }"
259
+ @click="() => { (props.readonly || image.imageData?.id) ? openImageFullScreen(image) : setDataUpdate(image) }"
251
260
  />
252
261
  </VCard>
253
262
  </VCol>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tantee-nuxt-commons",
3
- "version": "0.0.168",
3
+ "version": "0.0.170",
4
4
  "description": "Ramathibodi Nuxt modules for common components",
5
5
  "repository": {
6
6
  "type": "git",