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