vue-laravel-crud 2.0.1 → 2.0.5

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,698 @@
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
+ 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
+ }
689
698
  </style>