vue-laravel-crud 2.0.5 → 2.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,167 +1,319 @@
1
- <template>
2
- <div class="px-3 py-2">
3
- <div v-for="(column, indexc) in columns" :key="indexc">
4
- <div v-if="isColumnHasFilter(column)">
5
- <slot :name="'sidebar-filter-' + column.prop" v-bind:column="column" v-bind:filter="filter"
6
- v-bind:internalFilterByProp="internalFilterByProp" v-bind:getFilterForColumn="getFilterForColumn">
7
- <div class="form-group" v-if="column.type == 'boolean'">
8
- <label>{{ column.label }}</label>
9
-
10
- <select class="form-control" v-model="getFilterForColumn(column).value"
11
- @change="onChangeFilter($event)">
12
- <option value=""></option>
13
- <option value="1">Sí</option>
14
- <option value="0">No</option>
15
- </select>
16
- </div>
17
- <div class="form-group" v-else-if="column.type == 'date'">
18
- <div class="row">
19
- <div class="col-6">
20
- <b-form-datepicker v-model="getFilterForDateFrom(column).value
21
- " today-button reset-button close-button locale="es"></b-form-datepicker>
22
- </div>
23
- <div class="col-6">
24
- <b-form-datepicker v-model="getFilterForDateTo(column).value
25
- " today-button reset-button close-button locale="es"></b-form-datepicker>
26
- </div>
27
- </div>
28
- </div>
29
-
30
- <div class="form-group" v-else-if="column.type == 'number' || column.type == 'money'">
31
- <label>{{ column.label }}</label>
32
- <div class="row">
33
- <div class="col-6">
34
- <input
35
- type="number"
36
- class="form-control"
37
- v-model.number="getFilterForDateFrom(column).value"
38
- :step="column.type == 'money' ? '0.01' : '1'"
39
- @change="onChangeFilter($event)"
40
- placeholder="Desde" />
41
- </div>
42
- <div class="col-6">
43
- <input
44
- type="number"
45
- class="form-control"
46
- v-model.number="getFilterForDateTo(column).value"
47
- :step="column.type == 'money' ? '0.01' : '1'"
48
- @change="onChangeFilter($event)"
49
- placeholder="Hasta" />
50
- </div>
51
- </div>
52
- </div>
53
-
54
- <div class="form-group" v-else-if="column.type == 'state'">
55
- <label>{{ column.label }}</label>
56
-
57
- <select class="form-control" v-model="getFilterForColumn(column).value"
58
- @change="onChangeFilter($event)" v-if="column.options && Array.isArray(column.options)">
59
- <option value=""></option>
60
- <option :value="option.value" v-for="option in column.options"
61
- :key="option.value || option.id">
62
- {{ option.text }}
63
- </option>
64
- </select>
65
- </div>
66
-
67
- <div class="form-group" v-else-if="column.type == 'array'">
68
- <label>{{ column.label }}</label>
69
-
70
- <select class="form-control" v-model="getFilterForColumn(column).value"
71
- @change="onChangeFilter($event)" v-if="column.options && Array.isArray(column.options)">
72
- <option value=""></option>
73
- <option :value="option.value" v-for="option in column.options"
74
- :key="option.value || option.id">
75
- {{ option.text }}
76
- </option>
77
- </select>
78
- </div>
79
-
80
- <div class="form-group" v-else>
81
- <label>{{ column.label }}</label>
82
-
83
- <input class="form-control" v-model.lazy="getFilterForColumn(column).value"
84
- @change="onChangeFilter($event)" />
85
- </div>
86
- </slot>
87
- </div>
88
- </div>
89
-
90
- <div class="mt-3 d-flex justify-content-center">
91
- <button class="btn btn-light" @click="resetFilters()">
92
- Reset
93
- </button>
94
- <button class="btn btn-info" @click="onChangeFilter($event)">
95
- Filtrar
96
- </button>
97
- </div>
98
- </div>
99
- </template>
100
-
101
- <script>
102
- export default {
103
- name: 'CrudFilters',
104
- inject: [
105
- 'columns',
106
- 'isColumnHasFilter',
107
- 'filter',
108
- 'internalFilterByProp',
109
- 'optionsLoaded',
110
- 'onChangeFilter',
111
- 'resetFilters',
112
- 'setupFilters',
113
- 'internalFilters'
114
- ],
115
- methods: {
116
- // Método helper para obtener el filtro de forma segura, creándolo si no existe
117
- getFilterForColumn(column) {
118
- let filter = this.internalFilterByProp(column.prop);
119
-
120
- // Si el filtro no existe, intentar inicializar los filtros
121
- if (!filter) {
122
- // Verificar si hay filtros inicializados
123
- if (this.internalFilters && this.internalFilters.length === 0) {
124
- this.setupFilters();
125
- // Intentar obtener el filtro nuevamente después de inicializar
126
- filter = this.internalFilterByProp(column.prop);
127
- }
128
- }
129
-
130
- // Si aún no existe, crear un objeto temporal para evitar errores
131
- if (!filter) {
132
- return {
133
- value: null
134
- };
135
- }
136
-
137
- return filter;
138
- },
139
-
140
- // Método helper específico para campos de fecha (from)
141
- getFilterForDateFrom(column) {
142
- const filter = this.internalFilterByProp(column.prop + '_from');
143
- if (!filter) {
144
- if (this.internalFilters && this.internalFilters.length === 0) {
145
- this.setupFilters();
146
- return this.internalFilterByProp(column.prop + '_from') || { value: null };
147
- }
148
- return { value: null };
149
- }
150
- return filter;
151
- },
152
-
153
- // Método helper específico para campos de fecha (to)
154
- getFilterForDateTo(column) {
155
- const filter = this.internalFilterByProp(column.prop + '_to');
156
- if (!filter) {
157
- if (this.internalFilters && this.internalFilters.length === 0) {
158
- this.setupFilters();
159
- return this.internalFilterByProp(column.prop + '_to') || { value: null };
160
- }
161
- return { value: null };
162
- }
163
- return filter;
164
- }
165
- }
166
- };
167
- </script>
1
+ <template>
2
+ <div class="px-3 py-2">
3
+ <div v-for="(column, indexc) in columns" :key="indexc">
4
+ <div v-if="isColumnHasFilter(column)">
5
+ <slot :name="'sidebar-filter-' + column.prop" v-bind:column="column" v-bind:filter="filter"
6
+ v-bind:internalFilterByProp="internalFilterByProp" v-bind:getFilterForColumn="getFilterForColumn">
7
+ <div class="form-group" v-if="column.type == 'boolean'">
8
+ <label>{{ column.label }}</label>
9
+
10
+ <select class="form-control" v-model="getFilterForColumn(column).value"
11
+ @change="onChangeFilter($event)">
12
+ <option value=""></option>
13
+ <option value="1">Sí</option>
14
+ <option value="0">No</option>
15
+ </select>
16
+ </div>
17
+ <div class="form-group" v-else-if="column.type == 'date'">
18
+ <div class="row">
19
+ <div class="col-6">
20
+ <b-form-datepicker v-model="getFilterForDateFrom(column).value
21
+ " today-button reset-button close-button locale="es"></b-form-datepicker>
22
+ </div>
23
+ <div class="col-6">
24
+ <b-form-datepicker v-model="getFilterForDateTo(column).value
25
+ " today-button reset-button close-button locale="es"></b-form-datepicker>
26
+ </div>
27
+ </div>
28
+ </div>
29
+
30
+ <div class="form-group" v-else-if="column.type == 'number' || column.type == 'money'">
31
+ <label>{{ column.label }}</label>
32
+ <div class="row">
33
+ <div class="col-6">
34
+ <input
35
+ type="number"
36
+ class="form-control"
37
+ v-model.number="getFilterForDateFrom(column).value"
38
+ :step="column.type == 'money' ? '0.01' : '1'"
39
+ @change="onChangeFilter($event)"
40
+ placeholder="Desde" />
41
+ </div>
42
+ <div class="col-6">
43
+ <input
44
+ type="number"
45
+ class="form-control"
46
+ v-model.number="getFilterForDateTo(column).value"
47
+ :step="column.type == 'money' ? '0.01' : '1'"
48
+ @change="onChangeFilter($event)"
49
+ placeholder="Hasta" />
50
+ </div>
51
+ </div>
52
+ </div>
53
+
54
+ <div class="form-group" v-else-if="column.type == 'state'">
55
+ <label>{{ column.label }}</label>
56
+
57
+ <select class="form-control" v-model="getFilterForColumn(column).value"
58
+ @change="onChangeFilter($event)" v-if="column.options && Array.isArray(column.options)">
59
+ <option value=""></option>
60
+ <option :value="option.value" v-for="option in column.options"
61
+ :key="option.value || option.id">
62
+ {{ option.text }}
63
+ </option>
64
+ </select>
65
+ </div>
66
+
67
+ <div class="form-group" v-else-if="column.type == 'array'">
68
+ <label>{{ column.label }}</label>
69
+
70
+ <select class="form-control" v-model="getFilterForColumn(column).value"
71
+ @change="onChangeFilter($event)" v-if="column.options && Array.isArray(column.options)">
72
+ <option value=""></option>
73
+ <option :value="option.value" v-for="option in column.options"
74
+ :key="option.value || option.id">
75
+ {{ option.text }}
76
+ </option>
77
+ </select>
78
+ </div>
79
+
80
+ <div class="form-group" v-else>
81
+ <label>{{ column.label }}</label>
82
+
83
+ <input class="form-control" v-model.lazy="getFilterForColumn(column).value"
84
+ @change="onChangeFilter($event)" />
85
+ </div>
86
+ </slot>
87
+ </div>
88
+ </div>
89
+
90
+ <!-- Filtros custom -->
91
+ <div v-for="(customFilter, indexcf) in customFilters" :key="'custom-' + indexcf">
92
+ <div v-if="isCustomFilterEnabled(customFilter)">
93
+ <!-- Slot personalizado para filtro custom -->
94
+ <slot :name="'sidebar-filter-custom-' + customFilter.prop" v-bind:column="customFilter" v-bind:filter="filter"
95
+ v-bind:internalFilterByProp="internalFilterByProp" v-bind:getFilterForColumn="getFilterForColumn">
96
+
97
+ <!-- Si type es una función callback -->
98
+ <RenderCustomFilter
99
+ v-if="typeof customFilter.type === 'function'"
100
+ :render-function="customFilter.type"
101
+ :custom-filter="customFilter"
102
+ :filter="filter"
103
+ :internal-filter-by-prop="internalFilterByProp"
104
+ :get-filter-for-column="getFilterForColumn"
105
+ :on-change-filter="onChangeFilter"
106
+ />
107
+
108
+ <!-- Si type es string, usar la misma lógica que las columnas -->
109
+ <template v-else>
110
+ <div class="form-group" v-if="customFilter.type == 'boolean'">
111
+ <label>{{ customFilter.label }}</label>
112
+
113
+ <select class="form-control" v-model="getFilterForColumn(customFilter).value"
114
+ @change="onChangeFilter($event)">
115
+ <option value=""></option>
116
+ <option value="1">Sí</option>
117
+ <option value="0">No</option>
118
+ </select>
119
+ </div>
120
+
121
+ <div class="form-group" v-else-if="customFilter.type == 'date'">
122
+ <label>{{ customFilter.label }}</label>
123
+ <div class="row">
124
+ <div class="col-6">
125
+ <b-form-datepicker v-model="getFilterForDateFrom(customFilter).value
126
+ " today-button reset-button close-button locale="es"></b-form-datepicker>
127
+ </div>
128
+ <div class="col-6">
129
+ <b-form-datepicker v-model="getFilterForDateTo(customFilter).value
130
+ " today-button reset-button close-button locale="es"></b-form-datepicker>
131
+ </div>
132
+ </div>
133
+ </div>
134
+
135
+ <div class="form-group" v-else-if="customFilter.type == 'number' || customFilter.type == 'money'">
136
+ <label>{{ customFilter.label }}</label>
137
+ <div class="row">
138
+ <div class="col-6">
139
+ <input
140
+ type="number"
141
+ class="form-control"
142
+ v-model.number="getFilterForDateFrom(customFilter).value"
143
+ :step="customFilter.type == 'money' ? '0.01' : '1'"
144
+ @change="onChangeFilter($event)"
145
+ placeholder="Desde" />
146
+ </div>
147
+ <div class="col-6">
148
+ <input
149
+ type="number"
150
+ class="form-control"
151
+ v-model.number="getFilterForDateTo(customFilter).value"
152
+ :step="customFilter.type == 'money' ? '0.01' : '1'"
153
+ @change="onChangeFilter($event)"
154
+ placeholder="Hasta" />
155
+ </div>
156
+ </div>
157
+ </div>
158
+
159
+ <div class="form-group" v-else-if="customFilter.type == 'state'">
160
+ <label>{{ customFilter.label }}</label>
161
+
162
+ <select class="form-control" v-model="getFilterForColumn(customFilter).value"
163
+ @change="onChangeFilter($event)" v-if="customFilter.options && Array.isArray(customFilter.options)">
164
+ <option value=""></option>
165
+ <option :value="option.value" v-for="option in customFilter.options"
166
+ :key="option.value || option.id">
167
+ {{ option.text }}
168
+ </option>
169
+ </select>
170
+ </div>
171
+
172
+ <div class="form-group" v-else-if="customFilter.type == 'array'">
173
+ <label>{{ customFilter.label }}</label>
174
+
175
+ <select class="form-control" v-model="getFilterForColumn(customFilter).value"
176
+ @change="onChangeFilter($event)" v-if="customFilter.options && Array.isArray(customFilter.options)">
177
+ <option value=""></option>
178
+ <option :value="option.value" v-for="option in customFilter.options"
179
+ :key="option.value || option.id">
180
+ {{ option.text }}
181
+ </option>
182
+ </select>
183
+ </div>
184
+
185
+ <div class="form-group" v-else>
186
+ <label>{{ customFilter.label }}</label>
187
+
188
+ <input class="form-control" v-model.lazy="getFilterForColumn(customFilter).value"
189
+ @change="onChangeFilter($event)" />
190
+ </div>
191
+ </template>
192
+ </slot>
193
+ </div>
194
+ </div>
195
+
196
+ <div class="mt-3 d-flex justify-content-center">
197
+ <button class="btn btn-light" @click="resetFilters()">
198
+ Reset
199
+ </button>
200
+ <button class="btn btn-info" @click="onChangeFilter($event)">
201
+ Filtrar
202
+ </button>
203
+ </div>
204
+ </div>
205
+ </template>
206
+
207
+ <script>
208
+ // Componente funcional para renderizar filtros custom con callback
209
+ const RenderCustomFilter = {
210
+ functional: true,
211
+ props: {
212
+ renderFunction: {
213
+ type: Function,
214
+ required: true
215
+ },
216
+ customFilter: {
217
+ type: Object,
218
+ required: true
219
+ },
220
+ filter: {
221
+ type: Array,
222
+ default: () => []
223
+ },
224
+ internalFilterByProp: {
225
+ type: Function,
226
+ required: true
227
+ },
228
+ getFilterForColumn: {
229
+ type: Function,
230
+ required: true
231
+ },
232
+ onChangeFilter: {
233
+ type: Function,
234
+ required: true
235
+ }
236
+ },
237
+ render(h, context) {
238
+ const { renderFunction, customFilter, filter, internalFilterByProp, getFilterForColumn, onChangeFilter } = context.props;
239
+ return renderFunction(h, {
240
+ column: customFilter,
241
+ filter: filter,
242
+ internalFilterByProp: internalFilterByProp,
243
+ getFilterForColumn: getFilterForColumn,
244
+ onChangeFilter: onChangeFilter
245
+ });
246
+ }
247
+ };
248
+
249
+ export default {
250
+ name: 'CrudFilters',
251
+ components: {
252
+ RenderCustomFilter
253
+ },
254
+ inject: [
255
+ 'columns',
256
+ 'customFilters',
257
+ 'isColumnHasFilter',
258
+ 'isCustomFilterEnabled',
259
+ 'filter',
260
+ 'internalFilterByProp',
261
+ 'optionsLoaded',
262
+ 'onChangeFilter',
263
+ 'resetFilters',
264
+ 'setupFilters',
265
+ 'internalFilters'
266
+ ],
267
+ methods: {
268
+ // Método helper para obtener el filtro de forma segura, creándolo si no existe
269
+ getFilterForColumn(column) {
270
+ let filter = this.internalFilterByProp(column.prop);
271
+
272
+ // Si el filtro no existe, intentar inicializar los filtros
273
+ if (!filter) {
274
+ // Verificar si hay filtros inicializados
275
+ if (this.internalFilters && this.internalFilters.length === 0) {
276
+ this.setupFilters();
277
+ // Intentar obtener el filtro nuevamente después de inicializar
278
+ filter = this.internalFilterByProp(column.prop);
279
+ }
280
+ }
281
+
282
+ // Si aún no existe, crear un objeto temporal para evitar errores
283
+ if (!filter) {
284
+ return {
285
+ value: null
286
+ };
287
+ }
288
+
289
+ return filter;
290
+ },
291
+
292
+ // Método helper específico para campos de fecha (from)
293
+ getFilterForDateFrom(column) {
294
+ const filter = this.internalFilterByProp(column.prop + '_from');
295
+ if (!filter) {
296
+ if (this.internalFilters && this.internalFilters.length === 0) {
297
+ this.setupFilters();
298
+ return this.internalFilterByProp(column.prop + '_from') || { value: null };
299
+ }
300
+ return { value: null };
301
+ }
302
+ return filter;
303
+ },
304
+
305
+ // Método helper específico para campos de fecha (to)
306
+ getFilterForDateTo(column) {
307
+ const filter = this.internalFilterByProp(column.prop + '_to');
308
+ if (!filter) {
309
+ if (this.internalFilters && this.internalFilters.length === 0) {
310
+ this.setupFilters();
311
+ return this.internalFilterByProp(column.prop + '_to') || { value: null };
312
+ }
313
+ return { value: null };
314
+ }
315
+ return filter;
316
+ }
317
+ }
318
+ };
319
+ </script>