@schukai/monster 3.55.6 → 3.56.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/package.json +2 -2
  3. package/source/components/datatable/change-button.mjs +269 -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,30 @@
1
1
 
2
+ ## [3.56.1] - 2024-02-26
3
+
4
+ ### Bug Fixes
5
+
6
+ - [3] is not the right way [#151](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/151)
7
+
8
+ ## [3.56.0] - 2024-02-26
9
+
10
+ ### Add Features
11
+
12
+ - 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)
13
+ ### Changes
14
+
15
+ - release and publish to npm new version 3.56.0
16
+ - format
17
+ - format
18
+ - [#144](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/144)
19
+
2
20
  ## [3.55.6] - 2024-01-26
3
21
 
4
22
  ### Bug Fixes
5
23
 
6
24
  - wrong font family for tab buttons [#140](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/140)
25
+ ### Changes
26
+
27
+ - release and publish to npm new version 3.55.6
7
28
 
8
29
  ## [3.55.5] - 2024-01-24
9
30
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schukai/monster",
3
- "version": "3.55.6",
3
+ "version": "3.56.1",
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,269 @@
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 {addAttributeToken} from "../../dom/attributes.mjs";
9
+ import {ATTRIBUTE_ERRORMESSAGE} from "../../dom/constants.mjs";
10
+ import {
11
+ assembleMethodSymbol,
12
+ CustomElement,
13
+ registerCustomElement,
14
+ } from "../../dom/customelement.mjs";
15
+ import { isString, isArray } from "../../types/is.mjs";
16
+ import { Observer } from "../../types/observer.mjs";
17
+ import { clone } from "../../util/clone.mjs";
18
+ import { State } from "../form/types/state.mjs";
19
+ import { ATTRIBUTE_DATASOURCE_SELECTOR } from "./constants.mjs";
20
+ import { ChangeButtonStyleSheet } from "./stylesheet/change-button.mjs";
21
+
22
+ export { ChangeButton };
23
+
24
+ /**
25
+ * @private
26
+ * @type {symbol}
27
+ */
28
+ const stateButtonElementSymbol = Symbol("stateButtonElement");
29
+
30
+ /**
31
+ * @private
32
+ * @type {symbol}
33
+ */
34
+ const datasetLinkedElementSymbol = Symbol("datasetLinkedElement");
35
+ /**
36
+ * @private
37
+ * @type {symbol}
38
+ */
39
+ const overlayLinkedElementSymbol = Symbol("overlayLinkedElement");
40
+
41
+ class ChangeButton extends CustomElement {
42
+ /**
43
+ * This method is called by the `instanceof` operator.
44
+ * @returns {symbol}
45
+ */
46
+ static get [instanceSymbol]() {
47
+ return Symbol.for(
48
+ "@schukai/monster/components/datasource/change-button@@instance",
49
+ );
50
+ }
51
+
52
+ /**
53
+ * To set the options via the html tag the attribute `data-monster-options` must be used.
54
+ * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
55
+ *
56
+ * The individual configuration values can be found in the table.
57
+ *
58
+ * @property {Object} templates Template definitions
59
+ * @property {string} templates.main Main template
60
+ * @property {object} datasource The datasource
61
+ * @property {string} datasource.selector The selector of the datasource
62
+ * @property {object} mapping The mapping
63
+ * @property {string} mapping.data The data
64
+ * @property {number} mapping.index The index
65
+ * @property {Array} data The data
66
+ * @return {Object}
67
+ */
68
+ get defaults() {
69
+ const obj = Object.assign({}, super.defaults, {
70
+ templates: {
71
+ main: getTemplate(),
72
+ },
73
+
74
+ labels: {
75
+ button: `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
76
+ class="bi bi-grid" viewBox="0 0 16 16">
77
+ <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"/>
78
+ </svg>`,
79
+ },
80
+
81
+ classes: {
82
+ bar: "monster-button-primary",
83
+ },
84
+
85
+ dataset: {
86
+ selector: null,
87
+ },
88
+
89
+ overlay: {
90
+ selector: null,
91
+ },
92
+
93
+ mapping: {
94
+ data: "dataset",
95
+ index: 0,
96
+ },
97
+
98
+ data: {},
99
+
100
+ disabled: false,
101
+ });
102
+
103
+ updateOptionsFromArguments.call(this, obj);
104
+ return obj;
105
+ }
106
+
107
+ /**
108
+ *
109
+ * @return {string}
110
+ */
111
+ static getTag() {
112
+ return "monster-datatable-change-button";
113
+ }
114
+
115
+ /**
116
+ * This method is responsible for assembling the component.
117
+ */
118
+ [assembleMethodSymbol]() {
119
+ super[assembleMethodSymbol]();;
120
+
121
+ initControlReferences.call(this);
122
+ initEventHandler.call(this);
123
+ }
124
+
125
+ /**
126
+ *
127
+ * @return [CSSStyleSheet]
128
+ */
129
+ static getCSSStyleSheet() {
130
+ return [ChangeButtonStyleSheet];
131
+ }
132
+ }
133
+
134
+ /**
135
+ * @private
136
+ * @return {Monster.Components.Datatable.Form}
137
+ */
138
+ function initControlReferences() {
139
+ if (!this.shadowRoot) {
140
+ throw new Error("no shadow-root is defined");
141
+ }
142
+
143
+ const selector = this.getOption("dataset.selector");
144
+
145
+ if (isString(selector)) {
146
+ const elements = document.querySelectorAll(selector);
147
+ if (elements.length !== 1) {
148
+ throw new Error("the selector must match exactly one element");
149
+ }
150
+
151
+ const element = elements[0];
152
+ if (!(element instanceof HTMLElement)) {
153
+ throw new TypeError("the element must be a dataset");
154
+ }
155
+
156
+ this[datasetLinkedElementSymbol] = element;
157
+ }
158
+
159
+ const selector2 = this.getOption("overlay.selector");
160
+
161
+ if (isString(selector2)) {
162
+ const elements = document.querySelectorAll(selector2);
163
+ if (elements.length !== 1) {
164
+ throw new Error("the selector must match exactly one element");
165
+ }
166
+
167
+ const element = elements[0];
168
+ if (!(element instanceof HTMLElement)) {
169
+ throw new TypeError("the element must be a overlay");
170
+ }
171
+
172
+ this[overlayLinkedElementSymbol] = element;
173
+ }
174
+
175
+ this[stateButtonElementSymbol] = this.shadowRoot.querySelector(
176
+ "[data-monster-role=state-button]",
177
+ );
178
+
179
+ if (this[stateButtonElementSymbol]) {
180
+ setTimeout(() => {
181
+ const states = {
182
+ changed: new State(
183
+ "changed",
184
+ `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-record-circle" viewBox="0 0 16 16">
185
+ <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"/>
186
+ <path d="M11 8a3 3 0 1 1-6 0 3 3 0 0 1 6 0"/>
187
+ </svg>`,
188
+ ),
189
+ };
190
+
191
+ this[stateButtonElementSymbol].removeState();
192
+ this[stateButtonElementSymbol].setOption("states", states);
193
+ this[stateButtonElementSymbol].setOption(
194
+ "labels.button",
195
+ this.getOption("labels.button"),
196
+ );
197
+ }, 1);
198
+ }
199
+
200
+ return this;
201
+ }
202
+
203
+ function getIndex() {
204
+ if (!(this instanceof HTMLElement)) {
205
+ return;
206
+ }
207
+
208
+ const row = this.closest("[data-monster-insert-reference]");
209
+ if (!row) {
210
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, "no reference found");
211
+ return;
212
+ }
213
+
214
+ const ref = row.getAttribute("data-monster-insert-reference");
215
+ if (!ref) {
216
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, "reference is missing or empty");
217
+ return;
218
+ }
219
+
220
+ const index = Number(ref.split("-").pop());
221
+ if (isNaN(index)) {
222
+ return;
223
+ }
224
+
225
+ return index;
226
+ }
227
+
228
+ /**
229
+ * @private
230
+ */
231
+ function initEventHandler() {
232
+ setTimeout(() => {
233
+ this[stateButtonElementSymbol].setOption("actions.click", () => {
234
+ const index = getIndex.call(this);
235
+
236
+ if (!isNaN(index)) {
237
+ this[datasetLinkedElementSymbol].setOption("mapping.index", index);
238
+ this[overlayLinkedElementSymbol].open();
239
+ }
240
+ });
241
+ }, 1);
242
+ }
243
+
244
+ /**
245
+ * @param {Object} options
246
+ */
247
+ function updateOptionsFromArguments(options) {
248
+ const selector = this.getAttribute(ATTRIBUTE_DATASOURCE_SELECTOR);
249
+ if (selector) {
250
+ options.datasource.selector = selector;
251
+ }
252
+ }
253
+
254
+ /**
255
+ * @private
256
+ * @return {string}
257
+ */
258
+ function getTemplate() {
259
+ // language=HTML
260
+ return `
261
+ <div data-monster-role="control" part="control"
262
+ data-monster-attributes="disabled path:disabled | if:true">
263
+ <monster-state-button data-monster-role="state-button"></monster-state-button>
264
+
265
+ </div>
266
+ `;
267
+ }
268
+
269
+ 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
  /**