@drax/crud-vue 0.11.4 → 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 CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.11.4",
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.11.3",
28
- "@drax/crud-front": "^0.11.3",
29
- "@drax/crud-share": "^0.11.4",
30
- "@drax/media-vue": "^0.11.3"
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": "543e9fc9947da228d0f2dc37d2bae3a39ec32250"
67
+ "gitHead": "76fd366e12449f5f605662197f985a28d98058a2"
68
68
  }
package/src/EntityCrud.ts CHANGED
@@ -1,184 +1,191 @@
1
1
  import type {
2
- IEntityCrud, IEntityCrudForm, IEntityCrudHeader, IEntityCrudRefs,
3
- IEntityCrudRules, IEntityCrudField, IEntityCrudPermissions,
4
- IDraxCrudProvider, IEntityCrudFilter, IEntityCrudFormFilter
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
- class EntityCrud implements IEntityCrud{
10
+ name: string = ''
10
11
 
11
- name: string = ''
12
-
13
- constructor() {
14
- }
12
+ constructor() {
13
+ }
15
14
 
16
- static get instance():IEntityCrud{
17
- throw new Error('EntityCrud instance not found')
18
- }
15
+ static get instance(): IEntityCrud {
16
+ throw new Error('EntityCrud instance not found')
17
+ }
19
18
 
20
19
 
21
- get headers():IEntityCrudHeader[]{
22
- return [
23
- {title: 'ID',key:'_id'},
24
- ]
25
- }
20
+ get headers(): IEntityCrudHeader[] {
21
+ return [
22
+ {title: 'ID', key: '_id'},
23
+ ]
24
+ }
26
25
 
27
- get actionHeaders():IEntityCrudHeader[]{
28
- return [
29
- {
30
- title: 'action.actions',
31
- key: 'actions',
32
- sortable: false,
33
- align: 'center',
34
- minWidth: '190px'
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
- get permissions(): IEntityCrudPermissions {
41
- return {
42
- manage: 'manage', view: 'view', create: 'create', update: 'update', delete: 'delete'
39
+ get permissions(): IEntityCrudPermissions {
40
+ return {
41
+ manage: 'manage', view: 'view', create: 'create', update: 'update', delete: 'delete'
42
+ }
43
43
  }
44
- }
45
44
 
46
- get provider(): IDraxCrudProvider<any, any, any>{
47
- throw new Error('provider not implemented')
48
- }
45
+ get provider(): IDraxCrudProvider<any, any, any> {
46
+ throw new Error('provider not implemented')
47
+ }
49
48
 
50
- get fields():IEntityCrudField[]{
51
- return [
52
- {name: '_id', type: 'string', label: 'ID', default: '' },
53
- ]
54
- }
49
+ get fields(): IEntityCrudField[] {
50
+ return [
51
+ {name: '_id', type: 'string', label: 'ID', default: ''},
52
+ ]
53
+ }
55
54
 
56
- get createFields(){
57
- return this.fields
58
- }
55
+ get createFields() {
56
+ return this.fields
57
+ }
59
58
 
60
- get updateFields(){
61
- return this.fields
62
- }
59
+ get updateFields() {
60
+ return this.fields
61
+ }
63
62
 
64
- get deleteFields(){
65
- return this.fields
66
- }
63
+ get deleteFields() {
64
+ return this.fields
65
+ }
67
66
 
68
- get viewFields(){
69
- return this.fields
70
- }
67
+ get viewFields() {
68
+ return this.fields
69
+ }
71
70
 
72
- get filters():IEntityCrudFilter[]{
73
- return [
74
- {name: '_id', type: 'string', label: 'ID', default: '', operator: 'eq' },
75
- ]
76
- }
71
+ get filters(): IEntityCrudFilter[] {
72
+ return [
73
+ {name: '_id', type: 'string', label: 'ID', default: '', operator: 'eq'},
74
+ ]
75
+ }
77
76
 
78
- objectFields(field:IEntityCrudField){
79
- let value:any = {}
80
- if(field.objectFields){
81
- field.objectFields.forEach(subField => {
82
- if(subField.type === 'object'){
83
- value[subField.name] = this.objectFields(subField)
84
- }if(subField.type === 'number' && field.default!= undefined){
85
- value[subField.name] = null
86
- }else{
87
- value[subField.name] = subField.default
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
- return this.fields.reduce((acc, field) => {
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
- return {...acc, [field.name]: value }
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
- get refs():IEntityCrudRefs{
121
- return {}
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
- getRef(ref: string):IEntityCrud{
125
- if(!this.refs.hasOwnProperty(ref)) {
126
- throw new Error("Ref not found: " + ref)
124
+ get refs(): IEntityCrudRefs {
125
+ return {}
127
126
  }
128
127
 
129
- return this.refs[ref]
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
- get rules(): IEntityCrudRules{
133
- return {}
134
- }
136
+ get rules(): IEntityCrudRules {
137
+ return {}
138
+ }
135
139
 
136
- getRule(field:string|undefined):Array<Function>|undefined {
137
- return field && this.rules[field] && this.rules[field].length > 0 ? this.rules[field] : undefined
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
- get isViewable(){
141
- return true
142
- }
144
+ get isViewable() {
145
+ return true
146
+ }
143
147
 
144
- get isEditable(){
145
- return true
146
- }
148
+ get isEditable() {
149
+ return true
150
+ }
147
151
 
148
- get isCreatable(){
149
- return true
150
- }
152
+ get isCreatable() {
153
+ return true
154
+ }
151
155
 
152
- get isDeletable(){
153
- return true
154
- }
156
+ get isDeletable() {
157
+ return true
158
+ }
155
159
 
156
- get isExportable(){
157
- return true
158
- }
160
+ get isExportable() {
161
+ return true
162
+ }
159
163
 
160
- get exportFormats(){
161
- return ['CSV', 'JSON']
162
- }
164
+ get exportFormats() {
165
+ return ['CSV', 'JSON']
166
+ }
163
167
 
164
- get exportHeaders(){
165
- return ['_id']
166
- }
168
+ get exportHeaders() {
169
+ return ['_id']
170
+ }
167
171
 
168
- get isImportable(){
169
- return true
170
- }
172
+ get isImportable() {
173
+ return true
174
+ }
171
175
 
172
- get importFormats(){
173
- return ['CSV', 'JSON']
174
- }
176
+ get importFormats() {
177
+ return ['CSV', 'JSON']
178
+ }
175
179
 
176
- get dialogFullscreen(){
177
- return false
178
- }
180
+ get dialogFullscreen() {
181
+ return false
182
+ }
179
183
 
184
+ get dialogMaxWidth() {
185
+ return ''
186
+ }
180
187
 
181
188
  }
182
189
 
183
190
  export default EntityCrud;
184
- export { EntityCrud }
191
+ export {EntityCrud}
@@ -22,6 +22,28 @@ onBeforeMount(() => {
22
22
  prepareFilters()
23
23
  })
24
24
 
25
+ const emit = defineEmits(['created', 'updated', 'deleted', 'viewed'])
26
+
27
+ async function submit() {
28
+ let result = await onSubmit(form.value)
29
+ switch (result.status) {
30
+ case "created":
31
+ emit("created", result.item)
32
+ break
33
+ case "updated":
34
+ emit("updated", result.item)
35
+ break
36
+ case "deleted":
37
+ emit("deleted")
38
+ break
39
+ case "viewed":
40
+ emit("deleted")
41
+ break
42
+ }
43
+
44
+
45
+ }
46
+
25
47
  </script>
26
48
 
27
49
  <template>
@@ -73,7 +95,7 @@ onBeforeMount(() => {
73
95
  :error="error"
74
96
  :operation="operation"
75
97
  :readonly="operation === 'delete'"
76
- @submit="onSubmit"
98
+ @submit="submit"
77
99
  @cancel="onCancel"
78
100
  >
79
101
 
@@ -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._id === id)) {
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>
@@ -30,7 +30,7 @@ const title = computed(() => {
30
30
  </script>
31
31
 
32
32
  <template>
33
- <v-dialog v-model="dialog" :fullscreen="entity.dialogFullscreen">
33
+ <v-dialog v-model="dialog" :fullscreen="entity.dialogFullscreen" :max-width="entity.dialogMaxWidth">
34
34
  <v-card>
35
35
  <v-toolbar>
36
36
  <v-toolbar-title>{{title}}</v-toolbar-title>
@@ -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._id">ID: {{ valueModel._id }}</v-card-subtitle>
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>
@@ -115,7 +119,7 @@ const {
115
119
  <v-card-actions>
116
120
  <v-spacer></v-spacer>
117
121
  <v-btn variant="text" color="grey" @click="cancel">{{ t('action.cancel') }}</v-btn>
118
- <v-btn variant="flat" v-if="operation != 'view'" :color="submitColor" @click="submit">
122
+ <v-btn variant="flat" v-if="operation != 'view'" :color="submitColor" @click="submit" :loading="store.loading">
119
123
  {{ operation ? t('action.' + operation) : t('action.sent') }}
120
124
  </v-btn>
121
125
  </v-card-actions>
@@ -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
- //console.log("inputErrors name",name, index, sIndex)
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 }} - {{valueModel[index][Object.keys(valueModel[index] as any)[0]]}}
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="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
- clearable @click:clear="() => model = ''"
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
- import {computed} from "vue";
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]?._id ? item[field.name]._id : 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?._id ? i._id : 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
 
@@ -242,22 +247,20 @@ export function useCrud(entity: IEntityCrud) {
242
247
  store.setInputErrors(null)
243
248
  }
244
249
 
245
- function onSubmit(formData: any) {
250
+ async function onSubmit(formData: any): Promise<{status:string,item?:any}> {
246
251
  store.setInputErrors(null)
247
252
  switch (store.operation) {
248
253
  case "view":
249
254
  closeDialog()
250
- break
255
+ return {status: 'viewed'}
251
256
  case "create":
252
- doCreate(formData)
253
- break
257
+ return doCreate(formData)
254
258
  case "edit":
255
- doUpdate(formData)
256
- break
259
+ return doUpdate(formData)
257
260
  case "delete":
258
- doDelete(formData)
259
- break
261
+ return doDelete(formData)
260
262
  }
263
+ return {status: 'unknown'}
261
264
  }
262
265
 
263
266
  function openDialog() {
@@ -270,26 +273,33 @@ export function useCrud(entity: IEntityCrud) {
270
273
 
271
274
  async function doCreate(formData: any) {
272
275
  try {
273
- await entity?.provider.create(formData)
276
+ store.setLoading(true)
277
+ let item = await entity?.provider.create(toRaw(formData))
274
278
  await doPaginate()
275
279
  closeDialog()
276
280
  store.showMessage("Entity created successfully!")
281
+ return {status: 'created', item: item}
277
282
  } catch (e: any) {
278
283
  if (e.inputErrors) {
279
284
  store.setInputErrors(e.inputErrors)
280
285
  }
281
286
  store.setError(e.message || "An error occurred while creating the entity")
282
287
  console.error("Error creating entity", e)
288
+ return {status: 'error'}
289
+ } finally {
290
+ store.setLoading(false)
283
291
  }
284
292
 
285
293
  }
286
294
 
287
295
  async function doUpdate(formData: any) {
288
296
  try {
289
- await entity?.provider.update(formData._id, formData)
297
+ store.setLoading(true)
298
+ let item = await entity?.provider.update(getItemId(formData), toRaw(formData))
290
299
  await doPaginate()
291
300
  closeDialog()
292
301
  store.showMessage("Entity updated successfully!")
302
+ return {status: 'updated', item: item}
293
303
  } catch (e: any) {
294
304
  //console.log("inputErrors", e.inputErrors)
295
305
  if (e.inputErrors) {
@@ -297,19 +307,27 @@ export function useCrud(entity: IEntityCrud) {
297
307
  }
298
308
  store.setError(e.message || "An error occurred while updating the entity")
299
309
  console.error("Error updating entity", e)
310
+ return {status: 'error'}
311
+ } finally {
312
+ store.setLoading(false)
300
313
  }
301
314
 
302
315
  }
303
316
 
304
317
  async function doDelete(formData: any) {
305
318
  try {
306
- await entity?.provider.delete(formData._id)
319
+ store.setLoading(true)
320
+ await entity?.provider.delete(getItemId(formData))
307
321
  await doPaginate()
308
322
  closeDialog()
309
323
  store.showMessage("Entity deleted successfully!")
324
+ return {status: 'deleted'}
310
325
  } catch (e: any) {
311
326
  store.setError(e.message || "An error occurred while deleting the entity")
312
327
  console.error("Error updating entity", e)
328
+ return {status: 'error'}
329
+ } finally {
330
+ store.setLoading(false)
313
331
  }
314
332
 
315
333
  }
@@ -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
+ }
@@ -0,0 +1,11 @@
1
+ const getItemId = (item: any) => {
2
+ if(item && item._id) {
3
+ return item._id
4
+ }else if(item && item.id) {
5
+ return item.id
6
+ }
7
+ return null
8
+ }
9
+
10
+ export default getItemId
11
+ export {getItemId}
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: 5 as number,
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
- getInputErrors(state: any) {
30
- return (fieldName:string) => {
31
- if (state.inputErrors && state.inputErrors[fieldName]) {
32
- return state.inputErrors[fieldName]
33
- }
34
- return []
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
  },