@drax/crud-vue 0.11.5 → 0.12.1
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/package.json +6 -6
- package/src/EntityCrud.ts +142 -138
- package/src/components/CrudAutocomplete.vue +2 -5
- package/src/components/CrudForm.vue +5 -1
- package/src/components/CrudFormField.vue +1 -2
- package/src/components/CrudFormList.vue +11 -1
- package/src/components/CrudSearch.vue +22 -2
- package/src/composables/UseCrud.ts +9 -4
- package/src/composables/UseInputErrorI18n.ts +19 -0
- package/src/helpers/getItemId.ts +11 -0
- package/src/index.ts +2 -0
- package/src/stores/UseCrudStore.ts +21 -11
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.12.1",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "./src/index.ts",
|
|
9
9
|
"module": "./src/index.ts",
|
|
@@ -24,10 +24,10 @@
|
|
|
24
24
|
"format": "prettier --write src/"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@drax/common-front": "^0.
|
|
28
|
-
"@drax/crud-front": "^0.
|
|
29
|
-
"@drax/crud-share": "^0.
|
|
30
|
-
"@drax/media-vue": "^0.
|
|
27
|
+
"@drax/common-front": "^0.12.1",
|
|
28
|
+
"@drax/crud-front": "^0.12.1",
|
|
29
|
+
"@drax/crud-share": "^0.12.1",
|
|
30
|
+
"@drax/media-vue": "^0.12.1"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"pinia": "^2.2.2",
|
|
@@ -64,5 +64,5 @@
|
|
|
64
64
|
"vue-tsc": "^2.1.10",
|
|
65
65
|
"vuetify": "^3.7.1"
|
|
66
66
|
},
|
|
67
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "76fd366e12449f5f605662197f985a28d98058a2"
|
|
68
68
|
}
|
package/src/EntityCrud.ts
CHANGED
|
@@ -1,187 +1,191 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
IEntityCrud, IEntityCrudForm, IEntityCrudHeader, IEntityCrudRefs,
|
|
3
|
+
IEntityCrudRules, IEntityCrudField, IEntityCrudPermissions,
|
|
4
|
+
IDraxCrudProvider, IEntityCrudFilter, IEntityCrudFormFilter
|
|
5
5
|
} from "@drax/crud-share";
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
class EntityCrud implements IEntityCrud {
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
name: string = ''
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
constructor() {
|
|
14
|
-
}
|
|
12
|
+
constructor() {
|
|
13
|
+
}
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
static get instance(): IEntityCrud {
|
|
16
|
+
throw new Error('EntityCrud instance not found')
|
|
17
|
+
}
|
|
19
18
|
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
get headers(): IEntityCrudHeader[] {
|
|
21
|
+
return [
|
|
22
|
+
{title: 'ID', key: '_id'},
|
|
23
|
+
]
|
|
24
|
+
}
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
26
|
+
get actionHeaders(): IEntityCrudHeader[] {
|
|
27
|
+
return [
|
|
28
|
+
{
|
|
29
|
+
title: 'action.actions',
|
|
30
|
+
key: 'actions',
|
|
31
|
+
sortable: false,
|
|
32
|
+
align: 'center',
|
|
33
|
+
minWidth: '190px'
|
|
34
|
+
},
|
|
35
|
+
]
|
|
36
|
+
}
|
|
38
37
|
|
|
39
38
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
get permissions(): IEntityCrudPermissions {
|
|
40
|
+
return {
|
|
41
|
+
manage: 'manage', view: 'view', create: 'create', update: 'update', delete: 'delete'
|
|
42
|
+
}
|
|
43
43
|
}
|
|
44
|
-
}
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
get provider(): IDraxCrudProvider<any, any, any> {
|
|
46
|
+
throw new Error('provider not implemented')
|
|
47
|
+
}
|
|
49
48
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
49
|
+
get fields(): IEntityCrudField[] {
|
|
50
|
+
return [
|
|
51
|
+
{name: '_id', type: 'string', label: 'ID', default: ''},
|
|
52
|
+
]
|
|
53
|
+
}
|
|
55
54
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
get createFields() {
|
|
56
|
+
return this.fields
|
|
57
|
+
}
|
|
59
58
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
get updateFields() {
|
|
60
|
+
return this.fields
|
|
61
|
+
}
|
|
63
62
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
get deleteFields() {
|
|
64
|
+
return this.fields
|
|
65
|
+
}
|
|
67
66
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
get viewFields() {
|
|
68
|
+
return this.fields
|
|
69
|
+
}
|
|
71
70
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
71
|
+
get filters(): IEntityCrudFilter[] {
|
|
72
|
+
return [
|
|
73
|
+
{name: '_id', type: 'string', label: 'ID', default: '', operator: 'eq'},
|
|
74
|
+
]
|
|
75
|
+
}
|
|
77
76
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
77
|
+
objectFields(field: IEntityCrudField) {
|
|
78
|
+
let value: any = {}
|
|
79
|
+
if (field.objectFields) {
|
|
80
|
+
field.objectFields.forEach(subField => {
|
|
81
|
+
|
|
82
|
+
if (subField.default != undefined) {
|
|
83
|
+
value[subField.name] = field.default
|
|
84
|
+
} else if (subField.type === 'object') {
|
|
85
|
+
value[subField.name] = this.objectFields(field)
|
|
86
|
+
} else if (/array/.test(field.type)) {
|
|
87
|
+
value[subField.name] = []
|
|
88
|
+
} else {
|
|
89
|
+
value = null
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
})
|
|
88
93
|
}
|
|
89
|
-
|
|
90
|
-
})
|
|
94
|
+
return value
|
|
91
95
|
}
|
|
92
|
-
return value
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
get form():IEntityCrudForm{
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
let value = null
|
|
99
|
-
if(field.type === 'object'){
|
|
100
|
-
value = this.objectFields(field)
|
|
101
|
-
}else if(field.default != undefined){
|
|
102
|
-
value = field.default
|
|
103
|
-
}else{
|
|
104
|
-
value = null
|
|
105
|
-
}
|
|
97
|
+
get form(): IEntityCrudForm {
|
|
106
98
|
|
|
107
|
-
|
|
108
|
-
|
|
99
|
+
return this.fields.reduce((acc, field) => {
|
|
100
|
+
let value = null
|
|
101
|
+
if (field.default != undefined) {
|
|
102
|
+
value = field.default
|
|
103
|
+
} else if (field.type === 'object') {
|
|
104
|
+
value = this.objectFields(field)
|
|
105
|
+
} else if (/array/.test(field.type)) {
|
|
106
|
+
value = []
|
|
107
|
+
} else {
|
|
108
|
+
value = null
|
|
109
|
+
}
|
|
109
110
|
|
|
110
|
-
|
|
111
|
+
return {...acc, [field.name]: value}
|
|
112
|
+
}, {})
|
|
111
113
|
|
|
114
|
+
}
|
|
112
115
|
|
|
113
|
-
get formFilters():IEntityCrudFormFilter[]{
|
|
114
|
-
return this.filters.map(
|
|
115
|
-
(filter:IEntityCrudFilter) =>
|
|
116
|
-
({field:filter.name, value: null, operator: filter.operator })
|
|
117
|
-
)
|
|
118
|
-
}
|
|
119
116
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
117
|
+
get formFilters(): IEntityCrudFormFilter[] {
|
|
118
|
+
return this.filters.map(
|
|
119
|
+
(filter: IEntityCrudFilter) =>
|
|
120
|
+
({field: filter.name, value: null, operator: filter.operator})
|
|
121
|
+
)
|
|
122
|
+
}
|
|
123
123
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
throw new Error("Ref not found: " + ref)
|
|
124
|
+
get refs(): IEntityCrudRefs {
|
|
125
|
+
return {}
|
|
127
126
|
}
|
|
128
127
|
|
|
129
|
-
|
|
130
|
-
|
|
128
|
+
getRef(ref: string): IEntityCrud {
|
|
129
|
+
if (!this.refs.hasOwnProperty(ref)) {
|
|
130
|
+
throw new Error("Ref not found: " + ref)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return this.refs[ref]
|
|
134
|
+
}
|
|
131
135
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
136
|
+
get rules(): IEntityCrudRules {
|
|
137
|
+
return {}
|
|
138
|
+
}
|
|
135
139
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
140
|
+
getRule(field: string | undefined): Array<Function> | undefined {
|
|
141
|
+
return field && this.rules[field] && this.rules[field].length > 0 ? this.rules[field] : undefined
|
|
142
|
+
}
|
|
139
143
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
144
|
+
get isViewable() {
|
|
145
|
+
return true
|
|
146
|
+
}
|
|
143
147
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
148
|
+
get isEditable() {
|
|
149
|
+
return true
|
|
150
|
+
}
|
|
147
151
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
152
|
+
get isCreatable() {
|
|
153
|
+
return true
|
|
154
|
+
}
|
|
151
155
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
156
|
+
get isDeletable() {
|
|
157
|
+
return true
|
|
158
|
+
}
|
|
155
159
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
160
|
+
get isExportable() {
|
|
161
|
+
return true
|
|
162
|
+
}
|
|
159
163
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
164
|
+
get exportFormats() {
|
|
165
|
+
return ['CSV', 'JSON']
|
|
166
|
+
}
|
|
163
167
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
168
|
+
get exportHeaders() {
|
|
169
|
+
return ['_id']
|
|
170
|
+
}
|
|
167
171
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
172
|
+
get isImportable() {
|
|
173
|
+
return true
|
|
174
|
+
}
|
|
171
175
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
176
|
+
get importFormats() {
|
|
177
|
+
return ['CSV', 'JSON']
|
|
178
|
+
}
|
|
175
179
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
180
|
+
get dialogFullscreen() {
|
|
181
|
+
return false
|
|
182
|
+
}
|
|
179
183
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
184
|
+
get dialogMaxWidth() {
|
|
185
|
+
return ''
|
|
186
|
+
}
|
|
183
187
|
|
|
184
188
|
}
|
|
185
189
|
|
|
186
190
|
export default EntityCrud;
|
|
187
|
-
export {
|
|
191
|
+
export {EntityCrud}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import {debounce} from "@drax/common-front"
|
|
3
3
|
import { type PropType, type Ref} from "vue";
|
|
4
4
|
import {ref, onBeforeMount} from "vue";
|
|
5
|
+
import {getItemId} from "../helpers/getItemId"
|
|
5
6
|
import type {IEntityCrud, IEntityCrudField} from "@drax/crud-share";
|
|
6
7
|
|
|
7
8
|
const valueModel = defineModel<string | string[]>({type: [String, Array], required: false})
|
|
@@ -57,7 +58,6 @@ async function search(value: any) {
|
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
onBeforeMount(async () => {
|
|
60
|
-
|
|
61
61
|
await search('')
|
|
62
62
|
await checkIds()
|
|
63
63
|
})
|
|
@@ -68,7 +68,7 @@ async function checkIds(ids: Array<string> = []) {
|
|
|
68
68
|
if(valueModel.value) {
|
|
69
69
|
let ids = Array.isArray(valueModel.value) ? valueModel.value : [valueModel.value]
|
|
70
70
|
for (let id of ids) {
|
|
71
|
-
if (!items.value.some((item: any) => item
|
|
71
|
+
if (!items.value.some((item: any) => getItemId(item) === id)) {
|
|
72
72
|
if (!entity) {
|
|
73
73
|
throw new Error('CrudAutocomplete Entity is required')
|
|
74
74
|
}
|
|
@@ -88,9 +88,6 @@ async function checkIds(ids: Array<string> = []) {
|
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
91
|
defineEmits(['updateValue'])
|
|
95
92
|
|
|
96
93
|
</script>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import {useI18n} from "vue-i18n";
|
|
3
3
|
import type {IEntityCrud, IEntityCrudField, IEntityCrudOperation} from "@drax/crud-share";
|
|
4
4
|
import {useFormUtils} from "../composables/UseFormUtils";
|
|
5
|
+
import {getItemId} from "../helpers/getItemId";
|
|
5
6
|
import CrudFormField from "./CrudFormField.vue";
|
|
6
7
|
import {computed, defineEmits, defineModel, defineProps, ref} from "vue";
|
|
7
8
|
import type {PropType} from "vue";
|
|
@@ -11,6 +12,8 @@ import {useAuth} from '@drax/identity-vue'
|
|
|
11
12
|
const {hasPermission} = useAuth()
|
|
12
13
|
const {t, te} = useI18n()
|
|
13
14
|
|
|
15
|
+
|
|
16
|
+
|
|
14
17
|
const valueModel = defineModel({type: [Object]})
|
|
15
18
|
|
|
16
19
|
const {entity, operation} = defineProps({
|
|
@@ -20,6 +23,7 @@ const {entity, operation} = defineProps({
|
|
|
20
23
|
error: {type: String, required: false},
|
|
21
24
|
})
|
|
22
25
|
|
|
26
|
+
|
|
23
27
|
const emit = defineEmits(['submit', 'cancel'])
|
|
24
28
|
|
|
25
29
|
const store = useCrudStore()
|
|
@@ -76,7 +80,7 @@ const {
|
|
|
76
80
|
<v-form ref="formRef" @submit.prevent>
|
|
77
81
|
<v-card flat>
|
|
78
82
|
|
|
79
|
-
<v-card-subtitle v-if="valueModel
|
|
83
|
+
<v-card-subtitle v-if="getItemId(valueModel)">ID: {{ getItemId(valueModel) }}</v-card-subtitle>
|
|
80
84
|
|
|
81
85
|
<v-card-text v-if="error">
|
|
82
86
|
<v-alert color="error">{{ te(error) ? t(error) : error }}</v-alert>
|
|
@@ -59,8 +59,7 @@ const rules = computed(() => {
|
|
|
59
59
|
const inputErrors = computed(() => {
|
|
60
60
|
let sIndex = (index != null && index >= 0) ? `${index}.` : ''
|
|
61
61
|
let name = parentField ? `${parentField}.${sIndex}${field.name}` : field.name
|
|
62
|
-
|
|
63
|
-
return store.getInputErrors(name).map((error: string) => t(te(error) ? t(error) : error))
|
|
62
|
+
return store.getFieldInputErrors(name).map((error: string) =>te(error) ? t(error) : error)
|
|
64
63
|
}
|
|
65
64
|
)
|
|
66
65
|
|
|
@@ -3,7 +3,9 @@ import {computed, type PropType} from "vue";
|
|
|
3
3
|
import CrudFormField from "./CrudFormField.vue";
|
|
4
4
|
import type {IEntityCrud, IEntityCrudField} from "@drax/crud-share";
|
|
5
5
|
import {useI18n} from "vue-i18n";
|
|
6
|
+
import {useCrudStore} from "../stores/UseCrudStore";
|
|
6
7
|
|
|
8
|
+
const store = useCrudStore()
|
|
7
9
|
const {t, te} = useI18n()
|
|
8
10
|
const valueModel = defineModel({type: Array, default: () => []});
|
|
9
11
|
|
|
@@ -49,6 +51,14 @@ const label = computed(() => {
|
|
|
49
51
|
return te(i18n) ? t(i18n) : field.label
|
|
50
52
|
})
|
|
51
53
|
|
|
54
|
+
const hasError = computed(() => {
|
|
55
|
+
return (index:number) => {
|
|
56
|
+
const fieldListName = field.name + '.' + index
|
|
57
|
+
return store.hasFieldListInputErrors(fieldListName)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
})
|
|
61
|
+
|
|
52
62
|
defineEmits(['updateValue'])
|
|
53
63
|
|
|
54
64
|
</script>
|
|
@@ -62,7 +72,7 @@ defineEmits(['updateValue'])
|
|
|
62
72
|
<v-expansion-panel v-for="(item,index) in valueModel" :key="index">
|
|
63
73
|
|
|
64
74
|
<v-expansion-panel-title>
|
|
65
|
-
{{ index }}
|
|
75
|
+
<v-chip class="mr-2" :color="hasError(index) ? 'red':'teal'">{{ index }}</v-chip> {{valueModel[index][Object.keys(valueModel[index] as any)[0]]}}
|
|
66
76
|
|
|
67
77
|
<template v-slot:actions="{expanded}">
|
|
68
78
|
<v-icon>{{expanded ? "mdi-menu-down" : "mdi-menu-up"}}</v-icon>
|
|
@@ -1,18 +1,38 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import {useI18n} from "vue-i18n";
|
|
3
|
+
import {debounce} from "@drax/common-front"
|
|
4
|
+
import {ref, defineModel} from "vue"
|
|
5
|
+
|
|
6
|
+
|
|
3
7
|
const {t} = useI18n()
|
|
4
8
|
const model = defineModel<any>()
|
|
9
|
+
|
|
10
|
+
let input = ref(model.value)
|
|
11
|
+
|
|
12
|
+
const debouncedSearch = debounce(updateModel, 500)
|
|
13
|
+
|
|
14
|
+
function updateModel() {
|
|
15
|
+
model.value = input.value
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function clear() {
|
|
19
|
+
input.value = ''
|
|
20
|
+
updateModel()
|
|
21
|
+
}
|
|
22
|
+
|
|
5
23
|
</script>
|
|
6
24
|
|
|
7
25
|
<template>
|
|
8
|
-
<v-text-field v-model="
|
|
26
|
+
<v-text-field v-model="input"
|
|
9
27
|
density="compact"
|
|
10
28
|
class="mr-2"
|
|
11
29
|
variant="outlined"
|
|
12
30
|
append-inner-icon="mdi-magnify"
|
|
13
31
|
:label="t('action.search')"
|
|
14
32
|
single-line hide-details
|
|
15
|
-
|
|
33
|
+
@update:modelValue="debouncedSearch"
|
|
34
|
+
clearable
|
|
35
|
+
@click:clear="clear"
|
|
16
36
|
/>
|
|
17
37
|
</template>
|
|
18
38
|
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import type {IDraxPaginateResult, IEntityCrud} from "@drax/crud-share";
|
|
2
2
|
import {useCrudStore} from "../stores/UseCrudStore";
|
|
3
3
|
import {computed, toRaw} from "vue";
|
|
4
|
+
import getItemId from "../helpers/getItemId";
|
|
4
5
|
|
|
5
6
|
export function useCrud(entity: IEntityCrud) {
|
|
6
7
|
|
|
7
8
|
const store = useCrudStore()
|
|
8
9
|
|
|
10
|
+
|
|
9
11
|
const dialog = computed({
|
|
10
12
|
get() {
|
|
11
13
|
return store.dialog
|
|
@@ -198,13 +200,16 @@ export function useCrud(entity: IEntityCrud) {
|
|
|
198
200
|
|
|
199
201
|
entity.fields.filter(field => field.type === 'ref')
|
|
200
202
|
.forEach(field => {
|
|
201
|
-
item[field.name] = item[field.name]
|
|
203
|
+
item[field.name] = getItemId(item[field.name]) ? getItemId(item[field.name]) : item[field.name]
|
|
204
|
+
|
|
202
205
|
})
|
|
203
206
|
|
|
204
207
|
entity.fields.filter(field => field.type === 'array.ref')
|
|
205
208
|
.forEach(field => {
|
|
206
209
|
if (item[field.name] && Array.isArray(item[field.name])) {
|
|
207
|
-
item[field.name] = item[field.name].map(((i: any) => i
|
|
210
|
+
item[field.name] = item[field.name].map(((i: any) => getItemId(i) ? getItemId(i) : i))
|
|
211
|
+
}else{
|
|
212
|
+
item[field.name] = []
|
|
208
213
|
}
|
|
209
214
|
})
|
|
210
215
|
|
|
@@ -290,7 +295,7 @@ export function useCrud(entity: IEntityCrud) {
|
|
|
290
295
|
async function doUpdate(formData: any) {
|
|
291
296
|
try {
|
|
292
297
|
store.setLoading(true)
|
|
293
|
-
let item = await entity?.provider.update(formData
|
|
298
|
+
let item = await entity?.provider.update(getItemId(formData), toRaw(formData))
|
|
294
299
|
await doPaginate()
|
|
295
300
|
closeDialog()
|
|
296
301
|
store.showMessage("Entity updated successfully!")
|
|
@@ -312,7 +317,7 @@ export function useCrud(entity: IEntityCrud) {
|
|
|
312
317
|
async function doDelete(formData: any) {
|
|
313
318
|
try {
|
|
314
319
|
store.setLoading(true)
|
|
315
|
-
await entity?.provider.delete(formData
|
|
320
|
+
await entity?.provider.delete(getItemId(formData))
|
|
316
321
|
await doPaginate()
|
|
317
322
|
closeDialog()
|
|
318
323
|
store.showMessage("Entity deleted successfully!")
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {useCrudStore} from "../stores/UseCrudStore";
|
|
2
|
+
import {useI18n} from "vue-i18n";
|
|
3
|
+
import {computed} from "vue";
|
|
4
|
+
|
|
5
|
+
export function useInputErrorI18n() {
|
|
6
|
+
|
|
7
|
+
const store = useCrudStore()
|
|
8
|
+
|
|
9
|
+
const {t, te} = useI18n()
|
|
10
|
+
|
|
11
|
+
const inputErrorsI18n = computed(() => {
|
|
12
|
+
return (name:string) => {
|
|
13
|
+
return store.getFieldInputErrors(name).map((error: string) => te(error) ? t(error) : error)
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
return {inputErrorsI18n}
|
|
19
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -10,6 +10,7 @@ import CrudAutocomplete from "./components/CrudAutocomplete.vue";
|
|
|
10
10
|
import {useCrudStore} from "./stores/UseCrudStore";
|
|
11
11
|
import {useCrud} from "./composables/UseCrud";
|
|
12
12
|
import {useFormUtils} from "./composables/UseFormUtils";
|
|
13
|
+
import {useInputErrorI18n} from "./composables/UseInputErrorI18n";
|
|
13
14
|
import {EntityCrud} from "./EntityCrud";
|
|
14
15
|
|
|
15
16
|
|
|
@@ -26,6 +27,7 @@ export {
|
|
|
26
27
|
useCrud,
|
|
27
28
|
useFormUtils,
|
|
28
29
|
useCrudStore,
|
|
30
|
+
useInputErrorI18n,
|
|
29
31
|
EntityCrud
|
|
30
32
|
|
|
31
33
|
}
|
|
@@ -14,7 +14,7 @@ export const useCrudStore = defineStore('CrudStore', {
|
|
|
14
14
|
filters: [] as any[],
|
|
15
15
|
items: [] as any[],
|
|
16
16
|
totalItems: 0 as number,
|
|
17
|
-
itemsPerPage:
|
|
17
|
+
itemsPerPage: 10 as number,
|
|
18
18
|
page: 1 as number,
|
|
19
19
|
search: '' as string,
|
|
20
20
|
sortBy: [] as any[],
|
|
@@ -25,15 +25,25 @@ export const useCrudStore = defineStore('CrudStore', {
|
|
|
25
25
|
exportListVisible: false,
|
|
26
26
|
}
|
|
27
27
|
),
|
|
28
|
-
getters:{
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
getters: {
|
|
29
|
+
getFieldInputErrors(state: any) {
|
|
30
|
+
return (fieldName: string) => {
|
|
31
|
+
if (state.inputErrors && state.inputErrors[fieldName]) {
|
|
32
|
+
return state.inputErrors[fieldName]
|
|
33
|
+
}
|
|
34
|
+
return []
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
hasFieldListInputErrors(state: any) {
|
|
38
|
+
return (fieldListName: string) => {
|
|
39
|
+
if(state.inputErrors && typeof state.inputErrors === 'object'){
|
|
40
|
+
for(const key in state.inputErrors) {
|
|
41
|
+
return key.startsWith(fieldListName)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
37
47
|
},
|
|
38
48
|
actions: {
|
|
39
49
|
setOperation(operation: IEntityCrudOperation) {
|
|
@@ -85,7 +95,7 @@ export const useCrudStore = defineStore('CrudStore', {
|
|
|
85
95
|
setInputErrors(inputErrors: any) {
|
|
86
96
|
this.inputErrors = inputErrors
|
|
87
97
|
},
|
|
88
|
-
resetErrors(){
|
|
98
|
+
resetErrors() {
|
|
89
99
|
this.inputErrors = null
|
|
90
100
|
this.error = ''
|
|
91
101
|
},
|