@schukai/monster 3.87.1 → 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 +70 -43
- package/package.json +1 -1
- package/source/components/content/stylesheet/copy.mjs +1 -1
- package/source/components/datatable/datatable.mjs +928 -909
- 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,75 +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
|
+
|
85
|
+
export { DataTable };
|
84
86
|
|
85
87
|
/**
|
86
88
|
* @private
|
@@ -148,398 +150,404 @@ const resizeObserverSymbol = Symbol("resizeObserver");
|
|
148
150
|
* @fires monster-datatable-row-added
|
149
151
|
**/
|
150
152
|
class DataTable extends CustomElement {
|
151
|
-
|
152
|
-
|
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
|
-
|
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
|
+
}
|
543
551
|
}
|
544
552
|
|
545
553
|
/**
|
@@ -547,7 +555,7 @@ class DataTable extends CustomElement {
|
|
547
555
|
* @return {string}
|
548
556
|
*/
|
549
557
|
function getColumnVisibilityConfigKey() {
|
550
|
-
|
558
|
+
return generateUniqueConfigKey("datatable", this?.id, "columns-visibility");
|
551
559
|
}
|
552
560
|
|
553
561
|
/**
|
@@ -555,7 +563,7 @@ function getColumnVisibilityConfigKey() {
|
|
555
563
|
* @return {string}
|
556
564
|
*/
|
557
565
|
function getFilterConfigKey() {
|
558
|
-
|
566
|
+
return generateUniqueConfigKey("datatable", this?.id, "filter");
|
559
567
|
}
|
560
568
|
|
561
569
|
/**
|
@@ -563,403 +571,410 @@ function getFilterConfigKey() {
|
|
563
571
|
* @return {Promise}
|
564
572
|
*/
|
565
573
|
function getHostConfig(callback) {
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
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
|
+
});
|
584
592
|
}
|
585
593
|
|
586
594
|
/**
|
587
595
|
* @private
|
588
596
|
*/
|
589
597
|
function updateColumnBar() {
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
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);
|
610
618
|
}
|
611
619
|
|
612
620
|
/**
|
613
621
|
* @private
|
614
622
|
*/
|
615
623
|
function updateHeaderFromColumnBar() {
|
616
|
-
|
617
|
-
|
618
|
-
|
624
|
+
if (!this[columnBarElementSymbol]) {
|
625
|
+
return;
|
626
|
+
}
|
619
627
|
|
620
|
-
|
621
|
-
|
628
|
+
const options = this[columnBarElementSymbol].getOption("columns");
|
629
|
+
if (!isArray(options)) return;
|
622
630
|
|
623
|
-
|
631
|
+
const invisibleMap = {};
|
624
632
|
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
633
|
+
for (let i = 0; i < options.length; i++) {
|
634
|
+
const option = options[i];
|
635
|
+
invisibleMap[option.index] = option.visible;
|
636
|
+
}
|
629
637
|
|
630
|
-
|
631
|
-
|
638
|
+
for (const header of this.getOption("headers")) {
|
639
|
+
const mode = header.getInternal("mode");
|
632
640
|
|
633
|
-
|
634
|
-
|
635
|
-
|
641
|
+
if (mode === ATTRIBUTE_DATATABLE_MODE_FIXED) {
|
642
|
+
continue;
|
643
|
+
}
|
636
644
|
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
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
|
+
}
|
643
651
|
}
|
644
652
|
|
645
653
|
/**
|
646
654
|
* @private
|
647
655
|
*/
|
648
656
|
function updateConfigColumnBar() {
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
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
|
+
}
|
673
681
|
}
|
674
682
|
|
675
683
|
/**
|
676
684
|
* @private
|
677
685
|
*/
|
678
686
|
function initEventHandler() {
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
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
|
-
|
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
|
+
}
|
832
847
|
}
|
833
848
|
|
834
849
|
/**
|
835
850
|
* @private
|
836
851
|
*/
|
837
852
|
function initGridAndStructs(hostConfig, headerOrderMap) {
|
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
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
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
|
+
});
|
963
978
|
}
|
964
979
|
|
965
980
|
/**
|
@@ -967,79 +982,79 @@ function initGridAndStructs(hostConfig, headerOrderMap) {
|
|
967
982
|
* @return {string}
|
968
983
|
*/
|
969
984
|
export function getStoredOrderConfigKey() {
|
970
|
-
|
985
|
+
return generateUniqueConfigKey("datatable", this?.id, "stored-order");
|
971
986
|
}
|
972
987
|
|
973
988
|
/**
|
974
989
|
* @private
|
975
990
|
*/
|
976
991
|
function storeOrderStatement(doFetch) {
|
977
|
-
|
978
|
-
|
979
|
-
|
992
|
+
const headers = this.getOption("headers");
|
993
|
+
const statement = createOrderStatement(headers);
|
994
|
+
setDataSource.call(this, { orderBy: statement }, doFetch);
|
980
995
|
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
996
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
997
|
+
if (!(host && this.id)) {
|
998
|
+
return;
|
999
|
+
}
|
985
1000
|
|
986
|
-
|
1001
|
+
const configKey = getStoredOrderConfigKey.call(this);
|
987
1002
|
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
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
|
+
}
|
993
1008
|
|
994
|
-
|
1009
|
+
host.setConfig(configKey, list);
|
995
1010
|
}
|
996
1011
|
|
997
1012
|
/**
|
998
1013
|
* @private
|
999
1014
|
*/
|
1000
1015
|
function updateGrid() {
|
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
|
-
|
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
|
+
}
|
1043
1058
|
}
|
1044
1059
|
|
1045
1060
|
/**
|
@@ -1047,20 +1062,20 @@ function updateGrid() {
|
|
1047
1062
|
* @param {Header[]} headers
|
1048
1063
|
* @param {bool} doFetch
|
1049
1064
|
*/
|
1050
|
-
function setDataSource({orderBy}, doFetch) {
|
1051
|
-
|
1065
|
+
function setDataSource({ orderBy }, doFetch) {
|
1066
|
+
const datasource = this[datasourceLinkedElementSymbol];
|
1052
1067
|
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1068
|
+
if (!datasource) {
|
1069
|
+
return;
|
1070
|
+
}
|
1056
1071
|
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1072
|
+
if (isFunction(datasource?.setParameters)) {
|
1073
|
+
datasource.setParameters({ orderBy });
|
1074
|
+
}
|
1060
1075
|
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1076
|
+
if (doFetch !== false && isFunction(datasource?.fetch)) {
|
1077
|
+
datasource.fetch();
|
1078
|
+
}
|
1064
1079
|
}
|
1065
1080
|
|
1066
1081
|
/**
|
@@ -1068,28 +1083,28 @@ function setDataSource({orderBy}, doFetch) {
|
|
1068
1083
|
* @return {DataTable}
|
1069
1084
|
*/
|
1070
1085
|
function initControlReferences() {
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
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;
|
1093
1108
|
}
|
1094
1109
|
|
1095
1110
|
/**
|
@@ -1099,22 +1114,22 @@ function initControlReferences() {
|
|
1099
1114
|
* @throws {Error} the datasource could not be initialized
|
1100
1115
|
*/
|
1101
1116
|
function initOptionsFromArguments() {
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
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;
|
1118
1133
|
}
|
1119
1134
|
|
1120
1135
|
/**
|
@@ -1122,7 +1137,7 @@ function initOptionsFromArguments() {
|
|
1122
1137
|
* @return {string}
|
1123
1138
|
*/
|
1124
1139
|
function getEmptyTemplate() {
|
1125
|
-
|
1140
|
+
return `<monster-state data-monster-role="empty-without-action">
|
1126
1141
|
<div part="visual">
|
1127
1142
|
<svg width="4rem" height="4rem" fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
1128
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"/>
|
@@ -1140,8 +1155,8 @@ function getEmptyTemplate() {
|
|
1140
1155
|
* @return {string}
|
1141
1156
|
*/
|
1142
1157
|
function getTemplate() {
|
1143
|
-
|
1144
|
-
|
1158
|
+
// language=HTML
|
1159
|
+
return `
|
1145
1160
|
<div data-monster-role="control" part="control" data-monster-attributes="class path:classes.control">
|
1146
1161
|
<template id="headers-row">
|
1147
1162
|
<div data-monster-attributes="class path:headers-row.classes,
|
@@ -1155,6 +1170,10 @@ function getTemplate() {
|
|
1155
1170
|
<slot name="filter"></slot>
|
1156
1171
|
</div>
|
1157
1172
|
<div class="bar">
|
1173
|
+
<monster-context-help
|
1174
|
+
data-monster-attributes="class path:features.help | ?::hidden"
|
1175
|
+
data-monster-replace="path:labels.helpText"
|
1176
|
+
></monster-context-help>
|
1158
1177
|
<a href="#" data-monster-attributes="class path:features.copyAll | ?::hidden" data-monster-role="copy-all" data-monster-replace="path:locale.copyAll">Copy all</a>
|
1159
1178
|
<monster-column-bar
|
1160
1179
|
data-monster-attributes="class path:features.settings | ?::hidden"></monster-column-bar>
|