@schukai/monster 3.88.0 → 3.88.1
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 +65 -46
- package/package.json +1 -1
- package/source/components/content/stylesheet/copy.mjs +1 -1
- package/source/components/datatable/datatable.mjs +922 -914
- package/source/components/datatable/filter.mjs +914 -920
- package/source/components/datatable/pagination.mjs +1 -3
- package/source/components/datatable/stylesheet/change-button.mjs +1 -1
- package/source/components/datatable/stylesheet/column-bar.mjs +13 -6
- package/source/components/datatable/stylesheet/dataset.mjs +1 -1
- package/source/components/datatable/stylesheet/datatable.mjs +13 -6
- package/source/components/datatable/stylesheet/embedded-pagination.mjs +13 -6
- package/source/components/datatable/stylesheet/filter-select.mjs +1 -1
- package/source/components/datatable/stylesheet/filter.mjs +13 -6
- package/source/components/datatable/stylesheet/save-button.mjs +1 -1
- package/source/components/datatable/stylesheet/status.mjs +1 -1
- package/source/components/form/api-button.mjs +420 -415
- package/source/components/form/button-bar.mjs +24 -6
- package/source/components/form/popper.mjs +1 -1
- package/source/components/form/stylesheet/action-button.mjs +13 -6
- package/source/components/form/stylesheet/button.mjs +13 -6
- package/source/components/form/stylesheet/confirm-button.mjs +13 -6
- package/source/components/form/stylesheet/form.mjs +1 -1
- package/source/components/form/stylesheet/popper-button.mjs +13 -6
- package/source/components/form/stylesheet/select.mjs +13 -6
- package/source/components/form/stylesheet/state-button.mjs +13 -6
- package/source/components/form/tree-select.mjs +1 -1
- package/source/components/host/stylesheet/call-button.mjs +1 -1
- package/source/components/host/stylesheet/host.mjs +1 -1
- package/source/components/host/stylesheet/overlay.mjs +1 -1
- package/source/components/host/stylesheet/toggle-button.mjs +1 -1
- package/source/components/host/stylesheet/viewer.mjs +1 -1
- package/source/components/layout/stylesheet/collapse.mjs +1 -1
- package/source/components/layout/stylesheet/details.mjs +1 -1
- package/source/components/layout/stylesheet/slider.mjs +1 -1
- package/source/components/layout/stylesheet/tabs.mjs +1 -1
- package/source/components/navigation/stylesheet/table-of-content.mjs +1 -1
- package/source/components/navigation/table-of-content.mjs +20 -4
- package/source/components/style/common.css +1 -1
- package/source/components/style/common.pcss +7 -1
- package/source/components/style/mixin/property.pcss +1 -0
- package/source/components/style/normalize.css +1 -1
- package/source/components/style/normalize.pcss +8 -0
- package/source/components/style/property.css +1 -1
- package/source/components/stylesheet/common.mjs +7 -14
- package/source/components/stylesheet/mixin/property.mjs +6 -13
- package/source/components/stylesheet/normalize.mjs +7 -14
- package/source/components/stylesheet/property.mjs +1 -1
- package/source/components/tree-menu/style/tree-menu.pcss +0 -2
- package/source/components/tree-menu/stylesheet/tree-menu.mjs +7 -14
- package/source/types/is.mjs +9 -1
- package/source/types/version.mjs +1 -1
- package/test/cases/monster.mjs +1 -1
- package/test/cases/types/is.mjs +59 -1
- package/test/util/jsdom.mjs +2 -0
- package/test/web/test.html +2 -2
- package/test/web/tests.js +83 -21
@@ -12,77 +12,77 @@
|
|
12
12
|
* SPDX-License-Identifier: AGPL-3.0
|
13
13
|
*/
|
14
14
|
|
15
|
-
import {Datasource} from "./datasource.mjs";
|
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 {clone} from "../../util/clone.mjs";
|
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 {Observer} from "../../types/observer.mjs";
|
39
|
+
import { Observer } from "../../types/observer.mjs";
|
40
40
|
import {
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
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_MODE_VISIBLE,
|
50
|
+
ATTRIBUTE_DATATABLE_RESPONSIVE_BREAKPOINT,
|
51
|
+
ATTRIBUTE_DATATABLE_MODE_FIXED,
|
52
52
|
} from "./constants.mjs";
|
53
|
-
import {instanceSymbol} from "../../constants.mjs";
|
53
|
+
import { instanceSymbol } from "../../constants.mjs";
|
54
54
|
import {
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
55
|
+
Header,
|
56
|
+
createOrderStatement,
|
57
|
+
DIRECTION_ASC,
|
58
|
+
DIRECTION_DESC,
|
59
|
+
DIRECTION_NONE,
|
60
60
|
} from "./datatable/header.mjs";
|
61
|
-
import {DatatableStyleSheet} from "./stylesheet/datatable.mjs";
|
61
|
+
import { DatatableStyleSheet } from "./stylesheet/datatable.mjs";
|
62
62
|
import {
|
63
|
-
|
64
|
-
|
63
|
+
handleDataSourceChanges,
|
64
|
+
datasourceLinkedElementSymbol,
|
65
65
|
} from "./util.mjs";
|
66
66
|
import "./columnbar.mjs";
|
67
67
|
import "./filter-button.mjs";
|
68
68
|
import {
|
69
|
-
|
70
|
-
|
71
|
-
|
69
|
+
findElementWithSelectorUpwards,
|
70
|
+
getDocument,
|
71
|
+
getWindow,
|
72
72
|
} from "../../dom/util.mjs";
|
73
|
-
import {addAttributeToken} from "../../dom/attributes.mjs";
|
74
|
-
import {ATTRIBUTE_ERRORMESSAGE} from "../../dom/constants.mjs";
|
75
|
-
import {getDocumentTranslations} from "../../i18n/translations.mjs";
|
73
|
+
import { addAttributeToken } from "../../dom/attributes.mjs";
|
74
|
+
import { ATTRIBUTE_ERRORMESSAGE } from "../../dom/constants.mjs";
|
75
|
+
import { getDocumentTranslations } from "../../i18n/translations.mjs";
|
76
76
|
import "../state/state.mjs";
|
77
77
|
import "../host/collapse.mjs";
|
78
|
-
import {generateUniqueConfigKey} from "../host/util.mjs";
|
78
|
+
import { generateUniqueConfigKey } from "../host/util.mjs";
|
79
79
|
|
80
80
|
import "./datasource/dom.mjs";
|
81
81
|
import "./datasource/rest.mjs";
|
82
82
|
|
83
83
|
import "../form/context-help.mjs";
|
84
84
|
|
85
|
-
export {DataTable};
|
85
|
+
export { DataTable };
|
86
86
|
|
87
87
|
/**
|
88
88
|
* @private
|
@@ -150,403 +150,404 @@ const resizeObserverSymbol = Symbol("resizeObserver");
|
|
150
150
|
* @fires monster-datatable-row-added
|
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
|
-
|
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 {Object} templateMapping Template mapping
|
187
|
+
* @property {string} templateMapping.row-key Row key
|
188
|
+
* @property {string} templateMapping.filter-id Filter id
|
189
|
+
**/
|
190
|
+
get defaults() {
|
191
|
+
return Object.assign(
|
192
|
+
{},
|
193
|
+
super.defaults,
|
194
|
+
{
|
195
|
+
templates: {
|
196
|
+
main: getTemplate(),
|
197
|
+
emptyState: getEmptyTemplate(),
|
198
|
+
},
|
199
|
+
|
200
|
+
datasource: {
|
201
|
+
selector: null,
|
202
|
+
},
|
203
|
+
|
204
|
+
mapping: {
|
205
|
+
data: "dataset",
|
206
|
+
},
|
207
|
+
|
208
|
+
data: [],
|
209
|
+
headers: [],
|
210
|
+
|
211
|
+
responsive: {
|
212
|
+
breakpoint: 900,
|
213
|
+
},
|
214
|
+
|
215
|
+
labels: {
|
216
|
+
theListContainsNoEntries: "The list contains no entries",
|
217
|
+
copyAll: "Copy all",
|
218
|
+
helpText:
|
219
|
+
"<p>You can copy the values from individual rows<br>" +
|
220
|
+
"to the clipboard by double-clicking on the relevant column.</p>" +
|
221
|
+
"<p>To copy an entire row, hold down the Shift key while clicking.<br>" +
|
222
|
+
"If you want to copy all rows, you can use the <strong>Copy All</strong> button.</p>",
|
223
|
+
},
|
224
|
+
|
225
|
+
classes: {
|
226
|
+
control: "monster-theme-control-container-1",
|
227
|
+
container: "",
|
228
|
+
row: "monster-theme-control-row-1",
|
229
|
+
},
|
230
|
+
|
231
|
+
features: {
|
232
|
+
settings: true,
|
233
|
+
footer: true,
|
234
|
+
autoInit: true,
|
235
|
+
doubleClickCopyToClipboard: true,
|
236
|
+
copyAll: true,
|
237
|
+
help: true,
|
238
|
+
},
|
239
|
+
|
240
|
+
copy: {
|
241
|
+
delimiter: ";",
|
242
|
+
quoteOpen: '"',
|
243
|
+
quoteClose: '"',
|
244
|
+
rowBreak: "\n",
|
245
|
+
},
|
246
|
+
|
247
|
+
templateMapping: {
|
248
|
+
"row-key": null,
|
249
|
+
"filter-id": null,
|
250
|
+
},
|
251
|
+
},
|
252
|
+
initOptionsFromArguments.call(this),
|
253
|
+
);
|
254
|
+
}
|
255
|
+
|
256
|
+
/**
|
257
|
+
*
|
258
|
+
* @param {string} selector
|
259
|
+
* @return {NodeListOf<*>}
|
260
|
+
*/
|
261
|
+
getGridElements(selector) {
|
262
|
+
return this[gridElementSymbol].querySelectorAll(selector);
|
263
|
+
}
|
264
|
+
|
265
|
+
/**
|
266
|
+
*
|
267
|
+
* @return {string}
|
268
|
+
*/
|
269
|
+
static getTag() {
|
270
|
+
return "monster-datatable";
|
271
|
+
}
|
272
|
+
|
273
|
+
/**
|
274
|
+
* @return {void}
|
275
|
+
*/
|
276
|
+
disconnectedCallback() {
|
277
|
+
super.disconnectedCallback();
|
278
|
+
if (this?.[resizeObserverSymbol] instanceof ResizeObserver) {
|
279
|
+
this[resizeObserverSymbol].disconnect();
|
280
|
+
}
|
281
|
+
}
|
282
|
+
|
283
|
+
/**
|
284
|
+
* @return {void}
|
285
|
+
*/
|
286
|
+
connectedCallback() {
|
287
|
+
const self = this;
|
288
|
+
super.connectedCallback();
|
289
|
+
|
290
|
+
this[resizeObserverSymbol] = new ResizeObserver((entries) => {
|
291
|
+
updateGrid.call(self);
|
292
|
+
});
|
293
|
+
|
294
|
+
this[resizeObserverSymbol].observe(this.parentNode);
|
295
|
+
}
|
296
|
+
|
297
|
+
/**
|
298
|
+
* @return void
|
299
|
+
*/
|
300
|
+
[assembleMethodSymbol]() {
|
301
|
+
const rawKey = this.getOption("templateMapping.row-key");
|
302
|
+
|
303
|
+
if (rawKey === null) {
|
304
|
+
if (this.id !== null && this.id !== "") {
|
305
|
+
const rawKey = this.getOption("templateMapping.row-key");
|
306
|
+
if (rawKey === null) {
|
307
|
+
this.setOption("templateMapping.row-key", this.id + "-row");
|
308
|
+
}
|
309
|
+
} else {
|
310
|
+
this.setOption("templateMapping.row-key", "row");
|
311
|
+
}
|
312
|
+
}
|
313
|
+
|
314
|
+
if (this.id !== null && this.id !== "") {
|
315
|
+
this.setOption("templateMapping.filter-id", "" + this.id + "-filter");
|
316
|
+
} else {
|
317
|
+
this.setOption("templateMapping.filter-id", "filter");
|
318
|
+
}
|
319
|
+
|
320
|
+
super[assembleMethodSymbol]();
|
321
|
+
|
322
|
+
initControlReferences.call(this);
|
323
|
+
initEventHandler.call(this);
|
324
|
+
|
325
|
+
const selector = this.getOption("datasource.selector");
|
326
|
+
|
327
|
+
if (isString(selector)) {
|
328
|
+
const element = findElementWithSelectorUpwards(this, selector);
|
329
|
+
if (element === null) {
|
330
|
+
throw new Error("the selector must match exactly one element");
|
331
|
+
}
|
332
|
+
|
333
|
+
if (!isInstance(element, Datasource)) {
|
334
|
+
throw new TypeError("the element must be a datasource");
|
335
|
+
}
|
336
|
+
|
337
|
+
this[datasourceLinkedElementSymbol] = element;
|
338
|
+
|
339
|
+
queueMicrotask(() => {
|
340
|
+
handleDataSourceChanges.call(this);
|
341
|
+
element.datasource.attachObserver(
|
342
|
+
new Observer(handleDataSourceChanges.bind(this)),
|
343
|
+
);
|
344
|
+
});
|
345
|
+
}
|
346
|
+
|
347
|
+
getHostConfig
|
348
|
+
.call(this, getColumnVisibilityConfigKey)
|
349
|
+
.then((config) => {
|
350
|
+
const headerOrderMap = new Map();
|
351
|
+
|
352
|
+
getHostConfig
|
353
|
+
.call(this, getStoredOrderConfigKey)
|
354
|
+
.then((orderConfig) => {
|
355
|
+
if (isArray(orderConfig) || orderConfig.length > 0) {
|
356
|
+
for (let i = 0; i < orderConfig.length; i++) {
|
357
|
+
const item = orderConfig[i];
|
358
|
+
const parts = item.split(" ");
|
359
|
+
const field = parts[0];
|
360
|
+
const direction = parts[1] || DIRECTION_ASC;
|
361
|
+
headerOrderMap.set(field, direction);
|
362
|
+
}
|
363
|
+
}
|
364
|
+
})
|
365
|
+
.then(() => {
|
366
|
+
try {
|
367
|
+
initGridAndStructs.call(this, config, headerOrderMap);
|
368
|
+
} catch (error) {
|
369
|
+
addAttributeToken(
|
370
|
+
this,
|
371
|
+
ATTRIBUTE_ERRORMESSAGE,
|
372
|
+
error?.message || error.toString(),
|
373
|
+
);
|
374
|
+
}
|
375
|
+
|
376
|
+
updateColumnBar.call(this);
|
377
|
+
})
|
378
|
+
.catch((error) => {
|
379
|
+
addAttributeToken(
|
380
|
+
this,
|
381
|
+
ATTRIBUTE_ERRORMESSAGE,
|
382
|
+
error?.message || error.toString(),
|
383
|
+
);
|
384
|
+
});
|
385
|
+
})
|
386
|
+
.catch((error) => {
|
387
|
+
addAttributeToken(
|
388
|
+
this,
|
389
|
+
ATTRIBUTE_ERRORMESSAGE,
|
390
|
+
error?.message || error.toString(),
|
391
|
+
);
|
392
|
+
});
|
393
|
+
}
|
394
|
+
|
395
|
+
/**
|
396
|
+
* @return {CSSStyleSheet[]}
|
397
|
+
*/
|
398
|
+
static getCSSStyleSheet() {
|
399
|
+
return [DatatableStyleSheet];
|
400
|
+
}
|
401
|
+
|
402
|
+
/**
|
403
|
+
* Copy a row from the datatable
|
404
|
+
*
|
405
|
+
* @param {number|string} fromIndex
|
406
|
+
* @param {number|string} toIndex
|
407
|
+
* @return {DataTable}
|
408
|
+
* @fires monster-datatable-row-copied
|
409
|
+
*/
|
410
|
+
copyRow(fromIndex, toIndex) {
|
411
|
+
const datasource = this[datasourceLinkedElementSymbol];
|
412
|
+
if (!datasource) {
|
413
|
+
return this;
|
414
|
+
}
|
415
|
+
let d = datasource.data;
|
416
|
+
let c = clone(d);
|
417
|
+
|
418
|
+
let rows = c;
|
419
|
+
const mapping = this.getOption("mapping.data");
|
420
|
+
|
421
|
+
if (mapping) {
|
422
|
+
rows = c?.[mapping];
|
423
|
+
}
|
424
|
+
|
425
|
+
if (rows === undefined || rows === null) {
|
426
|
+
rows = [];
|
427
|
+
}
|
428
|
+
|
429
|
+
if (toIndex === undefined) {
|
430
|
+
toIndex = rows.length;
|
431
|
+
}
|
432
|
+
|
433
|
+
if (isString(fromIndex)) {
|
434
|
+
fromIndex = parseInt(fromIndex);
|
435
|
+
}
|
436
|
+
if (isString(toIndex)) {
|
437
|
+
toIndex = parseInt(toIndex);
|
438
|
+
}
|
439
|
+
|
440
|
+
if (toIndex < 0 || toIndex > rows.length) {
|
441
|
+
throw new RangeError("index out of bounds");
|
442
|
+
}
|
443
|
+
|
444
|
+
validateArray(rows);
|
445
|
+
validateInteger(fromIndex);
|
446
|
+
validateInteger(toIndex);
|
447
|
+
|
448
|
+
if (fromIndex < 0 || fromIndex >= rows.length) {
|
449
|
+
throw new RangeError("index out of bounds");
|
450
|
+
}
|
451
|
+
|
452
|
+
rows.splice(toIndex, 0, clone(rows[fromIndex]));
|
453
|
+
datasource.data = c;
|
454
|
+
|
455
|
+
fireCustomEvent(this, "monster-datatable-row-copied", {
|
456
|
+
index: toIndex,
|
457
|
+
});
|
458
|
+
|
459
|
+
return this;
|
460
|
+
}
|
461
|
+
|
462
|
+
/**
|
463
|
+
* Remove a row from the datatable
|
464
|
+
*
|
465
|
+
* @param {number|string} index
|
466
|
+
* @return {DataTable}
|
467
|
+
* @fires monster-datatable-row-removed
|
468
|
+
*/
|
469
|
+
removeRow(index) {
|
470
|
+
const datasource = this[datasourceLinkedElementSymbol];
|
471
|
+
if (!datasource) {
|
472
|
+
return this;
|
473
|
+
}
|
474
|
+
let d = datasource.data;
|
475
|
+
let c = clone(d);
|
476
|
+
|
477
|
+
let rows = c;
|
478
|
+
const mapping = this.getOption("mapping.data");
|
479
|
+
|
480
|
+
if (mapping) {
|
481
|
+
rows = c?.[mapping];
|
482
|
+
}
|
483
|
+
|
484
|
+
if (rows === undefined || rows === null) {
|
485
|
+
rows = [];
|
486
|
+
}
|
487
|
+
|
488
|
+
if (isString(index)) {
|
489
|
+
index = parseInt(index);
|
490
|
+
}
|
491
|
+
|
492
|
+
validateArray(rows);
|
493
|
+
validateInteger(index);
|
494
|
+
|
495
|
+
if (index < 0 || index >= rows.length) {
|
496
|
+
throw new RangeError("index out of bounds");
|
497
|
+
}
|
498
|
+
if (mapping) {
|
499
|
+
rows = c?.[mapping];
|
500
|
+
}
|
501
|
+
|
502
|
+
rows.splice(index, 1);
|
503
|
+
datasource.data = c;
|
504
|
+
|
505
|
+
fireCustomEvent(this, "monster-datatable-row-removed", {
|
506
|
+
index: index,
|
507
|
+
});
|
508
|
+
|
509
|
+
return this;
|
510
|
+
}
|
511
|
+
|
512
|
+
/**
|
513
|
+
* Add a row to the datatable
|
514
|
+
*
|
515
|
+
* @param {Object} data
|
516
|
+
* @return {DataTable}
|
517
|
+
*
|
518
|
+
* @fires monster-datatable-row-added
|
519
|
+
**/
|
520
|
+
addRow(data) {
|
521
|
+
const datasource = this[datasourceLinkedElementSymbol];
|
522
|
+
if (!datasource) {
|
523
|
+
return this;
|
524
|
+
}
|
525
|
+
let d = datasource.data;
|
526
|
+
let c = clone(d);
|
527
|
+
|
528
|
+
let rows = c;
|
529
|
+
|
530
|
+
const mapping = this.getOption("mapping.data");
|
531
|
+
if (mapping) {
|
532
|
+
rows = c?.[mapping];
|
533
|
+
}
|
534
|
+
|
535
|
+
if (rows === undefined || rows === null) {
|
536
|
+
rows = [];
|
537
|
+
}
|
538
|
+
|
539
|
+
validateArray(rows);
|
540
|
+
validateObject(data);
|
541
|
+
|
542
|
+
rows.push(data);
|
543
|
+
datasource.data = c;
|
544
|
+
|
545
|
+
fireCustomEvent(this, "monster-datatable-row-added", {
|
546
|
+
index: rows.length - 1,
|
547
|
+
});
|
548
|
+
|
549
|
+
return this;
|
550
|
+
}
|
550
551
|
}
|
551
552
|
|
552
553
|
/**
|
@@ -554,7 +555,7 @@ class DataTable extends CustomElement {
|
|
554
555
|
* @return {string}
|
555
556
|
*/
|
556
557
|
function getColumnVisibilityConfigKey() {
|
557
|
-
|
558
|
+
return generateUniqueConfigKey("datatable", this?.id, "columns-visibility");
|
558
559
|
}
|
559
560
|
|
560
561
|
/**
|
@@ -562,7 +563,7 @@ function getColumnVisibilityConfigKey() {
|
|
562
563
|
* @return {string}
|
563
564
|
*/
|
564
565
|
function getFilterConfigKey() {
|
565
|
-
|
566
|
+
return generateUniqueConfigKey("datatable", this?.id, "filter");
|
566
567
|
}
|
567
568
|
|
568
569
|
/**
|
@@ -570,403 +571,410 @@ function getFilterConfigKey() {
|
|
570
571
|
* @return {Promise}
|
571
572
|
*/
|
572
573
|
function getHostConfig(callback) {
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
574
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
575
|
+
|
576
|
+
if (!(host && this.id)) {
|
577
|
+
return Promise.resolve({});
|
578
|
+
}
|
579
|
+
|
580
|
+
if (!host || !isFunction(host?.getConfig)) {
|
581
|
+
throw new TypeError("the host must be a monster-host");
|
582
|
+
}
|
583
|
+
|
584
|
+
const configKey = callback.call(this);
|
585
|
+
return host.hasConfig(configKey).then((hasConfig) => {
|
586
|
+
if (hasConfig) {
|
587
|
+
return host.getConfig(configKey);
|
588
|
+
} else {
|
589
|
+
return {};
|
590
|
+
}
|
591
|
+
});
|
591
592
|
}
|
592
593
|
|
593
594
|
/**
|
594
595
|
* @private
|
595
596
|
*/
|
596
597
|
function updateColumnBar() {
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
598
|
+
if (!this[columnBarElementSymbol]) {
|
599
|
+
return;
|
600
|
+
}
|
601
|
+
|
602
|
+
const columns = [];
|
603
|
+
for (const header of this.getOption("headers")) {
|
604
|
+
const mode = header.getInternal("mode");
|
605
|
+
|
606
|
+
if (mode === ATTRIBUTE_DATATABLE_MODE_FIXED) {
|
607
|
+
continue;
|
608
|
+
}
|
609
|
+
|
610
|
+
columns.push({
|
611
|
+
visible: mode !== ATTRIBUTE_DATATABLE_MODE_HIDDEN,
|
612
|
+
name: header.label,
|
613
|
+
index: header.index,
|
614
|
+
});
|
615
|
+
}
|
616
|
+
|
617
|
+
this[columnBarElementSymbol].setOption("columns", columns);
|
617
618
|
}
|
618
619
|
|
619
620
|
/**
|
620
621
|
* @private
|
621
622
|
*/
|
622
623
|
function updateHeaderFromColumnBar() {
|
623
|
-
|
624
|
-
|
625
|
-
|
624
|
+
if (!this[columnBarElementSymbol]) {
|
625
|
+
return;
|
626
|
+
}
|
626
627
|
|
627
|
-
|
628
|
-
|
628
|
+
const options = this[columnBarElementSymbol].getOption("columns");
|
629
|
+
if (!isArray(options)) return;
|
629
630
|
|
630
|
-
|
631
|
+
const invisibleMap = {};
|
631
632
|
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
633
|
+
for (let i = 0; i < options.length; i++) {
|
634
|
+
const option = options[i];
|
635
|
+
invisibleMap[option.index] = option.visible;
|
636
|
+
}
|
636
637
|
|
637
|
-
|
638
|
-
|
638
|
+
for (const header of this.getOption("headers")) {
|
639
|
+
const mode = header.getInternal("mode");
|
639
640
|
|
640
|
-
|
641
|
-
|
642
|
-
|
641
|
+
if (mode === ATTRIBUTE_DATATABLE_MODE_FIXED) {
|
642
|
+
continue;
|
643
|
+
}
|
643
644
|
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
645
|
+
if (invisibleMap[header.index] === false) {
|
646
|
+
header.setInternal("mode", ATTRIBUTE_DATATABLE_MODE_HIDDEN);
|
647
|
+
} else {
|
648
|
+
header.setInternal("mode", ATTRIBUTE_DATATABLE_MODE_VISIBLE);
|
649
|
+
}
|
650
|
+
}
|
650
651
|
}
|
651
652
|
|
652
653
|
/**
|
653
654
|
* @private
|
654
655
|
*/
|
655
656
|
function updateConfigColumnBar() {
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
657
|
+
if (!this[columnBarElementSymbol]) {
|
658
|
+
return;
|
659
|
+
}
|
660
|
+
|
661
|
+
const options = this[columnBarElementSymbol].getOption("columns");
|
662
|
+
if (!isArray(options)) return;
|
663
|
+
|
664
|
+
const map = {};
|
665
|
+
for (let i = 0; i < options.length; i++) {
|
666
|
+
const option = options[i];
|
667
|
+
map[option.name] = option.visible;
|
668
|
+
}
|
669
|
+
|
670
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
671
|
+
if (!(host && this.id)) {
|
672
|
+
return;
|
673
|
+
}
|
674
|
+
const configKey = getColumnVisibilityConfigKey.call(this);
|
675
|
+
|
676
|
+
try {
|
677
|
+
host.setConfig(configKey, map);
|
678
|
+
} catch (error) {
|
679
|
+
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, String(error));
|
680
|
+
}
|
680
681
|
}
|
681
682
|
|
682
683
|
/**
|
683
684
|
* @private
|
684
685
|
*/
|
685
686
|
function initEventHandler() {
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
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
|
-
|
687
|
+
const self = this;
|
688
|
+
|
689
|
+
const quoteOpenChar = this.getOption("copy.quoteOpen");
|
690
|
+
const quoteCloseChar = this.getOption("copy.quoteClose");
|
691
|
+
const delimiterChar = this.getOption("copy.delimiter");
|
692
|
+
const rowBreak = this.getOption("copy.rowBreak");
|
693
|
+
|
694
|
+
self[columnBarElementSymbol].attachObserver(
|
695
|
+
new Observer((e) => {
|
696
|
+
updateHeaderFromColumnBar.call(self);
|
697
|
+
updateGrid.call(self);
|
698
|
+
updateConfigColumnBar.call(self);
|
699
|
+
}),
|
700
|
+
);
|
701
|
+
|
702
|
+
self[gridHeadersElementSymbol].addEventListener("click", function (event) {
|
703
|
+
let element = null;
|
704
|
+
const datasource = self[datasourceLinkedElementSymbol];
|
705
|
+
if (!datasource) {
|
706
|
+
return;
|
707
|
+
}
|
708
|
+
|
709
|
+
element = findTargetElementFromEvent(event, ATTRIBUTE_DATATABLE_SORTABLE);
|
710
|
+
if (element) {
|
711
|
+
const index = element.parentNode.getAttribute(ATTRIBUTE_DATATABLE_INDEX);
|
712
|
+
const headers = self.getOption("headers");
|
713
|
+
|
714
|
+
event.preventDefault();
|
715
|
+
|
716
|
+
headers[index].changeDirection();
|
717
|
+
|
718
|
+
queueMicrotask(function () {
|
719
|
+
/** hotfix, normally this should be done via the updater, no idea why this is not possible. */
|
720
|
+
element.setAttribute(
|
721
|
+
ATTRIBUTE_DATATABLE_SORTABLE,
|
722
|
+
`${headers[index].field} ${headers[index].direction}`,
|
723
|
+
);
|
724
|
+
|
725
|
+
storeOrderStatement.call(self, true);
|
726
|
+
});
|
727
|
+
}
|
728
|
+
});
|
729
|
+
|
730
|
+
const eventHandlerDoubleClickCopyToClipboard = (event) => {
|
731
|
+
const element = findTargetElementFromEvent(event, "data-monster-head");
|
732
|
+
if (element) {
|
733
|
+
let text = "";
|
734
|
+
|
735
|
+
if (event.shiftKey) {
|
736
|
+
const index = element.getAttribute("data-monster-insert-reference");
|
737
|
+
if (index) {
|
738
|
+
const cols = self.getGridElements(
|
739
|
+
`[data-monster-insert-reference="${index}"]`,
|
740
|
+
);
|
741
|
+
|
742
|
+
const colTexts = [];
|
743
|
+
for (let i = 0; i < cols.length; i++) {
|
744
|
+
const col = cols[i];
|
745
|
+
|
746
|
+
if (
|
747
|
+
col.querySelector("monster-button-bar") ||
|
748
|
+
col.querySelector("monster-button")
|
749
|
+
) {
|
750
|
+
continue;
|
751
|
+
}
|
752
|
+
|
753
|
+
if (col.textContent) {
|
754
|
+
colTexts.push(
|
755
|
+
quoteOpenChar + col.textContent.trim() + quoteCloseChar,
|
756
|
+
);
|
757
|
+
}
|
758
|
+
}
|
759
|
+
|
760
|
+
text = colTexts.join(delimiterChar);
|
761
|
+
}
|
762
|
+
} else {
|
763
|
+
if (
|
764
|
+
element.querySelector("monster-button-bar") ||
|
765
|
+
element.querySelector("monster-button")
|
766
|
+
) {
|
767
|
+
return;
|
768
|
+
}
|
769
|
+
|
770
|
+
text = element.textContent.trim();
|
771
|
+
}
|
772
|
+
|
773
|
+
if (getWindow().navigator.clipboard && text) {
|
774
|
+
getWindow()
|
775
|
+
.navigator.clipboard.writeText(text)
|
776
|
+
.then(
|
777
|
+
() => {},
|
778
|
+
(err) => {},
|
779
|
+
);
|
780
|
+
}
|
781
|
+
}
|
782
|
+
};
|
783
|
+
|
784
|
+
if (self.getOption("features.doubleClickCopyToClipboard")) {
|
785
|
+
self[gridElementSymbol].addEventListener(
|
786
|
+
"dblclick",
|
787
|
+
eventHandlerDoubleClickCopyToClipboard,
|
788
|
+
);
|
789
|
+
}
|
790
|
+
|
791
|
+
if (self.getOption("features.copyAll") && this[copyAllElementSymbol]) {
|
792
|
+
this[copyAllElementSymbol].addEventListener("click", (event) => {
|
793
|
+
event.preventDefault();
|
794
|
+
|
795
|
+
const table = [];
|
796
|
+
let currentRow = [];
|
797
|
+
let currentIndex = null;
|
798
|
+
|
799
|
+
const cols = self.getGridElements(`[data-monster-insert-reference]`);
|
800
|
+
const rowIndexes = new Map();
|
801
|
+
cols.forEach((col) => {
|
802
|
+
const index = col.getAttribute("data-monster-insert-reference");
|
803
|
+
rowIndexes.set(index, true);
|
804
|
+
});
|
805
|
+
|
806
|
+
rowIndexes.forEach((value, key) => {
|
807
|
+
const cols = self.getGridElements(
|
808
|
+
`[data-monster-insert-reference="${key}"]`,
|
809
|
+
);
|
810
|
+
|
811
|
+
for (let i = 0; i < cols.length; i++) {
|
812
|
+
const col = cols[i];
|
813
|
+
|
814
|
+
if (
|
815
|
+
col.querySelector("monster-button-bar") ||
|
816
|
+
col.querySelector("monster-button")
|
817
|
+
) {
|
818
|
+
continue;
|
819
|
+
}
|
820
|
+
|
821
|
+
if (col.textContent) {
|
822
|
+
currentRow.push(
|
823
|
+
quoteOpenChar + col.textContent.trim() + quoteCloseChar,
|
824
|
+
);
|
825
|
+
}
|
826
|
+
}
|
827
|
+
|
828
|
+
if (currentRow.length > 0) {
|
829
|
+
table.push(currentRow);
|
830
|
+
}
|
831
|
+
currentRow = [];
|
832
|
+
});
|
833
|
+
|
834
|
+
if (table.length > 0) {
|
835
|
+
const text = table.map((row) => row.join(delimiterChar)).join(rowBreak);
|
836
|
+
if (getWindow().navigator.clipboard && text) {
|
837
|
+
getWindow()
|
838
|
+
.navigator.clipboard.writeText(text)
|
839
|
+
.then(
|
840
|
+
() => {},
|
841
|
+
(err) => {},
|
842
|
+
);
|
843
|
+
}
|
844
|
+
}
|
845
|
+
});
|
846
|
+
}
|
839
847
|
}
|
840
848
|
|
841
849
|
/**
|
842
850
|
* @private
|
843
851
|
*/
|
844
852
|
function initGridAndStructs(hostConfig, headerOrderMap) {
|
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
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
853
|
+
const rowID = this.getOption("templateMapping.row-key");
|
854
|
+
|
855
|
+
if (!this[gridElementSymbol]) {
|
856
|
+
throw new Error("no grid element is defined");
|
857
|
+
}
|
858
|
+
|
859
|
+
let template;
|
860
|
+
getSlottedElements.call(this).forEach((e) => {
|
861
|
+
if (e instanceof HTMLTemplateElement && e.id === rowID) {
|
862
|
+
template = e;
|
863
|
+
}
|
864
|
+
});
|
865
|
+
|
866
|
+
if (!template) {
|
867
|
+
throw new Error("no template is defined");
|
868
|
+
}
|
869
|
+
|
870
|
+
const rowCount = template.content.children.length;
|
871
|
+
|
872
|
+
const headers = [];
|
873
|
+
|
874
|
+
for (let i = 0; i < rowCount; i++) {
|
875
|
+
let hClass = "";
|
876
|
+
const row = template.content.children[i];
|
877
|
+
|
878
|
+
let mode = "";
|
879
|
+
if (row.hasAttribute(ATTRIBUTE_DATATABLE_MODE)) {
|
880
|
+
mode = row.getAttribute(ATTRIBUTE_DATATABLE_MODE);
|
881
|
+
}
|
882
|
+
|
883
|
+
let grid = row.getAttribute(ATTRIBUTE_DATATABLE_GRID_TEMPLATE);
|
884
|
+
if (!grid || grid === "" || grid === "auto") {
|
885
|
+
grid = "minmax(0, 1fr)";
|
886
|
+
}
|
887
|
+
|
888
|
+
let label = "";
|
889
|
+
let labelKey = "";
|
890
|
+
|
891
|
+
if (row.hasAttribute(ATTRIBUTE_DATATABLE_HEAD)) {
|
892
|
+
label = row.getAttribute(ATTRIBUTE_DATATABLE_HEAD);
|
893
|
+
labelKey = label;
|
894
|
+
|
895
|
+
try {
|
896
|
+
if (label.startsWith("i18n:")) {
|
897
|
+
label = label.substring(5, label.length);
|
898
|
+
label = getDocumentTranslations().getText(label, label);
|
899
|
+
}
|
900
|
+
} catch (e) {
|
901
|
+
label = "i18n error " + label;
|
902
|
+
}
|
903
|
+
}
|
904
|
+
|
905
|
+
if (!label) {
|
906
|
+
label = i + 1 + "";
|
907
|
+
mode = ATTRIBUTE_DATATABLE_MODE_FIXED;
|
908
|
+
labelKey = label;
|
909
|
+
}
|
910
|
+
|
911
|
+
if (isObject(hostConfig) && hostConfig.hasOwnProperty(label)) {
|
912
|
+
if (hostConfig[label] === false) {
|
913
|
+
mode = ATTRIBUTE_DATATABLE_MODE_HIDDEN;
|
914
|
+
} else {
|
915
|
+
mode = ATTRIBUTE_DATATABLE_MODE_VISIBLE;
|
916
|
+
}
|
917
|
+
}
|
918
|
+
|
919
|
+
let align = "";
|
920
|
+
if (row.hasAttribute(ATTRIBUTE_DATATABLE_ALIGN)) {
|
921
|
+
align = row.getAttribute(ATTRIBUTE_DATATABLE_ALIGN);
|
922
|
+
}
|
923
|
+
|
924
|
+
switch (align) {
|
925
|
+
case "center":
|
926
|
+
hClass = "flex-center";
|
927
|
+
break;
|
928
|
+
case "end":
|
929
|
+
hClass = "flex-end";
|
930
|
+
break;
|
931
|
+
case "start":
|
932
|
+
hClass = "flex-start";
|
933
|
+
break;
|
934
|
+
default:
|
935
|
+
hClass = "flex-start";
|
936
|
+
}
|
937
|
+
|
938
|
+
let field = "";
|
939
|
+
let direction = DIRECTION_NONE;
|
940
|
+
if (row.hasAttribute(ATTRIBUTE_DATATABLE_SORTABLE)) {
|
941
|
+
field = row.getAttribute(ATTRIBUTE_DATATABLE_SORTABLE).trim();
|
942
|
+
const parts = field.split(" ").map((item) => item.trim());
|
943
|
+
field = parts[0];
|
944
|
+
|
945
|
+
if (headerOrderMap.has(field)) {
|
946
|
+
direction = headerOrderMap.get(field);
|
947
|
+
} else if (
|
948
|
+
parts.length === 2 &&
|
949
|
+
[DIRECTION_ASC, DIRECTION_DESC].indexOf(parts[1]) !== -1
|
950
|
+
) {
|
951
|
+
direction = parts[1];
|
952
|
+
}
|
953
|
+
}
|
954
|
+
|
955
|
+
if (mode === ATTRIBUTE_DATATABLE_MODE_HIDDEN) {
|
956
|
+
hClass += " hidden";
|
957
|
+
}
|
958
|
+
|
959
|
+
const header = new Header();
|
960
|
+
header.setInternals({
|
961
|
+
field: field,
|
962
|
+
label: label,
|
963
|
+
classes: hClass,
|
964
|
+
index: i,
|
965
|
+
mode: mode,
|
966
|
+
grid: grid,
|
967
|
+
labelKey: labelKey,
|
968
|
+
direction: direction,
|
969
|
+
});
|
970
|
+
|
971
|
+
headers.push(header);
|
972
|
+
}
|
973
|
+
|
974
|
+
this.setOption("headers", headers);
|
975
|
+
queueMicrotask(() => {
|
976
|
+
storeOrderStatement.call(this, this.getOption("features.autoInit"));
|
977
|
+
});
|
970
978
|
}
|
971
979
|
|
972
980
|
/**
|
@@ -974,79 +982,79 @@ function initGridAndStructs(hostConfig, headerOrderMap) {
|
|
974
982
|
* @return {string}
|
975
983
|
*/
|
976
984
|
export function getStoredOrderConfigKey() {
|
977
|
-
|
985
|
+
return generateUniqueConfigKey("datatable", this?.id, "stored-order");
|
978
986
|
}
|
979
987
|
|
980
988
|
/**
|
981
989
|
* @private
|
982
990
|
*/
|
983
991
|
function storeOrderStatement(doFetch) {
|
984
|
-
|
985
|
-
|
986
|
-
|
992
|
+
const headers = this.getOption("headers");
|
993
|
+
const statement = createOrderStatement(headers);
|
994
|
+
setDataSource.call(this, { orderBy: statement }, doFetch);
|
987
995
|
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
996
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
997
|
+
if (!(host && this.id)) {
|
998
|
+
return;
|
999
|
+
}
|
992
1000
|
|
993
|
-
|
1001
|
+
const configKey = getStoredOrderConfigKey.call(this);
|
994
1002
|
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1003
|
+
// statement explode with , and remove all empty
|
1004
|
+
const list = statement.split(",").filter((item) => item.trim() !== "");
|
1005
|
+
if (list.length === 0) {
|
1006
|
+
return;
|
1007
|
+
}
|
1000
1008
|
|
1001
|
-
|
1009
|
+
host.setConfig(configKey, list);
|
1002
1010
|
}
|
1003
1011
|
|
1004
1012
|
/**
|
1005
1013
|
* @private
|
1006
1014
|
*/
|
1007
1015
|
function updateGrid() {
|
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
|
-
|
1016
|
+
if (!this[gridElementSymbol]) {
|
1017
|
+
throw new Error("no grid element is defined");
|
1018
|
+
}
|
1019
|
+
|
1020
|
+
let gridTemplateColumns = "";
|
1021
|
+
|
1022
|
+
const headers = this.getOption("headers");
|
1023
|
+
|
1024
|
+
let styles = "";
|
1025
|
+
|
1026
|
+
for (let i = 0; i < headers.length; i++) {
|
1027
|
+
const header = headers[i];
|
1028
|
+
|
1029
|
+
if (header.mode === ATTRIBUTE_DATATABLE_MODE_HIDDEN) {
|
1030
|
+
styles += `[data-monster-role=datatable]>[data-monster-head="${header.labelKey}"] { display: none; }\n`;
|
1031
|
+
styles += `[data-monster-role=datatable-headers]>[data-monster-index="${header.index}"] { display: none; }\n`;
|
1032
|
+
} else {
|
1033
|
+
gridTemplateColumns += `${header.grid} `;
|
1034
|
+
}
|
1035
|
+
}
|
1036
|
+
|
1037
|
+
const sheet = new CSSStyleSheet();
|
1038
|
+
if (styles !== "") sheet.replaceSync(styles);
|
1039
|
+
this.shadowRoot.adoptedStyleSheets = [...DataTable.getCSSStyleSheet(), sheet];
|
1040
|
+
|
1041
|
+
const bodyWidth = this.parentNode.clientWidth;
|
1042
|
+
|
1043
|
+
const breakpoint = this.getOption("responsive.breakpoint");
|
1044
|
+
this[dataControlElementSymbol].classList.toggle(
|
1045
|
+
"small",
|
1046
|
+
bodyWidth <= breakpoint,
|
1047
|
+
);
|
1048
|
+
|
1049
|
+
if (bodyWidth > breakpoint) {
|
1050
|
+
this[gridElementSymbol].style.gridTemplateColumns =
|
1051
|
+
`${gridTemplateColumns}`;
|
1052
|
+
this[gridHeadersElementSymbol].style.gridTemplateColumns =
|
1053
|
+
`${gridTemplateColumns}`;
|
1054
|
+
} else {
|
1055
|
+
this[gridElementSymbol].style.gridTemplateColumns = "auto";
|
1056
|
+
this[gridHeadersElementSymbol].style.gridTemplateColumns = "auto";
|
1057
|
+
}
|
1050
1058
|
}
|
1051
1059
|
|
1052
1060
|
/**
|
@@ -1054,20 +1062,20 @@ function updateGrid() {
|
|
1054
1062
|
* @param {Header[]} headers
|
1055
1063
|
* @param {bool} doFetch
|
1056
1064
|
*/
|
1057
|
-
function setDataSource({orderBy}, doFetch) {
|
1058
|
-
|
1065
|
+
function setDataSource({ orderBy }, doFetch) {
|
1066
|
+
const datasource = this[datasourceLinkedElementSymbol];
|
1059
1067
|
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1068
|
+
if (!datasource) {
|
1069
|
+
return;
|
1070
|
+
}
|
1063
1071
|
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1072
|
+
if (isFunction(datasource?.setParameters)) {
|
1073
|
+
datasource.setParameters({ orderBy });
|
1074
|
+
}
|
1067
1075
|
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1076
|
+
if (doFetch !== false && isFunction(datasource?.fetch)) {
|
1077
|
+
datasource.fetch();
|
1078
|
+
}
|
1071
1079
|
}
|
1072
1080
|
|
1073
1081
|
/**
|
@@ -1075,28 +1083,28 @@ function setDataSource({orderBy}, doFetch) {
|
|
1075
1083
|
* @return {DataTable}
|
1076
1084
|
*/
|
1077
1085
|
function initControlReferences() {
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1086
|
+
if (!this.shadowRoot) {
|
1087
|
+
throw new Error("no shadow-root is defined");
|
1088
|
+
}
|
1089
|
+
|
1090
|
+
this[dataControlElementSymbol] = this.shadowRoot.querySelector(
|
1091
|
+
"[data-monster-role=control]",
|
1092
|
+
);
|
1093
|
+
|
1094
|
+
this[gridElementSymbol] = this.shadowRoot.querySelector(
|
1095
|
+
"[data-monster-role=datatable]",
|
1096
|
+
);
|
1097
|
+
this[gridHeadersElementSymbol] = this.shadowRoot.querySelector(
|
1098
|
+
"[data-monster-role=datatable-headers]",
|
1099
|
+
);
|
1100
|
+
this[columnBarElementSymbol] =
|
1101
|
+
this.shadowRoot.querySelector("monster-column-bar");
|
1102
|
+
|
1103
|
+
this[copyAllElementSymbol] = this.shadowRoot.querySelector(
|
1104
|
+
"[data-monster-role=copy-all]",
|
1105
|
+
);
|
1106
|
+
|
1107
|
+
return this;
|
1100
1108
|
}
|
1101
1109
|
|
1102
1110
|
/**
|
@@ -1106,22 +1114,22 @@ function initControlReferences() {
|
|
1106
1114
|
* @throws {Error} the datasource could not be initialized
|
1107
1115
|
*/
|
1108
1116
|
function initOptionsFromArguments() {
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1117
|
+
const options = {};
|
1118
|
+
const selector = this.getAttribute(ATTRIBUTE_DATASOURCE_SELECTOR);
|
1119
|
+
|
1120
|
+
if (selector) {
|
1121
|
+
options.datasource = { selector: selector };
|
1122
|
+
}
|
1123
|
+
|
1124
|
+
const breakpoint = this.getAttribute(
|
1125
|
+
ATTRIBUTE_DATATABLE_RESPONSIVE_BREAKPOINT,
|
1126
|
+
);
|
1127
|
+
if (breakpoint) {
|
1128
|
+
options.responsive = {};
|
1129
|
+
options.responsive.breakpoint = parseInt(breakpoint);
|
1130
|
+
}
|
1131
|
+
|
1132
|
+
return options;
|
1125
1133
|
}
|
1126
1134
|
|
1127
1135
|
/**
|
@@ -1129,7 +1137,7 @@ function initOptionsFromArguments() {
|
|
1129
1137
|
* @return {string}
|
1130
1138
|
*/
|
1131
1139
|
function getEmptyTemplate() {
|
1132
|
-
|
1140
|
+
return `<monster-state data-monster-role="empty-without-action">
|
1133
1141
|
<div part="visual">
|
1134
1142
|
<svg width="4rem" height="4rem" fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
1135
1143
|
<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"/>
|
@@ -1147,8 +1155,8 @@ function getEmptyTemplate() {
|
|
1147
1155
|
* @return {string}
|
1148
1156
|
*/
|
1149
1157
|
function getTemplate() {
|
1150
|
-
|
1151
|
-
|
1158
|
+
// language=HTML
|
1159
|
+
return `
|
1152
1160
|
<div data-monster-role="control" part="control" data-monster-attributes="class path:classes.control">
|
1153
1161
|
<template id="headers-row">
|
1154
1162
|
<div data-monster-attributes="class path:headers-row.classes,
|