pui9-components 2.0.8 → 3.0.0

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.
Files changed (67) hide show
  1. package/dist/pui9-components.common.js +5300 -22115
  2. package/dist/pui9-components.css +3 -6
  3. package/package-lock.json +1 -141
  4. package/package.json +1 -5
  5. package/src/App.vue +0 -117
  6. package/src/components/PuiAutocomplete.vue +0 -196
  7. package/src/components/PuiCauDialog.vue +0 -192
  8. package/src/components/PuiCheckbox.vue +0 -126
  9. package/src/components/PuiCodeEditor.vue +0 -124
  10. package/src/components/PuiDateField.vue +0 -1043
  11. package/src/components/PuiField.vue +0 -30
  12. package/src/components/PuiFieldSet.vue +0 -27
  13. package/src/components/PuiFileUpload.vue +0 -275
  14. package/src/components/PuiFileUploadGroup.vue +0 -241
  15. package/src/components/PuiFilter.vue +0 -104
  16. package/src/components/PuiFilterGroup.vue +0 -291
  17. package/src/components/PuiFilterRule.vue +0 -683
  18. package/src/components/PuiFormFooter.vue +0 -48
  19. package/src/components/PuiFormFooterBtns.vue +0 -118
  20. package/src/components/PuiFormHeader.vue +0 -25
  21. package/src/components/PuiFormLoading.vue +0 -14
  22. package/src/components/PuiFormMiniAudit.vue +0 -53
  23. package/src/components/PuiFormTooltip.vue +0 -50
  24. package/src/components/PuiMasterDetail.vue +0 -103
  25. package/src/components/PuiModalDialog.vue +0 -91
  26. package/src/components/PuiModalDialogForm.vue +0 -209
  27. package/src/components/PuiMultiSelect.vue +0 -636
  28. package/src/components/PuiNumberField.vue +0 -434
  29. package/src/components/PuiPasswordField.vue +0 -105
  30. package/src/components/PuiRadioGroup.vue +0 -105
  31. package/src/components/PuiRichTextEditor.vue +0 -116
  32. package/src/components/PuiSelect.vue +0 -1675
  33. package/src/components/PuiSelectDetailDialog.vue +0 -113
  34. package/src/components/PuiSelectTextService.vue +0 -61
  35. package/src/components/PuiSelectorList.vue +0 -169
  36. package/src/components/PuiSort.vue +0 -98
  37. package/src/components/PuiSpinnerField.vue +0 -464
  38. package/src/components/PuiSwitch.vue +0 -104
  39. package/src/components/PuiTextArea.vue +0 -204
  40. package/src/components/PuiTextField.vue +0 -389
  41. package/src/dateTimeUtils.js +0 -78
  42. package/src/index.js +0 -89
  43. package/src/main.js +0 -34
  44. package/src/mixins/PuiFormComponentMixin.js +0 -77
  45. package/src/mixins/PuiSortMixin.js +0 -136
  46. package/src/mixins/PuiUtilsNumberMixin.js +0 -29
  47. package/src/plugins/vuetify.js +0 -33
  48. package/src/tests/TestAutocomplete.vue +0 -138
  49. package/src/tests/TestCodeEditor.vue +0 -48
  50. package/src/tests/TestField.vue +0 -22
  51. package/src/tests/TestFieldSet.vue +0 -30
  52. package/src/tests/TestInputCheckbox.vue +0 -53
  53. package/src/tests/TestInputDate.vue +0 -146
  54. package/src/tests/TestInputNumber.vue +0 -77
  55. package/src/tests/TestInputRadioGroup.vue +0 -86
  56. package/src/tests/TestInputSpinner.vue +0 -77
  57. package/src/tests/TestInputSwitch.vue +0 -52
  58. package/src/tests/TestInputText.vue +0 -120
  59. package/src/tests/TestInputTextArea.vue +0 -73
  60. package/src/tests/TestMultiSelect.vue +0 -127
  61. package/src/tests/TestPuiForm.vue +0 -68
  62. package/src/tests/TestRichTextEditor.vue +0 -54
  63. package/src/tests/unit/PuiCheckbox.spec.js +0 -86
  64. package/src/tests/unit/PuiTextArea.spec.js +0 -62
  65. package/src/tests/unit/PuiTextField.spec.js +0 -119
  66. package/src/tests/unit/index.js +0 -5
  67. package/src/utils.js +0 -158
@@ -1,1675 +0,0 @@
1
- <template>
2
- <!-- DESKTOP -->
3
- <div v-if="!isMobile">
4
- <div v-if="toplabel" class="ml-1 mr-1">
5
- <v-layout>
6
- <v-flex xs12>
7
- <label v-if="getLabel === '$nbsp;'">&nbsp;</label>
8
- <label v-else :class="getLabelRequiredClass">{{ getLabel }}</label>
9
- <pui-form-tooltip v-bind="{ tooltipDescription, tooltipIcon }" v-if="showTooltip" ref="tooltip"></pui-form-tooltip>
10
- <v-btn v-if="copyClipboardEnabled && !multiple" style="color:var(--N-300)" class="pb-1" x-small text @click="copySelectedItemToClipboard">
11
- <v-icon x-small>far fa-copy</v-icon>
12
- </v-btn>
13
- </v-flex>
14
- </v-layout>
15
- <v-layout>
16
- <v-flex
17
- :class="
18
- (prependInnerIconRead || prependInnerIconUpdate) && prependInnerIconInsert
19
- ? 'xs10'
20
- : (prependInnerIconRead || prependInnerIconUpdate) && !prependInnerIconInsert
21
- ? 'xs11'
22
- : 'xs12'
23
- "
24
- >
25
- <v-autocomplete
26
- v-model="selectedItems"
27
- class="pui-select"
28
- :class="getEditedClass"
29
- solo
30
- flat
31
- ref="arrowUp"
32
- :attach="attach ? true : false"
33
- :autocomplete="!filterServerSide"
34
- :no-filter="filterServerSide"
35
- :readonly="readonly"
36
- :return-object="return_object"
37
- :clearable="clearable"
38
- :items="theItems"
39
- :error="internalError"
40
- :error-messages="internalErrorMessages"
41
- :item-text="itemText"
42
- :item-value="itemValue"
43
- :search-input.sync="search"
44
- :required="required"
45
- :rules="getRules"
46
- :disabled="disabled"
47
- :multiple="multiple"
48
- :placeholder="getPlaceholder"
49
- :filter="filter"
50
- v-bind="allProps"
51
- :hide-details="hideDetails"
52
- @focus="focusValue"
53
- @blur="checkValue"
54
- @keydown="setDropDownDirection"
55
- @click:append="menuArrow"
56
- @click:clear="requestItems"
57
- >
58
- <template slot="append-item" v-if="modelName">
59
- <infinite-loading @infinite="loading === false && getMoreItemsFromPuiList(search)" ref="infiniteLoading">
60
- <span style="font-weight: bold" slot="no-more">{{ allShownMesage }}</span>
61
- <span slot="no-results"></span>
62
- </infinite-loading>
63
- </template>
64
- <template v-slot:item="{ item, attrs, on }">
65
- <template v-if="!itemTemplate">
66
- <v-list-item v-bind="attrs" v-on="on" class="pui-select__item">
67
- <v-list-item-content class="pl-3">
68
- <pui-select-text-service :item="item" :itemText="itemText" />
69
- </v-list-item-content>
70
- <v-list-item-action class="pr-3" v-if="attrs['aria-selected'] === 'true'">
71
- <v-icon small class="pui-select__item-icon">fa fa-check</v-icon>
72
- </v-list-item-action>
73
- </v-list-item>
74
- </template>
75
- <template v-else>
76
- <slot name="theTemplate" :item="item" :selected="attrs.selected"></slot>
77
- </template>
78
- </template>
79
- <template slot="selection" slot-scope="{ item, selected, parent }">
80
- <template v-if="selectTemplate">
81
- <slot name="selectionTemplate" :item="item"></slot>
82
- </template>
83
- <template v-else-if="multiple === true">
84
- <v-chip color="grey lighten-2" :input-value="selected" label small tabindex="-1">
85
- <pui-select-text-service :item="item" type="select" :itemText="itemText" />
86
- <v-icon v-if="!(disabled || readonly)" small @click.native.stop.prevent.capture="parent.selectItem(item)">fal fa-times</v-icon>
87
- </v-chip>
88
- </template>
89
- <template v-else>
90
- <pui-select-text-service
91
- :truncate="!isDisabled"
92
- :writing="isMenuOpened"
93
- :disabled="disabled"
94
- :item="item"
95
- type="select"
96
- :itemText="itemText"
97
- />
98
- </template>
99
- </template>
100
- </v-autocomplete>
101
- </v-flex>
102
- <v-flex xs1 v-if="prependInnerIconUpdate || prependInnerIconRead">
103
- <v-btn v-if="prependInnerIconUpdate" class="pui-select__prepend-inner-icon--desktop" icon @click="goToDetail('update')">
104
- <v-icon>{{ prependInnerIconUpdate }}</v-icon>
105
- </v-btn>
106
- <v-btn v-else-if="prependInnerIconRead" class="pui-select__prepend-inner-icon--desktop" icon @click="goToDetail('read')">
107
- <v-icon>{{ prependInnerIconRead }}</v-icon>
108
- </v-btn>
109
- </v-flex>
110
- <v-flex xs1 v-if="prependInnerIconInsert">
111
- <v-btn v-if="prependInnerIconInsert" class="pui-select__prepend-inner-icon--desktop" icon @click="goToDetail('create')">
112
- <v-icon>{{ prependInnerIconInsert }}</v-icon>
113
- </v-btn>
114
- </v-flex>
115
- </v-layout>
116
- </div>
117
- <div v-else class="ml-1 mr-1">
118
- <v-layout>
119
- <v-flex :class="labelColumnStyles ? labelColumnStyles : 'xs12 sm6 md4 xl3'">
120
- <label :class="getLabelRequiredClass">{{ getLabel }}</label>
121
- <pui-form-tooltip v-bind="{ tooltipDescription, tooltipIcon }" v-if="showTooltip" ref="tooltip"></pui-form-tooltip>
122
- <v-btn v-if="copyClipboardEnabled && !multiple" style="color:var(--N-300)" class="pb-1" x-small text @click="copySelectedItemToClipboard">
123
- <v-icon x-small>far fa-copy</v-icon>
124
- </v-btn>
125
- </v-flex>
126
- <v-flex
127
- :class="
128
- valueColumnStyles
129
- ? valueColumnStyles
130
- : !prependInnerIconRead && !prependInnerIconUpdate && !prependInnerIconInsert
131
- ? 'xs12 sm6 md8 xl9'
132
- : 'xs10 sm5 md7 xl8'
133
- "
134
- >
135
- <v-autocomplete
136
- v-model="selectedItems"
137
- class="pui-select"
138
- :class="getEditedClass"
139
- solo
140
- flat
141
- ref="arrowUp"
142
- :attach="attach ? true : false"
143
- :autocomplete="!filterServerSide"
144
- :no-filter="filterServerSide"
145
- :readonly="readonly"
146
- :return-object="return_object"
147
- :clearable="clearable"
148
- :label="label"
149
- :error="internalError"
150
- :error-messages="internalErrorMessages"
151
- :items="theItems"
152
- :item-text="itemText"
153
- :item-value="itemValue"
154
- :search-input.sync="search"
155
- :required="required"
156
- :rules="getRules"
157
- :disabled="isDisabled"
158
- :multiple="multiple"
159
- :placeholder="getPlaceholder"
160
- :filter="filter"
161
- v-bind="allProps"
162
- :hide-details="hideDetails"
163
- @focus="focusValue"
164
- @blur="checkValue"
165
- @click:append="menuArrow"
166
- @click:clear="requestItems"
167
- >
168
- <template slot="append-item" v-if="modelName">
169
- <infinite-loading @infinite="loading === false && getMoreItemsFromPuiList(search)" ref="infiniteLoading">
170
- <span style="font-weight: bold" slot="no-more">{{ allShownMesage }}</span>
171
- <span slot="no-results"></span>
172
- </infinite-loading>
173
- </template>
174
- <template v-slot:item="{ item, attrs, on }">
175
- <template v-if="!itemTemplate">
176
- <v-list-item v-bind="attrs" v-on="on" class="pui-select__item">
177
- <v-list-item-content class="pl-3">
178
- <pui-select-text-service :item="item" :itemText="itemText" />
179
- </v-list-item-content>
180
- <v-list-item-action class="pr-3" v-if="attrs['aria-selected'] === 'true'">
181
- <v-icon small class="pui-select__item-icon">fa fa-check</v-icon>
182
- </v-list-item-action>
183
- </v-list-item>
184
- </template>
185
- <template v-else>
186
- <slot name="theTemplate" :item="item" :selected="attrs.selected" :tile="attrs.tile"></slot>
187
- </template>
188
- </template>
189
- <template slot="selection" slot-scope="{ item, selected, parent }">
190
- <template v-if="selectTemplate === true">
191
- <slot name="selectionTemplate" :item="item"></slot>
192
- </template>
193
- <template v-else-if="multiple === true">
194
- <v-chip color="grey lighten-2" :input-value="selected" label small tabindex="-1">
195
- <pui-select-text-service :item="item" type="select" :itemText="itemText" />
196
- <v-icon small @click.native.stop.prevent.capture="parent.selectItem(item)">close</v-icon>
197
- </v-chip>
198
- </template>
199
- <template v-else>
200
- <pui-select-text-service
201
- :truncate="!isDisabled"
202
- :writing="isMenuOpened"
203
- :item="item"
204
- type="select"
205
- :itemText="itemText"
206
- />
207
- </template>
208
- </template>
209
- </v-autocomplete>
210
- </v-flex>
211
- <v-flex xs1 v-if="prependInnerIconUpdate || prependInnerIconRead">
212
- <v-btn v-if="prependInnerIconUpdate" class="pui-select__prepend-inner-icon--desktop" icon @click="goToDetail('update')">
213
- <v-icon>{{ prependInnerIconUpdate }}</v-icon>
214
- </v-btn>
215
- <v-btn v-else-if="prependInnerIconRead" class="pui-select__prepend-inner-icon--desktop" icon @click="goToDetail('read')">
216
- <v-icon>{{ prependInnerIconRead }}</v-icon>
217
- </v-btn>
218
- </v-flex>
219
- <v-flex xs1 v-if="prependInnerIconInsert">
220
- <v-btn v-if="prependInnerIconInsert" class="pui-select__prepend-inner-icon--desktop" icon @click="goToDetail('create')">
221
- <v-icon>{{ prependInnerIconInsert }}</v-icon>
222
- </v-btn>
223
- </v-flex>
224
- </v-layout>
225
- </div>
226
- <pui-select-detail-dialog
227
- v-if="showDetailComponent"
228
- :parentId="puiSelectId"
229
- :componentLabel="detailComponentLabel"
230
- :componentName="detailComponentName"
231
- :componentPk="detailComponentPk"
232
- :componentMethod="detailComponentMethod"
233
- :modelName="detailModelName"
234
- ></pui-select-detail-dialog>
235
- </div>
236
- <!-- MOBILE -->
237
- <div v-else>
238
- <v-layout>
239
- <v-flex xs12>
240
- <label v-if="getLabel === '$nbsp;'">&nbsp;</label>
241
- <label v-else class="pui-select__label-mobile" :class="getLabelRequiredClass">{{ getLabel }}</label>
242
- </v-flex>
243
- </v-layout>
244
- <v-layout>
245
- <v-flex
246
- :class="
247
- (prependInnerIconRead || prependInnerIconUpdate) && prependInnerIconInsert
248
- ? 'xs10'
249
- : (prependInnerIconRead || prependInnerIconUpdate) && !prependInnerIconInsert
250
- ? 'xs11'
251
- : 'xs12'
252
- "
253
- >
254
- <v-autocomplete
255
- v-model="selectedItems"
256
- class="pui-select"
257
- :class="getEditedClass"
258
- solo
259
- flat
260
- ref="arrowUp"
261
- :attach="attach ? true : false"
262
- :autocomplete="!filterServerSide"
263
- :no-filter="filterServerSide"
264
- :readonly="readonly"
265
- :return-object="return_object"
266
- :clearable="clearable"
267
- :items="theItems"
268
- :error="internalError"
269
- :error-messages="internalErrorMessages"
270
- :item-text="itemText"
271
- :item-value="itemValue"
272
- :search-input.sync="search"
273
- :required="required"
274
- :rules="getRules"
275
- :disabled="disabled"
276
- :multiple="multiple"
277
- :placeholder="getPlaceholder"
278
- :filter="filter"
279
- v-bind="allProps"
280
- :hide-details="hideDetails"
281
- @focus="focusValue"
282
- @blur="checkValue"
283
- @click:append="menuArrow"
284
- @click:clear="requestItems"
285
- >
286
- <template slot="append-item" v-if="modelName">
287
- <infinite-loading @infinite="loading === false && getMoreItemsFromPuiList(search)" ref="infiniteLoading">
288
- <span style="font-weight: bold" slot="no-more">{{ allShownMesage }}</span>
289
- <span slot="no-results"></span>
290
- </infinite-loading>
291
- </template>
292
- <template v-slot:item="{ item, attrs, on }">
293
- <template v-if="!itemTemplate">
294
- <v-list-item v-bind="attrs" v-on="on" class="pui-select__item">
295
- <v-list-item-content class="pl-3">
296
- <pui-select-text-service :item="item" :itemText="itemText" />
297
- </v-list-item-content>
298
- <v-list-item-action class="pr-3" v-if="attrs['aria-selected'] === 'true'">
299
- <v-icon class="pui-select__item-icon">fa fa-check</v-icon>
300
- </v-list-item-action>
301
- </v-list-item>
302
- </template>
303
- <template v-else>
304
- <slot name="theTemplate" :item="item" :selected="attrs.selected"></slot>
305
- </template>
306
- </template>
307
- <template slot="selection" slot-scope="{ item, selected, parent }">
308
- <template v-if="selectTemplate">
309
- <slot name="selectionTemplate" :item="item"></slot>
310
- </template>
311
- <template v-else-if="multiple === true">
312
- <v-chip color="grey lighten-2" :input-value="selected" label small>
313
- <pui-select-text-service :item="item" type="select" :itemText="itemText" />
314
- <v-icon small @click.native.stop.prevent.capture="parent.selectItem(item)">close</v-icon>
315
- </v-chip>
316
- </template>
317
- <template v-else>
318
- <pui-select-text-service
319
- :truncate="!isDisabled"
320
- :writing="isMenuOpened"
321
- :item="item"
322
- type="select"
323
- :itemText="itemText"
324
- />
325
- </template>
326
- </template>
327
- </v-autocomplete>
328
- </v-flex>
329
- <v-flex xs1 v-if="prependInnerIconUpdate || prependInnerIconRead">
330
- <v-btn v-if="prependInnerIconUpdate" class="pui-select__prepend-inner-icon--desktop" icon @click="goToDetail('update')">
331
- <v-icon>{{ prependInnerIconUpdate }}</v-icon>
332
- </v-btn>
333
- <v-btn v-else-if="prependInnerIconRead" class="pui-select__prepend-inner-icon--desktop" icon @click="goToDetail('read')">
334
- <v-icon>{{ prependInnerIconRead }}</v-icon>
335
- </v-btn>
336
- </v-flex>
337
- <v-flex xs1 v-if="prependInnerIconInsert">
338
- <v-btn v-if="prependInnerIconInsert" class="pui-select__prepend-inner-icon--desktop" icon @click="goToDetail('create')">
339
- <v-icon>{{ prependInnerIconInsert }}</v-icon>
340
- </v-btn>
341
- </v-flex>
342
- </v-layout>
343
- <pui-select-detail-dialog
344
- v-if="showDetailComponent"
345
- :parentId="puiSelectId"
346
- :componentLabel="detailComponentLabel"
347
- :componentName="detailComponentName"
348
- :componentPk="detailComponentPk"
349
- :componentMethod="detailComponentMethod"
350
- :modelName="detailModelName"
351
- ></pui-select-detail-dialog>
352
- </div>
353
- </template>
354
-
355
- <script>
356
- import PuiSelectTextService from './PuiSelectTextService';
357
- import PuiSelectDetailDialog from './PuiSelectDetailDialog';
358
- import InfiniteLoading from 'vue-infinite-loading';
359
-
360
- export default {
361
- //TOFOLLOW
362
- //https://github.com/vuetifyjs/vuetify/issues/5087 Al cerrar las chips del multiselect se abre el menú
363
- name: 'PuiSelect',
364
- inject: {
365
- form: {
366
- default: null
367
- }
368
- },
369
- components: {
370
- PuiSelectTextService,
371
- PuiSelectDetailDialog,
372
- 'infinite-loading': InfiniteLoading
373
- },
374
- /* Properties provided by the pui-select */
375
- props: {
376
- value: {
377
- required: false
378
- },
379
- /* Type: Boolean
380
- Native by the v-select
381
- If true adds a close icon to the selection*/
382
- clearable: {
383
- type: [Boolean],
384
- default: false,
385
- required: false
386
- },
387
- /* Type: Boolean
388
- Native by the v-select
389
- If true allows to select multiple items, selectedItems becomes an Array*/
390
- multiple: {
391
- type: [Boolean],
392
- default: false,
393
- required: false
394
- },
395
- /* Type: Boolean
396
- If true applies a custom template slot for the list of items
397
- The parent has to provide it*/
398
- itemTemplate: {
399
- type: Boolean,
400
- default: false
401
- },
402
- selectTemplate: {
403
- type: Boolean,
404
- default: false
405
- },
406
- /* Type: Number {Integer}
407
- It is used when the items come from a Service,
408
- it will requeste paginated requests of ths number of items*/
409
- rows: {
410
- type: Number,
411
- default: -1
412
- },
413
- disabled: {
414
- type: [Boolean],
415
- default: false,
416
- required: false
417
- },
418
- filter: {
419
- type: Function,
420
- required: false
421
- },
422
- readonly: {
423
- type: [Boolean],
424
- default: false,
425
- required: false
426
- },
427
- toplabel: {
428
- type: [Boolean],
429
- default: false,
430
- required: false
431
- },
432
- placeholder: {
433
- type: [String],
434
- default: ' ',
435
- required: false
436
- },
437
- return_object: {
438
- type: Boolean,
439
- default: true
440
- },
441
- noeditable: {
442
- type: [Boolean],
443
- default: false,
444
- required: false
445
- },
446
- attach: {
447
- type: String,
448
- default: null,
449
- required: false
450
- },
451
- labelColumnStyles: {
452
- type: [String],
453
- required: false
454
- },
455
- valueColumnStyles: {
456
- type: [String],
457
- required: false
458
- },
459
- hideDetails: {
460
- type: Boolean,
461
- default: false,
462
- required: false
463
- },
464
- 'hide-selected': {
465
- type: Boolean,
466
- default: false,
467
- required: false
468
- },
469
- 'hide-no-data': {
470
- type: Boolean,
471
- default: false,
472
- required: false
473
- },
474
- detailModelName: {
475
- type: String,
476
- default: null,
477
- required: false
478
- },
479
- detailComponentName: {
480
- type: String,
481
- default: null,
482
- required: false
483
- },
484
- detailActions: {
485
- type: Object,
486
- default: () => {
487
- return {
488
- read: true,
489
- create: true,
490
- update: true
491
- };
492
- },
493
- required: false
494
- },
495
- /*
496
- Type: Array of Objects
497
- Items provided by the parent component */
498
- items: {
499
- type: Array,
500
- default: null,
501
- required: false
502
- },
503
- /**
504
- * Los items seleccionados que se pasan de inicio, se pasa en la directiva v-model al utilizar este componente
505
- * puede ser un array de Items igual que en la propiedad :items, o un array con los id's solamente
506
- */
507
- itemsToSelect: {
508
- type: Array,
509
- default: () => []
510
- },
511
- /**
512
- * The fields to be searched
513
- */
514
- queryFields: {
515
- type: Array,
516
- default: () => [],
517
- required: false
518
- },
519
- /* Type: String
520
- Native by the v-select
521
- If Present the select will show this label in the input */
522
- label: {
523
- type: [String],
524
- default: '',
525
- required: false
526
- },
527
- /* Type: String
528
- Instead of providing the items, if controller is provided it will get the items by calling this web service in @getItemsFromPuiList */
529
- controller: {
530
- type: String,
531
- default: '/puisearch',
532
- required: false
533
- },
534
- /* Type: Object
535
- The pui9 list filter object*/
536
- pui9filter: {
537
- type: Object,
538
- default: null,
539
- required: false
540
- },
541
- filterId: {
542
- type: String
543
- },
544
- filterMap: {
545
- type: Object,
546
- default: null
547
- },
548
- filterMapOp: {
549
- type: String,
550
- default: 'and'
551
- },
552
- filterParentMap: {
553
- type: Object,
554
- default: null
555
- },
556
- fixedFilter: {
557
- type: Object,
558
- default: null
559
- },
560
- order: {
561
- type: Object,
562
- default: null
563
- },
564
- /* Type: String
565
- Instead of providing the items, if controller is provided it will get the items by calling the controller in @getItems */
566
- modelFormMapping: {
567
- type: Object,
568
- default: null,
569
- required: false
570
- },
571
- /* Type: String
572
- The items text property name */
573
- itemText: {
574
- type: [String, Array, Function],
575
- default: 'text',
576
- required: true
577
- },
578
- modelName: {
579
- type: String
580
- },
581
- rules: {
582
- type: Array,
583
- default: () => {
584
- return [];
585
- }
586
- },
587
- /* Type: String
588
- The items id property name */
589
- itemValue: {
590
- type: [String, Array, Function],
591
- default: 'value',
592
- required: false
593
- },
594
- /* Type: Boolean
595
- Native by the v-select
596
- If true adds a close icon to the selection, @model[property] */
597
- searchable: {
598
- type: [Boolean],
599
- default: true,
600
- required: false
601
- },
602
-
603
- /* Type: Boolean
604
- If true applies the required rule in @rules.required */
605
- required: {
606
- type: [Boolean],
607
- default: false,
608
- required: false
609
- },
610
- /* Type: Number
611
- Default number of rows for a multiselect */
612
- rowNum: {
613
- type: Number,
614
- default: 1000,
615
- required: false
616
- },
617
- /* Type: Boolean
618
- Fix for reactivity, require itemsToSelect to be a computed */
619
- reactive: {
620
- type: Boolean,
621
- default: false,
622
- required: false
623
- },
624
- emitSelectedItemsEventOnFirstLoad: {
625
- type: Boolean,
626
- default: true,
627
- required: false
628
- },
629
- tooltipDescription: {
630
- type: String,
631
- required: false
632
- },
633
- tooltipIcon: {
634
- type: String,
635
- required: false
636
- },
637
- singleItemAutoselect: {
638
- type: Boolean,
639
- required: false
640
- },
641
- copyClipboard: {
642
- type: Boolean,
643
- default: null,
644
- required: false
645
- }
646
- },
647
- data() {
648
- return {
649
- isMobile: false,
650
- initialValue: null,
651
- selectedItems: null,
652
- page: 0,
653
- showDetailComponent: false,
654
- newDisabled: undefined,
655
- hasBeenFocused: false,
656
- itemTextMultiple: false,
657
- itemValueMultiple: false,
658
- itemTextNested: false,
659
- itemValueNested: false,
660
- search: '',
661
- loading: false,
662
- theItems: [],
663
- internalError: false,
664
- internalErrorMessages: '',
665
- selected: false,
666
- initialItemsToSelect: [],
667
- previousSelectedItems: undefined,
668
- doingThings: false,
669
- itemManuallySelected: false,
670
- itemProgrammaticallySelected: false,
671
- firstLoad: true,
672
- requestDataPromise: undefined,
673
- selectedItemsEventFirstLoad: true,
674
- internalQueryFields: [],
675
- singleItemAutoselectEnabled: false,
676
- valid: true
677
- };
678
- },
679
- computed: {
680
- allProps() {
681
- const propsWithoutLabel = { ...this.$props };
682
- delete propsWithoutLabel.label;
683
- return { ...this.$attrs, propsWithoutLabel };
684
- },
685
- theModel() {
686
- return this.$store.getters.getModelByName(this.modelName);
687
- },
688
- internalController() {
689
- return this.controller; // || this.theModel.url.list;
690
- },
691
- fixedFilterWatcher() {
692
- return JSON.stringify(this.fixedFilter);
693
- },
694
- filterMapWatcher() {
695
- return JSON.stringify(this.filterMap);
696
- },
697
- requiredMessage() {
698
- return this.$t('pui9.error.field_required');
699
- },
700
- allShownMesage() {
701
- return this.$t('pui9.components.select.all-items-showed');
702
- },
703
- isDisabled() {
704
- if (!this.hasEmptyValue(this.newDisabled)) {
705
- return this.newDisabled;
706
- }
707
- return this.disabled;
708
- },
709
- filterServerSide() {
710
- if (this.items) {
711
- return false;
712
- }
713
- return true;
714
- },
715
- getLabel() {
716
- return this.label;
717
- },
718
- getLabelRequiredClass() {
719
- return { 'v-label--required': this.required };
720
- },
721
- getEditedClass() {
722
- const editedClass = { 'v-text-field--edited': this.isEdited };
723
- if (this.attach) {
724
- editedClass['puiselect-' + this.attach] = true;
725
- }
726
- return editedClass;
727
- },
728
- getPlaceholder() {
729
- var placeholder = this.placeholder;
730
- if (this.isMobile && this.placeholder === ' ') {
731
- placeholder = this.label;
732
- }
733
- return placeholder;
734
- },
735
- prependInnerIconRead() {
736
- if (this.detailModelName && this.detailComponentName && this.detailActions.read) {
737
- const model = this.$store.getters.getModelByName(this.detailModelName);
738
- if (model && model.functionalities) {
739
- if (this.$store.getters.hasFunctionality(model.functionalities.get)) {
740
- return 'far fa-info-circle';
741
- }
742
- }
743
- }
744
- return null;
745
- },
746
- prependInnerIconUpdate() {
747
- if (this.detailModelName && !this.disabled && this.detailActions.update) {
748
- const model = this.$store.getters.getModelByName(this.detailModelName);
749
- if (model && model.functionalities) {
750
- // eslint-disable-next-line
751
- if (this.$store.getters.hasFunctionality(model.functionalities.update)) {
752
- return 'far fa-edit';
753
- }
754
- }
755
- }
756
- return null;
757
- },
758
- prependInnerIconInsert() {
759
- if (this.detailModelName && !this.disabled && this.detailActions.create) {
760
- const model = this.$store.getters.getModelByName(this.detailModelName);
761
- if (model && model.functionalities) {
762
- // eslint-disable-next-line
763
- if (this.$store.getters.hasFunctionality(model.functionalities.insert)) {
764
- return 'far fa-plus-circle';
765
- }
766
- }
767
- }
768
- return null;
769
- },
770
- getRules() {
771
- return [...this.rules];
772
- },
773
- isEdited() {
774
- if (this.noeditable || this.disabled || this.readonly || this.selected === false) {
775
- return false;
776
- } else {
777
- return this.compareInitialWithCurrentSelected();
778
- }
779
- },
780
- isMenuOpened() {
781
- return this.$refs.arrowUp ? this.$refs.arrowUp.isMenuActive || this.$refs.arrowUp.isFocused : false;
782
- },
783
- showTooltip() {
784
- if (this.getLabel === '' || this.getLabel === null) {
785
- return false;
786
- }
787
- return this.tooltipDescription || this.tooltip;
788
- },
789
- copyClipboardEnabled() {
790
- return this.copyClipboard != null ? this.copyClipboard : this.$store.state.components.copyClipboardSelect;
791
- }
792
- },
793
- watch: {
794
- modelName(modelName) {
795
- if (modelName && this.hasEmptyValue(this.theItems)) {
796
- this.setInternalQueryFields();
797
- this.getItemsFromPuiList();
798
- }
799
- },
800
- itemsToSelect: {
801
- handler(newValue) {
802
- this.reactiveHandler(newValue);
803
- },
804
- deep: true
805
- },
806
- fixedFilterWatcher: {
807
- handler(newFilter, oldFilter) {
808
- if (newFilter === oldFilter) {
809
- return;
810
- }
811
- this.previousSelectedItems = this.previousSelectedItems || this.selectedItems;
812
- this.resetItems();
813
- this.filterItems();
814
- },
815
- deep: true
816
- },
817
- filterMapWatcher: {
818
- handler(newFilter, oldFilter) {
819
- if (newFilter === oldFilter) {
820
- return;
821
- }
822
- this.resetItems(JSON.parse(newFilter));
823
- this.filterItems(null);
824
- },
825
- deep: true
826
- },
827
- loading(newValue, oldValue) {
828
- if (newValue === false && oldValue === true && !this.hasEmptyValue(this.previousSelectedItems)) {
829
- this.selectPreviousValidItems();
830
- this.previousSelectedItems = undefined;
831
- }
832
- },
833
- search(newValue, oldValue) {
834
- if (this.multiple && this.hasEmptyValue(newValue) && this.hasEmptyValue(oldValue)) {
835
- return;
836
- }
837
- this.searchable && this.filterItems(newValue);
838
- },
839
- selectedItems(newVal) {
840
- if (this.reactive) {
841
- if (this.firstLoad) {
842
- this.firstLoad = false;
843
- } else if (!this.itemProgrammaticallySelected) {
844
- this.itemManuallySelected = true;
845
- } else {
846
- this.itemProgrammaticallySelected = false;
847
- }
848
- }
849
- this.clearMessages();
850
- if (this.modelFormMapping) {
851
- this.$emit('input', this.replaceMapping());
852
- } else {
853
- this.$emit('input', newVal);
854
- }
855
- this.$emit('change', newVal);
856
-
857
- if (this.emitSelectedItemsEventOnFirstLoad || !this.selectedItemsEventFirstLoad) {
858
- this.$puiEvents.$emit(`onPuiSelect_selectedItems-${this.puiSelectId}`, { id: this.puiSelectId, model: newVal });
859
- }
860
- this.selectedItemsEventFirstLoad = false;
861
- if (this.attach && this.puiSelectId && !this.multiple && newVal) {
862
- // Need for browser to recalculate correctly getBoundingClientSelectPosition
863
- document.getElementById(this.puiSelectId).click();
864
- }
865
- },
866
- disabled(newVal) {
867
- this.newDisabled = newVal;
868
- if (newVal) {
869
- this.clearMessages();
870
- }
871
- },
872
- detailComponentName(newValue, oldValue) {
873
- if (!this.hasEmptyValue(oldValue)) {
874
- this.$puiEvents.$off(`pui-modalDialog-${oldValue}_${this.puiSelectId}_popup-hide`);
875
- }
876
- if (!this.hasEmptyValue(newValue)) {
877
- const self = this;
878
- this.$puiEvents.$on(`pui-modalDialog-${newValue}_${this.puiSelectId}_popup-hide`, (data) => {
879
- self.showDetailComponent = false;
880
- if (data) {
881
- const newItem = {};
882
- const itemValues = this.itemValue;
883
- itemValues.forEach((pkValue) => {
884
- newItem[pkValue] = data[pkValue];
885
- });
886
- self.itemsToSelect[0] = newItem;
887
- self.onPuiSelectItemsToSelect = [newItem];
888
- self.getSelectedItemsFromPuiList();
889
- }
890
- });
891
- }
892
- },
893
- theItems() {
894
- if (this.singleItemAutoselectEnabled && this.theItems.length == 1) {
895
- this.selectedItems = this.theItems[0];
896
- }
897
- }
898
- },
899
- created() {
900
- // v-form injected
901
- this.form && this.form.register(this);
902
-
903
- this.puiSelectId = this.$attrs.id;
904
- this.isMobile = this.$store.getters.isMobile;
905
-
906
- //TODO poner itemValues como un array si viene de string, para unificar simplificar donde haya comprobaciones itemValuesMultiple
907
- this.itemsToSelect && this.itemsToSelect.forEach((item) => {
908
- this.initialItemsToSelect.push(item);
909
- });
910
-
911
- // Check Item Text
912
- this.itemTextMultiple = Array.isArray(this.itemText);
913
- if (this.itemTextMultiple === false) {
914
- this.itemTextNested = this.checkForNestedFields(this.itemText);
915
- }
916
-
917
- // Check Item Value
918
- this.itemValueMultiple = Array.isArray(this.itemValue);
919
- if (this.itemValueMultiple === false) {
920
- this.itemValueNested = this.checkForNestedFields(this.itemValue);
921
- }
922
-
923
- this.setInternalQueryFields();
924
- this.getItems();
925
-
926
- this.setSingleItemAutoselectEnabled();
927
-
928
- // Subscribe events
929
- this.$puiEvents.$on(`onPuiSelect_${this.puiSelectId}`, (newVal) => {
930
- this.itemsToSelect[0] = newVal;
931
- this.onPuiSelectItemsToSelect = [newVal];
932
- this.getSelectedItemsFromPuiList();
933
- });
934
- },
935
- mounted() {
936
- if (this.detailComponentName) {
937
- const self = this;
938
- this.$puiEvents.$on(`pui-modalDialog-${this.detailComponentName}_${this.puiSelectId}_popup-hide`, (data) => {
939
- self.showDetailComponent = false;
940
- if (data) {
941
- const newItem = {};
942
- const itemValues = this.itemValue;
943
- itemValues.forEach((pkValue) => {
944
- newItem[pkValue] = data[pkValue];
945
- });
946
- self.itemsToSelect[0] = newItem;
947
- self.onPuiSelectItemsToSelect = [newItem];
948
- self.getSelectedItemsFromPuiList();
949
- }
950
- });
951
- }
952
- },
953
- beforeDestroy() {
954
- // Unsubscribe events
955
- this.$puiEvents.$off(`onPuiSelect_${this.puiSelectId}`);
956
- this.$puiEvents.$off(`pui-modalDialog-${this.detailComponentName}_${this.puiSelectId}_popup-hide`);
957
- },
958
- methods: {
959
- validate() {
960
- this.checkValue();
961
- this.valid = !this.internalError;
962
- return this.valid;
963
- },
964
- requestItems() {
965
- this.getItemsFromPuiList();
966
- },
967
- setInternalQueryFields() {
968
- this.internalQueryFields = this.queryFields;
969
-
970
- if (this.modelName && this.hasEmptyValue(this.queryFields)) {
971
- this.internalQueryFields = this.theModel.columns?.map((c) => c.name);
972
- }
973
- },
974
- setSingleItemAutoselectEnabled() {
975
- if (this.singleItemAutoselect || (this.$store.state.global.singleItemAutoselectOnRequired && this.required)) {
976
- this.singleItemAutoselectEnabled = true;
977
- }
978
- },
979
- focusValue() {
980
- this.hasBeenFocused = true;
981
- this.$refs.arrowUp.isMenuActive = true;
982
- this.setDropDownDirection();
983
- },
984
- setDropDownDirection() {
985
- if (this.$refs.arrowUp && this.attach) {
986
- setTimeout(() => {
987
- const puiSelect = this.$refs.arrowUp.$el;
988
- const puiSelectPositions = puiSelect.getBoundingClientRect();
989
-
990
- const heightBrowser = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
991
- const screenAvailableForDropDown = heightBrowser - puiSelectPositions.top;
992
-
993
- const dropDown = puiSelect.querySelector('.v-menu__content');
994
- if (dropDown) {
995
- if (screenAvailableForDropDown < parseInt(dropDown.style['max-height']?.replace('px', '')) + 10) {
996
- dropDown.style.top = 'initial';
997
- dropDown.style.bottom = '40px';
998
- } else {
999
- dropDown.style.bottom = 'initial';
1000
- dropDown.style.top = '40px';
1001
- }
1002
- }
1003
- }, 0);
1004
- }
1005
- },
1006
- menuArrow() {
1007
- const arrowEl = this.$refs.arrowUp;
1008
- if (arrowEl.isMenuActive) {
1009
- arrowEl.isMenuActive = false;
1010
- arrowEl.blur();
1011
- } else {
1012
- arrowEl.isFocused = true;
1013
- this.focusValue();
1014
- }
1015
- },
1016
- compareInitialWithCurrentSelected() {
1017
- if (this.multiple) {
1018
- //comprobamos existencias, luego dimensiones y por último contenido de los arrays
1019
- if (!this.initialItemsToSelect || this.selectedItems.length === 0) {
1020
- if (this.initialItemsToSelect) {
1021
- return true;
1022
- } else if (this.selectedItems.length > 0) {
1023
- return true;
1024
- }
1025
- //los dos estan vacios
1026
- return false;
1027
- }
1028
- if (!this.hasEmptyValue(this.itemValue)) {
1029
- if (this.initialItemsToSelect.length !== this.selectedItems.length) {
1030
- return true;
1031
- } else if (this.itemValueNested === true) {
1032
- //TODO
1033
- } else if (this.itemValueMultiple === true) {
1034
- for (let index = 0, length = this.initialItemsToSelect.length; index < length; index++) {
1035
- const item = this.initialItemsToSelect[index];
1036
- const selectedItem = this.selectedItems[index];
1037
- for (let i = 0, length = this.itemValue.length; i < length; i++) {
1038
- const pkProp = this.itemValue[i];
1039
- if (item[pkProp] !== selectedItem[pkProp]) {
1040
- return true;
1041
- }
1042
- }
1043
- }
1044
- } else {
1045
- for (let i = 0, length = this.initialItemsToSelect.length; i < length; i++) {
1046
- if (this.initialItemsToSelect[i][this.itemValue] !== this.selectedItems[i][this.itemValue]) {
1047
- return true;
1048
- }
1049
- }
1050
- }
1051
- return false;
1052
- } else {
1053
- for (let i = 0, length = this.initialItemsToSelect.length; i < length; i++) {
1054
- if (this.initialItemsToSelect[i] !== this.selectedItems[i]) {
1055
- return true;
1056
- }
1057
- }
1058
- }
1059
- return false;
1060
- } else {
1061
- //comprobamos existencias y por último contenido de los objetos
1062
- if (this.hasEmptyValue(this.initialItemsToSelect) || this.hasEmptyValue(this.selectedItems)) {
1063
- if (this.initialItemsToSelect && this.initialItemsToSelect.length > 0) {
1064
- if (this.itemValueMultiple === true) {
1065
- return !this.hasEmptyValue(this.initialItemsToSelect[this.itemValue[0]]);
1066
- } else {
1067
- return !this.hasEmptyValue(this.initialItemsToSelect[this.itemValue]);
1068
- }
1069
- } else if (!this.hasEmptyValue(this.selectedItems)) {
1070
- return true;
1071
- }
1072
- //los dos estan vacios
1073
- return false;
1074
- }
1075
- if (!this.hasEmptyValue(this.itemValue)) {
1076
- if (this.itemValueMultiple === true) {
1077
- for (let i = 0, length = this.itemValue.length; i < length; i++) {
1078
- if (this.selectedItems[this.itemValue[i]] !== this.initialItemsToSelect[0][this.itemValue[i]]) {
1079
- return true;
1080
- }
1081
- }
1082
- return false;
1083
- } else if (this.itemValueNested === true) {
1084
- //TODO
1085
- }
1086
- return this.initialItemsToSelect[0] != null && this.initialItemsToSelect[0][this.itemValue] !== this.selectedItems[this.itemValue];
1087
- }
1088
- return this.initialItemsToSelect[0] !== this.selectedItems;
1089
- }
1090
- },
1091
- checkValue() {
1092
- this.search = '';
1093
- this.clearMessages();
1094
- if (this.required) {
1095
- if (this.hasEmptyValue(this.selectedItems)) {
1096
- this.showErrorMessage();
1097
- }
1098
- }
1099
- },
1100
- clearMessages() {
1101
- this.internalError = false;
1102
- this.internalErrorMessages = [];
1103
- },
1104
- showErrorMessage() {
1105
- this.internalError = true;
1106
- this.internalErrorMessages = [this.requiredMessage];
1107
- },
1108
- filterItems(search) {
1109
- if (this.modelName) {
1110
- clearTimeout(this.delayTimer);
1111
- this.delayTimer = setTimeout(() => {
1112
- this.getItemsFromPuiList(search);
1113
- }, 500);
1114
- }
1115
- },
1116
- disableInput() {
1117
- this.$el.children[0].children[0].children[0].children[0].children[0].children[1].setAttribute('disabled', '');
1118
- this.disabledInput = true;
1119
- },
1120
- goToDetail(method) {
1121
- if (!this.hasEmptyValue(this.selectedItems)) {
1122
- const detailPk = {};
1123
- let itemValues = this.itemValue;
1124
- if (this.itemValueMultiple === false) {
1125
- itemValues = [this.itemValue];
1126
- }
1127
- itemValues.forEach((pkProperty) => {
1128
- if (!this.hasEmptyValue(this.selectedItems[pkProperty])) {
1129
- detailPk[pkProperty] = this.selectedItems[pkProperty];
1130
- }
1131
- });
1132
-
1133
- this.detailComponentMethod = method;
1134
- this.detailComponentLabel = this.label;
1135
- this.detailComponentPk = this.$puiUtils.utf8ToB64(JSON.stringify(detailPk));
1136
- this.showDetailComponent = true;
1137
- } else if (method === 'create') {
1138
- this.detailComponentMethod = method;
1139
- this.detailComponentLabel = this.label;
1140
- this.detailComponentPk = 'new';
1141
- this.showDetailComponent = true;
1142
- }
1143
- },
1144
- replaceMapping() {
1145
- let itemValues = this.itemValue;
1146
- if (this.itemValueMultiple === false) {
1147
- itemValues = [this.itemValue];
1148
- }
1149
- if (this.multiple !== true) {
1150
- itemValues.forEach((pkValue) => {
1151
- if (this.hasEmptyValue(this.selectedItems)) {
1152
- if (this.filterId && this.filterMap) {
1153
- let isParentPkValue = false;
1154
- for (const property in this.filterMap) {
1155
- if (property === pkValue) {
1156
- isParentPkValue = true;
1157
- break;
1158
- }
1159
- }
1160
- if (!isParentPkValue) {
1161
- this.value[this.modelFormMapping[pkValue]] = null;
1162
- }
1163
- } else {
1164
- this.value[this.modelFormMapping[pkValue]] = null;
1165
- }
1166
- return;
1167
- }
1168
- this.value[this.modelFormMapping[pkValue]] = this.selectedItems[pkValue];
1169
- for (const property in this.selectedItems) {
1170
- if (pkValue === property && !Object.prototype.hasOwnProperty.call(this.value, property)) {
1171
- this.value[property] = this.selectedItems[property];
1172
- }
1173
- }
1174
- if (this.filterId && this.filterMap) {
1175
- const oldMapNull = Object.values(this.filterMap).some((e) => e === null);
1176
- if ((oldMapNull && !this.firstLoad) || !this.selectedItemsEventFirstLoad) {
1177
- this.sendDataToParent();
1178
- }
1179
- }
1180
- });
1181
- } else {
1182
- this.selectedItems.forEach((item, index) => {
1183
- itemValues.forEach((pkValue) => {
1184
- this.value[index][this.modelFormMapping[pkValue]] = item[pkValue];
1185
- for (var property in this.selectedItems[index]) {
1186
- if (pkValue === property && !Object.prototype.hasOwnProperty.call(this.value[index], property)) {
1187
- this.value[index][property] = this.selectedItems[index][property];
1188
- }
1189
- }
1190
- });
1191
- });
1192
- }
1193
- return this.value;
1194
- },
1195
- sendDataToParent() {
1196
- const selectedObject = {};
1197
- for (const property in this.filterMap) {
1198
- let parentProperty = property;
1199
- if (this.filterParentMap && !this.hasEmptyValue(this.filterParentMap[property])) {
1200
- parentProperty = this.filterParentMap[property];
1201
- }
1202
- selectedObject[parentProperty] = this.selectedItems[property];
1203
- }
1204
- this.$puiEvents.$emit(`onPuiSelect_${this.filterId}`, selectedObject);
1205
- },
1206
- getItems() {
1207
- if (this.items) {
1208
- this.theItems = this.items;
1209
- }
1210
- this.loading = false;
1211
- this.selectItems();
1212
- },
1213
- getItemsFromPuiList(search) {
1214
- this.page = 1;
1215
- this.loading = true;
1216
- const loadItems = (response) => {
1217
- this.$refs.infiniteLoading && this.$refs.infiniteLoading.stateChanger.reset();
1218
- if (response && response.data) {
1219
- this.theItems = response.data.data;
1220
- if (this.selected === false) {
1221
- this.selectItems();
1222
- } else {
1223
- this.checkSelectedItems();
1224
- }
1225
- this.$refs.infiniteLoading && this.$refs.infiniteLoading.stateChanger.loaded();
1226
- }
1227
- if (response.data.totalPages <= this.page) {
1228
- this.$refs.infiniteLoading && this.$refs.infiniteLoading.stateChanger.complete();
1229
- }
1230
- this.loading = false;
1231
- };
1232
- const bodyRequest = this.getBodyRequest(search);
1233
- this.postRequest(bodyRequest, loadItems);
1234
- },
1235
- /**
1236
- * Metodo llamado por el componente infinteloading al hacer scroll, nadie más lo llama directamente
1237
- */
1238
- getMoreItemsFromPuiList(search) {
1239
- this.loading = true;
1240
- this.page++;
1241
- const bodyRequest = this.getBodyRequest(search);
1242
- const loadMoreItems = (response) => {
1243
- if (response && response.data) {
1244
- this.theItems = this.theItems.concat(response.data.data);
1245
- this.$refs.infiniteLoading.stateChanger.loaded();
1246
- if (response.data.totalPages <= this.page) {
1247
- this.$refs.infiniteLoading.stateChanger.complete();
1248
- }
1249
- }
1250
- this.loading = false;
1251
- };
1252
- this.postRequest(bodyRequest, loadMoreItems);
1253
- },
1254
- postRequest(body, successCallback) {
1255
- this.$puiRequests.postRequest(this.internalController, body, successCallback, (error) => {
1256
- console.log(error);
1257
- });
1258
- },
1259
- getBodyRequest(search) {
1260
- let paginateItemsParams = {
1261
- model: this.modelName,
1262
- filter: this.createFilter()
1263
- };
1264
-
1265
- paginateItemsParams.rows = this.rows;
1266
- paginateItemsParams.page = this.page;
1267
- paginateItemsParams.queryText = search;
1268
- paginateItemsParams.queryFields = this.internalQueryFields;
1269
-
1270
- const searchOrder = this.createOrder();
1271
- if (searchOrder) {
1272
- paginateItemsParams.order = searchOrder;
1273
- }
1274
- return paginateItemsParams;
1275
- },
1276
- createFilter() {
1277
- let theFilter = this.pui9filter;
1278
-
1279
- if (this.filterMap) {
1280
- const group = this.createRelatedComboFilterGroup();
1281
- if (group && group.rules && group.rules.length > 0) {
1282
- if (theFilter) {
1283
- theFilter.groups.push(group);
1284
- } else {
1285
- theFilter = group;
1286
- }
1287
- }
1288
- }
1289
-
1290
- if (this.fixedFilter && !this.isDisabled) {
1291
- if (theFilter) {
1292
- theFilter.groups.push(this.fixedFilter);
1293
- } else {
1294
- theFilter = this.fixedFilter;
1295
- }
1296
- }
1297
-
1298
- return theFilter;
1299
- },
1300
- createRelatedComboFilterGroup() {
1301
- const group = {
1302
- groupOp: this.filterMapOp ? this.filterMapOp.toLowerCase() : 'and',
1303
- rules: [],
1304
- groups: []
1305
- };
1306
-
1307
- if (this.multiple !== true) {
1308
- for (const colmodel in this.filterMap) {
1309
- const value = this.filterMap[colmodel];
1310
- if (Object.prototype.hasOwnProperty.call(this.filterMap, colmodel) && !this.hasEmptyValue(value)) {
1311
- group.rules.push({
1312
- field: colmodel,
1313
- op: 'eq',
1314
- data: value
1315
- });
1316
- }
1317
- }
1318
- } else {
1319
- // TODO: multiple with filter...
1320
- }
1321
-
1322
- return group;
1323
- },
1324
- createOrder() {
1325
- if (!this.order) {
1326
- return null;
1327
- }
1328
- const searchOrder = [];
1329
- for (const column in this.order) {
1330
- const direction = this.order[column];
1331
- searchOrder.push({ column: column, direction: direction });
1332
- }
1333
-
1334
- return searchOrder;
1335
- },
1336
- checkForNestedFields(stringField) {
1337
- if (stringField instanceof Function) {
1338
- return false;
1339
- }
1340
-
1341
- return stringField.split('.').length > 1;
1342
- },
1343
- getFilterRequest(itemsToSelect) {
1344
- const filter = {
1345
- groupOp: 'and',
1346
- rules: [],
1347
- groups: []
1348
- };
1349
-
1350
- const itemValuesToSearch = this.itemValueMultiple === false ? [this.itemValue] : this.itemValue;
1351
- const itemsToSearch = itemsToSelect || this.itemsToSelect;
1352
-
1353
- itemsToSearch.forEach((itemToSearch) => {
1354
- itemValuesToSearch.forEach((pkProperty) => {
1355
- if (itemToSearch && !this.hasEmptyValue(itemToSearch[pkProperty])) {
1356
- filter.rules.push({ field: pkProperty, op: 'eq', data: itemToSearch[pkProperty] });
1357
- }
1358
- });
1359
- });
1360
-
1361
- if (this.filterMap) {
1362
- const group = this.createRelatedComboFilterGroup();
1363
- if (group && group.rules && group.rules.length > 0) {
1364
- filter.groups.push(group);
1365
- }
1366
- }
1367
-
1368
- if (this.fixedFilter && !this.isDisabled) {
1369
- filter.groups.push(this.fixedFilter);
1370
- }
1371
-
1372
- return filter;
1373
- },
1374
- getSelectedItems() {
1375
- for (let i = 0, length = this.itemsToSelect.length; i < length; i++) {
1376
- this.selectItemById(this.itemsToSelect[i][this.itemValue] || this.itemsToSelect[i], this.itemsToSelect[i]);
1377
- }
1378
- this.checkSelectedItems();
1379
- if (!this.hasEmptyValue(this.modelFormMapping, this.selectedItems)) {
1380
- this.replaceMapping();
1381
- }
1382
- },
1383
- selectItemById(id) {
1384
- var itemValueTemp = this.itemValue;
1385
- var selectedItem;
1386
- for (let index = 0, length = this.theItems.length; index < length; index++) {
1387
- var item = this.theItems[index];
1388
- if (this.itemValueMultiple === true) {
1389
- let allPropsEqual = false;
1390
- for (let i = 0, length = this.itemValue.length; i < length; i++) {
1391
- if (item[this.itemValue[i]] !== id[this.itemValue[i]]) {
1392
- allPropsEqual = true;
1393
- break;
1394
- }
1395
- }
1396
- if (allPropsEqual === true) {
1397
- continue;
1398
- }
1399
- selectedItem = this.return_object ? item : id;
1400
- if (this.multiple === false) {
1401
- this.selectedItems = selectedItem;
1402
- } else {
1403
- this.selectedItems.push(selectedItem);
1404
- }
1405
- //eslint-disable-next-line no-useless-return
1406
- return;
1407
- } else if (item[itemValueTemp] === id) {
1408
- selectedItem = this.return_object ? item : id;
1409
- if (this.multiple === false) {
1410
- this.selectedItems = selectedItem;
1411
- } else {
1412
- this.selectedItems.push(selectedItem);
1413
- }
1414
- //eslint-disable-next-line no-useless-return
1415
- return;
1416
- } else if (item === id) {
1417
- this.selectedItems = item;
1418
- return;
1419
- }
1420
- }
1421
- },
1422
- getSelectedItemsFromPuiList() {
1423
- const filter = this.getFilterRequest();
1424
- if (this.hasEmptyValue(filter.rules) && this.hasEmptyValue(filter.groups)) {
1425
- if (this.firstLoad) this.firstLoad = false;
1426
- return;
1427
- }
1428
-
1429
- const data = {
1430
- model: this.modelName,
1431
- queryFields: this.internalQueryFields,
1432
- filter
1433
- };
1434
-
1435
- const searchOrder = this.createOrder();
1436
- if (searchOrder) {
1437
- data.order = searchOrder;
1438
- }
1439
-
1440
- const itemsToSelectOldValue = JSON.stringify(this.itemsToSelect);
1441
-
1442
- let promise = new Promise((resolve) => {
1443
- this.$puiRequests.postRequest(this.internalController, data, (response) => {
1444
- if (response && response.data) {
1445
- if (this.multiple === false) {
1446
- const itemsToSelectHaveValue = this.haveItemsToSelectValue();
1447
- if (itemsToSelectHaveValue) {
1448
- const itemsToSelectNewValue = JSON.stringify(this.itemsToSelect);
1449
- if (itemsToSelectNewValue != itemsToSelectOldValue && this.firstLoad) {
1450
- this.theItems = response.data.data;
1451
- this.selectItem(this.itemsToSelect);
1452
- } else {
1453
- this.selectedItems = response.data.data[0];
1454
- }
1455
- } else {
1456
- this.selectedItems = this.multiple ? [] : null;
1457
- }
1458
- } else {
1459
- this.selectedItems = response.data.data;
1460
- }
1461
- this.checkSelectedItems();
1462
- resolve(response.data.data);
1463
- if (this.firstLoad) this.firstLoad = false;
1464
- }
1465
- });
1466
- });
1467
-
1468
- if (!this.firstLoad) {
1469
- this.requestDataPromise = promise;
1470
- }
1471
- },
1472
- haveItemsToSelectValue() {
1473
- const itemValues = this.itemValueMultiple === false ? [this.itemValue] : this.itemValue;
1474
- let itemsToSelectHasValue = true;
1475
- this.itemsToSelect.forEach((item) => {
1476
- itemValues.forEach((pkProperty) => {
1477
- if (item && this.hasEmptyValue(item[pkProperty])) {
1478
- itemsToSelectHasValue = false;
1479
- }
1480
- });
1481
- });
1482
- if (!itemsToSelectHasValue && this.onPuiSelectItemsToSelect) {
1483
- itemsToSelectHasValue = true;
1484
- this.onPuiSelectItemsToSelect.forEach((item) => {
1485
- itemValues.forEach((pkProperty) => {
1486
- if (this.hasEmptyValue(item[pkProperty])) {
1487
- itemsToSelectHasValue = false;
1488
- }
1489
- });
1490
- });
1491
- this.onPuiSelectItemsToSelect = null;
1492
- }
1493
- return itemsToSelectHasValue;
1494
- },
1495
- selectItems() {
1496
- this.selectedItems = this.multiple ? [] : null;
1497
- if (this.multiple === true) {
1498
- this.selectedItems = [];
1499
- }
1500
-
1501
- // only for multiselect
1502
- this.setAvailableItems && this.setAvailableItems();
1503
- if (this.hasEmptyValue(this.itemsToSelect)) {
1504
- return;
1505
- }
1506
-
1507
- if (this.multiple === false && this.modelName) {
1508
- this.getSelectedItemsFromPuiList();
1509
- } else {
1510
- this.getSelectedItems();
1511
- }
1512
-
1513
- this.selected = true;
1514
- },
1515
- /**
1516
- * Este método se aplica en el componente pui-select y cuando hay un controlador de pui.
1517
- *
1518
- * Lo que hace es: como el listado de items cuando hay un controlador es paginado, puede ser que,
1519
- * los items a seleccionar no se encuentren en la primera página de items.
1520
- * Por esto comprueba que si no coincide itemsToSelect y selectedItems, y si no coinciden,
1521
- * cargará los primeros a theItems y después seleccionará
1522
- **/
1523
- checkSelectedItems() {
1524
- if (this.modelName) {
1525
- if (this.multiple === false) {
1526
- // si es la selección inicial y itemsToSelect no esta en theItems, por tanto no se ha seleccionado
1527
- if (this.selected === false && !this.selectedItems && this.itemsToSelect && this.itemsToSelect.length > 0) {
1528
- this.selectedItems = this.itemsToSelect[0];
1529
- }
1530
-
1531
- this.selectedItems && this.theItems.unshift(this.selectedItems);
1532
- } else {
1533
- // si no es la selección inicial, viene de una selección por un getItems de una búsqueda, ya no utilizamos itemsToSelect
1534
- if (this.selected === true) {
1535
- this.selectedItems.forEach((item) => {
1536
- this.theItems.unshift(item);
1537
- });
1538
- // si es la selección inicial
1539
- } else {
1540
- if (this.selectedItems.length < this.itemsToSelect.length) {
1541
- this.selectedItems = [];
1542
- this.itemsToSelect.forEach((item) => {
1543
- this.theItems.unshift(item);
1544
- this.selectedItems.push(item);
1545
- });
1546
- }
1547
- }
1548
- }
1549
- }
1550
- },
1551
- resetItems(newValue) {
1552
- if (this.hasEmptyValue(newValue)) {
1553
- this.selectedItems = this.multiple ? [] : null;
1554
- }
1555
- if (this.hasEmptyValue(this.selectedItems)) {
1556
- return;
1557
- }
1558
- let filtersValid = true;
1559
- for (var pkProperty in this.filterMap) {
1560
- let parentPkProperty = pkProperty;
1561
- if (this.filterParentMap && this.filterParentMap[pkProperty]) {
1562
- parentPkProperty = this.filterParentMap[pkProperty];
1563
- }
1564
- if (
1565
- !this.hasEmptyValue(newValue[pkProperty]) &&
1566
- newValue[pkProperty] !== this.selectedItems[pkProperty] &&
1567
- !this.hasEmptyValue(newValue[parentPkProperty]) &&
1568
- newValue[parentPkProperty] !== this.selectedItems[pkProperty]
1569
- ) {
1570
- filtersValid = false;
1571
- }
1572
- }
1573
- if (!filtersValid || !this.filterMap) this.selectedItems = this.multiple ? [] : null;
1574
- },
1575
- selectPreviousValidItems() {
1576
- if (this.multiple === true) {
1577
- this.selectedItems = [];
1578
- this.previousSelectedItems.forEach((previousItem) => {
1579
- const strPkPrevItem = JSON.stringify(this.getPkFromItem(previousItem));
1580
- this.theItems.forEach((requestItem) => {
1581
- const strPkRequestItem = JSON.stringify(this.getPkFromItem(requestItem));
1582
- if (strPkPrevItem === strPkRequestItem) {
1583
- this.selectedItems.push(previousItem);
1584
- }
1585
- });
1586
- });
1587
- } else {
1588
- const strPkPrevItem = JSON.stringify(this.getPkFromItem(this.previousSelectedItems));
1589
- this.theItems.forEach((requestItem) => {
1590
- const strPkRequestItem = JSON.stringify(this.getPkFromItem(requestItem));
1591
- if (strPkPrevItem === strPkRequestItem) {
1592
- this.theItems.unshift(requestItem);
1593
- this.selectedItems = requestItem;
1594
- }
1595
- });
1596
- }
1597
- },
1598
- getPkFromItem(item) {
1599
- const theItemPkFields = Array.isArray(this.itemValue) ? this.itemValue : [this.itemValue];
1600
- const objectPk = {};
1601
- theItemPkFields.forEach((pkField) => {
1602
- objectPk[pkField] = item[pkField];
1603
- });
1604
- return objectPk;
1605
- },
1606
- selectItem(itemToSelect) {
1607
- this.itemProgrammaticallySelected = true;
1608
- const newSelected = this.theItems.find((element) => {
1609
- for (const key in itemToSelect[0]) {
1610
- if (Object.prototype.hasOwnProperty.call(itemToSelect[0], key)) {
1611
- if (itemToSelect[0][key] !== element[key]) return false;
1612
- }
1613
- }
1614
- return true;
1615
- });
1616
- const filter = this.getFilterRequest(itemToSelect);
1617
- if (this.hasEmptyValue(newSelected) && this.modelName && filter.rules.length > 0) {
1618
- const params = {
1619
- model: this.modelName,
1620
- filter: filter
1621
- };
1622
- this.postRequest(params, (response) => {
1623
- if (response && response.data && response.data.data.length > 0) {
1624
- this.theItems = this.theItems.concat(this.multiple === true ? response.data.data : [response.data.data[0]]);
1625
- this.selectedItems = this.multiple === true ? response.data.data : response.data.data[0];
1626
- } else {
1627
- this.selectedItems = undefined;
1628
- }
1629
- });
1630
- } else {
1631
- this.selectedItems = newSelected;
1632
- }
1633
- },
1634
- reactiveHandler(newValue) {
1635
- if (this.reactive) {
1636
- if ((!this.itemManuallySelected || Object.values(newValue[0]).some((x) => !x)) && !this.firstLoad) {
1637
- this.itemManuallySelected = false;
1638
- this.selectItem(newValue);
1639
- } else {
1640
- if (this.requestDataPromise) {
1641
- this.requestDataPromise.then((theItems) => {
1642
- if (!this.itemManuallySelected) {
1643
- this.theItems = theItems;
1644
- this.selectItem(newValue);
1645
- }
1646
- delete this.requestDataPromise;
1647
- });
1648
- }
1649
- this.itemManuallySelected = false;
1650
- }
1651
- }
1652
- },
1653
- hasEmptyValue(...values) {
1654
- return values.some(
1655
- (value) =>
1656
- value === undefined ||
1657
- value === null ||
1658
- (typeof value === 'string' && value.trim() === '') ||
1659
- (Array.isArray(value) && value.length === 0)
1660
- );
1661
- },
1662
- copySelectedItemToClipboard() {
1663
- let selectedText = this.$refs.arrowUp.$el.firstChild.firstChild.firstChild.firstChild.firstChild.innerHTML;
1664
- navigator.clipboard.writeText(selectedText).then(
1665
- () => {
1666
- // console.log('Content copied to clipboard');
1667
- },
1668
- () => {
1669
- // console.error('Failed to copy');
1670
- }
1671
- );
1672
- }
1673
- }
1674
- };
1675
- </script>