@schukai/monster 3.105.1 → 3.106.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
+ ## [3.106.0] - 2025-02-07
6
+
7
+ ### Add Features
8
+
9
+ - nullabel integer bind, add debug logging for save-button
10
+
11
+
12
+
13
+ ## [3.105.2] - 2025-02-06
14
+
15
+ ### Bug Fixes
16
+
17
+ - **select:** prevent lookup race condition
18
+
19
+
20
+
5
21
  ## [3.105.1] - 2025-02-06
6
22
 
7
23
  ### Bug Fixes
package/package.json CHANGED
@@ -1 +1 @@
1
- {"author":"schukai GmbH","dependencies":{"@floating-ui/dom":"^1.6.13","@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":"3.105.1"}
1
+ {"author":"schukai GmbH","dependencies":{"@floating-ui/dom":"^1.6.13","@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":"3.106.0"}
@@ -99,6 +99,8 @@ class SaveButton extends CustomElement {
99
99
  * @property {string} classes.badge The badge class
100
100
  * @property {Array} ignoreChanges The ignore changes (regex)
101
101
  * @property {Array} data The data
102
+ * @property {boolean} disabled The disabled state
103
+ * @property {string} logLevel The log level (off, debug)
102
104
  * @return {Object}
103
105
  */
104
106
  get defaults() {
@@ -125,6 +127,9 @@ class SaveButton extends CustomElement {
125
127
  data: {},
126
128
 
127
129
  disabled: false,
130
+
131
+ logLevel: "off",
132
+
128
133
  });
129
134
 
130
135
  updateOptionsFromArguments.call(this, obj);
@@ -199,6 +204,27 @@ class SaveButton extends CustomElement {
199
204
  const ignoreChanges = self.getOption("ignoreChanges");
200
205
 
201
206
  const result = diff(self[originValuesSymbol], currentValues);
207
+ if(self.getOption("logLevel") === "debug") {
208
+ console.groupCollapsed("SaveButton");
209
+ console.log(result);
210
+
211
+ if(isArray(result)&&result.length>0) {
212
+ const formattedDiff = result.map(change => ({
213
+ Operator: change?.operator,
214
+ Path: change?.path?.join("."),
215
+ "First Value": change?.first?.value,
216
+ "First Type": change?.first?.type,
217
+ "Second Value": change?.second?.value,
218
+ "Second Type": change?.second?.type
219
+ }));
220
+
221
+ console.table(formattedDiff);
222
+ } else {
223
+ console.log("There are no changes to save");
224
+ }
225
+ console.groupEnd();
226
+
227
+ }
202
228
 
203
229
  if (isArray(ignoreChanges) && ignoreChanges.length > 0) {
204
230
  const itemsToRemove = [];
@@ -221,6 +221,12 @@ const areOptionsAvailableAndInitSymbol = Symbol("@@areOptionsAvailableAndInit");
221
221
  */
222
222
  const disabledRequestMarker = Symbol("@@disabledRequestMarker");
223
223
 
224
+ /**
225
+ * @private
226
+ * @type {symbol}
227
+ */
228
+ const runLookupOnceSymbol = Symbol("runLookupOnce");
229
+
224
230
  /**
225
231
  * @private
226
232
  * @type {number}
@@ -560,7 +566,7 @@ class Select extends CustomControl {
560
566
  );
561
567
 
562
568
  areOptionsAvailableAndInit.call(self);
563
- },0);
569
+ }, 0);
564
570
 
565
571
  return this;
566
572
  }
@@ -1120,14 +1126,14 @@ function attachResizeObserver() {
1120
1126
  });
1121
1127
 
1122
1128
 
1123
- let parent = this.parentNode;
1124
- while (!(parent instanceof HTMLElement) && parent !== null) {
1125
- parent = parent.parentNode;
1126
- }
1129
+ let parent = this.parentNode;
1130
+ while (!(parent instanceof HTMLElement) && parent !== null) {
1131
+ parent = parent.parentNode;
1132
+ }
1127
1133
 
1128
- if (parent instanceof HTMLElement) {
1129
- this[resizeObserverSymbol].observe(parent);
1130
- }
1134
+ if (parent instanceof HTMLElement) {
1135
+ this[resizeObserverSymbol].observe(parent);
1136
+ }
1131
1137
 
1132
1138
  }
1133
1139
 
@@ -1352,13 +1358,13 @@ function initOptionObserver() {
1352
1358
  self.updateI18n();
1353
1359
  } catch (e) {
1354
1360
  addErrorAttribute(self, e);
1355
- setStatusOrRemoveBadges.call(self, "error");
1361
+ setStatusOrRemoveBadges.call(self, "error");
1356
1362
  }
1357
1363
  try {
1358
1364
  areOptionsAvailableAndInit.call(self);
1359
1365
  } catch (e) {
1360
1366
  addErrorAttribute(self, e);
1361
- setStatusOrRemoveBadges.call(self, "error");
1367
+ setStatusOrRemoveBadges.call(self, "error");
1362
1368
  }
1363
1369
 
1364
1370
  setSummaryAndControlText.call(self);
@@ -2246,8 +2252,8 @@ function isValueIsEmpty(value) {
2246
2252
  let equivalents = this.getOption("empty.equivalents");
2247
2253
  if (!isArray(equivalents)) {
2248
2254
  if (equivalents === undefined) {
2249
- return false;
2250
- }
2255
+ return false;
2256
+ }
2251
2257
  equivalents = [equivalents];
2252
2258
  }
2253
2259
 
@@ -2262,13 +2268,13 @@ function isValueIsEmpty(value) {
2262
2268
  */
2263
2269
  function isValueIsEmptyThenGetNormalize(value) {
2264
2270
  let emptyDefault = null
2265
- if (this.getOption("type")==="checkbox") {
2271
+ if (this.getOption("type") === "checkbox") {
2266
2272
  emptyDefault = this.getOption("empty.defaultValueCheckbox");
2267
2273
  } else {
2268
2274
  emptyDefault = this.getOption("empty.defaultValueRadio");
2269
2275
  }
2270
2276
 
2271
- if (isValueIsEmpty.call(this,value)) {
2277
+ if (isValueIsEmpty.call(this, value)) {
2272
2278
  return emptyDefault;
2273
2279
  }
2274
2280
 
@@ -2289,13 +2295,13 @@ function setSelection(selection) {
2289
2295
  selection = result?.selection;
2290
2296
  }
2291
2297
 
2292
- selection = isValueIsEmptyThenGetNormalize.call(this,selection);
2298
+ selection = isValueIsEmptyThenGetNormalize.call(this, selection);
2293
2299
  validateArray(selection);
2294
2300
 
2295
2301
  let resultSelection = [];
2296
2302
  for (let i = 0; i < selection.length; i++) {
2297
2303
 
2298
- if(isValueIsEmpty.call(this,selection[i].value)) {
2304
+ if (isValueIsEmpty.call(this, selection[i].value)) {
2299
2305
  continue
2300
2306
  }
2301
2307
 
@@ -2329,12 +2335,16 @@ function setSelection(selection) {
2329
2335
 
2330
2336
  fireEvent(this, "change"); // https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/291
2331
2337
 
2332
- const lazyLoadFlag =
2333
- this.getOption("features.lazyLoad") && this[lazyLoadDoneSymbol] !== true;
2334
- let remoteFilterFlag = getFilterMode.call(this) === FILTER_MODE_REMOTE;
2338
+ if(this[runLookupOnceSymbol] !== true && selection.length > 0) {
2339
+
2340
+ this[runLookupOnceSymbol] = true
2335
2341
 
2336
- if (lazyLoadFlag || remoteFilterFlag) {
2337
- lookupSelection.call(self);
2342
+ const lazyLoadFlag =
2343
+ this.getOption("features.lazyLoad") && this[lazyLoadDoneSymbol] !== true;
2344
+ let remoteFilterFlag = getFilterMode.call(this) === FILTER_MODE_REMOTE;
2345
+ if (lazyLoadFlag || remoteFilterFlag) {
2346
+ lookupSelection.call(self);
2347
+ }
2338
2348
  }
2339
2349
 
2340
2350
  return new Processing(() => {
@@ -2863,12 +2873,12 @@ function getTemplate() {
2863
2873
  data-monster-attributes="
2864
2874
  type path:type,
2865
2875
  role path:role,
2866
- value path:options | index:value,
2876
+ value path:options.value,
2867
2877
  name path:name,
2868
2878
  part path:type | prefix:option- | suffix: form,
2869
2879
  class path:options.class
2870
2880
  " tabindex="-1">
2871
- <div data-monster-replace="path:options | index:label"
2881
+ <div data-monster-replace="path:options.label"
2872
2882
  part="option-label"></div>
2873
2883
  </label>
2874
2884
  </div>
@@ -404,6 +404,16 @@ function retrieveAndSetValue(element) {
404
404
 
405
405
  const type = element.getAttribute(ATTRIBUTE_UPDATER_BIND_TYPE);
406
406
  switch (type) {
407
+
408
+ case "integer?":
409
+ case "int?":
410
+ case "number?":
411
+ value = Number(value);
412
+ if (isNaN(value)||0===value) {
413
+ value = undefined;
414
+ }
415
+ break;
416
+
407
417
  case "number":
408
418
  case "int":
409
419
  case "float":
@@ -238,6 +238,8 @@ function format(text) {
238
238
  throw new Error("too deep nesting");
239
239
  }
240
240
 
241
+ validateString(text);
242
+
241
243
  const openMarker =
242
244
  this[internalSymbol]["marker"]["open"]?.[this[markerOpenIndexSymbol]];
243
245
  const closeMarker =