vue-laravel-crud 2.0.5 → 2.0.7

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