@ramathibodi/nuxt-commons 0.1.50 → 0.1.51
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/form/ActionPad.vue +64 -58
- package/dist/runtime/components/form/EditPad.vue +140 -0
- package/dist/runtime/components/form/Table.vue +0 -6
- package/dist/runtime/components/form/TableData.vue +82 -0
- package/dist/runtime/components/model/Pad.vue +26 -72
- package/dist/runtime/composables/document/templateFormTable.js +1 -1
- package/package.json +1 -1
package/dist/module.json
CHANGED
|
@@ -6,23 +6,23 @@ import type {FormDialogCallback} from '../../types/formDialog'
|
|
|
6
6
|
interface Props {
|
|
7
7
|
title?: string
|
|
8
8
|
initialData?: object
|
|
9
|
-
|
|
10
|
-
updateCaption?: string
|
|
9
|
+
saveCaption?: string
|
|
11
10
|
cancelCaption?: string
|
|
11
|
+
readonly?: boolean
|
|
12
12
|
showTitle?: boolean
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
const props = withDefaults(defineProps<Props>(), {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
saveCaption: 'บันทึก',
|
|
17
|
+
cancelCaption: 'ยกเลิก',
|
|
18
|
+
readonly: false,
|
|
19
19
|
showTitle: false,
|
|
20
20
|
})
|
|
21
21
|
|
|
22
22
|
const isSaving = ref<boolean>(false)
|
|
23
23
|
const formPadRef = ref()
|
|
24
|
-
const formOriginalData = ref<object>()
|
|
25
24
|
const formData = ref<object>({})
|
|
25
|
+
const formDataOriginalValue = ref<object>()
|
|
26
26
|
|
|
27
27
|
const emit = defineEmits(['create', 'update'])
|
|
28
28
|
|
|
@@ -38,7 +38,8 @@ function cancel() {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
function reset() {
|
|
41
|
-
|
|
41
|
+
formDataOriginalValue.value = undefined
|
|
42
|
+
formPadRef.value.reset()
|
|
42
43
|
loadFormData()
|
|
43
44
|
}
|
|
44
45
|
|
|
@@ -53,11 +54,11 @@ const callback: FormDialogCallback = {
|
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
const isDataChange = computed(() => {
|
|
56
|
-
return !((isCreating.value) ? isEqual(formData.value, createOriginalValue.value) : isEqual(formData.value,
|
|
57
|
+
return !((isCreating.value) ? isEqual(formData.value, createOriginalValue.value) : isEqual(formData.value, formDataOriginalValue.value))
|
|
57
58
|
})
|
|
58
59
|
|
|
59
60
|
const isCreating = computed(() => {
|
|
60
|
-
return !
|
|
61
|
+
return !formDataOriginalValue.value
|
|
61
62
|
})
|
|
62
63
|
|
|
63
64
|
const createOriginalValue = computed(() => {
|
|
@@ -65,69 +66,74 @@ const createOriginalValue = computed(() => {
|
|
|
65
66
|
})
|
|
66
67
|
|
|
67
68
|
const loadFormData = () => {
|
|
68
|
-
if (
|
|
69
|
-
formData.value = cloneDeep(
|
|
69
|
+
if (formDataOriginalValue.value) {
|
|
70
|
+
formData.value = cloneDeep(formDataOriginalValue.value)
|
|
70
71
|
}
|
|
71
72
|
else {
|
|
72
73
|
formData.value = Object.assign({}, props.initialData)
|
|
73
74
|
}
|
|
74
75
|
}
|
|
75
76
|
|
|
77
|
+
const operation = ref({ isDataChange, isCreating, isSaving, save, cancel })
|
|
78
|
+
|
|
76
79
|
watchEffect(loadFormData)
|
|
77
80
|
|
|
78
81
|
function setOriginalData(originalData?: object) {
|
|
79
|
-
|
|
82
|
+
formDataOriginalValue.value = originalData
|
|
80
83
|
}
|
|
81
84
|
|
|
82
|
-
defineExpose({setOriginalData,
|
|
85
|
+
defineExpose({setOriginalData,operation})
|
|
83
86
|
</script>
|
|
84
87
|
|
|
85
88
|
<template>
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
<VCard flat>
|
|
90
|
+
<VToolbar v-if="showTitle">
|
|
91
|
+
<slot name="titleToolbar" :operation="operation">
|
|
92
|
+
<VToolbarTitle>
|
|
93
|
+
<slot name="title" :operation="operation">
|
|
94
|
+
{{ (isCreating) ? "New" : "Edit" }} {{ title }}
|
|
95
|
+
</slot>
|
|
96
|
+
</VToolbarTitle>
|
|
91
97
|
</slot>
|
|
92
|
-
</
|
|
93
|
-
<
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
isolated
|
|
100
|
-
>
|
|
101
|
-
<template #default="slotData">
|
|
102
|
-
<slot
|
|
103
|
-
v-bind="slotData"
|
|
104
|
-
:is-creating="isCreating"
|
|
105
|
-
:is-data-change="isDataChange"
|
|
106
|
-
/>
|
|
107
|
-
</template>
|
|
108
|
-
</form-pad>
|
|
109
|
-
</VCardText>
|
|
110
|
-
<VCardActions>
|
|
111
|
-
<slot name="action" :save="save" :cancel="cancel">
|
|
112
|
-
<VSpacer />
|
|
113
|
-
<VBtn
|
|
114
|
-
color="primary"
|
|
115
|
-
variant="flat"
|
|
116
|
-
:loading="isSaving"
|
|
117
|
-
:disabled="!isDataChange"
|
|
118
|
-
@click="save"
|
|
119
|
-
>
|
|
120
|
-
{{ (isCreating) ? createCaption : updateCaption }}
|
|
121
|
-
</VBtn>
|
|
122
|
-
<VBtn
|
|
123
|
-
color="error"
|
|
124
|
-
variant="flat"
|
|
125
|
-
:disabled="isSaving"
|
|
126
|
-
@click="cancel"
|
|
98
|
+
</VToolbar>
|
|
99
|
+
<VCardText>
|
|
100
|
+
<form-pad
|
|
101
|
+
ref="formPadRef"
|
|
102
|
+
v-model="formData"
|
|
103
|
+
:readonly="readonly"
|
|
104
|
+
isolated
|
|
127
105
|
>
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
106
|
+
<template #default="slotData">
|
|
107
|
+
<slot
|
|
108
|
+
v-bind="slotData"
|
|
109
|
+
:is-creating="isCreating"
|
|
110
|
+
:is-data-change="isDataChange"
|
|
111
|
+
/>
|
|
112
|
+
</template>
|
|
113
|
+
</form-pad>
|
|
114
|
+
</VCardText>
|
|
115
|
+
<VCardActions>
|
|
116
|
+
<slot name="action" :operation="operation">
|
|
117
|
+
<VSpacer />
|
|
118
|
+
<VBtn
|
|
119
|
+
color="primary"
|
|
120
|
+
variant="flat"
|
|
121
|
+
:loading="isSaving"
|
|
122
|
+
:disabled="!isDataChange"
|
|
123
|
+
@click="save"
|
|
124
|
+
v-if="!readonly"
|
|
125
|
+
>
|
|
126
|
+
{{ saveCaption }}
|
|
127
|
+
</VBtn>
|
|
128
|
+
<VBtn
|
|
129
|
+
color="error"
|
|
130
|
+
variant="flat"
|
|
131
|
+
:disabled="isSaving"
|
|
132
|
+
@click="cancel"
|
|
133
|
+
>
|
|
134
|
+
{{ cancelCaption }}
|
|
135
|
+
</VBtn>
|
|
136
|
+
</slot>
|
|
137
|
+
</VCardActions>
|
|
138
|
+
</VCard>
|
|
133
139
|
</template>
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import {computed, ref, watchEffect} from 'vue'
|
|
3
|
+
import {cloneDeep, isEqual} from 'lodash-es'
|
|
4
|
+
import type {FormDialogCallback} from '../../types/formDialog'
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
title?: string
|
|
8
|
+
initialData?: object
|
|
9
|
+
formData?: object
|
|
10
|
+
saveCaption?: string
|
|
11
|
+
cancelCaption?: string
|
|
12
|
+
readonly?: boolean
|
|
13
|
+
showTitle?: boolean
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
17
|
+
saveCaption: 'บันทึก',
|
|
18
|
+
cancelCaption: 'ยกเลิก',
|
|
19
|
+
readonly: false,
|
|
20
|
+
showTitle: false,
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
const isSaving = ref<boolean>(false)
|
|
24
|
+
const formPadRef = ref()
|
|
25
|
+
const formData = ref<object>({})
|
|
26
|
+
const formDataOriginalValue = ref<object>()
|
|
27
|
+
|
|
28
|
+
const emit = defineEmits(['create', 'update'])
|
|
29
|
+
|
|
30
|
+
function save() {
|
|
31
|
+
if (formPadRef.value.isValid) {
|
|
32
|
+
isSaving.value = true
|
|
33
|
+
emit((isCreating.value) ? 'create' : 'update', cloneDeep(formData.value), callback)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function cancel() {
|
|
38
|
+
reset()
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function reset() {
|
|
42
|
+
formDataOriginalValue.value = undefined
|
|
43
|
+
formPadRef.value.reset()
|
|
44
|
+
loadFormData()
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const callback: FormDialogCallback = {
|
|
48
|
+
done: function () {
|
|
49
|
+
isSaving.value = false
|
|
50
|
+
},
|
|
51
|
+
error: function () {
|
|
52
|
+
isSaving.value = false
|
|
53
|
+
},
|
|
54
|
+
setData: function (item: object) {
|
|
55
|
+
formData.value = cloneDeep(item)
|
|
56
|
+
formDataOriginalValue.value = cloneDeep(item)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const isDataChange = computed(() => {
|
|
61
|
+
return !((isCreating.value) ? isEqual(formData.value, createOriginalValue.value) : isEqual(formData.value, formDataOriginalValue.value))
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
const isCreating = computed(() => {
|
|
65
|
+
return !props.formData
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
const createOriginalValue = computed(() => {
|
|
69
|
+
return Object.assign({}, props.initialData)
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
const loadFormData = () => {
|
|
73
|
+
if (props.formData) {
|
|
74
|
+
formData.value = cloneDeep(props.formData)
|
|
75
|
+
formDataOriginalValue.value = cloneDeep(props.formData)
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
formData.value = Object.assign({}, props.initialData)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const operation = ref({ isDataChange, isCreating, isSaving, save, cancel })
|
|
83
|
+
|
|
84
|
+
watchEffect(loadFormData)
|
|
85
|
+
|
|
86
|
+
defineExpose({operation})
|
|
87
|
+
</script>
|
|
88
|
+
|
|
89
|
+
<template>
|
|
90
|
+
<VCard flat>
|
|
91
|
+
<VToolbar v-if="showTitle">
|
|
92
|
+
<slot name="titleToolbar" :operation="operation">
|
|
93
|
+
<VToolbarTitle>
|
|
94
|
+
<slot name="title" :operation="operation">
|
|
95
|
+
{{ (isCreating) ? "New" : "Edit" }} {{ title }}
|
|
96
|
+
</slot>
|
|
97
|
+
</VToolbarTitle>
|
|
98
|
+
</slot>
|
|
99
|
+
</VToolbar>
|
|
100
|
+
<VCardText>
|
|
101
|
+
<form-pad
|
|
102
|
+
ref="formPadRef"
|
|
103
|
+
v-model="formData"
|
|
104
|
+
:readonly="readonly"
|
|
105
|
+
isolated
|
|
106
|
+
>
|
|
107
|
+
<template #default="slotData">
|
|
108
|
+
<slot
|
|
109
|
+
v-bind="slotData"
|
|
110
|
+
:is-creating="isCreating"
|
|
111
|
+
:is-data-change="isDataChange"
|
|
112
|
+
/>
|
|
113
|
+
</template>
|
|
114
|
+
</form-pad>
|
|
115
|
+
</VCardText>
|
|
116
|
+
<VCardActions>
|
|
117
|
+
<slot name="action" :operation="operation">
|
|
118
|
+
<VSpacer />
|
|
119
|
+
<VBtn
|
|
120
|
+
color="primary"
|
|
121
|
+
variant="flat"
|
|
122
|
+
:loading="isSaving"
|
|
123
|
+
:disabled="!isDataChange"
|
|
124
|
+
@click="save"
|
|
125
|
+
v-if="!readonly"
|
|
126
|
+
>
|
|
127
|
+
{{ saveCaption }}
|
|
128
|
+
</VBtn>
|
|
129
|
+
<VBtn
|
|
130
|
+
color="error"
|
|
131
|
+
variant="flat"
|
|
132
|
+
:disabled="isSaving"
|
|
133
|
+
@click="cancel"
|
|
134
|
+
>
|
|
135
|
+
{{ cancelCaption }}
|
|
136
|
+
</VBtn>
|
|
137
|
+
</slot>
|
|
138
|
+
</VCardActions>
|
|
139
|
+
</VCard>
|
|
140
|
+
</template>
|
|
@@ -26,7 +26,6 @@ interface Props extends /* @vue-ignore */ InstanceType<typeof VDataTable['$props
|
|
|
26
26
|
inputPadOnly?: boolean
|
|
27
27
|
saveAndStay?: boolean
|
|
28
28
|
stringFields?: Array<string>
|
|
29
|
-
items?: Record<string, any>[]
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
const props = withDefaults(defineProps<Props>(), {
|
|
@@ -85,11 +84,6 @@ watch(items, (newValue) => {
|
|
|
85
84
|
emit('update:modelValue', newValue)
|
|
86
85
|
}, { deep: true })
|
|
87
86
|
|
|
88
|
-
onMounted(()=>{
|
|
89
|
-
if (props.items){
|
|
90
|
-
items.value = props.items
|
|
91
|
-
}
|
|
92
|
-
})
|
|
93
87
|
|
|
94
88
|
function createItem(item: Record<string, any>, callback?: FormDialogCallback) {
|
|
95
89
|
if (items.value.length > 0) item[props.modelKey] = Math.max(...items.value.map(i => i[props.modelKey] || 0)) + 1
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {VDataTable} from 'vuetify/components/VDataTable'
|
|
3
|
+
import {computed, onMounted, ref, useAttrs, watch} from 'vue'
|
|
4
|
+
import {omit} from "lodash-es";
|
|
5
|
+
interface Props extends /* @vue-ignore */ InstanceType<typeof VDataTable['$props']> {
|
|
6
|
+
title: string
|
|
7
|
+
modelValue?: Record<string, any>[]
|
|
8
|
+
modelKey?: string
|
|
9
|
+
toolbarColor?: string
|
|
10
|
+
items : Record<string, any>
|
|
11
|
+
}
|
|
12
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
13
|
+
modelKey: 'id',
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
const emit = defineEmits(['update:modelValue'])
|
|
17
|
+
const attrs = useAttrs()
|
|
18
|
+
const plainAttrs = computed(() => {
|
|
19
|
+
return omit(attrs, ['modelValue', 'onUpdate:modelValue'])
|
|
20
|
+
})
|
|
21
|
+
const modelValue = ref()
|
|
22
|
+
const setDataItems = ()=>{
|
|
23
|
+
modelValue.value = props.items
|
|
24
|
+
}
|
|
25
|
+
watch(() => props.modelValue, (newValue) => {
|
|
26
|
+
if (!Array.isArray(newValue) || !newValue.every(item => typeof item === 'object')) {
|
|
27
|
+
modelValue.value = []
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
let maxKey = 0
|
|
31
|
+
|
|
32
|
+
newValue.forEach((item) => {
|
|
33
|
+
if (!item.hasOwnProperty(props.modelKey)) {
|
|
34
|
+
maxKey = Math.max(maxKey, ...newValue.map(i => i[props.modelKey] || 0))
|
|
35
|
+
item[props.modelKey] = maxKey + 1
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
modelValue.value = newValue
|
|
40
|
+
}
|
|
41
|
+
}, { immediate: true })
|
|
42
|
+
|
|
43
|
+
watch(modelValue, (newValue) => {
|
|
44
|
+
emit('update:modelValue', newValue)
|
|
45
|
+
}, { deep: true })
|
|
46
|
+
|
|
47
|
+
onMounted(()=>{
|
|
48
|
+
setDataItems()
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
<template>
|
|
55
|
+
<form-table
|
|
56
|
+
v-bind="plainAttrs"
|
|
57
|
+
v-model="modelValue"
|
|
58
|
+
:title="props.title"
|
|
59
|
+
:toolbarColor="props.toolbarColor"
|
|
60
|
+
:model-key="props.modelKey"
|
|
61
|
+
:insertable="false"
|
|
62
|
+
:importable="false"
|
|
63
|
+
:exportable="false"
|
|
64
|
+
:searchable="false"
|
|
65
|
+
hide-default-footer>
|
|
66
|
+
<!-- @ts-ignore -->
|
|
67
|
+
<template
|
|
68
|
+
v-for="(_, name, index) in ($slots as {})"
|
|
69
|
+
:key="index"
|
|
70
|
+
#[name]="slotData"
|
|
71
|
+
>
|
|
72
|
+
<slot
|
|
73
|
+
:name="name"
|
|
74
|
+
v-bind="((slotData || {}) as object)"
|
|
75
|
+
/>
|
|
76
|
+
</template>
|
|
77
|
+
</form-table>
|
|
78
|
+
</template>
|
|
79
|
+
|
|
80
|
+
<style scoped>
|
|
81
|
+
|
|
82
|
+
</style>
|
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
-
import { computed,
|
|
3
|
-
import { cloneDeep, isEqual } from 'lodash-es'
|
|
2
|
+
import { computed, useTemplateRef } from 'vue'
|
|
4
3
|
import { type GraphqlModelItemProps, useGraphqlModelItem } from '../../composables/graphqlModelItem'
|
|
4
|
+
import EditPad from '../form/EditPad.vue'
|
|
5
5
|
|
|
6
6
|
defineOptions({
|
|
7
7
|
inheritAttrs: false,
|
|
8
8
|
})
|
|
9
9
|
|
|
10
|
-
interface Props {
|
|
11
|
-
title?: string
|
|
12
|
-
initialData?: object
|
|
13
|
-
saveCaption?: string
|
|
14
|
-
cancelCaption?: string
|
|
10
|
+
interface Props extends /* @vue-ignore */ InstanceType<typeof EditPad['$props']> {
|
|
15
11
|
}
|
|
16
12
|
|
|
17
13
|
const props = withDefaults(defineProps<Props & GraphqlModelItemProps>(), {
|
|
@@ -25,92 +21,43 @@ const { item,
|
|
|
25
21
|
createItem, updateItem,
|
|
26
22
|
reload, isLoading } = useGraphqlModelItem(props)
|
|
27
23
|
|
|
28
|
-
const
|
|
29
|
-
const formData = ref<object>({})
|
|
24
|
+
const editPad = useTemplateRef<typeof EditPad>("editPadRef")
|
|
30
25
|
|
|
31
|
-
const canSave = computed(() => { return (canCreate.value &&
|
|
26
|
+
const canSave = computed<boolean>(() => { return ((canCreate.value && editPad.value?.operation?.isCreating?.value) || canUpdate.value) as boolean})
|
|
32
27
|
|
|
33
|
-
const
|
|
34
|
-
return
|
|
28
|
+
const operation : any = computed(()=>{
|
|
29
|
+
return Object.assign({},editPad.value?.operation,{canSave,reload,item})
|
|
35
30
|
})
|
|
36
31
|
|
|
37
|
-
|
|
38
|
-
return !item.value
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
const createOriginalValue = computed(() => {
|
|
42
|
-
return Object.assign({}, props.initialData)
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
const loadFormData = () => {
|
|
46
|
-
if (item.value) {
|
|
47
|
-
formData.value = cloneDeep(item.value)
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
formData.value = Object.assign({}, props.initialData)
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
watchEffect(loadFormData)
|
|
55
|
-
|
|
56
|
-
function save() {
|
|
57
|
-
if (formPadRef.value.isValid) {
|
|
58
|
-
if (isCreating.value) createItem(formData.value)
|
|
59
|
-
else updateItem(formData.value)
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function cancel() {
|
|
64
|
-
formPadRef.value.reset()
|
|
65
|
-
loadFormData()
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const operation = ref({save, cancel, reload, item, canSave, isLoading,isDataChange,isCreating})
|
|
69
|
-
|
|
70
|
-
defineExpose({ save, cancel, reload, item, isLoading })
|
|
32
|
+
defineExpose({ operation })
|
|
71
33
|
</script>
|
|
72
34
|
|
|
73
35
|
<template>
|
|
74
|
-
<
|
|
75
|
-
<
|
|
36
|
+
<FormEditPad :form-data="item" ref="editPadRef" @create="createItem" @update="updateItem">
|
|
37
|
+
<template #titleToolbar="slotData">
|
|
76
38
|
<slot name="titleToolbar" :operation="operation">
|
|
77
39
|
<VToolbarTitle>
|
|
78
40
|
<slot name="title" :operation="operation">
|
|
79
41
|
{{ title }}
|
|
80
42
|
<v-icon
|
|
81
|
-
|
|
82
|
-
|
|
43
|
+
size="small"
|
|
44
|
+
@click="reload"
|
|
83
45
|
>
|
|
84
46
|
mdi mdi-refresh
|
|
85
47
|
</v-icon>
|
|
86
48
|
</slot>
|
|
87
49
|
</VToolbarTitle>
|
|
88
50
|
</slot>
|
|
89
|
-
</
|
|
90
|
-
<
|
|
91
|
-
<form-pad
|
|
92
|
-
ref="formPadRef"
|
|
93
|
-
v-model="formData"
|
|
94
|
-
isolated
|
|
95
|
-
>
|
|
96
|
-
<template #default="slotData">
|
|
97
|
-
<slot
|
|
98
|
-
v-bind="slotData"
|
|
99
|
-
:is-creating="isCreating"
|
|
100
|
-
:is-data-change="isDataChange"
|
|
101
|
-
/>
|
|
102
|
-
</template>
|
|
103
|
-
</form-pad>
|
|
104
|
-
</VCardText>
|
|
105
|
-
<VCardActions>
|
|
51
|
+
</template>
|
|
52
|
+
<template #action="slotData">
|
|
106
53
|
<slot name="action" :operation="operation">
|
|
107
54
|
<VSpacer />
|
|
108
55
|
<VBtn
|
|
109
56
|
color="primary"
|
|
110
57
|
variant="flat"
|
|
111
58
|
:loading="isLoading"
|
|
112
|
-
:disabled="!isDataChange || !canSave"
|
|
113
|
-
@click="save"
|
|
59
|
+
:disabled="!slotData.operation?.isDataChange || !canSave"
|
|
60
|
+
@click="slotData.operation?.save"
|
|
114
61
|
>
|
|
115
62
|
{{ saveCaption }}
|
|
116
63
|
</VBtn>
|
|
@@ -118,11 +65,18 @@ defineExpose({ save, cancel, reload, item, isLoading })
|
|
|
118
65
|
color="error"
|
|
119
66
|
variant="flat"
|
|
120
67
|
:disabled="isLoading"
|
|
121
|
-
@click="cancel"
|
|
68
|
+
@click="slotData.operation?.cancel"
|
|
122
69
|
>
|
|
123
70
|
{{ cancelCaption }}
|
|
124
71
|
</VBtn>
|
|
125
72
|
</slot>
|
|
126
|
-
</
|
|
127
|
-
|
|
73
|
+
</template>
|
|
74
|
+
<template #default="slotData">
|
|
75
|
+
<slot
|
|
76
|
+
v-bind="slotData"
|
|
77
|
+
:is-creating="isCreating"
|
|
78
|
+
:is-data-change="isDataChange"
|
|
79
|
+
/>
|
|
80
|
+
</template>
|
|
81
|
+
</FormEditPad>
|
|
128
82
|
</template>
|
|
@@ -37,7 +37,7 @@ export function processTemplateFormTableData(item, parentTemplates) {
|
|
|
37
37
|
</template>`;
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
|
-
item.inputType = "
|
|
40
|
+
item.inputType = "FormTableData";
|
|
41
41
|
return processDefaultTemplate(item, tableTemplate, `title="${tableOptions.title}"
|
|
42
42
|
:headers='${escapeObjectForInlineBinding(tableHeader)}'
|
|
43
43
|
:items='${escapeObjectForInlineBinding(tableItems)}'
|