@schukai/monster 3.98.3 → 3.99.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.
- package/CHANGELOG.md +14 -0
- package/package.json +1 -1
- package/source/components/datatable/datatable.mjs +1151 -1139
- package/source/components/form/action-button.mjs +2 -1
- package/source/components/form/api-button.mjs +4 -4
- package/source/components/form/button-bar.mjs +2 -3
- package/source/components/form/button.mjs +1 -0
- package/source/components/form/context-error.mjs +1 -0
- package/source/components/form/field-set.mjs +1 -0
- package/source/components/form/popper-button.mjs +274 -273
- package/source/components/form/reload.mjs +1 -0
- package/source/components/form/toggle-switch.mjs +2 -2
- package/source/components/notify/monitor-attribute-errors.mjs +5 -1
- package/source/dom/customelement.mjs +944 -945
- package/source/dom/error.mjs +106 -0
- package/source/types/version.mjs +1 -1
- package/test/cases/dom/customcontrol.mjs +1 -1
- package/test/cases/dom/customelement.mjs +3 -3
- package/test/cases/monster.mjs +1 -1
- package/test/web/test.html +2 -2
- package/test/web/tests.js +87 -24
@@ -12,79 +12,79 @@
|
|
12
12
|
* SPDX-License-Identifier: AGPL-3.0
|
13
13
|
*/
|
14
14
|
|
15
|
-
import {
|
15
|
+
import {Datasource} from "./datasource.mjs";
|
16
16
|
import {
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
assembleMethodSymbol,
|
18
|
+
CustomElement,
|
19
|
+
registerCustomElement,
|
20
|
+
getSlottedElements,
|
21
21
|
} from "../../dom/customelement.mjs";
|
22
22
|
import {
|
23
|
-
|
24
|
-
|
23
|
+
findTargetElementFromEvent,
|
24
|
+
fireCustomEvent,
|
25
25
|
} from "../../dom/events.mjs";
|
26
|
-
import {
|
26
|
+
import {clone} from "../../util/clone.mjs";
|
27
27
|
import {
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
28
|
+
isString,
|
29
|
+
isFunction,
|
30
|
+
isInstance,
|
31
|
+
isObject,
|
32
|
+
isArray,
|
33
33
|
} from "../../types/is.mjs";
|
34
34
|
import {
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
validateArray,
|
36
|
+
validateInteger,
|
37
|
+
validateObject,
|
38
38
|
} from "../../types/validate.mjs";
|
39
|
-
import {
|
39
|
+
import {Observer} from "../../types/observer.mjs";
|
40
40
|
import {
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
41
|
+
ATTRIBUTE_DATATABLE_HEAD,
|
42
|
+
ATTRIBUTE_DATATABLE_GRID_TEMPLATE,
|
43
|
+
ATTRIBUTE_DATASOURCE_SELECTOR,
|
44
|
+
ATTRIBUTE_DATATABLE_ALIGN,
|
45
|
+
ATTRIBUTE_DATATABLE_SORTABLE,
|
46
|
+
ATTRIBUTE_DATATABLE_MODE,
|
47
|
+
ATTRIBUTE_DATATABLE_INDEX,
|
48
|
+
ATTRIBUTE_DATATABLE_MODE_HIDDEN,
|
49
|
+
ATTRIBUTE_DATATABLE_FEATURES,
|
50
|
+
ATTRIBUTE_DATATABLE_MODE_VISIBLE,
|
51
|
+
ATTRIBUTE_DATATABLE_RESPONSIVE_BREAKPOINT,
|
52
|
+
ATTRIBUTE_DATATABLE_MODE_FIXED,
|
53
53
|
} from "./constants.mjs";
|
54
|
-
import {
|
54
|
+
import {instanceSymbol} from "../../constants.mjs";
|
55
55
|
import {
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
56
|
+
Header,
|
57
|
+
createOrderStatement,
|
58
|
+
DIRECTION_ASC,
|
59
|
+
DIRECTION_DESC,
|
60
|
+
DIRECTION_NONE,
|
61
61
|
} from "./datatable/header.mjs";
|
62
|
-
import {
|
62
|
+
import {DatatableStyleSheet} from "./stylesheet/datatable.mjs";
|
63
63
|
import {
|
64
|
-
|
65
|
-
|
64
|
+
handleDataSourceChanges,
|
65
|
+
datasourceLinkedElementSymbol,
|
66
66
|
} from "./util.mjs";
|
67
67
|
import "./columnbar.mjs";
|
68
68
|
import "./filter-button.mjs";
|
69
69
|
import {
|
70
|
-
|
71
|
-
|
72
|
-
|
70
|
+
findElementWithSelectorUpwards,
|
71
|
+
getDocument,
|
72
|
+
getWindow,
|
73
73
|
} from "../../dom/util.mjs";
|
74
|
-
|
75
|
-
import {
|
76
|
-
import { getDocumentTranslations } from "../../i18n/translations.mjs";
|
74
|
+
|
75
|
+
import {getDocumentTranslations} from "../../i18n/translations.mjs";
|
77
76
|
import "../state/state.mjs";
|
78
77
|
import "../host/collapse.mjs";
|
79
|
-
import {
|
78
|
+
import {generateUniqueConfigKey} from "../host/util.mjs";
|
80
79
|
|
81
80
|
import "./datasource/dom.mjs";
|
82
81
|
import "./datasource/rest.mjs";
|
83
82
|
|
84
83
|
import "../form/context-help.mjs";
|
85
|
-
import {
|
84
|
+
import {getLocaleOfDocument} from "../../dom/locale.mjs";
|
85
|
+
import {addErrorAttribute} from "../../dom/error.mjs";
|
86
86
|
|
87
|
-
export {
|
87
|
+
export {DataTable};
|
88
88
|
|
89
89
|
/**
|
90
90
|
* @private
|
@@ -150,419 +150,421 @@ const resizeObserverSymbol = Symbol("resizeObserver");
|
|
150
150
|
* @fires monster-datatable-selection-changed
|
151
151
|
**/
|
152
152
|
class DataTable extends CustomElement {
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
153
|
+
/**
|
154
|
+
* This method is called by the `instanceof` operator.
|
155
|
+
* @return {symbol}
|
156
|
+
*/
|
157
|
+
static get [instanceSymbol]() {
|
158
|
+
return Symbol.for("@schukai/monster/components/datatable@@instance");
|
159
|
+
}
|
160
|
+
|
161
|
+
/**
|
162
|
+
* To set the options via the HTML tag, the attribute `data-monster-options` must be used.
|
163
|
+
* @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
|
164
|
+
*
|
165
|
+
* The individual configuration values can be found in the table.
|
166
|
+
*
|
167
|
+
* @property {Object} templates Template definitions
|
168
|
+
* @property {string} templates.main Main template
|
169
|
+
* @property {Object} datasource Datasource configuration
|
170
|
+
* @property {string} datasource.selector Selector for the datasource
|
171
|
+
* @property {Object} mapping Mapping configuration
|
172
|
+
* @property {string} mapping.data Data mapping
|
173
|
+
* @property {Array} data Data
|
174
|
+
* @property {Array} headers Headers
|
175
|
+
* @property {Object} responsive Responsive configuration
|
176
|
+
* @property {number} responsive.breakpoint Breakpoint for responsive mode
|
177
|
+
* @property {Object} labels Labels
|
178
|
+
* @property {string} labels.theListContainsNoEntries Label for empty state
|
179
|
+
* @property {Object} classes Classes
|
180
|
+
* @property {string} classes.container Container class
|
181
|
+
* @property {Object} features Features
|
182
|
+
* @property {boolean} features.settings Settings feature
|
183
|
+
* @property {boolean} features.footer Footer feature
|
184
|
+
* @property {boolean} features.autoInit Auto init feature (init datasource automatically)
|
185
|
+
* @property {boolean} features.doubleClickCopyToClipboard Double click copy to clipboard feature
|
186
|
+
* @property {boolean} features.copyAll Copy all feature
|
187
|
+
* @property {boolean} features.help Help feature
|
188
|
+
* @property {Object} templateMapping Template mapping
|
189
|
+
* @property {string} templateMapping.row-key Row key
|
190
|
+
* @property {string} templateMapping.filter-id Filter id
|
191
|
+
**/
|
192
|
+
get defaults() {
|
193
|
+
return Object.assign(
|
194
|
+
{},
|
195
|
+
super.defaults,
|
196
|
+
{
|
197
|
+
templates: {
|
198
|
+
main: getTemplate(),
|
199
|
+
emptyState: getEmptyTemplate(),
|
200
|
+
},
|
201
|
+
|
202
|
+
datasource: {
|
203
|
+
selector: null,
|
204
|
+
},
|
205
|
+
|
206
|
+
mapping: {
|
207
|
+
data: "dataset",
|
208
|
+
},
|
209
|
+
|
210
|
+
data: [],
|
211
|
+
headers: [],
|
212
|
+
|
213
|
+
responsive: {
|
214
|
+
breakpoint: 900,
|
215
|
+
},
|
216
|
+
|
217
|
+
labels: getTranslations(),
|
218
|
+
|
219
|
+
classes: {
|
220
|
+
control: "monster-theme-control-container-1",
|
221
|
+
container: "",
|
222
|
+
row: "monster-theme-control-row-1",
|
223
|
+
},
|
224
|
+
|
225
|
+
features: {
|
226
|
+
settings: true,
|
227
|
+
footer: true,
|
228
|
+
autoInit: true,
|
229
|
+
doubleClickCopyToClipboard: true,
|
230
|
+
copyAll: true,
|
231
|
+
help: true,
|
232
|
+
},
|
233
|
+
|
234
|
+
copy: {
|
235
|
+
delimiter: ";",
|
236
|
+
quoteOpen: '"',
|
237
|
+
quoteClose: '"',
|
238
|
+
rowBreak: "\n",
|
239
|
+
},
|
240
|
+
|
241
|
+
templateMapping: {
|
242
|
+
"row-key": null,
|
243
|
+
"filter-id": null,
|
244
|
+
},
|
245
|
+
},
|
246
|
+
initOptionsFromArguments.call(this),
|
247
|
+
);
|
248
|
+
}
|
249
|
+
|
250
|
+
/**
|
251
|
+
*
|
252
|
+
* @param {string} selector
|
253
|
+
* @return {NodeList}
|
254
|
+
*/
|
255
|
+
getGridElements(selector) {
|
256
|
+
return this[gridElementSymbol].querySelectorAll(selector);
|
257
|
+
}
|
258
|
+
|
259
|
+
/**
|
260
|
+
*
|
261
|
+
* @return {string}
|
262
|
+
*/
|
263
|
+
static getTag() {
|
264
|
+
return "monster-datatable";
|
265
|
+
}
|
266
|
+
|
267
|
+
/**
|
268
|
+
* @return {void}
|
269
|
+
*/
|
270
|
+
disconnectedCallback() {
|
271
|
+
super.disconnectedCallback();
|
272
|
+
if (this?.[resizeObserverSymbol] instanceof ResizeObserver) {
|
273
|
+
this[resizeObserverSymbol].disconnect();
|
274
|
+
}
|
275
|
+
}
|
276
|
+
|
277
|
+
/**
|
278
|
+
* @return {void}
|
279
|
+
*/
|
280
|
+
connectedCallback() {
|
281
|
+
const self = this;
|
282
|
+
super.connectedCallback();
|
283
|
+
|
284
|
+
this[resizeObserverSymbol] = new ResizeObserver((entries) => {
|
285
|
+
updateGrid.call(self);
|
286
|
+
});
|
287
|
+
|
288
|
+
this[resizeObserverSymbol].observe(this.parentNode);
|
289
|
+
}
|
290
|
+
|
291
|
+
/**
|
292
|
+
* Get the row number of the selected rows as an array
|
293
|
+
*
|
294
|
+
* @returns {number[]}
|
295
|
+
*/
|
296
|
+
getSelectedRows() {
|
297
|
+
const rows = this.getGridElements(`[data-monster-role="select-row"]`);
|
298
|
+
const selectedRows = [];
|
299
|
+
rows.forEach((row) => {
|
300
|
+
if (row.checked) {
|
301
|
+
const key = row.parentNode.getAttribute(
|
302
|
+
"data-monster-insert-reference",
|
303
|
+
);
|
304
|
+
const index = key.split("-").pop();
|
305
|
+
selectedRows.push(parseInt(index, 10));
|
306
|
+
}
|
307
|
+
});
|
308
|
+
|
309
|
+
return selectedRows;
|
310
|
+
}
|
311
|
+
|
312
|
+
/**
|
313
|
+
* @return void
|
314
|
+
*/
|
315
|
+
[assembleMethodSymbol]() {
|
316
|
+
const rawKey = this.getOption("templateMapping.row-key");
|
317
|
+
|
318
|
+
if (rawKey === null) {
|
319
|
+
if (this.id !== null && this.id !== "") {
|
320
|
+
const rawKey = this.getOption("templateMapping.row-key");
|
321
|
+
if (rawKey === null) {
|
322
|
+
this.setOption("templateMapping.row-key", this.id + "-row");
|
323
|
+
}
|
324
|
+
} else {
|
325
|
+
this.setOption("templateMapping.row-key", "row");
|
326
|
+
}
|
327
|
+
}
|
328
|
+
|
329
|
+
if (this.id !== null && this.id !== "") {
|
330
|
+
this.setOption("templateMapping.filter-id", "" + this.id + "-filter");
|
331
|
+
} else {
|
332
|
+
this.setOption("templateMapping.filter-id", "filter");
|
333
|
+
}
|
334
|
+
|
335
|
+
super[assembleMethodSymbol]();
|
336
|
+
|
337
|
+
initControlReferences.call(this);
|
338
|
+
initEventHandler.call(this);
|
339
|
+
|
340
|
+
getHostConfig
|
341
|
+
.call(this, getColumnVisibilityConfigKey)
|
342
|
+
.then((config) => {
|
343
|
+
const headerOrderMap = new Map();
|
344
|
+
|
345
|
+
getHostConfig
|
346
|
+
.call(this, getStoredOrderConfigKey)
|
347
|
+
.then((orderConfig) => {
|
348
|
+
if (isArray(orderConfig) || orderConfig.length > 0) {
|
349
|
+
for (let i = 0; i < orderConfig.length; i++) {
|
350
|
+
const item = orderConfig[i];
|
351
|
+
const parts = item.split(" ");
|
352
|
+
const field = parts[0];
|
353
|
+
const direction = parts[1] || DIRECTION_ASC;
|
354
|
+
headerOrderMap.set(field, direction);
|
355
|
+
}
|
356
|
+
}
|
357
|
+
})
|
358
|
+
.then(() => {
|
359
|
+
try {
|
360
|
+
initGridAndStructs.call(this, config, headerOrderMap);
|
361
|
+
} catch (error) {
|
362
|
+
addErrorAttribute(
|
363
|
+
this,
|
364
|
+
error
|
365
|
+
);
|
366
|
+
}
|
367
|
+
|
368
|
+
updateColumnBar.call(this);
|
369
|
+
})
|
370
|
+
.catch((error) => {
|
371
|
+
addErrorAttribute(
|
372
|
+
this, error,
|
373
|
+
);
|
374
|
+
});
|
375
|
+
})
|
376
|
+
.catch((error) => {
|
377
|
+
addErrorAttribute(
|
378
|
+
this,
|
379
|
+
error
|
380
|
+
);
|
381
|
+
})
|
382
|
+
.finally(() => {
|
383
|
+
|
384
|
+
const selector = this.getOption("datasource.selector");
|
385
|
+
|
386
|
+
if (isString(selector)) {
|
387
|
+
const element = findElementWithSelectorUpwards(this, selector);
|
388
|
+
if (element === null) {
|
389
|
+
throw new Error("the selector must match exactly one element");
|
390
|
+
}
|
391
|
+
|
392
|
+
if (!isInstance(element, Datasource)) {
|
393
|
+
throw new TypeError("the element must be a datasource");
|
394
|
+
}
|
395
|
+
|
396
|
+
this[datasourceLinkedElementSymbol] = element;
|
397
|
+
|
398
|
+
getWindow().requestAnimationFrame(() => {
|
399
|
+
|
400
|
+
handleDataSourceChanges.call(this);
|
401
|
+
if (element && "datasource" in element) {
|
402
|
+
element.datasource.attachObserver(
|
403
|
+
new Observer(handleDataSourceChanges.bind(this)),
|
404
|
+
);
|
405
|
+
}
|
406
|
+
});
|
407
|
+
}
|
408
|
+
});
|
409
|
+
|
410
|
+
}
|
411
|
+
|
412
|
+
/**
|
413
|
+
* @return {CSSStyleSheet[]}
|
414
|
+
*/
|
415
|
+
static getCSSStyleSheet() {
|
416
|
+
return [DatatableStyleSheet];
|
417
|
+
}
|
418
|
+
|
419
|
+
/**
|
420
|
+
* Copy a row from the datatable
|
421
|
+
*
|
422
|
+
* @param {number|string} fromIndex
|
423
|
+
* @param {number|string} toIndex
|
424
|
+
* @return {DataTable}
|
425
|
+
* @fires monster-datatable-row-copied
|
426
|
+
*/
|
427
|
+
copyRow(fromIndex, toIndex) {
|
428
|
+
const datasource = this[datasourceLinkedElementSymbol];
|
429
|
+
if (!datasource) {
|
430
|
+
return this;
|
431
|
+
}
|
432
|
+
let d = datasource.data;
|
433
|
+
let c = clone(d);
|
434
|
+
|
435
|
+
let rows = c;
|
436
|
+
const mapping = this.getOption("mapping.data");
|
437
|
+
|
438
|
+
if (mapping) {
|
439
|
+
rows = c?.[mapping];
|
440
|
+
}
|
441
|
+
|
442
|
+
if (rows === undefined || rows === null) {
|
443
|
+
rows = [];
|
444
|
+
}
|
445
|
+
|
446
|
+
if (toIndex === undefined) {
|
447
|
+
toIndex = rows.length;
|
448
|
+
}
|
449
|
+
|
450
|
+
if (isString(fromIndex)) {
|
451
|
+
fromIndex = parseInt(fromIndex);
|
452
|
+
}
|
453
|
+
if (isString(toIndex)) {
|
454
|
+
toIndex = parseInt(toIndex);
|
455
|
+
}
|
456
|
+
|
457
|
+
if (toIndex < 0 || toIndex > rows.length) {
|
458
|
+
throw new RangeError("index out of bounds");
|
459
|
+
}
|
460
|
+
|
461
|
+
validateArray(rows);
|
462
|
+
validateInteger(fromIndex);
|
463
|
+
validateInteger(toIndex);
|
464
|
+
|
465
|
+
if (fromIndex < 0 || fromIndex >= rows.length) {
|
466
|
+
throw new RangeError("index out of bounds");
|
467
|
+
}
|
468
|
+
|
469
|
+
rows.splice(toIndex, 0, clone(rows[fromIndex]));
|
470
|
+
datasource.data = c;
|
471
|
+
|
472
|
+
fireCustomEvent(this, "monster-datatable-row-copied", {
|
473
|
+
index: toIndex,
|
474
|
+
});
|
475
|
+
|
476
|
+
return this;
|
477
|
+
}
|
478
|
+
|
479
|
+
/**
|
480
|
+
* Remove a row from the datatable
|
481
|
+
*
|
482
|
+
* @param {number|string} index
|
483
|
+
* @return {DataTable}
|
484
|
+
* @fires monster-datatable-row-removed
|
485
|
+
*/
|
486
|
+
removeRow(index) {
|
487
|
+
const datasource = this[datasourceLinkedElementSymbol];
|
488
|
+
if (!datasource) {
|
489
|
+
return this;
|
490
|
+
}
|
491
|
+
let d = datasource.data;
|
492
|
+
let c = clone(d);
|
493
|
+
|
494
|
+
let rows = c;
|
495
|
+
const mapping = this.getOption("mapping.data");
|
496
|
+
|
497
|
+
if (mapping) {
|
498
|
+
rows = c?.[mapping];
|
499
|
+
}
|
500
|
+
|
501
|
+
if (rows === undefined || rows === null) {
|
502
|
+
rows = [];
|
503
|
+
}
|
504
|
+
|
505
|
+
if (isString(index)) {
|
506
|
+
index = parseInt(index);
|
507
|
+
}
|
508
|
+
|
509
|
+
validateArray(rows);
|
510
|
+
validateInteger(index);
|
511
|
+
|
512
|
+
if (index < 0 || index >= rows.length) {
|
513
|
+
throw new RangeError("index out of bounds");
|
514
|
+
}
|
515
|
+
if (mapping) {
|
516
|
+
rows = c?.[mapping];
|
517
|
+
}
|
518
|
+
|
519
|
+
rows.splice(index, 1);
|
520
|
+
datasource.data = c;
|
521
|
+
|
522
|
+
fireCustomEvent(this, "monster-datatable-row-removed", {
|
523
|
+
index: index,
|
524
|
+
});
|
525
|
+
|
526
|
+
return this;
|
527
|
+
}
|
528
|
+
|
529
|
+
/**
|
530
|
+
* Add a row to the datatable
|
531
|
+
*
|
532
|
+
* @param {Object} data
|
533
|
+
* @return {DataTable}
|
534
|
+
*
|
535
|
+
* @fires monster-datatable-row-added
|
536
|
+
**/
|
537
|
+
addRow(data) {
|
538
|
+
const datasource = this[datasourceLinkedElementSymbol];
|
539
|
+
if (!datasource) {
|
540
|
+
return this;
|
541
|
+
}
|
542
|
+
let d = datasource.data;
|
543
|
+
let c = clone(d);
|
544
|
+
|
545
|
+
let rows = c;
|
546
|
+
|
547
|
+
const mapping = this.getOption("mapping.data");
|
548
|
+
if (mapping) {
|
549
|
+
rows = c?.[mapping];
|
550
|
+
}
|
551
|
+
|
552
|
+
if (rows === undefined || rows === null) {
|
553
|
+
rows = [];
|
554
|
+
}
|
555
|
+
|
556
|
+
validateArray(rows);
|
557
|
+
validateObject(data);
|
558
|
+
|
559
|
+
rows.push(data);
|
560
|
+
datasource.data = c;
|
561
|
+
|
562
|
+
fireCustomEvent(this, "monster-datatable-row-added", {
|
563
|
+
index: rows.length - 1,
|
564
|
+
});
|
565
|
+
|
566
|
+
return this;
|
567
|
+
}
|
566
568
|
}
|
567
569
|
|
568
570
|
/**
|
@@ -570,7 +572,7 @@ class DataTable extends CustomElement {
|
|
570
572
|
* @return {string}
|
571
573
|
*/
|
572
574
|
function getColumnVisibilityConfigKey() {
|
573
|
-
|
575
|
+
return generateUniqueConfigKey("datatable", this?.id, "columns-visibility");
|
574
576
|
}
|
575
577
|
|
576
578
|
/**
|
@@ -578,7 +580,7 @@ function getColumnVisibilityConfigKey() {
|
|
578
580
|
* @return {string}
|
579
581
|
*/
|
580
582
|
function getFilterConfigKey() {
|
581
|
-
|
583
|
+
return generateUniqueConfigKey("datatable", this?.id, "filter");
|
582
584
|
}
|
583
585
|
|
584
586
|
/**
|
@@ -586,519 +588,529 @@ function getFilterConfigKey() {
|
|
586
588
|
* @return {Promise}
|
587
589
|
*/
|
588
590
|
function getHostConfig(callback) {
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
});
|
591
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
592
|
+
|
593
|
+
if (!host) {
|
594
|
+
addErrorAttribute(this, "no host found");
|
595
|
+
return Promise.resolve({});
|
596
|
+
}
|
597
|
+
|
598
|
+
if (!this.id) {
|
599
|
+
addErrorAttribute(
|
600
|
+
this,
|
601
|
+
"no id found; id is required for config",
|
602
|
+
);
|
603
|
+
return Promise.resolve({});
|
604
|
+
}
|
605
|
+
|
606
|
+
if (!host || !isFunction(host?.getConfig)) {
|
607
|
+
throw new TypeError("the host must be a monster-host");
|
608
|
+
}
|
609
|
+
|
610
|
+
const configKey = callback.call(this);
|
611
|
+
return host.hasConfig(configKey).then((hasConfig) => {
|
612
|
+
if (hasConfig) {
|
613
|
+
return host.getConfig(configKey);
|
614
|
+
} else {
|
615
|
+
return {};
|
616
|
+
}
|
617
|
+
});
|
617
618
|
}
|
618
619
|
|
619
620
|
/**
|
620
621
|
* @private
|
621
622
|
*/
|
622
623
|
function updateColumnBar() {
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
624
|
+
if (!this[columnBarElementSymbol]) {
|
625
|
+
return;
|
626
|
+
}
|
627
|
+
|
628
|
+
const columns = [];
|
629
|
+
for (const header of this.getOption("headers")) {
|
630
|
+
const mode = header.getInternal("mode");
|
631
|
+
|
632
|
+
if (mode === ATTRIBUTE_DATATABLE_MODE_FIXED) {
|
633
|
+
continue;
|
634
|
+
}
|
635
|
+
|
636
|
+
columns.push({
|
637
|
+
visible: mode !== ATTRIBUTE_DATATABLE_MODE_HIDDEN,
|
638
|
+
name: header.label,
|
639
|
+
index: header.index,
|
640
|
+
});
|
641
|
+
}
|
642
|
+
|
643
|
+
this[columnBarElementSymbol].setOption("columns", columns);
|
643
644
|
}
|
644
645
|
|
645
646
|
/**
|
646
647
|
* @private
|
647
648
|
*/
|
648
649
|
function updateHeaderFromColumnBar() {
|
649
|
-
|
650
|
-
|
651
|
-
|
650
|
+
if (!this[columnBarElementSymbol]) {
|
651
|
+
return;
|
652
|
+
}
|
652
653
|
|
653
|
-
|
654
|
-
|
654
|
+
const options = this[columnBarElementSymbol].getOption("columns");
|
655
|
+
if (!isArray(options)) return;
|
655
656
|
|
656
|
-
|
657
|
+
const invisibleMap = {};
|
657
658
|
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
659
|
+
for (let i = 0; i < options.length; i++) {
|
660
|
+
const option = options[i];
|
661
|
+
invisibleMap[option.index] = option.visible;
|
662
|
+
}
|
662
663
|
|
663
|
-
|
664
|
-
|
664
|
+
for (const header of this.getOption("headers")) {
|
665
|
+
const mode = header.getInternal("mode");
|
665
666
|
|
666
|
-
|
667
|
-
|
668
|
-
|
667
|
+
if (mode === ATTRIBUTE_DATATABLE_MODE_FIXED) {
|
668
|
+
continue;
|
669
|
+
}
|
669
670
|
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
671
|
+
if (invisibleMap[header.index] === false) {
|
672
|
+
header.setInternal("mode", ATTRIBUTE_DATATABLE_MODE_HIDDEN);
|
673
|
+
} else {
|
674
|
+
header.setInternal("mode", ATTRIBUTE_DATATABLE_MODE_VISIBLE);
|
675
|
+
}
|
676
|
+
}
|
676
677
|
}
|
677
678
|
|
678
679
|
/**
|
679
680
|
* @private
|
680
681
|
*/
|
681
682
|
function updateConfigColumnBar() {
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
683
|
+
if (!this[columnBarElementSymbol]) {
|
684
|
+
return;
|
685
|
+
}
|
686
|
+
|
687
|
+
const options = this[columnBarElementSymbol].getOption("columns");
|
688
|
+
if (!isArray(options)) return;
|
689
|
+
|
690
|
+
const map = {};
|
691
|
+
for (let i = 0; i < options.length; i++) {
|
692
|
+
const option = options[i];
|
693
|
+
map[option.name] = option.visible;
|
694
|
+
}
|
695
|
+
|
696
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
697
|
+
if (!(host && this.id)) {
|
698
|
+
return;
|
699
|
+
}
|
700
|
+
const configKey = getColumnVisibilityConfigKey.call(this);
|
701
|
+
|
702
|
+
try {
|
703
|
+
host.setConfig(configKey, map);
|
704
|
+
} catch (error) {
|
705
|
+
addErrorAttribute(this, error);
|
706
|
+
}
|
706
707
|
}
|
707
708
|
|
708
709
|
/**
|
709
710
|
* @private
|
710
711
|
*/
|
711
712
|
function initEventHandler() {
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
713
|
+
const self = this;
|
714
|
+
|
715
|
+
const quoteOpenChar = this.getOption("copy.quoteOpen");
|
716
|
+
const quoteCloseChar = this.getOption("copy.quoteClose");
|
717
|
+
const delimiterChar = this.getOption("copy.delimiter");
|
718
|
+
const rowBreak = this.getOption("copy.rowBreak");
|
719
|
+
|
720
|
+
self[columnBarElementSymbol].attachObserver(
|
721
|
+
new Observer((e) => {
|
722
|
+
updateHeaderFromColumnBar.call(self);
|
723
|
+
updateGrid.call(self);
|
724
|
+
updateConfigColumnBar.call(self);
|
725
|
+
}),
|
726
|
+
);
|
727
|
+
|
728
|
+
self[gridHeadersElementSymbol].addEventListener("click", function (event) {
|
729
|
+
let element = null;
|
730
|
+
const datasource = self[datasourceLinkedElementSymbol];
|
731
|
+
if (!datasource) {
|
732
|
+
return;
|
733
|
+
}
|
734
|
+
|
735
|
+
element = findTargetElementFromEvent(event, ATTRIBUTE_DATATABLE_SORTABLE);
|
736
|
+
if (element) {
|
737
|
+
const index = element.parentNode.getAttribute(ATTRIBUTE_DATATABLE_INDEX);
|
738
|
+
const headers = self.getOption("headers");
|
739
|
+
|
740
|
+
event.preventDefault();
|
741
|
+
|
742
|
+
headers[index].changeDirection();
|
743
|
+
|
744
|
+
queueMicrotask(function () {
|
745
|
+
/** hotfix, normally this should be done via the updater, no idea why this is not possible. */
|
746
|
+
element.setAttribute(
|
747
|
+
ATTRIBUTE_DATATABLE_SORTABLE,
|
748
|
+
`${headers[index].field} ${headers[index].direction}`,
|
749
|
+
);
|
750
|
+
|
751
|
+
storeOrderStatement.call(self, true);
|
752
|
+
});
|
753
|
+
}
|
754
|
+
});
|
755
|
+
|
756
|
+
const eventHandlerDoubleClickCopyToClipboard = (event) => {
|
757
|
+
const element = findTargetElementFromEvent(event, "data-monster-head");
|
758
|
+
if (element) {
|
759
|
+
let text = "";
|
760
|
+
|
761
|
+
if (event.shiftKey) {
|
762
|
+
const index = element.getAttribute("data-monster-insert-reference");
|
763
|
+
if (index) {
|
764
|
+
const cols = self.getGridElements(
|
765
|
+
`[data-monster-insert-reference="${index}"]`,
|
766
|
+
);
|
767
|
+
|
768
|
+
const colTexts = [];
|
769
|
+
for (let i = 0; i < cols.length; i++) {
|
770
|
+
const col = cols[i];
|
771
|
+
|
772
|
+
if (
|
773
|
+
col.querySelector("monster-button-bar") ||
|
774
|
+
col.querySelector("monster-button")
|
775
|
+
) {
|
776
|
+
continue;
|
777
|
+
}
|
778
|
+
|
779
|
+
if (col.textContent) {
|
780
|
+
colTexts.push(
|
781
|
+
quoteOpenChar + col.textContent.trim() + quoteCloseChar,
|
782
|
+
);
|
783
|
+
}
|
784
|
+
}
|
785
|
+
|
786
|
+
text = colTexts.join(delimiterChar);
|
787
|
+
}
|
788
|
+
} else {
|
789
|
+
if (
|
790
|
+
element.querySelector("monster-button-bar") ||
|
791
|
+
element.querySelector("monster-button")
|
792
|
+
) {
|
793
|
+
return;
|
794
|
+
}
|
795
|
+
|
796
|
+
text = element.textContent.trim();
|
797
|
+
}
|
798
|
+
|
799
|
+
if (getWindow().navigator.clipboard && text) {
|
800
|
+
getWindow()
|
801
|
+
.navigator.clipboard.writeText(text)
|
802
|
+
.then(
|
803
|
+
() => {
|
804
|
+
},
|
805
|
+
(err) => {
|
806
|
+
},
|
807
|
+
);
|
808
|
+
}
|
809
|
+
}
|
810
|
+
};
|
811
|
+
|
812
|
+
if (self.getOption("features.doubleClickCopyToClipboard")) {
|
813
|
+
self[gridElementSymbol].addEventListener(
|
814
|
+
"dblclick",
|
815
|
+
eventHandlerDoubleClickCopyToClipboard,
|
816
|
+
);
|
817
|
+
}
|
818
|
+
|
819
|
+
if (self.getOption("features.copyAll") && this[copyAllElementSymbol]) {
|
820
|
+
this[copyAllElementSymbol].addEventListener("click", (event) => {
|
821
|
+
event.preventDefault();
|
822
|
+
|
823
|
+
const table = [];
|
824
|
+
let currentRow = [];
|
825
|
+
let currentIndex = null;
|
826
|
+
|
827
|
+
const cols = self.getGridElements(`[data-monster-insert-reference]`);
|
828
|
+
const rowIndexes = new Map();
|
829
|
+
cols.forEach((col) => {
|
830
|
+
const index = col.getAttribute("data-monster-insert-reference");
|
831
|
+
rowIndexes.set(index, true);
|
832
|
+
});
|
833
|
+
|
834
|
+
rowIndexes.forEach((value, key) => {
|
835
|
+
const cols = self.getGridElements(
|
836
|
+
`[data-monster-insert-reference="${key}"]`,
|
837
|
+
);
|
838
|
+
|
839
|
+
for (let i = 0; i < cols.length; i++) {
|
840
|
+
const col = cols[i];
|
841
|
+
|
842
|
+
if (
|
843
|
+
col.querySelector("monster-button-bar") ||
|
844
|
+
col.querySelector("monster-button")
|
845
|
+
) {
|
846
|
+
continue;
|
847
|
+
}
|
848
|
+
|
849
|
+
if (col.textContent) {
|
850
|
+
currentRow.push(
|
851
|
+
quoteOpenChar + col.textContent.trim() + quoteCloseChar,
|
852
|
+
);
|
853
|
+
}
|
854
|
+
}
|
855
|
+
|
856
|
+
if (currentRow.length > 0) {
|
857
|
+
table.push(currentRow);
|
858
|
+
}
|
859
|
+
currentRow = [];
|
860
|
+
});
|
861
|
+
|
862
|
+
if (table.length > 0) {
|
863
|
+
const text = table.map((row) => row.join(delimiterChar)).join(rowBreak);
|
864
|
+
if (getWindow().navigator.clipboard && text) {
|
865
|
+
getWindow()
|
866
|
+
.navigator.clipboard.writeText(text)
|
867
|
+
.then(
|
868
|
+
() => {
|
869
|
+
},
|
870
|
+
(err) => {
|
871
|
+
},
|
872
|
+
);
|
873
|
+
}
|
874
|
+
}
|
875
|
+
});
|
876
|
+
}
|
877
|
+
|
878
|
+
const selectRowCallback = (event) => {
|
879
|
+
const element = findTargetElementFromEvent(
|
880
|
+
event,
|
881
|
+
"data-monster-role",
|
882
|
+
"select-row",
|
883
|
+
);
|
884
|
+
if (element) {
|
885
|
+
const key = element.parentNode.getAttribute(
|
886
|
+
"data-monster-insert-reference",
|
887
|
+
);
|
888
|
+
const row = self.getGridElements(
|
889
|
+
`[data-monster-insert-reference="${key}"]`,
|
890
|
+
);
|
891
|
+
|
892
|
+
const index = key.split("-").pop();
|
893
|
+
|
894
|
+
if (element.checked) {
|
895
|
+
row.forEach((col) => {
|
896
|
+
col.classList.add("selected");
|
897
|
+
});
|
898
|
+
|
899
|
+
fireCustomEvent(self, "monster-datatable-row-selected", {
|
900
|
+
index: index,
|
901
|
+
});
|
902
|
+
} else {
|
903
|
+
row.forEach((col) => {
|
904
|
+
col.classList.remove("selected");
|
905
|
+
});
|
906
|
+
|
907
|
+
fireCustomEvent(self, "monster-datatable-row-deselected", {
|
908
|
+
index: index,
|
909
|
+
});
|
910
|
+
}
|
911
|
+
|
912
|
+
fireCustomEvent(this, "monster-datatable-selection-changed", {});
|
913
|
+
}
|
914
|
+
|
915
|
+
const rows = self.getGridElements(`[data-monster-role="select-row"]`);
|
916
|
+
const allSelected = Array.from(rows).every((row) => row.checked);
|
917
|
+
const selectAll = this[gridHeadersElementSymbol].querySelector(
|
918
|
+
`[data-monster-role="select-all"]`,
|
919
|
+
);
|
920
|
+
selectAll.checked = allSelected;
|
921
|
+
};
|
922
|
+
|
923
|
+
this[gridElementSymbol].addEventListener("click", selectRowCallback);
|
924
|
+
this[gridElementSymbol].addEventListener("touch", selectRowCallback);
|
925
|
+
|
926
|
+
const selectAllCallback = (event) => {
|
927
|
+
const element = findTargetElementFromEvent(
|
928
|
+
event,
|
929
|
+
"data-monster-role",
|
930
|
+
"select-all",
|
931
|
+
);
|
932
|
+
if (element) {
|
933
|
+
const mode = element.checked;
|
934
|
+
|
935
|
+
const rows = this.getGridElements(`[data-monster-role="select-row"]`);
|
936
|
+
rows.forEach((row) => {
|
937
|
+
row.checked = mode;
|
938
|
+
});
|
939
|
+
|
940
|
+
if (mode) {
|
941
|
+
fireCustomEvent(this, "monster-datatable-all-rows-selected", {});
|
942
|
+
} else {
|
943
|
+
fireCustomEvent(this, "monster-datatable-all-rows-deselected", {});
|
944
|
+
}
|
945
|
+
|
946
|
+
fireCustomEvent(this, "monster-datatable-selection-changed", {});
|
947
|
+
}
|
948
|
+
};
|
949
|
+
|
950
|
+
this[gridHeadersElementSymbol].addEventListener("click", selectAllCallback);
|
951
|
+
this[gridHeadersElementSymbol].addEventListener("touch", selectAllCallback);
|
947
952
|
}
|
948
953
|
|
949
954
|
/**
|
950
955
|
* @private
|
951
956
|
*/
|
952
957
|
function initGridAndStructs(hostConfig, headerOrderMap) {
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
958
|
+
const rowID = this.getOption("templateMapping.row-key");
|
959
|
+
|
960
|
+
if (!this[gridElementSymbol]) {
|
961
|
+
addErrorAttribute(this, "no grid element found");
|
962
|
+
return;
|
963
|
+
}
|
964
|
+
|
965
|
+
let template;
|
966
|
+
getSlottedElements.call(this).forEach((e) => {
|
967
|
+
if (e instanceof HTMLTemplateElement && e.id === rowID) {
|
968
|
+
template = e;
|
969
|
+
}
|
970
|
+
});
|
971
|
+
|
972
|
+
if (!template) {
|
973
|
+
addErrorAttribute(
|
974
|
+
this,
|
975
|
+
"no template found, please add a template",
|
976
|
+
);
|
977
|
+
return;
|
978
|
+
}
|
979
|
+
|
980
|
+
const rowCount = template.content.children.length;
|
981
|
+
|
982
|
+
const headers = [];
|
983
|
+
|
984
|
+
for (let i = 0; i < rowCount; i++) {
|
985
|
+
let hClass = "";
|
986
|
+
const row = template.content.children[i];
|
987
|
+
|
988
|
+
let mode = "";
|
989
|
+
if (row.hasAttribute(ATTRIBUTE_DATATABLE_MODE)) {
|
990
|
+
mode = row.getAttribute(ATTRIBUTE_DATATABLE_MODE);
|
991
|
+
}
|
992
|
+
|
993
|
+
let grid = row.getAttribute(ATTRIBUTE_DATATABLE_GRID_TEMPLATE);
|
994
|
+
if (!grid || grid === "" || grid === "auto") {
|
995
|
+
grid = "minmax(0, 1fr)";
|
996
|
+
}
|
997
|
+
|
998
|
+
let label = "";
|
999
|
+
let labelKey = "";
|
1000
|
+
|
1001
|
+
if (row.hasAttribute(ATTRIBUTE_DATATABLE_HEAD)) {
|
1002
|
+
label = row.getAttribute(ATTRIBUTE_DATATABLE_HEAD);
|
1003
|
+
labelKey = label;
|
1004
|
+
|
1005
|
+
try {
|
1006
|
+
if (label.startsWith("i18n:")) {
|
1007
|
+
label = label.substring(5, label.length);
|
1008
|
+
label = getDocumentTranslations().getText(label, label);
|
1009
|
+
}
|
1010
|
+
} catch (e) {
|
1011
|
+
label = "i18n error " + label;
|
1012
|
+
}
|
1013
|
+
}
|
1014
|
+
|
1015
|
+
if (!label) {
|
1016
|
+
label = i + 1 + "";
|
1017
|
+
mode = ATTRIBUTE_DATATABLE_MODE_FIXED;
|
1018
|
+
labelKey = label;
|
1019
|
+
}
|
1020
|
+
|
1021
|
+
if (isObject(hostConfig) && hostConfig.hasOwnProperty(label)) {
|
1022
|
+
if (hostConfig[label] === false) {
|
1023
|
+
mode = ATTRIBUTE_DATATABLE_MODE_HIDDEN;
|
1024
|
+
} else {
|
1025
|
+
mode = ATTRIBUTE_DATATABLE_MODE_VISIBLE;
|
1026
|
+
}
|
1027
|
+
}
|
1028
|
+
|
1029
|
+
let align = "";
|
1030
|
+
if (row.hasAttribute(ATTRIBUTE_DATATABLE_ALIGN)) {
|
1031
|
+
align = row.getAttribute(ATTRIBUTE_DATATABLE_ALIGN);
|
1032
|
+
}
|
1033
|
+
|
1034
|
+
switch (align) {
|
1035
|
+
case "center":
|
1036
|
+
hClass = "flex-center";
|
1037
|
+
break;
|
1038
|
+
case "end":
|
1039
|
+
hClass = "flex-end";
|
1040
|
+
break;
|
1041
|
+
case "start":
|
1042
|
+
hClass = "flex-start";
|
1043
|
+
break;
|
1044
|
+
default:
|
1045
|
+
hClass = "flex-start";
|
1046
|
+
}
|
1047
|
+
|
1048
|
+
let field = "";
|
1049
|
+
let direction = DIRECTION_NONE;
|
1050
|
+
if (row.hasAttribute(ATTRIBUTE_DATATABLE_SORTABLE)) {
|
1051
|
+
field = row.getAttribute(ATTRIBUTE_DATATABLE_SORTABLE).trim();
|
1052
|
+
const parts = field.split(" ").map((item) => item.trim());
|
1053
|
+
field = parts[0];
|
1054
|
+
|
1055
|
+
if (headerOrderMap.has(field)) {
|
1056
|
+
direction = headerOrderMap.get(field);
|
1057
|
+
} else if (
|
1058
|
+
parts.length === 2 &&
|
1059
|
+
[DIRECTION_ASC, DIRECTION_DESC].indexOf(parts[1]) !== -1
|
1060
|
+
) {
|
1061
|
+
direction = parts[1];
|
1062
|
+
}
|
1063
|
+
}
|
1064
|
+
|
1065
|
+
if (mode === ATTRIBUTE_DATATABLE_MODE_HIDDEN) {
|
1066
|
+
hClass += " hidden";
|
1067
|
+
}
|
1068
|
+
|
1069
|
+
const features = [];
|
1070
|
+
|
1071
|
+
if (row.hasAttribute(ATTRIBUTE_DATATABLE_FEATURES)) {
|
1072
|
+
const fl = row
|
1073
|
+
.getAttribute(ATTRIBUTE_DATATABLE_FEATURES)
|
1074
|
+
.split(" ");
|
1075
|
+
|
1076
|
+
fl.forEach((feature) => {
|
1077
|
+
features.push(feature.trim());
|
1078
|
+
|
1079
|
+
if (feature === "select") {
|
1080
|
+
label = "<input type='checkbox' data-monster-role='select-all' />";
|
1081
|
+
|
1082
|
+
while (row.firstChild) {
|
1083
|
+
row.removeChild(row.firstChild);
|
1084
|
+
}
|
1085
|
+
|
1086
|
+
const checkbox = document.createElement("input");
|
1087
|
+
checkbox.type = "checkbox";
|
1088
|
+
checkbox.setAttribute("data-monster-role", "select-row");
|
1089
|
+
row.appendChild(checkbox);
|
1090
|
+
}
|
1091
|
+
});
|
1092
|
+
}
|
1093
|
+
|
1094
|
+
const header = new Header();
|
1095
|
+
header.setInternals({
|
1096
|
+
field: field,
|
1097
|
+
label: label,
|
1098
|
+
classes: hClass,
|
1099
|
+
index: i,
|
1100
|
+
mode: mode,
|
1101
|
+
grid: grid,
|
1102
|
+
labelKey: labelKey,
|
1103
|
+
direction: direction,
|
1104
|
+
features: features,
|
1105
|
+
});
|
1106
|
+
|
1107
|
+
headers.push(header);
|
1108
|
+
}
|
1109
|
+
|
1110
|
+
this.setOption("headers", headers);
|
1111
|
+
queueMicrotask(() => {
|
1112
|
+
storeOrderStatement.call(this, this.getOption("features.autoInit"));
|
1113
|
+
});
|
1102
1114
|
}
|
1103
1115
|
|
1104
1116
|
/**
|
@@ -1106,101 +1118,101 @@ function initGridAndStructs(hostConfig, headerOrderMap) {
|
|
1106
1118
|
* @returns {object}
|
1107
1119
|
*/
|
1108
1120
|
function getTranslations() {
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
1150
|
-
|
1151
|
-
|
1152
|
-
|
1153
|
-
|
1154
|
-
|
1155
|
-
|
1156
|
-
|
1157
|
-
|
1158
|
-
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
1166
|
-
|
1167
|
-
|
1168
|
-
|
1169
|
-
|
1170
|
-
|
1171
|
-
|
1172
|
-
|
1173
|
-
|
1174
|
-
|
1175
|
-
|
1176
|
-
|
1177
|
-
|
1178
|
-
|
1179
|
-
|
1180
|
-
|
1181
|
-
|
1182
|
-
|
1183
|
-
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1199
|
-
|
1200
|
-
|
1201
|
-
|
1202
|
-
|
1203
|
-
|
1121
|
+
const locale = getLocaleOfDocument();
|
1122
|
+
switch (locale.language) {
|
1123
|
+
case "de":
|
1124
|
+
return {
|
1125
|
+
theListContainsNoEntries: "Die Liste enthält keine Einträge",
|
1126
|
+
copyAll: "Alles kopieren",
|
1127
|
+
helpText:
|
1128
|
+
"<p>Sie können die Werte aus einzelnen Zeilen<br>" +
|
1129
|
+
"in die Zwischenablage kopieren, indem Sie auf die entsprechende Spalte doppelklicken.</p>" +
|
1130
|
+
"<p>Um eine ganze Zeile zu kopieren, halten Sie die Umschalttaste gedrückt, während Sie klicken.<br>" +
|
1131
|
+
"Wenn Sie alle Zeilen kopieren möchten, können Sie die Schaltfläche <strong>Alles kopieren</strong> verwenden.</p>",
|
1132
|
+
};
|
1133
|
+
case "fr":
|
1134
|
+
return {
|
1135
|
+
theListContainsNoEntries: "La liste ne contient aucune entrée",
|
1136
|
+
copyAll: "Copier tout",
|
1137
|
+
helpText:
|
1138
|
+
"<p>Vous pouvez copier les valeurs des rangées individuelles<br>" +
|
1139
|
+
"dans le presse-papiers en double-cliquant sur la colonne concernée.</p>" +
|
1140
|
+
"<p>Pour copier une rangée entière, maintenez la touche Maj enfoncée tout en cliquant.<br>" +
|
1141
|
+
"Si vous souhaitez copier toutes les rangées, vous pouvez utiliser le bouton <strong>Copier tout</strong>.</p>",
|
1142
|
+
};
|
1143
|
+
case "sp":
|
1144
|
+
return {
|
1145
|
+
theListContainsNoEntries: "La lista no contiene entradas",
|
1146
|
+
copyAll: "Copiar todo",
|
1147
|
+
helpText:
|
1148
|
+
"<p>Puedes copiar los valores de filas individuales<br>" +
|
1149
|
+
"al portapapeles haciendo doble clic en la columna correspondiente.</p>" +
|
1150
|
+
"<p>Para copiar una fila entera, mantén presionada la tecla Shift mientras haces clic.<br>" +
|
1151
|
+
"Si quieres copiar todas las filas, puedes usar el botón <strong>Copiar todo</strong>.</p>",
|
1152
|
+
};
|
1153
|
+
case "it":
|
1154
|
+
return {
|
1155
|
+
theListContainsNoEntries: "L'elenco non contiene voci",
|
1156
|
+
copyAll: "Copia tutto",
|
1157
|
+
helpText:
|
1158
|
+
"<p>Puoi copiare i valori dalle singole righe<br>" +
|
1159
|
+
"negli appunti facendo doppio clic sulla colonna relativa.</p>" +
|
1160
|
+
"<p>Per copiare un'intera riga, tieni premuto il tasto Shift mentre clicchi.<br>" +
|
1161
|
+
"Se vuoi copiare tutte le righe, puoi usare il pulsante <strong>Copia tutto</strong>.</p>",
|
1162
|
+
};
|
1163
|
+
case "pl":
|
1164
|
+
return {
|
1165
|
+
theListContainsNoEntries: "Lista nie zawiera wpisów",
|
1166
|
+
copyAll: "Kopiuj wszystko",
|
1167
|
+
helpText:
|
1168
|
+
"<p>Możesz skopiować wartości z poszczególnych wierszy<br>" +
|
1169
|
+
"do schowka, klikając dwukrotnie na odpowiednią kolumnę.</p>" +
|
1170
|
+
"<p>Aby skopiować cały wiersz, przytrzymaj klawisz Shift podczas klikania.<br>" +
|
1171
|
+
"Jeśli chcesz skopiować wszystkie wiersze, możesz użyć przycisku <strong>Kopiuj wszystko</strong>.</p>",
|
1172
|
+
};
|
1173
|
+
case "no":
|
1174
|
+
return {
|
1175
|
+
theListContainsNoEntries: "Listen inneholder ingen oppføringer",
|
1176
|
+
copyAll: "Kopier alt",
|
1177
|
+
helpText:
|
1178
|
+
"<p>Du kan kopiere verdier fra enkeltrader<br>" +
|
1179
|
+
"til utklippstavlen ved å dobbeltklikke på den relevante kolonnen.</p>" +
|
1180
|
+
"<p>For å kopiere en hel rad, hold nede Skift-tasten mens du klikker.<br>" +
|
1181
|
+
"Hvis du vil kopiere alle radene, kan du bruke knappen <strong>Kopier alt</strong>.</p>",
|
1182
|
+
};
|
1183
|
+
case "dk":
|
1184
|
+
return {
|
1185
|
+
theListContainsNoEntries: "Listen indeholder ingen poster",
|
1186
|
+
copyAll: "Kopiér alt",
|
1187
|
+
helpText:
|
1188
|
+
"<p>Du kan kopiere værdier fra enkelte rækker<br>" +
|
1189
|
+
"til udklipsholderen ved at dobbeltklikke på den relevante kolonne.</p>" +
|
1190
|
+
"<p>For at kopiere en hel række, hold Shift-tasten nede, mens du klikker.<br>" +
|
1191
|
+
"Hvis du vil kopiere alle rækker, kan du bruge knappen <strong>Kopiér alt</strong>.</p>",
|
1192
|
+
};
|
1193
|
+
case "sw":
|
1194
|
+
return {
|
1195
|
+
theListContainsNoEntries: "Listan innehåller inga poster",
|
1196
|
+
copyAll: "Kopiera allt",
|
1197
|
+
helpText:
|
1198
|
+
"<p>Du kan kopiera värden från enskilda rader<br>" +
|
1199
|
+
"till urklipp genom att dubbelklicka på den relevanta kolumnen.</p>" +
|
1200
|
+
"<p>För att kopiera en hel rad, håll ned Shift-tangenten medan du klickar.<br>" +
|
1201
|
+
"Om du vill kopiera alla rader kan du använda knappen <strong>Kopiera allt</strong>.</p>",
|
1202
|
+
};
|
1203
|
+
|
1204
|
+
case "en":
|
1205
|
+
default:
|
1206
|
+
return {
|
1207
|
+
theListContainsNoEntries: "The list contains no entries",
|
1208
|
+
copyAll: "Copy all",
|
1209
|
+
helpText:
|
1210
|
+
"<p>You can copy the values from individual rows<br>" +
|
1211
|
+
"to the clipboard by double-clicking on the relevant column.</p>" +
|
1212
|
+
"<p>To copy an entire row, hold down the Shift key while clicking.<br>" +
|
1213
|
+
"If you want to copy all rows, you can use the <strong>Copy All</strong> button.</p>",
|
1214
|
+
};
|
1215
|
+
}
|
1204
1216
|
}
|
1205
1217
|
|
1206
1218
|
/**
|
@@ -1208,79 +1220,79 @@ function getTranslations() {
|
|
1208
1220
|
* @return {string}
|
1209
1221
|
*/
|
1210
1222
|
export function getStoredOrderConfigKey() {
|
1211
|
-
|
1223
|
+
return generateUniqueConfigKey("datatable", this?.id, "stored-order");
|
1212
1224
|
}
|
1213
1225
|
|
1214
1226
|
/**
|
1215
1227
|
* @private
|
1216
1228
|
*/
|
1217
1229
|
function storeOrderStatement(doFetch) {
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1230
|
+
const headers = this.getOption("headers");
|
1231
|
+
const statement = createOrderStatement(headers);
|
1232
|
+
setDataSource.call(this, {orderBy: statement}, doFetch);
|
1221
1233
|
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1225
|
-
|
1234
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
1235
|
+
if (!(host && this.id)) {
|
1236
|
+
return;
|
1237
|
+
}
|
1226
1238
|
|
1227
|
-
|
1239
|
+
const configKey = getStoredOrderConfigKey.call(this);
|
1228
1240
|
|
1229
|
-
|
1230
|
-
|
1231
|
-
|
1232
|
-
|
1233
|
-
|
1241
|
+
// statement explode with , and remove all empty
|
1242
|
+
const list = statement.split(",").filter((item) => item.trim() !== "");
|
1243
|
+
if (list.length === 0) {
|
1244
|
+
return;
|
1245
|
+
}
|
1234
1246
|
|
1235
|
-
|
1247
|
+
host.setConfig(configKey, list);
|
1236
1248
|
}
|
1237
1249
|
|
1238
1250
|
/**
|
1239
1251
|
* @private
|
1240
1252
|
*/
|
1241
1253
|
function updateGrid() {
|
1242
|
-
|
1243
|
-
|
1244
|
-
|
1245
|
-
|
1246
|
-
|
1247
|
-
|
1248
|
-
|
1249
|
-
|
1250
|
-
|
1251
|
-
|
1252
|
-
|
1253
|
-
|
1254
|
-
|
1255
|
-
|
1256
|
-
|
1257
|
-
|
1258
|
-
|
1259
|
-
|
1260
|
-
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1266
|
-
|
1267
|
-
|
1268
|
-
|
1269
|
-
|
1270
|
-
|
1271
|
-
|
1272
|
-
|
1273
|
-
|
1274
|
-
|
1275
|
-
|
1276
|
-
|
1277
|
-
|
1278
|
-
|
1279
|
-
|
1280
|
-
|
1281
|
-
|
1282
|
-
|
1283
|
-
|
1254
|
+
if (!this[gridElementSymbol]) {
|
1255
|
+
throw new Error("no grid element is defined");
|
1256
|
+
}
|
1257
|
+
|
1258
|
+
let gridTemplateColumns = "";
|
1259
|
+
|
1260
|
+
const headers = this.getOption("headers");
|
1261
|
+
|
1262
|
+
let styles = "";
|
1263
|
+
|
1264
|
+
for (let i = 0; i < headers.length; i++) {
|
1265
|
+
const header = headers[i];
|
1266
|
+
|
1267
|
+
if (header.mode === ATTRIBUTE_DATATABLE_MODE_HIDDEN) {
|
1268
|
+
styles += `[data-monster-role=datatable]>[data-monster-head="${header.labelKey}"] { display: none; }\n`;
|
1269
|
+
styles += `[data-monster-role=datatable-headers]>[data-monster-index="${header.index}"] { display: none; }\n`;
|
1270
|
+
} else {
|
1271
|
+
gridTemplateColumns += `${header.grid} `;
|
1272
|
+
}
|
1273
|
+
}
|
1274
|
+
|
1275
|
+
const sheet = new CSSStyleSheet();
|
1276
|
+
if (styles !== "") sheet.replaceSync(styles);
|
1277
|
+
this.shadowRoot.adoptedStyleSheets = [...DataTable.getCSSStyleSheet(), sheet];
|
1278
|
+
|
1279
|
+
const bodyWidth = this.parentNode.clientWidth;
|
1280
|
+
|
1281
|
+
const breakpoint = this.getOption("responsive.breakpoint");
|
1282
|
+
this[dataControlElementSymbol].classList.toggle(
|
1283
|
+
"small",
|
1284
|
+
bodyWidth <= breakpoint,
|
1285
|
+
);
|
1286
|
+
|
1287
|
+
if (bodyWidth > breakpoint) {
|
1288
|
+
this[gridElementSymbol].style.gridTemplateColumns =
|
1289
|
+
`${gridTemplateColumns}`;
|
1290
|
+
this[gridHeadersElementSymbol].style.gridTemplateColumns =
|
1291
|
+
`${gridTemplateColumns}`;
|
1292
|
+
} else {
|
1293
|
+
this[gridElementSymbol].style.gridTemplateColumns = "auto";
|
1294
|
+
this[gridHeadersElementSymbol].style.gridTemplateColumns = "auto";
|
1295
|
+
}
|
1284
1296
|
}
|
1285
1297
|
|
1286
1298
|
/**
|
@@ -1288,20 +1300,20 @@ function updateGrid() {
|
|
1288
1300
|
* @param {Header[]} headers
|
1289
1301
|
* @param {bool} doFetch
|
1290
1302
|
*/
|
1291
|
-
function setDataSource({
|
1292
|
-
|
1303
|
+
function setDataSource({orderBy}, doFetch) {
|
1304
|
+
const datasource = this[datasourceLinkedElementSymbol];
|
1293
1305
|
|
1294
|
-
|
1295
|
-
|
1296
|
-
|
1306
|
+
if (!datasource) {
|
1307
|
+
return;
|
1308
|
+
}
|
1297
1309
|
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1310
|
+
if (isFunction(datasource?.setParameters)) {
|
1311
|
+
datasource.setParameters({orderBy});
|
1312
|
+
}
|
1301
1313
|
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
1314
|
+
if (doFetch !== false && isFunction(datasource?.fetch)) {
|
1315
|
+
datasource.fetch();
|
1316
|
+
}
|
1305
1317
|
}
|
1306
1318
|
|
1307
1319
|
/**
|
@@ -1309,30 +1321,30 @@ function setDataSource({ orderBy }, doFetch) {
|
|
1309
1321
|
* @return {DataTable}
|
1310
1322
|
*/
|
1311
1323
|
function initControlReferences() {
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1324
|
+
if (!this.shadowRoot) {
|
1325
|
+
throw new Error("no shadow-root is defined");
|
1326
|
+
}
|
1315
1327
|
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1328
|
+
this[dataControlElementSymbol] = this.shadowRoot.querySelector(
|
1329
|
+
"[data-monster-role=control]",
|
1330
|
+
);
|
1319
1331
|
|
1320
|
-
|
1321
|
-
|
1322
|
-
|
1332
|
+
this[gridElementSymbol] = this.shadowRoot.querySelector(
|
1333
|
+
"[data-monster-role=datatable]",
|
1334
|
+
);
|
1323
1335
|
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1336
|
+
this[gridHeadersElementSymbol] = this.shadowRoot.querySelector(
|
1337
|
+
"[data-monster-role=datatable-headers]",
|
1338
|
+
);
|
1327
1339
|
|
1328
|
-
|
1329
|
-
|
1340
|
+
this[columnBarElementSymbol] =
|
1341
|
+
this.shadowRoot.querySelector("monster-column-bar");
|
1330
1342
|
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
1343
|
+
this[copyAllElementSymbol] = this.shadowRoot.querySelector(
|
1344
|
+
"[data-monster-role=copy-all]",
|
1345
|
+
);
|
1334
1346
|
|
1335
|
-
|
1347
|
+
return this;
|
1336
1348
|
}
|
1337
1349
|
|
1338
1350
|
/**
|
@@ -1342,22 +1354,22 @@ function initControlReferences() {
|
|
1342
1354
|
* @throws {Error} the datasource could not be initialized
|
1343
1355
|
*/
|
1344
1356
|
function initOptionsFromArguments() {
|
1345
|
-
|
1346
|
-
|
1347
|
-
|
1348
|
-
|
1349
|
-
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1356
|
-
|
1357
|
-
|
1358
|
-
|
1359
|
-
|
1360
|
-
|
1357
|
+
const options = {};
|
1358
|
+
const selector = this.getAttribute(ATTRIBUTE_DATASOURCE_SELECTOR);
|
1359
|
+
|
1360
|
+
if (selector) {
|
1361
|
+
options.datasource = {selector: selector};
|
1362
|
+
}
|
1363
|
+
|
1364
|
+
const breakpoint = this.getAttribute(
|
1365
|
+
ATTRIBUTE_DATATABLE_RESPONSIVE_BREAKPOINT,
|
1366
|
+
);
|
1367
|
+
if (breakpoint) {
|
1368
|
+
options.responsive = {};
|
1369
|
+
options.responsive.breakpoint = parseInt(breakpoint);
|
1370
|
+
}
|
1371
|
+
|
1372
|
+
return options;
|
1361
1373
|
}
|
1362
1374
|
|
1363
1375
|
/**
|
@@ -1365,7 +1377,7 @@ function initOptionsFromArguments() {
|
|
1365
1377
|
* @return {string}
|
1366
1378
|
*/
|
1367
1379
|
function getEmptyTemplate() {
|
1368
|
-
|
1380
|
+
return `<monster-state data-monster-role="empty-without-action">
|
1369
1381
|
<div part="visual">
|
1370
1382
|
<svg width="4rem" height="4rem" fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
1371
1383
|
<path d="m21.5 22h-19c-1.378 0-2.5-1.121-2.5-2.5v-7c0-.07.015-.141.044-.205l3.969-8.82c.404-.896 1.299-1.475 2.28-1.475h11.414c.981 0 1.876.579 2.28 1.475l3.969 8.82c.029.064.044.135.044.205v7c0 1.379-1.122 2.5-2.5 2.5zm-20.5-9.393v6.893c0 .827.673 1.5 1.5 1.5h19c.827 0 1.5-.673 1.5-1.5v-6.893l-3.925-8.723c-.242-.536-.779-.884-1.368-.884h-11.414c-.589 0-1.126.348-1.368.885z"/>
|
@@ -1383,8 +1395,8 @@ function getEmptyTemplate() {
|
|
1383
1395
|
* @return {string}
|
1384
1396
|
*/
|
1385
1397
|
function getTemplate() {
|
1386
|
-
|
1387
|
-
|
1398
|
+
// language=HTML
|
1399
|
+
return `
|
1388
1400
|
<div data-monster-role="control" part="control" data-monster-attributes="class path:classes.control">
|
1389
1401
|
<template id="headers-row">
|
1390
1402
|
<div data-monster-attributes="class path:headers-row.classes,
|