@schukai/monster 3.61.0 → 3.63.0

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