@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.
- package/README.md +9 -2
- package/dist/module.json +4 -4
- package/dist/module.mjs +4 -4
- package/dist/runtime/bridges/authentication.d.ts +21 -0
- package/dist/runtime/bridges/authentication.js +20 -0
- package/dist/runtime/bridges/graphql.d.ts +17 -0
- package/dist/runtime/bridges/graphql.js +45 -0
- package/dist/runtime/components/Alert.d.vue.ts +3 -0
- package/dist/runtime/components/Alert.vue +17 -26
- package/dist/runtime/components/Alert.vue.d.ts +3 -0
- package/dist/runtime/components/BarcodeReader.d.vue.ts +9 -0
- package/dist/runtime/components/BarcodeReader.vue +56 -81
- package/dist/runtime/components/BarcodeReader.vue.d.ts +9 -0
- package/dist/runtime/components/ExportCSV.d.vue.ts +55 -0
- package/dist/runtime/components/ExportCSV.vue +39 -76
- package/dist/runtime/components/ExportCSV.vue.d.ts +55 -0
- package/dist/runtime/components/FileBtn.d.vue.ts +53 -0
- package/dist/runtime/components/FileBtn.vue +23 -50
- package/dist/runtime/components/FileBtn.vue.d.ts +53 -0
- package/dist/runtime/components/ImportCSV.d.vue.ts +52 -0
- package/dist/runtime/components/ImportCSV.vue +60 -111
- package/dist/runtime/components/ImportCSV.vue.d.ts +52 -0
- package/dist/runtime/components/MrzReader.d.vue.ts +19 -0
- package/dist/runtime/components/MrzReader.vue +69 -109
- package/dist/runtime/components/MrzReader.vue.d.ts +19 -0
- package/dist/runtime/components/SplitterPanel.d.vue.ts +15 -0
- package/dist/runtime/components/SplitterPanel.vue +18 -35
- package/dist/runtime/components/SplitterPanel.vue.d.ts +15 -0
- package/dist/runtime/components/TabsGroup.d.vue.ts +19 -0
- package/dist/runtime/components/TabsGroup.vue +8 -20
- package/dist/runtime/components/TabsGroup.vue.d.ts +19 -0
- package/dist/runtime/components/TextBarcode.d.vue.ts +12 -0
- package/dist/runtime/components/TextBarcode.vue +22 -45
- package/dist/runtime/components/TextBarcode.vue.d.ts +12 -0
- package/dist/runtime/components/device/IdCardButton.d.vue.ts +57 -0
- package/dist/runtime/components/device/IdCardButton.vue +30 -67
- package/dist/runtime/components/device/IdCardButton.vue.d.ts +57 -0
- package/dist/runtime/components/device/IdCardWebSocket.d.vue.ts +55 -0
- package/dist/runtime/components/device/IdCardWebSocket.vue +104 -165
- package/dist/runtime/components/device/IdCardWebSocket.vue.d.ts +55 -0
- package/dist/runtime/components/device/Scanner.d.vue.ts +66 -0
- package/dist/runtime/components/device/Scanner.vue +97 -178
- package/dist/runtime/components/device/Scanner.vue.d.ts +66 -0
- package/dist/runtime/components/dialog/Confirm.d.vue.ts +37 -0
- package/dist/runtime/components/dialog/Confirm.vue +30 -59
- package/dist/runtime/components/dialog/Confirm.vue.d.ts +37 -0
- package/dist/runtime/components/dialog/Host.d.vue.ts +9 -0
- package/dist/runtime/components/dialog/Host.vue +34 -57
- package/dist/runtime/components/dialog/Host.vue.d.ts +9 -0
- package/dist/runtime/components/dialog/Index.d.vue.ts +24 -0
- package/dist/runtime/components/dialog/Index.vue +20 -40
- package/dist/runtime/components/dialog/Index.vue.d.ts +24 -0
- package/dist/runtime/components/dialog/Loading.d.vue.ts +21 -0
- package/dist/runtime/components/dialog/Loading.vue +12 -29
- package/dist/runtime/components/dialog/Loading.vue.d.ts +21 -0
- package/dist/runtime/components/dialog/default/Confirm.d.vue.ts +40 -0
- package/dist/runtime/components/dialog/default/Confirm.vue +29 -62
- package/dist/runtime/components/dialog/default/Confirm.vue.d.ts +40 -0
- package/dist/runtime/components/dialog/default/Loading.d.vue.ts +23 -0
- package/dist/runtime/components/dialog/default/Loading.vue +12 -29
- package/dist/runtime/components/dialog/default/Loading.vue.d.ts +23 -0
- package/dist/runtime/components/dialog/default/Notify.d.vue.ts +23 -0
- package/dist/runtime/components/dialog/default/Notify.vue +19 -48
- package/dist/runtime/components/dialog/default/Notify.vue.d.ts +23 -0
- package/dist/runtime/components/dialog/default/Printing.d.vue.ts +21 -0
- package/dist/runtime/components/dialog/default/Printing.vue +13 -29
- package/dist/runtime/components/dialog/default/Printing.vue.d.ts +21 -0
- package/dist/runtime/components/dialog/default/VerifyUser.d.vue.ts +29 -0
- package/dist/runtime/components/dialog/default/VerifyUser.vue +44 -82
- package/dist/runtime/components/dialog/default/VerifyUser.vue.d.ts +29 -0
- package/dist/runtime/components/document/Form.d.vue.ts +9 -0
- package/dist/runtime/components/document/Form.vue +27 -42
- package/dist/runtime/components/document/Form.vue.d.ts +9 -0
- package/dist/runtime/components/document/TemplateBuilder.d.vue.ts +24 -0
- package/dist/runtime/components/document/TemplateBuilder.vue +154 -194
- package/dist/runtime/components/document/TemplateBuilder.vue.d.ts +24 -0
- package/dist/runtime/components/form/ActionPad.d.vue.ts +114 -0
- package/dist/runtime/components/form/ActionPad.vue +48 -85
- package/dist/runtime/components/form/ActionPad.vue.d.ts +114 -0
- package/dist/runtime/components/form/Birthdate.d.vue.ts +38 -0
- package/dist/runtime/components/form/Birthdate.vue +44 -76
- package/dist/runtime/components/form/Birthdate.vue.d.ts +38 -0
- package/dist/runtime/components/form/CheckboxGroup.d.vue.ts +41 -0
- package/dist/runtime/components/form/CheckboxGroup.vue +34 -64
- package/dist/runtime/components/form/CheckboxGroup.vue.d.ts +41 -0
- package/dist/runtime/components/form/CodeEditor.d.vue.ts +25 -0
- package/dist/runtime/components/form/CodeEditor.vue +18 -36
- package/dist/runtime/components/form/CodeEditor.vue.d.ts +25 -0
- package/dist/runtime/components/form/Date.d.vue.ts +86 -0
- package/dist/runtime/components/form/Date.vue +109 -162
- package/dist/runtime/components/form/Date.vue.d.ts +86 -0
- package/dist/runtime/components/form/DateTime.d.vue.ts +36 -0
- package/dist/runtime/components/form/DateTime.vue +94 -143
- package/dist/runtime/components/form/DateTime.vue.d.ts +36 -0
- package/dist/runtime/components/form/Dialog.d.vue.ts +69 -0
- package/dist/runtime/components/form/Dialog.vue +60 -96
- package/dist/runtime/components/form/Dialog.vue.d.ts +69 -0
- package/dist/runtime/components/form/EditPad.d.vue.ts +113 -0
- package/dist/runtime/components/form/EditPad.vue +49 -85
- package/dist/runtime/components/form/EditPad.vue.d.ts +113 -0
- package/dist/runtime/components/form/File.d.vue.ts +65 -0
- package/dist/runtime/components/form/File.vue +112 -186
- package/dist/runtime/components/form/File.vue.d.ts +65 -0
- package/dist/runtime/components/form/Hidden.d.vue.ts +12 -0
- package/dist/runtime/components/form/Hidden.vue +17 -34
- package/dist/runtime/components/form/Hidden.vue.d.ts +12 -0
- package/dist/runtime/components/form/Iterator.d.vue.ts +279 -0
- package/dist/runtime/components/form/Iterator.vue +162 -252
- package/dist/runtime/components/form/Iterator.vue.d.ts +279 -0
- package/dist/runtime/components/form/Login.d.vue.ts +32 -0
- package/dist/runtime/components/form/Login.vue +23 -55
- package/dist/runtime/components/form/Login.vue.d.ts +32 -0
- package/dist/runtime/components/form/Pad.d.vue.ts +674 -0
- package/dist/runtime/components/form/Pad.vue +166 -265
- package/dist/runtime/components/form/Pad.vue.d.ts +674 -0
- package/dist/runtime/components/form/SignPad.d.vue.ts +62 -0
- package/dist/runtime/components/form/SignPad.vue +80 -126
- package/dist/runtime/components/form/SignPad.vue.d.ts +62 -0
- package/dist/runtime/components/form/System.d.vue.ts +34 -0
- package/dist/runtime/components/form/System.vue +18 -32
- package/dist/runtime/components/form/System.vue.d.ts +34 -0
- package/dist/runtime/components/form/Table.d.vue.ts +221 -0
- package/dist/runtime/components/form/Table.vue +123 -182
- package/dist/runtime/components/form/Table.vue.d.ts +221 -0
- package/dist/runtime/components/form/TableData.d.vue.ts +102 -0
- package/dist/runtime/components/form/TableData.vue +109 -139
- package/dist/runtime/components/form/TableData.vue.d.ts +102 -0
- package/dist/runtime/components/form/Time.d.vue.ts +49 -0
- package/dist/runtime/components/form/Time.vue +64 -99
- package/dist/runtime/components/form/Time.vue.d.ts +49 -0
- package/dist/runtime/components/form/images/Capture.d.vue.ts +96 -0
- package/dist/runtime/components/form/images/Capture.vue +104 -147
- package/dist/runtime/components/form/images/Capture.vue.d.ts +96 -0
- package/dist/runtime/components/form/images/Edit.d.vue.ts +29 -0
- package/dist/runtime/components/form/images/Edit.vue +57 -81
- package/dist/runtime/components/form/images/Edit.vue.d.ts +29 -0
- package/dist/runtime/components/form/images/Field.d.vue.ts +27 -0
- package/dist/runtime/components/form/images/Field.vue +136 -205
- package/dist/runtime/components/form/images/Field.vue.d.ts +27 -0
- package/dist/runtime/components/form/images/Pad.d.vue.ts +13 -0
- package/dist/runtime/components/form/images/Pad.vue +23 -40
- package/dist/runtime/components/form/images/Pad.vue.d.ts +13 -0
- package/dist/runtime/components/label/Date.d.vue.ts +13 -0
- package/dist/runtime/components/label/Date.vue +13 -29
- package/dist/runtime/components/label/Date.vue.d.ts +13 -0
- package/dist/runtime/components/label/DateAgo.d.vue.ts +20 -0
- package/dist/runtime/components/label/DateAgo.vue +43 -75
- package/dist/runtime/components/label/DateAgo.vue.d.ts +20 -0
- package/dist/runtime/components/label/DateCount.d.vue.ts +22 -0
- package/dist/runtime/components/label/DateCount.vue +58 -105
- package/dist/runtime/components/label/DateCount.vue.d.ts +22 -0
- package/dist/runtime/components/label/Field.d.vue.ts +38 -0
- package/dist/runtime/components/label/Field.vue +18 -40
- package/dist/runtime/components/label/Field.vue.d.ts +38 -0
- package/dist/runtime/components/label/FormatMoney.d.vue.ts +12 -0
- package/dist/runtime/components/label/FormatMoney.vue +12 -28
- package/dist/runtime/components/label/FormatMoney.vue.d.ts +12 -0
- package/dist/runtime/components/label/Mask.d.vue.ts +10 -0
- package/dist/runtime/components/label/Mask.vue +21 -38
- package/dist/runtime/components/label/Mask.vue.d.ts +10 -0
- package/dist/runtime/components/label/Object.d.vue.ts +8 -0
- package/dist/runtime/components/label/Object.vue +10 -20
- package/dist/runtime/components/label/Object.vue.d.ts +8 -0
- package/dist/runtime/components/master/Autocomplete.d.vue.ts +70 -0
- package/dist/runtime/components/master/Autocomplete.vue +25 -34
- package/dist/runtime/components/master/Autocomplete.vue.d.ts +70 -0
- package/dist/runtime/components/master/Combobox.d.vue.ts +70 -0
- package/dist/runtime/components/master/Combobox.vue +26 -35
- package/dist/runtime/components/master/Combobox.vue.d.ts +70 -0
- package/dist/runtime/components/master/RadioGroup.d.vue.ts +51 -0
- package/dist/runtime/components/master/RadioGroup.vue +44 -59
- package/dist/runtime/components/master/RadioGroup.vue.d.ts +51 -0
- package/dist/runtime/components/master/Select.d.vue.ts +68 -0
- package/dist/runtime/components/master/Select.vue +25 -34
- package/dist/runtime/components/master/Select.vue.d.ts +68 -0
- package/dist/runtime/components/master/label.d.vue.ts +24 -0
- package/dist/runtime/components/master/label.vue +22 -42
- package/dist/runtime/components/master/label.vue.d.ts +24 -0
- package/dist/runtime/components/model/Autocomplete.d.vue.ts +82 -0
- package/dist/runtime/components/model/Autocomplete.vue +50 -49
- package/dist/runtime/components/model/Autocomplete.vue.d.ts +82 -0
- package/dist/runtime/components/model/Combobox.d.vue.ts +82 -0
- package/dist/runtime/components/model/Combobox.vue +51 -49
- package/dist/runtime/components/model/Combobox.vue.d.ts +82 -0
- package/dist/runtime/components/model/Pad.d.vue.ts +72 -0
- package/dist/runtime/components/model/Pad.vue +50 -65
- package/dist/runtime/components/model/Pad.vue.d.ts +72 -0
- package/dist/runtime/components/model/Select.d.vue.ts +72 -0
- package/dist/runtime/components/model/Select.vue +42 -44
- package/dist/runtime/components/model/Select.vue.d.ts +72 -0
- package/dist/runtime/components/model/Table.d.vue.ts +272 -0
- package/dist/runtime/components/model/Table.vue +121 -145
- package/dist/runtime/components/model/Table.vue.d.ts +272 -0
- package/dist/runtime/components/model/iterator.d.vue.ts +321 -0
- package/dist/runtime/components/model/iterator.vue +148 -183
- package/dist/runtime/components/model/iterator.vue.d.ts +321 -0
- package/dist/runtime/components/model/label.d.vue.ts +26 -0
- package/dist/runtime/components/model/label.vue +25 -43
- package/dist/runtime/components/model/label.vue.d.ts +26 -0
- package/dist/runtime/components/pdf/Print.d.vue.ts +17 -0
- package/dist/runtime/components/pdf/Print.vue +27 -50
- package/dist/runtime/components/pdf/Print.vue.d.ts +17 -0
- package/dist/runtime/components/pdf/View.d.vue.ts +52 -0
- package/dist/runtime/components/pdf/View.vue +58 -95
- package/dist/runtime/components/pdf/View.vue.d.ts +52 -0
- package/dist/runtime/composables/api.js +4 -2
- package/dist/runtime/composables/assetFile.js +4 -2
- package/dist/runtime/composables/dialog.d.ts +1 -1
- package/dist/runtime/composables/document/template.js +3 -3
- package/dist/runtime/composables/document/templateFormTable.js +1 -0
- package/dist/runtime/composables/graphql.d.ts +2 -2
- package/dist/runtime/composables/graphql.js +5 -5
- package/dist/runtime/composables/graphqlModel.d.ts +6 -6
- package/dist/runtime/composables/graphqlModelItem.d.ts +4 -4
- package/dist/runtime/composables/graphqlModelOperation.d.ts +6 -6
- package/dist/runtime/composables/graphqlModelOperation.js +2 -1
- package/dist/runtime/composables/graphqlOperation.js +5 -1
- package/dist/runtime/composables/hostAgentWs.d.ts +1 -1
- package/dist/runtime/composables/lookupListMaster.js +3 -3
- package/dist/runtime/composables/menu.js +2 -2
- package/dist/runtime/composables/userPermission.d.ts +1 -1
- package/dist/runtime/composables/utils/fuzzy.d.ts +2 -1
- package/dist/runtime/labs/Calendar.d.vue.ts +35 -0
- package/dist/runtime/labs/Calendar.vue +47 -75
- package/dist/runtime/labs/Calendar.vue.d.ts +35 -0
- package/dist/runtime/labs/form/EditMobile.d.vue.ts +12 -0
- package/dist/runtime/labs/form/EditMobile.vue +19 -36
- package/dist/runtime/labs/form/EditMobile.vue.d.ts +12 -0
- package/dist/runtime/labs/form/TextFieldMask.d.vue.ts +21 -0
- package/dist/runtime/labs/form/TextFieldMask.vue +19 -25
- package/dist/runtime/labs/form/TextFieldMask.vue.d.ts +21 -0
- package/dist/runtime/plugins/dialogManager.js +2 -2
- package/dist/runtime/plugins/permission.js +3 -3
- package/dist/runtime/types/bridge.d.ts +14 -0
- package/dist/runtime/utils/datetime.js +1 -1
- package/dist/types.d.mts +2 -6
- package/package.json +71 -58
- package/scripts/ci-release.mjs +125 -0
- package/scripts/release-version.mjs +68 -0
- package/scripts/release.mjs +49 -0
- package/dist/module.cjs +0 -5
- package/dist/module.d.ts +0 -8
- package/dist/types.d.ts +0 -7
|
@@ -1,237 +1,163 @@
|
|
|
1
|
-
<script
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
*/
|
|
31
|
-
const props = withDefaults(defineProps<Props>(), {
|
|
32
|
-
accept: '*',
|
|
33
|
-
multiple: false,
|
|
34
|
-
maxSize: 5,
|
|
35
|
-
downloadable: false,
|
|
36
|
-
autoHydrate: false,
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Custom events emitted by FormFile.
|
|
41
|
-
* Parents can listen to these events to react to user actions and internal state changes.
|
|
42
|
-
*/
|
|
43
|
-
const emit = defineEmits<{
|
|
44
|
-
(e: 'update:modelValue', value: Base64File | Base64File[] | null): void
|
|
45
|
-
}>()
|
|
46
|
-
|
|
47
|
-
/** UI ref */
|
|
48
|
-
const fileInput = ref<HTMLInputElement | null>(null)
|
|
49
|
-
|
|
50
|
-
/** Internal sources (always arrays) */
|
|
51
|
-
const assets = ref<Base64File[]>([]) // items with server id (or ones we keep as “assets”)
|
|
52
|
-
const files = shallowRef<File[]>([]) // native File objects picked by the user
|
|
53
|
-
|
|
54
|
-
/** Cache to avoid re-reading the same File repeatedly */
|
|
55
|
-
const fileCache = new WeakMap<File, Promise<Base64File>>()
|
|
56
|
-
|
|
57
|
-
/** Re-entrancy guard to break the emit -> props watcher -> syncFromModel loop */
|
|
58
|
-
let internalSync = false
|
|
59
|
-
|
|
60
|
-
/** Build a stable dedupe key */
|
|
61
|
-
function base64FileKey(x: Base64File): string {
|
|
62
|
-
if (x.id != null) return `id:${x.id}`
|
|
63
|
-
const name = x.fileName ?? ''
|
|
64
|
-
const len = x.base64String?.length ?? 0
|
|
65
|
-
return `n:${name}|l:${len}`
|
|
1
|
+
<script setup>
|
|
2
|
+
import { castArray } from "lodash-es";
|
|
3
|
+
import { ref, shallowRef, watch, computed } from "vue";
|
|
4
|
+
import { VTextField } from "vuetify/components/VTextField";
|
|
5
|
+
import { useAlert } from "../../composables/alert";
|
|
6
|
+
import {} from "../../composables/assetFile";
|
|
7
|
+
import { useAssetFile } from "../../composables/assetFile";
|
|
8
|
+
const alert = useAlert();
|
|
9
|
+
const { hydrateAssetFile, base64ToFile, fileToBase64, downloadBase64File } = useAssetFile();
|
|
10
|
+
const fileToBase64WithMaxSize = (file) => fileToBase64(file, props.maxSize);
|
|
11
|
+
const props = defineProps({
|
|
12
|
+
accept: { type: String, required: false, default: "*" },
|
|
13
|
+
multiple: { type: Boolean, required: false, default: false },
|
|
14
|
+
maxSize: { type: Number, required: false, default: 5 },
|
|
15
|
+
modelValue: { type: [Object, Array, null], required: false },
|
|
16
|
+
downloadable: { type: Boolean, required: false, default: false },
|
|
17
|
+
autoHydrate: { type: Boolean, required: false, default: false }
|
|
18
|
+
});
|
|
19
|
+
const emit = defineEmits(["update:modelValue"]);
|
|
20
|
+
const fileInput = ref(null);
|
|
21
|
+
const assets = ref([]);
|
|
22
|
+
const files = shallowRef([]);
|
|
23
|
+
const fileCache = /* @__PURE__ */ new WeakMap();
|
|
24
|
+
let internalSync = false;
|
|
25
|
+
function base64FileKey(x) {
|
|
26
|
+
if (x.id != null) return `id:${x.id}`;
|
|
27
|
+
const name = x.fileName ?? "";
|
|
28
|
+
const len = x.base64String?.length ?? 0;
|
|
29
|
+
return `n:${name}|l:${len}`;
|
|
66
30
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const seen = new Set<string>()
|
|
71
|
-
const out: Base64File[] = []
|
|
31
|
+
function uniqByKey(arr) {
|
|
32
|
+
const seen = /* @__PURE__ */ new Set();
|
|
33
|
+
const out = [];
|
|
72
34
|
for (const it of arr) {
|
|
73
|
-
const k = base64FileKey(it)
|
|
35
|
+
const k = base64FileKey(it);
|
|
74
36
|
if (!seen.has(k)) {
|
|
75
|
-
seen.add(k)
|
|
76
|
-
out.push(it)
|
|
37
|
+
seen.add(k);
|
|
38
|
+
out.push(it);
|
|
77
39
|
}
|
|
78
40
|
}
|
|
79
|
-
return out
|
|
41
|
+
return out;
|
|
80
42
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if (a === b) return true
|
|
85
|
-
if (a.length !== b.length) return false
|
|
43
|
+
function arraysEqualByKey(a, b) {
|
|
44
|
+
if (a === b) return true;
|
|
45
|
+
if (a.length !== b.length) return false;
|
|
86
46
|
for (let i = 0; i < a.length; i++) {
|
|
87
|
-
if (base64FileKey(a[i]) !== base64FileKey(b[i])) return false
|
|
47
|
+
if (base64FileKey(a[i]) !== base64FileKey(b[i])) return false;
|
|
88
48
|
}
|
|
89
|
-
return true
|
|
49
|
+
return true;
|
|
90
50
|
}
|
|
91
|
-
|
|
92
|
-
/** Normalize incoming modelValue into arrays for internal use */
|
|
93
51
|
async function syncFromModel() {
|
|
94
|
-
const mv = props.modelValue
|
|
52
|
+
const mv = props.modelValue;
|
|
95
53
|
if (!mv) {
|
|
96
|
-
assets.value = []
|
|
97
|
-
files.value = []
|
|
98
|
-
return
|
|
54
|
+
assets.value = [];
|
|
55
|
+
files.value = [];
|
|
56
|
+
return;
|
|
99
57
|
}
|
|
100
|
-
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const incomingAssets = asArray.filter(a => a.id != null)
|
|
105
|
-
const inlineBase64 = asArray.filter(a => a.id == null && a.base64String)
|
|
106
|
-
|
|
107
|
-
// Convert inline base64 to File for consistent UX
|
|
108
|
-
const inlineFiles: File[] = []
|
|
58
|
+
const asArray = castArray(mv);
|
|
59
|
+
const incomingAssets = asArray.filter((a) => a.id != null);
|
|
60
|
+
const inlineBase64 = asArray.filter((a) => a.id == null && a.base64String);
|
|
61
|
+
const inlineFiles = [];
|
|
109
62
|
for (const item of inlineBase64) {
|
|
110
|
-
const f = base64ToFile(item.base64String
|
|
111
|
-
if (f) inlineFiles.push(f)
|
|
63
|
+
const f = base64ToFile(item.base64String, item.fileName);
|
|
64
|
+
if (f) inlineFiles.push(f);
|
|
112
65
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
files.value = inlineFiles
|
|
116
|
-
|
|
117
|
-
// Optionally hydrate assets that need it
|
|
66
|
+
assets.value = incomingAssets;
|
|
67
|
+
files.value = inlineFiles;
|
|
118
68
|
if (props.autoHydrate) {
|
|
119
|
-
const needsHydration = assets.value.filter(a => a.id != null && !a.base64String)
|
|
69
|
+
const needsHydration = assets.value.filter((a) => a.id != null && !a.base64String);
|
|
120
70
|
if (needsHydration.length) {
|
|
121
|
-
await Promise.allSettled(needsHydration.map(hydrateAssetFile))
|
|
71
|
+
await Promise.allSettled(needsHydration.map(hydrateAssetFile));
|
|
122
72
|
}
|
|
123
73
|
}
|
|
124
74
|
}
|
|
125
|
-
|
|
126
|
-
/** Open chooser */
|
|
127
75
|
function openWindowUpload() {
|
|
128
|
-
if (props.multiple ||
|
|
129
|
-
fileInput.value?.click()
|
|
76
|
+
if (props.multiple || assets.value.length === 0 && files.value.length === 0) {
|
|
77
|
+
fileInput.value?.click();
|
|
130
78
|
}
|
|
131
79
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
if (Array.isArray(payload)) files.value = [...files.value, ...payload]
|
|
136
|
-
else files.value = [...files.value, payload]
|
|
80
|
+
function addFiles(payload) {
|
|
81
|
+
if (Array.isArray(payload)) files.value = [...files.value, ...payload];
|
|
82
|
+
else files.value = [...files.value, payload];
|
|
137
83
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
function removeFileByIndex(i: number | string) {
|
|
141
|
-
const idx = Number(i)
|
|
84
|
+
function removeFileByIndex(i) {
|
|
85
|
+
const idx = Number(i);
|
|
142
86
|
if (idx >= 0 && idx < files.value.length) {
|
|
143
|
-
const copy = files.value.slice()
|
|
144
|
-
copy.splice(idx, 1)
|
|
145
|
-
files.value = copy
|
|
87
|
+
const copy = files.value.slice();
|
|
88
|
+
copy.splice(idx, 1);
|
|
89
|
+
files.value = copy;
|
|
146
90
|
}
|
|
147
91
|
}
|
|
148
|
-
function removeAssetByIndex(i
|
|
149
|
-
const idx = Number(i)
|
|
92
|
+
function removeAssetByIndex(i) {
|
|
93
|
+
const idx = Number(i);
|
|
150
94
|
if (idx >= 0 && idx < assets.value.length) {
|
|
151
|
-
const copy = assets.value.slice()
|
|
152
|
-
copy.splice(idx, 1)
|
|
153
|
-
assets.value = copy
|
|
95
|
+
const copy = assets.value.slice();
|
|
96
|
+
copy.splice(idx, 1);
|
|
97
|
+
assets.value = copy;
|
|
154
98
|
}
|
|
155
99
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
const tasks = list.map(f => {
|
|
160
|
-
let p = fileCache.get(f)
|
|
100
|
+
async function filesToBase64Files(list) {
|
|
101
|
+
const tasks = list.map((f) => {
|
|
102
|
+
let p = fileCache.get(f);
|
|
161
103
|
if (!p) {
|
|
162
|
-
p = fileToBase64WithMaxSize(f)
|
|
163
|
-
fileCache.set(f, p)
|
|
104
|
+
p = fileToBase64WithMaxSize(f);
|
|
105
|
+
fileCache.set(f, p);
|
|
164
106
|
}
|
|
165
|
-
return p
|
|
166
|
-
})
|
|
167
|
-
return Promise.all(tasks)
|
|
107
|
+
return p;
|
|
108
|
+
});
|
|
109
|
+
return Promise.all(tasks);
|
|
168
110
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
/** Dirty flag for <v-text-field> */
|
|
174
|
-
const isDirty = computed(() =>
|
|
175
|
-
props.multiple ? combinedArray.value.length > 0 : combinedArray.value[0] != null
|
|
176
|
-
)
|
|
177
|
-
|
|
178
|
-
/** Sync from props.modelValue (guarded) */
|
|
111
|
+
const combinedArray = ref([]);
|
|
112
|
+
const isDirty = computed(
|
|
113
|
+
() => props.multiple ? combinedArray.value.length > 0 : combinedArray.value[0] != null
|
|
114
|
+
);
|
|
179
115
|
watch(
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
)
|
|
187
|
-
|
|
188
|
-
/** Rebuild combined and emit (guarded, deduped, only-on-change) */
|
|
116
|
+
() => props.modelValue,
|
|
117
|
+
() => {
|
|
118
|
+
if (internalSync) return;
|
|
119
|
+
void syncFromModel();
|
|
120
|
+
},
|
|
121
|
+
{ deep: true, immediate: true }
|
|
122
|
+
);
|
|
189
123
|
watch([assets, files], async () => {
|
|
190
124
|
try {
|
|
191
|
-
const base64FromFiles = await filesToBase64Files(files.value)
|
|
192
|
-
|
|
193
|
-
const
|
|
194
|
-
? [...assets.value, ...base64FromFiles]
|
|
195
|
-
: (assets.value[0] ?? base64FromFiles[0] ?? null)
|
|
196
|
-
? [assets.value[0] ?? base64FromFiles[0]]
|
|
197
|
-
: []
|
|
198
|
-
|
|
199
|
-
const nextCombined = props.multiple ? uniqByKey(mergedArray) : mergedArray
|
|
200
|
-
|
|
125
|
+
const base64FromFiles = await filesToBase64Files(files.value);
|
|
126
|
+
const mergedArray = props.multiple ? [...assets.value, ...base64FromFiles] : assets.value[0] ?? base64FromFiles[0] ?? null ? [assets.value[0] ?? base64FromFiles[0]] : [];
|
|
127
|
+
const nextCombined = props.multiple ? uniqByKey(mergedArray) : mergedArray;
|
|
201
128
|
if (!arraysEqualByKey(combinedArray.value, nextCombined)) {
|
|
202
|
-
combinedArray.value = nextCombined
|
|
203
|
-
|
|
204
|
-
internalSync = true
|
|
129
|
+
combinedArray.value = nextCombined;
|
|
130
|
+
internalSync = true;
|
|
205
131
|
try {
|
|
206
132
|
if (props.multiple) {
|
|
207
|
-
emit(
|
|
133
|
+
emit("update:modelValue", combinedArray.value);
|
|
208
134
|
} else {
|
|
209
|
-
emit(
|
|
135
|
+
emit("update:modelValue", combinedArray.value[0] ?? null);
|
|
210
136
|
}
|
|
211
137
|
} finally {
|
|
212
|
-
|
|
213
|
-
|
|
138
|
+
queueMicrotask(() => {
|
|
139
|
+
internalSync = false;
|
|
140
|
+
});
|
|
214
141
|
}
|
|
215
142
|
}
|
|
216
|
-
} catch (error
|
|
217
|
-
alert?.addAlert({ message: String(error), alertType:
|
|
218
|
-
files.value = []
|
|
219
|
-
const fallback = props.multiple
|
|
220
|
-
? [...assets.value]
|
|
221
|
-
: (assets.value[0] ? [assets.value[0]] : [])
|
|
222
|
-
|
|
143
|
+
} catch (error) {
|
|
144
|
+
alert?.addAlert({ message: String(error), alertType: "error" });
|
|
145
|
+
files.value = [];
|
|
146
|
+
const fallback = props.multiple ? [...assets.value] : assets.value[0] ? [assets.value[0]] : [];
|
|
223
147
|
if (!arraysEqualByKey(combinedArray.value, fallback)) {
|
|
224
|
-
combinedArray.value = fallback
|
|
225
|
-
internalSync = true
|
|
148
|
+
combinedArray.value = fallback;
|
|
149
|
+
internalSync = true;
|
|
226
150
|
try {
|
|
227
|
-
if (props.multiple) emit(
|
|
228
|
-
else emit(
|
|
151
|
+
if (props.multiple) emit("update:modelValue", combinedArray.value);
|
|
152
|
+
else emit("update:modelValue", combinedArray.value[0] ?? null);
|
|
229
153
|
} finally {
|
|
230
|
-
queueMicrotask(() => {
|
|
154
|
+
queueMicrotask(() => {
|
|
155
|
+
internalSync = false;
|
|
156
|
+
});
|
|
231
157
|
}
|
|
232
158
|
}
|
|
233
159
|
}
|
|
234
|
-
}, { deep: true, immediate: true })
|
|
160
|
+
}, { deep: true, immediate: true });
|
|
235
161
|
</script>
|
|
236
162
|
|
|
237
163
|
<template>
|
|
@@ -293,4 +219,4 @@ watch([assets, files], async () => {
|
|
|
293
219
|
style="display: none"
|
|
294
220
|
@update:model-value="addFiles"
|
|
295
221
|
/>
|
|
296
|
-
</template>
|
|
222
|
+
</template>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { VTextField } from 'vuetify/components/VTextField';
|
|
2
|
+
import { type Base64File } from '../../composables/assetFile.js';
|
|
3
|
+
interface Props extends /* @vue-ignore */ InstanceType<typeof VTextField['$props']> {
|
|
4
|
+
accept?: string;
|
|
5
|
+
multiple?: boolean;
|
|
6
|
+
maxSize?: number;
|
|
7
|
+
modelValue?: Base64File | Base64File[] | null;
|
|
8
|
+
downloadable?: boolean;
|
|
9
|
+
autoHydrate?: boolean;
|
|
10
|
+
}
|
|
11
|
+
declare var __VLS_17: {
|
|
12
|
+
item: {
|
|
13
|
+
fileName: string;
|
|
14
|
+
originalFileName?: string | undefined;
|
|
15
|
+
fileType?: string | undefined;
|
|
16
|
+
id?: number | undefined;
|
|
17
|
+
base64String?: string | undefined;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
type __VLS_Slots = {} & {
|
|
21
|
+
download?: (props: typeof __VLS_17) => any;
|
|
22
|
+
};
|
|
23
|
+
declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<Props>, {
|
|
24
|
+
accept: string;
|
|
25
|
+
multiple: boolean;
|
|
26
|
+
maxSize: number;
|
|
27
|
+
downloadable: boolean;
|
|
28
|
+
autoHydrate: boolean;
|
|
29
|
+
}>>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
30
|
+
"update:modelValue": (value: Base64File | Base64File[] | null) => any;
|
|
31
|
+
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<Props>, {
|
|
32
|
+
accept: string;
|
|
33
|
+
multiple: boolean;
|
|
34
|
+
maxSize: number;
|
|
35
|
+
downloadable: boolean;
|
|
36
|
+
autoHydrate: boolean;
|
|
37
|
+
}>>> & Readonly<{
|
|
38
|
+
"onUpdate:modelValue"?: ((value: Base64File | Base64File[] | null) => any) | undefined;
|
|
39
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
40
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
41
|
+
declare const _default: typeof __VLS_export;
|
|
42
|
+
export default _default;
|
|
43
|
+
type __VLS_TypePropsToOption<T> = {
|
|
44
|
+
[K in keyof T]-?: {} extends Pick<T, K> ? {
|
|
45
|
+
type: import('vue').PropType<Required<T>[K]>;
|
|
46
|
+
} : {
|
|
47
|
+
type: import('vue').PropType<T[K]>;
|
|
48
|
+
required: true;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
type __VLS_WithDefaults<P, D> = {
|
|
52
|
+
[K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_PrettifyLocal<P[K] & {
|
|
53
|
+
default: D[K];
|
|
54
|
+
}> : P[K];
|
|
55
|
+
};
|
|
56
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
57
|
+
new (): {
|
|
58
|
+
$slots: S;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
type __VLS_PrettifyLocal<T> = (T extends any ? {
|
|
62
|
+
[K in keyof T]: T[K];
|
|
63
|
+
} : {
|
|
64
|
+
[K in keyof T as K]: T[K];
|
|
65
|
+
}) & {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
itemValue?: any;
|
|
3
|
+
hook?: Function;
|
|
4
|
+
modelValue?: any;
|
|
5
|
+
}
|
|
6
|
+
declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
7
|
+
"update:modelValue": (...args: any[]) => void;
|
|
8
|
+
}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
|
|
9
|
+
"onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
|
|
10
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
11
|
+
declare const _default: typeof __VLS_export;
|
|
12
|
+
export default _default;
|
|
@@ -1,39 +1,22 @@
|
|
|
1
|
-
<script
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
modelValue?: any // Bound value for v-model synchronization with the parent component.
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Public props accepted by FormHidden.
|
|
17
|
-
* Document each prop field with intent, defaults, and side effects for clear generated docs.
|
|
18
|
-
*/
|
|
19
|
-
const props = defineProps<Props>()
|
|
20
|
-
/**
|
|
21
|
-
* Custom events emitted by FormHidden.
|
|
22
|
-
* Parents can listen to these events to react to user actions and internal state changes.
|
|
23
|
-
*/
|
|
24
|
-
const emit = defineEmits(['update:modelValue'])
|
|
25
|
-
|
|
26
|
-
watch(() => props.itemValue, (newValue,oldValue) => {
|
|
27
|
-
const resultValue = cloneDeep(newValue)
|
|
1
|
+
<script setup>
|
|
2
|
+
import { watch } from "vue";
|
|
3
|
+
import { cloneDeep } from "lodash-es";
|
|
4
|
+
const props = defineProps({
|
|
5
|
+
itemValue: { type: null, required: false },
|
|
6
|
+
hook: { type: Function, required: false },
|
|
7
|
+
modelValue: { type: null, required: false }
|
|
8
|
+
});
|
|
9
|
+
const emit = defineEmits(["update:modelValue"]);
|
|
10
|
+
watch(() => props.itemValue, (newValue, oldValue) => {
|
|
11
|
+
const resultValue = cloneDeep(newValue);
|
|
28
12
|
if (props.hook) {
|
|
29
|
-
Promise.resolve(props.hook(resultValue, props.modelValue,newValue,oldValue)).then((result) => {
|
|
30
|
-
emit(
|
|
31
|
-
}).catch(e => void e)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
emit('update:modelValue', resultValue)
|
|
13
|
+
Promise.resolve(props.hook(resultValue, props.modelValue, newValue, oldValue)).then((result) => {
|
|
14
|
+
emit("update:modelValue", result);
|
|
15
|
+
}).catch((e) => void e);
|
|
16
|
+
} else {
|
|
17
|
+
emit("update:modelValue", resultValue);
|
|
35
18
|
}
|
|
36
|
-
}, { deep: true, immediate: true })
|
|
19
|
+
}, { deep: true, immediate: true });
|
|
37
20
|
</script>
|
|
38
21
|
|
|
39
22
|
<template>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
itemValue?: any;
|
|
3
|
+
hook?: Function;
|
|
4
|
+
modelValue?: any;
|
|
5
|
+
}
|
|
6
|
+
declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
7
|
+
"update:modelValue": (...args: any[]) => void;
|
|
8
|
+
}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
|
|
9
|
+
"onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
|
|
10
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
11
|
+
declare const _default: typeof __VLS_export;
|
|
12
|
+
export default _default;
|