@schukai/monster 3.85.0 → 3.85.2
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 +19 -0
- package/package.json +1 -1
- package/source/components/content/copy.mjs +381 -317
- package/source/components/datatable/columnbar.mjs +15 -36
- package/source/components/datatable/datasource/dom.mjs +1 -0
- package/source/components/datatable/datatable.mjs +757 -765
- package/source/components/datatable/stylesheet/datatable.mjs +7 -14
- package/source/components/datatable/util.mjs +1 -0
- package/source/dom/ready.mjs +1 -1
- package/source/util/deadmansswitch.mjs +13 -1
|
@@ -12,75 +12,75 @@
|
|
|
12
12
|
* SPDX-License-Identifier: AGPL-3.0
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import {
|
|
15
|
+
import {Datasource} from "./datasource.mjs";
|
|
16
16
|
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
assembleMethodSymbol,
|
|
18
|
+
CustomElement,
|
|
19
|
+
registerCustomElement,
|
|
20
|
+
getSlottedElements,
|
|
21
21
|
} from "../../dom/customelement.mjs";
|
|
22
22
|
import {
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
findTargetElementFromEvent,
|
|
24
|
+
fireCustomEvent,
|
|
25
25
|
} from "../../dom/events.mjs";
|
|
26
|
-
import {
|
|
26
|
+
import {clone} from "../../util/clone.mjs";
|
|
27
27
|
import {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
isString,
|
|
29
|
+
isFunction,
|
|
30
|
+
isInstance,
|
|
31
|
+
isObject,
|
|
32
|
+
isArray,
|
|
33
33
|
} from "../../types/is.mjs";
|
|
34
34
|
import {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
validateArray,
|
|
36
|
+
validateInteger,
|
|
37
|
+
validateObject,
|
|
38
38
|
} from "../../types/validate.mjs";
|
|
39
|
-
import {
|
|
39
|
+
import {Observer} from "../../types/observer.mjs";
|
|
40
40
|
import {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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 {
|
|
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 {
|
|
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 {
|
|
74
|
-
import {
|
|
75
|
-
import {
|
|
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 {
|
|
78
|
+
import {generateUniqueConfigKey} from "../host/util.mjs";
|
|
79
79
|
|
|
80
80
|
import "./datasource/dom.mjs";
|
|
81
81
|
import "./datasource/rest.mjs";
|
|
82
82
|
|
|
83
|
-
export {
|
|
83
|
+
export {DataTable};
|
|
84
84
|
|
|
85
85
|
/**
|
|
86
86
|
* @private
|
|
@@ -103,394 +103,386 @@ const columnBarElementSymbol = Symbol("columnBarElement");
|
|
|
103
103
|
/**
|
|
104
104
|
* The DataTable component is used to show the data from a data source.
|
|
105
105
|
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
*
|
|
113
|
-
* ```html
|
|
114
|
-
* <monster-datatable></monster-datatable>
|
|
115
|
-
* ```
|
|
116
|
-
*
|
|
117
|
-
* Or you can create this CustomControl directly in Javascript:
|
|
118
|
-
*
|
|
119
|
-
* ```js
|
|
120
|
-
* import '@schukai/component-datatable/source/datatable.mjs';
|
|
121
|
-
* document.createElement('monster-datatable');
|
|
122
|
-
* ```
|
|
123
|
-
*
|
|
124
|
-
* The Body should have a class "hidden" to ensure that the styles are applied correctly.
|
|
106
|
+
* @copyright schukai GmbH
|
|
107
|
+
* @summary A data table
|
|
108
|
+
|
|
109
|
+
*/
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* A DataTable
|
|
125
113
|
*
|
|
126
|
-
*
|
|
127
|
-
* body.hidden {
|
|
128
|
-
* visibility: hidden;
|
|
129
|
-
* }
|
|
130
|
-
* ```
|
|
114
|
+
* @fragments /fragments/components/datatable/datatable/
|
|
131
115
|
*
|
|
132
|
-
* @
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
* @enduml
|
|
116
|
+
* @example /examples/components/datatable/empty
|
|
117
|
+
* @example /examples/components/datatable/data-using-javascript
|
|
118
|
+
* @example /examples/components/datatable/alignment
|
|
119
|
+
* @example /examples/components/datatable/row-mode
|
|
120
|
+
* @example /examples/components/datatable/grid-template
|
|
138
121
|
*
|
|
139
122
|
* @copyright schukai GmbH
|
|
140
|
-
* @summary A data table
|
|
123
|
+
* @summary A beautiful and highly customizable data table. It can be used to display data from a data source.
|
|
141
124
|
* @fires monster-datatable-row-copied
|
|
142
125
|
* @fires monster-datatable-row-removed
|
|
143
126
|
* @fires monster-datatable-row-added
|
|
144
|
-
|
|
127
|
+
**/
|
|
145
128
|
class DataTable extends CustomElement {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
-
|
|
129
|
+
/**
|
|
130
|
+
* This method is called by the `instanceof` operator.
|
|
131
|
+
* @return {symbol}
|
|
132
|
+
*/
|
|
133
|
+
static get [instanceSymbol]() {
|
|
134
|
+
return Symbol.for("@schukai/monster/components/datatable@@instance");
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* To set the options via the HTML tag, the attribute `data-monster-options` must be used.
|
|
139
|
+
* @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
|
|
140
|
+
*
|
|
141
|
+
* The individual configuration values can be found in the table.
|
|
142
|
+
*
|
|
143
|
+
* @property {Object} templates Template definitions
|
|
144
|
+
* @property {string} templates.main Main template
|
|
145
|
+
* @property {Object} datasource Datasource configuration
|
|
146
|
+
* @property {string} datasource.selector Selector for the datasource
|
|
147
|
+
* @property {Object} mapping Mapping configuration
|
|
148
|
+
* @property {string} mapping.data Data mapping
|
|
149
|
+
* @property {Array} data Data
|
|
150
|
+
* @property {Array} headers Headers
|
|
151
|
+
* @property {Object} responsive Responsive configuration
|
|
152
|
+
* @property {number} responsive.breakpoint Breakpoint for responsive mode
|
|
153
|
+
* @property {Object} labels Labels
|
|
154
|
+
* @property {string} labels.theListContainsNoEntries Label for empty state
|
|
155
|
+
* @property {Object} classes Classes
|
|
156
|
+
* @property {string} classes.container Container class
|
|
157
|
+
* @property {Object} features Features
|
|
158
|
+
* @property {boolean} features.settings Settings feature
|
|
159
|
+
* @property {boolean} features.footer Footer feature
|
|
160
|
+
* @property {boolean} features.autoInit Auto init feature (init datasource automatically)
|
|
161
|
+
* @property {Object} templateMapping Template mapping
|
|
162
|
+
* @property {string} templateMapping.row-key Row key
|
|
163
|
+
* @property {string} templateMapping.filter-id Filter id
|
|
164
|
+
**/
|
|
165
|
+
get defaults() {
|
|
166
|
+
return Object.assign(
|
|
167
|
+
{},
|
|
168
|
+
super.defaults,
|
|
169
|
+
{
|
|
170
|
+
templates: {
|
|
171
|
+
main: getTemplate(),
|
|
172
|
+
emptyState: getEmptyTemplate(),
|
|
173
|
+
},
|
|
174
|
+
|
|
175
|
+
datasource: {
|
|
176
|
+
selector: null,
|
|
177
|
+
},
|
|
178
|
+
|
|
179
|
+
mapping: {
|
|
180
|
+
data: "dataset",
|
|
181
|
+
},
|
|
182
|
+
|
|
183
|
+
data: [],
|
|
184
|
+
headers: [],
|
|
185
|
+
|
|
186
|
+
responsive: {
|
|
187
|
+
breakpoint: 800,
|
|
188
|
+
},
|
|
189
|
+
|
|
190
|
+
labels: {
|
|
191
|
+
theListContainsNoEntries: "The list contains no entries",
|
|
192
|
+
},
|
|
193
|
+
|
|
194
|
+
classes: {
|
|
195
|
+
control: "monster-theme-control-container-1",
|
|
196
|
+
container: "",
|
|
197
|
+
row: "monster-theme-control-row-1",
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
features: {
|
|
201
|
+
settings: true,
|
|
202
|
+
footer: true,
|
|
203
|
+
autoInit: true,
|
|
204
|
+
},
|
|
205
|
+
|
|
206
|
+
templateMapping: {
|
|
207
|
+
"row-key": null,
|
|
208
|
+
"filter-id": null,
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
initOptionsFromArguments.call(this),
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
*
|
|
217
|
+
* @param {string} selector
|
|
218
|
+
* @return {NodeListOf<*>}
|
|
219
|
+
*/
|
|
220
|
+
getGridElements(selector) {
|
|
221
|
+
return this[gridElementSymbol].querySelectorAll(selector);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
*
|
|
226
|
+
* @return {string}
|
|
227
|
+
*/
|
|
228
|
+
static getTag() {
|
|
229
|
+
return "monster-datatable";
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* @return void
|
|
234
|
+
*/
|
|
235
|
+
[assembleMethodSymbol]() {
|
|
236
|
+
const rawKey = this.getOption("templateMapping.row-key");
|
|
237
|
+
|
|
238
|
+
if (rawKey === null) {
|
|
239
|
+
if (this.id !== null && this.id !== "") {
|
|
240
|
+
const rawKey = this.getOption("templateMapping.row-key");
|
|
241
|
+
if (rawKey === null) {
|
|
242
|
+
this.setOption("templateMapping.row-key", this.id + "-row");
|
|
243
|
+
}
|
|
244
|
+
} else {
|
|
245
|
+
this.setOption("templateMapping.row-key", "row");
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (this.id !== null && this.id !== "") {
|
|
250
|
+
this.setOption("templateMapping.filter-id", "" + this.id + "-filter");
|
|
251
|
+
} else {
|
|
252
|
+
this.setOption("templateMapping.filter-id", "filter");
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
super[assembleMethodSymbol]();
|
|
256
|
+
|
|
257
|
+
initControlReferences.call(this);
|
|
258
|
+
initEventHandler.call(this);
|
|
259
|
+
|
|
260
|
+
const selector = this.getOption("datasource.selector");
|
|
261
|
+
|
|
262
|
+
if (isString(selector)) {
|
|
263
|
+
const element = findElementWithSelectorUpwards(this, selector);
|
|
264
|
+
if (element === null) {
|
|
265
|
+
throw new Error("the selector must match exactly one element");
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (!isInstance(element, Datasource)) {
|
|
269
|
+
throw new TypeError("the element must be a datasource");
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
this[datasourceLinkedElementSymbol] = element;
|
|
273
|
+
|
|
274
|
+
queueMicrotask(() => {
|
|
275
|
+
handleDataSourceChanges.call(this);
|
|
276
|
+
element.datasource.attachObserver(
|
|
277
|
+
new Observer(handleDataSourceChanges.bind(this)),
|
|
278
|
+
);
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
getHostConfig
|
|
283
|
+
.call(this, getColumnVisibilityConfigKey)
|
|
284
|
+
.then((config) => {
|
|
285
|
+
const headerOrderMap = new Map();
|
|
286
|
+
|
|
287
|
+
getHostConfig
|
|
288
|
+
.call(this, getStoredOrderConfigKey)
|
|
289
|
+
.then((orderConfig) => {
|
|
290
|
+
if (isArray(orderConfig) || orderConfig.length > 0) {
|
|
291
|
+
for (let i = 0; i < orderConfig.length; i++) {
|
|
292
|
+
const item = orderConfig[i];
|
|
293
|
+
const parts = item.split(" ");
|
|
294
|
+
const field = parts[0];
|
|
295
|
+
const direction = parts[1] || DIRECTION_ASC;
|
|
296
|
+
headerOrderMap.set(field, direction);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
})
|
|
300
|
+
.then(() => {
|
|
301
|
+
try {
|
|
302
|
+
initGridAndStructs.call(this, config, headerOrderMap);
|
|
303
|
+
} catch (error) {
|
|
304
|
+
addAttributeToken(
|
|
305
|
+
this,
|
|
306
|
+
ATTRIBUTE_ERRORMESSAGE,
|
|
307
|
+
error?.message || error.toString(),
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
updateColumnBar.call(this);
|
|
312
|
+
})
|
|
313
|
+
.catch((error) => {
|
|
314
|
+
addAttributeToken(
|
|
315
|
+
this,
|
|
316
|
+
ATTRIBUTE_ERRORMESSAGE,
|
|
317
|
+
error?.message || error.toString(),
|
|
318
|
+
);
|
|
319
|
+
});
|
|
320
|
+
})
|
|
321
|
+
.catch((error) => {
|
|
322
|
+
addAttributeToken(
|
|
323
|
+
this,
|
|
324
|
+
ATTRIBUTE_ERRORMESSAGE,
|
|
325
|
+
error?.message || error.toString(),
|
|
326
|
+
);
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* @return {CSSStyleSheet[]}
|
|
332
|
+
*/
|
|
333
|
+
static getCSSStyleSheet() {
|
|
334
|
+
return [DatatableStyleSheet];
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Copy a row from the datatable
|
|
339
|
+
*
|
|
340
|
+
* @param {number|string} fromIndex
|
|
341
|
+
* @param {number|string} toIndex
|
|
342
|
+
* @return {DataTable}
|
|
343
|
+
* @fires monster-datatable-row-copied
|
|
344
|
+
*/
|
|
345
|
+
copyRow(fromIndex, toIndex) {
|
|
346
|
+
const datasource = this[datasourceLinkedElementSymbol];
|
|
347
|
+
if (!datasource) {
|
|
348
|
+
return this;
|
|
349
|
+
}
|
|
350
|
+
let d = datasource.data;
|
|
351
|
+
let c = clone(d);
|
|
352
|
+
|
|
353
|
+
let rows = c;
|
|
354
|
+
const mapping = this.getOption("mapping.data");
|
|
355
|
+
|
|
356
|
+
if (mapping) {
|
|
357
|
+
rows = c?.[mapping];
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
if (rows === undefined || rows === null) {
|
|
361
|
+
rows = [];
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
if (toIndex === undefined) {
|
|
365
|
+
toIndex = rows.length;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
if (isString(fromIndex)) {
|
|
369
|
+
fromIndex = parseInt(fromIndex);
|
|
370
|
+
}
|
|
371
|
+
if (isString(toIndex)) {
|
|
372
|
+
toIndex = parseInt(toIndex);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if (toIndex < 0 || toIndex > rows.length) {
|
|
376
|
+
throw new RangeError("index out of bounds");
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
validateArray(rows);
|
|
380
|
+
validateInteger(fromIndex);
|
|
381
|
+
validateInteger(toIndex);
|
|
382
|
+
|
|
383
|
+
if (fromIndex < 0 || fromIndex >= rows.length) {
|
|
384
|
+
throw new RangeError("index out of bounds");
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
rows.splice(toIndex, 0, clone(rows[fromIndex]));
|
|
388
|
+
datasource.data = c;
|
|
389
|
+
|
|
390
|
+
fireCustomEvent(this, "monster-datatable-row-copied", {
|
|
391
|
+
index: toIndex,
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
return this;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Remove a row from the datatable
|
|
399
|
+
*
|
|
400
|
+
* @param {number|string} index
|
|
401
|
+
* @return {DataTable}
|
|
402
|
+
* @fires monster-datatable-row-removed
|
|
403
|
+
*/
|
|
404
|
+
removeRow(index) {
|
|
405
|
+
const datasource = this[datasourceLinkedElementSymbol];
|
|
406
|
+
if (!datasource) {
|
|
407
|
+
return this;
|
|
408
|
+
}
|
|
409
|
+
let d = datasource.data;
|
|
410
|
+
let c = clone(d);
|
|
411
|
+
|
|
412
|
+
let rows = c;
|
|
413
|
+
const mapping = this.getOption("mapping.data");
|
|
414
|
+
|
|
415
|
+
if (mapping) {
|
|
416
|
+
rows = c?.[mapping];
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
if (rows === undefined || rows === null) {
|
|
420
|
+
rows = [];
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
if (isString(index)) {
|
|
424
|
+
index = parseInt(index);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
validateArray(rows);
|
|
428
|
+
validateInteger(index);
|
|
429
|
+
|
|
430
|
+
if (index < 0 || index >= rows.length) {
|
|
431
|
+
throw new RangeError("index out of bounds");
|
|
432
|
+
}
|
|
433
|
+
if (mapping) {
|
|
434
|
+
rows = c?.[mapping];
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
rows.splice(index, 1);
|
|
438
|
+
datasource.data = c;
|
|
439
|
+
|
|
440
|
+
fireCustomEvent(this, "monster-datatable-row-removed", {
|
|
441
|
+
index: index,
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
return this;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Add a row to the datatable
|
|
449
|
+
*
|
|
450
|
+
* @param {Object} data
|
|
451
|
+
* @return {DataTable}
|
|
452
|
+
*
|
|
453
|
+
* @fires monster-datatable-row-added
|
|
454
|
+
**/
|
|
455
|
+
addRow(data) {
|
|
456
|
+
const datasource = this[datasourceLinkedElementSymbol];
|
|
457
|
+
if (!datasource) {
|
|
458
|
+
return this;
|
|
459
|
+
}
|
|
460
|
+
let d = datasource.data;
|
|
461
|
+
let c = clone(d);
|
|
462
|
+
|
|
463
|
+
let rows = c;
|
|
464
|
+
|
|
465
|
+
const mapping = this.getOption("mapping.data");
|
|
466
|
+
if (mapping) {
|
|
467
|
+
rows = c?.[mapping];
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
if (rows === undefined || rows === null) {
|
|
471
|
+
rows = [];
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
validateArray(rows);
|
|
475
|
+
validateObject(data);
|
|
476
|
+
|
|
477
|
+
rows.push(data);
|
|
478
|
+
datasource.data = c;
|
|
479
|
+
|
|
480
|
+
fireCustomEvent(this, "monster-datatable-row-added", {
|
|
481
|
+
index: rows.length - 1,
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
return this;
|
|
485
|
+
}
|
|
494
486
|
}
|
|
495
487
|
|
|
496
488
|
/**
|
|
@@ -498,7 +490,7 @@ class DataTable extends CustomElement {
|
|
|
498
490
|
* @return {string}
|
|
499
491
|
*/
|
|
500
492
|
function getColumnVisibilityConfigKey() {
|
|
501
|
-
|
|
493
|
+
return generateUniqueConfigKey("datatable", this?.id, "columns-visibility");
|
|
502
494
|
}
|
|
503
495
|
|
|
504
496
|
/**
|
|
@@ -506,7 +498,7 @@ function getColumnVisibilityConfigKey() {
|
|
|
506
498
|
* @return {string}
|
|
507
499
|
*/
|
|
508
500
|
function getFilterConfigKey() {
|
|
509
|
-
|
|
501
|
+
return generateUniqueConfigKey("datatable", this?.id, "filter");
|
|
510
502
|
}
|
|
511
503
|
|
|
512
504
|
/**
|
|
@@ -514,291 +506,291 @@ function getFilterConfigKey() {
|
|
|
514
506
|
* @return {Promise}
|
|
515
507
|
*/
|
|
516
508
|
function getHostConfig(callback) {
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
509
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
|
510
|
+
|
|
511
|
+
if (!(host && this.id)) {
|
|
512
|
+
return Promise.resolve({});
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
if (!host || !isFunction(host?.getConfig)) {
|
|
516
|
+
throw new TypeError("the host must be a monster-host");
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
const configKey = callback.call(this);
|
|
520
|
+
return host.hasConfig(configKey).then((hasConfig) => {
|
|
521
|
+
if (hasConfig) {
|
|
522
|
+
return host.getConfig(configKey);
|
|
523
|
+
} else {
|
|
524
|
+
return {};
|
|
525
|
+
}
|
|
526
|
+
});
|
|
535
527
|
}
|
|
536
528
|
|
|
537
529
|
/**
|
|
538
530
|
* @private
|
|
539
531
|
*/
|
|
540
532
|
function updateColumnBar() {
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
533
|
+
if (!this[columnBarElementSymbol]) {
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
const columns = [];
|
|
538
|
+
for (const header of this.getOption("headers")) {
|
|
539
|
+
const mode = header.getInternal("mode");
|
|
540
|
+
|
|
541
|
+
if (mode === ATTRIBUTE_DATATABLE_MODE_FIXED) {
|
|
542
|
+
continue;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
columns.push({
|
|
546
|
+
visible: mode !== ATTRIBUTE_DATATABLE_MODE_HIDDEN,
|
|
547
|
+
name: header.label,
|
|
548
|
+
index: header.index,
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
this[columnBarElementSymbol].setOption("columns", columns);
|
|
561
553
|
}
|
|
562
554
|
|
|
563
555
|
/**
|
|
564
556
|
* @private
|
|
565
557
|
*/
|
|
566
558
|
function updateHeaderFromColumnBar() {
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
559
|
+
if (!this[columnBarElementSymbol]) {
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
570
562
|
|
|
571
|
-
|
|
572
|
-
|
|
563
|
+
const options = this[columnBarElementSymbol].getOption("columns");
|
|
564
|
+
if (!isArray(options)) return;
|
|
573
565
|
|
|
574
|
-
|
|
566
|
+
const invisibleMap = {};
|
|
575
567
|
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
568
|
+
for (let i = 0; i < options.length; i++) {
|
|
569
|
+
const option = options[i];
|
|
570
|
+
invisibleMap[option.index] = option.visible;
|
|
571
|
+
}
|
|
580
572
|
|
|
581
|
-
|
|
582
|
-
|
|
573
|
+
for (const header of this.getOption("headers")) {
|
|
574
|
+
const mode = header.getInternal("mode");
|
|
583
575
|
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
576
|
+
if (mode === ATTRIBUTE_DATATABLE_MODE_FIXED) {
|
|
577
|
+
continue;
|
|
578
|
+
}
|
|
587
579
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
580
|
+
if (invisibleMap[header.index] === false) {
|
|
581
|
+
header.setInternal("mode", ATTRIBUTE_DATATABLE_MODE_HIDDEN);
|
|
582
|
+
} else {
|
|
583
|
+
header.setInternal("mode", ATTRIBUTE_DATATABLE_MODE_VISIBLE);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
594
586
|
}
|
|
595
587
|
|
|
596
588
|
/**
|
|
597
589
|
* @private
|
|
598
590
|
*/
|
|
599
591
|
function updateConfigColumnBar() {
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
592
|
+
if (!this[columnBarElementSymbol]) {
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
const options = this[columnBarElementSymbol].getOption("columns");
|
|
597
|
+
if (!isArray(options)) return;
|
|
598
|
+
|
|
599
|
+
const map = {};
|
|
600
|
+
for (let i = 0; i < options.length; i++) {
|
|
601
|
+
const option = options[i];
|
|
602
|
+
map[option.name] = option.visible;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
|
606
|
+
if (!(host && this.id)) {
|
|
607
|
+
return;
|
|
608
|
+
}
|
|
609
|
+
const configKey = getColumnVisibilityConfigKey.call(this);
|
|
610
|
+
|
|
611
|
+
try {
|
|
612
|
+
host.setConfig(configKey, map);
|
|
613
|
+
} catch (error) {
|
|
614
|
+
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, String(error));
|
|
615
|
+
}
|
|
624
616
|
}
|
|
625
617
|
|
|
626
618
|
/**
|
|
627
619
|
* @private
|
|
628
620
|
*/
|
|
629
621
|
function initEventHandler() {
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
622
|
+
const self = this;
|
|
623
|
+
|
|
624
|
+
getWindow().addEventListener("resize", (event) => {
|
|
625
|
+
updateGrid.call(self);
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
self[columnBarElementSymbol].attachObserver(
|
|
629
|
+
new Observer((e) => {
|
|
630
|
+
updateHeaderFromColumnBar.call(self);
|
|
631
|
+
updateGrid.call(self);
|
|
632
|
+
updateConfigColumnBar.call(self);
|
|
633
|
+
}),
|
|
634
|
+
);
|
|
635
|
+
|
|
636
|
+
self[gridHeadersElementSymbol].addEventListener("click", function (event) {
|
|
637
|
+
let element = null;
|
|
638
|
+
const datasource = self[datasourceLinkedElementSymbol];
|
|
639
|
+
if (!datasource) {
|
|
640
|
+
return;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
element = findTargetElementFromEvent(event, ATTRIBUTE_DATATABLE_SORTABLE);
|
|
644
|
+
if (element) {
|
|
645
|
+
const index = element.parentNode.getAttribute(ATTRIBUTE_DATATABLE_INDEX);
|
|
646
|
+
const headers = self.getOption("headers");
|
|
647
|
+
|
|
648
|
+
event.preventDefault();
|
|
649
|
+
|
|
650
|
+
headers[index].changeDirection();
|
|
651
|
+
|
|
652
|
+
queueMicrotask(function () {
|
|
653
|
+
/** hotfix, normally this should be done via the updater, no idea why this is not possible. */
|
|
654
|
+
element.setAttribute(
|
|
655
|
+
ATTRIBUTE_DATATABLE_SORTABLE,
|
|
656
|
+
`${headers[index].field} ${headers[index].direction}`,
|
|
657
|
+
);
|
|
658
|
+
|
|
659
|
+
storeOrderStatement.call(self, true);
|
|
660
|
+
});
|
|
661
|
+
}
|
|
662
|
+
});
|
|
671
663
|
}
|
|
672
664
|
|
|
673
665
|
/**
|
|
674
666
|
* @private
|
|
675
667
|
*/
|
|
676
668
|
function initGridAndStructs(hostConfig, headerOrderMap) {
|
|
677
|
-
|
|
678
|
-
|
|
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
|
-
|
|
669
|
+
const rowID = this.getOption("templateMapping.row-key");
|
|
670
|
+
|
|
671
|
+
if (!this[gridElementSymbol]) {
|
|
672
|
+
throw new Error("no grid element is defined");
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
let template;
|
|
676
|
+
getSlottedElements.call(this).forEach((e) => {
|
|
677
|
+
if (e instanceof HTMLTemplateElement && e.id === rowID) {
|
|
678
|
+
template = e;
|
|
679
|
+
}
|
|
680
|
+
});
|
|
681
|
+
|
|
682
|
+
if (!template) {
|
|
683
|
+
throw new Error("no template is defined");
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
const rowCount = template.content.children.length;
|
|
687
|
+
|
|
688
|
+
const headers = [];
|
|
689
|
+
|
|
690
|
+
for (let i = 0; i < rowCount; i++) {
|
|
691
|
+
let hClass = "";
|
|
692
|
+
const row = template.content.children[i];
|
|
693
|
+
|
|
694
|
+
let mode = "";
|
|
695
|
+
if (row.hasAttribute(ATTRIBUTE_DATATABLE_MODE)) {
|
|
696
|
+
mode = row.getAttribute(ATTRIBUTE_DATATABLE_MODE);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
let grid = row.getAttribute(ATTRIBUTE_DATATABLE_GRID_TEMPLATE);
|
|
700
|
+
if (!grid || grid === "" || grid === "auto") {
|
|
701
|
+
grid = "minmax(0, 1fr)";
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
let label = "";
|
|
705
|
+
let labelKey = "";
|
|
706
|
+
|
|
707
|
+
if (row.hasAttribute(ATTRIBUTE_DATATABLE_HEAD)) {
|
|
708
|
+
label = row.getAttribute(ATTRIBUTE_DATATABLE_HEAD);
|
|
709
|
+
labelKey = label;
|
|
710
|
+
|
|
711
|
+
try {
|
|
712
|
+
if (label.startsWith("i18n:")) {
|
|
713
|
+
label = label.substring(5, label.length);
|
|
714
|
+
label = getDocumentTranslations().getText(label, label);
|
|
715
|
+
}
|
|
716
|
+
} catch (e) {
|
|
717
|
+
label = "i18n error " + label;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
if (!label) {
|
|
722
|
+
label = i + 1 + "";
|
|
723
|
+
mode = ATTRIBUTE_DATATABLE_MODE_FIXED;
|
|
724
|
+
labelKey = label;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
if (isObject(hostConfig) && hostConfig.hasOwnProperty(label)) {
|
|
728
|
+
if (hostConfig[label] === false) {
|
|
729
|
+
mode = ATTRIBUTE_DATATABLE_MODE_HIDDEN;
|
|
730
|
+
} else {
|
|
731
|
+
mode = ATTRIBUTE_DATATABLE_MODE_VISIBLE;
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
let align = "";
|
|
736
|
+
if (row.hasAttribute(ATTRIBUTE_DATATABLE_ALIGN)) {
|
|
737
|
+
align = row.getAttribute(ATTRIBUTE_DATATABLE_ALIGN);
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
switch (align) {
|
|
741
|
+
case "center":
|
|
742
|
+
hClass = "flex-center";
|
|
743
|
+
break;
|
|
744
|
+
case "end":
|
|
745
|
+
hClass = "flex-end";
|
|
746
|
+
break;
|
|
747
|
+
case "start":
|
|
748
|
+
hClass = "flex-start";
|
|
749
|
+
break;
|
|
750
|
+
default:
|
|
751
|
+
hClass = "flex-start";
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
let field = "";
|
|
755
|
+
let direction = DIRECTION_NONE;
|
|
756
|
+
if (row.hasAttribute(ATTRIBUTE_DATATABLE_SORTABLE)) {
|
|
757
|
+
field = row.getAttribute(ATTRIBUTE_DATATABLE_SORTABLE).trim();
|
|
758
|
+
const parts = field.split(" ").map((item) => item.trim());
|
|
759
|
+
field = parts[0];
|
|
760
|
+
|
|
761
|
+
if (headerOrderMap.has(field)) {
|
|
762
|
+
direction = headerOrderMap.get(field);
|
|
763
|
+
} else if (
|
|
764
|
+
parts.length === 2 &&
|
|
765
|
+
[DIRECTION_ASC, DIRECTION_DESC].indexOf(parts[1]) !== -1
|
|
766
|
+
) {
|
|
767
|
+
direction = parts[1];
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
if (mode === ATTRIBUTE_DATATABLE_MODE_HIDDEN) {
|
|
772
|
+
hClass += " hidden";
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
const header = new Header();
|
|
776
|
+
header.setInternals({
|
|
777
|
+
field: field,
|
|
778
|
+
label: label,
|
|
779
|
+
classes: hClass,
|
|
780
|
+
index: i,
|
|
781
|
+
mode: mode,
|
|
782
|
+
grid: grid,
|
|
783
|
+
labelKey: labelKey,
|
|
784
|
+
direction: direction,
|
|
785
|
+
});
|
|
786
|
+
|
|
787
|
+
headers.push(header);
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
this.setOption("headers", headers);
|
|
791
|
+
queueMicrotask(() => {
|
|
792
|
+
storeOrderStatement.call(this, this.getOption("features.autoInit"));
|
|
793
|
+
});
|
|
802
794
|
}
|
|
803
795
|
|
|
804
796
|
/**
|
|
@@ -806,75 +798,75 @@ function initGridAndStructs(hostConfig, headerOrderMap) {
|
|
|
806
798
|
* @return {string}
|
|
807
799
|
*/
|
|
808
800
|
export function getStoredOrderConfigKey() {
|
|
809
|
-
|
|
801
|
+
return generateUniqueConfigKey("datatable", this?.id, "stored-order");
|
|
810
802
|
}
|
|
811
803
|
|
|
812
804
|
/**
|
|
813
805
|
* @private
|
|
814
806
|
*/
|
|
815
807
|
function storeOrderStatement(doFetch) {
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
808
|
+
const headers = this.getOption("headers");
|
|
809
|
+
const statement = createOrderStatement(headers);
|
|
810
|
+
setDataSource.call(this, {orderBy: statement}, doFetch);
|
|
819
811
|
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
812
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
|
813
|
+
if (!(host && this.id)) {
|
|
814
|
+
return;
|
|
815
|
+
}
|
|
824
816
|
|
|
825
|
-
|
|
817
|
+
const configKey = getStoredOrderConfigKey.call(this);
|
|
826
818
|
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
819
|
+
// statement explode with , and remove all empty
|
|
820
|
+
const list = statement.split(",").filter((item) => item.trim() !== "");
|
|
821
|
+
if (list.length === 0) {
|
|
822
|
+
return;
|
|
823
|
+
}
|
|
832
824
|
|
|
833
|
-
|
|
825
|
+
host.setConfig(configKey, list);
|
|
834
826
|
}
|
|
835
827
|
|
|
836
828
|
/**
|
|
837
829
|
* @private
|
|
838
830
|
*/
|
|
839
831
|
function updateGrid() {
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
832
|
+
if (!this[gridElementSymbol]) {
|
|
833
|
+
throw new Error("no grid element is defined");
|
|
834
|
+
}
|
|
843
835
|
|
|
844
|
-
|
|
836
|
+
let gridTemplateColumns = "";
|
|
845
837
|
|
|
846
|
-
|
|
838
|
+
const headers = this.getOption("headers");
|
|
847
839
|
|
|
848
|
-
|
|
840
|
+
let styles = "";
|
|
849
841
|
|
|
850
|
-
|
|
851
|
-
|
|
842
|
+
for (let i = 0; i < headers.length; i++) {
|
|
843
|
+
const header = headers[i];
|
|
852
844
|
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
845
|
+
if (header.mode === ATTRIBUTE_DATATABLE_MODE_HIDDEN) {
|
|
846
|
+
styles += `[data-monster-role=datatable]>[data-monster-head="${header.labelKey}"] { display: none; }\n`;
|
|
847
|
+
styles += `[data-monster-role=datatable-headers]>[data-monster-index="${header.index}"] { display: none; }\n`;
|
|
848
|
+
} else {
|
|
849
|
+
gridTemplateColumns += `${header.grid} `;
|
|
850
|
+
}
|
|
851
|
+
}
|
|
860
852
|
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
853
|
+
const sheet = new CSSStyleSheet();
|
|
854
|
+
if (styles !== "") sheet.replaceSync(styles);
|
|
855
|
+
this.shadowRoot.adoptedStyleSheets = [...DataTable.getCSSStyleSheet(), sheet];
|
|
864
856
|
|
|
865
|
-
|
|
857
|
+
const bodyWidth = getDocument().body.getBoundingClientRect().width;
|
|
866
858
|
|
|
867
|
-
|
|
859
|
+
const breakpoint = this.getOption("responsive.breakpoint");
|
|
868
860
|
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
861
|
+
if (bodyWidth > breakpoint) {
|
|
862
|
+
this[gridElementSymbol].style.gridTemplateColumns =
|
|
863
|
+
`${gridTemplateColumns}`;
|
|
864
|
+
this[gridHeadersElementSymbol].style.gridTemplateColumns =
|
|
865
|
+
`${gridTemplateColumns}`;
|
|
866
|
+
} else {
|
|
867
|
+
this[gridElementSymbol].style.gridTemplateColumns = "auto";
|
|
868
|
+
this[gridHeadersElementSymbol].style.gridTemplateColumns = "auto";
|
|
869
|
+
}
|
|
878
870
|
}
|
|
879
871
|
|
|
880
872
|
/**
|
|
@@ -882,20 +874,20 @@ function updateGrid() {
|
|
|
882
874
|
* @param {Monster.Components.Datatable.Header[]} headers
|
|
883
875
|
* @param {bool} doFetch
|
|
884
876
|
*/
|
|
885
|
-
function setDataSource({
|
|
886
|
-
|
|
877
|
+
function setDataSource({orderBy}, doFetch) {
|
|
878
|
+
const datasource = this[datasourceLinkedElementSymbol];
|
|
887
879
|
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
880
|
+
if (!datasource) {
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
891
883
|
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
884
|
+
if (isFunction(datasource?.setParameters)) {
|
|
885
|
+
datasource.setParameters({orderBy});
|
|
886
|
+
}
|
|
895
887
|
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
888
|
+
if (doFetch !== false && isFunction(datasource?.fetch)) {
|
|
889
|
+
datasource.fetch();
|
|
890
|
+
}
|
|
899
891
|
}
|
|
900
892
|
|
|
901
893
|
/**
|
|
@@ -903,20 +895,20 @@ function setDataSource({ orderBy }, doFetch) {
|
|
|
903
895
|
* @return {Monster.Components.Datatable.Form}
|
|
904
896
|
*/
|
|
905
897
|
function initControlReferences() {
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
898
|
+
if (!this.shadowRoot) {
|
|
899
|
+
throw new Error("no shadow-root is defined");
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
this[gridElementSymbol] = this.shadowRoot.querySelector(
|
|
903
|
+
"[data-monster-role=datatable]",
|
|
904
|
+
);
|
|
905
|
+
this[gridHeadersElementSymbol] = this.shadowRoot.querySelector(
|
|
906
|
+
"[data-monster-role=datatable-headers]",
|
|
907
|
+
);
|
|
908
|
+
this[columnBarElementSymbol] =
|
|
909
|
+
this.shadowRoot.querySelector("monster-column-bar");
|
|
910
|
+
|
|
911
|
+
return this;
|
|
920
912
|
}
|
|
921
913
|
|
|
922
914
|
/**
|
|
@@ -926,22 +918,22 @@ function initControlReferences() {
|
|
|
926
918
|
* @throws {Error} the datasource could not be initialized
|
|
927
919
|
*/
|
|
928
920
|
function initOptionsFromArguments() {
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
921
|
+
const options = {};
|
|
922
|
+
const selector = this.getAttribute(ATTRIBUTE_DATASOURCE_SELECTOR);
|
|
923
|
+
|
|
924
|
+
if (selector) {
|
|
925
|
+
options.datasource = {selector: selector};
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
const breakpoint = this.getAttribute(
|
|
929
|
+
ATTRIBUTE_DATATABLE_RESPONSIVE_BREAKPOINT,
|
|
930
|
+
);
|
|
931
|
+
if (breakpoint) {
|
|
932
|
+
options.responsive = {};
|
|
933
|
+
options.responsive.breakpoint = parseInt(breakpoint);
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
return options;
|
|
945
937
|
}
|
|
946
938
|
|
|
947
939
|
/**
|
|
@@ -949,7 +941,7 @@ function initOptionsFromArguments() {
|
|
|
949
941
|
* @return {string}
|
|
950
942
|
*/
|
|
951
943
|
function getEmptyTemplate() {
|
|
952
|
-
|
|
944
|
+
return `<monster-state data-monster-role="empty-without-action">
|
|
953
945
|
<div part="visual">
|
|
954
946
|
<svg width="4rem" height="4rem" fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
955
947
|
<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"/>
|
|
@@ -967,8 +959,8 @@ function getEmptyTemplate() {
|
|
|
967
959
|
* @return {string}
|
|
968
960
|
*/
|
|
969
961
|
function getTemplate() {
|
|
970
|
-
|
|
971
|
-
|
|
962
|
+
// language=HTML
|
|
963
|
+
return `
|
|
972
964
|
<div data-monster-role="control" part="control" data-monster-attributes="class path:classes.control">
|
|
973
965
|
<template id="headers-row">
|
|
974
966
|
<div data-monster-attributes="class path:headers-row.classes,
|
|
@@ -977,7 +969,7 @@ function getTemplate() {
|
|
|
977
969
|
</template>
|
|
978
970
|
<slot></slot>
|
|
979
971
|
<div data-monster-attributes="class path:classes.container"
|
|
980
|
-
|
|
972
|
+
data-monster-role="table-container" part="table-container">
|
|
981
973
|
<div class="filter">
|
|
982
974
|
<slot name="filter"></slot>
|
|
983
975
|
</div>
|