vue-laravel-crud 2.0.1 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +344 -148
- package/dist/vue-laravel-crud.esm.js +363 -124
- package/dist/vue-laravel-crud.min.js +3 -3
- package/dist/vue-laravel-crud.ssr.js +402 -143
- package/package.json +4 -2
- package/src/components/CrudPagination.vue +87 -20
- package/src/components/table/TableCell.vue +52 -2
- package/src/components/table/TableHeader.vue +26 -5
- package/src/vue-laravel-crud.vue +695 -688
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vue-laravel-crud",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "",
|
|
6
6
|
"homepage": "https://github.com/clonixdev/vue-laravel-crud",
|
|
@@ -21,7 +21,9 @@
|
|
|
21
21
|
"build": "cross-env NODE_ENV=production rollup --config build/rollup.config.js",
|
|
22
22
|
"build:ssr": "cross-env NODE_ENV=production rollup --config build/rollup.config.js --format cjs",
|
|
23
23
|
"build:es": "cross-env NODE_ENV=production rollup --config build/rollup.config.js --format es",
|
|
24
|
-
"build:unpkg": "cross-env NODE_ENV=production rollup --config build/rollup.config.js --format iife"
|
|
24
|
+
"build:unpkg": "cross-env NODE_ENV=production rollup --config build/rollup.config.js --format iife",
|
|
25
|
+
"build:demo": "cross-env NODE_ENV=production vue-cli-service build --mode production dev/demo/main.js",
|
|
26
|
+
"build:gh-pages": "npm run build:demo"
|
|
25
27
|
},
|
|
26
28
|
"dependencies": {
|
|
27
29
|
"axios": "^1.3.5",
|
|
@@ -26,18 +26,33 @@
|
|
|
26
26
|
<span class="paginator-label">Filas:</span>
|
|
27
27
|
<span class="paginator-value">{{ pagination.total }}</span>
|
|
28
28
|
</span>
|
|
29
|
-
<
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
29
|
+
<b-dropdown
|
|
30
|
+
variant="outline-secondary"
|
|
31
|
+
size="sm"
|
|
32
|
+
class="paginator-dropdown"
|
|
33
|
+
:text="`xPág: ${pagination.per_page}`"
|
|
34
|
+
>
|
|
35
|
+
<b-dropdown-item
|
|
36
|
+
v-for="option in perPageOptions"
|
|
37
|
+
:key="option"
|
|
38
|
+
@click="onPerPageChange(option)"
|
|
39
|
+
:active="pagination.per_page === option"
|
|
40
|
+
>
|
|
41
|
+
{{ option }}
|
|
42
|
+
</b-dropdown-item>
|
|
43
|
+
</b-dropdown>
|
|
44
|
+
<b-dropdown
|
|
45
|
+
v-if="selectedItemsCount > 0"
|
|
46
|
+
variant="outline-secondary"
|
|
47
|
+
size="sm"
|
|
48
|
+
class="paginator-dropdown paginator-badge-dropdown"
|
|
49
|
+
:text="`Seleccionados: ${selectedItemsCount}`"
|
|
50
|
+
>
|
|
51
|
+
<b-dropdown-item @click="clearSelection">
|
|
52
|
+
<b-icon-x-circle class="mr-1"></b-icon-x-circle>
|
|
53
|
+
Limpiar selección
|
|
54
|
+
</b-dropdown-item>
|
|
55
|
+
</b-dropdown>
|
|
41
56
|
</div>
|
|
42
57
|
|
|
43
58
|
<div class="crud-paginator">
|
|
@@ -73,28 +88,42 @@ export default {
|
|
|
73
88
|
'selectedItems',
|
|
74
89
|
'showPaginator',
|
|
75
90
|
'infiniteHandler',
|
|
76
|
-
'onPaginationChange'
|
|
77
|
-
|
|
91
|
+
'onPaginationChange',
|
|
92
|
+
'onPerPageChange',
|
|
93
|
+
'clearSelection'
|
|
94
|
+
],
|
|
95
|
+
data() {
|
|
96
|
+
return {
|
|
97
|
+
perPageOptions: [10, 20, 50, 100]
|
|
98
|
+
};
|
|
99
|
+
},
|
|
100
|
+
computed: {
|
|
101
|
+
selectedItemsCount() {
|
|
102
|
+
// Computed para forzar reactividad del contador
|
|
103
|
+
return this.selectedItems ? this.selectedItems.length : 0;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
78
106
|
};
|
|
79
107
|
</script>
|
|
80
108
|
|
|
81
109
|
<style scoped>
|
|
82
110
|
.paginator-container {
|
|
83
|
-
display:
|
|
84
|
-
|
|
111
|
+
display: grid;
|
|
112
|
+
grid-template-columns: 1fr auto 1fr;
|
|
85
113
|
align-items: center;
|
|
86
114
|
width: 100%;
|
|
87
115
|
margin-top: 1rem;
|
|
88
|
-
gap:
|
|
116
|
+
gap: 1rem;
|
|
89
117
|
}
|
|
90
118
|
|
|
91
119
|
.paginator-data {
|
|
92
120
|
display: flex;
|
|
93
|
-
flex-wrap:
|
|
94
|
-
justify-content:
|
|
121
|
+
flex-wrap: nowrap;
|
|
122
|
+
justify-content: flex-start;
|
|
95
123
|
align-items: center;
|
|
96
124
|
gap: 0.5rem;
|
|
97
125
|
font-size: 0.875rem;
|
|
126
|
+
grid-column: 1;
|
|
98
127
|
}
|
|
99
128
|
|
|
100
129
|
.paginator-badge {
|
|
@@ -124,10 +153,48 @@ export default {
|
|
|
124
153
|
color: #212529;
|
|
125
154
|
}
|
|
126
155
|
|
|
156
|
+
.paginator-dropdown {
|
|
157
|
+
font-size: 0.875rem;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.paginator-dropdown >>> .btn {
|
|
161
|
+
padding: 0.375rem 0.625rem;
|
|
162
|
+
font-size: 0.875rem;
|
|
163
|
+
background-color: #f8f9fa;
|
|
164
|
+
border: 1px solid #dee2e6;
|
|
165
|
+
color: #495057;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.paginator-dropdown >>> .btn:hover {
|
|
169
|
+
background-color: #e9ecef;
|
|
170
|
+
border-color: #ced4da;
|
|
171
|
+
}
|
|
172
|
+
|
|
127
173
|
.crud-paginator {
|
|
128
174
|
display: flex;
|
|
129
175
|
justify-content: center;
|
|
130
176
|
align-items: center;
|
|
131
|
-
|
|
177
|
+
grid-column: 2;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.paginator-badge-dropdown {
|
|
181
|
+
z-index: 1;
|
|
182
|
+
position: relative;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.paginator-badge-dropdown >>> .btn {
|
|
186
|
+
padding: 0.375rem 0.625rem;
|
|
187
|
+
font-size: 0.875rem;
|
|
188
|
+
background-color: #f8f9fa;
|
|
189
|
+
border: 1px solid #dee2e6;
|
|
190
|
+
color: #495057;
|
|
191
|
+
display: inline-flex;
|
|
192
|
+
align-items: center;
|
|
193
|
+
gap: 0.25rem;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.paginator-badge-dropdown >>> .btn:hover {
|
|
197
|
+
background-color: #e9ecef;
|
|
198
|
+
border-color: #ced4da;
|
|
132
199
|
}
|
|
133
200
|
</style>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<td :scope="column.prop == 'id' ? 'row' : ''"
|
|
2
|
+
<td :scope="column.prop == 'id' ? 'row' : ''"
|
|
3
|
+
:class="{ 'actions-cell': column.type == 'actions' }">
|
|
3
4
|
<slot :name="'cell-' + column.prop" v-bind:item="item" v-bind:index="index" v-bind:itemindex="index"
|
|
4
5
|
v-bind:columnindex="columnIndex">
|
|
5
6
|
<span v-if="column.type == 'boolean'">
|
|
@@ -25,6 +26,10 @@
|
|
|
25
26
|
<b-form-checkbox v-model="item.selected" @change="onCheckSelect($event, item)">
|
|
26
27
|
</b-form-checkbox>
|
|
27
28
|
</span>
|
|
29
|
+
<span v-else-if="column.type == 'checkbox'">
|
|
30
|
+
<b-form-checkbox v-model="item.selected" @change="onCheckSelect($event, item)">
|
|
31
|
+
</b-form-checkbox>
|
|
32
|
+
</span>
|
|
28
33
|
<span v-else-if="column.type == 'state' && optionsLoaded">
|
|
29
34
|
{{
|
|
30
35
|
getStateValue(itemValue(column, item), column.options)
|
|
@@ -44,7 +49,30 @@
|
|
|
44
49
|
</span>
|
|
45
50
|
</slot>
|
|
46
51
|
|
|
47
|
-
|
|
52
|
+
<!-- Modo dropdown cuando useDropdown está activo -->
|
|
53
|
+
<b-dropdown v-if="column.type == 'actions' && column.useDropdown"
|
|
54
|
+
variant="secondary"
|
|
55
|
+
size="sm"
|
|
56
|
+
class="actions-dropdown">
|
|
57
|
+
<template #button-content>
|
|
58
|
+
<b-icon-list></b-icon-list>
|
|
59
|
+
</template>
|
|
60
|
+
<slot name="rowAction" v-bind:item="item" v-bind:index="index" v-bind:showItem="showItem"
|
|
61
|
+
v-bind:updateItem="updateItem" v-bind:removeItem="removeItem">
|
|
62
|
+
<b-dropdown-item @click="showItem(item.id, index)">
|
|
63
|
+
<b-icon-eye></b-icon-eye> Ver
|
|
64
|
+
</b-dropdown-item>
|
|
65
|
+
<b-dropdown-item @click="updateItem(item.id, index)">
|
|
66
|
+
<b-icon-pencil></b-icon-pencil> Editar
|
|
67
|
+
</b-dropdown-item>
|
|
68
|
+
<b-dropdown-item @click="removeItem(item.id, index)" class="text-danger">
|
|
69
|
+
<b-icon-trash></b-icon-trash> Eliminar
|
|
70
|
+
</b-dropdown-item>
|
|
71
|
+
</slot>
|
|
72
|
+
</b-dropdown>
|
|
73
|
+
|
|
74
|
+
<!-- Modo botones normal (comportamiento original) -->
|
|
75
|
+
<b-button-group v-else-if="column.type == 'actions'" class="actions-button-group">
|
|
48
76
|
<slot name="rowAction" v-bind:item="item" v-bind:index="index" v-bind:showItem="showItem"
|
|
49
77
|
v-bind:updateItem="updateItem" v-bind:removeItem="removeItem">
|
|
50
78
|
<b-button variant="primary" @click="showItem(item.id, index)">
|
|
@@ -89,3 +117,25 @@ export default {
|
|
|
89
117
|
}
|
|
90
118
|
};
|
|
91
119
|
</script>
|
|
120
|
+
|
|
121
|
+
<style scoped>
|
|
122
|
+
/* Fijar ancho de la columna de acciones */
|
|
123
|
+
.actions-cell {
|
|
124
|
+
width: 1%;
|
|
125
|
+
white-space: nowrap;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.actions-button-group {
|
|
129
|
+
display: inline-flex;
|
|
130
|
+
flex-wrap: nowrap;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.actions-dropdown {
|
|
134
|
+
display: inline-block;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/* Asegurar que los botones no se expandan */
|
|
138
|
+
.actions-button-group .btn {
|
|
139
|
+
flex-shrink: 0;
|
|
140
|
+
}
|
|
141
|
+
</style>
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
<tr>
|
|
4
4
|
<slot name="rowHead">
|
|
5
5
|
<th v-for="(column, indexc) in columns" :key="indexc"
|
|
6
|
-
:style="{ width: column.width ? column.width : 'inherit' }"
|
|
6
|
+
:style="{ width: column.width ? column.width : (column.type == 'actions' ? '1%' : 'inherit') }"
|
|
7
|
+
:class="{ 'actions-header': column.type == 'actions' }"
|
|
8
|
+
scope="col"
|
|
7
9
|
@mouseenter="hoveredColumn = column.prop"
|
|
8
10
|
@mouseleave="hoveredColumn = null">
|
|
9
11
|
<slot :name="'filter-' + column.prop" v-bind:column="column" v-bind:filter="filter"
|
|
@@ -65,10 +67,13 @@
|
|
|
65
67
|
</select>
|
|
66
68
|
|
|
67
69
|
<b-form-checkbox v-else-if="column.type == 'checkbox'" name="select-all"
|
|
68
|
-
|
|
70
|
+
:checked="isAllSelected"
|
|
71
|
+
@change="toggleAll">
|
|
69
72
|
</b-form-checkbox>
|
|
70
73
|
|
|
71
|
-
<b-form-checkbox v-else-if="column.type == 'select'" name="select-all"
|
|
74
|
+
<b-form-checkbox v-else-if="column.type == 'select'" name="select-all"
|
|
75
|
+
:checked="isAllSelected"
|
|
76
|
+
@change="toggleAll">
|
|
72
77
|
</b-form-checkbox>
|
|
73
78
|
|
|
74
79
|
<input v-else class="form-control form-control-md p-2"
|
|
@@ -78,7 +83,14 @@
|
|
|
78
83
|
</div>
|
|
79
84
|
</slot>
|
|
80
85
|
<span v-else-if="column.type == 'select'">
|
|
81
|
-
<b-form-checkbox name="select-all"
|
|
86
|
+
<b-form-checkbox name="select-all"
|
|
87
|
+
:checked="isAllSelected"
|
|
88
|
+
@change="toggleAll"></b-form-checkbox>
|
|
89
|
+
</span>
|
|
90
|
+
<span v-else-if="column.type == 'checkbox'">
|
|
91
|
+
<b-form-checkbox name="select-all"
|
|
92
|
+
:checked="isAllSelected"
|
|
93
|
+
@change="toggleAll"></b-form-checkbox>
|
|
82
94
|
</span>
|
|
83
95
|
<span v-else>{{ column.label }}</span>
|
|
84
96
|
|
|
@@ -109,7 +121,8 @@ export default {
|
|
|
109
121
|
'toggleAll',
|
|
110
122
|
'toggleSortFilter',
|
|
111
123
|
'sortable',
|
|
112
|
-
'optionsLoaded'
|
|
124
|
+
'optionsLoaded',
|
|
125
|
+
'isAllSelected'
|
|
113
126
|
],
|
|
114
127
|
data() {
|
|
115
128
|
return {
|
|
@@ -143,3 +156,11 @@ export default {
|
|
|
143
156
|
}
|
|
144
157
|
};
|
|
145
158
|
</script>
|
|
159
|
+
|
|
160
|
+
<style scoped>
|
|
161
|
+
/* Fijar ancho de la columna de acciones en el header */
|
|
162
|
+
.actions-header {
|
|
163
|
+
width: 1%;
|
|
164
|
+
white-space: nowrap;
|
|
165
|
+
}
|
|
166
|
+
</style>
|