@schukai/monster 4.91.0 → 4.92.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 CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
 
4
4
 
5
+ ## [4.92.0] - 2026-01-12
6
+
7
+ ### Add Features
8
+
9
+ - Improve data resolution in form handling [#372](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/372)
10
+
11
+
12
+
13
+ ## [4.91.1] - 2026-01-12
14
+
15
+ ### Bug Fixes
16
+
17
+ - update colums
18
+
19
+
20
+
5
21
  ## [4.91.0] - 2026-01-12
6
22
 
7
23
  ### Add Features
package/package.json CHANGED
@@ -1 +1 @@
1
- {"author":"Volker Schukai","dependencies":{"@floating-ui/dom":"^1.7.4","@popperjs/core":"^2.11.8"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"4.91.0"}
1
+ {"author":"Volker Schukai","dependencies":{"@floating-ui/dom":"^1.7.4","@popperjs/core":"^2.11.8"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"4.92.0"}
@@ -28,6 +28,7 @@ import {
28
28
  import { fireCustomEvent } from "../../dom/events.mjs";
29
29
  import { addErrorAttribute } from "../../dom/error.mjs";
30
30
  import { getDocumentTheme } from "../../dom/theme.mjs";
31
+ import { getLocaleOfDocument } from "../../dom/locale.mjs";
31
32
  import { Pathfinder } from "../../data/pathfinder.mjs";
32
33
  import { datasourceLinkedElementSymbol } from "../datatable/util.mjs";
33
34
  import { Observer } from "../../types/observer.mjs";
@@ -126,12 +127,9 @@ class RepeatFieldSet extends CustomControl {
126
127
  templates: {
127
128
  main: getTemplate(),
128
129
  },
129
- labels: {
130
- add: "Add",
131
- remove: "Remove",
132
- },
130
+ labels: getTranslations(),
133
131
  classes: {
134
- content: "collapse-alignment",
132
+ content: "collapse-alignment-no-padding",
135
133
  },
136
134
  features: {
137
135
  multipleColumns: true,
@@ -185,6 +183,56 @@ class RepeatFieldSet extends CustomControl {
185
183
  }
186
184
  }
187
185
 
186
+ /**
187
+ * @private
188
+ * @returns {object}
189
+ */
190
+ function getTranslations() {
191
+ const locale = getLocaleOfDocument();
192
+ switch (locale.language) {
193
+ case "de":
194
+ return { add: "Hinzufügen", remove: "Entfernen" };
195
+ case "fr":
196
+ return { add: "Ajouter", remove: "Supprimer" };
197
+ case "es":
198
+ return { add: "Agregar", remove: "Eliminar" };
199
+ case "zh":
200
+ return { add: "添加", remove: "删除" };
201
+ case "hi":
202
+ return { add: "जोड़ें", remove: "हटाएं" };
203
+ case "bn":
204
+ return { add: "যোগ করুন", remove: "মুছে ফেলুন" };
205
+ case "pt":
206
+ return { add: "Adicionar", remove: "Remover" };
207
+ case "ru":
208
+ return { add: "Добавить", remove: "Удалить" };
209
+ case "ja":
210
+ return { add: "追加", remove: "削除" };
211
+ case "pa":
212
+ return { add: "ਸ਼ਾਮਲ ਕਰੋ", remove: "ਹਟਾਓ" };
213
+ case "mr":
214
+ return { add: "जोडा", remove: "काढा" };
215
+ case "it":
216
+ return { add: "Aggiungi", remove: "Rimuovi" };
217
+ case "nl":
218
+ return { add: "Toevoegen", remove: "Verwijderen" };
219
+ case "sv":
220
+ return { add: "Lägg till", remove: "Ta bort" };
221
+ case "pl":
222
+ return { add: "Dodaj", remove: "Usuń" };
223
+ case "da":
224
+ return { add: "Tilføj", remove: "Fjern" };
225
+ case "fi":
226
+ return { add: "Lisää", remove: "Poista" };
227
+ case "no":
228
+ return { add: "Legg til", remove: "Fjern" };
229
+ case "cs":
230
+ return { add: "Přidat", remove: "Odebrat" };
231
+ default:
232
+ return { add: "Add", remove: "Remove" };
233
+ }
234
+ }
235
+
188
236
  /**
189
237
  * @private
190
238
  */
@@ -221,8 +269,8 @@ function ensureItemsContainer() {
221
269
  * @return {HTMLStyleElement}
222
270
  */
223
271
  function ensureItemsStyleSheet() {
224
- const root = this.ownerDocument || document;
225
- if (!("adoptedStyleSheets" in root)) {
272
+ const root = this.getRootNode?.() || this.ownerDocument || document;
273
+ if (!root || !("adoptedStyleSheets" in root)) {
226
274
  return;
227
275
  }
228
276
  const sheets = root.adoptedStyleSheets || [];
@@ -462,7 +510,6 @@ function syncInsertDefinition() {
462
510
  if (this.getAttribute(ATTRIBUTE_UPDATER_INSERT)) {
463
511
  this.removeAttribute(ATTRIBUTE_UPDATER_INSERT);
464
512
  }
465
-
466
513
  }
467
514
 
468
515
  /**
@@ -844,7 +891,10 @@ function persistItems(items, options = {}) {
844
891
  if (syncDatasource) {
845
892
  const datasourceContext = getDatasourceContext.call(this);
846
893
  const datasourceData = datasourceContext?.target?.data;
847
- if (datasourceContext && (isObject(datasourceData) || isArray(datasourceData))) {
894
+ if (
895
+ datasourceContext &&
896
+ (isObject(datasourceData) || isArray(datasourceData))
897
+ ) {
848
898
  const nextData = clone(datasourceData);
849
899
  try {
850
900
  new Pathfinder(nextData).setVia(datasourceContext.path, items);
@@ -878,7 +928,6 @@ function persistItems(items, options = {}) {
878
928
  path: context.path,
879
929
  },
880
930
  });
881
-
882
931
  }
883
932
 
884
933
  /**
@@ -985,7 +1034,6 @@ function syncOptionData() {
985
1034
  }
986
1035
  }
987
1036
  }
988
-
989
1037
  }
990
1038
 
991
1039
  /**
@@ -995,34 +1043,32 @@ function syncOptionData() {
995
1043
  * @return {object}
996
1044
  */
997
1045
  function resolveFormRecord(form, datasource) {
998
- let data = datasource?.data;
1046
+ const { data, dataPath } = resolveDatasourceBasePath(form, datasource);
999
1047
  if (!isObject(data) && !isArray(data)) {
1000
1048
  return {};
1001
1049
  }
1002
1050
 
1003
- const mappingData = form.getOption?.("mapping.data");
1004
- if (isString(mappingData) && mappingData.trim() !== "") {
1005
- try {
1006
- data = new Pathfinder(data).getVia(mappingData.trim());
1007
- } catch {
1008
- data = {};
1051
+ let resolvedData = data;
1052
+ if (isObject(resolvedData) && !isArray(resolvedData)) {
1053
+ if (isArray(resolvedData.data)) {
1054
+ resolvedData = resolvedData.data;
1055
+ } else if (isArray(resolvedData.dataset)) {
1056
+ resolvedData = resolvedData.dataset;
1057
+ } else if (dataPath === "") {
1058
+ resolvedData = Object.values(resolvedData);
1009
1059
  }
1010
1060
  }
1011
1061
 
1012
- if (isObject(data)) {
1013
- data = Object.values(data);
1014
- }
1015
-
1016
1062
  const mappingIndex = form.getOption?.("mapping.index");
1017
1063
  if (mappingIndex !== null && mappingIndex !== undefined) {
1018
- data = data?.[mappingIndex];
1064
+ resolvedData = resolvedData?.[mappingIndex];
1019
1065
  }
1020
1066
 
1021
- if (!isObject(data) && !isArray(data)) {
1067
+ if (!isObject(resolvedData) && !isArray(resolvedData)) {
1022
1068
  return {};
1023
1069
  }
1024
1070
 
1025
- return data;
1071
+ return resolvedData;
1026
1072
  }
1027
1073
 
1028
1074
  /**
@@ -1037,14 +1083,14 @@ function getDatasourceContext() {
1037
1083
  return null;
1038
1084
  }
1039
1085
 
1040
- const mappingData = form?.getOption?.("mapping.data");
1041
1086
  const mappingIndex = form?.getOption?.("mapping.index");
1087
+ const { dataPath } = resolveDatasourceBasePath(form, datasource);
1042
1088
  const record = resolveFormRecord(form, datasource);
1043
1089
  const normalizedPath = normalizePathForRecord(path, record);
1044
1090
  let basePath = "";
1045
1091
 
1046
- if (isString(mappingData) && mappingData.trim() !== "") {
1047
- basePath = mappingData.trim();
1092
+ if (isString(dataPath) && dataPath.trim() !== "") {
1093
+ basePath = dataPath.trim();
1048
1094
  }
1049
1095
 
1050
1096
  if (mappingIndex !== null && mappingIndex !== undefined) {
@@ -1056,6 +1102,42 @@ function getDatasourceContext() {
1056
1102
  return { target: datasource, path: finalPath };
1057
1103
  }
1058
1104
 
1105
+ /**
1106
+ * @private
1107
+ * @param {HTMLElement} form
1108
+ * @param {HTMLElement} datasource
1109
+ * @return {{data: object|Array, dataPath: string}}
1110
+ */
1111
+ function resolveDatasourceBasePath(form, datasource) {
1112
+ let data = datasource?.data;
1113
+ if (!isObject(data) && !isArray(data)) {
1114
+ return { data: {}, dataPath: "" };
1115
+ }
1116
+
1117
+ let dataPath = "";
1118
+ const mappingData = form?.getOption?.("mapping.data");
1119
+ if (isString(mappingData) && mappingData.trim() !== "") {
1120
+ const trimmed = mappingData.trim();
1121
+ try {
1122
+ const mapped = new Pathfinder(data).getVia(trimmed);
1123
+ if (mapped !== undefined) {
1124
+ data = mapped;
1125
+ dataPath = trimmed;
1126
+ }
1127
+ } catch {}
1128
+ }
1129
+
1130
+ if (dataPath === "" && isObject(data) && !isArray(data)) {
1131
+ if (isArray(data.data)) {
1132
+ dataPath = "data";
1133
+ } else if (isArray(data.dataset)) {
1134
+ dataPath = "dataset";
1135
+ }
1136
+ }
1137
+
1138
+ return { data, dataPath };
1139
+ }
1140
+
1059
1141
  /**
1060
1142
  * @private
1061
1143
  * @return {string}
@@ -65,6 +65,7 @@ export * from "./components/form/variant-select.mjs";
65
65
  export * from "./components/form/register-wizard.mjs";
66
66
  export * from "./components/form/action-button.mjs";
67
67
  export * from "./components/form/form.mjs";
68
+ export * from "./components/form/repeat-field-set.mjs";
68
69
  export * from "./components/form/api-button.mjs";
69
70
  export * from "./components/form/digits.mjs";
70
71
  export * from "./components/form/tree-select.mjs";
@@ -74,7 +75,6 @@ export * from "./components/form/input-group.mjs";
74
75
  export * from "./components/form/shadow-reload.mjs";
75
76
  export * from "./components/form/button.mjs";
76
77
  export * from "./components/form/field-set.mjs";
77
- export * from "./components/form/repeat-field-set.mjs";
78
78
  export * from "./components/form/toggle-switch.mjs";
79
79
  export * from "./components/form/types/state.mjs";
80
80
  export * from "./components/form/template.mjs";
@@ -156,7 +156,7 @@ function getMonsterVersion() {
156
156
  }
157
157
 
158
158
  /** don't touch, replaced by make with package.json version */
159
- monsterVersion = new Version("4.76.0");
159
+ monsterVersion = new Version("4.91.0");
160
160
 
161
161
  return monsterVersion;
162
162
  }
@@ -7,7 +7,7 @@ describe('Monster', function () {
7
7
  let monsterVersion
8
8
 
9
9
  /** don´t touch, replaced by make with package.json version */
10
- monsterVersion = new Version("4.76.0")
10
+ monsterVersion = new Version("4.91.0")
11
11
 
12
12
  let m = getMonsterVersion();
13
13
 
@@ -4,10 +4,10 @@ import "../cases/components/layout/tabs.mjs";
4
4
  import "../cases/components/layout/slit-panel.mjs";
5
5
  import "../cases/components/layout/panel.mjs";
6
6
  import "../cases/components/form/buy-box.mjs";
7
+ import "../cases/components/form/message-state-button.mjs";
7
8
  import "../cases/components/form/button-bar.mjs";
8
9
  import "../cases/components/form/reload.mjs";
9
10
  import "../cases/components/form/state-button.mjs";
10
- import "../cases/components/form/message-state-button.mjs";
11
11
  import "../cases/components/form/select.mjs";
12
12
  import "../cases/components/form/confirm-button.mjs";
13
13
  import "../cases/components/form/form.mjs";
@@ -9,8 +9,8 @@
9
9
  </head>
10
10
  <body>
11
11
  <div id="headline" style="display: flex;align-items: center;justify-content: center;flex-direction: column;">
12
- <h1 style='margin-bottom: 0.1em;'>Monster 4.76.0</h1>
13
- <div id="lastupdate" style='font-size:0.7em'>last update Mo 5. Jan 16:52:49 CET 2026</div>
12
+ <h1 style='margin-bottom: 0.1em;'>Monster 4.91.0</h1>
13
+ <div id="lastupdate" style='font-size:0.7em'>last update Mo 12. Jan 23:49:41 CET 2026</div>
14
14
  </div>
15
15
  <div id="mocha-errors"
16
16
  style="color: red;font-weight: bold;display: flex;align-items: center;justify-content: center;flex-direction: column;margin:20px;"></div>