@schukai/monster 3.71.3 → 3.73.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.
- package/CHANGELOG.md +27 -0
- package/package.json +1 -1
- package/source/components/datatable/dataset.mjs +268 -272
- package/source/components/datatable/datasource/dom.mjs +2 -2
- package/source/components/datatable/datasource/rest.mjs +408 -410
- package/source/components/datatable/filter.mjs +0 -1
- package/source/components/datatable/style/datatable.pcss +7 -5
- package/source/components/datatable/style/embedded-pagination.pcss +1 -1
- package/source/components/datatable/style/pagination.pcss +1 -1
- package/source/components/datatable/stylesheet/change-button.mjs +2 -4
- package/source/components/datatable/stylesheet/column-bar.mjs +2 -4
- package/source/components/datatable/stylesheet/dataset.mjs +2 -4
- package/source/components/datatable/stylesheet/datasource.mjs +1 -3
- package/source/components/datatable/stylesheet/datatable.mjs +2 -4
- package/source/components/datatable/stylesheet/embedded-pagination.mjs +1 -1
- package/source/components/datatable/stylesheet/filter-button.mjs +1 -3
- package/source/components/datatable/stylesheet/filter-controls-defaults.mjs +14 -7
- package/source/components/datatable/stylesheet/filter-date-range.mjs +1 -3
- package/source/components/datatable/stylesheet/filter-range.mjs +1 -3
- package/source/components/datatable/stylesheet/filter.mjs +2 -4
- package/source/components/datatable/stylesheet/pagination.mjs +2 -4
- package/source/components/datatable/stylesheet/save-button.mjs +2 -4
- package/source/components/datatable/stylesheet/select-filter.mjs +2 -4
- package/source/components/datatable/stylesheet/status.mjs +2 -4
- package/source/components/form/context-help.mjs +1 -1
- package/source/components/form/field-set.mjs +219 -219
- package/source/components/form/form.mjs +309 -185
- package/source/components/form/reload.mjs +211 -211
- package/source/components/form/select.mjs +12 -13
- package/source/components/form/style/field-set.pcss +2 -2
- package/source/components/form/style/form.pcss +8 -0
- package/source/components/form/stylesheet/action-button.mjs +2 -4
- package/source/components/form/stylesheet/api-button.mjs +1 -3
- package/source/components/form/stylesheet/button-bar.mjs +2 -4
- package/source/components/form/stylesheet/button.mjs +2 -4
- package/source/components/form/stylesheet/confirm-button.mjs +2 -4
- package/source/components/form/stylesheet/context-error.mjs +2 -4
- package/source/components/form/stylesheet/context-help.mjs +2 -4
- package/source/components/form/stylesheet/field-set.mjs +14 -7
- package/source/components/form/stylesheet/form.mjs +14 -7
- package/source/components/form/stylesheet/message-state-button.mjs +1 -3
- package/source/components/form/stylesheet/popper-button.mjs +2 -4
- package/source/components/form/stylesheet/select.mjs +14 -7
- package/source/components/form/stylesheet/state-button.mjs +2 -4
- package/source/components/form/stylesheet/tree-select.mjs +1 -3
- package/source/components/host/stylesheet/call-button.mjs +2 -4
- package/source/components/host/stylesheet/config-manager.mjs +1 -3
- package/source/components/host/stylesheet/host.mjs +2 -4
- package/source/components/host/stylesheet/overlay.mjs +2 -4
- package/source/components/host/stylesheet/toggle-button.mjs +2 -4
- package/source/components/host/stylesheet/viewer.mjs +2 -4
- package/source/components/layout/style/collapse.pcss +2 -2
- package/source/components/layout/style/details.pcss +2 -2
- package/source/components/layout/stylesheet/collapse.mjs +14 -7
- package/source/components/layout/stylesheet/details.mjs +2 -4
- package/source/components/layout/stylesheet/panel.mjs +2 -4
- package/source/components/layout/stylesheet/popper.mjs +2 -4
- package/source/components/layout/stylesheet/split-panel.mjs +1 -3
- package/source/components/layout/stylesheet/tabs.mjs +2 -4
- package/source/components/layout/stylesheet/width-toggle.mjs +1 -3
- package/source/components/layout/tabs.mjs +0 -1
- package/source/components/navigation/stylesheet/table-of-content.mjs +2 -4
- package/source/components/notify/stylesheet/message.mjs +2 -4
- package/source/components/notify/stylesheet/notify.mjs +2 -4
- package/source/components/state/stylesheet/log.mjs +2 -4
- package/source/components/state/stylesheet/state.mjs +2 -4
- package/source/components/style/control.pcss +5 -0
- package/source/components/style/data-grid.pcss +2 -2
- package/source/components/style/mixin/typography.pcss +7 -1
- package/source/components/style/normalize.pcss +1 -1
- package/source/components/stylesheet/badge.mjs +1 -3
- package/source/components/stylesheet/border.mjs +1 -3
- package/source/components/stylesheet/button.mjs +1 -3
- package/source/components/stylesheet/card.mjs +1 -3
- package/source/components/stylesheet/color.mjs +1 -3
- package/source/components/stylesheet/common.mjs +1 -3
- package/source/components/stylesheet/control.mjs +2 -4
- package/source/components/stylesheet/data-grid.mjs +2 -4
- package/source/components/stylesheet/display.mjs +1 -3
- package/source/components/stylesheet/floating-ui.mjs +1 -3
- package/source/components/stylesheet/form.mjs +13 -6
- package/source/components/stylesheet/host.mjs +1 -3
- package/source/components/stylesheet/icons.mjs +1 -3
- package/source/components/stylesheet/mixin/badge.mjs +1 -3
- package/source/components/stylesheet/mixin/button.mjs +1 -3
- package/source/components/stylesheet/mixin/form.mjs +13 -6
- package/source/components/stylesheet/mixin/hover.mjs +1 -3
- package/source/components/stylesheet/mixin/icon.mjs +1 -3
- package/source/components/stylesheet/mixin/media.mjs +1 -3
- package/source/components/stylesheet/mixin/property.mjs +13 -6
- package/source/components/stylesheet/mixin/skeleton.mjs +1 -3
- package/source/components/stylesheet/mixin/spinner.mjs +1 -3
- package/source/components/stylesheet/mixin/typography.mjs +1 -3
- package/source/components/stylesheet/normalize.mjs +1 -3
- package/source/components/stylesheet/popper.mjs +1 -3
- package/source/components/stylesheet/property.mjs +2 -4
- package/source/components/stylesheet/ripple.mjs +1 -3
- package/source/components/stylesheet/skeleton.mjs +1 -3
- package/source/components/stylesheet/space.mjs +1 -3
- package/source/components/stylesheet/spinner.mjs +1 -3
- package/source/components/stylesheet/table.mjs +1 -3
- package/source/components/stylesheet/theme.mjs +1 -3
- package/source/components/stylesheet/typography.mjs +13 -6
- package/source/components/tree-menu/dragable-tree-menu.mjs +693 -0
- package/source/components/tree-menu/style/tree-menu.pcss +69 -42
- package/source/components/tree-menu/stylesheet/tree-menu.mjs +2 -4
- package/source/components/tree-menu/tree-menu.mjs +260 -331
- package/source/data/datasource/server/restapi.mjs +194 -191
- package/source/data/datasource/server.mjs +107 -105
- package/source/data/diff.mjs +1 -1
- package/source/dom/constants.mjs +18 -0
- package/source/dom/customelement.mjs +2 -6
- package/source/dom/slotted.mjs +6 -1
- package/source/dom/updater.mjs +2 -0
- package/test/cases/components/host/details.mjs +1 -1
- package/test/cases/components/host/host.mjs +1 -1
- package/test/cases/components/host/overlay.mjs +1 -1
- package/test/cases/dom/customcontrol.mjs +1 -1
- 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 "
|
|
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 {
|
|
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
|
|
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
|
|
64
|
+
const controlElementSymbol = Symbol("controlElement");
|
|
90
65
|
|
|
91
66
|
/**
|
|
92
67
|
* @private
|
|
93
68
|
* @type {symbol}
|
|
94
69
|
*/
|
|
95
|
-
const
|
|
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.
|
|
134
|
+
* @property {String} mapping.parentKey=parent
|
|
157
135
|
* @property {String} mapping.selection
|
|
158
136
|
*/
|
|
159
137
|
get defaults() {
|
|
160
|
-
return Object.assign(
|
|
161
|
-
{
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
283
|
-
cmp(parseInt(
|
|
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
|
|
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(
|
|
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"
|
|
348
|
-
const
|
|
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
|
-
|
|
353
|
-
|
|
354
|
-
|
|
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
|
|
364
|
-
const value = formattedValues
|
|
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
|
-
|
|
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 {
|
|
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
|
|
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
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
<
|
|
653
|
-
|
|
654
|
-
|
|
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>
|