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,152 +1,154 @@
1
- <template>
2
- <div class="crud-header" v-if="showHeader">
3
- <h4 class="crud-title" v-if="showTitle">{{ title }}</h4>
4
-
5
- <b-sidebar :visible="sidebarVisible" @hidden="closeSidebar" title="Filtrar" right shadow>
6
- <CrudFilters />
7
- </b-sidebar>
8
-
9
- <div class="table-options">
10
- <b-button-group class="mr-1">
11
- <slot name="tableActions" v-bind:createItem="createItem" v-bind:toggleDisplayMode="toggleDisplayMode"
12
- v-bind:loading="loading">
13
- <slot name="tableActionsPrepend" v-bind:loading="loading"> </slot>
14
-
15
- <b-button variant="info" @click="showImportModal()" v-if="showImport">
16
- <b-icon-cloud-upload></b-icon-cloud-upload>{{ messageImport }}
17
- </b-button>
18
- <b-button variant="info" @click="showExportModal()" v-if="showExport">
19
- <b-icon-cloud-download></b-icon-cloud-download>{{ messageExport }}
20
- </b-button>
21
- <b-button variant="info" v-if="showPrincipalSortBtn" @click="togglePrincipalSort()" :disabled="loading">
22
- <b-icon-sort-numeric-down v-if="principalSort"></b-icon-sort-numeric-down>
23
- <b-icon-sort-numeric-up v-else></b-icon-sort-numeric-up>
24
- </b-button>
25
- <b-button variant="danger" @click="confirmBulkDelete()"
26
- v-if="bulkDelete"><b-icon-trash></b-icon-trash></b-button>
27
- <b-button variant="success" v-if="showCreateBtn" @click="createItem()" :disabled="loading">
28
- <b-icon-plus></b-icon-plus>{{ messageNew }}
29
- </b-button>
30
- <b-button variant="info" v-if="enableFilters" @click="toggleFilters()">Filtros</b-button>
31
- <b-button variant="info" @click="refresh()"><b-icon-arrow-clockwise></b-icon-arrow-clockwise></b-button>
32
- <b-button variant="info" @click="toggleDisplayMode()" :disabled="loading" v-if="displayModeToggler">
33
- <b-icon-card-list v-if="currentDisplayMode == displayModes.MODE_TABLE"></b-icon-card-list>
34
- <b-icon-table v-else-if="currentDisplayMode == displayModes.MODE_CARDS"></b-icon-table>
35
- </b-button>
36
-
37
- <div class="crud-search m-0" v-if="showSearch">
38
- <b-input-group>
39
- <b-input-group-prepend>
40
- <b-button variant="info" @click="displaySearch = !displaySearch"
41
- :class="{ open: displaySearch }"><b-icon-search></b-icon-search></b-button>
42
- </b-input-group-prepend>
43
- <b-form-input v-if="displaySearch" v-model="search" class="pl-2" type="search" required
44
- :placeholder="searchPlaceholder" debounce="500"></b-form-input>
45
- </b-input-group>
46
-
47
- <slot name="tableActionsAppend" v-bind:loading="loading"> </slot>
48
- </div>
49
- </slot>
50
- </b-button-group>
51
- </div>
52
- </div>
53
- </template>
54
-
55
- <script>
56
- import CrudFilters from './CrudFilters.vue';
57
-
58
- export default {
59
- name: 'CrudHeader',
60
- components: {
61
- CrudFilters
62
- },
63
- inject: [
64
- 'showHeader',
65
- 'showTitle',
66
- 'title',
67
- 'filterSidebarOpen',
68
- 'showImport',
69
- 'showExport',
70
- 'showPrincipalSortBtn',
71
- 'principalSort',
72
- 'bulkDelete',
73
- 'showCreateBtn',
74
- 'enableFilters',
75
- 'displayModeToggler',
76
- 'displayMode',
77
- 'displayModes',
78
- 'showSearch',
79
- 'displaySearch',
80
- 'search',
81
- 'searchPlaceholder',
82
- 'loading',
83
- 'messageImport',
84
- 'messageExport',
85
- 'messageNew',
86
- 'createItem',
87
- 'toggleDisplayMode',
88
- 'togglePrincipalSort',
89
- 'confirmBulkDelete',
90
- 'toggleFilters',
91
- 'refresh'
92
- ],
93
- computed: {
94
- sidebarVisible() {
95
- // Acceder directamente al componente padre para obtener reactividad
96
- return this.$parent ? this.$parent.filterSidebarOpen : this.filterSidebarOpen;
97
- },
98
- currentDisplayMode() {
99
- if (!this.displayMode) return 1;
100
- if (this.displayMode.value !== undefined) {
101
- return this.displayMode.value;
102
- }
103
- if (typeof this.displayMode === 'function') {
104
- return this.displayMode();
105
- }
106
- return this.displayMode;
107
- }
108
- },
109
- methods: {
110
- closeSidebar() {
111
- if (this.filterSidebarOpen) {
112
- this.toggleFilters();
113
- }
114
- }
115
- }
116
- };
117
- </script>
118
-
119
- <style scoped>
120
- .crud-header {
121
- display: flex;
122
- justify-content: space-between;
123
- max-height: 3rem;
124
- }
125
-
126
- .crud-title {
127
- margin: 0;
128
- }
129
-
130
- .crud-search {
131
- max-width: 15rem;
132
- }
133
-
134
- .crud-search .btn {
135
- border-top-left-radius: 0;
136
- border-bottom-left-radius: 0;
137
- border-top-right-radius: 0.375rem;
138
- border-bottom-right-radius: 0.375rem;
139
- }
140
-
141
- .crud-search .btn.open {
142
- border-top-right-radius: 0;
143
- border-bottom-right-radius: 0;
144
- }
145
-
146
- .table-options {
147
- margin-bottom: 1rem;
148
- display: flex;
149
- align-items: center;
150
- justify-content: flex-end;
151
- }
152
- </style>
1
+ <template>
2
+ <div class="crud-header" v-if="showHeader">
3
+ <h4 class="crud-title" v-if="showTitle">{{ title }}</h4>
4
+
5
+ <b-sidebar :visible="sidebarVisible" @hidden="closeSidebar" title="Filtrar" right shadow>
6
+ <CrudFilters />
7
+ </b-sidebar>
8
+
9
+ <div class="table-options">
10
+ <b-button-group class="mr-1">
11
+ <slot name="tableActions" v-bind:createItem="createItem" v-bind:toggleDisplayMode="toggleDisplayMode"
12
+ v-bind:loading="loading">
13
+ <slot name="tableActionsPrepend" v-bind:loading="loading"> </slot>
14
+
15
+ <b-button variant="info" @click="showImportModal()" v-if="showImport">
16
+ <b-icon-cloud-upload></b-icon-cloud-upload>{{ messageImport }}
17
+ </b-button>
18
+ <b-button variant="info" @click="showExportModal()" v-if="showExport">
19
+ <b-icon-cloud-download></b-icon-cloud-download>{{ messageExport }}
20
+ </b-button>
21
+ <b-button variant="info" v-if="showPrincipalSortBtn" @click="togglePrincipalSort()" :disabled="loading">
22
+ <b-icon-sort-numeric-down v-if="principalSort"></b-icon-sort-numeric-down>
23
+ <b-icon-sort-numeric-up v-else></b-icon-sort-numeric-up>
24
+ </b-button>
25
+ <b-button variant="danger" @click="confirmBulkDelete()"
26
+ v-if="bulkDelete"><b-icon-trash></b-icon-trash></b-button>
27
+ <b-button variant="success" v-if="showCreateBtn" @click="createItem()" :disabled="loading">
28
+ <b-icon-plus></b-icon-plus>{{ messageNew }}
29
+ </b-button>
30
+ <b-button variant="info" v-if="enableFilters" @click="toggleFilters()">Filtros</b-button>
31
+ <b-button variant="info" @click="refresh()"><b-icon-arrow-clockwise></b-icon-arrow-clockwise></b-button>
32
+ <b-button variant="info" @click="toggleDisplayMode()" :disabled="loading" v-if="displayModeToggler">
33
+ <b-icon-card-list v-if="currentDisplayMode == displayModes.MODE_TABLE"></b-icon-card-list>
34
+ <b-icon-table v-else-if="currentDisplayMode == displayModes.MODE_CARDS"></b-icon-table>
35
+ </b-button>
36
+
37
+ <div class="crud-search m-0" v-if="showSearch">
38
+ <b-input-group>
39
+ <b-input-group-prepend>
40
+ <b-button variant="info" @click="displaySearch = !displaySearch"
41
+ :class="{ open: displaySearch }"><b-icon-search></b-icon-search></b-button>
42
+ </b-input-group-prepend>
43
+ <b-form-input v-if="displaySearch" v-model="search" class="pl-2" type="search" required
44
+ :placeholder="searchPlaceholder" debounce="500"></b-form-input>
45
+ </b-input-group>
46
+
47
+ <slot name="tableActionsAppend" v-bind:loading="loading"> </slot>
48
+ </div>
49
+ </slot>
50
+ </b-button-group>
51
+ </div>
52
+ </div>
53
+ </template>
54
+
55
+ <script>
56
+ import CrudFilters from './CrudFilters.vue';
57
+
58
+ export default {
59
+ name: 'CrudHeader',
60
+ components: {
61
+ CrudFilters
62
+ },
63
+ inject: [
64
+ 'showHeader',
65
+ 'showTitle',
66
+ 'title',
67
+ 'filterSidebarOpen',
68
+ 'showImport',
69
+ 'showExport',
70
+ 'showPrincipalSortBtn',
71
+ 'principalSort',
72
+ 'bulkDelete',
73
+ 'showCreateBtn',
74
+ 'enableFilters',
75
+ 'displayModeToggler',
76
+ 'displayMode',
77
+ 'displayModes',
78
+ 'showSearch',
79
+ 'displaySearch',
80
+ 'search',
81
+ 'searchPlaceholder',
82
+ 'loading',
83
+ 'messageImport',
84
+ 'messageExport',
85
+ 'messageNew',
86
+ 'createItem',
87
+ 'toggleDisplayMode',
88
+ 'togglePrincipalSort',
89
+ 'confirmBulkDelete',
90
+ 'toggleFilters',
91
+ 'refresh',
92
+ 'showImportModal',
93
+ 'showExportModal'
94
+ ],
95
+ computed: {
96
+ sidebarVisible() {
97
+ // Acceder directamente al componente padre para obtener reactividad
98
+ return this.$parent ? this.$parent.filterSidebarOpen : this.filterSidebarOpen;
99
+ },
100
+ currentDisplayMode() {
101
+ if (!this.displayMode) return 1;
102
+ if (this.displayMode.value !== undefined) {
103
+ return this.displayMode.value;
104
+ }
105
+ if (typeof this.displayMode === 'function') {
106
+ return this.displayMode();
107
+ }
108
+ return this.displayMode;
109
+ }
110
+ },
111
+ methods: {
112
+ closeSidebar() {
113
+ if (this.filterSidebarOpen) {
114
+ this.toggleFilters();
115
+ }
116
+ }
117
+ }
118
+ };
119
+ </script>
120
+
121
+ <style scoped>
122
+ .crud-header {
123
+ display: flex;
124
+ justify-content: space-between;
125
+ max-height: 3rem;
126
+ }
127
+
128
+ .crud-title {
129
+ margin: 0;
130
+ }
131
+
132
+ .crud-search {
133
+ max-width: 15rem;
134
+ }
135
+
136
+ .crud-search .btn {
137
+ border-top-left-radius: 0;
138
+ border-bottom-left-radius: 0;
139
+ border-top-right-radius: 0.375rem;
140
+ border-bottom-right-radius: 0.375rem;
141
+ }
142
+
143
+ .crud-search .btn.open {
144
+ border-top-right-radius: 0;
145
+ border-bottom-right-radius: 0;
146
+ }
147
+
148
+ .table-options {
149
+ margin-bottom: 1rem;
150
+ display: flex;
151
+ align-items: center;
152
+ justify-content: flex-end;
153
+ }
154
+ </style>
@@ -1,36 +1,36 @@
1
- <template>
2
- <div v-if="currentDisplayMode == displayModes.MODE_KANBAN">
3
- <KanbanBoard>
4
- <template v-for="(slot, name) in $scopedSlots" v-slot:[name]="slotProps">
5
- <slot :name="name" v-bind="slotProps" />
6
- </template>
7
- </KanbanBoard>
8
- </div>
9
- </template>
10
-
11
- <script>
12
- import KanbanBoard from './kanban/KanbanBoard.vue';
13
-
14
- export default {
15
- name: 'CrudKanban',
16
- components: {
17
- KanbanBoard
18
- },
19
- inject: [
20
- 'displayMode',
21
- 'displayModes'
22
- ],
23
- computed: {
24
- currentDisplayMode() {
25
- if (!this.displayMode) return 1;
26
- if (this.displayMode.value !== undefined) {
27
- return this.displayMode.value;
28
- }
29
- if (typeof this.displayMode === 'function') {
30
- return this.displayMode();
31
- }
32
- return this.displayMode;
33
- }
34
- }
35
- };
36
- </script>
1
+ <template>
2
+ <div v-if="currentDisplayMode == displayModes.MODE_KANBAN">
3
+ <KanbanBoard>
4
+ <template v-for="(slot, name) in $scopedSlots" v-slot:[name]="slotProps">
5
+ <slot :name="name" v-bind="slotProps" />
6
+ </template>
7
+ </KanbanBoard>
8
+ </div>
9
+ </template>
10
+
11
+ <script>
12
+ import KanbanBoard from './kanban/KanbanBoard.vue';
13
+
14
+ export default {
15
+ name: 'CrudKanban',
16
+ components: {
17
+ KanbanBoard
18
+ },
19
+ inject: [
20
+ 'displayMode',
21
+ 'displayModes'
22
+ ],
23
+ computed: {
24
+ currentDisplayMode() {
25
+ if (!this.displayMode) return 1;
26
+ if (this.displayMode.value !== undefined) {
27
+ return this.displayMode.value;
28
+ }
29
+ if (typeof this.displayMode === 'function') {
30
+ return this.displayMode();
31
+ }
32
+ return this.displayMode;
33
+ }
34
+ }
35
+ };
36
+ </script>
@@ -72,10 +72,26 @@
72
72
  <p v-if="selectedItems.length">Se exportará {{ selectedItems.length }} elementos.</p>
73
73
  <p v-else>Se exportará la consulta actual.</p>
74
74
 
75
- <select class="form-control" v-model="exportFormat">
76
- <option value="JSON">JSON</option>
77
- <option value="XLSX">XLSX</option>
78
- </select>
75
+ <b-form-group label="Seleccione el formato de exportación:" class="mt-3">
76
+ <div class="export-format-options">
77
+ <b-form-radio
78
+ v-model="exportFormat"
79
+ value="JSON"
80
+ class="export-format-radio"
81
+ >
82
+ <b-icon-file-text class="mr-2"></b-icon-file-text>
83
+ JSON
84
+ </b-form-radio>
85
+ <b-form-radio
86
+ v-model="exportFormat"
87
+ value="XLSX"
88
+ class="export-format-radio"
89
+ >
90
+ <b-icon-table class="mr-2"></b-icon-table>
91
+ XLSX
92
+ </b-form-radio>
93
+ </div>
94
+ </b-form-group>
79
95
 
80
96
  <div class="text-center mt-3">
81
97
  <b-button variant="info" v-on:click="exportItems()" :disabled="loading">
@@ -132,3 +148,66 @@ export default {
132
148
  }
133
149
  };
134
150
  </script>
151
+
152
+ <style scoped>
153
+ .export-format-options {
154
+ display: flex;
155
+ gap: 1rem;
156
+ justify-content: center;
157
+ flex-wrap: wrap;
158
+ }
159
+
160
+ .export-format-radio {
161
+ flex: 1;
162
+ min-width: 150px;
163
+ padding: 1rem;
164
+ border: 2px solid #dee2e6;
165
+ border-radius: 0.5rem;
166
+ cursor: pointer;
167
+ transition: all 0.3s ease;
168
+ text-align: center;
169
+ display: flex;
170
+ align-items: center;
171
+ justify-content: center;
172
+ background-color: #fff;
173
+ }
174
+
175
+ .export-format-radio:hover {
176
+ border-color: #007bff;
177
+ background-color: #f8f9fa;
178
+ transform: translateY(-2px);
179
+ box-shadow: 0 2px 8px rgba(0, 123, 255, 0.2);
180
+ }
181
+
182
+ .export-format-radio >>> .custom-control-input:checked ~ .custom-control-label {
183
+ color: #007bff;
184
+ font-weight: 600;
185
+ }
186
+
187
+ .export-format-radio >>> .custom-control-input:checked ~ .custom-control-label::before {
188
+ border-color: #007bff;
189
+ background-color: #007bff;
190
+ }
191
+
192
+ .export-format-radio >>> .custom-control-label {
193
+ display: flex;
194
+ align-items: center;
195
+ justify-content: center;
196
+ width: 100%;
197
+ cursor: pointer;
198
+ font-size: 1rem;
199
+ }
200
+
201
+ .export-format-radio >>> .custom-control-label::before {
202
+ margin-right: 0.5rem;
203
+ }
204
+
205
+ .export-format-radio >>> svg {
206
+ font-size: 1.5rem;
207
+ color: #495057;
208
+ }
209
+
210
+ .export-format-radio >>> .custom-control-input:checked ~ .custom-control-label svg {
211
+ color: #007bff;
212
+ }
213
+ </style>