@ramathibodi/nuxt-commons 0.1.74 → 4.0.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.
Files changed (243) hide show
  1. package/README.md +9 -2
  2. package/dist/module.json +4 -4
  3. package/dist/module.mjs +4 -4
  4. package/dist/runtime/bridges/authentication.d.ts +21 -0
  5. package/dist/runtime/bridges/authentication.js +20 -0
  6. package/dist/runtime/bridges/graphql.d.ts +17 -0
  7. package/dist/runtime/bridges/graphql.js +45 -0
  8. package/dist/runtime/components/Alert.d.vue.ts +3 -0
  9. package/dist/runtime/components/Alert.vue +17 -26
  10. package/dist/runtime/components/Alert.vue.d.ts +3 -0
  11. package/dist/runtime/components/BarcodeReader.d.vue.ts +9 -0
  12. package/dist/runtime/components/BarcodeReader.vue +56 -81
  13. package/dist/runtime/components/BarcodeReader.vue.d.ts +9 -0
  14. package/dist/runtime/components/ExportCSV.d.vue.ts +55 -0
  15. package/dist/runtime/components/ExportCSV.vue +39 -76
  16. package/dist/runtime/components/ExportCSV.vue.d.ts +55 -0
  17. package/dist/runtime/components/FileBtn.d.vue.ts +53 -0
  18. package/dist/runtime/components/FileBtn.vue +23 -50
  19. package/dist/runtime/components/FileBtn.vue.d.ts +53 -0
  20. package/dist/runtime/components/ImportCSV.d.vue.ts +52 -0
  21. package/dist/runtime/components/ImportCSV.vue +60 -111
  22. package/dist/runtime/components/ImportCSV.vue.d.ts +52 -0
  23. package/dist/runtime/components/MrzReader.d.vue.ts +19 -0
  24. package/dist/runtime/components/MrzReader.vue +69 -109
  25. package/dist/runtime/components/MrzReader.vue.d.ts +19 -0
  26. package/dist/runtime/components/SplitterPanel.d.vue.ts +15 -0
  27. package/dist/runtime/components/SplitterPanel.vue +18 -35
  28. package/dist/runtime/components/SplitterPanel.vue.d.ts +15 -0
  29. package/dist/runtime/components/TabsGroup.d.vue.ts +19 -0
  30. package/dist/runtime/components/TabsGroup.vue +8 -20
  31. package/dist/runtime/components/TabsGroup.vue.d.ts +19 -0
  32. package/dist/runtime/components/TextBarcode.d.vue.ts +12 -0
  33. package/dist/runtime/components/TextBarcode.vue +22 -45
  34. package/dist/runtime/components/TextBarcode.vue.d.ts +12 -0
  35. package/dist/runtime/components/device/IdCardButton.d.vue.ts +57 -0
  36. package/dist/runtime/components/device/IdCardButton.vue +30 -67
  37. package/dist/runtime/components/device/IdCardButton.vue.d.ts +57 -0
  38. package/dist/runtime/components/device/IdCardWebSocket.d.vue.ts +55 -0
  39. package/dist/runtime/components/device/IdCardWebSocket.vue +104 -165
  40. package/dist/runtime/components/device/IdCardWebSocket.vue.d.ts +55 -0
  41. package/dist/runtime/components/device/Scanner.d.vue.ts +66 -0
  42. package/dist/runtime/components/device/Scanner.vue +97 -178
  43. package/dist/runtime/components/device/Scanner.vue.d.ts +66 -0
  44. package/dist/runtime/components/dialog/Confirm.d.vue.ts +37 -0
  45. package/dist/runtime/components/dialog/Confirm.vue +30 -59
  46. package/dist/runtime/components/dialog/Confirm.vue.d.ts +37 -0
  47. package/dist/runtime/components/dialog/Host.d.vue.ts +9 -0
  48. package/dist/runtime/components/dialog/Host.vue +34 -57
  49. package/dist/runtime/components/dialog/Host.vue.d.ts +9 -0
  50. package/dist/runtime/components/dialog/Index.d.vue.ts +24 -0
  51. package/dist/runtime/components/dialog/Index.vue +20 -40
  52. package/dist/runtime/components/dialog/Index.vue.d.ts +24 -0
  53. package/dist/runtime/components/dialog/Loading.d.vue.ts +21 -0
  54. package/dist/runtime/components/dialog/Loading.vue +12 -29
  55. package/dist/runtime/components/dialog/Loading.vue.d.ts +21 -0
  56. package/dist/runtime/components/dialog/default/Confirm.d.vue.ts +40 -0
  57. package/dist/runtime/components/dialog/default/Confirm.vue +29 -62
  58. package/dist/runtime/components/dialog/default/Confirm.vue.d.ts +40 -0
  59. package/dist/runtime/components/dialog/default/Loading.d.vue.ts +23 -0
  60. package/dist/runtime/components/dialog/default/Loading.vue +12 -29
  61. package/dist/runtime/components/dialog/default/Loading.vue.d.ts +23 -0
  62. package/dist/runtime/components/dialog/default/Notify.d.vue.ts +23 -0
  63. package/dist/runtime/components/dialog/default/Notify.vue +19 -48
  64. package/dist/runtime/components/dialog/default/Notify.vue.d.ts +23 -0
  65. package/dist/runtime/components/dialog/default/Printing.d.vue.ts +21 -0
  66. package/dist/runtime/components/dialog/default/Printing.vue +13 -29
  67. package/dist/runtime/components/dialog/default/Printing.vue.d.ts +21 -0
  68. package/dist/runtime/components/dialog/default/VerifyUser.d.vue.ts +29 -0
  69. package/dist/runtime/components/dialog/default/VerifyUser.vue +44 -82
  70. package/dist/runtime/components/dialog/default/VerifyUser.vue.d.ts +29 -0
  71. package/dist/runtime/components/document/Form.d.vue.ts +9 -0
  72. package/dist/runtime/components/document/Form.vue +27 -42
  73. package/dist/runtime/components/document/Form.vue.d.ts +9 -0
  74. package/dist/runtime/components/document/TemplateBuilder.d.vue.ts +24 -0
  75. package/dist/runtime/components/document/TemplateBuilder.vue +154 -194
  76. package/dist/runtime/components/document/TemplateBuilder.vue.d.ts +24 -0
  77. package/dist/runtime/components/form/ActionPad.d.vue.ts +114 -0
  78. package/dist/runtime/components/form/ActionPad.vue +48 -85
  79. package/dist/runtime/components/form/ActionPad.vue.d.ts +114 -0
  80. package/dist/runtime/components/form/Birthdate.d.vue.ts +38 -0
  81. package/dist/runtime/components/form/Birthdate.vue +44 -76
  82. package/dist/runtime/components/form/Birthdate.vue.d.ts +38 -0
  83. package/dist/runtime/components/form/CheckboxGroup.d.vue.ts +41 -0
  84. package/dist/runtime/components/form/CheckboxGroup.vue +34 -64
  85. package/dist/runtime/components/form/CheckboxGroup.vue.d.ts +41 -0
  86. package/dist/runtime/components/form/CodeEditor.d.vue.ts +25 -0
  87. package/dist/runtime/components/form/CodeEditor.vue +18 -36
  88. package/dist/runtime/components/form/CodeEditor.vue.d.ts +25 -0
  89. package/dist/runtime/components/form/Date.d.vue.ts +86 -0
  90. package/dist/runtime/components/form/Date.vue +109 -162
  91. package/dist/runtime/components/form/Date.vue.d.ts +86 -0
  92. package/dist/runtime/components/form/DateTime.d.vue.ts +36 -0
  93. package/dist/runtime/components/form/DateTime.vue +94 -143
  94. package/dist/runtime/components/form/DateTime.vue.d.ts +36 -0
  95. package/dist/runtime/components/form/Dialog.d.vue.ts +69 -0
  96. package/dist/runtime/components/form/Dialog.vue +60 -96
  97. package/dist/runtime/components/form/Dialog.vue.d.ts +69 -0
  98. package/dist/runtime/components/form/EditPad.d.vue.ts +113 -0
  99. package/dist/runtime/components/form/EditPad.vue +49 -85
  100. package/dist/runtime/components/form/EditPad.vue.d.ts +113 -0
  101. package/dist/runtime/components/form/File.d.vue.ts +65 -0
  102. package/dist/runtime/components/form/File.vue +112 -186
  103. package/dist/runtime/components/form/File.vue.d.ts +65 -0
  104. package/dist/runtime/components/form/Hidden.d.vue.ts +12 -0
  105. package/dist/runtime/components/form/Hidden.vue +17 -34
  106. package/dist/runtime/components/form/Hidden.vue.d.ts +12 -0
  107. package/dist/runtime/components/form/Iterator.d.vue.ts +279 -0
  108. package/dist/runtime/components/form/Iterator.vue +162 -252
  109. package/dist/runtime/components/form/Iterator.vue.d.ts +279 -0
  110. package/dist/runtime/components/form/Login.d.vue.ts +32 -0
  111. package/dist/runtime/components/form/Login.vue +23 -55
  112. package/dist/runtime/components/form/Login.vue.d.ts +32 -0
  113. package/dist/runtime/components/form/Pad.d.vue.ts +674 -0
  114. package/dist/runtime/components/form/Pad.vue +166 -265
  115. package/dist/runtime/components/form/Pad.vue.d.ts +674 -0
  116. package/dist/runtime/components/form/SignPad.d.vue.ts +62 -0
  117. package/dist/runtime/components/form/SignPad.vue +80 -126
  118. package/dist/runtime/components/form/SignPad.vue.d.ts +62 -0
  119. package/dist/runtime/components/form/System.d.vue.ts +34 -0
  120. package/dist/runtime/components/form/System.vue +18 -32
  121. package/dist/runtime/components/form/System.vue.d.ts +34 -0
  122. package/dist/runtime/components/form/Table.d.vue.ts +221 -0
  123. package/dist/runtime/components/form/Table.vue +123 -182
  124. package/dist/runtime/components/form/Table.vue.d.ts +221 -0
  125. package/dist/runtime/components/form/TableData.d.vue.ts +102 -0
  126. package/dist/runtime/components/form/TableData.vue +109 -139
  127. package/dist/runtime/components/form/TableData.vue.d.ts +102 -0
  128. package/dist/runtime/components/form/Time.d.vue.ts +49 -0
  129. package/dist/runtime/components/form/Time.vue +64 -99
  130. package/dist/runtime/components/form/Time.vue.d.ts +49 -0
  131. package/dist/runtime/components/form/images/Capture.d.vue.ts +96 -0
  132. package/dist/runtime/components/form/images/Capture.vue +104 -147
  133. package/dist/runtime/components/form/images/Capture.vue.d.ts +96 -0
  134. package/dist/runtime/components/form/images/Edit.d.vue.ts +29 -0
  135. package/dist/runtime/components/form/images/Edit.vue +57 -81
  136. package/dist/runtime/components/form/images/Edit.vue.d.ts +29 -0
  137. package/dist/runtime/components/form/images/Field.d.vue.ts +27 -0
  138. package/dist/runtime/components/form/images/Field.vue +136 -205
  139. package/dist/runtime/components/form/images/Field.vue.d.ts +27 -0
  140. package/dist/runtime/components/form/images/Pad.d.vue.ts +13 -0
  141. package/dist/runtime/components/form/images/Pad.vue +23 -40
  142. package/dist/runtime/components/form/images/Pad.vue.d.ts +13 -0
  143. package/dist/runtime/components/label/Date.d.vue.ts +13 -0
  144. package/dist/runtime/components/label/Date.vue +13 -29
  145. package/dist/runtime/components/label/Date.vue.d.ts +13 -0
  146. package/dist/runtime/components/label/DateAgo.d.vue.ts +20 -0
  147. package/dist/runtime/components/label/DateAgo.vue +43 -75
  148. package/dist/runtime/components/label/DateAgo.vue.d.ts +20 -0
  149. package/dist/runtime/components/label/DateCount.d.vue.ts +22 -0
  150. package/dist/runtime/components/label/DateCount.vue +58 -105
  151. package/dist/runtime/components/label/DateCount.vue.d.ts +22 -0
  152. package/dist/runtime/components/label/Field.d.vue.ts +38 -0
  153. package/dist/runtime/components/label/Field.vue +18 -40
  154. package/dist/runtime/components/label/Field.vue.d.ts +38 -0
  155. package/dist/runtime/components/label/FormatMoney.d.vue.ts +12 -0
  156. package/dist/runtime/components/label/FormatMoney.vue +12 -28
  157. package/dist/runtime/components/label/FormatMoney.vue.d.ts +12 -0
  158. package/dist/runtime/components/label/Mask.d.vue.ts +10 -0
  159. package/dist/runtime/components/label/Mask.vue +21 -38
  160. package/dist/runtime/components/label/Mask.vue.d.ts +10 -0
  161. package/dist/runtime/components/label/Object.d.vue.ts +8 -0
  162. package/dist/runtime/components/label/Object.vue +10 -20
  163. package/dist/runtime/components/label/Object.vue.d.ts +8 -0
  164. package/dist/runtime/components/master/Autocomplete.d.vue.ts +70 -0
  165. package/dist/runtime/components/master/Autocomplete.vue +25 -34
  166. package/dist/runtime/components/master/Autocomplete.vue.d.ts +70 -0
  167. package/dist/runtime/components/master/Combobox.d.vue.ts +70 -0
  168. package/dist/runtime/components/master/Combobox.vue +26 -35
  169. package/dist/runtime/components/master/Combobox.vue.d.ts +70 -0
  170. package/dist/runtime/components/master/RadioGroup.d.vue.ts +51 -0
  171. package/dist/runtime/components/master/RadioGroup.vue +44 -59
  172. package/dist/runtime/components/master/RadioGroup.vue.d.ts +51 -0
  173. package/dist/runtime/components/master/Select.d.vue.ts +68 -0
  174. package/dist/runtime/components/master/Select.vue +25 -34
  175. package/dist/runtime/components/master/Select.vue.d.ts +68 -0
  176. package/dist/runtime/components/master/label.d.vue.ts +24 -0
  177. package/dist/runtime/components/master/label.vue +22 -42
  178. package/dist/runtime/components/master/label.vue.d.ts +24 -0
  179. package/dist/runtime/components/model/Autocomplete.d.vue.ts +82 -0
  180. package/dist/runtime/components/model/Autocomplete.vue +50 -49
  181. package/dist/runtime/components/model/Autocomplete.vue.d.ts +82 -0
  182. package/dist/runtime/components/model/Combobox.d.vue.ts +82 -0
  183. package/dist/runtime/components/model/Combobox.vue +51 -49
  184. package/dist/runtime/components/model/Combobox.vue.d.ts +82 -0
  185. package/dist/runtime/components/model/Pad.d.vue.ts +72 -0
  186. package/dist/runtime/components/model/Pad.vue +50 -65
  187. package/dist/runtime/components/model/Pad.vue.d.ts +72 -0
  188. package/dist/runtime/components/model/Select.d.vue.ts +72 -0
  189. package/dist/runtime/components/model/Select.vue +42 -44
  190. package/dist/runtime/components/model/Select.vue.d.ts +72 -0
  191. package/dist/runtime/components/model/Table.d.vue.ts +272 -0
  192. package/dist/runtime/components/model/Table.vue +121 -145
  193. package/dist/runtime/components/model/Table.vue.d.ts +272 -0
  194. package/dist/runtime/components/model/iterator.d.vue.ts +321 -0
  195. package/dist/runtime/components/model/iterator.vue +148 -183
  196. package/dist/runtime/components/model/iterator.vue.d.ts +321 -0
  197. package/dist/runtime/components/model/label.d.vue.ts +26 -0
  198. package/dist/runtime/components/model/label.vue +25 -43
  199. package/dist/runtime/components/model/label.vue.d.ts +26 -0
  200. package/dist/runtime/components/pdf/Print.d.vue.ts +17 -0
  201. package/dist/runtime/components/pdf/Print.vue +27 -50
  202. package/dist/runtime/components/pdf/Print.vue.d.ts +17 -0
  203. package/dist/runtime/components/pdf/View.d.vue.ts +52 -0
  204. package/dist/runtime/components/pdf/View.vue +58 -95
  205. package/dist/runtime/components/pdf/View.vue.d.ts +52 -0
  206. package/dist/runtime/composables/api.js +4 -2
  207. package/dist/runtime/composables/assetFile.js +4 -2
  208. package/dist/runtime/composables/dialog.d.ts +1 -1
  209. package/dist/runtime/composables/document/template.js +3 -3
  210. package/dist/runtime/composables/document/templateFormTable.js +1 -0
  211. package/dist/runtime/composables/graphql.d.ts +2 -2
  212. package/dist/runtime/composables/graphql.js +5 -5
  213. package/dist/runtime/composables/graphqlModel.d.ts +6 -6
  214. package/dist/runtime/composables/graphqlModelItem.d.ts +4 -4
  215. package/dist/runtime/composables/graphqlModelOperation.d.ts +6 -6
  216. package/dist/runtime/composables/graphqlModelOperation.js +2 -1
  217. package/dist/runtime/composables/graphqlOperation.js +5 -1
  218. package/dist/runtime/composables/hostAgentWs.d.ts +1 -1
  219. package/dist/runtime/composables/lookupListMaster.js +3 -3
  220. package/dist/runtime/composables/menu.js +2 -2
  221. package/dist/runtime/composables/userPermission.d.ts +1 -1
  222. package/dist/runtime/composables/utils/fuzzy.d.ts +2 -1
  223. package/dist/runtime/labs/Calendar.d.vue.ts +35 -0
  224. package/dist/runtime/labs/Calendar.vue +47 -75
  225. package/dist/runtime/labs/Calendar.vue.d.ts +35 -0
  226. package/dist/runtime/labs/form/EditMobile.d.vue.ts +12 -0
  227. package/dist/runtime/labs/form/EditMobile.vue +19 -36
  228. package/dist/runtime/labs/form/EditMobile.vue.d.ts +12 -0
  229. package/dist/runtime/labs/form/TextFieldMask.d.vue.ts +21 -0
  230. package/dist/runtime/labs/form/TextFieldMask.vue +19 -25
  231. package/dist/runtime/labs/form/TextFieldMask.vue.d.ts +21 -0
  232. package/dist/runtime/plugins/dialogManager.js +2 -2
  233. package/dist/runtime/plugins/permission.js +3 -3
  234. package/dist/runtime/types/bridge.d.ts +14 -0
  235. package/dist/runtime/utils/datetime.js +1 -1
  236. package/dist/types.d.mts +2 -6
  237. package/package.json +71 -58
  238. package/scripts/ci-release.mjs +125 -0
  239. package/scripts/release-version.mjs +68 -0
  240. package/scripts/release.mjs +49 -0
  241. package/dist/module.cjs +0 -5
  242. package/dist/module.d.ts +0 -8
  243. package/dist/types.d.ts +0 -7
@@ -0,0 +1,27 @@
1
+ import { type Base64Image } from '../../../composables/assetFile.js';
2
+ interface Props {
3
+ modelValue?: Base64Image[];
4
+ readonly?: boolean;
5
+ label?: string;
6
+ accept?: string;
7
+ autoHydrate?: boolean;
8
+ maxFileSize?: number;
9
+ }
10
+ declare const __VLS_export: import("vue").DefineComponent<Props, {
11
+ errorMessages: import("vue").ComputedRef<(string & string[]) | (readonly string[] & string[]) | undefined>;
12
+ isValid: import("vue").ComputedRef<boolean | null | undefined>;
13
+ reset: () => Promise<void> | undefined;
14
+ resetValidation: () => Promise<void> | undefined;
15
+ validate: () => Promise<string[]> | undefined;
16
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
17
+ "update:modelValue": (value: Base64Image[]) => any;
18
+ }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
19
+ "onUpdate:modelValue"?: ((value: Base64Image[]) => any) | undefined;
20
+ }>, {
21
+ modelValue: Base64Image[];
22
+ accept: string;
23
+ autoHydrate: boolean;
24
+ maxFileSize: number;
25
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
26
+ declare const _default: typeof __VLS_export;
27
+ export default _default;
@@ -1,241 +1,171 @@
1
- <script lang="ts" setup>
2
- /**
3
- * FormImagesField handles image capture, editing, preview, and value synchronization for schema-driven form image fields.
4
- * This doc block is consumed by vue-docgen for generated API documentation.
5
- */
6
- import { ref, watch,computed } from 'vue'
7
- import { isEqual } from 'lodash-es'
8
- import { VInput } from 'vuetify/components/VInput'
9
- import { assetUrl } from '#imports'
10
- import { useAlert } from '../../../composables/alert'
11
- import { useAssetFile, type Base64Image, type Base64Asset, type Base64File} from '../../../composables/assetFile'
12
-
13
- /**
14
- * Custom events emitted by FormImagesField.
15
- * Parents can listen to these events to react to user actions and internal state changes.
16
- */
17
- const emit = defineEmits<{
18
- (e: 'update:modelValue', value: Base64Image[]): void
19
- }>()
20
-
21
- const alert = useAlert()
22
- const { fileToBase64, hydrateAssetFile } = useAssetFile()
23
-
24
- interface Props {
25
- modelValue?: Base64Image[] // Bound value for v-model synchronization with the parent component.
26
- readonly?: boolean // renders as read-only while keeping value visible
27
- label?: string // UI label displayed to end users
28
- accept?: string // Accepted file MIME types or extensions for file selection.
29
- autoHydrate?: boolean // Converts incoming serialized values into component runtime format on mount/watch.
30
- maxFileSize?: number // Maximum allowed image file size in MB before conversion.
31
- }
32
- /**
33
- * Public props accepted by FormImagesField.
34
- * Document each prop field with intent, defaults, and side effects for clear generated docs.
35
- */
36
- const props = withDefaults(defineProps<Props>(), {
37
- modelValue: () => [] as Base64Image[],
38
- accept: '.jpg,.jpeg,.png,.webp,.gif,.bmp,.tiff,.tif',
39
- autoHydrate: false,
40
- maxFileSize: 10,
41
- })
42
-
43
- /** Internal state (always Base64Image[]) */
44
- const images = ref<Base64Image[]>([])
45
- const uploadImages = ref<File[]>([])
46
-
47
- /** Dialogs */
48
- const dialog = ref(false) // capture dialog
49
- const dialogUpdate = ref(false) // edit dialog
50
- const dataUpdate = ref<Base64Image>({ imageData: {}, imageTitle: '', imageProps: {} })
51
-
52
- /** Fullscreen preview */
53
- const dialogImageFullScreen = ref(false)
54
- const imageFullScreen = ref<{title: string,image: string|undefined}>({ title: '', image: '' })
55
-
56
- /** ---------- Stable keys + guards ---------- */
57
- let internalSync = false
58
- let lastEmittedSig = '' // signature of last emitted state
59
-
60
- function imageKey(im: Base64Image): string {
61
- const id = im.imageData?.id
62
- if (id != null) return `id:${id}`
63
- const title = im.imageTitle ?? ''
64
- const len = im.imageData?.base64String?.length ?? 0
65
- return `t:${title}|l:${len}`
1
+ <script setup>
2
+ import { ref, watch, computed } from "vue";
3
+ import { isEqual } from "lodash-es";
4
+ import { VInput } from "vuetify/components/VInput";
5
+ import { assetUrl } from "#imports";
6
+ import { useAlert } from "../../../composables/alert";
7
+ import { useAssetFile } from "../../../composables/assetFile";
8
+ const emit = defineEmits(["update:modelValue"]);
9
+ const alert = useAlert();
10
+ const { fileToBase64, hydrateAssetFile } = useAssetFile();
11
+ const props = defineProps({
12
+ modelValue: { type: Array, required: false, default: () => [] },
13
+ readonly: { type: Boolean, required: false },
14
+ label: { type: String, required: false },
15
+ accept: { type: String, required: false, default: ".jpg,.jpeg,.png,.webp,.gif,.bmp,.tiff,.tif" },
16
+ autoHydrate: { type: Boolean, required: false, default: false },
17
+ maxFileSize: { type: Number, required: false, default: 10 }
18
+ });
19
+ const images = ref([]);
20
+ const uploadImages = ref([]);
21
+ const dialog = ref(false);
22
+ const dialogUpdate = ref(false);
23
+ const dataUpdate = ref({ imageData: {}, imageTitle: "", imageProps: {} });
24
+ const dialogImageFullScreen = ref(false);
25
+ const imageFullScreen = ref({ title: "", image: "" });
26
+ let internalSync = false;
27
+ let lastEmittedSig = "";
28
+ function imageKey(im) {
29
+ const id = im.imageData?.id;
30
+ if (id != null) return `id:${id}`;
31
+ const title = im.imageTitle ?? "";
32
+ const len = im.imageData?.base64String?.length ?? 0;
33
+ return `t:${title}|l:${len}`;
66
34
  }
67
-
68
- function signature(arr: Base64Image[]): string {
69
- return arr.map(imageKey).join('|')
35
+ function signature(arr) {
36
+ return arr.map(imageKey).join("|");
70
37
  }
71
-
72
- /** Emit helper (guarded + updates last signature) */
73
- function emitNow(next: Base64Image[]) {
74
- const sig = signature(next)
75
- if (sig === lastEmittedSig) return
76
- internalSync = true
38
+ function emitNow(next) {
39
+ const sig = signature(next);
40
+ if (sig === lastEmittedSig) return;
41
+ internalSync = true;
77
42
  try {
78
- emit('update:modelValue', next)
79
- lastEmittedSig = sig
43
+ emit("update:modelValue", next);
44
+ lastEmittedSig = sig;
80
45
  } finally {
81
- queueMicrotask(() => { internalSync = false })
46
+ queueMicrotask(() => {
47
+ internalSync = false;
48
+ });
82
49
  }
83
50
  }
84
-
85
- /** ---------- Helpers ---------- */
86
-
87
- const addImage = (img: Base64Image) => {
51
+ const addImage = (img) => {
88
52
  images.value.push({
89
53
  imageData: img.imageData ?? {},
90
- imageTitle: img.imageTitle ?? '',
91
- imageProps: img.imageProps ?? {},
92
- })
93
- dialog.value = false
94
- }
95
-
96
- const remove = (index: number) => {
97
- images.value.splice(index, 1)
98
- }
99
-
100
- const setDataUpdate = (img: Base64Image) => {
54
+ imageTitle: img.imageTitle ?? "",
55
+ imageProps: img.imageProps ?? {}
56
+ });
57
+ dialog.value = false;
58
+ };
59
+ const remove = (index) => {
60
+ images.value.splice(index, 1);
61
+ };
62
+ const setDataUpdate = (img) => {
101
63
  dataUpdate.value = {
102
- imageData: { ...(img.imageData ?? {}) },
103
- imageTitle: img.imageTitle ?? '',
104
- imageProps: { ...(img.imageProps ?? {}) },
105
- }
106
- dialogUpdate.value = true
107
- }
108
-
109
- const checkDuplicationName = (name: string) => images.value.some(({ imageTitle }) => isEqual(imageTitle, name))
110
-
111
- const isImageDataUrl = (dataUrl: string) => /^data:image\//i.test(dataUrl)
112
-
113
- const imageSrcFromImageData = (imageData: Base64Image) => {
114
- if (imageData?.imageData?.base64String) return useAssetFile().ensureDataUrl(imageData?.imageData?.base64String.trim(),(imageData?.imageData as Base64File).fileType || "image/png")
115
- if (imageData?.imageData?.id != null) return assetUrl(imageData.imageData.id)
116
- return undefined
117
- }
118
-
119
- /** File → Base64Image using composable */
120
- const fileToBase64Image = async (file: File): Promise<Base64Image | null> => {
64
+ imageData: { ...img.imageData ?? {} },
65
+ imageTitle: img.imageTitle ?? "",
66
+ imageProps: { ...img.imageProps ?? {} }
67
+ };
68
+ dialogUpdate.value = true;
69
+ };
70
+ const checkDuplicationName = (name) => images.value.some(({ imageTitle }) => isEqual(imageTitle, name));
71
+ const isImageDataUrl = (dataUrl) => /^data:image\//i.test(dataUrl);
72
+ const imageSrcFromImageData = (imageData) => {
73
+ if (imageData?.imageData?.base64String) return useAssetFile().ensureDataUrl(imageData?.imageData?.base64String.trim(), (imageData?.imageData).fileType || "image/png");
74
+ if (imageData?.imageData?.id != null) return assetUrl(imageData.imageData.id);
75
+ return void 0;
76
+ };
77
+ const fileToBase64Image = async (file) => {
121
78
  try {
122
- const base64 = await fileToBase64(file,props.maxFileSize)
123
- const dataUrl = base64.base64String || ''
79
+ const base64 = await fileToBase64(file, props.maxFileSize);
80
+ const dataUrl = base64.base64String || "";
124
81
  if (!isImageDataUrl(dataUrl)) {
125
- alert?.addAlert({ message: `File "${base64.fileName}" is not supported image type.`, alertType: 'error' })
126
- return null
82
+ alert?.addAlert({ message: `File "${base64.fileName}" is not supported image type.`, alertType: "error" });
83
+ return null;
127
84
  }
128
85
  return {
129
- imageData: { base64String: dataUrl } as Base64Asset,
86
+ imageData: { base64String: dataUrl },
130
87
  imageTitle: base64.fileName,
131
- imageProps: {},
132
- }
133
- } catch (e: any) {
134
- alert?.addAlert({ message: String(e), alertType: 'error' })
135
- return null
88
+ imageProps: {}
89
+ };
90
+ } catch (e) {
91
+ alert?.addAlert({ message: String(e), alertType: "error" });
92
+ return null;
136
93
  }
137
- }
138
-
139
- /** Handle upload button update */
94
+ };
140
95
  const uploadImageFile = async () => {
141
- const duplicated: string[] = []
96
+ const duplicated = [];
142
97
  for (const file of uploadImages.value) {
143
98
  if (checkDuplicationName(file.name)) {
144
- duplicated.push(file.name)
145
- continue
99
+ duplicated.push(file.name);
100
+ continue;
146
101
  }
147
- const base64Image = await fileToBase64Image(file)
148
- if (base64Image) addImage(base64Image)
102
+ const base64Image = await fileToBase64Image(file);
103
+ if (base64Image) addImage(base64Image);
149
104
  }
150
- uploadImages.value = []
105
+ uploadImages.value = [];
151
106
  if (duplicated.length) {
152
- alert?.addAlert({ message: `File(s) are duplicated. ${duplicated.join(', ')}`, alertType: 'error' })
107
+ alert?.addAlert({ message: `File(s) are duplicated. ${duplicated.join(", ")}`, alertType: "error" });
153
108
  }
154
- }
155
-
156
- /** Capture flow (FormDialog) */
157
- type FormDialogCallback = { done: () => void }
158
- const modelData = ref()
159
-
160
- const captureImage = (payload: any, cb: FormDialogCallback) => {
161
- const dataUrl: string = payload?.imageCapture ?? ''
109
+ };
110
+ const modelData = ref();
111
+ const captureImage = (payload, cb) => {
112
+ const dataUrl = payload?.imageCapture ?? "";
162
113
  if (!dataUrl || !isImageDataUrl(dataUrl)) {
163
- alert?.addAlert({ message: 'Invalid image.', alertType: 'error' })
164
- return
114
+ alert?.addAlert({ message: "Invalid image.", alertType: "error" });
115
+ return;
165
116
  }
166
117
  addImage({
167
118
  imageData: { base64String: dataUrl },
168
119
  imageTitle: Math.random().toString(36).slice(2, 11),
169
- imageProps: {},
170
- })
171
- cb?.done?.()
172
- }
173
-
174
- /** Fullscreen preview */
175
- const openImageFullScreen = (img: Base64Image) => {
176
- dialogImageFullScreen.value = true
177
- imageFullScreen.value.title = img.imageTitle ?? ''
178
- imageFullScreen.value.image = imageSrcFromImageData(img)
179
- }
180
-
181
- /** ---------- Watchers (signature-based) ---------- */
182
-
183
- /* Parent → Internal */
120
+ imageProps: {}
121
+ });
122
+ cb?.done?.();
123
+ };
124
+ const openImageFullScreen = (img) => {
125
+ dialogImageFullScreen.value = true;
126
+ imageFullScreen.value.title = img.imageTitle ?? "";
127
+ imageFullScreen.value.image = imageSrcFromImageData(img);
128
+ };
184
129
  watch(
185
- () => props.modelValue,
186
- async (val) => {
187
- if (internalSync) return
188
-
189
- const next = Array.isArray(val) ? [...val] : []
190
- const nextSig = signature(next)
191
-
192
- // Only reassign when truly different
193
- if (nextSig !== signature(images.value)) {
194
- images.value = next
195
-
196
- // optional hydration
197
- if (props.autoHydrate && images.value.length) {
198
- const targets = images.value.filter(
199
- (im) => im.imageData?.id != null && !im.imageData?.base64String
200
- )
201
- if (targets.length) {
202
- await Promise.allSettled(targets.map((im) => hydrateAssetFile(im.imageData!)))
203
- // After hydration, emit once (guarded) to update parent
204
- emitNow(images.value)
205
- }
130
+ () => props.modelValue,
131
+ async (val) => {
132
+ if (internalSync) return;
133
+ const next = Array.isArray(val) ? [...val] : [];
134
+ const nextSig = signature(next);
135
+ if (nextSig !== signature(images.value)) {
136
+ images.value = next;
137
+ if (props.autoHydrate && images.value.length) {
138
+ const targets = images.value.filter(
139
+ (im) => im.imageData?.id != null && !im.imageData?.base64String
140
+ );
141
+ if (targets.length) {
142
+ await Promise.allSettled(targets.map((im) => hydrateAssetFile(im.imageData)));
143
+ emitNow(images.value);
206
144
  }
207
-
208
- // sync lastEmittedSig to current internal state so next local change emits
209
- lastEmittedSig = signature(images.value)
210
145
  }
211
- },
212
- { deep: true, immediate: true }
213
- )
214
-
215
- /* Internal → Parent: watch the signature instead of deep structure */
146
+ lastEmittedSig = signature(images.value);
147
+ }
148
+ },
149
+ { deep: true, immediate: true }
150
+ );
216
151
  watch(
217
- () => signature(images.value),
218
- () => {
219
- if (internalSync) return
220
- // Only emit when signature actually changes
221
- emitNow(images.value)
222
- },
223
- { immediate: false }
224
- )
225
-
226
- // validation passthrough
227
- const inputRef = ref<InstanceType<typeof VInput> | null>(null)
228
-
229
- const isValid = computed(() => inputRef.value?.isValid)
230
- const errorMessages = computed(() => inputRef.value?.errorMessages)
231
-
152
+ () => signature(images.value),
153
+ () => {
154
+ if (internalSync) return;
155
+ emitNow(images.value);
156
+ },
157
+ { immediate: false }
158
+ );
159
+ const inputRef = ref(null);
160
+ const isValid = computed(() => inputRef.value?.isValid);
161
+ const errorMessages = computed(() => inputRef.value?.errorMessages);
232
162
  defineExpose({
233
163
  errorMessages,
234
164
  isValid,
235
165
  reset: () => inputRef.value?.reset(),
236
166
  resetValidation: () => inputRef.value?.resetValidation(),
237
- validate: () => inputRef.value?.validate(),
238
- })
167
+ validate: () => inputRef.value?.validate()
168
+ });
239
169
  </script>
240
170
 
241
171
  <template>
@@ -267,7 +197,7 @@ defineExpose({
267
197
  </VToolbar>
268
198
 
269
199
  <VCardText>
270
- <VRow dense justify="start">
200
+ <VRow density="compact" justify="start">
271
201
  <VCol v-for="(image, index) in images" :key="`${imageKey(image)}-${index}`" cols="4">
272
202
  <VCard>
273
203
  <VToolbar density="compact">
@@ -288,7 +218,9 @@ defineExpose({
288
218
  <v-img
289
219
  :src="imageSrcFromImageData(image)"
290
220
  height="250"
291
- @click="() => { (props.readonly || image.imageData?.id || isReadonly?.value) ? openImageFullScreen(image) : setDataUpdate(image) }"
221
+ @click="() => {
222
+ props.readonly || image.imageData?.id || isReadonly?.value ? openImageFullScreen(image) : setDataUpdate(image);
223
+ }"
292
224
  :disabled="isDisabled?.value"
293
225
  />
294
226
  </VCard>
@@ -300,7 +232,6 @@ defineExpose({
300
232
  </v-row>
301
233
  </v-container>
302
234
 
303
-
304
235
  <!-- Edit dialog -->
305
236
  <VDialog v-model="dialogUpdate" fullscreen transition="dialog-bottom-transition">
306
237
  <FormImagesPad
@@ -0,0 +1,27 @@
1
+ import { type Base64Image } from '../../../composables/assetFile.js';
2
+ interface Props {
3
+ modelValue?: Base64Image[];
4
+ readonly?: boolean;
5
+ label?: string;
6
+ accept?: string;
7
+ autoHydrate?: boolean;
8
+ maxFileSize?: number;
9
+ }
10
+ declare const __VLS_export: import("vue").DefineComponent<Props, {
11
+ errorMessages: import("vue").ComputedRef<(string & string[]) | (readonly string[] & string[]) | undefined>;
12
+ isValid: import("vue").ComputedRef<boolean | null | undefined>;
13
+ reset: () => Promise<void> | undefined;
14
+ resetValidation: () => Promise<void> | undefined;
15
+ validate: () => Promise<string[]> | undefined;
16
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
17
+ "update:modelValue": (value: Base64Image[]) => any;
18
+ }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
19
+ "onUpdate:modelValue"?: ((value: Base64Image[]) => any) | undefined;
20
+ }>, {
21
+ modelValue: Base64Image[];
22
+ accept: string;
23
+ autoHydrate: boolean;
24
+ maxFileSize: number;
25
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
26
+ declare const _default: typeof __VLS_export;
27
+ export default _default;
@@ -0,0 +1,13 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
2
+ modelValue: StringConstructor;
3
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
4
+ "update:modelValue": (...args: any[]) => void;
5
+ closedDialog: (...args: any[]) => void;
6
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
7
+ modelValue: StringConstructor;
8
+ }>> & Readonly<{
9
+ "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
10
+ onClosedDialog?: ((...args: any[]) => any) | undefined;
11
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
12
+ declare const _default: typeof __VLS_export;
13
+ export default _default;
@@ -1,55 +1,38 @@
1
- <script setup lang="ts">
2
- /**
3
- * FormImagesPad handles image capture, editing, preview, and value synchronization for schema-driven form image fields.
4
- * This doc block is consumed by vue-docgen for generated API documentation.
5
- */
6
- import { onMounted, nextTick } from 'vue';
7
- import Painterro from 'painterro';
8
-
9
- /**
10
- * Public props accepted by FormImagesPad.
11
- * Document each prop field with intent, defaults, and side effects for clear generated docs.
12
- */
1
+ <script setup>
2
+ import { onMounted, nextTick } from "vue";
3
+ import Painterro from "painterro";
13
4
  const props = defineProps({
14
5
  modelValue: String
15
- })
16
-
17
- /**
18
- * Custom events emitted by FormImagesPad.
19
- * Parents can listen to these events to react to user actions and internal state changes.
20
- */
21
- const emit = defineEmits(['update:modelValue', 'closedDialog'])
22
-
6
+ });
7
+ const emit = defineEmits(["update:modelValue", "closedDialog"]);
23
8
  const setting = {
24
9
  id: "painterroContainer",
25
- defaultTool: 'brush',
26
- toolbarPosition: 'top',
27
- toolbarHeightPx: '50',
28
- pixelizePixelSize: '5%',
10
+ defaultTool: "brush",
11
+ toolbarPosition: "top",
12
+ toolbarHeightPx: "50",
13
+ pixelizePixelSize: "5%",
29
14
  hiddenTools: [
30
- 'resize',
31
- 'redo',
32
- 'bucket',
33
- 'clear',
34
- 'settings',
15
+ "resize",
16
+ "redo",
17
+ "bucket",
18
+ "clear",
19
+ "settings"
35
20
  ],
36
- saveHandler: function (image:any, done:any) {
37
- emit('update:modelValue', image.asDataURL())
38
- emit('closedDialog', false)
39
- done(true)
21
+ saveHandler: function(image, done) {
22
+ emit("update:modelValue", image.asDataURL());
23
+ emit("closedDialog", false);
24
+ done(true);
40
25
  },
41
- onClose: function () {
42
- emit('closedDialog', false)
26
+ onClose: function() {
27
+ emit("closedDialog", false);
43
28
  }
44
- }
45
-
29
+ };
46
30
  onMounted(async () => {
47
31
  await nextTick();
48
- props.modelValue != "" ? Painterro(setting).show(props.modelValue) : Painterro(setting).show()
32
+ props.modelValue != "" ? Painterro(setting).show(props.modelValue) : Painterro(setting).show();
49
33
  });
50
-
51
34
  </script>
52
35
 
53
36
  <template>
54
37
  <div id="painterroContainer" style="width: 100%; height: 100dvh;"></div>
55
- </template>
38
+ </template>
@@ -0,0 +1,13 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
2
+ modelValue: StringConstructor;
3
+ }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
4
+ "update:modelValue": (...args: any[]) => void;
5
+ closedDialog: (...args: any[]) => void;
6
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
7
+ modelValue: StringConstructor;
8
+ }>> & Readonly<{
9
+ "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
10
+ onClosedDialog?: ((...args: any[]) => any) | undefined;
11
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
12
+ declare const _default: typeof __VLS_export;
13
+ export default _default;
@@ -0,0 +1,13 @@
1
+ import { type dateFormat, type dateTimeFormat } from '../../utils/datetime.js';
2
+ interface Props {
3
+ modelValue?: string;
4
+ locale?: 'TH' | 'EN';
5
+ fromFormat?: string;
6
+ format?: dateFormat | dateTimeFormat | string;
7
+ }
8
+ declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
9
+ locale: "TH" | "EN";
10
+ format: dateFormat | dateTimeFormat | string;
11
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
12
+ declare const _default: typeof __VLS_export;
13
+ export default _default;
@@ -1,35 +1,19 @@
1
- <script lang="ts" setup>
2
- /**
3
- * LabelDate renders read-only label output with formatting logic for display-oriented model values.
4
- * This doc block is consumed by vue-docgen for generated API documentation.
5
- */
6
- import { computed } from 'vue'
7
- import { type dateFormat, type dateTimeFormat, Datetime } from '../../utils/datetime'
8
-
9
- interface Props {
10
- modelValue?: string // Bound value for v-model synchronization with the parent component.
11
- locale?: 'TH' | 'EN' // Locale used for date/time formatting and localized labels.
12
- fromFormat?: string // Input format used to parse incoming string values.
13
- format?: dateFormat | dateTimeFormat | string // Output format used when converting the value for display or emit.
14
- }
15
-
16
- /**
17
- * Public props accepted by LabelDate.
18
- * Document each prop field with intent, defaults, and side effects for clear generated docs.
19
- */
20
- const props = withDefaults(defineProps<Props>(), {
21
- locale: 'TH',
22
- format: 'shortDate',
23
- })
24
-
1
+ <script setup>
2
+ import { computed } from "vue";
3
+ import { Datetime } from "../../utils/datetime";
4
+ const props = defineProps({
5
+ modelValue: { type: String, required: false },
6
+ locale: { type: String, required: false, default: "TH" },
7
+ fromFormat: { type: String, required: false },
8
+ format: { type: String, required: false, default: "shortDate" }
9
+ });
25
10
  const formattedDate = computed(() => {
26
11
  if (!props.modelValue) {
27
- return null
12
+ return null;
28
13
  }
29
-
30
- const dateTime = Datetime().fromString(props.modelValue, props.fromFormat)
31
- return dateTime.luxonDateTime.isValid ? dateTime.toFormat(props.format, props.locale) : props.modelValue
32
- })
14
+ const dateTime = Datetime().fromString(props.modelValue, props.fromFormat);
15
+ return dateTime.luxonDateTime.isValid ? dateTime.toFormat(props.format, props.locale) : props.modelValue;
16
+ });
33
17
  </script>
34
18
 
35
19
  <template>
@@ -0,0 +1,13 @@
1
+ import { type dateFormat, type dateTimeFormat } from '../../utils/datetime.js';
2
+ interface Props {
3
+ modelValue?: string;
4
+ locale?: 'TH' | 'EN';
5
+ fromFormat?: string;
6
+ format?: dateFormat | dateTimeFormat | string;
7
+ }
8
+ declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
9
+ locale: "TH" | "EN";
10
+ format: dateFormat | dateTimeFormat | string;
11
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
12
+ declare const _default: typeof __VLS_export;
13
+ export default _default;