@drax/crud-vue 0.5.8 → 0.5.11

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.5.8",
6
+ "version": "0.5.11",
7
7
  "type": "module",
8
8
  "main": "./src/index.ts",
9
9
  "module": "./src/index.ts",
@@ -24,9 +24,9 @@
24
24
  "format": "prettier --write src/"
25
25
  },
26
26
  "dependencies": {
27
- "@drax/common-front": "^0.5.5",
27
+ "@drax/common-front": "^0.5.11",
28
28
  "@drax/crud-front": "^0.5.3",
29
- "@drax/crud-share": "^0.5.5"
29
+ "@drax/crud-share": "^0.5.9"
30
30
  },
31
31
  "peerDependencies": {
32
32
  "pinia": "^2.2.2",
@@ -63,5 +63,5 @@
63
63
  "vue-tsc": "^2.0.11",
64
64
  "vuetify": "^3.7.1"
65
65
  },
66
- "gitHead": "22d4554627c707a23cfd0b138b8eb0fb91f809ab"
66
+ "gitHead": "f11fe7cb964e70b4510275004e4ef9248745a7f5"
67
67
  }
package/src/EntityCrud.ts CHANGED
@@ -60,6 +60,8 @@ class EntityCrud implements IEntityCrud{
60
60
  field.objectFields.forEach(subField => {
61
61
  if(subField.type === 'object'){
62
62
  value[subField.name] = this.objectFields(subField)
63
+ }if(subField.type === 'number' && field.default!= undefined){
64
+ value[subField.name] = null
63
65
  }else{
64
66
  value[subField.name] = subField.default
65
67
  }
@@ -77,6 +79,8 @@ class EntityCrud implements IEntityCrud{
77
79
  value = this.objectFields(field)
78
80
  }else if(field.default != undefined){
79
81
  value = field.default
82
+ }else{
83
+ value = null
80
84
  }
81
85
 
82
86
  return {...acc, [field.name]: value }
@@ -7,15 +7,16 @@ import {useI18n} from "vue-i18n";
7
7
  import {useCrudStore} from "../stores/UseCrudStore";
8
8
  import {VDateInput} from 'vuetify/labs/VDateInput'
9
9
  import type {IEntityCrud, IEntityCrudField, IEntityCrudFilter} from "@drax/crud-share";
10
+
10
11
  const {t, te} = useI18n()
11
12
 
12
13
  const store = useCrudStore()
13
14
 
14
15
  const valueModel = defineModel<any>({type: [String, Number, Boolean, Object, Array], default: false})
15
16
 
16
- const {index, entity, field, disableRules} = defineProps({
17
+ const {index, entity, field, disableRules, parentField} = defineProps({
17
18
  entity: {type: Object as PropType<IEntityCrud>, required: true},
18
- field: {type: Object as PropType<IEntityCrudField|IEntityCrudFilter|undefined>, required: true},
19
+ field: {type: Object as PropType<IEntityCrudField | IEntityCrudFilter | undefined>, required: true},
19
20
  prependIcon: {type: String, default: ''},
20
21
  prependInnerIcon: {type: String, default: ''},
21
22
  appendIcon: {type: String, default: ''},
@@ -25,18 +26,21 @@ const {index, entity, field, disableRules} = defineProps({
25
26
  singleLine: {type: Boolean, default: false},
26
27
  clearable: {type: Boolean, default: false},
27
28
  disableRules: {type: Boolean, default: false},
28
- index: {type: Number, default: 0},
29
+ parentField: {type: String, default: null, required: false},
30
+ index: {type: Number, default: null, required: false},
29
31
  density: {type: String as PropType<'comfortable' | 'compact' | 'default'>, default: 'default'},
30
- variant: {type: String as PropType<'underlined' | 'outlined' | 'filled' | 'solo' | 'solo-inverted' | 'solo-filled' | 'plain'>, default: 'filled'},
32
+ variant: {
33
+ type: String as PropType<'underlined' | 'outlined' | 'filled' | 'solo' | 'solo-inverted' | 'solo-filled' | 'plain'>,
34
+ default: 'filled'
35
+ },
31
36
  })
32
37
 
33
38
 
34
-
35
- if(!field){
39
+ if (!field) {
36
40
  throw new Error("CrudFormField must be provided with a field object")
37
41
  }
38
42
 
39
- const name = computed(() => index > 0 ? `${field.name}_${index}` : field.name)
43
+ const name = computed(() => index >= 0 ? `${field.name}_${index}` : field.name)
40
44
 
41
45
  const label = computed(() => {
42
46
  const i18n = `${entity.name}.field.${field.name}`
@@ -44,12 +48,16 @@ const label = computed(() => {
44
48
  })
45
49
 
46
50
  const rules = computed(() => {
47
- if(disableRules) return undefined
51
+ if (disableRules) return undefined
48
52
  return entity.getRule(field.name) as any
49
53
  })
50
54
 
51
- const inputErrors = computed(() =>
52
- store.getInputErrors(field.name).map((error: string) => t(te(error) ? t(error) : error))
55
+ const inputErrors = computed(() => {
56
+ let sIndex = (index != null && index >= 0) ? `${index}.` : ''
57
+ let name = parentField ? `${parentField}.${sIndex}${field.name}` : field.name
58
+ console.log("inputErrors name",name, index, sIndex)
59
+ return store.getInputErrors(name).map((error: string) => t(te(error) ? t(error) : error))
60
+ }
53
61
  )
54
62
 
55
63
  defineEmits(['updateValue'])
@@ -85,7 +93,7 @@ defineEmits(['updateValue'])
85
93
  type="number"
86
94
  :name="name"
87
95
  :label="label"
88
- v-model="valueModel"
96
+ v-model.number="valueModel"
89
97
  :readonly="readonly"
90
98
  :error-messages="inputErrors"
91
99
  :rules="rules"
@@ -148,6 +156,7 @@ defineEmits(['updateValue'])
148
156
  v-if="field.type === 'ref'"
149
157
  :entity="entity.getRef(field.ref)"
150
158
  :field="field"
159
+ :item-title="field?.refDisplay"
151
160
  v-model="valueModel"
152
161
  :label="label"
153
162
  :error-messages="inputErrors"
@@ -173,6 +182,7 @@ defineEmits(['updateValue'])
173
182
  v-for="oField in field.objectFields"
174
183
  :entity="entity"
175
184
  :field="oField"
185
+ :parent-field="field.name"
176
186
  v-model="valueModel[oField.name]"
177
187
  :density="density"
178
188
  :variant="variant"
@@ -219,6 +229,7 @@ defineEmits(['updateValue'])
219
229
  v-if="field.type === 'array.ref'"
220
230
  :entity="entity.getRef(field.ref)"
221
231
  :field="field"
232
+ :item-title="field?.refDisplay"
222
233
  v-model="valueModel"
223
234
  :multiple="true"
224
235
  :chips="true"
@@ -46,7 +46,7 @@ defineEmits(['updateValue'])
46
46
  <v-card-title class="text-h5">{{field.label}}</v-card-title>
47
47
  <v-card-text>
48
48
  <v-row>
49
- <v-col cols="12" v-for="(item,index) in valueModel" :key="index" class="text-right">
49
+ <v-col cols="12" v-for="(item,index) in valueModel" :key="index" >
50
50
  <v-row dense align="center">
51
51
  <v-col cols="11">
52
52
  <template v-for="key in Object.keys(item as Record<string, any>)" :key="key">
@@ -56,6 +56,7 @@ defineEmits(['updateValue'])
56
56
  :field="getField(key)"
57
57
  v-model="(valueModel[index] as any)[key]"
58
58
  :readonly="readonly"
59
+ :parentField="field.name"
59
60
  :index="index"
60
61
  :density="density"
61
62
  :variant="variant"
@@ -4,224 +4,331 @@ import {computed} from "vue";
4
4
 
5
5
  export function useCrud(entity: IEntityCrud) {
6
6
 
7
- const store = useCrudStore()
8
-
9
- const dialog = computed({get(){return store.dialog} , set(value){store.setDialog(value)}})
10
- const operation = computed({get(){return store.operation} , set(value){store.setOperation(value)}})
11
- const form = computed({get(){return store.form} , set(value){store.setForm(value)}})
12
- const formValid = computed({get(){return store.formValid} , set(value){store.setFormValid(value)}})
13
- const notify = computed({get(){return store.notify} , set(value){store.setNotify(value)}})
14
- const error = computed({get(){return store.error} , set(value){store.setError(value)}})
15
- const message = computed({get(){return store.message} , set(value){store.setMessage(value)}})
16
- const loading = computed({get(){return store.loading} , set(value){store.setLoading(value)}})
17
- const itemsPerPage = computed({get(){return store.itemsPerPage} , set(value){store.setItemsPerPage(value)}})
18
- const page = computed({get(){return store.page} , set(value){store.setPage(value)}})
19
- const sortBy = computed({get(){return store.sortBy} , set(value){store.setSortBy(value)}})
20
- const search = computed({get(){return store.search} , set(value){store.setSearch(value)}})
21
- const totalItems = computed({get(){return store.totalItems} , set(value){store.setTotalItems(value)}})
22
- const items = computed({get(){return store.items} , set(value){store.setItems(value)}})
23
- const exportFiles = computed({get(){return store.exportFiles} , set(value){store.setExportFiles(value)}})
24
- const exportLoading = computed({get(){return store.exportLoading} , set(value){store.setExportLoading(value)}})
25
- const exportListVisible = computed({get(){return store.exportListVisible} , set(value){store.setExportListVisible(value)}})
26
- const filters = computed({get(){return store.filters} , set(value){store.setFilters(value)}})
27
-
28
-
29
- async function doPaginate() {
30
- store.setLoading(true)
31
- try {
32
-
33
- const r: IDraxPaginateResult<any> = await entity?.provider.paginate({
34
- page: store.page,
35
- limit: store.itemsPerPage,
36
- orderBy: store.sortBy[0]?.key,
37
- order: store.sortBy[0]?.order,
38
- search: store.search,
39
- filters: store.filters
40
- })
41
- store.setItems(r.items)
42
- store.setTotalItems(r.total)
43
- } catch (e) {
44
- console.error("Error paginating", e)
45
- } finally {
46
- store.setLoading(false)
47
- }
48
- }
49
-
50
- async function doExport(format: 'JSON') {
51
- store.setExportLoading(true)
52
- store.setExportListVisible(true)
53
- try {
54
-
55
- if(!entity?.provider.export) {
56
- throw new Error("provider.export not implemented")
57
- }
58
-
59
- const headers: string = entity.exportHeaders.join(',')
60
-
61
- const r: any = await entity?.provider.export({
62
- format: format,
63
- headers: headers,
64
- separator: ";",
65
- orderBy: store.sortBy[0]?.key,
66
- order: store.sortBy[0]?.order,
67
- search: store.search
68
- })
69
-
70
- if(r && r.url) {
71
- store.addExportFile(r)
72
- store.showMessage("Export successful")
73
- }
74
-
75
- return r
76
-
77
- } catch (e) {
78
- console.error("Error exporting csv", e)
79
- } finally {
80
- store.setExportLoading(false)
81
- }
82
- }
83
-
84
-
85
-
86
- function cast(item: any){
87
- entity.fields.filter(field => field.type === 'date')
88
- .forEach(field => {
89
- item[field.name] = new Date(item[field.name])
90
- })
91
-
92
- entity.fields.filter(field => field.type === 'ref')
93
- .forEach(field => {
94
- item[field.name] = item[field.name]?._id ? item[field.name]._id : item[field.name]
95
- })
96
-
97
- entity.fields.filter(field => field.type === 'array.ref')
98
- .forEach(field => {
99
- if(item[field.name] && Array.isArray(item[field.name])){
100
- item[field.name] = item[field.name].map(((i:any) => i?._id ? i._id : i))
101
- }
102
- })
103
-
104
- return item
105
- }
106
-
107
- function onView(item: object) {
108
- store.setOperation("view")
109
- store.setForm(cast({...item}))
110
- openDialog()
111
- }
112
-
113
-
114
- function onCreate() {
115
- store.setOperation("create")
116
- store.setForm(entity.form)
117
- openDialog()
118
- }
119
-
120
- function onEdit(item: object) {
121
- store.setOperation("edit")
122
- store.setForm(cast({...item}))
123
- openDialog()
124
- }
125
-
126
- function onDelete(item: object) {
127
- store.setOperation("delete")
128
- store.setForm(cast({...item}))
129
- openDialog()
130
- }
131
-
132
- function onCancel() {
133
- closeDialog()
134
- store.setError("")
135
- store.setInputErrors(null)
136
- }
137
-
138
- function onSubmit(formData: any) {
139
- store.setInputErrors(null)
140
- switch (store.operation) {
141
- case "view":
7
+ const store = useCrudStore()
8
+
9
+ const dialog = computed({
10
+ get() {
11
+ return store.dialog
12
+ }, set(value) {
13
+ store.setDialog(value)
14
+ }
15
+ })
16
+ const operation = computed({
17
+ get() {
18
+ return store.operation
19
+ }, set(value) {
20
+ store.setOperation(value)
21
+ }
22
+ })
23
+ const form = computed({
24
+ get() {
25
+ return store.form
26
+ }, set(value) {
27
+ store.setForm(value)
28
+ }
29
+ })
30
+ const formValid = computed({
31
+ get() {
32
+ return store.formValid
33
+ }, set(value) {
34
+ store.setFormValid(value)
35
+ }
36
+ })
37
+ const notify = computed({
38
+ get() {
39
+ return store.notify
40
+ }, set(value) {
41
+ store.setNotify(value)
42
+ }
43
+ })
44
+ const error = computed({
45
+ get() {
46
+ return store.error
47
+ }, set(value) {
48
+ store.setError(value)
49
+ }
50
+ })
51
+ const message = computed({
52
+ get() {
53
+ return store.message
54
+ }, set(value) {
55
+ store.setMessage(value)
56
+ }
57
+ })
58
+ const loading = computed({
59
+ get() {
60
+ return store.loading
61
+ }, set(value) {
62
+ store.setLoading(value)
63
+ }
64
+ })
65
+ const itemsPerPage = computed({
66
+ get() {
67
+ return store.itemsPerPage
68
+ }, set(value) {
69
+ store.setItemsPerPage(value)
70
+ }
71
+ })
72
+ const page = computed({
73
+ get() {
74
+ return store.page
75
+ }, set(value) {
76
+ store.setPage(value)
77
+ }
78
+ })
79
+ const sortBy = computed({
80
+ get() {
81
+ return store.sortBy
82
+ }, set(value) {
83
+ store.setSortBy(value)
84
+ }
85
+ })
86
+ const search = computed({
87
+ get() {
88
+ return store.search
89
+ }, set(value) {
90
+ store.setSearch(value)
91
+ }
92
+ })
93
+ const totalItems = computed({
94
+ get() {
95
+ return store.totalItems
96
+ }, set(value) {
97
+ store.setTotalItems(value)
98
+ }
99
+ })
100
+ const items = computed({
101
+ get() {
102
+ return store.items
103
+ }, set(value) {
104
+ store.setItems(value)
105
+ }
106
+ })
107
+ const exportFiles = computed({
108
+ get() {
109
+ return store.exportFiles
110
+ }, set(value) {
111
+ store.setExportFiles(value)
112
+ }
113
+ })
114
+ const exportLoading = computed({
115
+ get() {
116
+ return store.exportLoading
117
+ }, set(value) {
118
+ store.setExportLoading(value)
119
+ }
120
+ })
121
+ const exportListVisible = computed({
122
+ get() {
123
+ return store.exportListVisible
124
+ }, set(value) {
125
+ store.setExportListVisible(value)
126
+ }
127
+ })
128
+ const filters = computed({
129
+ get() {
130
+ return store.filters
131
+ }, set(value) {
132
+ store.setFilters(value)
133
+ }
134
+ })
135
+
136
+
137
+ async function doPaginate() {
138
+ store.setLoading(true)
139
+ try {
140
+
141
+ const r: IDraxPaginateResult<any> = await entity?.provider.paginate({
142
+ page: store.page,
143
+ limit: store.itemsPerPage,
144
+ orderBy: store.sortBy[0]?.key,
145
+ order: store.sortBy[0]?.order,
146
+ search: store.search,
147
+ filters: store.filters
148
+ })
149
+ store.setItems(r.items)
150
+ store.setTotalItems(r.total)
151
+ } catch (e) {
152
+ console.error("Error paginating", e)
153
+ } finally {
154
+ store.setLoading(false)
155
+ }
156
+ }
157
+
158
+ async function doExport(format: 'JSON') {
159
+ store.setExportLoading(true)
160
+ store.setExportListVisible(true)
161
+ try {
162
+
163
+ if (!entity?.provider.export) {
164
+ throw new Error("provider.export not implemented")
165
+ }
166
+
167
+ const headers: string = entity.exportHeaders.join(',')
168
+
169
+ const r: any = await entity?.provider.export({
170
+ format: format,
171
+ headers: headers,
172
+ separator: ";",
173
+ orderBy: store.sortBy[0]?.key,
174
+ order: store.sortBy[0]?.order,
175
+ search: store.search
176
+ })
177
+
178
+ if (r && r.url) {
179
+ store.addExportFile(r)
180
+ store.showMessage("Export successful")
181
+ }
182
+
183
+ return r
184
+
185
+ } catch (e) {
186
+ console.error("Error exporting csv", e)
187
+ } finally {
188
+ store.setExportLoading(false)
189
+ }
190
+ }
191
+
192
+
193
+ function cast(item: any) {
194
+ entity.fields.filter(field => field.type === 'date')
195
+ .forEach(field => {
196
+ item[field.name] = new Date(item[field.name])
197
+ })
198
+
199
+ entity.fields.filter(field => field.type === 'ref')
200
+ .forEach(field => {
201
+ item[field.name] = item[field.name]?._id ? item[field.name]._id : item[field.name]
202
+ })
203
+
204
+ entity.fields.filter(field => field.type === 'array.ref')
205
+ .forEach(field => {
206
+ if (item[field.name] && Array.isArray(item[field.name])) {
207
+ item[field.name] = item[field.name].map(((i: any) => i?._id ? i._id : i))
208
+ }
209
+ })
210
+
211
+ return item
212
+ }
213
+
214
+ function onView(item: object) {
215
+ store.setOperation("view")
216
+ store.setForm(cast({...item}))
217
+ openDialog()
218
+ }
219
+
220
+
221
+ function onCreate() {
222
+ store.setOperation("create")
223
+ store.setForm(entity.form)
224
+ openDialog()
225
+ }
226
+
227
+ function onEdit(item: object) {
228
+ store.setOperation("edit")
229
+ store.setForm(cast({...item}))
230
+ openDialog()
231
+ }
232
+
233
+ function onDelete(item: object) {
234
+ store.setOperation("delete")
235
+ store.setForm(cast({...item}))
236
+ openDialog()
237
+ }
238
+
239
+ function onCancel() {
142
240
  closeDialog()
143
- break
144
- case "create":
145
- doCreate(formData)
146
- break
147
- case "edit":
148
- doUpdate(formData)
149
- break
150
- case "delete":
151
- doDelete(formData)
152
- break
153
- }
154
- }
155
-
156
- function openDialog() {
157
- store.setDialog(true)
158
- }
159
-
160
- function closeDialog() {
161
- store.setDialog(false)
162
- }
163
-
164
- async function doCreate(formData: any) {
165
- try {
166
- await entity?.provider.create(formData)
167
- await doPaginate()
168
- closeDialog()
169
- store.showMessage("Entity created successfully!")
170
- } catch (e: any) {
171
- if(e.inputErrors){
172
- store.setInputErrors(e.inputErrors)
173
- }
174
- store.setError(e.message || "An error occurred while creating the entity")
175
- console.error("Error creating entity", e)
176
- }
177
-
178
- }
179
-
180
- async function doUpdate(formData: any) {
181
- try {
182
- await entity?.provider.update(formData._id, formData)
183
- await doPaginate()
184
- closeDialog()
185
- store.showMessage("Entity updated successfully!")
186
- } catch (e: any) {
187
- console.log("inputErrors", e.inputErrors)
188
- if(e.inputErrors){
189
- store.setInputErrors(e.inputErrors)
190
- }
191
- store.setError(e.message || "An error occurred while updating the entity")
192
- console.error("Error updating entity", e)
193
- }
194
-
195
- }
196
-
197
- async function doDelete(formData: any) {
198
- try {
199
- await entity?.provider.delete(formData._id)
200
- await doPaginate()
201
- closeDialog()
202
- store.showMessage("Entity deleted successfully!")
203
- } catch (e: any) {
204
- store.setError(e.message || "An error occurred while deleting the entity")
205
- console.error("Error updating entity", e)
206
- }
207
-
208
- }
209
-
210
- function resetCrudStore(){
211
- store.$reset()
212
- }
213
-
214
- function prepareFilters(){
215
- store.setFilters(entity.formFilters)
216
- }
217
-
218
-
219
- return {
220
- doPaginate, doExport, onView, onCreate, onEdit, onDelete, onCancel, onSubmit,resetCrudStore,
221
- operation, dialog, form, notify, error, message, formValid,
222
- loading, itemsPerPage, page, sortBy, search, totalItems, items,
223
- prepareFilters,filters,
224
- exportFiles,exportLoading,exportListVisible
225
- }
241
+ store.setError("")
242
+ store.setInputErrors(null)
243
+ }
244
+
245
+ function onSubmit(formData: any) {
246
+ store.setInputErrors(null)
247
+ switch (store.operation) {
248
+ case "view":
249
+ closeDialog()
250
+ break
251
+ case "create":
252
+ doCreate(formData)
253
+ break
254
+ case "edit":
255
+ doUpdate(formData)
256
+ break
257
+ case "delete":
258
+ doDelete(formData)
259
+ break
260
+ }
261
+ }
262
+
263
+ function openDialog() {
264
+ store.setDialog(true)
265
+ }
266
+
267
+ function closeDialog() {
268
+ store.setDialog(false)
269
+ }
270
+
271
+ async function doCreate(formData: any) {
272
+ try {
273
+ await entity?.provider.create(formData)
274
+ await doPaginate()
275
+ closeDialog()
276
+ store.showMessage("Entity created successfully!")
277
+ } catch (e: any) {
278
+ if (e.inputErrors) {
279
+ store.setInputErrors(e.inputErrors)
280
+ }
281
+ store.setError(e.message || "An error occurred while creating the entity")
282
+ console.error("Error creating entity", e)
283
+ }
284
+
285
+ }
286
+
287
+ async function doUpdate(formData: any) {
288
+ try {
289
+ await entity?.provider.update(formData._id, formData)
290
+ await doPaginate()
291
+ closeDialog()
292
+ store.showMessage("Entity updated successfully!")
293
+ } catch (e: any) {
294
+ console.log("inputErrors", e.inputErrors)
295
+ if (e.inputErrors) {
296
+ store.setInputErrors(e.inputErrors)
297
+ }
298
+ store.setError(e.message || "An error occurred while updating the entity")
299
+ console.error("Error updating entity", e)
300
+ }
301
+
302
+ }
303
+
304
+ async function doDelete(formData: any) {
305
+ try {
306
+ await entity?.provider.delete(formData._id)
307
+ await doPaginate()
308
+ closeDialog()
309
+ store.showMessage("Entity deleted successfully!")
310
+ } catch (e: any) {
311
+ store.setError(e.message || "An error occurred while deleting the entity")
312
+ console.error("Error updating entity", e)
313
+ }
314
+
315
+ }
316
+
317
+ function resetCrudStore() {
318
+ store.$reset()
319
+ }
320
+
321
+ function prepareFilters() {
322
+ store.setFilters(entity.formFilters)
323
+ }
324
+
325
+
326
+ return {
327
+ doPaginate, doExport, onView, onCreate, onEdit, onDelete, onCancel, onSubmit, resetCrudStore,
328
+ operation, dialog, form, notify, error, message, formValid,
329
+ loading, itemsPerPage, page, sortBy, search, totalItems, items,
330
+ prepareFilters, filters,
331
+ exportFiles, exportLoading, exportListVisible
332
+ }
226
333
 
227
334
  }