@ramathibodi/nuxt-commons 0.1.12 → 0.1.13
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/dist/module.json +1 -1
- package/dist/runtime/components/TabsGroup.vue +12 -8
- package/dist/runtime/components/form/Birthdate.vue +199 -0
- package/dist/runtime/components/form/CodeEditor.vue +3 -3
- package/dist/runtime/components/form/Dialog.vue +3 -2
- package/dist/runtime/components/form/Pad.vue +31 -9
- package/dist/runtime/components/form/Table.vue +4 -4
- package/dist/runtime/components/master/Combobox.vue +29 -25
- package/dist/runtime/components/master/RadioGroup.vue +40 -30
- package/dist/runtime/components/master/Select.vue +34 -23
- package/dist/runtime/components/model/Pad.vue +122 -0
- package/dist/runtime/components/model/Table.vue +126 -103
- package/dist/runtime/components/model/iterator.vue +312 -0
- package/dist/runtime/composables/graphql.mjs +1 -1
- package/dist/runtime/composables/graphqlModel.d.ts +5 -18
- package/dist/runtime/composables/graphqlModel.mjs +16 -86
- package/dist/runtime/composables/graphqlModelItem.d.ts +20 -0
- package/dist/runtime/composables/graphqlModelItem.mjs +103 -0
- package/dist/runtime/composables/graphqlModelOperation.d.ts +21 -0
- package/dist/runtime/composables/graphqlModelOperation.mjs +77 -0
- package/dist/runtime/composables/graphqlOperation.d.ts +2 -2
- package/dist/runtime/composables/graphqlOperation.mjs +9 -9
- package/dist/runtime/types/formDialog.d.ts +3 -3
- package/dist/runtime/types/graphqlOperation.d.ts +14 -14
- package/package.json +1 -1
- package/scripts/postInstall.cjs +38 -35
- package/templates/.codegen/codegen.ts +8 -8
- package/templates/.codegen/plugin-schema-object.js +97 -97
package/dist/module.json
CHANGED
|
@@ -1,28 +1,32 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import {ref} from 'vue'
|
|
3
|
+
import {VTabs} from 'vuetify/components'
|
|
4
4
|
|
|
5
5
|
interface Props extends /* @vue-ignore */ InstanceType<typeof VTabs['$props']> {
|
|
6
6
|
flat?: boolean
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
defineOptions({
|
|
10
|
+
inheritAttrs: false,
|
|
11
|
+
})
|
|
12
|
+
|
|
9
13
|
const props = defineProps<Props>()
|
|
10
|
-
const currentTab = ref<
|
|
14
|
+
const currentTab = ref<string | number>()
|
|
11
15
|
</script>
|
|
12
16
|
|
|
13
17
|
<template>
|
|
14
18
|
<v-card :flat="props.flat">
|
|
15
19
|
<v-tabs
|
|
16
|
-
v-model="currentTab"
|
|
17
20
|
v-bind="$attrs"
|
|
21
|
+
v-model="currentTab"
|
|
18
22
|
show-arrows
|
|
19
23
|
>
|
|
20
24
|
<slot name="tabs" />
|
|
21
25
|
</v-tabs>
|
|
22
|
-
<v-card>
|
|
23
|
-
<v-window v-model="currentTab">
|
|
26
|
+
<v-card-text>
|
|
27
|
+
<v-tabs-window v-model="currentTab">
|
|
24
28
|
<slot name="items" />
|
|
25
|
-
</v-window>
|
|
26
|
-
</v-card>
|
|
29
|
+
</v-tabs-window>
|
|
30
|
+
</v-card-text>
|
|
27
31
|
</v-card>
|
|
28
32
|
</template>
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import Datepicker from '@vuepic/vue-datepicker'
|
|
3
|
+
import '@vuepic/vue-datepicker/dist/main.css'
|
|
4
|
+
import {nextTick, ref, watch, watchEffect} from 'vue'
|
|
5
|
+
import {type dateFormat, Datetime} from '../../utils/datetime'
|
|
6
|
+
|
|
7
|
+
interface IDobPrecision {
|
|
8
|
+
yearMonthDay: string
|
|
9
|
+
yearMonth: string
|
|
10
|
+
year: string
|
|
11
|
+
}
|
|
12
|
+
interface Props {
|
|
13
|
+
readonly?: boolean
|
|
14
|
+
locale?: 'TH' | 'EN'
|
|
15
|
+
format?: dateFormat | string
|
|
16
|
+
modelValue?: string | null
|
|
17
|
+
holiday?: object[] | undefined
|
|
18
|
+
minDate?: Date | string
|
|
19
|
+
maxDate?: Date | string
|
|
20
|
+
pickerOnly?: boolean
|
|
21
|
+
flow?: ('month' | 'year' | 'calendar' | 'time' | 'minutes' | 'hours' | 'seconds')[]
|
|
22
|
+
dobPrecisionText?: IDobPrecision
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
26
|
+
readonly: false,
|
|
27
|
+
locale: 'TH',
|
|
28
|
+
format: 'shortDate',
|
|
29
|
+
pickerOnly: false,
|
|
30
|
+
flow: () => ['year', 'month', 'calendar'],
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
const emit = defineEmits(['update:modelValue'])
|
|
34
|
+
|
|
35
|
+
const dobPrecisionText = computed(() => {
|
|
36
|
+
if (props.dobPrecisionText) return props.dobPrecisionText
|
|
37
|
+
else return {
|
|
38
|
+
yearMonthDay: 'YMD',
|
|
39
|
+
yearMonth: 'YM',
|
|
40
|
+
year: 'Y',
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
const dobPrecisionChoice = ref<('yearMonthDay' | 'yearMonth' | 'year')[]>(['yearMonthDay', 'yearMonth', 'year'])
|
|
44
|
+
const dobPrecisionSelected = defineModel<'yearMonthDay' | 'yearMonth' | 'year'>('dobPrecision', { default: 'yearMonthDay' })
|
|
45
|
+
|
|
46
|
+
const dobPrecisionDisplay = computed(() => {
|
|
47
|
+
return (dobPrecisionSelected.value) ? dobPrecisionText.value[dobPrecisionSelected.value] : dobPrecisionText.value['yearMonthDay']
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
const changeDobPrecision = () => {
|
|
51
|
+
if (dobPrecisionSelected.value && dobPrecisionChoice.value.includes(dobPrecisionSelected.value)) {
|
|
52
|
+
dobPrecisionSelected.value = dobPrecisionChoice.value[(dobPrecisionChoice.value.indexOf(dobPrecisionSelected.value) + 1) % dobPrecisionChoice.value.length]
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
dobPrecisionSelected.value = dobPrecisionChoice.value[0]
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const selectedDate = ref<string | null>(null)
|
|
60
|
+
const displayedDate = ref<string | null>(null)
|
|
61
|
+
|
|
62
|
+
const isMenuOpen = ref(false)
|
|
63
|
+
const isTextFieldFocused = ref(false)
|
|
64
|
+
const hasTextFieldInput = ref(false)
|
|
65
|
+
|
|
66
|
+
function handleTextFieldFocus(event: Event) {
|
|
67
|
+
isTextFieldFocused.value = true
|
|
68
|
+
nextTick(() => {
|
|
69
|
+
(event.target as HTMLInputElement).select()
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function handleTextFieldInput() {
|
|
74
|
+
if (!hasTextFieldInput.value) {
|
|
75
|
+
hasTextFieldInput.value = true
|
|
76
|
+
isMenuOpen.value = false
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function handleTextFieldBlur() {
|
|
81
|
+
if (hasTextFieldInput.value) {
|
|
82
|
+
updateDate(displayedDate.value)
|
|
83
|
+
hasTextFieldInput.value = false
|
|
84
|
+
}
|
|
85
|
+
isTextFieldFocused.value = false
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function handleTextFieldEnterKey() {
|
|
89
|
+
handleTextFieldBlur()
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function updateDatePicker(dateString: string | null) {
|
|
93
|
+
isMenuOpen.value = false
|
|
94
|
+
updateDate(dateString)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function updateDate(dateString: string | null) {
|
|
98
|
+
const dateTime = Datetime().fromString(dateString, undefined, props.locale)
|
|
99
|
+
if (!dateTime.luxonDateTime.isValid) {
|
|
100
|
+
displayedDate.value = null
|
|
101
|
+
selectedDate.value = null
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
selectedDate.value = dateTime.toFormat('yyyy-MM-dd', 'EN')
|
|
105
|
+
displayedDate.value = selectedDate.value
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (!isTextFieldFocused.value) displayedDate.value = formatDate(displayedDate.value)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function formatDate(dateString: string | null) {
|
|
112
|
+
if (!dateString) return null
|
|
113
|
+
|
|
114
|
+
const dateTime = Datetime().fromString(dateString, undefined, props.locale)
|
|
115
|
+
return dateTime.toFormat(props.format, props.locale)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function handleTextFieldClear() {
|
|
119
|
+
resetDatePicker()
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function resetDatePicker() {
|
|
123
|
+
selectedDate.value = null
|
|
124
|
+
displayedDate.value = null
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
watchEffect(() => {
|
|
128
|
+
if (!isTextFieldFocused.value && selectedDate.value) {
|
|
129
|
+
const dateTime = Datetime().fromString(selectedDate.value, undefined, props.locale)
|
|
130
|
+
displayedDate.value = dateTime.toFormat(props.format, props.locale)
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
displayedDate.value = selectedDate.value
|
|
134
|
+
}
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
watch(selectedDate, (newValue) => {
|
|
138
|
+
emit('update:modelValue', newValue)
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
watch(() => props.modelValue, () => {
|
|
142
|
+
updateDate(props.modelValue || null)
|
|
143
|
+
}, { immediate: true })
|
|
144
|
+
|
|
145
|
+
function toggleMenuOpen(trigger: string) {
|
|
146
|
+
if ((trigger === 'textField' && props.pickerOnly) || (trigger === 'icon' && !props.pickerOnly)) {
|
|
147
|
+
isMenuOpen.value = true
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
</script>
|
|
151
|
+
|
|
152
|
+
<template>
|
|
153
|
+
<v-menu
|
|
154
|
+
v-model="isMenuOpen"
|
|
155
|
+
:open-on-click="false"
|
|
156
|
+
>
|
|
157
|
+
<template #activator="{ props: activatorProps }">
|
|
158
|
+
<v-text-field
|
|
159
|
+
ref="textField"
|
|
160
|
+
v-model="displayedDate"
|
|
161
|
+
:readonly="readonly"
|
|
162
|
+
v-bind="$attrs"
|
|
163
|
+
@focus="handleTextFieldFocus"
|
|
164
|
+
@blur="handleTextFieldBlur"
|
|
165
|
+
@keydown="handleTextFieldInput"
|
|
166
|
+
@keyup.enter="handleTextFieldEnterKey"
|
|
167
|
+
@click:clear="handleTextFieldClear"
|
|
168
|
+
@click="toggleMenuOpen('textField')"
|
|
169
|
+
>
|
|
170
|
+
<template #append-inner>
|
|
171
|
+
<span
|
|
172
|
+
style="cursor: pointer;"
|
|
173
|
+
class="font-weight-medium"
|
|
174
|
+
@click="changeDobPrecision"
|
|
175
|
+
>{{ dobPrecisionDisplay }}</span>
|
|
176
|
+
|
|
177
|
+
<v-icon
|
|
178
|
+
v-bind="activatorProps"
|
|
179
|
+
@click="toggleMenuOpen('icon')"
|
|
180
|
+
>
|
|
181
|
+
fa:fa-regular fa-calendar
|
|
182
|
+
</v-icon>
|
|
183
|
+
</template>
|
|
184
|
+
</v-text-field>
|
|
185
|
+
</template>
|
|
186
|
+
<Datepicker
|
|
187
|
+
v-model="selectedDate"
|
|
188
|
+
model-type="yyyy-MM-dd"
|
|
189
|
+
:enable-time-picker="false"
|
|
190
|
+
:flow="flow"
|
|
191
|
+
:min-date="props.minDate"
|
|
192
|
+
:max-date="props.maxDate"
|
|
193
|
+
auto-apply
|
|
194
|
+
inline
|
|
195
|
+
:locale="locale"
|
|
196
|
+
@update:model-value="updateDatePicker"
|
|
197
|
+
/>
|
|
198
|
+
</v-menu>
|
|
199
|
+
</template>
|
|
@@ -30,8 +30,8 @@ const model = defineModel<string>()
|
|
|
30
30
|
|
|
31
31
|
<template>
|
|
32
32
|
<codemirror
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
v-model="model"
|
|
34
|
+
:extensions="extensions"
|
|
35
|
+
:style="{ height: height, minHeight: minHeight }"
|
|
36
36
|
/>
|
|
37
37
|
</template>
|
|
@@ -28,7 +28,7 @@ const emit = defineEmits(['create', 'update'])
|
|
|
28
28
|
function save() {
|
|
29
29
|
if (formPadRef.value.isValid) {
|
|
30
30
|
isSaving.value = true
|
|
31
|
-
emit((isCreating.value) ? 'create' : 'update', cloneDeep(formData.value)
|
|
31
|
+
emit((isCreating.value) ? 'create' : 'update', cloneDeep(formData.value), callback)
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -61,7 +61,8 @@ const createOriginalValue = computed(() => {
|
|
|
61
61
|
const loadFormData = () => {
|
|
62
62
|
if (props.formData) {
|
|
63
63
|
formData.value = cloneDeep(props.formData)
|
|
64
|
-
}
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
65
66
|
formData.value = Object.assign({}, props.initialData)
|
|
66
67
|
}
|
|
67
68
|
}
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-explicit-any,import/no-self-import */
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
import {
|
|
4
|
+
compile,
|
|
5
|
+
computed,
|
|
6
|
+
defineComponent,
|
|
7
|
+
defineOptions,
|
|
8
|
+
inject,
|
|
9
|
+
onMounted,
|
|
10
|
+
ref,
|
|
11
|
+
shallowRef,
|
|
12
|
+
watch,
|
|
13
|
+
withDefaults
|
|
14
|
+
} from 'vue'
|
|
15
|
+
import {isObject} from 'lodash-es'
|
|
16
|
+
import {watchDebounced} from '@vueuse/core'
|
|
17
|
+
import {useRules} from '../../composables/utils/validation'
|
|
18
|
+
import {useDocumentTemplate} from '../../composables/document/template'
|
|
8
19
|
import FormPad from './Pad.vue'
|
|
9
20
|
|
|
10
21
|
defineOptions({
|
|
@@ -18,18 +29,21 @@ interface Props {
|
|
|
18
29
|
disabled?: boolean
|
|
19
30
|
readonly?: boolean
|
|
20
31
|
isolated?: boolean
|
|
32
|
+
decoration?: object
|
|
21
33
|
}
|
|
22
34
|
|
|
23
35
|
const props = withDefaults(defineProps<Props>(), {
|
|
24
36
|
disabled: false,
|
|
25
37
|
readonly: false,
|
|
26
38
|
isolated: false,
|
|
39
|
+
decoration: () => { return {} },
|
|
27
40
|
})
|
|
28
41
|
|
|
29
42
|
const emit = defineEmits(['update:modelValue'])
|
|
30
43
|
|
|
31
44
|
const disabled = ref(props.disabled)
|
|
32
45
|
const readonly = ref(props.readonly)
|
|
46
|
+
const decoration = ref(props.decoration)
|
|
33
47
|
|
|
34
48
|
watch(() => props.disabled, (newValue) => {
|
|
35
49
|
disabled.value = newValue
|
|
@@ -39,6 +53,10 @@ watch(() => props.readonly, (newValue) => {
|
|
|
39
53
|
readonly.value = newValue
|
|
40
54
|
})
|
|
41
55
|
|
|
56
|
+
watch(() => props.decoration, (newValue) => {
|
|
57
|
+
decoration.value = newValue
|
|
58
|
+
}, { deep: true })
|
|
59
|
+
|
|
42
60
|
const { rules } = useRules()
|
|
43
61
|
|
|
44
62
|
const trimmedTemplate = ref<string>('')
|
|
@@ -73,7 +91,7 @@ function buildFormComponent() {
|
|
|
73
91
|
const originalConsoleError = console.warn
|
|
74
92
|
console.warn = (error) => { throw new Error(error) } // eslint-disable-line
|
|
75
93
|
try {
|
|
76
|
-
const componentTemplate = '<form-pad ref="formPadTemplate" v-model="formComponentData" :disabled="disabled" :readonly="readonly" :isolated="isolated"><template v-slot="{ data,isDisabled,isReadonly,rules,formProvided }">' + trimmedTemplate.value + '</template></form-pad>'
|
|
94
|
+
const componentTemplate = '<form-pad ref="formPadTemplate" v-model="formComponentData" :disabled="disabled" :readonly="readonly" :decoration="decoration" :isolated="isolated"><template v-slot="{ data,isDisabled,isReadonly,rules,formProvided,decoration }">' + trimmedTemplate.value + '</template></form-pad>'
|
|
77
95
|
compile(componentTemplate)
|
|
78
96
|
formComponent.value = defineComponent({
|
|
79
97
|
components: { FormPad },
|
|
@@ -81,6 +99,7 @@ function buildFormComponent() {
|
|
|
81
99
|
modelValue: { type: Object, default: undefined },
|
|
82
100
|
disabled: { type: Boolean, default: false },
|
|
83
101
|
readonly: { type: Boolean, default: false },
|
|
102
|
+
decoration: { type: Object, default: () => { return {} } },
|
|
84
103
|
isolated: { type: Boolean, default: false },
|
|
85
104
|
},
|
|
86
105
|
emits: ['update:modelValue'],
|
|
@@ -116,17 +135,17 @@ function buildFormComponent() {
|
|
|
116
135
|
|
|
117
136
|
function reset() {
|
|
118
137
|
if (!formInjected.value) formPad.value.reset()
|
|
119
|
-
else formInjected.value.items.forEach((item: any)=>item.reset())
|
|
138
|
+
else formInjected.value.items.forEach((item: any) => item.reset())
|
|
120
139
|
}
|
|
121
140
|
|
|
122
141
|
function validate() {
|
|
123
142
|
if (!formInjected.value) formPad.value.validate()
|
|
124
|
-
else formInjected.value.items.forEach((item: any)=>item.validate())
|
|
143
|
+
else formInjected.value.items.forEach((item: any) => item.validate())
|
|
125
144
|
}
|
|
126
145
|
|
|
127
146
|
function resetValidate() {
|
|
128
147
|
if (!formInjected.value) formPad.value.resetValidate()
|
|
129
|
-
else formInjected.value.items.forEach((item: any)=>item.resetValidate())
|
|
148
|
+
else formInjected.value.items.forEach((item: any) => item.resetValidate())
|
|
130
149
|
}
|
|
131
150
|
|
|
132
151
|
const isValid = computed(() => {
|
|
@@ -170,6 +189,7 @@ defineExpose({
|
|
|
170
189
|
:is-disabled="disabled"
|
|
171
190
|
:is-readonly="readonly"
|
|
172
191
|
:rules="rules"
|
|
192
|
+
:decoration="decoration"
|
|
173
193
|
/>
|
|
174
194
|
</template>
|
|
175
195
|
</v-form>
|
|
@@ -180,6 +200,7 @@ defineExpose({
|
|
|
180
200
|
:is-disabled="disabled"
|
|
181
201
|
:is-readonly="readonly"
|
|
182
202
|
:rules="rules"
|
|
203
|
+
:decoration="decoration"
|
|
183
204
|
/>
|
|
184
205
|
</template>
|
|
185
206
|
<component
|
|
@@ -189,6 +210,7 @@ defineExpose({
|
|
|
189
210
|
v-model="formData"
|
|
190
211
|
:disabled="disabled"
|
|
191
212
|
:readonly="readonly"
|
|
213
|
+
:decoration="decoration"
|
|
192
214
|
:isolated="isolated"
|
|
193
215
|
:class="$attrs.class"
|
|
194
216
|
/>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
import {VDataTable} from 'vuetify/components/VDataTable'
|
|
3
3
|
import {computed, defineOptions, nextTick, ref, useAttrs, watch} from 'vue'
|
|
4
|
-
import type {FormDialogCallback} from '../../types/formDialog'
|
|
5
4
|
import {omit} from 'lodash-es'
|
|
5
|
+
import type {FormDialogCallback} from '../../types/formDialog'
|
|
6
6
|
|
|
7
7
|
defineOptions({
|
|
8
8
|
inheritAttrs: false,
|
|
@@ -65,7 +65,7 @@ watch(items, (newValue) => {
|
|
|
65
65
|
}, { deep: true })
|
|
66
66
|
|
|
67
67
|
function createItem(item: Record<string, any>, callback?: FormDialogCallback) {
|
|
68
|
-
if (items.value.length>0) item[props.modelKey] = Math.max(...items.value.map(i => i[props.modelKey] || 0)) + 1
|
|
68
|
+
if (items.value.length > 0) item[props.modelKey] = Math.max(...items.value.map(i => i[props.modelKey] || 0)) + 1
|
|
69
69
|
else item[props.modelKey] = 1
|
|
70
70
|
|
|
71
71
|
items.value.push(item)
|
|
@@ -124,14 +124,14 @@ function deleteItem(deleteItem: Record<string, any>, callback?: FormDialogCallba
|
|
|
124
124
|
if (callback) callback.done()
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
const operation = ref({ createItem, updateItem, deleteItem, moveUpItem, moveDownItem })
|
|
128
|
-
|
|
129
127
|
function openDialog(item?: object) {
|
|
130
128
|
currentItem.value = item
|
|
131
129
|
nextTick(() => {
|
|
132
130
|
isDialogOpen.value = true
|
|
133
131
|
})
|
|
134
132
|
}
|
|
133
|
+
|
|
134
|
+
const operation = ref({ openDialog, createItem, updateItem, deleteItem, moveUpItem, moveDownItem })
|
|
135
135
|
</script>
|
|
136
136
|
|
|
137
137
|
<template>
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import {ref, watch
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {useGraphQl} from
|
|
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'
|
|
7
7
|
|
|
8
8
|
interface Props extends /* @vue-ignore */ InstanceType<typeof VCombobox['$props']> {
|
|
9
9
|
modelValue?: string
|
|
@@ -12,8 +12,8 @@ interface Props extends /* @vue-ignore */ InstanceType<typeof VCombobox['$props'
|
|
|
12
12
|
lang?: 'TH' | 'EN'
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
const props = withDefaults(defineProps<Props>(),{
|
|
16
|
-
lang: 'TH'
|
|
15
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
16
|
+
lang: 'TH',
|
|
17
17
|
})
|
|
18
18
|
|
|
19
19
|
const emit = defineEmits(['update:modelValue'])
|
|
@@ -25,12 +25,12 @@ function query() {
|
|
|
25
25
|
let fields: any[] = ['itemCode', 'itemValue', 'itemValueAlternative']
|
|
26
26
|
if (props.fields) fields = concat(fields, props.fields)
|
|
27
27
|
|
|
28
|
-
useGraphQl().queryPromise('masterItemByGroupKey',fields, variables).then((result
|
|
28
|
+
useGraphQl().queryPromise('masterItemByGroupKey', fields, variables).then((result: any) => {
|
|
29
29
|
items.value = result
|
|
30
|
-
}).catch((error)=>{
|
|
30
|
+
}).catch((error) => {
|
|
31
31
|
alert?.addAlert({
|
|
32
|
-
message
|
|
33
|
-
alertType:
|
|
32
|
+
message: `${error.message}`,
|
|
33
|
+
alertType: 'error',
|
|
34
34
|
})
|
|
35
35
|
})
|
|
36
36
|
}
|
|
@@ -53,30 +53,34 @@ query()
|
|
|
53
53
|
|
|
54
54
|
<template>
|
|
55
55
|
<v-combobox
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
v-model="selectedItem"
|
|
57
|
+
:items="items"
|
|
58
|
+
:item-title="itemTitleField"
|
|
59
|
+
item-value="itemCode"
|
|
60
60
|
>
|
|
61
61
|
<template
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
v-for="(_, name, index) in ($slots as {})"
|
|
63
|
+
:key="index"
|
|
64
|
+
#[name]="slotData"
|
|
65
65
|
>
|
|
66
66
|
<slot
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
:name="name"
|
|
68
|
+
v-bind="(slotData as object)"
|
|
69
|
+
:operation="operation"
|
|
70
70
|
/>
|
|
71
71
|
</template>
|
|
72
72
|
<template
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
v-if="!$slots.item"
|
|
74
|
+
#item="{ props, item }"
|
|
75
|
+
>
|
|
76
|
+
<v-list-item
|
|
77
|
+
v-bind="props"
|
|
78
|
+
:title="item.raw.itemValue"
|
|
79
|
+
/>
|
|
76
80
|
</template>
|
|
77
81
|
</v-combobox>
|
|
78
82
|
</template>
|
|
79
83
|
|
|
80
84
|
<style scoped>
|
|
81
85
|
|
|
82
|
-
</style>
|
|
86
|
+
</style>
|
|
@@ -1,68 +1,78 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
import {VRadioGroup} from 'vuetify/components/VRadioGroup'
|
|
3
3
|
import {computed, ref, watch} from 'vue'
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import {concat} from 'lodash-es'
|
|
5
|
+
import {useAlert} from '../../composables/alert'
|
|
6
|
+
import {useGraphQl} from '../../composables/graphql'
|
|
7
7
|
|
|
8
8
|
interface Props extends /* @vue-ignore */ InstanceType<typeof VRadioGroup['$props']> {
|
|
9
9
|
returnObject?: boolean
|
|
10
10
|
groupKey: string
|
|
11
11
|
modelValue?: any
|
|
12
|
-
fields?:string[]
|
|
12
|
+
fields?: string[]
|
|
13
13
|
lang?: 'TH' | 'EN'
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
const props = withDefaults(defineProps<Props>(),{
|
|
17
|
-
lang: 'TH'
|
|
16
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
17
|
+
lang: 'TH',
|
|
18
18
|
})
|
|
19
19
|
const emit = defineEmits(['update:modelValue'])
|
|
20
20
|
const items: any = ref([])
|
|
21
21
|
const value = ref()
|
|
22
22
|
const alert = useAlert()
|
|
23
|
-
const query =
|
|
24
|
-
const variables = { groupKey
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
let fields
|
|
30
|
-
if(props.fields) fields = concat(fields,props.fields)
|
|
23
|
+
const query = () => {
|
|
24
|
+
const variables = { groupKey: {
|
|
25
|
+
name: 'groupKey',
|
|
26
|
+
type: 'String!',
|
|
27
|
+
value: props.groupKey,
|
|
28
|
+
} }
|
|
29
|
+
let fields: any[] = ['itemCode', 'itemValue', 'itemValueAlternative']
|
|
30
|
+
if (props.fields) fields = concat(fields, props.fields)
|
|
31
31
|
|
|
32
|
-
useGraphQl().queryPromise('masterItemByGroupKey',fields, variables).then((result
|
|
32
|
+
useGraphQl().queryPromise('masterItemByGroupKey', fields, variables).then((result: any) => {
|
|
33
33
|
items.value = result
|
|
34
|
-
}).catch((error)=>{
|
|
34
|
+
}).catch((error) => {
|
|
35
35
|
alert?.addAlert({
|
|
36
|
-
message
|
|
37
|
-
alertType:
|
|
36
|
+
message: `${error.message}`,
|
|
37
|
+
alertType: 'error',
|
|
38
38
|
})
|
|
39
39
|
})
|
|
40
|
-
}
|
|
41
|
-
query()
|
|
40
|
+
}
|
|
41
|
+
query()
|
|
42
42
|
|
|
43
43
|
watch(() => props.modelValue, (newValue) => {
|
|
44
44
|
value.value = props.modelValue
|
|
45
|
-
|
|
46
|
-
}, {deep: true, immediate: true})
|
|
45
|
+
}, { deep: true, immediate: true })
|
|
47
46
|
|
|
48
47
|
const itemTitleField = computed(() => {
|
|
49
48
|
if (props.lang == 'TH') return 'itemValue'
|
|
50
49
|
else return 'itemValueAlternative'
|
|
51
50
|
})
|
|
52
51
|
</script>
|
|
52
|
+
|
|
53
53
|
<template>
|
|
54
|
-
<v-radio-group
|
|
54
|
+
<v-radio-group
|
|
55
|
+
v-model="value"
|
|
56
|
+
v-bind="$attrs"
|
|
57
|
+
@update:model-value="emit('update:modelValue', value.value)"
|
|
58
|
+
>
|
|
55
59
|
<template
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
60
|
+
v-for="(_, name, index) in ($slots as {})"
|
|
61
|
+
:key="index"
|
|
62
|
+
#[name]="slotData"
|
|
59
63
|
>
|
|
60
64
|
<slot
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
65
|
+
:name="name"
|
|
66
|
+
v-bind="(slotData as object)"
|
|
67
|
+
:operation="operation"
|
|
64
68
|
/>
|
|
65
69
|
</template>
|
|
66
|
-
<v-radio
|
|
70
|
+
<v-radio
|
|
71
|
+
v-for="i in items"
|
|
72
|
+
:key="i.itemCode"
|
|
73
|
+
v-bind="$attrs"
|
|
74
|
+
:label="i[itemTitleField]"
|
|
75
|
+
:value="returnObject ? i : i.itemCode"
|
|
76
|
+
/>
|
|
67
77
|
</v-radio-group>
|
|
68
78
|
</template>
|