@schukai/monster 3.71.3 → 3.73.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/package.json +1 -1
  3. package/source/components/datatable/dataset.mjs +268 -272
  4. package/source/components/datatable/datasource/dom.mjs +2 -2
  5. package/source/components/datatable/datasource/rest.mjs +408 -410
  6. package/source/components/datatable/filter.mjs +0 -1
  7. package/source/components/datatable/style/datatable.pcss +7 -5
  8. package/source/components/datatable/style/embedded-pagination.pcss +1 -1
  9. package/source/components/datatable/style/pagination.pcss +1 -1
  10. package/source/components/datatable/stylesheet/change-button.mjs +2 -4
  11. package/source/components/datatable/stylesheet/column-bar.mjs +2 -4
  12. package/source/components/datatable/stylesheet/dataset.mjs +2 -4
  13. package/source/components/datatable/stylesheet/datasource.mjs +1 -3
  14. package/source/components/datatable/stylesheet/datatable.mjs +2 -4
  15. package/source/components/datatable/stylesheet/embedded-pagination.mjs +1 -1
  16. package/source/components/datatable/stylesheet/filter-button.mjs +1 -3
  17. package/source/components/datatable/stylesheet/filter-controls-defaults.mjs +14 -7
  18. package/source/components/datatable/stylesheet/filter-date-range.mjs +1 -3
  19. package/source/components/datatable/stylesheet/filter-range.mjs +1 -3
  20. package/source/components/datatable/stylesheet/filter.mjs +2 -4
  21. package/source/components/datatable/stylesheet/pagination.mjs +2 -4
  22. package/source/components/datatable/stylesheet/save-button.mjs +2 -4
  23. package/source/components/datatable/stylesheet/select-filter.mjs +2 -4
  24. package/source/components/datatable/stylesheet/status.mjs +2 -4
  25. package/source/components/form/context-help.mjs +1 -1
  26. package/source/components/form/field-set.mjs +219 -219
  27. package/source/components/form/form.mjs +309 -185
  28. package/source/components/form/reload.mjs +211 -211
  29. package/source/components/form/select.mjs +12 -13
  30. package/source/components/form/style/field-set.pcss +2 -2
  31. package/source/components/form/style/form.pcss +8 -0
  32. package/source/components/form/stylesheet/action-button.mjs +2 -4
  33. package/source/components/form/stylesheet/api-button.mjs +1 -3
  34. package/source/components/form/stylesheet/button-bar.mjs +2 -4
  35. package/source/components/form/stylesheet/button.mjs +2 -4
  36. package/source/components/form/stylesheet/confirm-button.mjs +2 -4
  37. package/source/components/form/stylesheet/context-error.mjs +2 -4
  38. package/source/components/form/stylesheet/context-help.mjs +2 -4
  39. package/source/components/form/stylesheet/field-set.mjs +14 -7
  40. package/source/components/form/stylesheet/form.mjs +14 -7
  41. package/source/components/form/stylesheet/message-state-button.mjs +1 -3
  42. package/source/components/form/stylesheet/popper-button.mjs +2 -4
  43. package/source/components/form/stylesheet/select.mjs +14 -7
  44. package/source/components/form/stylesheet/state-button.mjs +2 -4
  45. package/source/components/form/stylesheet/tree-select.mjs +1 -3
  46. package/source/components/host/stylesheet/call-button.mjs +2 -4
  47. package/source/components/host/stylesheet/config-manager.mjs +1 -3
  48. package/source/components/host/stylesheet/host.mjs +2 -4
  49. package/source/components/host/stylesheet/overlay.mjs +2 -4
  50. package/source/components/host/stylesheet/toggle-button.mjs +2 -4
  51. package/source/components/host/stylesheet/viewer.mjs +2 -4
  52. package/source/components/layout/style/collapse.pcss +2 -2
  53. package/source/components/layout/style/details.pcss +2 -2
  54. package/source/components/layout/stylesheet/collapse.mjs +14 -7
  55. package/source/components/layout/stylesheet/details.mjs +2 -4
  56. package/source/components/layout/stylesheet/panel.mjs +2 -4
  57. package/source/components/layout/stylesheet/popper.mjs +2 -4
  58. package/source/components/layout/stylesheet/split-panel.mjs +1 -3
  59. package/source/components/layout/stylesheet/tabs.mjs +2 -4
  60. package/source/components/layout/stylesheet/width-toggle.mjs +1 -3
  61. package/source/components/layout/tabs.mjs +0 -1
  62. package/source/components/navigation/stylesheet/table-of-content.mjs +2 -4
  63. package/source/components/notify/stylesheet/message.mjs +2 -4
  64. package/source/components/notify/stylesheet/notify.mjs +2 -4
  65. package/source/components/state/stylesheet/log.mjs +2 -4
  66. package/source/components/state/stylesheet/state.mjs +2 -4
  67. package/source/components/style/control.pcss +5 -0
  68. package/source/components/style/data-grid.pcss +2 -2
  69. package/source/components/style/mixin/typography.pcss +7 -1
  70. package/source/components/style/normalize.pcss +1 -1
  71. package/source/components/stylesheet/badge.mjs +1 -3
  72. package/source/components/stylesheet/border.mjs +1 -3
  73. package/source/components/stylesheet/button.mjs +1 -3
  74. package/source/components/stylesheet/card.mjs +1 -3
  75. package/source/components/stylesheet/color.mjs +1 -3
  76. package/source/components/stylesheet/common.mjs +1 -3
  77. package/source/components/stylesheet/control.mjs +2 -4
  78. package/source/components/stylesheet/data-grid.mjs +2 -4
  79. package/source/components/stylesheet/display.mjs +1 -3
  80. package/source/components/stylesheet/floating-ui.mjs +1 -3
  81. package/source/components/stylesheet/form.mjs +13 -6
  82. package/source/components/stylesheet/host.mjs +1 -3
  83. package/source/components/stylesheet/icons.mjs +1 -3
  84. package/source/components/stylesheet/mixin/badge.mjs +1 -3
  85. package/source/components/stylesheet/mixin/button.mjs +1 -3
  86. package/source/components/stylesheet/mixin/form.mjs +13 -6
  87. package/source/components/stylesheet/mixin/hover.mjs +1 -3
  88. package/source/components/stylesheet/mixin/icon.mjs +1 -3
  89. package/source/components/stylesheet/mixin/media.mjs +1 -3
  90. package/source/components/stylesheet/mixin/property.mjs +13 -6
  91. package/source/components/stylesheet/mixin/skeleton.mjs +1 -3
  92. package/source/components/stylesheet/mixin/spinner.mjs +1 -3
  93. package/source/components/stylesheet/mixin/typography.mjs +1 -3
  94. package/source/components/stylesheet/normalize.mjs +1 -3
  95. package/source/components/stylesheet/popper.mjs +1 -3
  96. package/source/components/stylesheet/property.mjs +2 -4
  97. package/source/components/stylesheet/ripple.mjs +1 -3
  98. package/source/components/stylesheet/skeleton.mjs +1 -3
  99. package/source/components/stylesheet/space.mjs +1 -3
  100. package/source/components/stylesheet/spinner.mjs +1 -3
  101. package/source/components/stylesheet/table.mjs +1 -3
  102. package/source/components/stylesheet/theme.mjs +1 -3
  103. package/source/components/stylesheet/typography.mjs +13 -6
  104. package/source/components/tree-menu/dragable-tree-menu.mjs +693 -0
  105. package/source/components/tree-menu/style/tree-menu.pcss +69 -42
  106. package/source/components/tree-menu/stylesheet/tree-menu.mjs +2 -4
  107. package/source/components/tree-menu/tree-menu.mjs +260 -331
  108. package/source/data/datasource/server/restapi.mjs +194 -191
  109. package/source/data/datasource/server.mjs +107 -105
  110. package/source/data/diff.mjs +1 -1
  111. package/source/dom/constants.mjs +18 -0
  112. package/source/dom/customelement.mjs +2 -6
  113. package/source/dom/slotted.mjs +6 -1
  114. package/source/dom/updater.mjs +2 -0
  115. package/test/cases/components/host/details.mjs +1 -1
  116. package/test/cases/components/host/host.mjs +1 -1
  117. package/test/cases/components/host/overlay.mjs +1 -1
  118. package/test/cases/dom/customcontrol.mjs +1 -1
  119. package/test/cases/dom/customelement.mjs +2 -2
@@ -13,10 +13,9 @@
13
13
  */
14
14
 
15
15
  import { buildTree } from "../../data/buildtree.mjs";
16
- import { Datasource } from "../../data/datasource.mjs";
16
+ import { Datasource } from "../datatable/datasource.mjs";
17
17
  import { addAttributeToken } from "../../dom/attributes.mjs";
18
18
  import {
19
- ATTRIBUTE_DISABLED,
20
19
  ATTRIBUTE_ERRORMESSAGE,
21
20
  ATTRIBUTE_ROLE,
22
21
  ATTRIBUTE_UPDATER_INSERT_REFERENCE,
@@ -24,17 +23,22 @@ import {
24
23
  import {
25
24
  assembleMethodSymbol,
26
25
  CustomElement,
26
+ getSlottedElements,
27
27
  initMethodSymbol,
28
28
  registerCustomElement,
29
29
  } from "../../dom/customelement.mjs";
30
30
  import { findTargetElementFromEvent } from "../../dom/events.mjs";
31
+ import { findElementWithSelectorUpwards } from "../../dom/util.mjs";
31
32
  import { Formatter } from "../../text/formatter.mjs";
32
- import { isObject } from "../../types/is.mjs";
33
+ import { isFunction, isString } from "../../types/is.mjs";
33
34
  import { Node } from "../../types/node.mjs";
34
35
  import { NodeRecursiveIterator } from "../../types/noderecursiveiterator.mjs";
35
36
  import { Observer } from "../../types/observer.mjs";
36
- import { ProxyObserver } from "../../types/proxyobserver.mjs";
37
37
  import { validateInstance } from "../../types/validate.mjs";
38
+ import {
39
+ datasourceLinkedElementSymbol,
40
+ handleDataSourceChanges,
41
+ } from "../datatable/util.mjs";
38
42
  import { ATTRIBUTE_INTEND } from "./../constants.mjs";
39
43
  import { CommonStyleSheet } from "../stylesheet/common.mjs";
40
44
  import { TreeMenuStyleSheet } from "./stylesheet/tree-menu.mjs";
@@ -51,48 +55,19 @@ const internalNodesSymbol = Symbol("internalNodes");
51
55
  * @private
52
56
  * @type {symbol}
53
57
  */
54
- const controlElementSymbol = Symbol("controlElement");
55
-
56
- /**
57
- * @private
58
- * @type {symbol}
59
- */
60
- const openEntryEventHandlerSymbol = Symbol("openEntryEventHandler");
61
-
62
- /**
63
- * @private
64
- * @type {symbol}
65
- */
66
- const dragstartEventHandlerSymbol = Symbol("dragstartEventHandler");
67
- /**
68
- * @private
69
- * @type {symbol}
70
- */
71
- const dragenterEventHandlerSymbol = Symbol("dragenterEventHandler");
72
-
73
- /**
74
- * @private
75
- * @type {symbol}
76
- */
77
- const dragleaveEventHandlerSymbol = Symbol("dragleaveEventHandler");
78
-
79
- /**
80
- * @private
81
- * @type {symbol}
82
- */
83
- const dragEventHandlerSymbol = Symbol("dragEventHandler");
58
+ const preventChangeSymbol = Symbol("preventChangeCounter");
84
59
 
85
60
  /**
86
61
  * @private
87
62
  * @type {symbol}
88
63
  */
89
- const dragoverEventHandlerSymbol = Symbol("dragoverEventHandler");
64
+ const controlElementSymbol = Symbol("controlElement");
90
65
 
91
66
  /**
92
67
  * @private
93
68
  * @type {symbol}
94
69
  */
95
- const dropEventHandlerSymbol = Symbol("dropEventHandlerSymbol");
70
+ const openEntryEventHandlerSymbol = Symbol("openEntryEventHandler");
96
71
 
97
72
  /**
98
73
  * TreeMenu
@@ -121,11 +96,15 @@ const dropEventHandlerSymbol = Symbol("dropEventHandlerSymbol");
121
96
  * @enduml
122
97
  * @since 1.0.0
123
98
  * @copyright schukai GmbH
124
- * @memberOf Monster.Components.TreeMenu
125
99
  * @summary A TreeMenu control
126
100
  * @fires Monster.Components.TreeMenu.event:monster-fetched
127
101
  */
128
102
  class TreeMenu extends CustomElement {
103
+ constructor() {
104
+ super();
105
+ this[preventChangeSymbol] = false;
106
+ }
107
+
129
108
  /**
130
109
  * This method is called internal and should not be called directly.
131
110
  *
@@ -143,7 +122,6 @@ class TreeMenu extends CustomElement {
143
122
  * shadowMode: 'open',
144
123
  * })),'application/json',true).toString()
145
124
  * ```
146
- * @property {Object} toggleEventType=click,touch List of event types to be observed for opening the dropdown
147
125
  * @property {Object} templates Template definitions
148
126
  * @property {string} templates.main Main template
149
127
  * @property {Datasource} datasource data source
@@ -153,44 +131,46 @@ class TreeMenu extends CustomElement {
153
131
  * @property {String} mapping.keyTemplate="" template with the key placeholders in the form ${name}, where name is the key
154
132
  * @property {String} mapping.rootReferences=['0', undefined, null]
155
133
  * @property {String} mapping.idTemplate=id
156
- * @property {String} mapping.parentTemplate=parent
134
+ * @property {String} mapping.parentKey=parent
157
135
  * @property {String} mapping.selection
158
136
  */
159
137
  get defaults() {
160
- return Object.assign(
161
- {},
162
- super.defaults,
163
- {
164
- toggleEventType: ["click", "touch"],
165
- mapping: {
166
- rootReferences: ["0", undefined, null],
167
- idTemplate: "id",
168
- parentTemplate: "parent",
169
- selector: "*",
170
- labelTemplate: "",
171
- valueTemplate: "",
172
- filter: undefined,
173
- },
174
- templates: {
175
- main: getTemplate(),
138
+ return Object.assign({}, super.defaults, {
139
+ classes: {
140
+ control: "monster-theme-primary-1",
141
+ label: "monster-theme-primary-1",
142
+ },
143
+
144
+ mapping: {
145
+ rootReferences: ["0", undefined, null],
146
+ idTemplate: "id",
147
+ parentKey: "parent",
148
+ selector: "*",
149
+ labelTemplate: "",
150
+ valueTemplate: "",
151
+ iconTemplate: "",
152
+ filter: undefined,
153
+ },
154
+
155
+ templates: {
156
+ main: getTemplate(),
157
+ },
158
+
159
+ datasource: {
160
+ selector: null,
161
+ },
162
+
163
+ actions: {
164
+ open: null,
165
+ close: null,
166
+ select: (entry) => {
167
+ throw new Error("no action defined for select");
176
168
  },
177
- datasource: undefined,
178
- entries: [],
179
169
  },
180
- initOptionsFromArguments.call(this),
181
- );
182
- }
183
170
 
184
- /**
185
- * This method determines which attributes are to be monitored by `attributeChangedCallback()`.
186
- *
187
- * @return {string[]}
188
- * @since 1.15.0
189
- */
190
- static get observedAttributes() {
191
- const list = super.observedAttributes;
192
- //list.push(ATTRIBUTE_FORM_URL);
193
- return list;
171
+ data: [],
172
+ entries: [],
173
+ });
194
174
  }
195
175
 
196
176
  /**
@@ -201,18 +181,17 @@ class TreeMenu extends CustomElement {
201
181
  }
202
182
 
203
183
  /**
204
- *
205
- * @return {Monster.Components.TreeMenu.Form}
184
+ * @return {void}
206
185
  */
207
186
  [assembleMethodSymbol]() {
208
187
  super[assembleMethodSymbol]();
209
188
 
210
189
  initControlReferences.call(this);
211
190
  initEventHandler.call(this);
212
- importEntriesFromDatasource.call(this);
213
191
  initObserver.call(this);
214
-
215
- return this;
192
+ setTimeout(() => {
193
+ copyIconMap.call(this);
194
+ }, 0);
216
195
  }
217
196
 
218
197
  /**
@@ -232,13 +211,113 @@ class TreeMenu extends CustomElement {
232
211
  static getTag() {
233
212
  return "monster-tree-menu";
234
213
  }
214
+
215
+ /**
216
+ * @param {string} value
217
+ * @param value
218
+ */
219
+ selectEntry(value) {
220
+ this.shadowRoot
221
+ .querySelectorAll("[data-monster-role=entry]")
222
+ .forEach((entry) => {
223
+ entry.classList.remove("selected");
224
+ });
225
+
226
+ value = String(value);
227
+
228
+ const entries = this.getOption("entries");
229
+ const index = entries.findIndex((entry) => entry.value === value);
230
+
231
+ if (index === -1) {
232
+ return;
233
+ }
234
+
235
+ const currentNode = this.shadowRoot.querySelector(
236
+ "[data-monster-insert-reference=entries-" + index + "]",
237
+ );
238
+
239
+ console.log(currentNode);
240
+
241
+ currentNode.click();
242
+
243
+ let intend = parseInt(currentNode.getAttribute(ATTRIBUTE_INTEND));
244
+
245
+ if (intend > 0) {
246
+ let ref = currentNode.previousElementSibling;
247
+ while (ref && ref.hasAttribute(ATTRIBUTE_INTEND)) {
248
+ const i = parseInt(ref.getAttribute(ATTRIBUTE_INTEND));
249
+
250
+ if (isNaN(i)) {
251
+ break;
252
+ }
253
+
254
+ if (i < intend) {
255
+ if (ref.getAttribute("data-monster-state") !== "open") {
256
+ ref.click();
257
+ }
258
+
259
+ if (i === 0) {
260
+ break;
261
+ }
262
+ intend = i;
263
+ }
264
+ ref = ref.previousElementSibling;
265
+ }
266
+ }
267
+ }
268
+ }
269
+
270
+ /**
271
+ * @private
272
+ */
273
+ function copyIconMap() {
274
+ const nodes = getSlottedElements.call(this, "svg", null);
275
+ if (nodes.size > 0) {
276
+ for (const node of nodes) {
277
+ this.shadowRoot.appendChild(node);
278
+ }
279
+ }
235
280
  }
236
281
 
237
282
  /**
238
283
  * @private
239
284
  */
240
285
  function initEventHandler() {
241
- switchToConfig.call(this);
286
+ const selector = this.getOption("datasource.selector");
287
+
288
+ if (isString(selector)) {
289
+ const element = findElementWithSelectorUpwards(this, selector);
290
+ if (element === null) {
291
+ throw new Error("the selector must match exactly one element");
292
+ }
293
+
294
+ if (!(element instanceof HTMLElement)) {
295
+ throw new TypeError("the element must be an HTMLElement");
296
+ }
297
+
298
+ customElements.whenDefined(element.tagName.toLocaleLowerCase()).then(() => {
299
+ if (!(element instanceof Datasource)) {
300
+ throw new TypeError("the element must be a datasource");
301
+ }
302
+
303
+ this[datasourceLinkedElementSymbol] = element;
304
+
305
+ handleDataSourceChanges.call(this);
306
+ element.datasource.attachObserver(
307
+ new Observer(handleDataSourceChanges.bind(this)),
308
+ );
309
+
310
+ this.attachObserver(
311
+ new Observer(() => {
312
+ if (this[preventChangeSymbol] === true) {
313
+ return;
314
+ }
315
+ this[preventChangeSymbol] = true;
316
+ importEntries.call(this);
317
+ }),
318
+ );
319
+ });
320
+ }
242
321
 
243
322
  this[openEntryEventHandlerSymbol] = (event) => {
244
323
  const container = findTargetElementFromEvent(
@@ -246,26 +325,70 @@ function initEventHandler() {
246
325
  ATTRIBUTE_ROLE,
247
326
  "entry",
248
327
  );
328
+
249
329
  if (!(container instanceof HTMLElement)) {
250
330
  return;
251
331
  }
252
332
 
253
- //let container = findClosestByAttribute(element, ATTRIBUTE_ROLE, 'option');
254
333
  const index = container
255
334
  .getAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE)
256
335
  .split("-")
257
336
  .pop();
258
337
 
338
+ const currentEntry = this.getOption("entries." + index);
339
+
340
+ if (currentEntry["has-children"] === false) {
341
+ const doAction = this.getOption("actions.select");
342
+
343
+ this.shadowRoot
344
+ .querySelectorAll("[data-monster-role=entry].selected")
345
+ .forEach((entry) => {
346
+ entry.classList.remove("selected");
347
+ });
348
+
349
+ let intend = currentEntry.intend;
350
+ if (intend > 0) {
351
+ let ref = container.previousElementSibling;
352
+ while (ref && ref.hasAttribute(ATTRIBUTE_INTEND)) {
353
+ const i = parseInt(ref.getAttribute(ATTRIBUTE_INTEND));
354
+
355
+ if (isNaN(i)) {
356
+ break;
357
+ }
358
+
359
+ if (i < intend) {
360
+ ref.classList.add("selected");
361
+ if (i === 0) {
362
+ break;
363
+ }
364
+ intend = i;
365
+ }
366
+ ref = ref.previousElementSibling;
367
+ }
368
+ }
369
+
370
+ container.classList.add("selected");
371
+
372
+ if (isFunction(doAction)) {
373
+ doAction.call(this, currentEntry, index);
374
+ }
375
+ return;
376
+ }
377
+
259
378
  const currentState = this.getOption("entries." + index + ".state");
260
379
 
261
380
  const newState = currentState === "close" ? "open" : "close";
262
- this.setOption("entries." + index + ".state", newState);
263
381
 
382
+ const doAction = this.getOption("actions." + newState);
383
+ if (isFunction(doAction)) {
384
+ doAction.call(this, this.getOption("entries." + index), index);
385
+ }
386
+
387
+ this.setOption("entries." + index + ".state", newState);
264
388
  const newVisibility = newState === "open" ? "visible" : "hidden";
265
389
 
266
390
  if (container.hasAttribute(ATTRIBUTE_INTEND)) {
267
391
  const intend = container.getAttribute(ATTRIBUTE_INTEND);
268
-
269
392
  let ref = container.nextElementSibling;
270
393
  const childIntend = parseInt(intend) + 1;
271
394
 
@@ -277,15 +400,22 @@ function initEventHandler() {
277
400
  return a >= b;
278
401
  };
279
402
 
280
- while (
281
- ref &&
282
- ref.hasAttribute(ATTRIBUTE_INTEND) &&
283
- cmp(parseInt(ref.getAttribute(ATTRIBUTE_INTEND)), childIntend)
284
- ) {
403
+ while (ref && ref.hasAttribute(ATTRIBUTE_INTEND)) {
404
+ const refIntend = ref.getAttribute(ATTRIBUTE_INTEND);
405
+
406
+ if (!cmp(parseInt(refIntend), childIntend)) {
407
+ if (refIntend === intend) {
408
+ break;
409
+ }
410
+ ref = ref.nextElementSibling;
411
+ continue;
412
+ }
413
+
285
414
  const refIndex = ref
286
415
  .getAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE)
287
416
  .split("-")
288
417
  .pop();
418
+
289
419
  this.setOption("entries." + refIndex + ".visibility", newVisibility);
290
420
 
291
421
  if (newState === "close") {
@@ -302,28 +432,12 @@ function initEventHandler() {
302
432
  this.shadowRoot.addEventListener(type, this[openEntryEventHandlerSymbol]);
303
433
  }
304
434
 
305
- // for (const [, type] of Object.entries(types)) {
306
- //
307
- // self[controlElementSymbol].addEventListener(type, function (event) {
308
- //
309
- // const element = findTargetElementFromEvent(event, ATTRIBUTE_ROLE, 'entry');
310
- // if (!(element instanceof HTMLElement)) {
311
- // return;
312
- // }
313
- //
314
- // toggle.call(self);
315
- //
316
- //
317
- // })
318
- //
319
- // }
320
-
321
435
  return this;
322
436
  }
323
437
 
324
438
  /**
325
439
  * @private
326
- * @this Form
440
+ * @this {TreeMenu}
327
441
  */
328
442
  function initObserver() {}
329
443
 
@@ -331,12 +445,12 @@ function initObserver() {}
331
445
  * Import Menu Entries from dataset
332
446
  *
333
447
  * @since 1.0.0
334
- * @param {array|object|Map|Set} data
335
448
  * @return {TreeMenu}
336
449
  * @throws {Error} map is not iterable
337
450
  * @private
338
451
  */
339
- function importEntries(data) {
452
+ function importEntries() {
453
+ const data = this.getOption("data");
340
454
  this[internalNodesSymbol] = new Map();
341
455
 
342
456
  const mappingOptions = this.getOption("mapping", {});
@@ -344,15 +458,20 @@ function importEntries(data) {
344
458
  const filter = mappingOptions?.["filter"];
345
459
  const rootReferences = mappingOptions?.["rootReferences"];
346
460
 
347
- const id = this.getOption("mapping.idTemplate", "id");
348
- const parentID = this.getOption("mapping.parentTemplate", "parent");
461
+ const id = this.getOption("mapping.idTemplate");
462
+ const parentKey = this.getOption("mapping.parentKey");
349
463
 
350
464
  const selector = mappingOptions?.["selector"];
351
465
 
352
- const nodes = buildTree(data, selector, id, parentID, {
353
- filter,
354
- rootReferences,
355
- });
466
+ let nodes;
467
+ try {
468
+ nodes = buildTree(data, selector, id, parentKey, {
469
+ filter,
470
+ rootReferences,
471
+ });
472
+ } catch (error) {
473
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, String(error));
474
+ }
356
475
 
357
476
  const options = [];
358
477
  for (const node of nodes) {
@@ -360,8 +479,9 @@ function importEntries(data) {
360
479
  for (const n of iterator) {
361
480
  const formattedValues = formatKeyLabel.call(this, n);
362
481
 
363
- const label = formattedValues.label;
364
- const value = formattedValues.value;
482
+ const label = formattedValues?.label;
483
+ const value = formattedValues?.value;
484
+ const icon = formattedValues?.icon;
365
485
  const intend = n.level;
366
486
 
367
487
  const visibility = intend > 0 ? "hidden" : "visible";
@@ -372,6 +492,7 @@ function importEntries(data) {
372
492
  options.push({
373
493
  value,
374
494
  label,
495
+ icon,
375
496
  intend,
376
497
  state,
377
498
  visibility,
@@ -381,74 +502,43 @@ function importEntries(data) {
381
502
  }
382
503
 
383
504
  this.setOption("entries", options);
384
- return this;
385
- }
386
-
387
- /**
388
- * @private
389
- */
390
- function importEntriesFromDatasource() {
391
- const self = this;
392
- self.setAttribute(ATTRIBUTE_DISABLED, ATTRIBUTE_DISABLED);
393
-
394
- const datasource = self.getOption("datasource");
395
- if (!(datasource instanceof Datasource)) {
396
- addAttributeToken(
397
- self,
398
- ATTRIBUTE_ERRORMESSAGE,
399
- "datasource is not defined",
400
- );
401
- return;
402
- }
403
505
 
404
- datasource.attachObserver(
405
- new Observer(function () {
406
- if (isObject(this) && this instanceof ProxyObserver) {
407
- importEntries.call(self, datasource.get());
408
- }
409
- }),
410
- );
411
-
412
- datasource
413
- .read()
414
- .then(() => {
415
- new Processing(() => {
416
- self.removeAttribute(ATTRIBUTE_DISABLED);
417
- }).run();
418
- })
419
- .catch((e) => {
420
- addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.toString());
421
- });
422
-
423
- return self;
506
+ return this;
424
507
  }
425
508
 
426
509
  /**
427
510
  *
428
511
  * @param {Node} node
429
512
  * @return {array<label, value>}
430
- * @memberOf Monster.Components.TreeMenu
431
513
  * @private
432
514
  */
433
515
  function formatKeyLabel(node) {
434
516
  validateInstance(node, Node);
435
517
 
436
518
  const label = new Formatter(node.value).format(
437
- this.getOption("mapping.labelTemplate", ""),
519
+ this.getOption("mapping.labelTemplate"),
438
520
  );
521
+
439
522
  const value = new Formatter(node.value).format(
440
- this.getOption("mapping.valueTemplate", ""),
523
+ this.getOption("mapping.valueTemplate"),
524
+ );
525
+
526
+ const iconID = new Formatter(node.value).format(
527
+ this.getOption("mapping.iconTemplate"),
441
528
  );
442
529
 
530
+ const icon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><use xlink:href="#${iconID}"></use></svg>`;
531
+
443
532
  return {
444
533
  value,
445
534
  label,
535
+ icon,
446
536
  };
447
537
  }
448
538
 
449
539
  /**
450
540
  * @private
451
- * @return {Monster.Components.TreeMenu.Form}
541
+ * @return {TreeMenu}
452
542
  */
453
543
  function initControlReferences() {
454
544
  if (!this.shadowRoot) {
@@ -458,173 +548,10 @@ function initControlReferences() {
458
548
  this[controlElementSymbol] = this.shadowRoot.querySelector(
459
549
  "[data-monster-role=control]",
460
550
  );
461
- return this;
462
- }
463
-
464
- /**
465
- *
466
- * ```
467
- * <monster-tree-menu data-monster-url="https://example.com/"></monster-tree-menu>
468
- * ```
469
-
470
- * @private
471
- * @return {object}
472
- */
473
- function initOptionsFromArguments() {
474
- const options = {};
475
-
476
- // let url = self.getAttribute(ATTRIBUTE_FORM_URL);
477
- //
478
- // if (isString(url)) {
479
- // options['url'] = new URL(url, document.location).toString()
480
- // }
481
-
482
- return options;
483
- }
484
-
485
- function switchToConfig() {
486
- if (!this.shadowRoot) {
487
- throw new Error("no shadow-root is defined");
488
- }
489
-
490
- this[dragoverEventHandlerSymbol] = (event) => {
491
- const element = findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "entry");
492
- event.preventDefault();
493
- if (!(element instanceof HTMLElement)) {
494
- return;
495
- }
496
-
497
- const dropzone = document.createElement("div");
498
- dropzone.classList.add("dropzone");
499
-
500
- element.prepend(dropzone);
501
-
502
- console.log("over", element.outerHTML, event);
503
-
504
- event.dataTransfer.dropEffect = "move";
505
- };
506
551
 
507
- this[dragenterEventHandlerSymbol] = (event) => {
508
- const element = findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "entry");
509
- console.log("enter", element.outerHTML, event);
510
-
511
- event.dataTransfer.dropEffect = "move";
512
- event.preventDefault();
513
- };
514
-
515
- this[dragleaveEventHandlerSymbol] = (event) => {
516
- const element = findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "entry");
517
-
518
- event.preventDefault();
519
- if (!(element instanceof HTMLElement)) {
520
- return;
521
- }
522
-
523
- console.log("leave", element.outerHTML, event);
524
-
525
- event.dataTransfer.dropEffect = "move";
526
- event.preventDefault();
527
- };
528
-
529
- this[dragEventHandlerSymbol] = (event) => {
530
- event.preventDefault();
531
- };
532
-
533
- this[dropEventHandlerSymbol] = (event) => {
534
- const element = findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "entry");
535
- console.log("drop", element.outerHTML, event);
536
- event.preventDefault();
537
- };
538
-
539
- this[dragstartEventHandlerSymbol] = (event) => {
540
- const element = findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "entry");
541
- if (!(element instanceof HTMLElement)) {
542
- return;
543
- }
544
-
545
- //let container = findClosestByAttribute(element, ATTRIBUTE_ROLE, 'option');
546
- const index = element
547
- .getAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE)
548
- .split("-")
549
- .pop();
550
-
551
- const currentState = this.getOption("entries." + index + ".state");
552
- event.dataTransfer.setData("text/plain", "22");
553
- event.dataTransfer.setData("text/html", "22");
554
- event.dataTransfer.effectAllowed = "move";
555
- };
556
-
557
- this[controlElementSymbol].addEventListener(
558
- "dragstart",
559
- this[dragstartEventHandlerSymbol],
560
- );
561
- this[controlElementSymbol].addEventListener(
562
- "dragenter",
563
- this[dragenterEventHandlerSymbol],
564
- );
565
- this[controlElementSymbol].addEventListener(
566
- "dragleave",
567
- this[dragleaveEventHandlerSymbol],
568
- );
569
- this[controlElementSymbol].addEventListener(
570
- "dragover",
571
- this[dragoverEventHandlerSymbol],
572
- );
573
- this[controlElementSymbol].addEventListener(
574
- "drop",
575
- this[dropEventHandlerSymbol],
576
- );
552
+ return this;
577
553
  }
578
554
 
579
- // /**
580
- // * @private
581
- // * @throws {Error} missing default slot
582
- // * @throws {Error} no shadow-root is defined
583
- // * @throws {Error} missing url
584
- // * @throws {Error} we won't be able to read the data
585
- // * @throws {Error} request failed
586
- // * @throws {Error} not found
587
- // * @throws {Error} undefined status or type
588
- // * @fires Monster.Components.TreeMenu.event:monster-fetched
589
- // */
590
- // function initIntersectionObserver() {
591
- // const self = this;
592
- //
593
- // if (self[intersectionObserverWasInitialized] === true) {
594
- // return
595
- // }
596
- //
597
- // self[intersectionObserverWasInitialized] = true;
598
- //
599
- // let options = {
600
- // threshold: [0.5]
601
- // }
602
- //
603
- // const callback = (entries, observer) => {
604
- //
605
- // for (const [, entry] of entries.entries()) {
606
- // if (entry.isIntersecting === true) {
607
- // if (!self.hasAttribute(ATTRIBUTE_FORM_RELOAD) || self.getAttribute(ATTRIBUTE_FORM_RELOAD).toLowerCase() === 'onshow') {
608
- // observer.disconnect();
609
- // }
610
- //
611
- // try {
612
- // loadContent.call(self);
613
- // } catch (e) {
614
- // self.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.toString());
615
- // }
616
- //
617
- //
618
- // }
619
- // }
620
- // }
621
- //
622
- // const observer = new IntersectionObserver(callback, options);
623
- // observer.observe(self);
624
- //
625
- //
626
- // }
627
-
628
555
  /**
629
556
  * @private
630
557
  * @return {string}
@@ -632,29 +559,31 @@ function switchToConfig() {
632
559
  function getTemplate() {
633
560
  // language=HTML
634
561
  return `
562
+ <slot></slot>
563
+
635
564
  <template id="entries">
636
565
  <div data-monster-role="entry"
637
- draggable="true"
638
566
  data-monster-attributes="
639
567
  data-monster-intend path:entries.intend,
640
568
  data-monster-state path:entries.state,
641
569
  data-monster-visibility path:entries.visibility,
642
570
  data-monster-filtered path:entries.filtered,
643
571
  data-monster-has-children path:entries.has-children">
644
-
645
- <button data-monster-role="button"
646
- data-monster-attributes="
647
- type path:type,
648
- role path:role,
649
- value path:entries.value,
650
- name path:name,
651
- part path:type | prefix:option- | suffix: form" tabindex="-1">
652
- <span data-monster-role="folder-handler"></span>
653
- <span data-monster-replace="path:entries | index:label" part="entry-label"></span>
654
- </button>
572
+ <div data-monster-role="button"
573
+ data-monster-attributes="
574
+ value path:entries.value | tostring
575
+ " tabindex="0">
576
+ <div data-monster-role="status-badges"></div>
577
+ <div data-monster-role="icon" data-monster-replace="path:entries.icon">
578
+
579
+ </div>
580
+ <div data-monster-replace="path:entries.label"
581
+ part="entry-label"
582
+ data-monster-attributes="class static:id"></div>
583
+ </div>
655
584
  </template>
656
585
 
657
- <div data-monster-role="control" part="control">
586
+ <div data-monster-role="control" part="control" data-monster-attributes="class path:classes.control">
658
587
  <div part="entries" data-monster-role="entries"
659
588
  data-monster-insert="entries path:entries"
660
589
  tabindex="-1"></div>