vue-laravel-crud 2.0.6 → 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,719 +1,719 @@
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.loading,
118
- firstLoad: this.firstLoad,
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>
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
- }
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
+ }
719
719
  </style>