@ramathibodi/nuxt-commons 0.1.56 → 0.1.58

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 (31) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/components/document/TemplateBuilder.vue +133 -122
  3. package/dist/runtime/components/form/Pad.vue +39 -0
  4. package/dist/runtime/components/form/TableData.vue +180 -41
  5. package/dist/runtime/components/label/DateCount.vue +40 -0
  6. package/dist/runtime/components/label/Object.vue +14 -0
  7. package/dist/runtime/components/master/Autocomplete.vue +25 -108
  8. package/dist/runtime/components/master/Combobox.vue +59 -83
  9. package/dist/runtime/components/model/Autocomplete.vue +23 -234
  10. package/dist/runtime/components/model/Combobox.vue +70 -0
  11. package/dist/runtime/composables/document/template.d.ts +4 -1
  12. package/dist/runtime/composables/document/template.js +22 -15
  13. package/dist/runtime/composables/document/templateFormHidden.d.ts +1 -1
  14. package/dist/runtime/composables/document/templateFormHidden.js +5 -2
  15. package/dist/runtime/composables/document/templateFormTable.d.ts +3 -2
  16. package/dist/runtime/composables/document/templateFormTable.js +36 -40
  17. package/dist/runtime/composables/document/templateFormTableData.d.ts +2 -0
  18. package/dist/runtime/composables/document/templateFormTableData.js +21 -0
  19. package/dist/runtime/composables/graphqlModel.d.ts +6 -6
  20. package/dist/runtime/composables/graphqlModelItem.d.ts +4 -4
  21. package/dist/runtime/composables/graphqlModelOperation.d.ts +6 -6
  22. package/dist/runtime/composables/lookupList.d.ts +44 -0
  23. package/dist/runtime/composables/lookupList.js +194 -0
  24. package/dist/runtime/composables/lookupListMaster.d.ts +28 -0
  25. package/dist/runtime/composables/lookupListMaster.js +61 -0
  26. package/dist/runtime/types/menu.d.ts +7 -4
  27. package/dist/runtime/utils/formatter.d.ts +1 -0
  28. package/dist/runtime/utils/formatter.js +19 -0
  29. package/dist/runtime/utils/object.d.ts +1 -0
  30. package/dist/runtime/utils/object.js +46 -1
  31. package/package.json +2 -1
@@ -0,0 +1,40 @@
1
+ <script setup lang="ts">
2
+ import { DateTime } from "luxon";
3
+ import { computed } from "vue";
4
+
5
+ type Locale = "th" | "en" | "en-US" | "th-TH";
6
+
7
+ interface Props {
8
+ modelValue: DateTime;
9
+ endDate?: DateTime;
10
+ locale?: Locale;
11
+ zeroBase?: boolean; // true = start at 0, false = start at 1
12
+ }
13
+
14
+ const props = withDefaults(defineProps<Props>(), {
15
+ locale: "th",
16
+ zeroBase: true,
17
+ });
18
+
19
+ const normalizeLocale = (locale: Locale): "en" | "th" =>
20
+ locale.startsWith("en") ? "en" : "th";
21
+
22
+ const countDate = computed(() => {
23
+ const base = props.endDate ?? DateTime.now();
24
+ const baseLocale = normalizeLocale(props.locale);
25
+
26
+ let days = Math.floor(base.diff(props.modelValue, "days").days ?? 0);
27
+
28
+ if (!props.zeroBase) days += 1;
29
+
30
+ if (baseLocale === "en") {
31
+ return days === 1 ? "1 day" : `${days} days`;
32
+ }
33
+
34
+ return `${days} วัน`;
35
+ });
36
+ </script>
37
+
38
+ <template>
39
+ <span>{{ countDate }}</span>
40
+ </template>
@@ -0,0 +1,14 @@
1
+ <script lang="ts" setup>
2
+ import {joinObject} from "../../utils/formatter";
3
+
4
+ interface Props {
5
+ object: any,
6
+ attribute?: string,
7
+ separator?: string,
8
+ }
9
+ const props = withDefaults(defineProps<Props>(), {
10
+ })
11
+ </script>
12
+ <template>
13
+ <span>{{joinObject(object,attribute,separator)}}</span>
14
+ </template>
@@ -1,95 +1,30 @@
1
1
  <script lang="ts" setup>
2
- import {VAutocomplete} from 'vuetify/components/VAutocomplete'
3
- import {union} from 'lodash-es'
4
- import {computed} from 'vue'
2
+ import { VAutocomplete } from 'vuetify/components/VAutocomplete'
3
+ import { withDefaults } from 'vue'
4
+ import { useLookupListMaster, type MasterLikeProps } from '../../composables/lookupListMaster'
5
5
 
6
- interface Props extends /* @vue-ignore */ InstanceType<typeof VAutocomplete['$props']> {
7
- sortBy?: 'itemCode' | 'itemValue'
8
- showCode?: boolean
6
+ interface Props extends /* @vue-ignore */ InstanceType<typeof VAutocomplete['$props']> {}
9
7
 
10
- groupKey: string
11
- itemCodes?: string[]
12
- lang?: 'TH' | 'EN'
13
- fields?: Array<string | object>
14
- noDataText?: string
15
- filterText?: string
16
- waitForFilter?: boolean
17
- waitForFilterText?: string
18
-
19
- meilisearch?: boolean
20
-
21
- cache?: boolean | number
22
- }
23
-
24
- const props = withDefaults(defineProps<Props>(), {
8
+ const props = withDefaults(defineProps<Props & MasterLikeProps>(), {
25
9
  sortBy: 'itemValue',
26
10
  showCode: false,
27
-
28
11
  lang: 'TH',
29
12
  noDataText: 'ไม่พบข้อมูล',
30
13
  waitForFilter: false,
31
-
32
14
  meilisearch: false,
33
-
34
15
  cache: false,
35
16
  })
36
17
 
37
- const computedModelName = computed(()=>{
38
- let operation = 'masterItemByGroupKey'
39
- if (props.filterText) operation = 'masterItemByGroupKeyAndFilterText'
40
- if (props.itemCodes && props.itemCodes.length>0) operation = 'masterItemByGroupKeyAndItemCodeIn'
41
- if (props.meilisearch) operation = 'masterItemByGroupKeyAndFilterTextAndKeyword'
42
- if (props.waitForFilter && !props.filterText) operation = ""
43
- return operation
44
- })
45
-
46
- const computedModelBy = computed(()=>{
47
- let modelBy : Record<string,any> = {groupKey: props.groupKey}
48
- if (props.filterText) {
49
- modelBy["filterText"] = props.filterText
50
- }
51
- if (props.itemCodes && props.itemCodes.length>0) {
52
- modelBy["itemCodes"] = props.itemCodes
53
- }
54
- return modelBy
55
- })
56
-
57
- const computedModelSelectedItemBy = computed(()=>{
58
- return {groupKey: props.groupKey}
59
- })
60
-
61
- const computedFields = computed(()=>{
62
- let fields : Array<string | object> = []
63
- if (props.filterText) fields.push('filterText')
64
- if (props.meilisearch) fields.push('_formatted')
65
- return union(['itemCode', 'itemValue', 'itemValueAlternative'],fields,props.fields || [])
66
- })
67
-
68
- const itemTitleField = computed(() => {
69
- return (props.lang == 'TH') ? 'itemValue' : 'itemValueAlternative'
70
- })
71
-
72
- const formatItemTitle = (item: any)=>{
73
- if (props.meilisearch) {
74
- return (props.showCode ? item.raw?._formatted?.itemCode+'-' : '')+(item.raw?._formatted?.[itemTitleField.value] || item.raw?._formatted?.itemValue || item.raw?._formatted?.itemCode)
75
- } else {
76
- return (props.showCode ? item.raw.itemCode+'-' : '')+(item.title || item.raw.itemValue || item.raw.itemCode)
77
- }
78
- }
79
-
80
- const computedNoDataText = computed(() => {
81
- if (props.waitForFilter && !props.filterText) return props.waitForFilterText
82
- return props.noDataText
83
- })
84
-
85
- const computedSortBy = computed(()=>{
86
- if (props.sortBy == 'itemValue') {
87
- if (props.showCode) return ['itemCode']
88
- else return [itemTitleField.value,'itemValue','itemCode']
89
- } else {
90
- return [props.sortBy]
91
- }
92
- })
18
+ const {
19
+ computedModelName,
20
+ computedModelBy,
21
+ computedModelSelectedItemBy,
22
+ computedFields,
23
+ itemTitleField,
24
+ computedNoDataText,
25
+ computedSortBy,
26
+ formatItemTitle,
27
+ } = useLookupListMaster(props)
93
28
  </script>
94
29
 
95
30
  <template>
@@ -109,43 +44,25 @@ const computedSortBy = computed(()=>{
109
44
  :model-selected-item-by="computedModelSelectedItemBy"
110
45
  model-selected-item-key="itemCodes"
111
46
  >
112
- <template
113
- v-for="(_, name, index) in ($slots as {})"
114
- :key="index"
115
- #[name]="slotData"
116
- >
117
- <slot
118
- :name="name"
119
- v-bind="((slotData || {}) as object)"
120
- :operation="operation"
121
- />
47
+ <!-- pass-through slots -->
48
+ <!-- @ts-ignore -->
49
+ <template v-for="(_, name, index) in ($slots as {})" :key="index" #[name]="slotData">
50
+ <slot :name="name" v-bind="((slotData || {}) as object)" :operation="computedModelName" />
122
51
  </template>
123
52
 
124
- <template
125
- v-if="!$slots.item && !meilisearch"
126
- #item="{ props, item }"
127
- >
128
- <v-list-item
129
- v-bind="props"
130
- :title="formatItemTitle(item)"
131
- />
53
+ <template v-if="!$slots.item && !props.meilisearch" #item="{ props: itemProps, item }">
54
+ <v-list-item v-bind="itemProps" :title="formatItemTitle(item)" />
132
55
  </template>
133
56
 
134
- <template
135
- v-if="!$slots.item && meilisearch"
136
- #item="{ props, item }"
137
- >
138
- <v-list-item v-bind="props">
57
+ <template v-if="!$slots.item && props.meilisearch" #item="{ props: itemProps, item }">
58
+ <v-list-item v-bind="itemProps">
139
59
  <template #title v-if="item.raw?._formatted?.itemValue">
140
60
  <span v-html="formatItemTitle(item)" class="meilisearch-item"></span>
141
61
  </template>
142
62
  </v-list-item>
143
63
  </template>
144
64
 
145
- <template
146
- v-if="!$slots.selection && showCode"
147
- #selection="{ item }"
148
- >
65
+ <template v-if="!$slots.selection && props.showCode" #selection="{ item }">
149
66
  {{ formatItemTitle(item) }}
150
67
  </template>
151
68
  </model-autocomplete>
@@ -153,4 +70,4 @@ const computedSortBy = computed(()=>{
153
70
 
154
71
  <style>
155
72
  .meilisearch-item em{font-weight:700}
156
- </style>
73
+ </style>
@@ -1,97 +1,73 @@
1
- <script setup lang="ts">
2
- import {VCombobox} from 'vuetify/components/VCombobox'
3
- import {computed, ref, watch} from 'vue'
4
- import {concat} from 'lodash-es'
5
- import {useAlert} from '../../composables/alert'
6
- import {useGraphQl} from '../../composables/graphql'
1
+ <script lang="ts" setup>
2
+ import { VCombobox } from 'vuetify/components/VCombobox'
3
+ import { withDefaults } from 'vue'
4
+ import { useLookupListMaster, type MasterLikeProps } from '../../composables/lookupListMaster'
7
5
 
8
- interface Props extends /* @vue-ignore */ InstanceType<typeof VCombobox['$props']> {
9
- modelValue?: string
10
- groupKey: string
11
- fields?: string[]
12
- lang?: 'TH' | 'EN'
13
- }
6
+ interface Props extends /* @vue-ignore */ InstanceType<typeof VCombobox['$props']> {}
14
7
 
15
- const props = withDefaults(defineProps<Props>(), {
8
+ const props = withDefaults(defineProps<Props & MasterLikeProps>(), {
9
+ sortBy: 'itemValue',
10
+ showCode: false,
16
11
  lang: 'TH',
12
+ noDataText: 'ไม่พบข้อมูล',
13
+ waitForFilter: false,
14
+ meilisearch: false,
15
+ cache: false,
17
16
  })
18
17
 
19
- const emit = defineEmits(['update:modelValue'])
20
- const items = ref<Array<any>>([])
21
- const alert = useAlert()
22
- const selectedItem = ref<any>()
23
- function query() {
24
- const variables: Record<string, any> = { groupKey: { value: props.groupKey, required: true } }
25
- let fields: any[] = ['itemCode', 'itemValue', 'itemValueAlternative']
26
- if (props.fields) fields = concat(fields, props.fields)
27
-
28
- useGraphQl().queryPromise('masterItemByGroupKey', fields, variables).then((result: any) => {
29
- items.value = result
30
- }).catch((error) => {
31
- alert?.addAlert({
32
- message: `${error.message}`,
33
- alertType: 'error',
34
- })
35
- })
36
- }
37
-
38
- watch(() => props.groupKey, () => {
39
- query()
40
- }, { immediate: true })
41
-
42
- watch(selectedItem, (newValue) => {
43
- emit('update:modelValue', newValue.itemCode)
44
- })
45
-
46
- watch(
47
- () => props.modelValue,
48
- (newVal) => {
49
- if (newVal && items.value.length > 0) {
50
- const found = items.value.find(item => item.itemCode === newVal)
51
- if (found) selectedItem.value = found
52
- }
53
- },
54
- { immediate: true }
55
- )
56
-
57
- const itemTitleField = computed(() => {
58
- if (props.lang == 'TH') return 'itemValue'
59
- else return 'itemValueAlternative'
60
- })
61
-
62
- query()
18
+ const {
19
+ computedModelName,
20
+ computedModelBy,
21
+ computedModelSelectedItemBy,
22
+ computedFields,
23
+ itemTitleField,
24
+ computedNoDataText,
25
+ computedSortBy,
26
+ formatItemTitle,
27
+ } = useLookupListMaster(props)
63
28
  </script>
64
29
 
65
30
  <template>
66
- <v-combobox
67
- v-model="selectedItem"
68
- :items="items"
69
- :item-title="itemTitleField"
70
- item-value="itemCode"
31
+ <model-combobox
32
+ :model-name="computedModelName"
33
+ :model-by="computedModelBy"
34
+ :fields="computedFields"
35
+ :sort-by="computedSortBy"
36
+ :item-title="itemTitleField"
37
+ item-value="itemCode"
38
+ :no-data-text="computedNoDataText"
39
+ :show-code="props.showCode"
40
+ :cache="props.cache && !props.meilisearch"
41
+ :server-search="props.meilisearch && !!computedModelName"
42
+ server-search-key="keyword"
43
+ model-selected-item="masterItemByGroupKeyAndItemCodeIn"
44
+ :model-selected-item-by="computedModelSelectedItemBy"
45
+ model-selected-item-key="itemCodes"
71
46
  >
72
- <template
73
- v-for="(_, name, index) in ($slots as {})"
74
- :key="index"
75
- #[name]="slotData"
76
- >
77
- <slot
78
- :name="name"
79
- v-bind="((slotData || {}) as object)"
80
- :operation="operation"
81
- />
47
+ <!-- pass-through slots -->
48
+ <!-- @ts-ignore -->
49
+ <template v-for="(_, name, index) in ($slots as {})" :key="index" #[name]="slotData">
50
+ <slot :name="name" v-bind="((slotData || {}) as object)" :operation="computedModelName" />
82
51
  </template>
83
- <template
84
- v-if="!$slots.item"
85
- #item="{ props, item }"
86
- >
87
- <v-list-item
88
- v-bind="props"
89
- :title="item.raw.itemValue"
90
- />
52
+
53
+ <template v-if="!$slots.item && !props.meilisearch" #item="{ props: itemProps, item }">
54
+ <v-list-item v-bind="itemProps" :title="formatItemTitle(item)" />
91
55
  </template>
92
- </v-combobox>
93
- </template>
94
56
 
95
- <style scoped>
57
+ <template v-if="!$slots.item && props.meilisearch" #item="{ props: itemProps, item }">
58
+ <v-list-item v-bind="itemProps">
59
+ <template #title v-if="item.raw?._formatted?.itemValue">
60
+ <span v-html="formatItemTitle(item)" class="meilisearch-item"></span>
61
+ </template>
62
+ </v-list-item>
63
+ </template>
64
+
65
+ <template v-if="!$slots.selection && props.showCode" #selection="{ item }">
66
+ {{ formatItemTitle(item) }}
67
+ </template>
68
+ </model-combobox>
69
+ </template>
96
70
 
71
+ <style>
72
+ .meilisearch-item em{font-weight:700}
97
73
  </style>
@@ -1,235 +1,36 @@
1
1
  <script lang="ts" setup>
2
2
  import { VAutocomplete } from 'vuetify/components/VAutocomplete'
3
- import { union, isEmpty, isArray, sortBy, castArray } from 'lodash-es'
4
- import { computed, ref, watch, defineModel } from 'vue'
5
- import { watchDebounced } from '@vueuse/core'
6
- import { useFuzzy } from '../../composables/utils/fuzzy'
7
- import { useGraphQlOperation } from '../../composables/graphqlOperation'
3
+ import { defineModel, withDefaults } from 'vue'
4
+ import { useLookupList, type LookupProps } from '../../composables/lookupList'
8
5
 
9
- interface Props extends /* @vue-ignore */ InstanceType<typeof VAutocomplete['$props']> {
10
- fuzzy?: boolean
11
- sortBy?: string | string[]
12
- showCode?: boolean
6
+ interface Props extends /* @vue-ignore */ InstanceType<typeof VAutocomplete['$props']> {}
13
7
 
14
- modelName: string
15
- modelBy?: Record<string, any>
16
- itemTitle: string
17
- itemValue: string
18
- fields?: Array<string | object>
19
- cache?: boolean | number
20
-
21
- serverSearch?: boolean
22
- serverSearchKey?: string
23
- searchSearchSort?: boolean
24
- serverSearchDebounce?: number
25
-
26
- serverSearchText?: string
27
- serverSearchLoadingText?: string
28
-
29
- modelSelectedItem?: string
30
- modelSelectedItemBy?: Record<string, any>
31
- modelSelectedItemKey?: string
32
-
33
- filterKeys?: string|string[]
34
- noDataText?: string
35
- placeholder?: string
36
- multiple?: boolean
37
- }
38
-
39
- const props = withDefaults(defineProps<Props>(), {
8
+ const props = withDefaults(defineProps<Props & LookupProps>(), {
40
9
  fuzzy: false,
41
10
  showCode: false,
42
11
  cache: false,
43
12
  serverSearch: false,
44
13
  searchSearchSort: false,
45
- serverSearchText: "Type to search…",
46
- serverSearchLoadingText: "Searching…",
14
+ serverSearchText: 'Type to search…',
15
+ serverSearchLoadingText: 'Searching…',
47
16
  serverSearchDebounce: 500,
48
17
  })
49
18
 
50
19
  const emit = defineEmits<{
51
- (e: 'update:selectedObject', object: any|any[]): void
20
+ (e: 'update:selectedObject', object: any | any[]): void
52
21
  }>()
53
22
 
54
- const modelItems = ref<Array<any>>([])
55
- const items = ref<Array<any>>([])
56
- const searchData = ref<string>('')
57
-
58
- const isLoading = ref(false)
59
- const isErrorLoading = ref(false)
60
-
61
- const queryFields = computed(() => {
62
- let fieldsArray: any[] = [props.itemTitle, props.itemValue]
63
- if (props.fields) fieldsArray = union(fieldsArray, props.fields)
64
- return fieldsArray
65
- })
66
-
67
- const computedFilterKeys = computed(() => {
68
- if (props.filterKeys) return props.filterKeys
69
- return ['title','raw.'+props.itemValue]
70
- })
71
-
72
- const computedPlaceholder = computed(() => {
73
- if (!props.serverSearch) return props.placeholder
74
- return isLoading.value ? props.serverSearchLoadingText : props.serverSearchText
75
- })
76
-
77
- const computedNoDataText = computed(() => {
78
- if (!props.serverSearch) return props.noDataText
79
- if (isLoading.value) return props.serverSearchLoadingText
80
- if (!searchData.value) return props.serverSearchText
81
- return props.noDataText
82
- })
83
-
84
- let requestId = 0
85
-
86
- async function loadItems() {
87
- if (!props.modelName) {
88
- modelItems.value = []
89
- items.value = []
90
- return
91
- }
92
-
93
- const id = ++requestId
94
- isLoading.value = true
95
-
96
- const variables: Record<string, any> = { ...(props.modelBy || {}) }
97
- if (props.serverSearch && props.serverSearchKey) {
98
- variables[props.serverSearchKey] = searchData.value
99
- }
100
-
101
- try {
102
- const result: any = await useGraphQlOperation('Query', props.modelName, queryFields.value, variables, props.cache)
103
-
104
- if (id !== requestId) return
105
-
106
- if (isArray(result)) {
107
- modelItems.value = result
108
- items.value = result
109
- isErrorLoading.value = false
110
- } else {
111
- isErrorLoading.value = true
112
- modelItems.value = []
113
- items.value = []
114
- }
115
- } catch (_error) {
116
- if (id !== requestId) return
117
- isErrorLoading.value = true
118
- modelItems.value = []
119
- items.value = []
120
- } finally {
121
- if (id === requestId) isLoading.value = false
122
- }
123
- }
124
-
125
- function applyFuzzy() {
126
- if (!props.fuzzy) return
127
-
128
- if (isEmpty(searchData.value)) {
129
- items.value = modelItems.value
130
- return
131
- }
132
-
133
- const results: any = useFuzzy(searchData.value, modelItems.value, queryFields.value)
134
- const output: any[] = []
135
- if (results.value?.length) {
136
- for (let index = 0; index < results.value.length; index++) {
137
- const result = results.value[index]
138
- if (result?.item) output.push(result.item)
139
- }
140
- }
141
- items.value = output
142
- }
143
-
144
23
  const selectedItems = defineModel<any>()
145
- const selectedItemsObject = ref<any[]>([])
146
- async function syncSelectedFromModelValue() {
147
- const modelValueData: any = selectedItems.value
148
- const values = castArray(modelValueData).filter(value => value !== undefined && value !== null && value !== '')
149
-
150
- if (!values.length) {
151
- emit("update:selectedObject",(props.multiple) ? [] : undefined)
152
- selectedItemsObject.value = []
153
- return
154
- }
155
-
156
- let alreadyInObject : any[] = selectedItemsObject.value?.filter(item => values.includes(item?.[props.itemValue])) || []
157
-
158
- const haveSet = new Set<any>([...alreadyInObject.map(item => item?.[props.itemValue])])
159
- const missingValues: any[] = values.filter(value => !haveSet.has(value))
160
-
161
- const stillMissing: any[] = []
162
- for (const value of missingValues) {
163
- const localHit = modelItems.value.find(item => item?.[props.itemValue] === value)
164
- if (localHit) {
165
- alreadyInObject.push(localHit)
166
- haveSet.add(value)
167
- } else {
168
- stillMissing.push(value)
169
- }
170
- }
171
-
172
- if (stillMissing.length && props.modelSelectedItem) {
173
- try {
174
- const key = props.modelSelectedItemKey || 'id'
175
- const variables: Record<string, any> = { ...(props.modelSelectedItemBy || {}) }
176
- variables[key] = values
177
-
178
- const result: any = await useGraphQlOperation('Query', props.modelSelectedItem, queryFields.value,variables,props.cache)
179
- selectedItemsObject.value = castArray(result)
180
- } catch (_error) {
181
- void _error
182
- }
183
- } else {
184
- selectedItemsObject.value = alreadyInObject
185
- }
186
24
 
187
- emit("update:selectedObject",(props.multiple) ? selectedItemsObject.value : selectedItemsObject.value[0])
188
- }
189
-
190
- watch(
191
- () => [
192
- props.modelName,
193
- props.serverSearch,
194
- props.serverSearchKey,
195
- props.cache,
196
- props.modelBy,
197
- queryFields.value,
198
- ],
199
- () => loadItems(),
200
- { immediate: true, deep: true },
201
- )
202
-
203
- watchDebounced(searchData,()=>{
204
- if (props.serverSearch) loadItems()
205
- else applyFuzzy()
206
- },{ debounce: props.serverSearch ? props.serverSearchDebounce : 300, maxWait: 1500 })
207
-
208
- watch(()=>modelItems.value, () => {
209
- if (!props.serverSearch) applyFuzzy()
210
- })
211
-
212
- watch(()=>props.modelValue,()=>{
213
- syncSelectedFromModelValue()
214
- },{ immediate: true, deep: true })
215
-
216
- const computedItems = computed(() => {
217
- const sortByField = !props.sortBy || typeof props.sortBy === 'string'
218
- ? [props.sortBy || (props.showCode ? props.itemValue : props.itemTitle)]
219
- : props.sortBy
220
-
221
- const baseItems = (props.fuzzy || (props.serverSearch && !props.searchSearchSort)) && !isEmpty(searchData.value)
222
- ? items.value
223
- : sortBy(items.value, sortByField)
224
-
225
- for (const selectedItem of selectedItemsObject.value || []) {
226
- if (!baseItems.find(existingItem => existingItem[props.itemValue] === selectedItem[props.itemValue])) {
227
- baseItems.push(selectedItem)
228
- }
229
- }
230
-
231
- return baseItems
232
- })
25
+ const {
26
+ searchData,
27
+ computedItems,
28
+ computedFilterKeys,
29
+ computedPlaceholder,
30
+ computedNoDataText,
31
+ isLoading,
32
+ isErrorLoading,
33
+ } = useLookupList(props, emit, selectedItems)
233
34
  </script>
234
35
 
235
36
  <template>
@@ -247,34 +48,22 @@ const computedItems = computed(() => {
247
48
  :no-data-text="computedNoDataText"
248
49
  :multiple="props.multiple"
249
50
  >
51
+ <!-- passthrough slots -->
250
52
  <!-- @ts-ignore -->
251
- <template
252
- v-for="(_, name, index) in ($slots as {})"
253
- :key="index"
254
- #[name]="slotData"
255
- >
53
+ <template v-for="(_, name, index) in ($slots as {})" :key="index" #[name]="slotData">
256
54
  <slot :name="name" v-bind="((slotData || {}) as object)" />
257
55
  </template>
258
56
 
259
- <template
260
- v-if="!$slots.item"
261
- #item="{ props, item }"
262
- >
263
- <v-list-item
264
- v-bind="props"
265
- :title="(showCode ? item.value+'-' : '')+item.title"
266
- />
57
+ <template v-if="!$slots.item" #item="{ props: itemProps, item }">
58
+ <v-list-item v-bind="itemProps" :title="(props.showCode ? item.value + '-' : '') + item.title" />
267
59
  </template>
268
60
 
269
- <template
270
- v-if="!$slots.selection && showCode"
271
- #selection="{ item }"
272
- >
273
- {{item.value+'-'+item.title}}
61
+ <template v-if="!$slots.selection && props.showCode" #selection="{ item }">
62
+ {{ item.value + '-' + item.title }}
274
63
  </template>
275
64
 
276
65
  <template v-if="isErrorLoading" #append>
277
66
  <v-icon color="error">mdi mdi-alert</v-icon>
278
67
  </template>
279
68
  </v-autocomplete>
280
- </template>
69
+ </template>