@schukai/monster 3.61.0 → 3.63.0

Sign up to get free protection for your applications and to get access to all the features.
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,