@ramathibodi/nuxt-commons 0.1.73 → 0.1.75
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 +115 -96
- package/dist/module.json +1 -1
- package/dist/module.mjs +1 -0
- package/dist/runtime/components/Alert.vue +58 -54
- package/dist/runtime/components/BarcodeReader.vue +130 -122
- package/dist/runtime/components/ExportCSV.vue +110 -102
- package/dist/runtime/components/FileBtn.vue +79 -67
- package/dist/runtime/components/ImportCSV.vue +151 -139
- package/dist/runtime/components/MrzReader.vue +168 -0
- package/dist/runtime/components/SplitterPanel.vue +67 -59
- package/dist/runtime/components/TabsGroup.vue +39 -31
- package/dist/runtime/components/TextBarcode.vue +66 -54
- package/dist/runtime/components/device/IdCardButton.vue +95 -83
- package/dist/runtime/components/device/IdCardWebSocket.vue +207 -195
- package/dist/runtime/components/device/Scanner.vue +350 -338
- package/dist/runtime/components/dialog/Confirm.vue +112 -100
- package/dist/runtime/components/dialog/Host.vue +88 -84
- package/dist/runtime/components/dialog/Index.vue +84 -72
- package/dist/runtime/components/dialog/Loading.vue +51 -39
- package/dist/runtime/components/dialog/default/Confirm.vue +112 -100
- package/dist/runtime/components/dialog/default/Loading.vue +60 -48
- package/dist/runtime/components/dialog/default/Notify.vue +82 -70
- package/dist/runtime/components/dialog/default/Printing.vue +46 -34
- package/dist/runtime/components/dialog/default/VerifyUser.vue +144 -132
- package/dist/runtime/components/document/Form.vue +50 -42
- package/dist/runtime/components/document/TemplateBuilder.vue +536 -524
- package/dist/runtime/components/form/ActionPad.vue +156 -144
- package/dist/runtime/components/form/Birthdate.vue +116 -104
- package/dist/runtime/components/form/CheckboxGroup.vue +99 -87
- package/dist/runtime/components/form/CodeEditor.vue +45 -37
- package/dist/runtime/components/form/Date.vue +270 -258
- package/dist/runtime/components/form/DateTime.vue +220 -208
- package/dist/runtime/components/form/Dialog.vue +178 -166
- package/dist/runtime/components/form/EditPad.vue +157 -145
- package/dist/runtime/components/form/File.vue +295 -283
- package/dist/runtime/components/form/Hidden.vue +44 -32
- package/dist/runtime/components/form/Iterator.vue +538 -526
- package/dist/runtime/components/form/Login.vue +143 -131
- package/dist/runtime/components/form/Pad.vue +399 -387
- package/dist/runtime/components/form/SignPad.vue +226 -218
- package/dist/runtime/components/form/System.vue +34 -26
- package/dist/runtime/components/form/Table.vue +391 -379
- package/dist/runtime/components/form/TableData.vue +236 -224
- package/dist/runtime/components/form/Time.vue +177 -165
- package/dist/runtime/components/form/images/Capture.vue +245 -237
- package/dist/runtime/components/form/images/Edit.vue +133 -121
- package/dist/runtime/components/form/images/Field.vue +331 -320
- package/dist/runtime/components/form/images/Pad.vue +54 -42
- package/dist/runtime/components/label/Date.vue +37 -29
- package/dist/runtime/components/label/DateAgo.vue +102 -94
- package/dist/runtime/components/label/DateCount.vue +152 -144
- package/dist/runtime/components/label/Field.vue +111 -103
- package/dist/runtime/components/label/FormatMoney.vue +37 -29
- package/dist/runtime/components/label/Mask.vue +46 -38
- package/dist/runtime/components/label/Object.vue +21 -13
- package/dist/runtime/components/master/Autocomplete.vue +89 -81
- package/dist/runtime/components/master/Combobox.vue +88 -80
- package/dist/runtime/components/master/RadioGroup.vue +90 -78
- package/dist/runtime/components/master/Select.vue +70 -62
- package/dist/runtime/components/master/label.vue +55 -47
- package/dist/runtime/components/model/Autocomplete.vue +91 -79
- package/dist/runtime/components/model/Combobox.vue +90 -78
- package/dist/runtime/components/model/Pad.vue +114 -102
- package/dist/runtime/components/model/Select.vue +78 -72
- package/dist/runtime/components/model/Table.vue +370 -358
- package/dist/runtime/components/model/iterator.vue +497 -489
- package/dist/runtime/components/model/label.vue +58 -50
- package/dist/runtime/components/pdf/Print.vue +75 -63
- package/dist/runtime/components/pdf/View.vue +146 -134
- package/dist/runtime/composables/alert.d.ts +4 -0
- package/dist/runtime/composables/api.d.ts +4 -0
- package/dist/runtime/composables/dialog.d.ts +1 -1
- package/dist/runtime/composables/document/templateFormHidden.d.ts +4 -0
- package/dist/runtime/composables/graphql.d.ts +1 -1
- package/dist/runtime/composables/graphqlModel.d.ts +9 -9
- package/dist/runtime/composables/graphqlModelItem.d.ts +7 -7
- package/dist/runtime/composables/graphqlModelOperation.d.ts +6 -6
- package/dist/runtime/composables/localStorageModel.d.ts +4 -0
- package/dist/runtime/composables/lookupList.d.ts +4 -0
- package/dist/runtime/composables/menu.d.ts +4 -0
- package/dist/runtime/composables/useMrzReader.d.ts +48 -0
- package/dist/runtime/composables/useMrzReader.js +423 -0
- package/dist/runtime/composables/useTesseract.d.ts +16 -0
- package/dist/runtime/composables/useTesseract.js +45 -0
- package/dist/runtime/composables/userPermission.d.ts +1 -1
- 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/plugins/clientConfig.d.ts +1 -1
- package/dist/runtime/plugins/default.d.ts +1 -1
- package/dist/runtime/plugins/dialogManager.d.ts +1 -1
- package/dist/runtime/plugins/permission.d.ts +1 -1
- package/dist/runtime/types/alert.d.ts +11 -11
- package/dist/runtime/types/clientConfig.d.ts +13 -13
- package/dist/runtime/types/dialogManager.d.ts +35 -35
- package/dist/runtime/types/formDialog.d.ts +5 -5
- package/dist/runtime/types/graphqlOperation.d.ts +23 -23
- package/dist/runtime/types/menu.d.ts +31 -31
- package/dist/runtime/types/modules.d.ts +7 -7
- package/dist/runtime/types/permission.d.ts +13 -13
- package/dist/runtime/utils/asset.d.ts +2 -0
- package/dist/runtime/utils/asset.js +49 -0
- package/package.json +131 -122
- package/scripts/enrich-vue-docs-from-ai.mjs +197 -0
- package/scripts/generate-ai-summary.mjs +321 -0
- package/scripts/generate-composables-md.mjs +129 -0
- package/scripts/postInstall.cjs +70 -70
- package/templates/.codegen/codegen.ts +32 -32
- package/templates/.codegen/plugin-schema-object.js +161 -161
- package/templates/public/tesseract/mrz.traineddata.gz +0 -0
- package/templates/public/tesseract/ocrb.traineddata.gz +0 -0
|
@@ -1,78 +1,90 @@
|
|
|
1
|
-
<script lang="ts" setup>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
lang
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
/**
|
|
3
|
+
* MasterRadioGroup renders master-data driven option controls and synchronizes selected values with form models.
|
|
4
|
+
* This doc block is consumed by vue-docgen for generated API documentation.
|
|
5
|
+
*/
|
|
6
|
+
import {VRadioGroup} from 'vuetify/components/VRadioGroup'
|
|
7
|
+
import {computed, ref, watch} from 'vue'
|
|
8
|
+
import {concat} from 'lodash-es'
|
|
9
|
+
import {useAlert} from '../../composables/alert'
|
|
10
|
+
import {useGraphQl} from '../../composables/graphql'
|
|
11
|
+
|
|
12
|
+
interface Props extends /* @vue-ignore */ InstanceType<typeof VRadioGroup['$props']> {
|
|
13
|
+
returnObject?: boolean // Emits the full selected object instead of only primitive value.
|
|
14
|
+
groupKey: string // Master-data group key used to fetch option items.
|
|
15
|
+
modelValue?: any // Bound value for v-model synchronization with the parent component.
|
|
16
|
+
fields?: string[] // Field list/query selection used when fetching model or lookup data.
|
|
17
|
+
lang?: 'TH' | 'EN' // Language code used when selecting localized option labels.
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Public props accepted by MasterRadioGroup.
|
|
22
|
+
* Document each prop field with intent, defaults, and side effects for clear generated docs.
|
|
23
|
+
*/
|
|
24
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
25
|
+
lang: 'TH',
|
|
26
|
+
})
|
|
27
|
+
/**
|
|
28
|
+
* Custom events emitted by MasterRadioGroup.
|
|
29
|
+
* Parents can listen to these events to react to user actions and internal state changes.
|
|
30
|
+
*/
|
|
31
|
+
const emit = defineEmits(['update:modelValue'])
|
|
32
|
+
const items: any = ref([])
|
|
33
|
+
const value = ref()
|
|
34
|
+
const alert = useAlert()
|
|
35
|
+
const query = () => {
|
|
36
|
+
const variables = { groupKey: {
|
|
37
|
+
name: 'groupKey',
|
|
38
|
+
type: 'String!',
|
|
39
|
+
value: props.groupKey,
|
|
40
|
+
} }
|
|
41
|
+
let fields: any[] = ['itemCode', 'itemValue', 'itemValueAlternative']
|
|
42
|
+
if (props.fields) fields = concat(fields, props.fields)
|
|
43
|
+
|
|
44
|
+
useGraphQl().queryPromise('masterItemByGroupKey', fields, variables).then((result: any) => {
|
|
45
|
+
items.value = result
|
|
46
|
+
}).catch((error) => {
|
|
47
|
+
alert?.addAlert({
|
|
48
|
+
message: `${error.message}`,
|
|
49
|
+
alertType: 'error',
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
query()
|
|
54
|
+
|
|
55
|
+
watch(() => props.modelValue, (newValue) => {
|
|
56
|
+
value.value = props.modelValue
|
|
57
|
+
}, { deep: true, immediate: true })
|
|
58
|
+
|
|
59
|
+
const itemTitleField = computed(() => {
|
|
60
|
+
if (props.lang == 'TH') return 'itemValue'
|
|
61
|
+
else return 'itemValueAlternative'
|
|
62
|
+
})
|
|
63
|
+
</script>
|
|
64
|
+
|
|
65
|
+
<template>
|
|
66
|
+
<v-radio-group
|
|
67
|
+
v-model="value"
|
|
68
|
+
v-bind="$attrs"
|
|
69
|
+
@update:model-value="emit('update:modelValue', value.value)"
|
|
70
|
+
>
|
|
71
|
+
<template
|
|
72
|
+
v-for="(_, name, index) in ($slots as {})"
|
|
73
|
+
:key="index"
|
|
74
|
+
#[name]="slotData"
|
|
75
|
+
>
|
|
76
|
+
<slot
|
|
77
|
+
:name="name"
|
|
78
|
+
v-bind="((slotData || {}) as object)"
|
|
79
|
+
:operation="operation"
|
|
80
|
+
/>
|
|
81
|
+
</template>
|
|
82
|
+
<v-radio
|
|
83
|
+
v-for="i in items"
|
|
84
|
+
:key="i.itemCode"
|
|
85
|
+
v-bind="$attrs"
|
|
86
|
+
:label="i[itemTitleField]"
|
|
87
|
+
:value="returnObject ? i : i.itemCode"
|
|
88
|
+
/>
|
|
89
|
+
</v-radio-group>
|
|
90
|
+
</template>
|
|
@@ -1,63 +1,71 @@
|
|
|
1
|
-
<script lang="ts" setup>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
:
|
|
44
|
-
:
|
|
45
|
-
:
|
|
46
|
-
:
|
|
47
|
-
:
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
<template v-
|
|
60
|
-
|
|
61
|
-
</template>
|
|
62
|
-
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
/**
|
|
3
|
+
* MasterSelect renders master-data driven option controls and synchronizes selected values with form models.
|
|
4
|
+
* This doc block is consumed by vue-docgen for generated API documentation.
|
|
5
|
+
*/
|
|
6
|
+
import { VSelect } from 'vuetify/components/VSelect'
|
|
7
|
+
import { withDefaults } from 'vue'
|
|
8
|
+
import { useLookupListMaster, type StaticMasterLikeProps } from '../../composables/lookupListMaster'
|
|
9
|
+
|
|
10
|
+
interface Props extends /* @vue-ignore */ InstanceType<typeof VSelect['$props']> {}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Public props accepted by MasterSelect.
|
|
14
|
+
* Document each prop field with intent, defaults, and side effects for clear generated docs.
|
|
15
|
+
*/
|
|
16
|
+
const props = withDefaults(defineProps<Props & StaticMasterLikeProps>(), {
|
|
17
|
+
sortBy: 'itemValue', // Field used to sort options before rendering.
|
|
18
|
+
showCode: false, // Displays code values alongside labels in option lists.
|
|
19
|
+
lang: 'TH', // Language code used when selecting localized option labels.
|
|
20
|
+
noDataText: 'ไม่พบข้อมูล', // Fallback message shown when there is no data to display.
|
|
21
|
+
waitForFilter: false, // Delays loading options until the user provides a search/filter value.
|
|
22
|
+
cache: false, // Enables cached requests; number values represent cache TTL in milliseconds.
|
|
23
|
+
|
|
24
|
+
statusField: 'statusCode', // Field name that indicates active/inactive status in each item.
|
|
25
|
+
activeValue: 'active', // Value in statusField treated as active/selectable.
|
|
26
|
+
hideInactiveInList: true, // Hides inactive options from the displayed selection list.
|
|
27
|
+
preventSelectingInactive: true, // Blocks selecting inactive options even if present in the dataset.
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
const {
|
|
31
|
+
computedModelName,
|
|
32
|
+
computedModelBy,
|
|
33
|
+
computedFields,
|
|
34
|
+
itemTitleField,
|
|
35
|
+
computedNoDataText,
|
|
36
|
+
computedSortBy,
|
|
37
|
+
formatItemTitle,
|
|
38
|
+
} = useLookupListMaster(props)
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<template>
|
|
42
|
+
<model-select
|
|
43
|
+
:model-name="computedModelName"
|
|
44
|
+
:model-by="computedModelBy"
|
|
45
|
+
:fields="computedFields"
|
|
46
|
+
:sort-by="computedSortBy"
|
|
47
|
+
:item-title="itemTitleField"
|
|
48
|
+
item-value="itemCode"
|
|
49
|
+
:no-data-text="computedNoDataText"
|
|
50
|
+
:show-code="props.showCode"
|
|
51
|
+
:cache="props.cache"
|
|
52
|
+
:status-field="props.statusField"
|
|
53
|
+
:active-value="props.activeValue"
|
|
54
|
+
:hide-inactive-in-list="props.hideInactiveInList"
|
|
55
|
+
:prevent-selecting-inactive="props.preventSelectingInactive"
|
|
56
|
+
>
|
|
57
|
+
<!-- pass-through slots -->
|
|
58
|
+
<!-- @ts-ignore -->
|
|
59
|
+
<template v-for="(_, name, index) in ($slots as {})" :key="index" #[name]="slotData">
|
|
60
|
+
<slot :name="name" v-bind="((slotData || {}) as object)" :operation="computedModelName" />
|
|
61
|
+
</template>
|
|
62
|
+
|
|
63
|
+
<template v-if="!$slots.item" #item="{ props: itemProps, item }">
|
|
64
|
+
<v-list-item v-bind="itemProps" :title="formatItemTitle(item)" />
|
|
65
|
+
</template>
|
|
66
|
+
|
|
67
|
+
<template v-if="!$slots.selection && props.showCode" #selection="{ item }">
|
|
68
|
+
{{ formatItemTitle(item) }}
|
|
69
|
+
</template>
|
|
70
|
+
</model-select>
|
|
63
71
|
</template>
|
|
@@ -1,47 +1,55 @@
|
|
|
1
|
-
<script lang="ts" setup>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
return
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
:
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
/**
|
|
3
|
+
* MasterLabel renders master-data driven option controls and synchronizes selected values with form models.
|
|
4
|
+
* This doc block is consumed by vue-docgen for generated API documentation.
|
|
5
|
+
*/
|
|
6
|
+
import {computed} from "vue";
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
groupKey?: string | null // Master-data group key used to fetch option items.
|
|
10
|
+
itemCode?: string | null // Master-data item code used to resolve a single label.
|
|
11
|
+
locale?: string // Locale used for date/time formatting and localized labels.
|
|
12
|
+
cache?: boolean | number // Enables cached requests; number values represent cache TTL in milliseconds.
|
|
13
|
+
|
|
14
|
+
notFoundText?: string // Text shown when the resolved value or label is unavailable.
|
|
15
|
+
placeholder?: string // placeholder text shown when value is empty
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Public props accepted by MasterLabel.
|
|
20
|
+
* Document each prop field with intent, defaults, and side effects for clear generated docs.
|
|
21
|
+
*/
|
|
22
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
23
|
+
locale: 'TH',
|
|
24
|
+
cache: false,
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
const computedNotFoundText = computed(()=>{
|
|
28
|
+
return props.notFoundText || `${props.itemCode}`
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
const computedPlaceholder = computed(()=>{
|
|
32
|
+
return props.placeholder || `${props.groupKey}(${props.itemCode})`
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
const computedItemTitle = computed(()=>{
|
|
36
|
+
return (props.locale == 'TH')
|
|
37
|
+
? "itemValue"
|
|
38
|
+
: (result : Record<string,any>) => result["itemValueAlternative"] || result["itemValue"]
|
|
39
|
+
})
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<template>
|
|
43
|
+
<model-label
|
|
44
|
+
model-name="masterItemByGroupKeyAndItemCode"
|
|
45
|
+
:model-by="{groupKey: props.groupKey, itemCode: props.itemCode}"
|
|
46
|
+
:item-title="computedItemTitle"
|
|
47
|
+
:not-found-text="computedNotFoundText"
|
|
48
|
+
:placeholder="computedPlaceholder"
|
|
49
|
+
:cache="props.cache"
|
|
50
|
+
>
|
|
51
|
+
<template v-for="(_, name, index) in ($slots as {})" :key="index" #[name]="slotData">
|
|
52
|
+
<slot :name="name" v-bind="((slotData || {}) as object)" />
|
|
53
|
+
</template>
|
|
54
|
+
</model-label>
|
|
55
|
+
</template>
|
|
@@ -1,79 +1,91 @@
|
|
|
1
|
-
<script lang="ts" setup>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
:
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
<template v-
|
|
76
|
-
<
|
|
77
|
-
</template>
|
|
78
|
-
|
|
79
|
-
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
/**
|
|
3
|
+
* ModelAutocomplete connects model metadata to reusable selection, labeling, iterator, or table UI patterns.
|
|
4
|
+
* This doc block is consumed by vue-docgen for generated API documentation.
|
|
5
|
+
*/
|
|
6
|
+
import { VAutocomplete } from 'vuetify/components/VAutocomplete'
|
|
7
|
+
import { defineModel, withDefaults } from 'vue'
|
|
8
|
+
import { useLookupList, type LookupProps } from '../../composables/lookupList'
|
|
9
|
+
import { useLocalStorageModel, type PersistSlimProps } from '../../composables/localStorageModel'
|
|
10
|
+
|
|
11
|
+
interface Props extends /* @vue-ignore */ InstanceType<typeof VAutocomplete['$props']> {}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Public props accepted by ModelAutocomplete.
|
|
15
|
+
* Document each prop field with intent, defaults, and side effects for clear generated docs.
|
|
16
|
+
*/
|
|
17
|
+
const props = withDefaults(defineProps<Props & LookupProps & PersistSlimProps>(), {
|
|
18
|
+
fuzzy: false, // Enables fuzzy matching when filtering local options.
|
|
19
|
+
showCode: false, // Displays code values alongside labels in option lists.
|
|
20
|
+
cache: false, // Enables cached requests; number values represent cache TTL in milliseconds.
|
|
21
|
+
|
|
22
|
+
serverSearch: false, // Uses remote search requests instead of local filtering.
|
|
23
|
+
searchSearchSort: false, // Sorts server-search results based on search relevance.
|
|
24
|
+
serverSearchText: 'Type to search…', // Placeholder/help text shown before server search starts.
|
|
25
|
+
serverSearchLoadingText: 'Searching…', // Status text shown while server search request is running.
|
|
26
|
+
serverSearchDebounce: 500, // Debounce delay in milliseconds before sending server search.
|
|
27
|
+
|
|
28
|
+
statusField: 'statusCode', // Field name that indicates active/inactive status in each item.
|
|
29
|
+
activeValue: 'active', // Value in statusField treated as active/selectable.
|
|
30
|
+
hideInactiveInList: false, // Hides inactive options from the displayed selection list.
|
|
31
|
+
preventSelectingInactive: false, // Blocks selecting inactive options even if present in the dataset.
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Custom events emitted by ModelAutocomplete.
|
|
36
|
+
* Parents can listen to these events to react to user actions and internal state changes.
|
|
37
|
+
*/
|
|
38
|
+
const emit = defineEmits<{
|
|
39
|
+
(e: 'update:selectedObject', object: any | any[]): void
|
|
40
|
+
}>()
|
|
41
|
+
|
|
42
|
+
const selectedItems = defineModel<any>()
|
|
43
|
+
useLocalStorageModel(selectedItems, props)
|
|
44
|
+
|
|
45
|
+
const {
|
|
46
|
+
searchData,
|
|
47
|
+
computedItems,
|
|
48
|
+
computedFilterKeys,
|
|
49
|
+
computedPlaceholder,
|
|
50
|
+
computedNoDataText,
|
|
51
|
+
isLoading,
|
|
52
|
+
isErrorLoading,
|
|
53
|
+
onUpdateModelValue, // ✅ moved into composable
|
|
54
|
+
} = useLookupList(props as any, emit, selectedItems)
|
|
55
|
+
</script>
|
|
56
|
+
|
|
57
|
+
<template>
|
|
58
|
+
<v-autocomplete
|
|
59
|
+
:model-value="selectedItems"
|
|
60
|
+
@update:model-value="onUpdateModelValue"
|
|
61
|
+
v-model:search="searchData"
|
|
62
|
+
v-bind="$attrs"
|
|
63
|
+
:items="computedItems"
|
|
64
|
+
:filter-keys="computedFilterKeys"
|
|
65
|
+
:no-filter="props.fuzzy || props.serverSearch"
|
|
66
|
+
:item-title="props.itemTitle"
|
|
67
|
+
:item-value="props.itemValue"
|
|
68
|
+
:loading="isLoading"
|
|
69
|
+
:placeholder="computedPlaceholder"
|
|
70
|
+
:no-data-text="computedNoDataText"
|
|
71
|
+
:multiple="props.multiple"
|
|
72
|
+
>
|
|
73
|
+
<!-- passthrough slots -->
|
|
74
|
+
<!-- @ts-ignore -->
|
|
75
|
+
<template v-for="(_, name, index) in ($slots as {})" :key="index" #[name]="slotData">
|
|
76
|
+
<slot :name="name" v-bind="((slotData || {}) as object)" />
|
|
77
|
+
</template>
|
|
78
|
+
|
|
79
|
+
<template v-if="!$slots.item" #item="{ props: itemProps, item }">
|
|
80
|
+
<v-list-item v-bind="itemProps" :title="(props.showCode ? item.value + '-' : '') + item.title" />
|
|
81
|
+
</template>
|
|
82
|
+
|
|
83
|
+
<template v-if="!$slots.selection && props.showCode" #selection="{ item }">
|
|
84
|
+
{{ item.value + '-' + item.title }}
|
|
85
|
+
</template>
|
|
86
|
+
|
|
87
|
+
<template v-if="isErrorLoading" #append>
|
|
88
|
+
<v-icon color="error">mdi mdi-alert</v-icon>
|
|
89
|
+
</template>
|
|
90
|
+
</v-autocomplete>
|
|
91
|
+
</template>
|