@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 +16 -0
- package/package.json +1 -1
- package/source/components/form/repeat-field-set.mjs +110 -28
- package/source/monster.mjs +1 -1
- package/source/types/version.mjs +1 -1
- package/test/cases/monster.mjs +1 -1
- package/test/web/import.js +1 -1
- package/test/web/test.html +2 -2
- package/test/web/tests.js +952 -457
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.
|
|
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 (
|
|
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
|
-
|
|
1046
|
+
const { data, dataPath } = resolveDatasourceBasePath(form, datasource);
|
|
999
1047
|
if (!isObject(data) && !isArray(data)) {
|
|
1000
1048
|
return {};
|
|
1001
1049
|
}
|
|
1002
1050
|
|
|
1003
|
-
|
|
1004
|
-
if (
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
}
|
|
1008
|
-
|
|
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
|
-
|
|
1064
|
+
resolvedData = resolvedData?.[mappingIndex];
|
|
1019
1065
|
}
|
|
1020
1066
|
|
|
1021
|
-
if (!isObject(
|
|
1067
|
+
if (!isObject(resolvedData) && !isArray(resolvedData)) {
|
|
1022
1068
|
return {};
|
|
1023
1069
|
}
|
|
1024
1070
|
|
|
1025
|
-
return
|
|
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(
|
|
1047
|
-
basePath =
|
|
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}
|
package/source/monster.mjs
CHANGED
|
@@ -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";
|
package/source/types/version.mjs
CHANGED
package/test/cases/monster.mjs
CHANGED
package/test/web/import.js
CHANGED
|
@@ -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";
|
package/test/web/test.html
CHANGED
|
@@ -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.
|
|
13
|
-
<div id="lastupdate" style='font-size:0.7em'>last update Mo
|
|
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>
|