pui9-datatables 1.16.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.
Files changed (86) hide show
  1. package/README.md +24 -0
  2. package/dist/demo.html +10 -0
  3. package/dist/pui9-datatables.common.js +89206 -0
  4. package/dist/pui9-datatables.common.js.map +1 -0
  5. package/dist/pui9-datatables.css +5 -0
  6. package/dist/pui9-datatables.umd.js +89216 -0
  7. package/dist/pui9-datatables.umd.js.map +1 -0
  8. package/dist/pui9-datatables.umd.min.js +55 -0
  9. package/dist/pui9-datatables.umd.min.js.map +1 -0
  10. package/package-lock.json +15982 -0
  11. package/package.json +89 -0
  12. package/src/App.vue +37 -0
  13. package/src/components/desktop/PuiDatatable.vue +709 -0
  14. package/src/components/desktop/PuiQuickEditionDatatable.vue +548 -0
  15. package/src/components/desktop/PuiSimpleDatatable.vue +1498 -0
  16. package/src/components/desktop/datatables.net-plugins/pagination/input.js +213 -0
  17. package/src/components/desktop/footer/PuiDatatableFooter.vue +65 -0
  18. package/src/components/desktop/footer/PuiGridActionFooter.vue +132 -0
  19. package/src/components/desktop/quickedition/PuiQuickEditionExportBtn.vue +138 -0
  20. package/src/components/desktop/quickedition/PuiQuickEditionForm.vue +60 -0
  21. package/src/components/desktop/quickedition/PuiQuickEditionToolbar.vue +144 -0
  22. package/src/components/desktop/row/PuiGridRowActions.vue +112 -0
  23. package/src/components/desktop/subdialogs/PuiDatatableColumnMenu.vue +186 -0
  24. package/src/components/desktop/toolbar/PuiGridToolbar.vue +310 -0
  25. package/src/components/desktop/toolbar/actions/PuiGridActionListItem.vue +34 -0
  26. package/src/components/desktop/toolbar/actions/PuiGridActionsBtn.vue +56 -0
  27. package/src/components/desktop/toolbar/actions/PuiGridActionsDialog.vue +66 -0
  28. package/src/components/desktop/toolbar/actions/audit/PuiAuditDialog.vue +92 -0
  29. package/src/components/desktop/toolbar/actions/docgen/PuiDocgenTemplateMatchingsDialog.vue +139 -0
  30. package/src/components/desktop/toolbar/actions/docgen/PuiDocgenTemplateParametersDialog.vue +317 -0
  31. package/src/components/desktop/toolbar/actions/importexport/PuiGridExportDialog.vue +187 -0
  32. package/src/components/desktop/toolbar/actions/importexport/PuiGridImportDialog.vue +421 -0
  33. package/src/components/desktop/toolbar/export/PuiGridExportBtn.vue +175 -0
  34. package/src/components/desktop/toolbar/filtercombo/PuiGridFilterCombo.vue +237 -0
  35. package/src/components/desktop/toolbar/filtering/PuiGridFilterBtns.vue +163 -0
  36. package/src/components/desktop/toolbar/filtering/PuiGridFilterDialog.vue +434 -0
  37. package/src/components/desktop/toolbar/filtering/PuiGridFilterGroup.vue +313 -0
  38. package/src/components/desktop/toolbar/filtering/PuiGridFilterListBtn.vue +85 -0
  39. package/src/components/desktop/toolbar/filtering/PuiGridFilterListDialog.vue +254 -0
  40. package/src/components/desktop/toolbar/filtering/PuiGridFilterListItem.vue +192 -0
  41. package/src/components/desktop/toolbar/filtering/PuiGridFilterRule.vue +517 -0
  42. package/src/components/desktop/toolbar/grid-configuration/PuiGridConfBtns.vue +99 -0
  43. package/src/components/desktop/toolbar/grid-configuration/PuiGridConfDialog.vue +640 -0
  44. package/src/components/desktop/toolbar/grid-configuration/PuiSaveConfigDialog.vue +154 -0
  45. package/src/components/desktop/toolbar/row/PuiGridCreateBtn.vue +39 -0
  46. package/src/components/desktop/toolbar/row/PuiGridDeleteBtn.vue +86 -0
  47. package/src/components/desktop/toolbar/row/PuiGridRefreshBtn.vue +39 -0
  48. package/src/components/desktop/toolbar/row/PuiGridUpdateBtn.vue +56 -0
  49. package/src/components/desktop/toolbar/searching/PuiGridSearcher.vue +67 -0
  50. package/src/components/desktop/toolbar/searching/PuiGridSearcherColumnsList.vue +43 -0
  51. package/src/components/desktop/toolbar/sorting/PuiGridSortBtn.vue +44 -0
  52. package/src/components/desktop/toolbar/sorting/PuiGridSortDialog.vue +113 -0
  53. package/src/components/mobile/PuiDatalist.vue +477 -0
  54. package/src/components/mobile/PuiSimpleDatalist.vue +313 -0
  55. package/src/components/mobile/actions/PuiListActionListItem.vue +34 -0
  56. package/src/components/mobile/actions/PuiListActionsBtn.vue +38 -0
  57. package/src/components/mobile/actions/PuiListActionsDialog.vue +66 -0
  58. package/src/components/mobile/footer/PuiListActionFooter.vue +56 -0
  59. package/src/components/mobile/toolbar/PuiListToolbar.vue +60 -0
  60. package/src/components/mobile/toolbar/searching/PuiListSearcher.vue +53 -0
  61. package/src/components/mobile/toolbar/searching/PuiListSearcherColumnsList.vue +43 -0
  62. package/src/components/mobile/toolbar/sorting/PuiListSortBtn.vue +46 -0
  63. package/src/components/mobile/toolbar/sorting/PuiListSortDialog.vue +140 -0
  64. package/src/components/puiaudit/PuiAuditForm.vue +107 -0
  65. package/src/generalActions.js +135 -0
  66. package/src/index.js +31 -0
  67. package/src/main.js +67 -0
  68. package/src/mixins/PuiActionsBtnMixin.js +287 -0
  69. package/src/mixins/PuiActionsDialogMixin.js +161 -0
  70. package/src/mixins/PuiActionsListItemMixin.js +62 -0
  71. package/src/mixins/PuiDatatablesKeepPage.js +15 -0
  72. package/src/mixins/PuiGridFormMethodsMixin.js +133 -0
  73. package/src/mixins/PuiModelConfigurationMixin.js +15 -0
  74. package/src/mixins/PuiSearcherColumnsListMixin.js +108 -0
  75. package/src/mixins/PuiSearcherMixin.js +192 -0
  76. package/src/mixins/PuiSortBtnMixin.js +54 -0
  77. package/src/mixins/PuiSortDialogMixin.js +256 -0
  78. package/src/mixins/PuiToolbarBtnMixin.js +66 -0
  79. package/src/mixins/PuiToolbarDialogMixin.js +12 -0
  80. package/src/router.js +18 -0
  81. package/src/tests/PuiContainer.vue +139 -0
  82. package/src/tests/PuiProfileTestSimpleDatatable.vue +66 -0
  83. package/src/tests/PuiUserTestCompleteDatatable.vue +126 -0
  84. package/src/tests/PuiVariableTestQuickEditionDatatable.vue +39 -0
  85. package/src/tests/PuiVariableTestQuickEditionForm.vue +18 -0
  86. package/src/tests/modelConfigurations.json +3516 -0
@@ -0,0 +1,1498 @@
1
+ <template>
2
+ <v-layout class="ml-1 mr-1">
3
+ <v-flex xs12 :id="getDivTableId">
4
+ <!-- The table -->
5
+ <div class="ml-3 mr-3">
6
+ <table :id="completeGridName" :ref="completeGridName" class="cell-border hover stripe nowrap full-width">
7
+ <thead :id="completeGridNameHeader" :ref="completeGridNameHeader"></thead>
8
+ <tbody :id="completeGridNameBody" :ref="completeGridNameBody"></tbody>
9
+ </table>
10
+ </div>
11
+ </v-flex>
12
+ <pui-datatable-column-menu
13
+ v-if="headerCreated"
14
+ :colHeader="$colHeader"
15
+ :modelName="modelName"
16
+ :grouped="grouped"
17
+ :fixed="fixed"
18
+ ></pui-datatable-column-menu>
19
+ <pui-grid-row-actions
20
+ v-if="data === undefined && showGridRowActions"
21
+ :modelName="modelName"
22
+ :mouseOut="mouseOutOfTable"
23
+ :showViewButton="showGridRowActionsView"
24
+ :showEditButton="showGridRowActionsEdit"
25
+ :showDeleteButton="showGridRowActionsDelete"
26
+ ></pui-grid-row-actions>
27
+ <pui-grid-action-footer
28
+ v-show="actionFooter"
29
+ :action="actionRunning"
30
+ :registries="selectedRows"
31
+ :modelName="modelName"
32
+ ></pui-grid-action-footer>
33
+ <pui-select-detail-dialog
34
+ v-if="showDetailModalDialog"
35
+ :parentId="`${completeGridName}_detail`"
36
+ :componentLabel="detailComponentLabel"
37
+ :componentName="detailComponentName"
38
+ :componentPk="detailComponentPk"
39
+ :componentMethod="detailComponentMethod"
40
+ :modelName="detailModelName"
41
+ ></pui-select-detail-dialog>
42
+ </v-layout>
43
+ </template>
44
+
45
+ <script>
46
+ import $ from 'jquery';
47
+ import dt from 'datatables.net'; // eslint-disable-line
48
+ import 'datatables.net-dt/css/jquery.dataTables.css';
49
+ import select from 'datatables.net-select'; // eslint-disable-line
50
+ import 'datatables.net-select-dt/css/select.dataTables.css';
51
+ import colreorder from 'datatables.net-colreorder'; // eslint-disable-line
52
+ import 'datatables.net-colreorder-dt/css/colReorder.dataTables.css';
53
+ import rowgroup from 'datatables.net-rowgroup'; // eslint-disable-line
54
+ import 'datatables.net-rowgroup-dt/css/rowGroup.dataTables.css';
55
+ import keytable from 'datatables.net-keytable'; // eslint-disable-line
56
+ import 'datatables.net-keytable-dt/css/keyTable.dataTables.css';
57
+ import fixedcolumns from 'datatables.net-fixedcolumns'; // eslint-disable-line
58
+ import 'datatables.net-fixedcolumns-dt/css/fixedColumns.dataTables.css';
59
+ import fixedheader from 'datatables.net-fixedheader'; // eslint-disable-line
60
+ import 'datatables.net-fixedheader-dt/css/fixedHeader.dataTables.css';
61
+
62
+ import plugins from './datatables.net-plugins/pagination/input.js'; // eslint-disable-line
63
+
64
+ import PuiDatatableColumnMenu from './subdialogs/PuiDatatableColumnMenu';
65
+ import PuiGridActionFooter from './footer/PuiGridActionFooter';
66
+ import PuiGridRowActions from './row/PuiGridRowActions';
67
+
68
+ import { debounce } from 'lodash';
69
+
70
+ export default {
71
+ name: 'PuiSimpleDatatable',
72
+ components: {
73
+ PuiDatatableColumnMenu,
74
+ PuiGridActionFooter,
75
+ PuiGridRowActions
76
+ },
77
+ props: {
78
+ columns: {
79
+ type: Array,
80
+ required: true
81
+ },
82
+ modelName: {
83
+ type: String,
84
+ required: true
85
+ },
86
+ modelNameSuffix: {
87
+ type: String,
88
+ default: ''
89
+ },
90
+ info: {
91
+ type: Boolean,
92
+ default: true
93
+ },
94
+ lengthMenu: {
95
+ type: [Array],
96
+ default: () => [10, 20, 30, 50, 100]
97
+ },
98
+ parentModelName: {
99
+ type: String,
100
+ default: null
101
+ },
102
+ pageLength: {
103
+ type: Number
104
+ },
105
+ search: {
106
+ type: Boolean,
107
+ default: false
108
+ },
109
+ tableMaxHeight: {
110
+ type: Number,
111
+ default: 70
112
+ },
113
+ showPaginator: {
114
+ type: Boolean,
115
+ default: true
116
+ },
117
+ scrollX: {
118
+ type: Boolean,
119
+ default: true
120
+ },
121
+ scrollY: {
122
+ type: [Boolean, String],
123
+ default: true
124
+ },
125
+ scrollCollapse: {
126
+ type: Boolean,
127
+ default: false
128
+ },
129
+ data: {
130
+ type: Array
131
+ },
132
+ showActions: {
133
+ type: Boolean,
134
+ default: false
135
+ },
136
+ showRowActions: {
137
+ type: Boolean,
138
+ default: true
139
+ },
140
+ // external search is an array with 2 elements, searchText (String) and searchColumns (Array)
141
+ externalSearch: {
142
+ type: Array,
143
+ default: () => null
144
+ },
145
+ externalFilter: {
146
+ type: Object,
147
+ default: null
148
+ },
149
+ modelColumnDefs: {
150
+ type: Array
151
+ },
152
+ masterDetail: {
153
+ type: Boolean,
154
+ default: false
155
+ },
156
+ navigableDetail: {
157
+ type: Boolean,
158
+ default: true
159
+ },
160
+ isEditableRegistry: {
161
+ type: Function,
162
+ default: () => {
163
+ return true;
164
+ }
165
+ },
166
+ selectStyle: {
167
+ type: String,
168
+ default: 'single'
169
+ },
170
+ readOnly: {
171
+ type: Boolean,
172
+ default: false
173
+ },
174
+ defaultActionRead: {
175
+ type: Boolean,
176
+ default: false
177
+ },
178
+ modalDialog: {
179
+ type: Boolean,
180
+ default: false
181
+ }
182
+ },
183
+ data() {
184
+ return {
185
+ scrollingDown: false,
186
+ scrollingUp: false,
187
+ headerCreated: false,
188
+ table: null,
189
+ datatablesOrderApplied: [{ column: null, dir: null }],
190
+ order: [],
191
+ orderFixed: null,
192
+ fixed: false,
193
+ grouped: false,
194
+ model: {},
195
+ rows: 20,
196
+ top: 0,
197
+ page: 1,
198
+ loadedConfig: false,
199
+ searchText: null,
200
+ searchColumns: null,
201
+ gridCompleted: false,
202
+ completeGridName: '',
203
+ selectedRows: [],
204
+ disabledRows: [],
205
+ footerClassPrefix: 'bottom',
206
+ headerClassPrefix: 'dataTables_scrollHead',
207
+ actionFooter: false,
208
+ actionRunning: null,
209
+ pkColumns: [],
210
+ mouseOutOfTable: false,
211
+ rowsSelectedChecked: 0,
212
+ actionsView: true,
213
+ actionsEdit: true,
214
+ actionsDelete: true,
215
+ showGridRowActions: this.showRowActions && this.$store.state.grid.showRowActions,
216
+ showGridRowActionsView: false,
217
+ showGridRowActionsEdit: false,
218
+ showGridRowActionsDelete: false,
219
+ showDetailModalDialog: false,
220
+ debouncedAdjustTableColumns: null
221
+ };
222
+ },
223
+ computed: {
224
+ getDivTableId() {
225
+ return this.completeGridName + '_datatable_container';
226
+ },
227
+ completeGridNameHeader() {
228
+ return this.completeGridName + '_header';
229
+ },
230
+ completeGridNameBody() {
231
+ return this.completeGridName + '_body';
232
+ },
233
+ isCompleteDataTable() {
234
+ return !(this.data !== undefined && this.data.length !== undefined);
235
+ },
236
+ onPuiExpandMenu() {
237
+ return this.$store.state.menu.expandMenuForce;
238
+ },
239
+ onPuiSecondMenuShowed() {
240
+ return this.$store.state.menu.secondMenuShowedForce;
241
+ }
242
+ },
243
+ methods: {
244
+ handleScroll(event) {
245
+ this.mouseOutOfTable = true;
246
+ if (this.$colHeader == undefined) {
247
+ return;
248
+ }
249
+ const el = event.currentTarget;
250
+ if (el.scrollTop === 0) {
251
+ this.scrollingUp = false;
252
+ this.$colHeader[0] && this.$colHeader[0].classList.remove(`${this.headerClassPrefix}--scrolling`);
253
+ } else {
254
+ this.scrollingUp === false && this.$colHeader[0].classList.add(`${this.headerClassPrefix}--scrolling`);
255
+ }
256
+ if (el.clientHeight + el.scrollTop === el.scrollHeight) {
257
+ this.scrollingDown = false;
258
+ this.$footer && this.$footer[0].classList.remove(`${this.footerClassPrefix}--scrolling`);
259
+ } else {
260
+ this.scrollingDown === false && this.$footer && this.$footer[0].classList.add(`${this.footerClassPrefix}--scrolling`);
261
+ }
262
+ },
263
+ getPKColumnsModel() {
264
+ if (!this.model) {
265
+ return;
266
+ }
267
+ var pks = [];
268
+ for (let index = 0, length = this.model.columns.length; index < length; index++) {
269
+ const column = this.model.columns[index];
270
+ if (column.isPk) {
271
+ pks.push(column.name);
272
+ }
273
+ }
274
+ return pks;
275
+ },
276
+ createIndexRowData(data) {
277
+ var pk = [];
278
+ for (let index = 0, length = this.pkColumns.length; index < length; index++) {
279
+ const field = this.pkColumns[index];
280
+ var value = data[field];
281
+ pk.push(value);
282
+ }
283
+ return pk.join('|');
284
+ },
285
+ getTableAPI() {
286
+ return $(this.$el)
287
+ .find('#' + this.completeGridName)
288
+ .dataTable();
289
+ },
290
+ redrawTable() {
291
+ $(this.$el)
292
+ .find('#' + this.completeGridName)
293
+ .dataTable();
294
+ },
295
+ createDatatable(fromReloadGrid) {
296
+ this.rowsSelectedChecked = 0;
297
+ this.headerCreated = false;
298
+ var gridName = this.completeGridName;
299
+
300
+ this.gridCompleted = false;
301
+ // Grouping is just for client side, so we have to check if there is a previous grid state and use this value and if it does not exist
302
+ // use the one from the configuration. Same for column search option.
303
+ if (!this.gridConfiguration) {
304
+ this.gridConfiguration = this.$store.getters.getCurrentGridConfiguration(this.modelName);
305
+ if (!this.gridConfiguration) {
306
+ this.gridConfiguration = this.$store.getters.getDefaultGridConfiguration(this.modelName);
307
+ }
308
+ if (this.gridConfiguration) {
309
+ this.fixed = this.gridConfiguration.configuration.pinColumn;
310
+ this.grouped = this.gridConfiguration.configuration.grouped;
311
+ this.order = this.gridConfiguration.configuration.order;
312
+ this.columnSearch = this.gridConfiguration.configuration.columnSearch;
313
+ this.rows = this.gridConfiguration.configuration.rows || this.rows;
314
+ this.page = this.gridConfiguration.configuration.page || 1;
315
+ }
316
+ }
317
+ if (this.model) {
318
+ if (!fromReloadGrid) {
319
+ this.selectedRows = this.model.selectedRows || [];
320
+ }
321
+ this.$puiEvents.$emit(`onPui-selectItem-dataTable-${this.modelName}${this.modelNameSuffix}`, this.selectedRows);
322
+ this.model.selectedRows = [];
323
+ }
324
+
325
+ //add the actions
326
+
327
+ if (!this.showActions) {
328
+ const modelFuncs = this.model ? this.model.functionalities : {};
329
+ this.actionsView = this.$store.getters.hasFunctionality(modelFuncs.get);
330
+ this.actionsEdit = this.$store.getters.hasFunctionality(modelFuncs.update);
331
+ this.actionsDelete = this.$store.getters.hasFunctionality(modelFuncs.delete);
332
+ }
333
+
334
+ if (this.showGridRowActions) {
335
+ this.showGridRowActionsView = this.actionsView;
336
+ this.showGridRowActionsEdit = this.actionsEdit;
337
+ this.showGridRowActionsDelete = this.actionsDelete;
338
+ }
339
+
340
+ var actionsHtml = '';
341
+ if (this.actionsView) {
342
+ actionsHtml += "<button class='dt-button action-btn'><i class='material-icons row_view row__action'>visibility</i></button>";
343
+ }
344
+ if (this.actionsEdit) {
345
+ actionsHtml += "<button class='dt-button action-btn'><i class='material-icons row_edit row__action'>edit</i></button>";
346
+ }
347
+ if (this.actionsDelete) {
348
+ actionsHtml += "<button class='dt-button action-btn'><i class='material-icons row_delete row__action'>delete</i></button>";
349
+ }
350
+ this.showActions &&
351
+ this.tableColumns.push({
352
+ title: '',
353
+ name: 'actions',
354
+ data: null,
355
+ visible: true,
356
+ //orderable: false,
357
+ className: 'center all actions',
358
+ defaultContent: actionsHtml
359
+ });
360
+
361
+ // configure the buttons
362
+ var buttons = [];
363
+ var ajax;
364
+
365
+ if (this.isCompleteDataTable === true) {
366
+ const url = this.$store.getters.getBaseUrl + this.model.url.list;
367
+ // configure the ajax request and response
368
+ ajax = {
369
+ url: url,
370
+ type: 'POST',
371
+ contentType: 'application/json',
372
+ beforeSend: (request) => {
373
+ let headers = this.$store.getters.getHttpRequestHeaders;
374
+ for (let prop in headers) {
375
+ request.setRequestHeader(prop, headers[prop]);
376
+ }
377
+ },
378
+ data: (data) => {
379
+ this.fixPaginatorIfSorted(data);
380
+ let queryFields = [];
381
+ data.columns.forEach((col) => {
382
+ if (col.name !== 'selection' && col.search.value != null && col.search.value.length > 0) {
383
+ queryFields.push(col.name);
384
+ }
385
+ });
386
+
387
+ this.searchColumns &&
388
+ this.searchColumns.forEach((col) => {
389
+ if (col.checked === true) {
390
+ queryFields.push(col.name);
391
+ }
392
+ });
393
+
394
+ let lang = this.$store.getters.getUserLanguage;
395
+ if (!this.parentModelName) {
396
+ this.$store.commit('setRequestLang', null);
397
+ }
398
+ let langStore = this.$store.getters.getRequestLang;
399
+ if (langStore !== null) {
400
+ lang = langStore;
401
+ }
402
+
403
+ var newData = {
404
+ model: this.model.name,
405
+ page: this.page,
406
+ rows: data.length,
407
+ queryLang: lang,
408
+ queryText: this.searchText,
409
+ queryFields: queryFields,
410
+ queryFlexible: false,
411
+ filter: this.filter,
412
+ order: this.order
413
+ };
414
+ return JSON.stringify(newData);
415
+ },
416
+ error: (xhr) => {
417
+ if (xhr.status === 401) {
418
+ (xhr.responseJSON.internalCode === 202 ||
419
+ xhr.responseJSON.internalCode === 207 ||
420
+ xhr.responseJSON.internalCode === 209) &&
421
+ this.$store.dispatch('puiLoginSessionExpired');
422
+ } else {
423
+ this.processing = false;
424
+ this.$puiNotify.error(xhr.responseJSON.message);
425
+ }
426
+ },
427
+ dataSrc: (data) => {
428
+ data.recordsTotal = data.totalRecords;
429
+ data.recordsFiltered = data.totalRecords;
430
+ delete data.currentPage;
431
+ delete data.totalPages;
432
+ delete data.totalRecords;
433
+ return data.data;
434
+ }
435
+ };
436
+ }
437
+ // configure the options
438
+ //TODO hay que añadir la opción para que se cargue toda la información de una como en pui(loadonce: true) y haga ordenaciones, búsquedas y filtros
439
+ //sobre los datos ya cargados y no haga petición ajax cada vez https://stackoverflow.com/questions/31097028/datatables-draw-without-ajax-call
440
+ var options = {
441
+ stateLoadParams: (settings, data) => {
442
+ // If the grid shows the column search
443
+ this.columnSearch = data.columnSearch;
444
+ },
445
+ dom: '<"left"B><"right">frt<"bottom"<"left"li><"right"p>>', // 'Blfrtip',
446
+ serverSide: true,
447
+ select: {
448
+ style: this.selectStyle
449
+ },
450
+ fixedColumns: {
451
+ leftColumns: this.fixed ? 2 : 0
452
+ },
453
+ colReorder: {
454
+ fixedColumnsLeft: 1
455
+ //realtime: false
456
+ },
457
+ fixedHeader: {
458
+ header: true
459
+ },
460
+ autoWidth: false,
461
+ columnDefs: this.columnDefs,
462
+ orderFixed: this.orderFixed,
463
+ order: [],
464
+ stateSave: false,
465
+ destroy: true,
466
+ responsive: false,
467
+ search: false,
468
+ searchDelay: 500,
469
+ info: this.info,
470
+ searching: true,
471
+ ordering: true,
472
+ processing: true,
473
+ paging: this.showPaginator,
474
+ pagingType: 'input',
475
+ lengthChange: true,
476
+ pageLength: this.pageLength || this.rows,
477
+ lengthMenu: this.lengthMenu,
478
+ bLengthChange: !this.$store.getters.isMobile,
479
+ buttons: buttons,
480
+ scrollX: this.scrollX,
481
+ scrollY: this.tableHeight(), //277 es la suma de todo lo que hay por arriba y por debajo de la tabla, nunca cambia
482
+ scrollCollapse: this.scrollCollapse,
483
+ columns: this.tableColumns,
484
+ rowCallback: (row, data) => {
485
+ if (this.selectedRows.length === 0) {
486
+ return;
487
+ }
488
+ for (let i = this.rowsSelectedChecked; i < this.selectedRows.length; i++) {
489
+ if (this.getPk(data) === Object.keys(this.selectedRows[i])[0]) {
490
+ this.$puiEvents.$emit(`onPui-selectItem-dataTable-${this.modelName}${this.modelNameSuffix}`, this.selectedRows);
491
+ this.rowSelectedIndex = row._DT_RowIndex;
492
+ this.rowsSelectedChecked++;
493
+ }
494
+ }
495
+ },
496
+ language: {
497
+ sEmptyTable: this.$t('sEmptyTable'),
498
+ sInfo: this.$t('sInfo'),
499
+ sInfoEmpty: this.$t('sInfoEmpty'),
500
+ sInfoFiltered: this.$t('sInfoFiltered'),
501
+ sInfoPostFix: this.$t('sInfoPostFix'),
502
+ sInfoThousands: this.$t('sInfoThousands'),
503
+ sLengthMenu: this.$t('sLengthMenu'),
504
+ sLoadingRecords: this.$t('sLoadingRecords'),
505
+ sProcessing: this.$t('sProcessing'),
506
+ sSearch: this.$t('sSearch'),
507
+ sZeroRecords: this.$t('sZeroRecords'),
508
+ oPaginate: {
509
+ sFirst: '<i class="fal fa-arrow-to-left"></i>',
510
+ sLast: '<i class="fal fa-arrow-to-right"></i>',
511
+ sNext: '<i class="fal fa-arrow-right"></i>',
512
+ sPrevious: '<i class="fal fa-arrow-left"></i>'
513
+ },
514
+ oAria: {
515
+ sSortAscending: this.$t('sSortAscending'),
516
+ sSortDescending: this.$t('sSortDescending')
517
+ },
518
+ processing: '<i class="far fa-spinner fa-spin fa-3x fa-fw"></i><span class="sr-only">Loading...</span>'
519
+ },
520
+ initComplete: () => {
521
+ this.gridCompleted = true;
522
+ this.headerCreated = false;
523
+ if (this.page !== 1) {
524
+ this.table.page(this.page - 1).draw(false);
525
+ }
526
+ if (this.selectedRows.length === 1 && this.rowsSelectedChecked !== 1) {
527
+ this.showSelectedRowInAnotherPageMessage();
528
+ }
529
+
530
+ // Enable the column search
531
+ if (this.columnSearch) {
532
+ this.enableColumnSearch(this.columnSearch);
533
+ }
534
+ if (this.isCompleteDataTable === true) {
535
+ $(this.$refs[this.completeGridNameHeader]).parent().attr('style', 'border-bottom: none !important');
536
+ const colHeader = $(this.$refs[this.completeGridNameHeader]).parent().parent().parent();
537
+ if (colHeader !== this.$colHeader) {
538
+ this.headerCreated = true;
539
+ }
540
+ this.$colHeader = colHeader;
541
+ }
542
+ // Adjust the height
543
+ this.adjustGridHeight();
544
+
545
+ // Resize the table when the parent container is resized
546
+ this.$puiEvents.$on('onPuiMultiPanelChanged', () => {
547
+ this.table.columns.adjust().draw();
548
+ });
549
+
550
+ // Refresh data when a row is deleted
551
+ this.$puiEvents.$on(`onPui-deleteRow-dataTable-${this.modelName}${this.modelNameSuffix}`, () => {
552
+ this.isCompleteDataTable && this.table.ajax.reload().draw();
553
+ });
554
+ if (!this.table) {
555
+ this.table = $(this.$el)
556
+ .find('#' + gridName)
557
+ .dataTable()
558
+ .api();
559
+ }
560
+ if (this.grouped === true) {
561
+ this.table.colReorder.disable();
562
+ } else {
563
+ this.table.colReorder.enable();
564
+ }
565
+ this.registerDatatableListeners();
566
+
567
+ if (this.selectedRows.length === 1 && this.rowsSelectedChecked === 1 && this.rowSelectedIndex !== undefined) {
568
+ let row = this.table.row(this.rowSelectedIndex);
569
+ row.select();
570
+ // refresh data in selectedRows from datatable
571
+ let rowObj = {};
572
+ rowObj[this.getPk(row.data())] = row.data();
573
+ this.selectedRows = [rowObj];
574
+ this.$puiEvents.$emit(`onPui-selectItem-dataTable-${this.modelName}${this.modelNameSuffix}`, this.selectedRows);
575
+ } else {
576
+ this.selectedRows = [];
577
+ this.$puiEvents.$emit(`onPui-clearSelection-dataTable-${this.modelName}${this.modelNameSuffix}`);
578
+ }
579
+
580
+ if (this.selectStyle === 'multi') {
581
+ this.addSelectAllCheckbox(this);
582
+ }
583
+ }
584
+ };
585
+ if (ajax) {
586
+ options.ajax = ajax;
587
+ } else {
588
+ options.serverSide = false;
589
+ options.data = this.data;
590
+ }
591
+
592
+ const model = this.$store.getters.getModelByName(this.modelName);
593
+ if (!ajax || this.$store.getters.hasFunctionality(model.functionalities.list)) {
594
+ this.table = $(this.$el)
595
+ .find('#' + gridName)
596
+ .DataTable(options);
597
+ } else {
598
+ this.table = $(this.$el).find('#' + gridName);
599
+ }
600
+
601
+ this.$store.commit('puiModelsSetGridInitialized', { model: this.modelName, initialized: true });
602
+
603
+ // Move pagination dataTables_info from left to right container
604
+ if (this.showPaginator === true) {
605
+ this.$footer = $(this.$refs[this.completeGridName]).parent().parent().parent().find(`.${this.footerClassPrefix}`);
606
+ $(`#${gridName}_info`).prependTo(`#${this.completeGridName}_wrapper .${this.footerClassPrefix} .right`);
607
+ } else {
608
+ $(`#${gridName}_info`).remove();
609
+ }
610
+
611
+ this.$puiEvents.$emit(
612
+ `onPui-created-dataTable-${this.modelName}${this.modelNameSuffix}`,
613
+ this.$store.state.menu.expanded || this.$store.state.menu.expandMenu
614
+ );
615
+ },
616
+ showSelectedRowInAnotherPageMessage() {
617
+ //TODO, IMPLEMENTAR, QUE APAREZCA MENSAJE DE FILA SELECCIONADA EN OTRA PÁGINA EN EL FOOTER (.bottom)
618
+ },
619
+ registerDatatableListeners() {
620
+ var self = this;
621
+
622
+ if (this.isCompleteDataTable === true) {
623
+ this.table.on('column-reorder', () => {
624
+ this.$puiEvents.$emit(`onPui-colReorder-dataTable-${this.modelName}${this.modelNameSuffix}`, this.table.colReorder.order());
625
+ });
626
+ this.table.on('mouseenter', 'tbody tr', (event) => {
627
+ const $row = $(event.currentTarget);
628
+ if ($row.hasClass('group')) {
629
+ return;
630
+ }
631
+ const hoverInfo = {
632
+ y: $row.position().top + 160 - this.table.scrollDiv[0].scrollTop - this.toolbarSingleRowNegativeHeight,
633
+ row: this.table.row($row)
634
+ };
635
+ this.mouseOutOfTable = false;
636
+ this.$puiEvents.$emit(`onPui-hoverRow-dataTable-${this.modelName}${this.modelNameSuffix}`, hoverInfo);
637
+ });
638
+ if (this.actionsView && this.navigableDetail) {
639
+ // row double click
640
+ this.table.on('dblclick', 'tr', function (e) {
641
+ if (self.dblclick) {
642
+ return;
643
+ }
644
+ self.dblclick = true;
645
+ if (e.currentTarget.className !== 'group') {
646
+ var row = self.table.row(this);
647
+ if (self.actionsEdit && !self.readOnly && !self.defaultActionRead && self.isEditableRegistry(row.data())) {
648
+ self.editRegistry(row, 'update');
649
+ } else {
650
+ self.editRegistry(row, 'read');
651
+ }
652
+ }
653
+ setTimeout(function () {
654
+ self.dblclick = false;
655
+ }, 200);
656
+ });
657
+ }
658
+ // event for column visibility change
659
+ this.table.on('column-visibility.dt', () => {
660
+ if (!this.gridCompleted) {
661
+ return;
662
+ }
663
+
664
+ if (this.columnSearch) {
665
+ this.rebuildColumnFilters();
666
+ }
667
+ this.grouped && this.table.draw(false);
668
+ });
669
+
670
+ this.table.on('length.dt', (e, settings, len) => {
671
+ if (this.grouped) {
672
+ this.groupedFlag = true;
673
+ }
674
+ this.$puiEvents.$emit(`onPui-changeRowNum-dataTable-${this.modelName}${this.modelNameSuffix}`, len);
675
+ });
676
+ this.table.on('draw.dt', () => {
677
+ this.grouped === true /* && this.groupedFlag === true */ && this.groupRows(1);
678
+ this.actionRunning && this.applyDisableRowsByAction();
679
+ });
680
+
681
+ this.table.on('page.dt', () => {
682
+ if (this.grouped) {
683
+ this.groupedFlag = true;
684
+ }
685
+ this.rowsSelectedChecked = 0;
686
+ this.page = this.table.page.info().start / this.table.page.info().length + 1;
687
+ this.$puiEvents.$emit(`onPui-pageChange-dataTable-${this.modelName}${this.modelNameSuffix}`, this.page);
688
+ });
689
+ this.table.on('click', 'tr', function (e) {
690
+ if (self.dblclick) {
691
+ return;
692
+ }
693
+
694
+ const row = self.table.row(this);
695
+ const rowData = row.data();
696
+ if (!rowData) {
697
+ e.stopPropagation();
698
+ e.preventDefault();
699
+ return;
700
+ }
701
+
702
+ const rowPk = self.getPk(rowData);
703
+ const selectedRowObj = {};
704
+
705
+ for (let i = 0; i < self.disabledRows.length; i++) {
706
+ if (rowPk === self.disabledRows[i]) {
707
+ $(this).removeClass('selected');
708
+ e.stopPropagation();
709
+ e.preventDefault();
710
+ return;
711
+ }
712
+ }
713
+
714
+ setTimeout(function () {
715
+ if (self.dblclick) {
716
+ return;
717
+ }
718
+ for (let i = 0; i < self.selectedRows.length; i++) {
719
+ const selectedRow = self.selectedRows[i];
720
+ if (rowPk === Object.keys(selectedRow)[0]) {
721
+ self.selectedRows.splice(i, 1);
722
+ self.$puiEvents.$emit(`onPui-selectItem-dataTable-${self.modelName}${self.modelNameSuffix}`, self.selectedRows);
723
+ $(this).removeClass('selected');
724
+ e.stopPropagation();
725
+ e.preventDefault();
726
+ return;
727
+ } else if (self.table.select.style() === 'single') {
728
+ self.selectedRows.splice(i, 1);
729
+ }
730
+ }
731
+ selectedRowObj[rowPk] = rowData;
732
+ self.selectedRows.push(selectedRowObj);
733
+ self.$puiEvents.$emit(`onPui-selectItem-dataTable-${self.modelName}${self.modelNameSuffix}`, self.selectedRows);
734
+ $(this).addClass('selected');
735
+ }, 50);
736
+ });
737
+ this.table.on('click', 'tr.group', function (e) {
738
+ var target = $(e.target);
739
+
740
+ if (target.is('td')) {
741
+ target = target.parent();
742
+ }
743
+ if (target.is('tr')) {
744
+ let nextTr = target;
745
+ for (var i = 0; i < target.parent().children().length; i++) {
746
+ nextTr = nextTr.closest('tr').next('tr');
747
+ if (nextTr.hasClass('group')) {
748
+ break;
749
+ } else {
750
+ nextTr.toggle();
751
+ }
752
+ }
753
+ }
754
+ });
755
+ $(this.$refs[this.completeGridName]).on('mouseleave', () => {
756
+ this.mouseOutOfTable = true;
757
+ });
758
+ } else {
759
+ this.table.on('click', 'i.row_view', function (e) {
760
+ e.preventDefault();
761
+ if (self.actionsView) {
762
+ var tr = $(this).closest('tr');
763
+ var row = self.table.row(tr);
764
+ self.editRegistry(row, 'read');
765
+ }
766
+ });
767
+ // event for edit row
768
+ this.table.on('click', 'i.row_edit', function (e) {
769
+ e.preventDefault();
770
+ if (self.actionsEdit) {
771
+ var tr = $(this).closest('tr');
772
+ var row = self.table.row(tr);
773
+ self.editRegistry(row, 'update');
774
+ }
775
+ });
776
+
777
+ // event for delete row
778
+ this.table.on('click', 'i.row_delete', function (e) {
779
+ e.preventDefault();
780
+ if (self.actionsDelete) {
781
+ var tr = $(this).closest('tr');
782
+ var row = self.table.row(tr);
783
+ self.deleteRegistry(row);
784
+ }
785
+ });
786
+ }
787
+ this.table.scrollDiv = $(this.table.table().container()).find('.dataTables_scrollBody');
788
+ this.table.scrollDiv.on('scroll', (e) => {
789
+ this.handleScroll(e);
790
+ });
791
+ },
792
+ handleWheelRowActions(e) {
793
+ this.table.scrollDiv.scrollTop(this.table.scrollDiv.scrollTop() - e.wheelDeltaY);
794
+ },
795
+ createRegistry() {
796
+ this.goToElement(null, 'create');
797
+ },
798
+ editRegistry(row, readOrUpdate) {
799
+ this.selectedRows = [];
800
+ this.disabledRows = [];
801
+ const rowData = row.data();
802
+ if (!rowData) {
803
+ return;
804
+ }
805
+ const rowObj = {};
806
+ if (this.isCompleteDataTable === false) {
807
+ this.$puiEvents.$emit(`onPui-${readOrUpdate}Row-dataTable-${this.modelName}${this.modelNameSuffix}`, rowData);
808
+ return;
809
+ }
810
+ rowObj[this.getPk(row.data())] = rowData;
811
+ this.selectedRows.push(rowObj);
812
+ this.model.selectedRows = [rowObj];
813
+ this.goToElement(rowData, readOrUpdate);
814
+ },
815
+ removeSorting() {
816
+ this.table({
817
+ ordering: false
818
+ });
819
+ },
820
+ deleteRegistry(row) {
821
+ const data = row.data();
822
+ var params = {};
823
+ var modelName = this.model.name;
824
+ for (var index in this.model.columns) {
825
+ let column = this.model.columns[index];
826
+ if (column.isPk) {
827
+ params[column.name] = data[column.name];
828
+ }
829
+ }
830
+ if (Object.keys(params).length === 0) {
831
+ params = data;
832
+ }
833
+ if (this.isCompleteDataTable === false) {
834
+ //const rowIndex = this.table.row(row).index();
835
+ //this.data.splice(rowIndex, 1);
836
+ row.remove().draw();
837
+ }
838
+ this.$puiRequests.deleteRequest(
839
+ `/${modelName}/delete`,
840
+ null,
841
+ (response) => {
842
+ this.$puiEvents.$emit(`onPui-deleteRow-dataTable-${modelName}`, response.data);
843
+ this.$puiNotify.success(this.$puiI18n.t('pui9.delete.success'));
844
+ },
845
+ (error) => {
846
+ this.$store.dispatch('puiRequestShowServerError', { error });
847
+ },
848
+ params
849
+ );
850
+ },
851
+ goToElement(row, method) {
852
+ if (!this.modalDialog) {
853
+ if (this.masterDetail && this.model.searcher) {
854
+ this.model.searcher.goToElement = true;
855
+ }
856
+ var query = {};
857
+ var componentName = this.model.name;
858
+ var url = componentName + '/' + method + '/' + this.getPk(row, true) + '/';
859
+
860
+ if (this.parentModelName) {
861
+ this.$puiEvents.$emit(`onPuiGotoTableDetail-${this.parentModelName}`);
862
+ }
863
+ const params = {
864
+ router: this.$router,
865
+ url: url,
866
+ params: null,
867
+ query: query
868
+ };
869
+ this.$store.dispatch('puiRouterGoToUrl', params);
870
+ } else {
871
+ this.detailComponentMethod = method;
872
+ this.detailComponentPk = row !== null ? this.getPk(row, true) : 'new';
873
+ this.showDetailModalDialog = true;
874
+ }
875
+ },
876
+ getParametersForMultipanel(row, mode) {
877
+ let params = {};
878
+ if (row != null) {
879
+ for (var index in this.model.columns) {
880
+ let column = this.model.columns[index];
881
+ if (column.isPk) {
882
+ params[column.name] = row[column.name];
883
+ }
884
+ }
885
+ }
886
+ params['_mode'] = mode;
887
+ return params;
888
+ },
889
+ getPk(row) {
890
+ let pk = {};
891
+ if (row != null) {
892
+ for (var index in this.model.columns) {
893
+ let column = this.model.columns[index];
894
+ if (column.isPk) {
895
+ pk[column.name] = row[column.name];
896
+ }
897
+ }
898
+ }
899
+ var pkStr = JSON.stringify(pk);
900
+ var pk64 = this.$puiUtils.utf8ToB64(pkStr);
901
+ return pk64;
902
+ },
903
+ ungroupRows() {
904
+ this.table.rowGroup().dataSrc(this.table.data('column'));
905
+ const rows = this.table.rows({ page: 'current' }).nodes();
906
+ let last = null;
907
+ this.table
908
+ .column(1, { page: 'current' })
909
+ .data()
910
+ .each((group, i) => {
911
+ if (last !== group) {
912
+ /* const rowCount = this.table
913
+ .column(currentOrder)
914
+ .data()
915
+ .filter(x => {
916
+ return x == group;
917
+ }).length; */
918
+ $(rows).eq(i).prev().remove();
919
+ last = group;
920
+ }
921
+ });
922
+ },
923
+ groupRows(columnIndex) {
924
+ this.table.rowGroup().dataSrc(this.table.data('column'));
925
+ const rows = this.table.rows({ page: 'current' }).nodes();
926
+ let last = null;
927
+ //const colPosition = typeof this.table.column(1, { page: 'current' }).data()[0] === 'object' ? 0 : 1;
928
+ const renderFunctionForColumn =
929
+ this.table.context[0].aoColumns[columnIndex].mRender ||
930
+ function (data) {
931
+ return data;
932
+ };
933
+ this.table
934
+ .column(1, { page: 'current' })
935
+ .data()
936
+ .each((group, i) => {
937
+ if (last !== group) {
938
+ /* const rowCount = this.table
939
+ .column(currentOrder)
940
+ .data()
941
+ .filter(x => {
942
+ return x == group;
943
+ }).length; */
944
+ if ($(rows).eq(i).prev().hasClass('group') === false) {
945
+ $(rows)
946
+ .eq(i)
947
+ .before(
948
+ $(
949
+ '<tr class="group"><td class="group-bar no-side-borders" colspan="' +
950
+ columnIndex +
951
+ '"><i aria-hidden="true" class="v-icon fa fa fa fa-sm fa-caret-down theme--light"></i></td><td class="group-summary no-side-borders pointer">' +
952
+ renderFunctionForColumn(group) +
953
+ /* rowCount + */
954
+ '</td></tr>'
955
+ ).on('click', function (e) {
956
+ if (!e.target.cellIndex) {
957
+ return;
958
+ }
959
+ const theExpandIcon = $(e.currentTarget).find('.v-icon')[0];
960
+ const classes = theExpandIcon.classList;
961
+ if (classes.contains('fa-caret-down') === true) {
962
+ theExpandIcon.classList.remove('fa-caret-down');
963
+ theExpandIcon.classList.add('fa-caret-right');
964
+ } else {
965
+ theExpandIcon.classList.remove('fa-caret-right');
966
+ theExpandIcon.classList.add('fa-caret-down');
967
+ }
968
+ })
969
+ )
970
+ .prev()
971
+ .prev()
972
+ .addClass('group-last-row');
973
+ }
974
+ last = group;
975
+ }
976
+ });
977
+ },
978
+ getColumnName(index) {
979
+ if (!this.table) {
980
+ return;
981
+ }
982
+ const columns = this.table.context[0].aoColumns;
983
+ return columns[index].data;
984
+ },
985
+ getColumnIndex(name) {
986
+ if (!this.table) {
987
+ return;
988
+ }
989
+ const column = this.table.context[0].aoColumns.filter((column) => {
990
+ return column.name === name;
991
+ });
992
+ if (column.length === 1) {
993
+ return column[0].idx;
994
+ }
995
+ console.warn('error al obtener el nombre de una columna, esta columna no existe');
996
+ return 0;
997
+ },
998
+ unregisterDatatableListeners() {
999
+ if (this.table !== undefined) {
1000
+ this.table.off('column-reorder');
1001
+ this.table.off('mouseenter', 'tbody tr');
1002
+ this.table.off('click', 'tr');
1003
+ this.table.off('column-visibility.dt');
1004
+ this.table.off('length.dt');
1005
+ this.table.off('draw.dt');
1006
+ this.table.off('length.dt');
1007
+ this.table.off('click', 'tr.group');
1008
+ this.table.scrollDiv?.off('scroll');
1009
+ $(this.$refs[this.completeGridName]).off('mouseleave');
1010
+ }
1011
+ },
1012
+ setGroupColumn(columnIndex) {
1013
+ this.grouped = columnIndex !== -1;
1014
+ this.orderFixed = null;
1015
+ if (this.grouped === true) {
1016
+ this.table.colReorder.disable();
1017
+ const currentColumnsOrder = this.table.colReorder.order();
1018
+ let columnIndexOrder = columnIndex;
1019
+ for (let i = 0; i < currentColumnsOrder.length; i++) {
1020
+ if (currentColumnsOrder[i] === columnIndex) {
1021
+ columnIndexOrder = i;
1022
+ break;
1023
+ }
1024
+ }
1025
+ const sortingRule = { column: this.getColumnName(columnIndex), direction: 'asc' };
1026
+ const currentOrder = this.table.order()[0];
1027
+ const order = [];
1028
+ order.push([1, 'asc']);
1029
+ if (currentOrder !== undefined && currentOrder[0] !== 1) {
1030
+ order.push(currentOrder);
1031
+ }
1032
+ this.groupedFlag = true;
1033
+ this.table.colReorder.move(columnIndexOrder, 1);
1034
+ this.$puiEvents.$emit(`onPui-colReorder-dataTable-${this.modelName}${this.modelNameSuffix}`, this.table.colReorder.order());
1035
+ this.applyOrder(order, true);
1036
+ this.orderFixed = [[1, 'asc']];
1037
+ this.$puiEvents.$emit(`onPui-apply-sorting-dataTable-${this.modelName}${this.modelNameSuffix}`, [sortingRule]);
1038
+ this.$puiEvents.$emit(`onPui-groupColumn-dataTable-${this.modelName}${this.modelNameSuffix}`, columnIndex - 1);
1039
+ this.selectedRows = [];
1040
+ this.$puiEvents.$emit(`onPui-selectItem-dataTable-${this.modelName}${this.modelNameSuffix}`, this.selectedRows);
1041
+ } else {
1042
+ this.table.colReorder.enable();
1043
+ this.$puiEvents.$emit(`onPui-groupColumn-dataTable-${this.modelName}${this.modelNameSuffix}`, -1);
1044
+ this.ungroupRows();
1045
+ }
1046
+ },
1047
+ reloadGrid(config, columnDefs) {
1048
+ if (columnDefs !== undefined) {
1049
+ this.columnDefs = columnDefs;
1050
+ }
1051
+ this.gridConfiguration = {};
1052
+ this.tableColumns = (config && config.columns) || this.tableColumns;
1053
+ this.tableColumns[0].name !== 'selection' && this.addSelectCheckColumn();
1054
+ this.grouped = config && config.grouped ? true : false;
1055
+ this.fixed = this.fixedFlag === true ? true : config && config.pinColumn;
1056
+ this.rows = (config && config.rows) || this.rows;
1057
+ this.order = (config && config.order) || this.order;
1058
+ this.unregisterDatatableListeners();
1059
+
1060
+ // Rebuild the datatable with new configuration
1061
+ this.createDatatable(true);
1062
+ this.fixedFlag = false;
1063
+ },
1064
+ adjustGridHeight() {
1065
+ let gridName = this.completeGridName;
1066
+
1067
+ if (this.masterDetail) {
1068
+ $('#' + gridName + '_datatable_container .dataTables_scrollBody').css('height', 'auto');
1069
+ }
1070
+ },
1071
+ pinColumnToLeft(columnIndex) {
1072
+ this.fixed = columnIndex !== -1;
1073
+ this.fixedFlag = this.fixed;
1074
+ let columnDefs = this.modelColumnDefs;
1075
+ if (this.fixed === false) {
1076
+ this.$puiEvents.$emit(`onPui-fixedColumn-dataTable-${this.modelName}${this.modelNameSuffix}`, [-1]);
1077
+ } else {
1078
+ columnDefs = [];
1079
+ var prevFunction = (data) => {
1080
+ return data;
1081
+ };
1082
+
1083
+ if (this.modelColumnDefs && this.modelColumnDefs.length > 0) {
1084
+ columnDefs = this.modelColumnDefs.map((columnDef) => {
1085
+ columnDef.targets.forEach((targetCol, index) => {
1086
+ if (targetCol === columnIndex) {
1087
+ columnDef.targets[index] = 1;
1088
+ prevFunction = columnDef.render;
1089
+ } else if (targetCol < columnIndex) {
1090
+ columnDef.targets[index] = targetCol + 1;
1091
+ }
1092
+ });
1093
+ return columnDef;
1094
+ });
1095
+ }
1096
+ //Esto es para que la columan fijada (si tiene textos largos), se puede poner a un ancho limitado. HAy que hacerla un wrap con un div
1097
+ //https://datatables.net/forums/discussion/37124/columndefs-width-not-working-for-me
1098
+ const renderFunc = (data) => {
1099
+ const nData = prevFunction(data);
1100
+ return `<div style="width: 200px" class="pui-completeDatatable__table--column-fixed">${nData}</div>`;
1101
+ };
1102
+ const isTableOverflowed = this.table.scrollDiv[0].clientWidth < this.table.scrollDiv[0].scrollWidth;
1103
+ isTableOverflowed && columnDefs.push({ targets: 1, render: renderFunc });
1104
+ const column = this.tableColumns[columnIndex];
1105
+ this.tableColumns.splice(columnIndex, 1);
1106
+ this.tableColumns.splice(0, 1);
1107
+ this.tableColumns.unshift(column);
1108
+ this.$puiEvents.$emit(`onPui-fixedColumn-dataTable-${this.modelName}${this.modelNameSuffix}`, [columnIndex - 1, this.tableColumns]);
1109
+ }
1110
+ //tenemos que recargar la tabla obligatariomente porque hemos de cambiar las columnDefs (renderFunc para que se pueda reducir el width)
1111
+ //esto hace que tengamos que reconfigurar los targets de todos los columnsDefs 20 lineas arriba
1112
+ this.reloadGrid({ columns: this.tableColumns, order: this.order }, columnDefs);
1113
+ },
1114
+ orderInGroupedColumn(columnIndex, orderDir) {
1115
+ // si la columna de ordenacion es la misma que la de agrupación, solo cogemos la dirección de la ordenación
1116
+ if (columnIndex !== 1) {
1117
+ const order = [this.orderFixed[0], [columnIndex, orderDir]];
1118
+ this.applyOrder(order, false);
1119
+ } else {
1120
+ this.orderFixed = [[1, orderDir]];
1121
+ this.applyOrder(this.orderFixed, false);
1122
+ }
1123
+ this.$puiEvents.$emit(`onPui-apply-sorting-dataTable-${this.modelName}`, this.order);
1124
+ },
1125
+ //The order just as the datatable understands
1126
+ applyOrder(order, draw) {
1127
+ this.order = [];
1128
+ order.forEach((orderEl) => {
1129
+ this.order.push({ column: this.getColumnName(orderEl[0]), direction: orderEl[1] });
1130
+ });
1131
+ if (draw === true) {
1132
+ draw && this.table.draw();
1133
+ } else {
1134
+ this.table.order(order);
1135
+ this.table.ajax.reload();
1136
+ // reset datatable selected rows
1137
+ this.selectedRows = [];
1138
+ }
1139
+ this.$puiEvents.$emit(`onPui-selectItem-dataTable-${this.modelName}${this.modelNameSuffix}`, this.selectedRows);
1140
+ },
1141
+ //The order as a sorting rules that pui server understands //not used so far, only if a component needs to order from outside
1142
+ applySort(sortingRules, draw) {
1143
+ this.eventToolbar = true;
1144
+ const order = [];
1145
+ sortingRules.forEach((sortingRule) => {
1146
+ const columnIndex = this.getColumnIndex(sortingRule.column);
1147
+ order.push([columnIndex, sortingRule.direction]);
1148
+ });
1149
+ this.order = sortingRules;
1150
+ this.table && this.table.order(order);
1151
+ draw && this.table && this.table.draw(false);
1152
+ if (draw === false) {
1153
+ // reset datatable selected rows
1154
+ this.selectedRows = [];
1155
+ }
1156
+ this.$puiEvents.$emit(`onPui-selectItem-dataTable-${this.modelName}${this.modelNameSuffix}`, this.selectedRows);
1157
+ },
1158
+ applyFilter(filteringObject) {
1159
+ this.page = 1;
1160
+ this.$puiEvents.$emit(`onPui-pageChange-dataTable-${this.modelName}${this.modelNameSuffix}`, this.page);
1161
+ this.eventToolbar = true;
1162
+ this.filteringEnabled = true;
1163
+ this.filter = filteringObject;
1164
+ this.table && this.table.draw();
1165
+ },
1166
+ applySearch(searchText, searchColumns) {
1167
+ this.page = 1;
1168
+ this.$puiEvents.$emit(`onPui-pageChange-dataTable-${this.modelName}${this.modelNameSuffix}`, this.page);
1169
+ this.eventToolbar = true;
1170
+ this.searchText = searchText;
1171
+ this.searchColumns = searchColumns;
1172
+ this.table && this.table.draw();
1173
+ this.selectedRows = [];
1174
+ this.$puiEvents.$emit(`onPui-clearSelection-dataTable-${this.modelName}${this.modelNameSuffix}`);
1175
+ },
1176
+ addSelectCheckColumn() {
1177
+ if (this.isCompleteDataTable === true) {
1178
+ // select check
1179
+ var zeroField = {
1180
+ title: '',
1181
+ name: 'selection',
1182
+ data: null,
1183
+ visible: true,
1184
+ orderable: false,
1185
+ className: 'datatable-cell-selection',
1186
+ defaultContent:
1187
+ '<i aria-hidden="true" class="v-icon far fa-square"></i><i aria-hidden="true" class="v-icon fas fa-check-square"></i>'
1188
+ };
1189
+ this.tableColumns.unshift(zeroField);
1190
+ }
1191
+ },
1192
+ applyDisableRowsByAction() {
1193
+ this.table.select.style('multi');
1194
+ this.disabledRows = [];
1195
+ // guardamos en una variable el valor de rows(...).data() porque el checkAvailability necesita que le pasemos un objeto (por ejemplo, usuario), y con el .nodes() no se le enviaba el objeto
1196
+ var rows = this.table.rows({ page: 'current' }).data();
1197
+ this.table
1198
+ .rows({ page: 'current' })
1199
+ .nodes()
1200
+ .each((row, i) => {
1201
+ var enable = this.actionRunning.checkAvailability.call(this, rows[i]);
1202
+ if (!enable) {
1203
+ const pk = this.getPk(rows[i]);
1204
+ this.disabledRows.push(pk);
1205
+ this.selectedRows = this.selectedRows.filter((selectedRow) => selectedRow[pk] === undefined);
1206
+ this.table.rows(i).deselect();
1207
+ $(row).addClass('row__action-disabled');
1208
+ }
1209
+ });
1210
+
1211
+ this.addSelectAllCheckbox(this, rows);
1212
+ },
1213
+ addSelectAllCheckbox(self, rows) {
1214
+ let $selectAll = $(self.table.column(0).header());
1215
+ $selectAll.removeClass('datatable-cell-selection').addClass('datatable-cell-selectAll');
1216
+ $selectAll.empty().append('<i aria-hidden="true" class="v-icon far fa-square"></i>');
1217
+ let selectedAllRows = false;
1218
+
1219
+ $selectAll.on('click', function () {
1220
+ if (selectedAllRows) {
1221
+ $selectAll.empty().append('<i aria-hidden="true" class="v-icon far fa-square"></i>');
1222
+
1223
+ self.selectedRows = [];
1224
+ self.table.rows({ page: 'current' }).every((index) => {
1225
+ var enable = rows ? self.actionRunning.checkAvailability.call(self, rows[index]) : true;
1226
+ if (enable) {
1227
+ self.table.row(index).deselect();
1228
+ }
1229
+ });
1230
+ self.$puiEvents.$emit(`onPui-selectItem-dataTable-${self.modelName}${self.modelNameSuffix}`, self.selectedRows);
1231
+ } else {
1232
+ $selectAll.empty().append('<i aria-hidden="true" class="v-icon fas fa-check-square"></i>');
1233
+
1234
+ self.selectedRows = [];
1235
+ self.table.rows({ page: 'current' }).every((index) => {
1236
+ var enable = rows ? self.actionRunning.checkAvailability.call(self, rows[index]) : true;
1237
+ if (enable) {
1238
+ let row = self.table.row(index);
1239
+ row.select();
1240
+ let rowObj = {};
1241
+ rowObj[self.getPk(row.data())] = row.data();
1242
+ self.selectedRows.push(rowObj);
1243
+ }
1244
+ });
1245
+ self.$puiEvents.$emit(`onPui-selectItem-dataTable-${self.modelName}${self.modelNameSuffix}`, self.selectedRows);
1246
+ }
1247
+ selectedAllRows = !selectedAllRows;
1248
+ });
1249
+ },
1250
+ removeSelectAllCheckbox() {
1251
+ let $selectAll = $(this.table.column(0).header());
1252
+ $selectAll.removeClass('datatable-cell-selectAll').addClass('datatable-cell-selection');
1253
+ $selectAll.empty();
1254
+ $selectAll.off('click');
1255
+ },
1256
+ applyEnableRowsEndAction() {
1257
+ this.table.select.style(this.selectStyle);
1258
+ this.selectedRows = [];
1259
+ this.disabledRows = [];
1260
+ this.table.rows().deselect();
1261
+ this.table
1262
+ .rows({ page: 'current' })
1263
+ .nodes()
1264
+ .each((row) => {
1265
+ $(row).removeClass('row__action-disabled');
1266
+ });
1267
+
1268
+ this.removeSelectAllCheckbox();
1269
+ },
1270
+ subscribeToActionsEvents() {
1271
+ this.$puiEvents.$on(`onPui-action-before-running-${this.modelName}${this.modelNameSuffix}`, (obj) => {
1272
+ this.actionRunning = obj.action;
1273
+ if (this.actionRunning.selectionType === 'multiple') {
1274
+ this.actionFooter = true;
1275
+ this.applyDisableRowsByAction();
1276
+ } else if (this.selectedRows.length > 0 || this.actionRunning.selectionType === 'general') {
1277
+ // Run action
1278
+ this.actionFooter = false;
1279
+ const selectedRows = this.selectedRows.map((row) => {
1280
+ return Object.values(row)[0];
1281
+ });
1282
+ if (this.actionRunning.selectionType === 'single') {
1283
+ this.model.selectedRows = this.selectedRows;
1284
+ }
1285
+ this.actionRunning.runAction.call(this, this.actionRunning, this.model, selectedRows);
1286
+ }
1287
+ });
1288
+ this.$puiEvents.$on(`onPui-action-running-${this.modelName}${this.modelNameSuffix}`, () => {
1289
+ this.actionFooter = false;
1290
+ });
1291
+ this.$puiEvents.$on(`onPui-action-running-ended-${this.modelName}${this.modelNameSuffix}`, () => {
1292
+ this.endAction();
1293
+ });
1294
+ this.$puiEvents.$on(`onPui-action-running-cancelled-${this.modelName}${this.modelNameSuffix}`, () => {
1295
+ this.endAction();
1296
+ });
1297
+ this.$puiEvents.$on('onPui-form-changedModelLanguage', () => {
1298
+ this.unregisterDatatableListeners();
1299
+ this.createDatatable();
1300
+ });
1301
+ },
1302
+ onMenuExpandColapse() {
1303
+ this.$nextTick(() => {
1304
+ //FIXME
1305
+ //Se usa timeout porque sino solo funciona si se pone un debugger o un punto dentro del nextTick, fuera de eso, no funciona
1306
+ setTimeout(() => {
1307
+ this.adjustTableColumns();
1308
+ }, 150);
1309
+ });
1310
+ },
1311
+ adjustTableColumns() {
1312
+ this.table.columns.adjust();
1313
+ },
1314
+ endAction() {
1315
+ if (this.actionRunning && this.actionRunning.selectionType === 'multiple') {
1316
+ this.applyEnableRowsEndAction();
1317
+ }
1318
+ this.actionFooter = false;
1319
+ this.actionRunning = null;
1320
+ this.selectedRows = [];
1321
+ this.disabledRows = [];
1322
+ this.$puiEvents.$emit(`onPui-clearSelection-dataTable-${this.modelName}${this.modelNameSuffix}`);
1323
+ this.reloadGrid();
1324
+ },
1325
+ recalculateScrollY() {
1326
+ const tableContainerId = '#' + this.completeGridName + '_datatable_container';
1327
+ const newTableHeight = this.tableHeight();
1328
+ $(tableContainerId + ' .dataTables_scroll').height(newTableHeight);
1329
+ $(tableContainerId + ' .dataTables_scrollBody').height(newTableHeight);
1330
+ },
1331
+ adjustTableHeight() {
1332
+ if (!this.masterDetail) {
1333
+ //reduce table container
1334
+ const tableContainerId = '#' + this.completeGridName + '_datatable_container';
1335
+ const b = $(tableContainerId + ` .${this.footerClassPrefix}`).css('bottom');
1336
+ const bb = parseInt(b.replace('px', ''));
1337
+ const bbottom = isNaN(bb) ? 0 : bb;
1338
+ if (this.actionFooter) {
1339
+ const h = $(tableContainerId + ' .dataTables_scroll').height();
1340
+ const h2 = $(tableContainerId + ' .dataTables_scrollBody').height();
1341
+ $(tableContainerId + ' .dataTables_scroll').height(h - 55);
1342
+ $(tableContainerId + ' .dataTables_scrollBody').height(h2 - 55);
1343
+ $(tableContainerId + ` .${this.footerClassPrefix}`).css('bottom', `${bbottom + 55}px`);
1344
+ } else {
1345
+ this.recalculateScrollY();
1346
+ $(tableContainerId + ` .${this.footerClassPrefix}`).css('bottom', '');
1347
+ }
1348
+ }
1349
+ },
1350
+ tableHeight() {
1351
+ if (typeof this.scrollY === 'string') {
1352
+ return this.scrollY;
1353
+ }
1354
+ if (this.$parent.$options._componentTag === 'pui-datatable') {
1355
+ let newTableHeight = window.innerHeight;
1356
+ if (this.$store.state.global.appContainerHeader) {
1357
+ newTableHeight = newTableHeight - 64;
1358
+ }
1359
+ if (this.actionFooter === true) {
1360
+ return `${newTableHeight - 280}px`;
1361
+ } else if (this.masterDetail === true) {
1362
+ return `${newTableHeight - 320}px`;
1363
+ } else if (this.$store.getters.isMobile) {
1364
+ return `${newTableHeight - 350}px`;
1365
+ }
1366
+ return `${newTableHeight - 252}px`;
1367
+ }
1368
+ return true;
1369
+ },
1370
+ fixPaginatorIfSorted(data) {
1371
+ if (1 < data.draw && JSON.stringify(this.datatablesOrderApplied)?.localeCompare(JSON.stringify(this.order)) !== 0) {
1372
+ // Reset page if orderChange and is not firstDraw
1373
+ this.page = 1;
1374
+ }
1375
+ this.datatablesOrderApplied = this.order;
1376
+ }
1377
+ },
1378
+ watch: {
1379
+ actionFooter() {
1380
+ this.adjustTableHeight();
1381
+ },
1382
+ onPuiExpandMenu() {
1383
+ this.onMenuExpandColapse(this.$store.state.menu.expandMenu);
1384
+ },
1385
+ onPuiSecondMenuShowed() {
1386
+ this.onMenuExpandColapse(this.$store.state.menu.secondMenuShowed);
1387
+ }
1388
+ },
1389
+ created() {
1390
+ this.dateFormat = this.$store.getters.dateFormat;
1391
+ this.timeFormat = this.$store.getters.timeFormat;
1392
+ this.toolbarSingleRowNegativeHeight = 0;
1393
+ if (this.masterDetail === true) {
1394
+ this.toolbarSingleRowNegativeHeight = 65;
1395
+ }
1396
+ if (this.externalSearch) {
1397
+ this.searchText = this.externalSearch[0];
1398
+ this.searchColumns = this.externalSearch[1];
1399
+ }
1400
+ if (this.externalFilter) {
1401
+ this.filter = this.externalFilter;
1402
+ }
1403
+ this.tableColumns = [];
1404
+ this.columnDefs = this.modelColumnDefs;
1405
+ this.columns &&
1406
+ this.columns.forEach((column) => {
1407
+ this.tableColumns.push(column);
1408
+ });
1409
+ this.addSelectCheckColumn();
1410
+ this.model = this.$store.getters.getModelByName(this.modelName);
1411
+ this.pkColumns = this.getPKColumnsModel();
1412
+ if (this.modelNameSuffix) {
1413
+ this.$store.commit('addGridInstance', { model: this.modelName });
1414
+ }
1415
+ this.completeGridName = this.modelName + '_' + this.$store.getters.getGridNumberOfInstances(this.modelName);
1416
+ if (this.masterDetail && this.model.searcher) {
1417
+ this.model.searcher.goToElement = false;
1418
+ }
1419
+ this.subscribeToActionsEvents();
1420
+ },
1421
+ mounted() {
1422
+ this.createDatatable();
1423
+ //onMenuEspandColapse ajustará las columnas según esté el menú en el momento justo después de montar la tabla
1424
+ this.onMenuExpandColapse();
1425
+
1426
+ if (this.modalDialog) {
1427
+ this.detailComponentLabel = this.$t(`form.${this.modelName}`);
1428
+ this.detailComponentName = `${this.modelName}form`;
1429
+ this.$puiEvents.$on(`pui-modalDialog-${this.detailComponentName}_${this.completeGridName}_detail_popup-hide`, () => {
1430
+ this.showDetailModalDialog = false;
1431
+ });
1432
+ }
1433
+ this.debouncedAdjustTableColumns = debounce(this.adjustTableColumns, 300);
1434
+ window.addEventListener('resize', this.debouncedAdjustTableColumns);
1435
+ window.addEventListener('resize', this.recalculateScrollY);
1436
+ },
1437
+ beforeDestroy() {
1438
+ window.removeEventListener('resize', this.debouncedAdjustTableColumns);
1439
+ window.removeEventListener('resize', this.recalculateScrollY);
1440
+ this.table.destroy(true);
1441
+ if (this.masterDetail && !this.model.searcher.goToElement) {
1442
+ this.model.searcher = undefined; // reset searcher for detail model
1443
+ }
1444
+ },
1445
+ destroyed() {
1446
+ this.$puiEvents.$off(`onPui-action-before-running-${this.modelName}${this.modelNameSuffix}`);
1447
+ this.$puiEvents.$off(`onPui-action-running-${this.modelName}${this.modelNameSuffix}`);
1448
+ this.$puiEvents.$off(`onPui-action-running-ended-${this.modelName}${this.modelNameSuffix}`);
1449
+ this.$puiEvents.$off(`onPui-action-running-cancelled-${this.modelName}${this.modelNameSuffix}`);
1450
+
1451
+ this.$puiEvents.$off('onPuiMultiPanelChanged');
1452
+ this.$puiEvents.$off(`onPui-deleteRow-dataTable-${this.modelName}${this.modelNameSuffix}`);
1453
+ this.$puiEvents.$off('onPui-form-changedModelLanguage');
1454
+
1455
+ if (this.modalDialog) {
1456
+ this.$puiEvents.$off(`pui-modalDialog-${this.detailComponentName}_${this.completeGridName}_detail_popup-hide`);
1457
+ }
1458
+ }
1459
+ };
1460
+ </script>
1461
+
1462
+ <style lang="postcss" scoped>
1463
+ .full-width {
1464
+ width: 100% !important;
1465
+ }
1466
+ </style>
1467
+ <style>
1468
+ .row__action {
1469
+ font-size: 16px !important;
1470
+ }
1471
+ .selectionField {
1472
+ width: 14px !important;
1473
+ }
1474
+ .row__action-disabled {
1475
+ background-color: var(--N-25) !important;
1476
+ }
1477
+ .row__action-disabled .datatable-cell-selection .v-icon {
1478
+ display: none;
1479
+ }
1480
+ td.actions {
1481
+ text-align: center;
1482
+ }
1483
+ th.actions {
1484
+ background-image: none !important;
1485
+ }
1486
+ .action-btn {
1487
+ margin-left: 8px;
1488
+ margin-right: 8px;
1489
+ margin-top: 2px;
1490
+ margin-bottom: 2px;
1491
+ }
1492
+ .action-btn i {
1493
+ color: var(--N-400) !important;
1494
+ }
1495
+ .action-btn i:hover {
1496
+ color: var(--primarycolor) !important;
1497
+ }
1498
+ </style>