@ramathibodi/nuxt-commons 0.1.13 → 0.1.15
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 +96 -96
- package/dist/module.json +1 -1
- package/dist/runtime/components/Alert.vue +53 -53
- package/dist/runtime/components/BarcodeReader.vue +98 -98
- package/dist/runtime/components/ExportCSV.vue +55 -55
- package/dist/runtime/components/FileBtn.vue +62 -62
- package/dist/runtime/components/ImportCSV.vue +64 -64
- package/dist/runtime/components/SplitterPanel.vue +59 -59
- package/dist/runtime/components/TabsGroup.vue +32 -32
- package/dist/runtime/components/TextBarcode.vue +52 -52
- package/dist/runtime/components/dialog/Confirm.vue +100 -100
- package/dist/runtime/components/dialog/Index.vue +72 -72
- package/dist/runtime/components/dialog/Loading.vue +39 -39
- package/dist/runtime/components/document/TemplateBuilder.vue +203 -216
- package/dist/runtime/components/form/Birthdate.vue +216 -199
- package/dist/runtime/components/form/CodeEditor.vue +37 -37
- package/dist/runtime/components/form/Date.vue +163 -163
- package/dist/runtime/components/form/DateTime.vue +107 -107
- package/dist/runtime/components/form/Dialog.vue +138 -138
- package/dist/runtime/components/form/File.vue +187 -187
- package/dist/runtime/components/form/Hidden.vue +32 -32
- package/dist/runtime/components/form/Login.vue +131 -131
- package/dist/runtime/components/form/Pad.vue +217 -217
- package/dist/runtime/components/form/SignPad.vue +186 -186
- package/dist/runtime/components/form/Table.vue +266 -266
- package/dist/runtime/components/form/Time.vue +158 -158
- package/dist/runtime/components/form/images/Capture.vue +231 -0
- package/dist/runtime/components/form/images/Edit.vue +117 -143
- package/dist/runtime/components/label/Date.vue +29 -29
- package/dist/runtime/components/label/Field.vue +42 -29
- package/dist/runtime/components/label/FormatMoney.vue +29 -29
- package/dist/runtime/components/label/Mask.vue +38 -38
- package/dist/runtime/components/master/Autocomplete.vue +159 -159
- package/dist/runtime/components/master/Combobox.vue +84 -84
- package/dist/runtime/components/master/RadioGroup.vue +78 -78
- package/dist/runtime/components/master/Select.vue +82 -82
- package/dist/runtime/components/model/Pad.vue +122 -122
- package/dist/runtime/components/model/Table.vue +242 -240
- package/dist/runtime/components/model/iterator.vue +312 -312
- package/dist/runtime/components/pdf/Print.vue +63 -63
- package/dist/runtime/components/pdf/View.vue +104 -104
- package/dist/runtime/composables/graphqlModel.d.ts +4 -1
- package/dist/runtime/composables/graphqlModel.mjs +5 -5
- package/dist/runtime/composables/graphqlModelOperation.mjs +7 -4
- package/dist/runtime/labs/Calendar.vue +99 -99
- package/dist/runtime/labs/form/EditMobile.vue +152 -152
- package/dist/runtime/labs/form/TextFieldMask.vue +43 -43
- package/dist/runtime/types/alert.d.ts +11 -11
- package/dist/runtime/types/formDialog.d.ts +4 -4
- package/dist/runtime/types/graphqlOperation.d.ts +23 -23
- package/dist/runtime/types/menu.d.ts +25 -25
- package/dist/runtime/types/modules.d.ts +7 -7
- package/package.json +120 -118
- package/scripts/postInstall.cjs +70 -70
- package/templates/.codegen/codegen.ts +32 -32
- package/templates/.codegen/plugin-schema-object.js +154 -154
- package/dist/runtime/components/Camera.vue +0 -129
- package/dist/runtime/components/form/images/CameraCrop.vue +0 -58
- package/dist/runtime/components/form/images/Preview.vue +0 -48
|
@@ -1,62 +1,62 @@
|
|
|
1
|
-
<script lang="ts" setup>
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
interface Props extends /* @vue-ignore */ InstanceType<typeof VBtn['$props']> {
|
|
6
|
-
accept?: string
|
|
7
|
-
multiple?: boolean
|
|
8
|
-
iconOnly?: boolean
|
|
9
|
-
modelValue?: File | File[] | undefined
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const props = withDefaults(defineProps<Props>(), {
|
|
13
|
-
multiple: false,
|
|
14
|
-
accept: '*',
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
const emit = defineEmits<{
|
|
18
|
-
(event: 'update:modelValue', value: File | File[] | undefined): void
|
|
19
|
-
}>()
|
|
20
|
-
|
|
21
|
-
const fileInput = ref<HTMLInputElement>()
|
|
22
|
-
const files = ref<File | File[]>()
|
|
23
|
-
|
|
24
|
-
const openFileInput = () => {
|
|
25
|
-
fileInput.value?.click()
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const reset = () => {
|
|
29
|
-
files.value = undefined
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
watch(files, () => {
|
|
33
|
-
emit('update:modelValue', files.value)
|
|
34
|
-
}, { deep: true })
|
|
35
|
-
|
|
36
|
-
defineExpose({ reset })
|
|
37
|
-
</script>
|
|
38
|
-
|
|
39
|
-
<template>
|
|
40
|
-
<v-btn
|
|
41
|
-
v-bind="$attrs"
|
|
42
|
-
@click="openFileInput"
|
|
43
|
-
>
|
|
44
|
-
<template
|
|
45
|
-
v-for="(_, name, index) in ($slots as {})"
|
|
46
|
-
:key="index"
|
|
47
|
-
#[name]="slotData"
|
|
48
|
-
>
|
|
49
|
-
<slot
|
|
50
|
-
:name="name"
|
|
51
|
-
v-bind="(slotData as object)"
|
|
52
|
-
/>
|
|
53
|
-
</template>
|
|
54
|
-
</v-btn>
|
|
55
|
-
<v-file-input
|
|
56
|
-
ref="fileInput"
|
|
57
|
-
v-model="files"
|
|
58
|
-
:accept="props.accept"
|
|
59
|
-
:multiple="props.multiple"
|
|
60
|
-
style="display: none"
|
|
61
|
-
/>
|
|
62
|
-
</template>
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import {ref, watch} from 'vue'
|
|
3
|
+
import {VBtn} from 'vuetify/components/VBtn'
|
|
4
|
+
|
|
5
|
+
interface Props extends /* @vue-ignore */ InstanceType<typeof VBtn['$props']> {
|
|
6
|
+
accept?: string
|
|
7
|
+
multiple?: boolean
|
|
8
|
+
iconOnly?: boolean
|
|
9
|
+
modelValue?: File | File[] | undefined
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
13
|
+
multiple: false,
|
|
14
|
+
accept: '*',
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
const emit = defineEmits<{
|
|
18
|
+
(event: 'update:modelValue', value: File | File[] | undefined): void
|
|
19
|
+
}>()
|
|
20
|
+
|
|
21
|
+
const fileInput = ref<HTMLInputElement>()
|
|
22
|
+
const files = ref<File | File[]>()
|
|
23
|
+
|
|
24
|
+
const openFileInput = () => {
|
|
25
|
+
fileInput.value?.click()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const reset = () => {
|
|
29
|
+
files.value = undefined
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
watch(files, () => {
|
|
33
|
+
emit('update:modelValue', files.value)
|
|
34
|
+
}, { deep: true })
|
|
35
|
+
|
|
36
|
+
defineExpose({ reset })
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<template>
|
|
40
|
+
<v-btn
|
|
41
|
+
v-bind="$attrs"
|
|
42
|
+
@click="openFileInput"
|
|
43
|
+
>
|
|
44
|
+
<template
|
|
45
|
+
v-for="(_, name, index) in ($slots as {})"
|
|
46
|
+
:key="index"
|
|
47
|
+
#[name]="slotData"
|
|
48
|
+
>
|
|
49
|
+
<slot
|
|
50
|
+
:name="name"
|
|
51
|
+
v-bind="((slotData || {}) as object)"
|
|
52
|
+
/>
|
|
53
|
+
</template>
|
|
54
|
+
</v-btn>
|
|
55
|
+
<v-file-input
|
|
56
|
+
ref="fileInput"
|
|
57
|
+
v-model="files"
|
|
58
|
+
:accept="props.accept"
|
|
59
|
+
:multiple="props.multiple"
|
|
60
|
+
style="display: none"
|
|
61
|
+
/>
|
|
62
|
+
</template>
|
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
<script lang="ts" setup>
|
|
2
|
-
import * as XLSX from 'xlsx'
|
|
3
|
-
import {ref} from 'vue'
|
|
4
|
-
import {useAlert} from '../composables/alert'
|
|
5
|
-
|
|
6
|
-
const alert = useAlert()
|
|
7
|
-
const emit = defineEmits<{
|
|
8
|
-
(e: 'import', value: object[]): void
|
|
9
|
-
}>()
|
|
10
|
-
|
|
11
|
-
const loading = ref(false)
|
|
12
|
-
const fileBtnRef = ref()
|
|
13
|
-
|
|
14
|
-
function uploadedFile(files: File[] | File | undefined) {
|
|
15
|
-
if (!files) return
|
|
16
|
-
|
|
17
|
-
if (Array.isArray(files) && files.length != 1) {
|
|
18
|
-
alert?.addAlert({ message: 'Please select a single file for import', alertType: 'error' })
|
|
19
|
-
return
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (Array.isArray(files)) files = files[0]
|
|
23
|
-
|
|
24
|
-
const fileExtension = files.name.slice(files.name.lastIndexOf('.')).toLowerCase()
|
|
25
|
-
if (!['.xlsx', '.csv'].includes(fileExtension)) {
|
|
26
|
-
alert?.addAlert({ message: 'Please upload a file with .csv or .xlsx extension only (' + files.name + ')', alertType: 'error' })
|
|
27
|
-
return
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const reader = new FileReader()
|
|
31
|
-
reader.onload = (e: ProgressEvent<FileReader>) => {
|
|
32
|
-
const workbook = XLSX.read(e.target?.result)
|
|
33
|
-
emit('import', XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]]))
|
|
34
|
-
loading.value = false
|
|
35
|
-
fileBtnRef.value.reset()
|
|
36
|
-
}
|
|
37
|
-
loading.value = true
|
|
38
|
-
reader.readAsArrayBuffer(files)
|
|
39
|
-
}
|
|
40
|
-
</script>
|
|
41
|
-
|
|
42
|
-
<template>
|
|
43
|
-
<FileBtn
|
|
44
|
-
ref="fileBtnRef"
|
|
45
|
-
v-bind="$attrs"
|
|
46
|
-
color="primary"
|
|
47
|
-
:loading="loading"
|
|
48
|
-
text="Import CSV"
|
|
49
|
-
accept=".csv, .xlsx"
|
|
50
|
-
:multiple="false"
|
|
51
|
-
@update:model-value="uploadedFile"
|
|
52
|
-
>
|
|
53
|
-
<template
|
|
54
|
-
v-for="(_, name, index) in ($slots as {})"
|
|
55
|
-
:key="index"
|
|
56
|
-
#[name]="slotData"
|
|
57
|
-
>
|
|
58
|
-
<slot
|
|
59
|
-
:name="name"
|
|
60
|
-
v-bind="(slotData as object)"
|
|
61
|
-
/>
|
|
62
|
-
</template>
|
|
63
|
-
</FileBtn>
|
|
64
|
-
</template>
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import * as XLSX from 'xlsx'
|
|
3
|
+
import {ref} from 'vue'
|
|
4
|
+
import {useAlert} from '../composables/alert'
|
|
5
|
+
|
|
6
|
+
const alert = useAlert()
|
|
7
|
+
const emit = defineEmits<{
|
|
8
|
+
(e: 'import', value: object[]): void
|
|
9
|
+
}>()
|
|
10
|
+
|
|
11
|
+
const loading = ref(false)
|
|
12
|
+
const fileBtnRef = ref()
|
|
13
|
+
|
|
14
|
+
function uploadedFile(files: File[] | File | undefined) {
|
|
15
|
+
if (!files) return
|
|
16
|
+
|
|
17
|
+
if (Array.isArray(files) && files.length != 1) {
|
|
18
|
+
alert?.addAlert({ message: 'Please select a single file for import', alertType: 'error' })
|
|
19
|
+
return
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (Array.isArray(files)) files = files[0]
|
|
23
|
+
|
|
24
|
+
const fileExtension = files.name.slice(files.name.lastIndexOf('.')).toLowerCase()
|
|
25
|
+
if (!['.xlsx', '.csv'].includes(fileExtension)) {
|
|
26
|
+
alert?.addAlert({ message: 'Please upload a file with .csv or .xlsx extension only (' + files.name + ')', alertType: 'error' })
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const reader = new FileReader()
|
|
31
|
+
reader.onload = (e: ProgressEvent<FileReader>) => {
|
|
32
|
+
const workbook = XLSX.read(e.target?.result)
|
|
33
|
+
emit('import', XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]]))
|
|
34
|
+
loading.value = false
|
|
35
|
+
fileBtnRef.value.reset()
|
|
36
|
+
}
|
|
37
|
+
loading.value = true
|
|
38
|
+
reader.readAsArrayBuffer(files)
|
|
39
|
+
}
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<template>
|
|
43
|
+
<FileBtn
|
|
44
|
+
ref="fileBtnRef"
|
|
45
|
+
v-bind="$attrs"
|
|
46
|
+
color="primary"
|
|
47
|
+
:loading="loading"
|
|
48
|
+
text="Import CSV"
|
|
49
|
+
accept=".csv, .xlsx"
|
|
50
|
+
:multiple="false"
|
|
51
|
+
@update:model-value="uploadedFile"
|
|
52
|
+
>
|
|
53
|
+
<template
|
|
54
|
+
v-for="(_, name, index) in ($slots as {})"
|
|
55
|
+
:key="index"
|
|
56
|
+
#[name]="slotData"
|
|
57
|
+
>
|
|
58
|
+
<slot
|
|
59
|
+
:name="name"
|
|
60
|
+
v-bind="((slotData || {}) as object)"
|
|
61
|
+
/>
|
|
62
|
+
</template>
|
|
63
|
+
</FileBtn>
|
|
64
|
+
</template>
|
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import { ref } from 'vue'
|
|
3
|
-
import { VCard } from 'vuetify/components/VCard'
|
|
4
|
-
|
|
5
|
-
const isResizing = ref(false)
|
|
6
|
-
const pane1Width = ref('50%')
|
|
7
|
-
const containerRef = ref<HTMLElement>()
|
|
8
|
-
interface Props extends /* @vue-ignore */ InstanceType<typeof VCard['$props']> {
|
|
9
|
-
height?: number | string
|
|
10
|
-
}
|
|
11
|
-
const props = defineProps<Props>()
|
|
12
|
-
|
|
13
|
-
const startResize = () => {
|
|
14
|
-
isResizing.value = true
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const stopResize = () => {
|
|
18
|
-
isResizing.value = false
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const resize = (event: MouseEvent) => {
|
|
22
|
-
if (isResizing.value && containerRef.value) {
|
|
23
|
-
const containerRect = containerRef.value.getBoundingClientRect()
|
|
24
|
-
const newWidth = event.clientX - containerRect.left
|
|
25
|
-
pane1Width.value = `${(newWidth / containerRect.width) * 100}%`
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
</script>
|
|
29
|
-
|
|
30
|
-
<template>
|
|
31
|
-
<v-card :="$attrs">
|
|
32
|
-
<v-sheet
|
|
33
|
-
border
|
|
34
|
-
:height="height"
|
|
35
|
-
>
|
|
36
|
-
<div
|
|
37
|
-
ref="containerRef"
|
|
38
|
-
class="d-flex"
|
|
39
|
-
@mouseup="stopResize"
|
|
40
|
-
@mousemove="resize"
|
|
41
|
-
>
|
|
42
|
-
<v-sheet :width="pane1Width">
|
|
43
|
-
<slot name="left" />
|
|
44
|
-
</v-sheet>
|
|
45
|
-
<v-divider
|
|
46
|
-
:thickness="3"
|
|
47
|
-
vertical
|
|
48
|
-
class="cursor-move"
|
|
49
|
-
@mousedown="startResize"
|
|
50
|
-
/>
|
|
51
|
-
<v-sheet :width="`calc(100% - ${pane1Width})`">
|
|
52
|
-
<slot name="right" />
|
|
53
|
-
</v-sheet>
|
|
54
|
-
</div>
|
|
55
|
-
</v-sheet>
|
|
56
|
-
</v-card>
|
|
57
|
-
</template>
|
|
58
|
-
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
import { VCard } from 'vuetify/components/VCard'
|
|
4
|
+
|
|
5
|
+
const isResizing = ref(false)
|
|
6
|
+
const pane1Width = ref('50%')
|
|
7
|
+
const containerRef = ref<HTMLElement>()
|
|
8
|
+
interface Props extends /* @vue-ignore */ InstanceType<typeof VCard['$props']> {
|
|
9
|
+
height?: number | string
|
|
10
|
+
}
|
|
11
|
+
const props = defineProps<Props>()
|
|
12
|
+
|
|
13
|
+
const startResize = () => {
|
|
14
|
+
isResizing.value = true
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const stopResize = () => {
|
|
18
|
+
isResizing.value = false
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const resize = (event: MouseEvent) => {
|
|
22
|
+
if (isResizing.value && containerRef.value) {
|
|
23
|
+
const containerRect = containerRef.value.getBoundingClientRect()
|
|
24
|
+
const newWidth = event.clientX - containerRect.left
|
|
25
|
+
pane1Width.value = `${(newWidth / containerRect.width) * 100}%`
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<template>
|
|
31
|
+
<v-card :="$attrs">
|
|
32
|
+
<v-sheet
|
|
33
|
+
border
|
|
34
|
+
:height="height"
|
|
35
|
+
>
|
|
36
|
+
<div
|
|
37
|
+
ref="containerRef"
|
|
38
|
+
class="d-flex"
|
|
39
|
+
@mouseup="stopResize"
|
|
40
|
+
@mousemove="resize"
|
|
41
|
+
>
|
|
42
|
+
<v-sheet :width="pane1Width">
|
|
43
|
+
<slot name="left" />
|
|
44
|
+
</v-sheet>
|
|
45
|
+
<v-divider
|
|
46
|
+
:thickness="3"
|
|
47
|
+
vertical
|
|
48
|
+
class="cursor-move"
|
|
49
|
+
@mousedown="startResize"
|
|
50
|
+
/>
|
|
51
|
+
<v-sheet :width="`calc(100% - ${pane1Width})`">
|
|
52
|
+
<slot name="right" />
|
|
53
|
+
</v-sheet>
|
|
54
|
+
</div>
|
|
55
|
+
</v-sheet>
|
|
56
|
+
</v-card>
|
|
57
|
+
</template>
|
|
58
|
+
|
|
59
59
|
<style scoped>
|
|
60
60
|
|
|
61
|
-
</style>
|
|
61
|
+
</style>
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
<script lang="ts" setup>
|
|
2
|
-
import {ref} from 'vue'
|
|
3
|
-
import {VTabs} from 'vuetify/components'
|
|
4
|
-
|
|
5
|
-
interface Props extends /* @vue-ignore */ InstanceType<typeof VTabs['$props']> {
|
|
6
|
-
flat?: boolean
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
defineOptions({
|
|
10
|
-
inheritAttrs: false,
|
|
11
|
-
})
|
|
12
|
-
|
|
13
|
-
const props = defineProps<Props>()
|
|
14
|
-
const currentTab = ref<string | number>()
|
|
15
|
-
</script>
|
|
16
|
-
|
|
17
|
-
<template>
|
|
18
|
-
<v-card :flat="props.flat">
|
|
19
|
-
<v-tabs
|
|
20
|
-
v-bind="$attrs"
|
|
21
|
-
v-model="currentTab"
|
|
22
|
-
show-arrows
|
|
23
|
-
>
|
|
24
|
-
<slot name="tabs" />
|
|
25
|
-
</v-tabs>
|
|
26
|
-
<v-card-text>
|
|
27
|
-
<v-tabs-window v-model="currentTab">
|
|
28
|
-
<slot name="items" />
|
|
29
|
-
</v-tabs-window>
|
|
30
|
-
</v-card-text>
|
|
31
|
-
</v-card>
|
|
32
|
-
</template>
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import {ref} from 'vue'
|
|
3
|
+
import {VTabs} from 'vuetify/components'
|
|
4
|
+
|
|
5
|
+
interface Props extends /* @vue-ignore */ InstanceType<typeof VTabs['$props']> {
|
|
6
|
+
flat?: boolean
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
defineOptions({
|
|
10
|
+
inheritAttrs: false,
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
const props = defineProps<Props>()
|
|
14
|
+
const currentTab = ref<string | number>()
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<template>
|
|
18
|
+
<v-card :flat="props.flat">
|
|
19
|
+
<v-tabs
|
|
20
|
+
v-bind="$attrs"
|
|
21
|
+
v-model="currentTab"
|
|
22
|
+
show-arrows
|
|
23
|
+
>
|
|
24
|
+
<slot name="tabs" />
|
|
25
|
+
</v-tabs>
|
|
26
|
+
<v-card-text>
|
|
27
|
+
<v-tabs-window v-model="currentTab">
|
|
28
|
+
<slot name="items" />
|
|
29
|
+
</v-tabs-window>
|
|
30
|
+
</v-card-text>
|
|
31
|
+
</v-card>
|
|
32
|
+
</template>
|
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
<script lang="ts" setup>
|
|
2
|
-
import { ref, watch } from 'vue'
|
|
3
|
-
import { useAlert } from '../composables/alert'
|
|
4
|
-
|
|
5
|
-
interface Props {
|
|
6
|
-
modelValue?: string
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const props = defineProps<Props>()
|
|
10
|
-
const emit = defineEmits<{
|
|
11
|
-
(event: 'update:modelValue', value: string | undefined): void
|
|
12
|
-
}>()
|
|
13
|
-
const alert = useAlert()
|
|
14
|
-
|
|
15
|
-
const scanCode = ref<boolean>(false)
|
|
16
|
-
const currentValue = ref<string>()
|
|
17
|
-
|
|
18
|
-
const handleData = (data: string) => {
|
|
19
|
-
currentValue.value = data
|
|
20
|
-
scanCode.value = false
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const handleError = (error: string | unknown) => {
|
|
24
|
-
alert?.addAlert({ message: error as string, alertType: 'error' })
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
watch(() => props.modelValue, () => {
|
|
28
|
-
currentValue.value = props.modelValue
|
|
29
|
-
}, { immediate: true })
|
|
30
|
-
|
|
31
|
-
watch(currentValue, (newValue) => {
|
|
32
|
-
emit('update:modelValue', newValue)
|
|
33
|
-
})
|
|
34
|
-
</script>
|
|
35
|
-
|
|
36
|
-
<template>
|
|
37
|
-
<v-text-field
|
|
38
|
-
v-model="currentValue"
|
|
39
|
-
v-bind="$attrs"
|
|
40
|
-
append-inner-icon="mdi mdi-qrcode-scan"
|
|
41
|
-
@click:append-inner="scanCode = true"
|
|
42
|
-
/>
|
|
43
|
-
<v-dialog
|
|
44
|
-
v-model="scanCode"
|
|
45
|
-
width="auto"
|
|
46
|
-
>
|
|
47
|
-
<BarcodeReader
|
|
48
|
-
@decode="handleData"
|
|
49
|
-
@error="handleError"
|
|
50
|
-
/>
|
|
51
|
-
</v-dialog>
|
|
52
|
-
</template>
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { ref, watch } from 'vue'
|
|
3
|
+
import { useAlert } from '../composables/alert'
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
modelValue?: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const props = defineProps<Props>()
|
|
10
|
+
const emit = defineEmits<{
|
|
11
|
+
(event: 'update:modelValue', value: string | undefined): void
|
|
12
|
+
}>()
|
|
13
|
+
const alert = useAlert()
|
|
14
|
+
|
|
15
|
+
const scanCode = ref<boolean>(false)
|
|
16
|
+
const currentValue = ref<string>()
|
|
17
|
+
|
|
18
|
+
const handleData = (data: string) => {
|
|
19
|
+
currentValue.value = data
|
|
20
|
+
scanCode.value = false
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const handleError = (error: string | unknown) => {
|
|
24
|
+
alert?.addAlert({ message: error as string, alertType: 'error' })
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
watch(() => props.modelValue, () => {
|
|
28
|
+
currentValue.value = props.modelValue
|
|
29
|
+
}, { immediate: true })
|
|
30
|
+
|
|
31
|
+
watch(currentValue, (newValue) => {
|
|
32
|
+
emit('update:modelValue', newValue)
|
|
33
|
+
})
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
<template>
|
|
37
|
+
<v-text-field
|
|
38
|
+
v-model="currentValue"
|
|
39
|
+
v-bind="$attrs"
|
|
40
|
+
append-inner-icon="mdi mdi-qrcode-scan"
|
|
41
|
+
@click:append-inner="scanCode = true"
|
|
42
|
+
/>
|
|
43
|
+
<v-dialog
|
|
44
|
+
v-model="scanCode"
|
|
45
|
+
width="auto"
|
|
46
|
+
>
|
|
47
|
+
<BarcodeReader
|
|
48
|
+
@decode="handleData"
|
|
49
|
+
@error="handleError"
|
|
50
|
+
/>
|
|
51
|
+
</v-dialog>
|
|
52
|
+
</template>
|