innoboxrr-vue-datatable 1.2.21 → 1.2.23

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "innoboxrr-vue-datatable",
3
- "version": "1.2.21",
3
+ "version": "1.2.23",
4
4
  "description": "Datatable para vue3",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/src/DataTable.vue CHANGED
@@ -1,33 +1,17 @@
1
- <template>
2
-
1
+ <template>
3
2
  <div>
4
-
5
3
  <div v-if="showTopbar">
6
-
7
- <!-- Tools -->
8
4
  <div class="uk-container uk-container-expand pt-4">
9
-
10
5
  <div uk-grid>
11
-
12
- <!-- Actions -->
13
6
  <div class="uk-width-expand" v-if="hasActions">
14
-
15
- <!-- Action Button-->
16
7
  <button
17
8
  class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 mr-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800"
18
9
  @click="actionButtonClicked(crudActions)">
19
-
20
10
  Acciones
21
-
22
11
  </button>
23
-
24
- <!-- Dropdown Actions-->
25
12
  <nav-dropdown-component id="actionCrudDropdown" pos="right">
26
-
27
13
  <li v-for="action in crudActions" :key="action.id">
28
-
29
14
  <template v-if="action.route">
30
-
31
15
  <icon-route-component
32
16
  v-if="action.policy"
33
17
  :name="action.params.to.name"
@@ -35,103 +19,68 @@
35
19
  :query="action.params.to.query ? {...action.params.to.query} : null"
36
20
  :icon="action.icon"
37
21
  :text="action.name" />
38
-
39
22
  <disabled-link-component
40
23
  v-else
41
24
  :icon="action.icon"
42
25
  :text="action.name"/>
43
-
44
26
  </template>
45
-
46
27
  <template v-else>
47
-
48
28
  <icon-link-component
49
29
  v-if="action.policy"
50
30
  :icon="action.icon"
51
31
  :text="action.name"
52
32
  @click="actionClicked(action) , closeDropdown($event)" />
53
-
54
33
  <disabled-link-component
55
34
  v-else
56
35
  :icon="action.icon"
57
36
  :text="action.name"/>
58
-
59
37
  </template>
60
-
61
38
  </li>
62
-
63
39
  </nav-dropdown-component>
64
-
65
40
  </div>
66
-
67
41
  <div v-if="hasFilter" class="uk-width-auto">
68
-
69
42
  <div class="uk-grid-divider uk-child-width-expand uk-text-center" uk-grid>
70
-
71
43
  <div>
72
-
73
44
  <span
74
45
  class="uk-text-right pointer"
75
46
  :uk-tooltip="`title: ${'Update results'}`"
76
47
  @click="updateFilters">
77
-
78
48
  <svg class="w-6 h-6 text-slate-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 18 20">
79
- <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 1v5h-5M2 19v-5h5m10-4a8 8 0 0 1-14.947 3.97M1 10a8 8 0 0 1 14.947-3.97"/>
49
+ <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 1v5h-5M2 19v-5h5m10-4a8 8 0 0 1-14.947 3.97M1 10a8 8 0 0 1 14.947-3.97"/>
80
50
  </svg>
81
-
82
51
  </span>
83
-
84
52
  </div>
85
-
86
- <!-- Filter -->
87
53
  <div>
88
-
89
54
  <span
90
55
  class="uk-text-right pointer"
91
56
  uk-toggle="target: .filter-form; animation: uk-animation-scale-up;"
92
57
  uk-tooltip="title: Buscar">
93
-
94
58
  <svg class="w-6 h-6 text-slate-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 18">
95
- <path d="M18.85 1.1A1.99 1.99 0 0 0 17.063 0H2.937a2 2 0 0 0-1.566 3.242L6.99 9.868 7 14a1 1 0 0 0 .4.8l4 3A1 1 0 0 0 13 17l.01-7.134 5.66-6.676a1.99 1.99 0 0 0 .18-2.09Z"/>
59
+ <path d="M18.85 1.1A1.99 1.99 0 0 0 17.063 0H2.937a2 2 0 0 0-1.566 3.242L6.99 9.868 7 14a1 1 0 0 0 .4.8l4 3A1 1 0 0 0 13 17l.01-7.134 5.66-6.676a1.99 1.99 0 0 0 .18-2.09Z"/>
96
60
  </svg>
97
-
98
61
  </span>
99
-
100
62
  </div>
101
-
102
63
  </div>
103
-
104
64
  </div>
105
-
106
65
  </div>
107
-
108
66
  </div>
109
-
110
- <!-- Filter Form-->
111
67
  <div
112
68
  v-if="hasFilter"
113
69
  class="filter-form uk-card uk-card-body uk-padding-remove-top"
114
70
  hidden>
115
-
116
71
  <slot name="filterForm"></slot>
117
-
118
72
  </div>
119
-
120
73
  </div>
121
-
122
- <!-- Table -->
123
74
  <div
124
75
  class="uk-container uk-container-expand"
125
76
  :class="{
126
77
  'ptb-20': showTopbar
127
78
  }">
128
-
129
79
  <div
130
80
  class="uk-padding-small"
131
81
  :class="{
132
82
  'bg-white p-6 rounded-lg shadow dark:border-slate-700 dark:bg-slate-800': cardWrapper
133
83
  }">
134
-
135
84
  <data-table-component
136
85
  :actions="hasActions"
137
86
  :data-table="dataTable"
@@ -140,18 +89,13 @@
140
89
  @sortColumn="sortColumn"
141
90
  @actionButtonClicked="actionButtonClicked"
142
91
  @actionClicked="actionClicked" />
143
-
144
92
  <select-pagination-component
145
93
  :meta="pagination.meta"
146
94
  :links="pagination.links"
147
95
  @updatePage="updatePage" />
148
-
149
96
  </div>
150
-
151
97
  </div>
152
-
153
98
  </div>
154
-
155
99
  </template>
156
100
 
157
101
  <script>
@@ -166,269 +110,163 @@
166
110
  export default {
167
111
 
168
112
  components: {
169
-
170
113
  NavDropdownComponent,
171
-
172
114
  IconRouteComponent,
173
-
174
115
  IconLinkComponent,
175
-
176
116
  DisabledLinkComponent,
177
-
178
117
  DataTableComponent,
179
-
180
118
  SelectPaginationComponent
181
-
182
119
  },
183
-
184
120
  props: {
185
-
186
121
  dataUrl: {
187
122
  type: String,
188
123
  required: true
189
124
  },
190
-
191
125
  dataMethod: {
192
126
  type: String,
193
127
  default: 'post',
194
128
  },
195
-
196
129
  model: {
197
130
  type: Object,
198
131
  required: true
199
132
  },
200
-
201
133
  policyUrl: {
202
134
  type: String,
203
135
  required: true
204
136
  },
205
-
206
137
  policyMethod: {
207
138
  type: String,
208
139
  default: 'post'
209
140
  },
210
-
211
141
  showTopbar:{
212
142
  type: Boolean,
213
143
  default: true
214
144
  },
215
-
216
145
  hasActions: {
217
146
  type: Boolean,
218
147
  default: true,
219
148
  },
220
-
221
149
  hasFilter: {
222
150
  type: Boolean,
223
151
  default: true,
224
152
  },
225
-
226
153
  formFilters: {
227
154
  type: Object,
228
155
  default: {}
229
156
  },
230
-
231
157
  externalFilters: {
232
158
  type: Object,
233
159
  default: {}
234
160
  },
235
-
236
161
  extraParams: {
237
162
  type: Object,
238
163
  default: {}
239
164
  },
240
-
241
165
  hideColumns: {
242
166
  type: Array,
243
167
  default: []
244
168
  },
245
-
246
169
  cardWrapper: {
247
170
  type: Boolean,
248
171
  default: true
249
172
  },
250
-
251
173
  showTableHeader: {
252
174
  type: Boolean,
253
175
  default: true,
254
176
  }
255
-
256
177
  },
257
-
258
178
  mounted() {
259
-
260
179
  this.fetchData();
261
-
262
180
  },
263
-
264
181
  data() {
265
-
266
182
  return {
267
-
268
183
  crudActions: this.model.crudActions(),
269
-
270
184
  dataTable: {
271
-
272
185
  head: this.dataTableHead(),
273
-
274
186
  body: []
275
-
276
187
  },
277
-
278
- pagination: {
279
-
188
+ pagination: {
280
189
  meta: [],
281
-
282
190
  links: []
283
-
284
191
  },
285
-
286
192
  sort: this.model.dataTableSort(),
287
-
288
193
  orderBy: 'id',
289
-
290
194
  internalSort: false,
291
-
292
195
  page: 1,
293
-
294
196
  fetchDataAttempts: 0,
295
-
296
197
  fetchPoliciesAttempts: 0,
297
-
298
198
  }
299
-
300
199
  },
301
-
302
200
  watch: {
303
-
304
201
  formFilters: {
305
-
306
202
  handler(val, oldVal) {
307
-
308
203
  this.page = 1;
309
-
310
204
  this.updateFilters();
311
-
312
205
  },
313
-
314
206
  deep: true
315
-
316
207
  },
317
-
318
208
  externalFilters: {
319
-
320
209
  handler(val, oldVal) {
321
-
322
210
  if(!_.isEqual(val, oldVal)) this.updateFilters();
323
-
324
211
  },
325
-
326
212
  deep: true
327
-
328
213
  }
329
-
330
214
  },
331
-
332
215
  methods: {
333
-
334
216
  dataTableHead() {
335
-
336
217
  // NOTA: En este punto puede existir una oportunidad para sobreescribir las columnas del datatable
337
-
338
218
  let cols = this.model.dataTableHead();
339
-
340
219
  let rm = this.hideColumns;
341
-
342
220
  for( let i = cols.length - 1; i >= 0; i--) {
343
-
344
221
  for( let j = 0; j < rm.length; j++) {
345
-
346
222
  if(cols[i] && (cols[i].id === rm[j].id)){
347
-
348
223
  cols.splice(i, 1);
349
-
350
224
  }
351
-
352
225
  }
353
-
354
226
  }
355
-
356
227
  return cols;
357
-
358
228
  },
359
-
360
- fetchData() {
361
-
229
+ fetchData() {
362
230
  const requestData = {
363
-
364
231
  method: this.dataMethod,
365
-
366
232
  url: this.dataUrl,
367
-
368
233
  data: this.dataMethod === 'post' ? this.getFilters() : null,
369
-
370
234
  params: this.dataMethod === 'get' ? this.getFilters() : null
371
-
372
235
  };
373
-
374
236
  axios(requestData).then(res => {
375
-
376
237
  this.fetchDataAttempts = 0;
377
-
378
238
  this.dataTable.body = res.data.data;
379
-
380
239
  this.pagination.meta = res.data.meta;
381
-
382
240
  this.pagination.links = res.data.links;
383
-
384
241
  }).catch(error => {
385
-
386
242
  if (error.response.status === 403) {
387
-
388
243
  // this.$router.push({name: "NotAuthorized" });
389
-
390
244
  } else {
391
-
392
245
  if (this.fetchDataAttempts <= 3) {
393
-
394
246
  setTimeout(() => {
395
-
396
247
  ++this.fetchDataAttempts;
397
-
398
248
  this.fetchData();
399
-
400
249
  }, 1500);
401
-
402
250
  }
403
-
404
251
  }
405
-
406
252
  });
407
253
  },
408
-
409
254
  getFilters() {
410
-
411
255
  let formFilters = this.formFilters;
412
-
413
256
  let params = {
414
257
  _token: csrf_token,
415
258
  managed: true,
416
259
  except_view_any: true,
417
260
  }
418
-
419
261
  let order = {
420
262
  orderBy: this.orderBy,
421
263
  orderMode: this.sort[this.orderBy]
422
264
  }
423
-
424
265
  let page = {
425
266
  page: this.page
426
267
  }
427
-
428
268
  let filters = {};
429
-
430
269
  if(this.internalSort) {
431
-
432
270
  filters = {
433
271
  ...params,
434
272
  ...formFilters,
@@ -436,9 +274,7 @@
436
274
  ...order,
437
275
  ...page
438
276
  }
439
-
440
277
  } else {
441
-
442
278
  filters = {
443
279
  ...params,
444
280
  ...formFilters,
@@ -446,154 +282,84 @@
446
282
  ...this.externalFilters,
447
283
  ...page
448
284
  }
449
-
450
285
  }
451
-
452
286
  return filters;
453
-
454
287
  },
455
-
456
288
  updateFilters() {
457
-
458
289
  this.model.setFilters(this.getFilters());
459
-
460
290
  this.fetchData();
461
-
462
291
  },
463
-
464
292
  sortColumn(data) {
465
-
466
293
  if(data.sortable == true) {
467
-
468
294
  // Esto hace que se haga caso omiso a la ordenación de externalFilters
469
295
  this.internalSort = true;
470
-
471
296
  let column_id = data.id;
472
-
473
297
  // Determinar la columan que va a ordenar los resultados
474
298
  this.orderBy = column_id;
475
-
476
299
  // Encontrar el orden actual
477
300
  let order = (this.sort[column_id] == 'asc') ? 'desc' : 'asc';
478
-
479
301
  // Determinar el nuevo orden para la columna dada
480
302
  this.sort[column_id] = order;
481
-
482
303
  // Solicitar los datos
483
304
  this.updateFilters();
484
-
485
305
  }
486
-
487
306
  },
488
-
489
307
  updatePage(page) {
490
-
491
308
  this.page = page;
492
-
493
309
  this.updateFilters();
494
-
495
310
  },
496
-
497
311
  actionClicked(action) {
498
-
499
312
  this.model[action.callback](action.params).then( res => {
500
-
501
313
  this.updateFilters();
502
-
503
314
  }).catch( error => {
504
-
505
315
  console.error(error);
506
-
507
316
  });
508
-
509
317
  },
510
-
511
318
  actionButtonClicked(actions) {
512
-
513
319
  const id = actions[0].params.id;
514
-
515
320
  const requestData = {
516
-
517
321
  _token: csrf_token,
518
-
519
322
  id: id
520
-
521
323
  };
522
-
523
324
  const requestConfig = {
524
-
525
325
  method: this.policyMethod,
526
-
527
326
  url: this.policyUrl,
528
-
529
327
  data: this.policyMethod === 'post' ? requestData : null,
530
-
531
328
  params: this.policyMethod === 'get' ? requestData : null
532
-
533
329
  };
534
-
535
330
  axios(requestConfig).then(res => {
536
-
537
331
  this.fetchPoliciesAttempts = 0;
538
-
539
332
  const policies = res.data;
540
-
541
333
  actions.forEach(action => {
542
-
543
334
  if (policies[action.id]) {
544
-
545
335
  action.policy = true;
546
-
547
336
  }
548
-
549
337
  });
550
-
551
338
  }).catch(error => {
552
-
553
339
  if (this.fetchPoliciesAttempts <= 3) {
554
-
555
340
  setTimeout(() => {
556
-
557
341
  ++this.fetchPoliciesAttempts;
558
-
559
342
  this.actionButtonClicked(actions);
560
-
561
343
  }, 1500);
562
-
563
344
  } else {
564
-
565
345
  setTimeout(() => {
566
-
567
346
  this.fetchPoliciesAttempts = 0;
568
-
569
347
  }, 3000);
570
-
571
348
  }
572
-
573
349
  });
574
-
575
350
  },
576
-
577
351
  closeDropdown(event){
578
-
579
352
  let dropdown = event.target.closest('.uk-dropdown');
580
-
581
353
  UIkit.dropdown(dropdown).hide(false);
582
-
583
354
  }
584
-
585
355
  }
586
-
587
356
  }
588
-
589
357
  </script>
590
358
 
591
359
  <style scoped>
592
-
593
360
  .tools-icon {
594
361
  font-size: 30px;
595
362
  color: var(--secondary-color);
596
363
  padding: 10px 15px;
597
364
  }
598
-
599
365
  </style>
@@ -1,15 +1,10 @@
1
1
  <template>
2
-
3
2
  <div class="sm:rounded-lg overflow-x-auto">
4
-
5
3
  <table class="min-w-full w-full text-sm text-left text-slate-500 dark:text-slate-400 p-4 ">
6
-
7
4
  <thead
8
5
  v-if="showTableHeader"
9
6
  class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400 rounded-sm">
10
-
11
7
  <tr>
12
-
13
8
  <th
14
9
  v-for="head in dataTable.head"
15
10
  :key="head.id"
@@ -18,59 +13,40 @@
18
13
  scope="col"
19
14
  :class="{pointer: head.sortable}"
20
15
  @click="sortColumn(head)">
21
-
22
16
  {{ head.value }}
23
-
24
17
  </th>
25
-
26
18
  <th
27
19
  class="uk-table-shrink"
28
20
  v-if="actions"></th>
29
-
30
21
  </tr>
31
-
32
22
  </thead>
33
-
34
23
  <tbody>
35
-
36
24
  <tr
37
25
  v-for="body in dataTable.body"
38
26
  :key="body.id"
39
- class="bg-white border-b dark:bg-gray-800 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600">
40
-
27
+ class="bg-white border-b dark:bg-gray-800 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600">
41
28
  <td
42
29
  v-for="head in dataTable.head"
43
30
  :key="head.id"
44
31
  class="px-6 py-4">
45
-
46
32
  <span
47
33
  v-if="head.html"
48
34
  class="dark:text-white"
49
35
  v-html="setData(head, body)"></span>
50
-
51
36
  <span v-else class="dark:text-white">{{ setData(head, body) }}</span>
52
-
53
37
  </td>
54
-
55
38
  <td v-if="actions" class="uk-text-right">
56
-
57
39
  <button
58
40
  class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-2 py-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800"
59
41
  @click="actionButtonClicked(body.actions)">
60
-
61
42
  <i class="fas fa-cogs"></i>
62
-
63
43
  </button>
64
-
65
44
  <nav-dropdown-component :id="`dropdown_${body.id}`" pos="left">
66
-
67
45
  <li
68
46
  v-for="action in body.actions"
69
47
  :key="action.name"
70
48
  class="hover:bg-slate-100 dark:hover:bg-slate-600 px-2 py-1">
71
-
72
49
  <template v-if="action.route && !action?.link">
73
-
74
50
  <icon-route-component
75
51
  v-if="action.policy"
76
52
  :name="action.params.to.name"
@@ -78,54 +54,37 @@
78
54
  :query="action.params.to.query ? {...action.params.to.query} : null"
79
55
  :icon="action.icon"
80
56
  :text="action.name" />
81
-
82
57
  <disabled-link-component
83
58
  v-else
84
59
  :icon="action.icon"
85
60
  :text="action.name"/>
86
-
87
61
  </template>
88
-
89
62
  <template v-else-if="action.route && action.link">
90
-
91
63
  <icon-link-component
92
64
  v-if="action.policy"
93
65
  :link="action.params.link"
94
66
  :target="action.params.target"
95
67
  :icon="action.icon"
96
68
  :text="action.name" />
97
-
98
69
  </template>
99
-
100
70
  <template v-else>
101
-
102
71
  <icon-link-component
103
72
  v-if="action.policy"
104
73
  :icon="action.icon"
105
74
  :text="action.name"
106
75
  @click="actionClicked(action), closeDropdown($event)" />
107
-
108
76
  <disabled-link-component
109
77
  v-else
110
78
  :icon="action.icon"
111
79
  :text="action.name"/>
112
-
113
80
  </template>
114
-
115
81
  </li>
116
-
117
82
  </nav-dropdown-component>
118
-
119
83
  </td>
120
-
121
84
  </tr>
122
-
123
85
  </tbody>
124
-
125
86
  </table>
126
-
127
87
  </div>
128
-
129
88
  </template>
130
89
 
131
90
  <script>
@@ -136,90 +95,56 @@
136
95
  import DisabledLinkComponent from './DisabledLinkComponent.vue'
137
96
 
138
97
  export default {
139
-
140
98
  components: {
141
-
142
99
  NavDropdownComponent,
143
-
144
100
  IconRouteComponent,
145
-
146
101
  IconLinkComponent,
147
-
148
102
  DisabledLinkComponent
149
-
150
103
  },
151
-
152
104
  props: {
153
-
154
105
  actions: {
155
106
  type: Boolean,
156
107
  default: false
157
108
  },
158
-
159
109
  dataTable: {
160
110
  type: [Object, Boolean],
161
111
  required: true
162
112
  },
163
-
164
113
  extraParams: {
165
114
  type: Object,
166
115
  default: {}
167
116
  },
168
-
169
117
  showTableHeader: {
170
118
  type: Boolean,
171
119
  default: true,
172
120
  }
173
-
174
121
  },
175
-
176
122
  emits: ['sortColumn', 'actionButtonClicked', 'actionClicked'],
177
-
178
123
  methods: {
179
-
180
124
  sortColumn(data) {
181
-
182
125
  this.$emit('sortColumn', data);
183
-
184
126
  },
185
-
186
127
  actionButtonClicked(data) {
187
-
188
128
  this.$emit('actionButtonClicked', data);
189
-
190
129
  },
191
-
192
130
  actionClicked(data) {
193
-
194
131
  this.$emit('actionClicked', data);
195
-
196
132
  },
197
-
198
133
  setData(head, body) {
199
-
200
- return (typeof head.parser === 'function') ? head.parser(body[head.id], body) : body[head.id]
201
-
134
+ const data = JSON.parse(JSON.stringify(body));
135
+ return typeof head.parser === 'function' ? head.parser(data[head.id], data) : data[head.id];
202
136
  },
203
-
204
137
  closeDropdown(event){
205
-
206
138
  let dropdown = event.target.closest('.uk-dropdown');
207
-
208
139
  UIkit.dropdown(dropdown).hide(false);
209
-
210
140
  }
211
-
212
141
  }
213
-
214
142
  }
215
-
216
143
  </script>
217
144
 
218
145
  <style>
219
-
220
146
  .uk-table td {
221
147
  padding: 12px 14px;
222
148
  vertical-align: middle;
223
149
  }
224
-
225
150
  </style>