iobroker.mywebui 1.37.37 → 1.37.38

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/io-package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "mywebui",
4
- "version": "1.37.37",
4
+ "version": "1.37.38",
5
5
  "titleLang": {
6
6
  "en": "mywebui",
7
7
  "de": "mywebui",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.mywebui",
3
- "version": "1.37.37",
3
+ "version": "1.37.38",
4
4
  "description": "ioBroker mywebui - Custom edited mywebui by gokturk413",
5
5
  "type": "module",
6
6
  "main": "dist/backend/main.js",
@@ -404,9 +404,23 @@ export class IobrokerWebuiAppShell extends BaseCustomWebComponentConstructorAppe
404
404
  const designItem = selectedItems[0];
405
405
  const element = designItem.element;
406
406
 
407
- // Read existing signal from data-visibility-signal (NOT bind-prop:hidden)
408
- const existingSignal = element.getAttribute('data-visibility-signal') || null;
409
- const existingBinding = existingSignal ? { signal: existingSignal, target: 'property' } : null;
407
+ // Read existing signal from data-visibility-signal (may be plain signal string or JSON with signal+expression)
408
+ const existingSignalAttr = element.getAttribute('data-visibility-signal') || null;
409
+ let existingSignal = existingSignalAttr;
410
+ let existingBinding = null;
411
+ if (existingSignalAttr) {
412
+ if (existingSignalAttr.startsWith('{')) {
413
+ try {
414
+ const parsed = JSON.parse(existingSignalAttr);
415
+ existingSignal = parsed.signal || existingSignalAttr;
416
+ existingBinding = { ...parsed, target: 'property' };
417
+ } catch (e) {
418
+ existingBinding = { signal: existingSignalAttr, target: 'property' };
419
+ }
420
+ } else {
421
+ existingBinding = { signal: existingSignalAttr, target: 'property' };
422
+ }
423
+ }
410
424
 
411
425
  // Read group access control config from data attributes
412
426
  const dataConfig = {
@@ -436,11 +450,18 @@ export class IobrokerWebuiAppShell extends BaseCustomWebComponentConstructorAppe
436
450
  dlg.close();
437
451
  const signal = dynEdt.objectNames;
438
452
  if (signal) {
439
- designItem.setAttribute('data-visibility-signal', signal);
453
+ const bnd = { signal };
454
+ if (dynEdt.expression) bnd.expression = dynEdt.expression;
455
+ if (dynEdt.inverted) bnd.inverted = true;
456
+ if (dynEdt.twoWay) bnd.twoWay = true;
457
+ const attrValue = (bnd.expression || bnd.inverted || bnd.twoWay)
458
+ ? JSON.stringify(bnd)
459
+ : signal;
460
+ designItem.setAttribute('data-visibility-signal', attrValue);
440
461
  } else {
441
462
  designItem.removeAttribute('data-visibility-signal');
442
463
  }
443
- designItem.removeAttribute('bind-prop:hidden'); // clean up old approach
464
+ designItem.removeAttribute('bind-prop:hidden');
444
465
  this._updateVisibilityPanel();
445
466
  });
446
467
  };
@@ -449,13 +470,11 @@ export class IobrokerWebuiAppShell extends BaseCustomWebComponentConstructorAppe
449
470
  const bindRow = document.createElement('div');
450
471
  bindRow.style.cssText = 'display:flex;align-items:center;gap:6px;padding:4px 0;margin-bottom:10px;padding-bottom:10px;border-bottom:1px solid #ddd;';
451
472
 
452
- // button on the LEFT (like Properties panel style)
453
- const bindBtn = document.createElement('button');
454
- bindBtn.textContent = '';
455
- bindBtn.title = 'Right-click for binding options';
456
- bindBtn.style.cssText = existingSignal
457
- ? 'width:16px;height:16px;padding:0;font-size:11px;line-height:1;border:1px solid #888;background:#ffd700;cursor:pointer;flex-shrink:0;'
458
- : 'width:16px;height:16px;padding:0;font-size:11px;line-height:1;border:1px solid #888;background:#f0f0f0;cursor:pointer;flex-shrink:0;';
473
+ // Bind indicator styled exactly like PropertyGridPropertyList's isSetElement
474
+ const bindBtn = document.createElement('div');
475
+ bindBtn.title = existingSignal ? 'Visibility: ' + existingSignal + ' (click / right-click)' : 'Click to bind visibility signal';
476
+ bindBtn.style.cssText = 'width:7px;height:7px;border:1px solid white;cursor:pointer;flex-shrink:0;box-sizing:border-box;'
477
+ + (existingSignal ? 'background:orange;' : 'background:transparent;');
459
478
 
460
479
  bindBtn.onclick = openVisibilityBindingEditor;
461
480
 
@@ -44,11 +44,28 @@ class VisibilityService {
44
44
 
45
45
  // Step 2: Signal/state check (if objectId configured)
46
46
  if (visibilityConfig.objectId) {
47
+ // objectId may be a plain signal string or JSON like {"signal":"...","expression":"..."}
48
+ let signalId = visibilityConfig.objectId;
49
+ let expression = null;
50
+ if (typeof signalId === 'string' && signalId.startsWith('{')) {
51
+ try {
52
+ const parsed = JSON.parse(signalId);
53
+ signalId = parsed.signal || signalId;
54
+ expression = parsed.expression || null;
55
+ } catch (e) { /* keep raw */ }
56
+ }
57
+
47
58
  let stateVal = currentStateVal;
48
59
  if (stateVal === undefined) {
49
- const state = await iobrokerHandler.connection.getState(visibilityConfig.objectId);
60
+ const state = await iobrokerHandler.connection.getState(signalId);
50
61
  stateVal = state?.val;
51
62
  }
63
+
64
+ // Evaluate expression if present (same pattern as bind-content:text)
65
+ if (expression) {
66
+ try { stateVal = new Function('__0', expression)(stateVal); } catch (e) { console.warn('[Visibility] Expression error:', e); }
67
+ }
68
+
52
69
  // Truthy state value → apply action
53
70
  const isActive = stateVal !== null && stateVal !== undefined && stateVal !== false && stateVal !== 0 && stateVal !== '';
54
71
  this.#applyResult(element, isActive
@@ -75,7 +92,11 @@ class VisibilityService {
75
92
  await this.#checkAndApply(element, visibilityConfig, undefined);
76
93
 
77
94
  if (visibilityConfig.objectId) {
78
- await iobrokerHandler.subscribeState(visibilityConfig.objectId, (_id, state) => {
95
+ let signalId = visibilityConfig.objectId;
96
+ if (typeof signalId === 'string' && signalId.startsWith('{')) {
97
+ try { signalId = JSON.parse(signalId).signal || signalId; } catch (e) { /* keep raw */ }
98
+ }
99
+ await iobrokerHandler.subscribeState(signalId, (_id, state) => {
79
100
  this.#checkAndApply(element, visibilityConfig, state?.val);
80
101
  });
81
102
  }