iobroker.eos-admin 7.9.48 → 7.9.49
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/adminWww/assets/Objects-DPan0bzw.js +1 -1
- package/adminWww/assets/bootstrap-COulQZax.js +1 -1
- package/adminWww/assets/index-D2ymscJA.js +1 -1
- package/adminWww/index.html +6 -6
- package/adminWww/js/eos-branding.js +1 -1
- package/adminWww/js/eos-objects-state-tools.js +75 -69
- package/adminWww/js/eos-role-ui.js +2 -2
- package/adminWww/js/eos-security-ui.js +1 -1
- package/io-package.json +8 -4
- package/package.json +1 -1
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
(() => {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
window.NEXOWATT_EOS_OBJECTS_STATE_TOOLS_VERSION = '
|
|
4
|
+
window.NEXOWATT_EOS_OBJECTS_STATE_TOOLS_VERSION = 'v49-dp-write-performance-fix';
|
|
5
5
|
|
|
6
6
|
const ACTIVE_CLASS = 'eos-objects-surface';
|
|
7
|
-
const safe = fn => { try { return fn(); } catch (
|
|
7
|
+
const safe = fn => { try { return fn(); } catch (_) { return undefined; } };
|
|
8
8
|
|
|
9
9
|
const isObjectsRoute = () => {
|
|
10
10
|
const hash = String(window.location.hash || '');
|
|
11
11
|
if (/#tab-objects/.test(hash)) return true;
|
|
12
|
-
|
|
13
|
-
if (/[?&]tab=objects/.test(url)) return true;
|
|
14
|
-
return false;
|
|
12
|
+
return /[?&]tab=objects/.test(String(window.location.href || ''));
|
|
15
13
|
};
|
|
16
14
|
|
|
17
15
|
const setSurfaceState = () => {
|
|
@@ -52,119 +50,127 @@
|
|
|
52
50
|
'[role="tooltip"]'
|
|
53
51
|
].join(',');
|
|
54
52
|
|
|
53
|
+
const valueCellSelector = [
|
|
54
|
+
'.eos-object-value-cell',
|
|
55
|
+
'[data-eos-object-value-cell]',
|
|
56
|
+
'[title*="Wert schreiben"]',
|
|
57
|
+
'[title*="Button sofort testen"]'
|
|
58
|
+
].join(',');
|
|
59
|
+
|
|
60
|
+
const collect = (base, selector) => {
|
|
61
|
+
const out = [];
|
|
62
|
+
if (!base) return out;
|
|
63
|
+
if (base.nodeType === Node.ELEMENT_NODE && base.matches?.(selector)) out.push(base);
|
|
64
|
+
if (base.querySelectorAll) out.push(...Array.from(base.querySelectorAll(selector)));
|
|
65
|
+
return out;
|
|
66
|
+
};
|
|
67
|
+
|
|
55
68
|
const releaseNativeControls = root => safe(() => {
|
|
56
69
|
if (!setSurfaceState()) return;
|
|
57
70
|
const base = root && root.nodeType ? root : document;
|
|
58
|
-
|
|
59
|
-
if (base.nodeType === Node.ELEMENT_NODE && base.matches?.(interactiveSelector)) nodes.push(base);
|
|
60
|
-
nodes.push(...Array.from(base.querySelectorAll?.(interactiveSelector) || []));
|
|
61
|
-
nodes.forEach(el => {
|
|
71
|
+
collect(base, `${interactiveSelector},${nativeLayerSelector}`).forEach(el => {
|
|
62
72
|
if (!el || el.closest?.('#eos-assist-root,.eos-assist-root')) return;
|
|
63
73
|
el.classList?.remove('eos-security-hidden-delete', 'eos-protected-delete-control', 'eos-disabled-by-security');
|
|
64
74
|
el.removeAttribute?.('data-eos-security-blocked');
|
|
65
75
|
el.removeAttribute?.('aria-disabled');
|
|
66
|
-
el.style.pointerEvents = 'auto';
|
|
67
|
-
if (el.style
|
|
68
|
-
if (el.style
|
|
69
|
-
});
|
|
70
|
-
const layers = [];
|
|
71
|
-
if (base.nodeType === Node.ELEMENT_NODE && base.matches?.(nativeLayerSelector)) layers.push(base);
|
|
72
|
-
layers.push(...Array.from(base.querySelectorAll?.(nativeLayerSelector) || []));
|
|
73
|
-
layers.forEach(el => {
|
|
74
|
-
if (!el) return;
|
|
75
|
-
el.style.pointerEvents = 'auto';
|
|
76
|
+
if (el.style?.pointerEvents === 'none') el.style.pointerEvents = 'auto';
|
|
77
|
+
if (el.style?.visibility === 'hidden') el.style.visibility = 'visible';
|
|
78
|
+
if (el.style?.display === 'none' && !el.classList?.contains('eos-native-logout-hidden')) el.style.display = '';
|
|
76
79
|
});
|
|
77
80
|
});
|
|
78
81
|
|
|
79
|
-
const formatAge = ts => {
|
|
80
|
-
const n = Number(ts);
|
|
81
|
-
if (!Number.isFinite(n) || n <= 0) return 'unbekannt';
|
|
82
|
-
try { return new Date(n).toLocaleString(); } catch { return String(n); }
|
|
83
|
-
};
|
|
84
|
-
|
|
85
82
|
const annotateValueCells = root => safe(() => {
|
|
86
83
|
if (!setSurfaceState()) return;
|
|
87
84
|
const base = root && root.nodeType ? root : document;
|
|
88
|
-
|
|
89
|
-
const valueCellSelector = '.eos-object-value-cell,[data-eos-object-value-cell],[title*="Wert schreiben"],[title*="Button sofort testen"]';
|
|
90
|
-
if (base.nodeType === Node.ELEMENT_NODE && base.matches?.(valueCellSelector)) cells.push(base);
|
|
91
|
-
cells.push(...Array.from(base.querySelectorAll?.(valueCellSelector) || []));
|
|
92
|
-
cells.forEach(cell => {
|
|
85
|
+
collect(base, valueCellSelector).forEach(cell => {
|
|
93
86
|
const id = cell.getAttribute('data-eos-object-value-cell') || cell.closest?.('[id]')?.getAttribute('id') || '';
|
|
94
|
-
const
|
|
95
|
-
const writable = cell.getAttribute('data-eos-object-writable') === '1' || /Wert schreiben|Button sofort testen/i.test(
|
|
87
|
+
const nativeTitle = cell.getAttribute('title') || '';
|
|
88
|
+
const writable = cell.getAttribute('data-eos-object-writable') === '1' || /Wert schreiben|Button sofort testen/i.test(nativeTitle);
|
|
96
89
|
const visibleValue = (cell.textContent || '').trim().replace(/\s+/g, ' ') || '(leer)';
|
|
90
|
+
const cache = `${id}|${writable ? 1 : 0}|${visibleValue}`;
|
|
91
|
+
|
|
97
92
|
cell.style.pointerEvents = 'auto';
|
|
98
93
|
cell.style.cursor = writable ? 'pointer' : 'default';
|
|
94
|
+
cell.classList.add('eos-object-value-cell');
|
|
99
95
|
cell.classList.toggle('eos-object-value-writable', writable);
|
|
100
96
|
cell.classList.toggle('eos-object-value-readonly', !writable);
|
|
101
|
-
|
|
102
|
-
cell.
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
].filter(Boolean).join('\n'));
|
|
97
|
+
|
|
98
|
+
if (cell.getAttribute('data-eos-value-cache') !== cache) {
|
|
99
|
+
cell.setAttribute('data-eos-value-cache', cache);
|
|
100
|
+
cell.setAttribute('data-eos-current-visible-value', visibleValue);
|
|
101
|
+
const nextTitle = [
|
|
102
|
+
id ? `ID: ${id}` : null,
|
|
103
|
+
`Aktueller Wert: ${visibleValue}`,
|
|
104
|
+
`Status: ${writable ? 'beschreibbar' : 'nur lesbar'}`,
|
|
105
|
+
writable ? 'Klicken: Wert schreiben / Button sofort testen' : 'Nur lesbarer Wert'
|
|
106
|
+
].filter(Boolean).join('\n');
|
|
107
|
+
if (cell.getAttribute('title') !== nextTitle) cell.setAttribute('title', nextTitle);
|
|
108
|
+
}
|
|
114
109
|
});
|
|
115
110
|
});
|
|
116
111
|
|
|
117
|
-
const
|
|
112
|
+
const run = root => {
|
|
118
113
|
if (!setSurfaceState()) return;
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
if (cell.getAttribute('data-eos-object-writable') === '1') {
|
|
122
|
-
cell.classList.add('eos-object-value-hover');
|
|
123
|
-
}
|
|
114
|
+
releaseNativeControls(root);
|
|
115
|
+
annotateValueCells(root);
|
|
124
116
|
};
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
117
|
+
|
|
118
|
+
let scheduled = false;
|
|
119
|
+
const pendingRoots = new Set();
|
|
120
|
+
const schedule = root => {
|
|
121
|
+
if (!setSurfaceState()) return;
|
|
122
|
+
if (root) pendingRoots.add(root);
|
|
123
|
+
if (scheduled) return;
|
|
124
|
+
scheduled = true;
|
|
125
|
+
const execute = () => {
|
|
126
|
+
scheduled = false;
|
|
127
|
+
const roots = pendingRoots.size ? Array.from(pendingRoots) : [document];
|
|
128
|
+
pendingRoots.clear();
|
|
129
|
+
roots.slice(0, 60).forEach(run);
|
|
130
|
+
};
|
|
131
|
+
if ('requestIdleCallback' in window) window.requestIdleCallback(execute, { timeout: 500 });
|
|
132
|
+
else window.requestAnimationFrame(execute);
|
|
128
133
|
};
|
|
129
134
|
|
|
130
|
-
const
|
|
135
|
+
const handlePointerAssist = event => {
|
|
131
136
|
if (!setSurfaceState()) return;
|
|
132
|
-
|
|
133
|
-
|
|
137
|
+
const cell = event.target?.closest?.('.eos-object-value-cell');
|
|
138
|
+
if (cell?.getAttribute('data-eos-object-writable') === '1') cell.classList.add('eos-object-value-hover');
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const handlePointerLeave = event => {
|
|
142
|
+
event.target?.closest?.('.eos-object-value-cell')?.classList.remove('eos-object-value-hover');
|
|
134
143
|
};
|
|
135
144
|
|
|
136
|
-
window.addEventListener('hashchange', () => setTimeout(() =>
|
|
137
|
-
window.addEventListener('popstate', () => setTimeout(() =>
|
|
145
|
+
window.addEventListener('hashchange', () => window.setTimeout(() => schedule(document), 30));
|
|
146
|
+
window.addEventListener('popstate', () => window.setTimeout(() => schedule(document), 30));
|
|
138
147
|
document.addEventListener('mouseover', handlePointerAssist, true);
|
|
139
148
|
document.addEventListener('mouseout', handlePointerLeave, true);
|
|
140
149
|
document.addEventListener('click', event => {
|
|
141
150
|
if (!setSurfaceState()) return;
|
|
142
|
-
const nativeInteractive = event.target?.closest?.(interactiveSelector
|
|
151
|
+
const nativeInteractive = event.target?.closest?.(`${interactiveSelector},${nativeLayerSelector},.eos-object-value-cell`);
|
|
143
152
|
if (nativeInteractive) {
|
|
144
|
-
//
|
|
153
|
+
// Keep native React/ObjectBrowser handlers untouched; only repair stale CSS/attributes after the click.
|
|
145
154
|
releaseNativeControls(nativeInteractive);
|
|
146
|
-
window.setTimeout(() =>
|
|
147
|
-
window.setTimeout(() => annotateValueCells(document), 120);
|
|
155
|
+
window.setTimeout(() => schedule(nativeInteractive), 80);
|
|
148
156
|
}
|
|
149
157
|
}, false);
|
|
150
158
|
|
|
151
159
|
const observer = new MutationObserver(records => {
|
|
152
160
|
if (!setSurfaceState()) return;
|
|
153
|
-
let roots = [];
|
|
154
161
|
for (const rec of records) {
|
|
155
162
|
rec.addedNodes?.forEach(node => {
|
|
156
|
-
if (node.nodeType === Node.ELEMENT_NODE)
|
|
163
|
+
if (node.nodeType === Node.ELEMENT_NODE) schedule(node);
|
|
157
164
|
});
|
|
158
165
|
}
|
|
159
|
-
if (!roots.length) roots = [document];
|
|
160
|
-
window.requestAnimationFrame?.(() => roots.forEach(run)) || roots.forEach(run);
|
|
161
166
|
});
|
|
162
167
|
|
|
163
168
|
const start = () => {
|
|
164
169
|
setSurfaceState();
|
|
165
|
-
|
|
170
|
+
schedule(document);
|
|
166
171
|
observer.observe(document.documentElement, { childList: true, subtree: true });
|
|
167
|
-
|
|
172
|
+
// Low-frequency safety pass only; v45 scanned the complete page every 2.5s and hurt large object lists.
|
|
173
|
+
window.setInterval(() => schedule(document), 15000);
|
|
168
174
|
};
|
|
169
175
|
|
|
170
176
|
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', start, { once: true });
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
(() => {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
window.NEXOWATT_EOS_ROLE_UI_VERSION = '
|
|
4
|
+
window.NEXOWATT_EOS_ROLE_UI_VERSION = 'v49-dp-write-performance-fix';
|
|
5
5
|
|
|
6
6
|
const ASSET_BASE = (() => {
|
|
7
7
|
const script = document.currentScript?.src || document.querySelector('script[src*="eos-role-ui.js"]')?.src || window.location.href;
|
|
@@ -280,7 +280,7 @@
|
|
|
280
280
|
const startObserver = () => safe(() => {
|
|
281
281
|
if (state.observer || !document.documentElement) return;
|
|
282
282
|
state.observer = new MutationObserver(scheduleApply);
|
|
283
|
-
state.observer.observe(document.documentElement, { childList: true, subtree: true, attributes: true, attributeFilter: ['href', 'class', 'aria-label'
|
|
283
|
+
state.observer.observe(document.documentElement, { childList: true, subtree: true, attributes: true, attributeFilter: ['href', 'class', 'aria-label'] });
|
|
284
284
|
});
|
|
285
285
|
|
|
286
286
|
const start = () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
(() => {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
const VERSION = '
|
|
4
|
+
const VERSION = 'v49-dp-write-performance-fix';
|
|
5
5
|
const LEGACY_ADMIN = 'admin';
|
|
6
6
|
const LEGACY_ADMIN_INSTANCE = 'admin.0';
|
|
7
7
|
const CORE_PROTECTED_ADAPTERS = ['admin', 'eos-admin', 'backitup', 'nexowatt-devices', 'nexowatt-device', 'nexowatt-dev', 'nexowatt-ui'];
|
package/io-package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "eos-admin",
|
|
4
|
-
"version": "7.9.
|
|
4
|
+
"version": "7.9.49",
|
|
5
5
|
"titleLang": {
|
|
6
6
|
"en": "NexoWatt EOS Admin",
|
|
7
7
|
"de": "NexoWatt EOS Admin",
|
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
"connectionType": "local",
|
|
19
19
|
"dataSource": "push",
|
|
20
20
|
"news": {
|
|
21
|
+
"7.9.49": {
|
|
22
|
+
"en": "Reliable manual writes for writable states, corrected boolean switch handling and faster objects page updates.",
|
|
23
|
+
"de": "Zuverlässiges manuelles Beschreiben beschreibbarer Datenpunkte, korrigierte Boolean-/Switch-Behandlung und schnellere Datenpunkte-Oberfläche."
|
|
24
|
+
},
|
|
21
25
|
"7.9.48": {
|
|
22
26
|
"en": "Role guard fix: formal admin/installer/end-user roles, end-user auto-routing away from the blank intro page, and role-filtered EOS navigation.",
|
|
23
27
|
"de": "Rollen-Fix: klare Admin-/Installateur-/Endkundenrollen, automatische Endkunden-Weiterleitung weg von der leeren Intro-Seite und rollenbasierte EOS-Navigation."
|
|
@@ -251,7 +255,7 @@
|
|
|
251
255
|
"icon": "admin.svg",
|
|
252
256
|
"messagebox": true,
|
|
253
257
|
"enabled": true,
|
|
254
|
-
"extIcon": "https://unpkg.com/iobroker.eos-admin@7.9.
|
|
258
|
+
"extIcon": "https://unpkg.com/iobroker.eos-admin@7.9.49/admin/admin.svg",
|
|
255
259
|
"keywords": [
|
|
256
260
|
"NexoWatt",
|
|
257
261
|
"EOS",
|
|
@@ -262,7 +266,7 @@
|
|
|
262
266
|
"licensed"
|
|
263
267
|
],
|
|
264
268
|
"compact": true,
|
|
265
|
-
"readme": "https://unpkg.com/iobroker.eos-admin@7.9.
|
|
269
|
+
"readme": "https://unpkg.com/iobroker.eos-admin@7.9.49/README.md",
|
|
266
270
|
"authors": [
|
|
267
271
|
"bluefox <bluefox@ccu.io>",
|
|
268
272
|
"hobbyquaker <hq@ccu.io>"
|
|
@@ -331,7 +335,7 @@
|
|
|
331
335
|
"nondeletable": false,
|
|
332
336
|
"allowAdapterUpdate": true,
|
|
333
337
|
"allowAdapterDelete": false,
|
|
334
|
-
"meta": "https://unpkg.com/iobroker.eos-admin@7.9.
|
|
338
|
+
"meta": "https://unpkg.com/iobroker.eos-admin@7.9.49/io-package.json",
|
|
335
339
|
"npmPackage": "iobroker.eos-admin",
|
|
336
340
|
"packetName": "iobroker.eos-admin"
|
|
337
341
|
},
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.eos-admin",
|
|
3
3
|
"description": "NexoWatt EOS Admin interface with reliable repository update mapping and technical log preservation.",
|
|
4
|
-
"version": "7.9.
|
|
4
|
+
"version": "7.9.49",
|
|
5
5
|
"contributors": [
|
|
6
6
|
"bluefox <dogafox@gmail.com>",
|
|
7
7
|
"apollon77",
|