@ramathibodi/nuxt-commons 0.1.74 → 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 -115
- package/dist/module.json +1 -1
- package/dist/runtime/components/Alert.vue +58 -58
- package/dist/runtime/components/BarcodeReader.vue +130 -130
- package/dist/runtime/components/ExportCSV.vue +110 -110
- package/dist/runtime/components/FileBtn.vue +79 -79
- package/dist/runtime/components/ImportCSV.vue +151 -151
- package/dist/runtime/components/MrzReader.vue +168 -168
- package/dist/runtime/components/SplitterPanel.vue +67 -67
- package/dist/runtime/components/TabsGroup.vue +39 -39
- package/dist/runtime/components/TextBarcode.vue +66 -66
- package/dist/runtime/components/device/IdCardButton.vue +95 -95
- package/dist/runtime/components/device/IdCardWebSocket.vue +207 -207
- package/dist/runtime/components/device/Scanner.vue +350 -350
- package/dist/runtime/components/dialog/Confirm.vue +112 -112
- package/dist/runtime/components/dialog/Host.vue +88 -88
- package/dist/runtime/components/dialog/Index.vue +84 -84
- package/dist/runtime/components/dialog/Loading.vue +51 -51
- package/dist/runtime/components/dialog/default/Confirm.vue +112 -112
- package/dist/runtime/components/dialog/default/Loading.vue +60 -60
- package/dist/runtime/components/dialog/default/Notify.vue +82 -82
- package/dist/runtime/components/dialog/default/Printing.vue +46 -46
- package/dist/runtime/components/dialog/default/VerifyUser.vue +144 -144
- package/dist/runtime/components/document/Form.vue +50 -50
- package/dist/runtime/components/document/TemplateBuilder.vue +536 -536
- package/dist/runtime/components/form/ActionPad.vue +156 -156
- package/dist/runtime/components/form/Birthdate.vue +116 -116
- package/dist/runtime/components/form/CheckboxGroup.vue +99 -99
- package/dist/runtime/components/form/CodeEditor.vue +45 -45
- package/dist/runtime/components/form/Date.vue +270 -270
- package/dist/runtime/components/form/DateTime.vue +220 -220
- package/dist/runtime/components/form/Dialog.vue +178 -178
- package/dist/runtime/components/form/EditPad.vue +157 -157
- package/dist/runtime/components/form/File.vue +295 -295
- package/dist/runtime/components/form/Hidden.vue +44 -44
- package/dist/runtime/components/form/Iterator.vue +538 -538
- package/dist/runtime/components/form/Login.vue +143 -143
- package/dist/runtime/components/form/Pad.vue +399 -399
- package/dist/runtime/components/form/SignPad.vue +226 -226
- package/dist/runtime/components/form/System.vue +34 -34
- package/dist/runtime/components/form/Table.vue +391 -391
- package/dist/runtime/components/form/TableData.vue +236 -236
- package/dist/runtime/components/form/Time.vue +177 -177
- package/dist/runtime/components/form/images/Capture.vue +245 -245
- package/dist/runtime/components/form/images/Edit.vue +133 -133
- package/dist/runtime/components/form/images/Field.vue +331 -331
- package/dist/runtime/components/form/images/Pad.vue +54 -54
- package/dist/runtime/components/label/Date.vue +37 -37
- package/dist/runtime/components/label/DateAgo.vue +102 -102
- package/dist/runtime/components/label/DateCount.vue +152 -152
- package/dist/runtime/components/label/Field.vue +111 -111
- package/dist/runtime/components/label/FormatMoney.vue +37 -37
- package/dist/runtime/components/label/Mask.vue +46 -46
- package/dist/runtime/components/label/Object.vue +21 -21
- package/dist/runtime/components/master/Autocomplete.vue +89 -89
- package/dist/runtime/components/master/Combobox.vue +88 -88
- package/dist/runtime/components/master/RadioGroup.vue +90 -90
- package/dist/runtime/components/master/Select.vue +70 -70
- package/dist/runtime/components/master/label.vue +55 -55
- package/dist/runtime/components/model/Autocomplete.vue +91 -91
- package/dist/runtime/components/model/Combobox.vue +90 -90
- package/dist/runtime/components/model/Pad.vue +114 -114
- package/dist/runtime/components/model/Select.vue +78 -84
- package/dist/runtime/components/model/Table.vue +370 -370
- package/dist/runtime/components/model/iterator.vue +497 -497
- package/dist/runtime/components/model/label.vue +58 -58
- package/dist/runtime/components/pdf/Print.vue +75 -75
- package/dist/runtime/components/pdf/View.vue +146 -146
- package/dist/runtime/composables/dialog.d.ts +1 -1
- 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/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/package.json +131 -131
- package/scripts/enrich-vue-docs-from-ai.mjs +197 -197
- package/scripts/generate-ai-summary.mjs +321 -321
- package/scripts/generate-composables-md.mjs +129 -129
- package/scripts/postInstall.cjs +70 -70
- package/templates/.codegen/codegen.ts +32 -32
- package/templates/.codegen/plugin-schema-object.js +161 -161
|
@@ -1,236 +1,236 @@
|
|
|
1
|
-
<script lang="ts" setup>
|
|
2
|
-
/**
|
|
3
|
-
* FormTableData is a schema-driven form field component that binds model data, renders field UI, and emits normalized updates.
|
|
4
|
-
* This doc block is consumed by vue-docgen for generated API documentation.
|
|
5
|
-
*/
|
|
6
|
-
import {VDataTable} from 'vuetify/components/VDataTable'
|
|
7
|
-
import {VInput} from 'vuetify/components/VInput'
|
|
8
|
-
import {computed, defineOptions,defineExpose, ref, useAttrs, watch, useTemplateRef} from 'vue'
|
|
9
|
-
import {cloneDeep, isEqual, omit, isArray, isString} from 'lodash-es'
|
|
10
|
-
import {templateItemToString} from "../../composables/document/template";
|
|
11
|
-
import {templateToHeader} from "../../composables/document/templateFormTable";
|
|
12
|
-
import { useLocalStorageModel, type PersistSlimProps } from '../../composables/localStorageModel'
|
|
13
|
-
|
|
14
|
-
defineOptions({
|
|
15
|
-
inheritAttrs: false,
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
interface Props extends /* @vue-ignore */ InstanceType<typeof VDataTable['$props']> {
|
|
19
|
-
title: string // Title text displayed in the component header or dialog.
|
|
20
|
-
noDataText?: string // Fallback message shown when there is no data to display.
|
|
21
|
-
modelValue?: Record<string, any>[] // Bound value for v-model synchronization with the parent component.
|
|
22
|
-
modelKey?: string // Primary key field name used to track row identity.
|
|
23
|
-
toolbarColor?: string // Vuetify color name applied to toolbar and action areas.
|
|
24
|
-
headers: Record<string, any>[] // Column definitions used to render table headers and field mapping.
|
|
25
|
-
itemsInitial: Record<string, any>[] // Initial rows used before external data is loaded.
|
|
26
|
-
dataTemplate?: string | object // Template object/string used to seed new row data.
|
|
27
|
-
disableApplyToAll?: boolean | string | string[] // Disables apply-to-all behavior globally or for selected field keys.
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Public props accepted by FormTableData.
|
|
32
|
-
* Document each prop field with intent, defaults, and side effects for clear generated docs.
|
|
33
|
-
*/
|
|
34
|
-
const props = withDefaults(defineProps<Props & PersistSlimProps>(), {
|
|
35
|
-
noDataText: 'ไม่พบข้อมูล',
|
|
36
|
-
modelKey: 'id',
|
|
37
|
-
toolbarColor: 'primary',
|
|
38
|
-
disableApplyToAll: false,
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Custom events emitted by FormTableData.
|
|
43
|
-
* Parents can listen to these events to react to user actions and internal state changes.
|
|
44
|
-
*/
|
|
45
|
-
const emit = defineEmits(['update:modelValue'])
|
|
46
|
-
const attrs = useAttrs()
|
|
47
|
-
const plainAttrs = computed(() => {
|
|
48
|
-
return omit(attrs, ['modelValue','items','onUpdate:modelValue','itemsInitial','dataTemplate'])
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
const inputRef = useTemplateRef<VInput>("inputRef")
|
|
52
|
-
|
|
53
|
-
const itemsInternal = ref<Record<string, any>[]>([])
|
|
54
|
-
const itemsApplyAll = ref<Record<string, any>>({})
|
|
55
|
-
|
|
56
|
-
useLocalStorageModel(itemsInternal,props)
|
|
57
|
-
|
|
58
|
-
const computedDisableApplyToAll = computed(()=>{
|
|
59
|
-
if (isString(props.disableApplyToAll)) {
|
|
60
|
-
return props.disableApplyToAll.split(',').map(i=>i.trim())
|
|
61
|
-
}
|
|
62
|
-
return props.disableApplyToAll
|
|
63
|
-
})
|
|
64
|
-
const canApplyAll = (variableName: string) => {
|
|
65
|
-
if (isArray(computedDisableApplyToAll.value)) return !computedDisableApplyToAll.value.includes(variableName)
|
|
66
|
-
return !computedDisableApplyToAll.value
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
watch(() => props.modelValue, (newValue) => {
|
|
70
|
-
if (!Array.isArray(newValue) || !newValue.every(item => typeof item === 'object')) {
|
|
71
|
-
itemsInternal.value = cloneDeep(props.itemsInitial)
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
let maxKey = 0
|
|
75
|
-
|
|
76
|
-
newValue.forEach((item) => {
|
|
77
|
-
if (!item.hasOwnProperty(props.modelKey)) {
|
|
78
|
-
maxKey = Math.max(maxKey, ...newValue.map(i => i[props.modelKey] || 0))
|
|
79
|
-
item[props.modelKey] = maxKey + 1
|
|
80
|
-
}
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
itemsInternal.value = newValue
|
|
84
|
-
}
|
|
85
|
-
}, { immediate: true })
|
|
86
|
-
|
|
87
|
-
watch(()=>props.itemsInitial, (newValue,oldValue)=>{
|
|
88
|
-
if (!isEqual(newValue,oldValue)) itemsInternal.value = cloneDeep(props.itemsInitial)
|
|
89
|
-
},{immediate:true,deep:true})
|
|
90
|
-
|
|
91
|
-
watch(itemsInternal, () => {
|
|
92
|
-
emit('update:modelValue', itemsInternal.value)
|
|
93
|
-
}, { deep: true })
|
|
94
|
-
|
|
95
|
-
watch(itemsApplyAll, () => {
|
|
96
|
-
itemsInternal.value = itemsInternal.value?.map((item) => {
|
|
97
|
-
return Object.assign(item, itemsApplyAll.value)
|
|
98
|
-
})
|
|
99
|
-
},{deep:true})
|
|
100
|
-
|
|
101
|
-
const computedHeaders = computed(()=>{
|
|
102
|
-
let dataHeaders = templateToHeader(props.dataTemplate)
|
|
103
|
-
let combinedHeaders = [...props.headers, ...dataHeaders]
|
|
104
|
-
return combinedHeaders.map((header: any) => {
|
|
105
|
-
return {...header,headerProps:
|
|
106
|
-
{
|
|
107
|
-
style: 'font-weight: 800'
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
})
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
const computedDataTemplate = computed(()=>{
|
|
114
|
-
let template = cloneDeep(props.dataTemplate)
|
|
115
|
-
if (isString(props.dataTemplate)) {
|
|
116
|
-
try {
|
|
117
|
-
template = JSON.parse(props.dataTemplate)
|
|
118
|
-
} catch (e) {
|
|
119
|
-
void e
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
if (isArray(template)) {
|
|
123
|
-
return template.map((t: any) => {
|
|
124
|
-
const out = { ...t }
|
|
125
|
-
let s = out.inputAttributes?.trim() || ""
|
|
126
|
-
if (!/(^|\s)hide-details(\s|$)/.test(s) && !/(^|\s)hideDetails(\s|$)/.test(s)) {
|
|
127
|
-
s = `${s} hide-details`.trim()
|
|
128
|
-
}
|
|
129
|
-
out.inputAttributes = s
|
|
130
|
-
return out
|
|
131
|
-
})
|
|
132
|
-
}
|
|
133
|
-
return []
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
const reset = ()=>{
|
|
137
|
-
inputRef.value?.reset()
|
|
138
|
-
itemsApplyAll.value = {}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
const isValid = computed(()=>{
|
|
142
|
-
return inputRef.value?.isValid
|
|
143
|
-
})
|
|
144
|
-
|
|
145
|
-
const errorMessages = computed(()=>{
|
|
146
|
-
return inputRef.value?.errorMessages
|
|
147
|
-
})
|
|
148
|
-
|
|
149
|
-
const operation = ref({reset})
|
|
150
|
-
|
|
151
|
-
defineExpose({
|
|
152
|
-
errorMessages,
|
|
153
|
-
isValid,
|
|
154
|
-
reset,
|
|
155
|
-
resetValidation : ()=>inputRef.value?.resetValidation(),
|
|
156
|
-
validate : ()=>inputRef.value?.validate(),
|
|
157
|
-
operation
|
|
158
|
-
})
|
|
159
|
-
</script>
|
|
160
|
-
|
|
161
|
-
<template>
|
|
162
|
-
<v-input v-model="itemsInternal" v-bind="plainAttrs" ref="inputRef">
|
|
163
|
-
<template #default="{isReadonly,isDisabled}">
|
|
164
|
-
<v-container fluid class="ma-0 pa-0">
|
|
165
|
-
<v-card>
|
|
166
|
-
<slot
|
|
167
|
-
name="header"
|
|
168
|
-
:items="itemsInternal"
|
|
169
|
-
:operation="operation"
|
|
170
|
-
>
|
|
171
|
-
<VToolbar :color="toolbarColor">
|
|
172
|
-
<v-row
|
|
173
|
-
justify="end"
|
|
174
|
-
class="ma-1"
|
|
175
|
-
dense
|
|
176
|
-
no-gutters
|
|
177
|
-
align="center"
|
|
178
|
-
>
|
|
179
|
-
<v-col>
|
|
180
|
-
<VToolbarTitle class="pl-3">
|
|
181
|
-
<slot name="title">
|
|
182
|
-
{{ title }}
|
|
183
|
-
</slot>
|
|
184
|
-
</VToolbarTitle>
|
|
185
|
-
</v-col>
|
|
186
|
-
</v-row>
|
|
187
|
-
|
|
188
|
-
<VToolbarItems>
|
|
189
|
-
<slot name="toolbarItems" :items="itemsInternal" :operation="operation"/>
|
|
190
|
-
<VBtn
|
|
191
|
-
:color="toolbarColor"
|
|
192
|
-
icon="mdi:mdi-restore"
|
|
193
|
-
variant="flat"
|
|
194
|
-
@click="reset()"
|
|
195
|
-
>
|
|
196
|
-
</VBtn>
|
|
197
|
-
</VToolbarItems>
|
|
198
|
-
</VToolbar>
|
|
199
|
-
</slot>
|
|
200
|
-
<v-data-table
|
|
201
|
-
v-bind="plainAttrs"
|
|
202
|
-
color="primary"
|
|
203
|
-
:items="itemsInternal"
|
|
204
|
-
:headers="computedHeaders"
|
|
205
|
-
disable-sort
|
|
206
|
-
hide-default-footer
|
|
207
|
-
>
|
|
208
|
-
<!-- @ts-ignore -->
|
|
209
|
-
<template
|
|
210
|
-
v-for="(_, name, index) in ($slots as {})"
|
|
211
|
-
:key="index"
|
|
212
|
-
#[name]="slotData"
|
|
213
|
-
>
|
|
214
|
-
<slot
|
|
215
|
-
:name="name"
|
|
216
|
-
v-bind="((slotData || {}) as object)"
|
|
217
|
-
:operation="operation"
|
|
218
|
-
:isReadonly="isReadonly"
|
|
219
|
-
:isDisabled="isDisabled"
|
|
220
|
-
/>
|
|
221
|
-
</template>
|
|
222
|
-
|
|
223
|
-
<template v-for="template in computedDataTemplate" :key="template.variableName" #[`header.${template.variableName}`]="props">
|
|
224
|
-
<form-pad v-model="itemsApplyAll" :template="templateItemToString(template,[])" v-if="canApplyAll(template.variableName)"></form-pad>
|
|
225
|
-
<template v-else>{{props.column.title}}</template>
|
|
226
|
-
</template>
|
|
227
|
-
|
|
228
|
-
<template v-for="template in computedDataTemplate" :key="template.variableName" #[`item.${template.variableName}`]="{index}">
|
|
229
|
-
<form-pad v-model="itemsInternal[index]" :template="templateItemToString(template,[])"></form-pad>
|
|
230
|
-
</template>
|
|
231
|
-
</v-data-table>
|
|
232
|
-
</v-card>
|
|
233
|
-
</v-container>
|
|
234
|
-
</template>
|
|
235
|
-
</v-input>
|
|
236
|
-
</template>
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
/**
|
|
3
|
+
* FormTableData is a schema-driven form field component that binds model data, renders field UI, and emits normalized updates.
|
|
4
|
+
* This doc block is consumed by vue-docgen for generated API documentation.
|
|
5
|
+
*/
|
|
6
|
+
import {VDataTable} from 'vuetify/components/VDataTable'
|
|
7
|
+
import {VInput} from 'vuetify/components/VInput'
|
|
8
|
+
import {computed, defineOptions,defineExpose, ref, useAttrs, watch, useTemplateRef} from 'vue'
|
|
9
|
+
import {cloneDeep, isEqual, omit, isArray, isString} from 'lodash-es'
|
|
10
|
+
import {templateItemToString} from "../../composables/document/template";
|
|
11
|
+
import {templateToHeader} from "../../composables/document/templateFormTable";
|
|
12
|
+
import { useLocalStorageModel, type PersistSlimProps } from '../../composables/localStorageModel'
|
|
13
|
+
|
|
14
|
+
defineOptions({
|
|
15
|
+
inheritAttrs: false,
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
interface Props extends /* @vue-ignore */ InstanceType<typeof VDataTable['$props']> {
|
|
19
|
+
title: string // Title text displayed in the component header or dialog.
|
|
20
|
+
noDataText?: string // Fallback message shown when there is no data to display.
|
|
21
|
+
modelValue?: Record<string, any>[] // Bound value for v-model synchronization with the parent component.
|
|
22
|
+
modelKey?: string // Primary key field name used to track row identity.
|
|
23
|
+
toolbarColor?: string // Vuetify color name applied to toolbar and action areas.
|
|
24
|
+
headers: Record<string, any>[] // Column definitions used to render table headers and field mapping.
|
|
25
|
+
itemsInitial: Record<string, any>[] // Initial rows used before external data is loaded.
|
|
26
|
+
dataTemplate?: string | object // Template object/string used to seed new row data.
|
|
27
|
+
disableApplyToAll?: boolean | string | string[] // Disables apply-to-all behavior globally or for selected field keys.
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Public props accepted by FormTableData.
|
|
32
|
+
* Document each prop field with intent, defaults, and side effects for clear generated docs.
|
|
33
|
+
*/
|
|
34
|
+
const props = withDefaults(defineProps<Props & PersistSlimProps>(), {
|
|
35
|
+
noDataText: 'ไม่พบข้อมูล',
|
|
36
|
+
modelKey: 'id',
|
|
37
|
+
toolbarColor: 'primary',
|
|
38
|
+
disableApplyToAll: false,
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Custom events emitted by FormTableData.
|
|
43
|
+
* Parents can listen to these events to react to user actions and internal state changes.
|
|
44
|
+
*/
|
|
45
|
+
const emit = defineEmits(['update:modelValue'])
|
|
46
|
+
const attrs = useAttrs()
|
|
47
|
+
const plainAttrs = computed(() => {
|
|
48
|
+
return omit(attrs, ['modelValue','items','onUpdate:modelValue','itemsInitial','dataTemplate'])
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
const inputRef = useTemplateRef<VInput>("inputRef")
|
|
52
|
+
|
|
53
|
+
const itemsInternal = ref<Record<string, any>[]>([])
|
|
54
|
+
const itemsApplyAll = ref<Record<string, any>>({})
|
|
55
|
+
|
|
56
|
+
useLocalStorageModel(itemsInternal,props)
|
|
57
|
+
|
|
58
|
+
const computedDisableApplyToAll = computed(()=>{
|
|
59
|
+
if (isString(props.disableApplyToAll)) {
|
|
60
|
+
return props.disableApplyToAll.split(',').map(i=>i.trim())
|
|
61
|
+
}
|
|
62
|
+
return props.disableApplyToAll
|
|
63
|
+
})
|
|
64
|
+
const canApplyAll = (variableName: string) => {
|
|
65
|
+
if (isArray(computedDisableApplyToAll.value)) return !computedDisableApplyToAll.value.includes(variableName)
|
|
66
|
+
return !computedDisableApplyToAll.value
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
watch(() => props.modelValue, (newValue) => {
|
|
70
|
+
if (!Array.isArray(newValue) || !newValue.every(item => typeof item === 'object')) {
|
|
71
|
+
itemsInternal.value = cloneDeep(props.itemsInitial)
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
let maxKey = 0
|
|
75
|
+
|
|
76
|
+
newValue.forEach((item) => {
|
|
77
|
+
if (!item.hasOwnProperty(props.modelKey)) {
|
|
78
|
+
maxKey = Math.max(maxKey, ...newValue.map(i => i[props.modelKey] || 0))
|
|
79
|
+
item[props.modelKey] = maxKey + 1
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
itemsInternal.value = newValue
|
|
84
|
+
}
|
|
85
|
+
}, { immediate: true })
|
|
86
|
+
|
|
87
|
+
watch(()=>props.itemsInitial, (newValue,oldValue)=>{
|
|
88
|
+
if (!isEqual(newValue,oldValue)) itemsInternal.value = cloneDeep(props.itemsInitial)
|
|
89
|
+
},{immediate:true,deep:true})
|
|
90
|
+
|
|
91
|
+
watch(itemsInternal, () => {
|
|
92
|
+
emit('update:modelValue', itemsInternal.value)
|
|
93
|
+
}, { deep: true })
|
|
94
|
+
|
|
95
|
+
watch(itemsApplyAll, () => {
|
|
96
|
+
itemsInternal.value = itemsInternal.value?.map((item) => {
|
|
97
|
+
return Object.assign(item, itemsApplyAll.value)
|
|
98
|
+
})
|
|
99
|
+
},{deep:true})
|
|
100
|
+
|
|
101
|
+
const computedHeaders = computed(()=>{
|
|
102
|
+
let dataHeaders = templateToHeader(props.dataTemplate)
|
|
103
|
+
let combinedHeaders = [...props.headers, ...dataHeaders]
|
|
104
|
+
return combinedHeaders.map((header: any) => {
|
|
105
|
+
return {...header,headerProps:
|
|
106
|
+
{
|
|
107
|
+
style: 'font-weight: 800'
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
})
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
const computedDataTemplate = computed(()=>{
|
|
114
|
+
let template = cloneDeep(props.dataTemplate)
|
|
115
|
+
if (isString(props.dataTemplate)) {
|
|
116
|
+
try {
|
|
117
|
+
template = JSON.parse(props.dataTemplate)
|
|
118
|
+
} catch (e) {
|
|
119
|
+
void e
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (isArray(template)) {
|
|
123
|
+
return template.map((t: any) => {
|
|
124
|
+
const out = { ...t }
|
|
125
|
+
let s = out.inputAttributes?.trim() || ""
|
|
126
|
+
if (!/(^|\s)hide-details(\s|$)/.test(s) && !/(^|\s)hideDetails(\s|$)/.test(s)) {
|
|
127
|
+
s = `${s} hide-details`.trim()
|
|
128
|
+
}
|
|
129
|
+
out.inputAttributes = s
|
|
130
|
+
return out
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
return []
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
const reset = ()=>{
|
|
137
|
+
inputRef.value?.reset()
|
|
138
|
+
itemsApplyAll.value = {}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const isValid = computed(()=>{
|
|
142
|
+
return inputRef.value?.isValid
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
const errorMessages = computed(()=>{
|
|
146
|
+
return inputRef.value?.errorMessages
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
const operation = ref({reset})
|
|
150
|
+
|
|
151
|
+
defineExpose({
|
|
152
|
+
errorMessages,
|
|
153
|
+
isValid,
|
|
154
|
+
reset,
|
|
155
|
+
resetValidation : ()=>inputRef.value?.resetValidation(),
|
|
156
|
+
validate : ()=>inputRef.value?.validate(),
|
|
157
|
+
operation
|
|
158
|
+
})
|
|
159
|
+
</script>
|
|
160
|
+
|
|
161
|
+
<template>
|
|
162
|
+
<v-input v-model="itemsInternal" v-bind="plainAttrs" ref="inputRef">
|
|
163
|
+
<template #default="{isReadonly,isDisabled}">
|
|
164
|
+
<v-container fluid class="ma-0 pa-0">
|
|
165
|
+
<v-card>
|
|
166
|
+
<slot
|
|
167
|
+
name="header"
|
|
168
|
+
:items="itemsInternal"
|
|
169
|
+
:operation="operation"
|
|
170
|
+
>
|
|
171
|
+
<VToolbar :color="toolbarColor">
|
|
172
|
+
<v-row
|
|
173
|
+
justify="end"
|
|
174
|
+
class="ma-1"
|
|
175
|
+
dense
|
|
176
|
+
no-gutters
|
|
177
|
+
align="center"
|
|
178
|
+
>
|
|
179
|
+
<v-col>
|
|
180
|
+
<VToolbarTitle class="pl-3">
|
|
181
|
+
<slot name="title">
|
|
182
|
+
{{ title }}
|
|
183
|
+
</slot>
|
|
184
|
+
</VToolbarTitle>
|
|
185
|
+
</v-col>
|
|
186
|
+
</v-row>
|
|
187
|
+
|
|
188
|
+
<VToolbarItems>
|
|
189
|
+
<slot name="toolbarItems" :items="itemsInternal" :operation="operation"/>
|
|
190
|
+
<VBtn
|
|
191
|
+
:color="toolbarColor"
|
|
192
|
+
icon="mdi:mdi-restore"
|
|
193
|
+
variant="flat"
|
|
194
|
+
@click="reset()"
|
|
195
|
+
>
|
|
196
|
+
</VBtn>
|
|
197
|
+
</VToolbarItems>
|
|
198
|
+
</VToolbar>
|
|
199
|
+
</slot>
|
|
200
|
+
<v-data-table
|
|
201
|
+
v-bind="plainAttrs"
|
|
202
|
+
color="primary"
|
|
203
|
+
:items="itemsInternal"
|
|
204
|
+
:headers="computedHeaders"
|
|
205
|
+
disable-sort
|
|
206
|
+
hide-default-footer
|
|
207
|
+
>
|
|
208
|
+
<!-- @ts-ignore -->
|
|
209
|
+
<template
|
|
210
|
+
v-for="(_, name, index) in ($slots as {})"
|
|
211
|
+
:key="index"
|
|
212
|
+
#[name]="slotData"
|
|
213
|
+
>
|
|
214
|
+
<slot
|
|
215
|
+
:name="name"
|
|
216
|
+
v-bind="((slotData || {}) as object)"
|
|
217
|
+
:operation="operation"
|
|
218
|
+
:isReadonly="isReadonly"
|
|
219
|
+
:isDisabled="isDisabled"
|
|
220
|
+
/>
|
|
221
|
+
</template>
|
|
222
|
+
|
|
223
|
+
<template v-for="template in computedDataTemplate" :key="template.variableName" #[`header.${template.variableName}`]="props">
|
|
224
|
+
<form-pad v-model="itemsApplyAll" :template="templateItemToString(template,[])" v-if="canApplyAll(template.variableName)"></form-pad>
|
|
225
|
+
<template v-else>{{props.column.title}}</template>
|
|
226
|
+
</template>
|
|
227
|
+
|
|
228
|
+
<template v-for="template in computedDataTemplate" :key="template.variableName" #[`item.${template.variableName}`]="{index}">
|
|
229
|
+
<form-pad v-model="itemsInternal[index]" :template="templateItemToString(template,[])"></form-pad>
|
|
230
|
+
</template>
|
|
231
|
+
</v-data-table>
|
|
232
|
+
</v-card>
|
|
233
|
+
</v-container>
|
|
234
|
+
</template>
|
|
235
|
+
</v-input>
|
|
236
|
+
</template>
|