@schukai/monster 3.55.6 → 3.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/package.json +2 -2
  3. package/source/components/datatable/change-button.mjs +265 -0
  4. package/source/components/datatable/dataset.mjs +76 -5
  5. package/source/components/datatable/datasource/dom.mjs +1 -1
  6. package/source/components/datatable/datasource/rest.mjs +401 -345
  7. package/source/components/datatable/datasource.mjs +8 -0
  8. package/source/components/datatable/datatable.mjs +600 -600
  9. package/source/components/datatable/filter/range.mjs +1 -3
  10. package/source/components/datatable/filter/select.mjs +1 -1
  11. package/source/components/datatable/filter.mjs +1 -3
  12. package/source/components/datatable/save-button.mjs +301 -0
  13. package/source/components/datatable/status.mjs +6 -2
  14. package/source/components/datatable/style/change-button.pcss +19 -0
  15. package/source/components/datatable/style/save-button.pcss +44 -0
  16. package/source/components/datatable/stylesheet/change-button.mjs +27 -0
  17. package/source/components/datatable/stylesheet/save-button.mjs +27 -0
  18. package/source/components/datatable/util.mjs +3 -1
  19. package/source/components/form/button-bar.mjs +3 -3
  20. package/source/components/form/button.mjs +1 -2
  21. package/source/components/form/form.mjs +1 -1
  22. package/source/components/form/message-state-button.mjs +1 -1
  23. package/source/components/form/select.mjs +1744 -1777
  24. package/source/components/form/state-button.mjs +1 -1
  25. package/source/components/form/tabs.mjs +3 -3
  26. package/source/components/form/tree-select.mjs +6 -2
  27. package/source/components/host/overlay.mjs +4 -1
  28. package/source/components/tree-menu/tree-menu.mjs +0 -1
  29. package/source/data/datasource/server/restapi.mjs +2 -3
  30. package/source/data/datasource/server.mjs +1 -1
  31. package/source/data/extend.mjs +55 -55
  32. package/source/data/pathfinder.mjs +6 -4
  33. package/source/dom/constants.mjs +9 -0
  34. package/source/dom/customelement.mjs +25 -7
  35. package/source/dom/updater.mjs +34 -3
  36. package/source/i18n/translations.mjs +1 -1
  37. package/source/monster.mjs +0 -1
  38. package/source/types/noderecursiveiterator.mjs +2 -3
  39. package/source/types/version.mjs +1 -1
  40. package/test/cases/monster.mjs +1 -1
package/CHANGELOG.md CHANGED
@@ -1,9 +1,23 @@
1
1
 
2
+ ## [3.56.0] - 2024-02-26
3
+
4
+ ### Add Features
5
+
6
+ - update datatable controls [#150](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/150) [#149](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/149) [#148](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/148) [#147](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/147) [#146](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/146) [#145](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/145)
7
+ ### Changes
8
+
9
+ - format
10
+ - format
11
+ - [#144](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/144)
12
+
2
13
  ## [3.55.6] - 2024-01-26
3
14
 
4
15
  ### Bug Fixes
5
16
 
6
17
  - wrong font family for tab buttons [#140](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/140)
18
+ ### Changes
19
+
20
+ - release and publish to npm new version 3.55.6
7
21
 
8
22
  ## [3.55.5] - 2024-01-24
9
23
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schukai/monster",
3
- "version": "3.55.6",
3
+ "version": "3.56.0",
4
4
  "description": "Monster is a simple library for creating fast, robust and lightweight websites.",
5
5
  "keywords": [
6
6
  "framework",
@@ -40,7 +40,7 @@
40
40
  "author": "schukai GmbH",
41
41
  "license": "AGPL 3.0",
42
42
  "dependencies": {
43
- "@floating-ui/dom": "^1.5.4",
43
+ "@floating-ui/dom": "^1.6.3",
44
44
  "@popperjs/core": "^2.11.8",
45
45
  "vite-plugin-directory-index": "^3.0.1"
46
46
  }
@@ -0,0 +1,265 @@
1
+ /**
2
+ * Copyright 2023 schukai GmbH
3
+ * SPDX-License-Identifier: AGPL-3.0
4
+ */
5
+
6
+ import { instanceSymbol } from "../../constants.mjs";
7
+ import { diff } from "../../data/diff.mjs";
8
+ import {
9
+ assembleMethodSymbol,
10
+ CustomElement,
11
+ registerCustomElement,
12
+ } from "../../dom/customelement.mjs";
13
+ import { isString, isArray } from "../../types/is.mjs";
14
+ import { Observer } from "../../types/observer.mjs";
15
+ import { clone } from "../../util/clone.mjs";
16
+ import { State } from "../form/types/state.mjs";
17
+ import { ATTRIBUTE_DATASOURCE_SELECTOR } from "./constants.mjs";
18
+ import { ChangeButtonStyleSheet } from "./stylesheet/change-button.mjs";
19
+
20
+ export { ChangeButton };
21
+
22
+ /**
23
+ * @private
24
+ * @type {symbol}
25
+ */
26
+ const stateButtonElementSymbol = Symbol("stateButtonElement");
27
+
28
+ /**
29
+ * @private
30
+ * @type {symbol}
31
+ */
32
+ const datasetLinkedElementSymbol = Symbol("datasetLinkedElement");
33
+ /**
34
+ * @private
35
+ * @type {symbol}
36
+ */
37
+ const overlayLinkedElementSymbol = Symbol("overlayLinkedElement");
38
+
39
+ class ChangeButton extends CustomElement {
40
+ /**
41
+ * This method is called by the `instanceof` operator.
42
+ * @returns {symbol}
43
+ */
44
+ static get [instanceSymbol]() {
45
+ return Symbol.for(
46
+ "@schukai/monster/components/datasource/change-button@@instance",
47
+ );
48
+ }
49
+
50
+ /**
51
+ * To set the options via the html tag the attribute `data-monster-options` must be used.
52
+ * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
53
+ *
54
+ * The individual configuration values can be found in the table.
55
+ *
56
+ * @property {Object} templates Template definitions
57
+ * @property {string} templates.main Main template
58
+ * @property {object} datasource The datasource
59
+ * @property {string} datasource.selector The selector of the datasource
60
+ * @property {object} mapping The mapping
61
+ * @property {string} mapping.data The data
62
+ * @property {number} mapping.index The index
63
+ * @property {Array} data The data
64
+ * @return {Object}
65
+ */
66
+ get defaults() {
67
+ const obj = Object.assign({}, super.defaults, {
68
+ templates: {
69
+ main: getTemplate(),
70
+ },
71
+
72
+ labels: {
73
+ button: `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
74
+ class="bi bi-grid" viewBox="0 0 16 16">
75
+ <path d="M1 2.5A1.5 1.5 0 0 1 2.5 1h3A1.5 1.5 0 0 1 7 2.5v3A1.5 1.5 0 0 1 5.5 7h-3A1.5 1.5 0 0 1 1 5.5zM2.5 2a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5zm6.5.5A1.5 1.5 0 0 1 10.5 1h3A1.5 1.5 0 0 1 15 2.5v3A1.5 1.5 0 0 1 13.5 7h-3A1.5 1.5 0 0 1 9 5.5zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5zM1 10.5A1.5 1.5 0 0 1 2.5 9h3A1.5 1.5 0 0 1 7 10.5v3A1.5 1.5 0 0 1 5.5 15h-3A1.5 1.5 0 0 1 1 13.5zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5zm6.5.5A1.5 1.5 0 0 1 10.5 9h3a1.5 1.5 0 0 1 1.5 1.5v3a1.5 1.5 0 0 1-1.5 1.5h-3A1.5 1.5 0 0 1 9 13.5zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5z"/>
76
+ </svg>`,
77
+ },
78
+
79
+ classes: {
80
+ bar: "monster-button-primary",
81
+ },
82
+
83
+ dataset: {
84
+ selector: null,
85
+ },
86
+
87
+ overlay: {
88
+ selector: null,
89
+ },
90
+
91
+ mapping: {
92
+ data: "dataset",
93
+ index: 0,
94
+ },
95
+
96
+ data: {},
97
+
98
+ disabled: false,
99
+ });
100
+
101
+ updateOptionsFromArguments.call(this, obj);
102
+ return obj;
103
+ }
104
+
105
+ /**
106
+ *
107
+ * @return {string}
108
+ */
109
+ static getTag() {
110
+ return "monster-datatable-change-button";
111
+ }
112
+
113
+ /**
114
+ * This method is responsible for assembling the component.
115
+ */
116
+ [assembleMethodSymbol]() {
117
+ super[assembleMethodSymbol]();;
118
+
119
+ initControlReferences.call(this);
120
+ initEventHandler.call(this);
121
+ }
122
+
123
+ /**
124
+ *
125
+ * @return [CSSStyleSheet]
126
+ */
127
+ static getCSSStyleSheet() {
128
+ return [ChangeButtonStyleSheet];
129
+ }
130
+ }
131
+
132
+ /**
133
+ * @private
134
+ * @return {Monster.Components.Datatable.Form}
135
+ */
136
+ function initControlReferences() {
137
+ if (!this.shadowRoot) {
138
+ throw new Error("no shadow-root is defined");
139
+ }
140
+
141
+ const selector = this.getOption("dataset.selector");
142
+
143
+ if (isString(selector)) {
144
+ const elements = document.querySelectorAll(selector);
145
+ if (elements.length !== 1) {
146
+ throw new Error("the selector must match exactly one element");
147
+ }
148
+
149
+ const element = elements[0];
150
+ if (!(element instanceof HTMLElement)) {
151
+ throw new TypeError("the element must be a dataset");
152
+ }
153
+
154
+ this[datasetLinkedElementSymbol] = element;
155
+ }
156
+
157
+ const selector2 = this.getOption("overlay.selector");
158
+
159
+ if (isString(selector2)) {
160
+ const elements = document.querySelectorAll(selector2);
161
+ if (elements.length !== 1) {
162
+ throw new Error("the selector must match exactly one element");
163
+ }
164
+
165
+ const element = elements[0];
166
+ if (!(element instanceof HTMLElement)) {
167
+ throw new TypeError("the element must be a overlay");
168
+ }
169
+
170
+ this[overlayLinkedElementSymbol] = element;
171
+ }
172
+
173
+ this[stateButtonElementSymbol] = this.shadowRoot.querySelector(
174
+ "[data-monster-role=state-button]",
175
+ );
176
+
177
+ if (this[stateButtonElementSymbol]) {
178
+ setTimeout(() => {
179
+ const states = {
180
+ changed: new State(
181
+ "changed",
182
+ `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-record-circle" viewBox="0 0 16 16">
183
+ <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/>
184
+ <path d="M11 8a3 3 0 1 1-6 0 3 3 0 0 1 6 0"/>
185
+ </svg>`,
186
+ ),
187
+ };
188
+
189
+ this[stateButtonElementSymbol].removeState();
190
+ this[stateButtonElementSymbol].setOption("states", states);
191
+ this[stateButtonElementSymbol].setOption(
192
+ "labels.button",
193
+ this.getOption("labels.button"),
194
+ );
195
+ }, 1);
196
+ }
197
+
198
+ return this;
199
+ }
200
+
201
+ function getIndex() {
202
+ if (!(this instanceof HTMLElement)) {
203
+ return;
204
+ }
205
+
206
+ const row = this.closest("[data-monster-insert-reference]");
207
+ if (!row) {
208
+ return;
209
+ }
210
+
211
+ const ref = row.getAttribute("data-monster-insert-reference");
212
+ if (!ref) {
213
+ return;
214
+ }
215
+
216
+ const index = Number(ref.split("-")[3]);
217
+ if (isNaN(index)) {
218
+ return;
219
+ }
220
+
221
+ return index;
222
+ }
223
+
224
+ /**
225
+ * @private
226
+ */
227
+ function initEventHandler() {
228
+ setTimeout(() => {
229
+ this[stateButtonElementSymbol].setOption("actions.click", () => {
230
+ const index = getIndex.call(this);
231
+
232
+ if (!isNaN(index)) {
233
+ this[datasetLinkedElementSymbol].setOption("mapping.index", index);
234
+ this[overlayLinkedElementSymbol].open();
235
+ }
236
+ });
237
+ }, 1);
238
+ }
239
+
240
+ /**
241
+ * @param {Object} options
242
+ */
243
+ function updateOptionsFromArguments(options) {
244
+ const selector = this.getAttribute(ATTRIBUTE_DATASOURCE_SELECTOR);
245
+ if (selector) {
246
+ options.datasource.selector = selector;
247
+ }
248
+ }
249
+
250
+ /**
251
+ * @private
252
+ * @return {string}
253
+ */
254
+ function getTemplate() {
255
+ // language=HTML
256
+ return `
257
+ <div data-monster-role="control" part="control"
258
+ data-monster-attributes="disabled path:disabled | if:true">
259
+ <monster-state-button data-monster-role="state-button"></monster-state-button>
260
+
261
+ </div>
262
+ `;
263
+ }
264
+
265
+ registerCustomElement(ChangeButton);
@@ -3,7 +3,10 @@
3
3
  * SPDX-License-Identifier: AGPL-3.0
4
4
  */
5
5
 
6
- import { instanceSymbol } from "../../constants.mjs";
6
+ import { instanceSymbol, internalSymbol } from "../../constants.mjs";
7
+ import { Pathfinder } from "../../data/pathfinder.mjs";
8
+ import { getLinkedObjects, hasObjectLink } from "../../dom/attributes.mjs";
9
+ import { customElementUpdaterLinkSymbol } from "../../dom/constants.mjs";
7
10
  import {
8
11
  assembleMethodSymbol,
9
12
  CustomElement,
@@ -12,6 +15,7 @@ import {
12
15
  } from "../../dom/customelement.mjs";
13
16
  import { isString } from "../../types/is.mjs";
14
17
  import { Observer } from "../../types/observer.mjs";
18
+ import { clone } from "../../util/clone.mjs";
15
19
  import {
16
20
  ATTRIBUTE_DATASOURCE_SELECTOR,
17
21
  ATTRIBUTE_DATATABLE_INDEX,
@@ -22,6 +26,7 @@ import {
22
26
  handleDataSourceChanges,
23
27
  datasourceLinkedElementSymbol,
24
28
  } from "./util.mjs";
29
+ import { FormStyleSheet } from "../stylesheet/form.mjs";
25
30
 
26
31
  export { DataSet };
27
32
 
@@ -95,6 +100,11 @@ class DataSet extends CustomElement {
95
100
  * @property {Object} templates Template definitions
96
101
  * @property {string} templates.main Main template
97
102
  * @property {object} datasource The datasource
103
+ * @property {string} datasource.selector The selector of the datasource
104
+ * @property {object} mapping The mapping
105
+ * @property {string} mapping.data The data
106
+ * @property {number} mapping.index The index
107
+ * @property {Array} data The data
98
108
  */
99
109
  get defaults() {
100
110
  const obj = Object.assign({}, super.defaults, {
@@ -111,7 +121,7 @@ class DataSet extends CustomElement {
111
121
  index: 0,
112
122
  },
113
123
 
114
- data: [],
124
+ data: {},
115
125
  });
116
126
 
117
127
  updateOptionsFromArguments.call(this, obj);
@@ -126,9 +136,70 @@ class DataSet extends CustomElement {
126
136
  return "monster-dataset";
127
137
  }
128
138
 
139
+ write() {;
140
+
141
+ return new Promise((resolve, reject) => {
142
+ if (!this[datasourceLinkedElementSymbol]) {
143
+ reject(new Error("No datasource"));
144
+ return;
145
+ }
146
+
147
+ const internalUpdateCloneData = this.getInternalUpdateCloneData();
148
+ if (!internalUpdateCloneData) {
149
+ reject(new Error("No update data"));
150
+ return;
151
+ }
152
+
153
+ const internalData = internalUpdateCloneData?.["data"];
154
+ if (
155
+ internalData === undefined ||
156
+ internalData === null ||
157
+ internalData === ""
158
+ ) {
159
+ reject(new Error("No data"));
160
+ return;
161
+ }
162
+
163
+ setTimeout(() => {
164
+ const path = this.getOption("mapping.data");
165
+ const index = this.getOption("mapping.index");
166
+
167
+ let pathWithIndex;
168
+
169
+ if (isString(path) && path !== "") {
170
+ pathWithIndex = path + "." + index;
171
+ } else {
172
+ pathWithIndex = index;
173
+ }
174
+
175
+ const data = this[datasourceLinkedElementSymbol].data;
176
+ const unref = JSON.stringify(data);
177
+ const ref = JSON.parse(unref);
178
+
179
+ new Pathfinder(ref).setVia(pathWithIndex, internalData);
180
+
181
+ this[datasourceLinkedElementSymbol].data = ref;
182
+
183
+ resolve();
184
+ }, 0);
185
+ });
186
+ }
187
+
129
188
  /**
189
+ * This method is responsible for assembling the component.
190
+ *
191
+ * It calls the parent's assemble method first, then initializes control references and event handlers.
192
+ * If the `datasource.selector` option is provided and is a string, it searches for the corresponding
193
+ * element in the DOM using that selector.
194
+ *
195
+ * If the selector matches exactly one element, it checks if the element is an instance of the `Datasource` class.
196
+ *
197
+ * If it is, the component's `datasourceLinkedElementSymbol` property is set to the element, and the component
198
+ * attaches an observer to the datasource's changes.
130
199
  *
131
- * @return {Monster.Components.Form.Form}
200
+ * The observer is a function that calls the `handleDataSourceChanges` method in the context of the component.
201
+ * Additionally, the component attaches an observer to itself, which also calls the `handleDataSourceChanges`
202
+ * method in the component's context.
132
203
  */
133
204
  [assembleMethodSymbol]() {
134
205
  super[assembleMethodSymbol]();
@@ -167,7 +238,7 @@ class DataSet extends CustomElement {
167
238
  * @return [CSSStyleSheet]
168
239
  */
169
240
  static getCSSStyleSheet() {
170
- return [DatasetStyleSheet];
241
+ return [FormStyleSheet, DatasetStyleSheet];
171
242
  }
172
243
  }
173
244
 
@@ -185,7 +256,7 @@ function initEventHandler() {
185
256
 
186
257
  /**
187
258
  *
188
- * @param {Onject} options
259
+ * @param {Object} options
189
260
  */
190
261
  function updateOptionsFromArguments(options) {
191
262
  const index = this.getAttribute(ATTRIBUTE_DATATABLE_INDEX);
@@ -46,7 +46,7 @@ class Dom extends Datasource {
46
46
  * @returns {symbol}
47
47
  */
48
48
  static get [instanceSymbol]() {
49
- return Symbol.for("@schukai/monster/components/datasource/dom");
49
+ return Symbol.for("@schukai/monster/components/datasource/dom@@instance");
50
50
  }
51
51
 
52
52
  /**