vue-laravel-crud 2.0.1 → 2.0.4

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.
@@ -1,689 +1,696 @@
1
- <script>
2
- import CrudHeader from "./components/CrudHeader.vue";
3
- import CrudTable from "./components/CrudTable.vue";
4
- import CrudCards from "./components/CrudCards.vue";
5
- import CrudKanban from "./components/CrudKanban.vue";
6
- import CrudCustom from "./components/CrudCustom.vue";
7
- import CrudModals from "./components/CrudModals.vue";
8
- import CrudPagination from "./components/CrudPagination.vue";
9
-
10
- // Import mixins
11
- import crudData from "./mixins/crudData.js";
12
- import crudApi from "./mixins/crudApi.js";
13
- import crudFilters from "./mixins/crudFilters.js";
14
- import crudValidation from "./mixins/crudValidation.js";
15
- import crudHelpers from "./mixins/crudHelpers.js";
16
-
17
- export default /*#__PURE__*/ {
18
- name: "VueLaravelCrud",
19
- components: {
20
- CrudHeader,
21
- CrudTable,
22
- CrudCards,
23
- CrudKanban,
24
- CrudCustom,
25
- CrudModals,
26
- CrudPagination
27
- },
28
- mixins: [
29
- crudData,
30
- crudApi,
31
- crudFilters,
32
- crudValidation,
33
- crudHelpers
34
- ],
35
- provide() {
36
- return {
37
- // Props
38
- modelName: this.modelName,
39
- title: this.title,
40
- model: this.model,
41
- models: this.models,
42
- ajax: this.ajax,
43
- useVuexORM: this.useVuexORM,
44
- vuexInitRelations: this.vuexInitRelations,
45
- vuexLocalforage: this.vuexLocalforage,
46
- columns: this.columns,
47
- filter: this.filter,
48
- enableFilters: this.enableFilters,
49
- infiniteScroll: this.infiniteScroll,
50
- sortable: this.sortable,
51
- orderable: this.orderable,
52
- validate: this.validate,
53
- orderProp: this.orderProp,
54
- createMultipart: this.createMultipart,
55
- apiUrl: this.apiUrl,
56
- search: this.search,
57
- hideModalAfterSave: this.hideModalAfterSave,
58
- hideModalAfterCreate: this.hideModalAfterCreate,
59
- hideModalAfterUpdate: this.hideModalAfterUpdate,
60
- refreshAfterSave: this.refreshAfterSave,
61
- showPaginator: this.showPaginator,
62
- showCreateBtn: this.showCreateBtn,
63
- showSearch: this.showSearch,
64
- showPrincipalSortBtn: this.showPrincipalSortBtn,
65
- showHeader: this.showHeader,
66
- showTitle: this.showTitle,
67
- limit: this.limit,
68
- displayMode: this.displayMode,
69
- displayModeToggler: this.displayModeToggler,
70
- colXs: this.colXs,
71
- colSm: this.colSm,
72
- colMd: this.colMd,
73
- colLg: this.colLg,
74
- colXl: this.colXl,
75
- selectHover: this.selectHover,
76
- selectClick: this.selectClick,
77
- cardClass: this.cardClass,
78
- listContainerClass: this.listContainerClass,
79
- listItemClass: this.listItemClass,
80
- cardHideFooter: this.cardHideFooter,
81
- messageRemoveConfirm: this.messageRemoveConfirm,
82
- messageRemoveBulkConfirm: this.messageRemoveBulkConfirm,
83
- messageRemove: this.messageRemove,
84
- messageNew: this.messageNew,
85
- messageImport: this.messageImport,
86
- messageExport: this.messageExport,
87
- messageEmptyResults: this.messageEmptyResults,
88
- messageNoMore: this.messageNoMore,
89
- messageLoading: this.messageLoading,
90
- messageSave: this.messageSave,
91
- messageDefaultValidationError: this.messageDefaultValidationError,
92
- searchPlaceholder: this.searchPlaceholder,
93
- tableContainerClass: this.tableContainerClass,
94
- tableClass: this.tableClass,
95
- grouped: this.grouped,
96
- groupedAttribute: this.groupedAttribute,
97
- groupedLabelPre: this.groupedLabelPre,
98
- groupedLabelAfter: this.groupedLabelAfter,
99
- groupedSplit: this.groupedSplit,
100
- draggableGroup: this.draggableGroup,
101
- draggableOptions: this.draggableOptions,
102
- masonryEnabled: this.masonryEnabled,
103
- masonrySort: this.masonrySort,
104
- masonryColumns: this.masonryColumns,
105
- principalSortColumn: this.principalSortColumn,
106
- bulkDelete: this.bulkDelete,
107
- showImport: this.showImport,
108
- showExport: this.showExport,
109
- fileImport: this.fileImport,
110
- markDirty: this.markDirty,
111
-
112
- // Data from mixins
113
- crudUuid: this.crudUuid,
114
- moment: this.moment,
115
- loading: this.loading,
116
- firstLoad: this.firstLoad,
117
- item: this.item,
118
- items: this.items,
119
- selectedItems: this.selectedItems,
120
- pagination: this.pagination,
121
- displaySearch: this.displaySearch,
122
- itemDefault: this.itemDefault,
123
- filters: this.filters,
124
- filtersVisible: this.filtersVisible,
125
- filterSidebarOpen: this.filterSidebarOpen,
126
- internalFilters: this.internalFilters,
127
- forceRecomputeCounter: this.forceRecomputeCounter,
128
- displayModes: this.displayModes,
129
- infiniteScrollKey: this.infiniteScrollKey,
130
- optionsLoaded: this.optionsLoaded,
131
- isMobile: this.isMobile,
132
- refreshing: this.refreshing,
133
- fetchError: this.fetchError,
134
- principalSort: this.principalSort,
135
- exportFormat: this.exportFormat,
136
-
137
- // Computed from mixins
138
- itemValue: this.itemValue,
139
- isSplitGroups: this.isSplitGroups,
140
- itemsList: this.itemsList,
141
- paginationIndexStart: this.paginationIndexStart,
142
- paginationIndexEnd: this.paginationIndexEnd,
143
- finalFilters: this.finalFilters,
144
- sortFilter: this.sortFilter,
145
- groupFilter: this.groupFilter,
146
- internalFilter: this.internalFilter,
147
- internalFilterByProp: this.internalFilterByProp,
148
- columnOptions: this.columnOptions,
149
-
150
- // Methods from mixins
151
- handleResize: this.handleResize,
152
- rearrangeArray: this.rearrangeArray,
153
- clearItems: this.clearItems,
154
- updateData: this.updateData,
155
- externalUpdate: this.externalUpdate,
156
- makePagination: this.makePagination,
157
- fetchItemsVuex: this.fetchItemsVuex,
158
- fetchItemsLocal: this.fetchItemsLocal,
159
- fetchItems: this.fetchItems,
160
- groupItems: this.groupItems,
161
- saveItemVuex: this.saveItemVuex,
162
- saveItemLocal: this.saveItemLocal,
163
- saveItem: this.saveItem,
164
- deleteItem: this.deleteItem,
165
- deleteItemLocal: this.deleteItemLocal,
166
- deleteItemVuex: this.deleteItemVuex,
167
- deleteItemBulk: this.deleteItemBulk,
168
- deleteItemBulkLocal: this.deleteItemBulkLocal,
169
- deleteItemBulkVuex: this.deleteItemBulkVuex,
170
- saveSort: this.saveSort,
171
- exportItems: this.exportItems,
172
- importItems: this.importItems,
173
- refresh: this.refresh,
174
- onPaginationChange: this.onPaginationChange,
175
- infiniteHandler: this.infiniteHandler,
176
- setupFilters: this.setupFilters,
177
- toggleSortFilter: this.toggleSortFilter,
178
- toggleFilters: this.toggleFilters,
179
- resetFilters: this.resetFilters,
180
- isColumnHasFilter: this.isColumnHasFilter,
181
- setFilter: this.setFilter,
182
- onChangeFilter: this.onChangeFilter,
183
- togglePrincipalSort: this.togglePrincipalSort,
184
- loadOptions: this.loadOptions,
185
- getArrayValue: this.getArrayValue,
186
- getStateValue: this.getStateValue,
187
- onRowHover: this.onRowHover,
188
- onRowClick: this.onRowClick,
189
- onSort: this.onSort,
190
- onCheckSelect: this.onCheckSelect,
191
- toggleAll: this.toggleAll,
192
- unSelectItem: this.unSelectItem,
193
- selectItem: this.selectItem,
194
- getSelectedItems: this.getSelectedItems,
195
- onSelect: this.onSelect,
196
- showItem: this.showItem,
197
- createItem: this.createItem,
198
- updateItem: this.updateItem,
199
- removeItem: this.removeItem,
200
- confirmBulkDelete: this.confirmBulkDelete,
201
- toggleDisplayMode: this.toggleDisplayMode,
202
- showExportModal: this.showExportModal,
203
- showImportModal: this.showImportModal,
204
- onDraggableAdded: this.onDraggableAdded,
205
- onDraggableChange: this.onDraggableChange,
206
- onDragEnd: this.onDragEnd,
207
- toastError: this.toastError,
208
- toastSuccess: this.toastSuccess,
209
- downloadBlobResponse: this.downloadBlobResponse
210
- };
211
- },
212
- props: {
213
- modelName: String,
214
-
215
- title: String,
216
- model: {
217
- type: Object | Function,
218
- default() {
219
- return { id: 0 };
220
- },
221
- },
222
- models: {
223
- type: Array,
224
- default: () => [],
225
- },
226
- ajax: {
227
- type: Boolean,
228
- default: true,
229
- },
230
- useVuexORM: {
231
- type: Boolean,
232
- default: false,
233
- },
234
- vuexInitRelations: {
235
- type: Boolean | Array,
236
- default: true,
237
- },
238
- vuexLocalforage: {
239
- type: Boolean,
240
- default: false,
241
- },
242
-
243
- columns: {
244
- type: Array,
245
-
246
- default() {
247
- return [{ label: "Id", prop: "id", type: "number" }];
248
- },
249
- },
250
- filter: {
251
- type: Array,
252
- default: () => [],
253
- },
254
- enableFilters: {
255
- type: Boolean,
256
- default: false,
257
- },
258
-
259
- infiniteScroll: {
260
- type: Boolean,
261
- default: false,
262
- },
263
- sortable: {
264
- type: Boolean,
265
- default: false,
266
- },
267
- orderable: {
268
- type: Boolean,
269
- default: false,
270
- },
271
- validate: {
272
- type: Boolean,
273
- default: false,
274
- },
275
- orderProp: {
276
- type: String,
277
- default: "order",
278
- },
279
- createMultipart: {
280
- type: Boolean,
281
- default: false,
282
- },
283
- apiUrl: {
284
- type: String,
285
- default: "/api",
286
- },
287
- search: {
288
- type: String,
289
- default: "",
290
- },
291
- hideModalAfterSave: {
292
- type: Boolean,
293
- default: true,
294
- },
295
- hideModalAfterCreate: {
296
- type: Boolean,
297
- default: false,
298
- },
299
- hideModalAfterUpdate: {
300
- type: Boolean,
301
- default: false,
302
- },
303
- refreshAfterSave: {
304
- type: Boolean,
305
- default: true,
306
- },
307
- showPaginator: {
308
- type: Boolean,
309
- default: true,
310
- },
311
- showCreateBtn: {
312
- type: Boolean,
313
- default: true,
314
- },
315
- showSearch: {
316
- type: Boolean,
317
- default: true,
318
- },
319
- showPrincipalSortBtn: {
320
- type: Boolean,
321
- default: false,
322
- },
323
-
324
- showHeader: {
325
- type: Boolean,
326
- default: true,
327
- },
328
- showTitle: {
329
- type: Boolean,
330
- default: true,
331
- },
332
- limit: {
333
- type: Number,
334
- default: 20,
335
- },
336
- displayMode: {
337
- type: Number,
338
- default: 1,
339
- },
340
- displayModeToggler: {
341
- type: Boolean,
342
- default: false,
343
- },
344
-
345
- colXs: {
346
- default: 12,
347
- type: Number,
348
- },
349
- colSm: {
350
- default: 12,
351
- type: Number,
352
- },
353
- colMd: {
354
- default: 6,
355
- type: Number,
356
- },
357
- colLg: {
358
- default: 4,
359
- type: Number,
360
- },
361
- colXl: {
362
- default: 4,
363
- type: Number,
364
- },
365
-
366
- selectHover: {
367
- type: Boolean,
368
- default: false,
369
- },
370
- selectClick: {
371
- type: Boolean,
372
- default: false,
373
- },
374
-
375
- cardClass: {
376
- type: String,
377
- default: "",
378
- },
379
-
380
- listContainerClass: {
381
- type: String,
382
- default: "",
383
- },
384
-
385
- listItemClass: {
386
- type: String,
387
- default: "",
388
- },
389
-
390
- cardHideFooter: {
391
- type: Boolean,
392
- default: false,
393
- },
394
-
395
- messageRemoveConfirm: {
396
- type: String,
397
- default: "¿Esta seguro de borrar este elemento?",
398
- },
399
- messageRemoveBulkConfirm: {
400
- type: String,
401
- default: "¿Esta seguro de borrar los elementos seleccionados?",
402
- },
403
- messageRemove: {
404
- type: String,
405
- default: "BORRAR",
406
- },
407
- messageNew: {
408
- type: String,
409
- default: "Nuevo",
410
- },
411
- messageImport: {
412
- type: String,
413
- default: "Importar",
414
- },
415
- messageExport: {
416
- type: String,
417
- default: "Exportar",
418
- },
419
- messageEmptyResults: {
420
- type: String,
421
- default: "No se han encontrado resultados",
422
- },
423
- messageNoMore: {
424
- type: String,
425
- default: "No hay más elementos para mostrar.",
426
- },
427
- messageLoading: {
428
- type: String,
429
- default: "Cargando...",
430
- },
431
- messageSave: {
432
- type: String,
433
- default: "Guardar",
434
- },
435
- messageDefaultValidationError: {
436
- type: String,
437
- default: "Por favor controle el formulario, contiene errores.",
438
- },
439
- searchPlaceholder: {
440
- type: String,
441
- default: "Buscar...",
442
- },
443
-
444
- tableContainerClass: {
445
- type: String,
446
- default: "",
447
- },
448
- tableClass: {
449
- type: String,
450
- default: "",
451
- },
452
- grouped: {
453
- type: Boolean,
454
- default: false,
455
- },
456
- groupedAttribute: {
457
- type: String,
458
- default: "name",
459
- },
460
- groupedLabelPre: {
461
- type: String,
462
- default: "",
463
- },
464
- groupedLabelAfter: {
465
- type: String,
466
- default: "",
467
- },
468
- groupedSplit: {
469
- type: Boolean,
470
- default: false,
471
- },
472
- draggableGroup: {
473
- type: String,
474
- default: "people",
475
- },
476
-
477
- draggableOptions: {
478
- type: Object,
479
- default: function () {
480
- return { clone: false };
481
- }
482
-
483
- },
484
- masonryEnabled: {
485
- type: Boolean,
486
- default: false,
487
- },
488
-
489
- masonrySort: {
490
- type: Boolean,
491
- default: false,
492
- },
493
- masonryColumns: {
494
- type: Number,
495
- default: 3,
496
- },
497
-
498
- principalSortColumn: {
499
- type: String,
500
- default: "id",
501
- },
502
-
503
- bulkDelete: {
504
- type: Boolean,
505
- default: false,
506
- },
507
-
508
- showImport: {
509
- type: Boolean,
510
- default: false,
511
- },
512
-
513
- showExport: {
514
- type: Boolean,
515
- default: false,
516
- },
517
- markDirty: {
518
- type: Boolean,
519
- default: true,
520
- }
521
- },
522
-
523
- };
524
- </script>
525
-
526
- <template>
527
- <div class="crud">
528
- <CrudHeader />
529
-
530
- <CrudTable />
531
- <CrudCards />
532
- <CrudKanban />
533
- <CrudCustom />
534
-
535
- <b-overlay :show="loading" rounded="sm"></b-overlay>
536
-
537
- <CrudPagination />
538
- <CrudModals />
539
- </div>
540
- </template>
541
-
542
- <style lang="scss" scoped>
543
- tr td:last-child,
544
- tr td:first-child {
545
- width: 1%;
546
- white-space: nowrap;
547
- }
548
-
549
- tbody tr.selected {
550
- background-color: #e3f2fd !important;
551
-
552
- td {
553
- background-color: transparent !important;
554
- }
555
-
556
- &:hover {
557
- background-color: #bbdefb !important;
558
-
559
- td {
560
- background-color: transparent !important;
561
- }
562
- }
563
- }
564
-
565
- .table-striped tbody tr.selected:nth-of-type(odd) {
566
- background-color: #e3f2fd !important;
567
-
568
- td {
569
- background-color: transparent !important;
570
- }
571
- }
572
-
573
- .table-striped tbody tr.selected:nth-of-type(even) {
574
- background-color: #e3f2fd !important;
575
-
576
- td {
577
- background-color: transparent !important;
578
- }
579
- }
580
-
581
- .crud-pagination {
582
- display: flex;
583
- align-items: center;
584
- width: 100%;
585
- justify-content: center;
586
- margin-top: 1rem;
587
- }
588
-
589
- .crud-header {
590
- display: flex;
591
- justify-content: space-between;
592
- max-height: 3rem;
593
-
594
- .crud-title {
595
- margin: 0;
596
- }
597
-
598
- .crud-search {
599
- max-width: 15rem;
600
-
601
- .btn {
602
- border-top-left-radius: 0;
603
- border-bottom-left-radius: 0;
604
- border-top-right-radius: 0.375rem;
605
- border-bottom-right-radius: 0.375rem;
606
-
607
- &.open {
608
- border-top-right-radius: 0;
609
- border-bottom-right-radius: 0;
610
- }
611
- }
612
- }
613
-
614
- .table-options {
615
- margin-bottom: 1rem;
616
- display: flex;
617
- align-items: center;
618
- justify-content: flex-end;
619
- }
620
- }
621
-
622
- .custom-control {
623
- position: relative;
624
- }
625
-
626
-
627
- @media (min-width: 992px) {
628
- .table {
629
- table-layout: auto;
630
-
631
- tbody {
632
- td {
633
- overflow: scroll;
634
- -ms-overflow-style: none;
635
- /* IE and Edge */
636
- scrollbar-width: none;
637
- /* Firefox */
638
- }
639
-
640
- td::-webkit-scrollbar {
641
- display: none;
642
- }
643
- }
644
- }
645
- }
646
-
647
-
648
- .kanban-board {
649
- display: flex;
650
- gap: 1rem;
651
- overflow-x: auto;
652
- padding: 1rem;
653
- }
654
-
655
- .kanban-column {
656
- background: #f4f5f7;
657
- border-radius: 8px;
658
- width: 300px;
659
- display: flex;
660
- flex-direction: column;
661
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
662
- }
663
-
664
- .kanban-column-header {
665
- font-weight: bold;
666
- padding: 0.5rem;
667
- background: #dfe1e6;
668
- border-radius: 8px 8px 0 0;
669
- text-align: center;
670
- }
671
-
672
- .kanban-column-body {
673
- padding: 0.5rem;
674
- min-height: 100px;
675
- background: #ffffff;
676
- border-radius: 0 0 8px 8px;
677
- display: flex;
678
- flex-direction: column;
679
- gap: 0.5rem;
680
- }
681
-
682
- .kanban-card {
683
- background: #ffffff;
684
- border-radius: 4px;
685
- padding: 1rem;
686
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
687
- cursor: grab;
688
- }
1
+ <script>
2
+ import CrudHeader from "./components/CrudHeader.vue";
3
+ import CrudTable from "./components/CrudTable.vue";
4
+ import CrudCards from "./components/CrudCards.vue";
5
+ import CrudKanban from "./components/CrudKanban.vue";
6
+ import CrudCustom from "./components/CrudCustom.vue";
7
+ import CrudModals from "./components/CrudModals.vue";
8
+ import CrudPagination from "./components/CrudPagination.vue";
9
+
10
+ // Import mixins
11
+ import crudData from "./mixins/crudData.js";
12
+ import crudApi from "./mixins/crudApi.js";
13
+ import crudFilters from "./mixins/crudFilters.js";
14
+ import crudValidation from "./mixins/crudValidation.js";
15
+ import crudHelpers from "./mixins/crudHelpers.js";
16
+
17
+ export default /*#__PURE__*/ {
18
+ name: "VueLaravelCrud",
19
+ components: {
20
+ CrudHeader,
21
+ CrudTable,
22
+ CrudCards,
23
+ CrudKanban,
24
+ CrudCustom,
25
+ CrudModals,
26
+ CrudPagination
27
+ },
28
+ mixins: [
29
+ crudData,
30
+ crudApi,
31
+ crudFilters,
32
+ crudValidation,
33
+ crudHelpers
34
+ ],
35
+ provide() {
36
+ return {
37
+ // Props
38
+ modelName: this.modelName,
39
+ title: this.title,
40
+ model: this.model,
41
+ models: this.models,
42
+ ajax: this.ajax,
43
+ useVuexORM: this.useVuexORM,
44
+ vuexInitRelations: this.vuexInitRelations,
45
+ vuexLocalforage: this.vuexLocalforage,
46
+ columns: this.columns,
47
+ filter: this.filter,
48
+ enableFilters: this.enableFilters,
49
+ infiniteScroll: this.infiniteScroll,
50
+ sortable: this.sortable,
51
+ orderable: this.orderable,
52
+ validate: this.validate,
53
+ orderProp: this.orderProp,
54
+ createMultipart: this.createMultipart,
55
+ apiUrl: this.apiUrl,
56
+ search: this.search,
57
+ hideModalAfterSave: this.hideModalAfterSave,
58
+ hideModalAfterCreate: this.hideModalAfterCreate,
59
+ hideModalAfterUpdate: this.hideModalAfterUpdate,
60
+ refreshAfterSave: this.refreshAfterSave,
61
+ showPaginator: this.showPaginator,
62
+ showCreateBtn: this.showCreateBtn,
63
+ showSearch: this.showSearch,
64
+ showPrincipalSortBtn: this.showPrincipalSortBtn,
65
+ showHeader: this.showHeader,
66
+ showTitle: this.showTitle,
67
+ limit: this.limit,
68
+ displayMode: this.displayMode,
69
+ displayModeToggler: this.displayModeToggler,
70
+ colXs: this.colXs,
71
+ colSm: this.colSm,
72
+ colMd: this.colMd,
73
+ colLg: this.colLg,
74
+ colXl: this.colXl,
75
+ selectHover: this.selectHover,
76
+ selectClick: this.selectClick,
77
+ cardClass: this.cardClass,
78
+ listContainerClass: this.listContainerClass,
79
+ listItemClass: this.listItemClass,
80
+ cardHideFooter: this.cardHideFooter,
81
+ messageRemoveConfirm: this.messageRemoveConfirm,
82
+ messageRemoveBulkConfirm: this.messageRemoveBulkConfirm,
83
+ messageRemove: this.messageRemove,
84
+ messageNew: this.messageNew,
85
+ messageImport: this.messageImport,
86
+ messageExport: this.messageExport,
87
+ messageEmptyResults: this.messageEmptyResults,
88
+ messageNoMore: this.messageNoMore,
89
+ messageLoading: this.messageLoading,
90
+ messageSave: this.messageSave,
91
+ messageDefaultValidationError: this.messageDefaultValidationError,
92
+ searchPlaceholder: this.searchPlaceholder,
93
+ tableContainerClass: this.tableContainerClass,
94
+ tableClass: this.tableClass,
95
+ grouped: this.grouped,
96
+ groupedAttribute: this.groupedAttribute,
97
+ groupedLabelPre: this.groupedLabelPre,
98
+ groupedLabelAfter: this.groupedLabelAfter,
99
+ groupedSplit: this.groupedSplit,
100
+ draggableGroup: this.draggableGroup,
101
+ draggableOptions: this.draggableOptions,
102
+ masonryEnabled: this.masonryEnabled,
103
+ masonrySort: this.masonrySort,
104
+ masonryColumns: this.masonryColumns,
105
+ principalSortColumn: this.principalSortColumn,
106
+ bulkDelete: this.bulkDelete,
107
+ showImport: this.showImport,
108
+ showExport: this.showExport,
109
+ fileImport: this.fileImport,
110
+ markDirty: this.markDirty,
111
+
112
+ // Data from mixins
113
+ crudUuid: this.crudUuid,
114
+ moment: this.moment,
115
+ loading: this.loading,
116
+ firstLoad: this.firstLoad,
117
+ item: this.item,
118
+ items: this.items,
119
+ selectedItems: this.selectedItems,
120
+ pagination: this.pagination,
121
+ displaySearch: this.displaySearch,
122
+ itemDefault: this.itemDefault,
123
+ filters: this.filters,
124
+ filtersVisible: this.filtersVisible,
125
+ filterSidebarOpen: this.filterSidebarOpen,
126
+ internalFilters: this.internalFilters,
127
+ forceRecomputeCounter: this.forceRecomputeCounter,
128
+ displayModes: this.displayModes,
129
+ infiniteScrollKey: this.infiniteScrollKey,
130
+ optionsLoaded: this.optionsLoaded,
131
+ isMobile: this.isMobile,
132
+ refreshing: this.refreshing,
133
+ fetchError: this.fetchError,
134
+ principalSort: this.principalSort,
135
+ exportFormat: this.exportFormat,
136
+
137
+ // Computed from mixins
138
+ itemValue: this.itemValue,
139
+ isSplitGroups: this.isSplitGroups,
140
+ itemsList: this.itemsList,
141
+ paginationIndexStart: this.paginationIndexStart,
142
+ paginationIndexEnd: this.paginationIndexEnd,
143
+ finalFilters: this.finalFilters,
144
+ sortFilter: this.sortFilter,
145
+ groupFilter: this.groupFilter,
146
+ internalFilter: this.internalFilter,
147
+ internalFilterByProp: this.internalFilterByProp,
148
+ columnOptions: this.columnOptions,
149
+ isAllSelected: this.isAllSelected,
150
+
151
+ // Methods from mixins
152
+ handleResize: this.handleResize,
153
+ rearrangeArray: this.rearrangeArray,
154
+ clearItems: this.clearItems,
155
+ updateData: this.updateData,
156
+ externalUpdate: this.externalUpdate,
157
+ makePagination: this.makePagination,
158
+ fetchItemsVuex: this.fetchItemsVuex,
159
+ fetchItemsLocal: this.fetchItemsLocal,
160
+ fetchItems: this.fetchItems,
161
+ groupItems: this.groupItems,
162
+ saveItemVuex: this.saveItemVuex,
163
+ saveItemLocal: this.saveItemLocal,
164
+ saveItem: this.saveItem,
165
+ deleteItem: this.deleteItem,
166
+ deleteItemLocal: this.deleteItemLocal,
167
+ deleteItemVuex: this.deleteItemVuex,
168
+ deleteItemBulk: this.deleteItemBulk,
169
+ deleteItemBulkLocal: this.deleteItemBulkLocal,
170
+ deleteItemBulkVuex: this.deleteItemBulkVuex,
171
+ saveSort: this.saveSort,
172
+ exportItems: this.exportItems,
173
+ importItems: this.importItems,
174
+ refresh: this.refresh,
175
+ onPaginationChange: this.onPaginationChange,
176
+ onPerPageChange: this.onPerPageChange,
177
+ infiniteHandler: this.infiniteHandler,
178
+ setupFilters: this.setupFilters,
179
+ toggleSortFilter: this.toggleSortFilter,
180
+ toggleFilters: this.toggleFilters,
181
+ resetFilters: this.resetFilters,
182
+ isColumnHasFilter: this.isColumnHasFilter,
183
+ setFilter: this.setFilter,
184
+ onChangeFilter: this.onChangeFilter,
185
+ togglePrincipalSort: this.togglePrincipalSort,
186
+ loadOptions: this.loadOptions,
187
+ getArrayValue: this.getArrayValue,
188
+ getStateValue: this.getStateValue,
189
+ onRowHover: this.onRowHover,
190
+ onRowClick: this.onRowClick,
191
+ onSort: this.onSort,
192
+ onCheckSelect: this.onCheckSelect,
193
+ toggleAll: this.toggleAll,
194
+ unSelectItem: this.unSelectItem,
195
+ selectItem: this.selectItem,
196
+ getSelectedItems: this.getSelectedItems,
197
+ clearSelection: this.clearSelection,
198
+ onSelect: this.onSelect,
199
+ showItem: this.showItem,
200
+ createItem: this.createItem,
201
+ updateItem: this.updateItem,
202
+ removeItem: this.removeItem,
203
+ confirmBulkDelete: this.confirmBulkDelete,
204
+ toggleDisplayMode: this.toggleDisplayMode,
205
+ showExportModal: this.showExportModal,
206
+ showImportModal: this.showImportModal,
207
+ onDraggableAdded: this.onDraggableAdded,
208
+ onDraggableChange: this.onDraggableChange,
209
+ onDragEnd: this.onDragEnd,
210
+ toastError: this.toastError,
211
+ toastSuccess: this.toastSuccess,
212
+ downloadBlobResponse: this.downloadBlobResponse
213
+ };
214
+ },
215
+ props: {
216
+ modelName: String,
217
+
218
+ title: String,
219
+ model: {
220
+ type: Object | Function,
221
+ default() {
222
+ return { id: 0 };
223
+ },
224
+ },
225
+ models: {
226
+ type: Array,
227
+ default: () => [],
228
+ },
229
+ ajax: {
230
+ type: Boolean,
231
+ default: true,
232
+ },
233
+ useVuexORM: {
234
+ type: Boolean,
235
+ default: false,
236
+ },
237
+ vuexInitRelations: {
238
+ type: Boolean | Array,
239
+ default: true,
240
+ },
241
+ vuexLocalforage: {
242
+ type: Boolean,
243
+ default: false,
244
+ },
245
+
246
+ columns: {
247
+ type: Array,
248
+
249
+ default() {
250
+ return [{ label: "Id", prop: "id", type: "number" }];
251
+ },
252
+ },
253
+ filter: {
254
+ type: Array,
255
+ default: () => [],
256
+ },
257
+ enableFilters: {
258
+ type: Boolean,
259
+ default: false,
260
+ },
261
+
262
+ infiniteScroll: {
263
+ type: Boolean,
264
+ default: false,
265
+ },
266
+ sortable: {
267
+ type: Boolean,
268
+ default: false,
269
+ },
270
+ orderable: {
271
+ type: Boolean,
272
+ default: false,
273
+ },
274
+ validate: {
275
+ type: Boolean,
276
+ default: false,
277
+ },
278
+ orderProp: {
279
+ type: String,
280
+ default: "order",
281
+ },
282
+ createMultipart: {
283
+ type: Boolean,
284
+ default: false,
285
+ },
286
+ apiUrl: {
287
+ type: String,
288
+ default: "/api",
289
+ },
290
+ search: {
291
+ type: String,
292
+ default: "",
293
+ },
294
+ hideModalAfterSave: {
295
+ type: Boolean,
296
+ default: true,
297
+ },
298
+ hideModalAfterCreate: {
299
+ type: Boolean,
300
+ default: false,
301
+ },
302
+ hideModalAfterUpdate: {
303
+ type: Boolean,
304
+ default: false,
305
+ },
306
+ refreshAfterSave: {
307
+ type: Boolean,
308
+ default: true,
309
+ },
310
+ showPaginator: {
311
+ type: Boolean,
312
+ default: true,
313
+ },
314
+ showCreateBtn: {
315
+ type: Boolean,
316
+ default: true,
317
+ },
318
+ showSearch: {
319
+ type: Boolean,
320
+ default: true,
321
+ },
322
+ showPrincipalSortBtn: {
323
+ type: Boolean,
324
+ default: false,
325
+ },
326
+
327
+ showHeader: {
328
+ type: Boolean,
329
+ default: true,
330
+ },
331
+ showTitle: {
332
+ type: Boolean,
333
+ default: true,
334
+ },
335
+ limit: {
336
+ type: Number,
337
+ default: 20,
338
+ },
339
+ displayMode: {
340
+ type: Number,
341
+ default: 1,
342
+ },
343
+ displayModeToggler: {
344
+ type: Boolean,
345
+ default: false,
346
+ },
347
+
348
+ colXs: {
349
+ default: 12,
350
+ type: Number,
351
+ },
352
+ colSm: {
353
+ default: 12,
354
+ type: Number,
355
+ },
356
+ colMd: {
357
+ default: 6,
358
+ type: Number,
359
+ },
360
+ colLg: {
361
+ default: 4,
362
+ type: Number,
363
+ },
364
+ colXl: {
365
+ default: 4,
366
+ type: Number,
367
+ },
368
+
369
+ selectHover: {
370
+ type: Boolean,
371
+ default: false,
372
+ },
373
+ selectClick: {
374
+ type: Boolean,
375
+ default: false,
376
+ },
377
+
378
+ cardClass: {
379
+ type: String,
380
+ default: "",
381
+ },
382
+
383
+ listContainerClass: {
384
+ type: String,
385
+ default: "",
386
+ },
387
+
388
+ listItemClass: {
389
+ type: String,
390
+ default: "",
391
+ },
392
+
393
+ cardHideFooter: {
394
+ type: Boolean,
395
+ default: false,
396
+ },
397
+
398
+ messageRemoveConfirm: {
399
+ type: String,
400
+ default: "¿Esta seguro de borrar este elemento?",
401
+ },
402
+ messageRemoveBulkConfirm: {
403
+ type: String,
404
+ default: "¿Esta seguro de borrar los elementos seleccionados?",
405
+ },
406
+ messageRemove: {
407
+ type: String,
408
+ default: "BORRAR",
409
+ },
410
+ messageNew: {
411
+ type: String,
412
+ default: "Nuevo",
413
+ },
414
+ messageImport: {
415
+ type: String,
416
+ default: "Importar",
417
+ },
418
+ messageExport: {
419
+ type: String,
420
+ default: "Exportar",
421
+ },
422
+ messageEmptyResults: {
423
+ type: String,
424
+ default: "No se han encontrado resultados",
425
+ },
426
+ messageNoMore: {
427
+ type: String,
428
+ default: "No hay más elementos para mostrar.",
429
+ },
430
+ messageLoading: {
431
+ type: String,
432
+ default: "Cargando...",
433
+ },
434
+ messageSave: {
435
+ type: String,
436
+ default: "Guardar",
437
+ },
438
+ messageDefaultValidationError: {
439
+ type: String,
440
+ default: "Por favor controle el formulario, contiene errores.",
441
+ },
442
+ searchPlaceholder: {
443
+ type: String,
444
+ default: "Buscar...",
445
+ },
446
+
447
+ tableContainerClass: {
448
+ type: String,
449
+ default: "",
450
+ },
451
+ tableClass: {
452
+ type: String,
453
+ default: "",
454
+ },
455
+ grouped: {
456
+ type: Boolean,
457
+ default: false,
458
+ },
459
+ groupedAttribute: {
460
+ type: String,
461
+ default: "name",
462
+ },
463
+ groupedLabelPre: {
464
+ type: String,
465
+ default: "",
466
+ },
467
+ groupedLabelAfter: {
468
+ type: String,
469
+ default: "",
470
+ },
471
+ groupedSplit: {
472
+ type: Boolean,
473
+ default: false,
474
+ },
475
+ draggableGroup: {
476
+ type: String,
477
+ default: "people",
478
+ },
479
+
480
+ draggableOptions: {
481
+ type: Object,
482
+ default: function () {
483
+ return { clone: false };
484
+ }
485
+
486
+ },
487
+ masonryEnabled: {
488
+ type: Boolean,
489
+ default: false,
490
+ },
491
+
492
+ masonrySort: {
493
+ type: Boolean,
494
+ default: false,
495
+ },
496
+ masonryColumns: {
497
+ type: Number,
498
+ default: 3,
499
+ },
500
+
501
+ principalSortColumn: {
502
+ type: String,
503
+ default: "id",
504
+ },
505
+
506
+ bulkDelete: {
507
+ type: Boolean,
508
+ default: false,
509
+ },
510
+
511
+ showImport: {
512
+ type: Boolean,
513
+ default: false,
514
+ },
515
+
516
+ showExport: {
517
+ type: Boolean,
518
+ default: false,
519
+ },
520
+ markDirty: {
521
+ type: Boolean,
522
+ default: true,
523
+ }
524
+ },
525
+
526
+ };
527
+ </script>
528
+
529
+ <template>
530
+ <div class="crud">
531
+ <CrudHeader />
532
+
533
+ <CrudTable />
534
+ <CrudCards />
535
+ <CrudKanban />
536
+ <CrudCustom />
537
+
538
+ <b-overlay :show="loading" rounded="sm"></b-overlay>
539
+
540
+ <CrudPagination />
541
+ <CrudModals>
542
+ <template v-for="(slot, name) in $scopedSlots" v-slot:[name]="slotProps">
543
+ <slot :name="name" v-bind="slotProps" />
544
+ </template>
545
+ </CrudModals>
546
+ </div>
547
+ </template>
548
+
549
+ <style lang="scss" scoped>
550
+ tr td:last-child,
551
+ tr td:first-child {
552
+ width: 1%;
553
+ white-space: nowrap;
554
+ }
555
+
556
+ tbody tr.selected {
557
+ background-color: #e3f2fd !important;
558
+
559
+ td {
560
+ background-color: transparent !important;
561
+ }
562
+
563
+ &:hover {
564
+ background-color: #bbdefb !important;
565
+
566
+ td {
567
+ background-color: transparent !important;
568
+ }
569
+ }
570
+ }
571
+
572
+ .table-striped tbody tr.selected:nth-of-type(odd) {
573
+ background-color: #e3f2fd !important;
574
+
575
+ td {
576
+ background-color: transparent !important;
577
+ }
578
+ }
579
+
580
+ .table-striped tbody tr.selected:nth-of-type(even) {
581
+ background-color: #e3f2fd !important;
582
+
583
+ td {
584
+ background-color: transparent !important;
585
+ }
586
+ }
587
+
588
+ .crud-pagination {
589
+ display: flex;
590
+ align-items: center;
591
+ width: 100%;
592
+ justify-content: center;
593
+ margin-top: 1rem;
594
+ }
595
+
596
+ .crud-header {
597
+ display: flex;
598
+ justify-content: space-between;
599
+ max-height: 3rem;
600
+
601
+ .crud-title {
602
+ margin: 0;
603
+ }
604
+
605
+ .crud-search {
606
+ max-width: 15rem;
607
+
608
+ .btn {
609
+ border-top-left-radius: 0;
610
+ border-bottom-left-radius: 0;
611
+ border-top-right-radius: 0.375rem;
612
+ border-bottom-right-radius: 0.375rem;
613
+
614
+ &.open {
615
+ border-top-right-radius: 0;
616
+ border-bottom-right-radius: 0;
617
+ }
618
+ }
619
+ }
620
+
621
+ .table-options {
622
+ margin-bottom: 1rem;
623
+ display: flex;
624
+ align-items: center;
625
+ justify-content: flex-end;
626
+ }
627
+ }
628
+
629
+ .custom-control {
630
+ position: relative;
631
+ }
632
+
633
+
634
+ @media (min-width: 992px) {
635
+ .table {
636
+ table-layout: auto;
637
+
638
+ tbody {
639
+ td {
640
+ overflow: scroll;
641
+ -ms-overflow-style: none;
642
+ /* IE and Edge */
643
+ scrollbar-width: none;
644
+ /* Firefox */
645
+ }
646
+
647
+ td::-webkit-scrollbar {
648
+ display: none;
649
+ }
650
+ }
651
+ }
652
+ }
653
+
654
+
655
+ .kanban-board {
656
+ display: flex;
657
+ gap: 1rem;
658
+ overflow-x: auto;
659
+ padding: 1rem;
660
+ }
661
+
662
+ .kanban-column {
663
+ background: #f4f5f7;
664
+ border-radius: 8px;
665
+ width: 300px;
666
+ display: flex;
667
+ flex-direction: column;
668
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
669
+ }
670
+
671
+ .kanban-column-header {
672
+ font-weight: bold;
673
+ padding: 0.5rem;
674
+ background: #dfe1e6;
675
+ border-radius: 8px 8px 0 0;
676
+ text-align: center;
677
+ }
678
+
679
+ .kanban-column-body {
680
+ padding: 0.5rem;
681
+ min-height: 100px;
682
+ background: #ffffff;
683
+ border-radius: 0 0 8px 8px;
684
+ display: flex;
685
+ flex-direction: column;
686
+ gap: 0.5rem;
687
+ }
688
+
689
+ .kanban-card {
690
+ background: #ffffff;
691
+ border-radius: 4px;
692
+ padding: 1rem;
693
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
694
+ cursor: grab;
695
+ }
689
696
  </style>