@schukai/monster 3.55.6 → 3.56.0

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 +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
  /**