iobroker.eos-admin 7.9.67 → 7.9.69

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.
Files changed (30) hide show
  1. package/adminWww/assets/bootstrap-COulQZax-v54.js +1 -2
  2. package/adminWww/assets/bootstrap-COulQZax-v55.js +1 -2
  3. package/adminWww/assets/bootstrap-COulQZax-v56.js +1 -2
  4. package/adminWww/assets/bootstrap-COulQZax-v57.js +1 -2
  5. package/adminWww/assets/bootstrap-COulQZax-v58.js +1 -2
  6. package/adminWww/assets/bootstrap-COulQZax-v59.js +1 -2
  7. package/adminWww/assets/bootstrap-COulQZax-v60.js +1 -2
  8. package/adminWww/assets/bootstrap-COulQZax-v61.js +1 -1
  9. package/adminWww/assets/bootstrap-COulQZax-v67.js +1 -317
  10. package/adminWww/assets/bootstrap-COulQZax-v68.js +1 -0
  11. package/adminWww/assets/bootstrap-COulQZax-v69.js +317 -0
  12. package/adminWww/assets/bootstrap-COulQZax.js +1 -2
  13. package/adminWww/assets/index-CQZugZ1z-v55.js +1 -1
  14. package/adminWww/assets/index-CQZugZ1z-v56.js +1 -1
  15. package/adminWww/assets/index-CQZugZ1z-v57.js +1 -1
  16. package/adminWww/assets/index-CQZugZ1z-v58.js +1 -1
  17. package/adminWww/assets/index-CQZugZ1z-v59.js +1 -1
  18. package/adminWww/assets/index-CQZugZ1z-v60.js +1 -2
  19. package/adminWww/assets/index-CQZugZ1z-v61.js +1 -2
  20. package/adminWww/assets/index-CQZugZ1z-v67.js +1 -2
  21. package/adminWww/assets/index-CQZugZ1z-v68.js +1 -0
  22. package/adminWww/assets/index-CQZugZ1z-v69.js +2 -0
  23. package/adminWww/assets/index-CQZugZ1z.js +1 -1
  24. package/adminWww/css/eos-branding.css +3 -114
  25. package/adminWww/index.html +11 -10
  26. package/adminWww/js/eos-branding.js +114 -157
  27. package/adminWww/js/eos-toolbar-ghost-cleanup.js +102 -0
  28. package/io-package.json +5 -5
  29. package/package.json +1 -1
  30. package/tools/nexowatt-validate-package.cjs +15 -17
@@ -0,0 +1,102 @@
1
+ (() => {
2
+ 'use strict';
3
+
4
+ window.NEXOWATT_EOS_TOOLBAR_CLEANUP_VERSION = 'v69-v57-header-restore';
5
+
6
+ const PRIMARY_SELECTOR = '.eos-brand-badge, .eos-system-brand, [data-eos-primary-brand="true"]';
7
+ const HIDDEN_CLASS = 'eos-native-compact-identity-hidden';
8
+
9
+ const hide = element => {
10
+ if (!element || element.matches?.(PRIMARY_SELECTOR) || element.closest?.(PRIMARY_SELECTOR) || element.querySelector?.(PRIMARY_SELECTOR)) return;
11
+ const text = `${element.textContent || ''} ${element.getAttribute?.('aria-label') || ''} ${element.getAttribute?.('title') || ''}`.toLowerCase();
12
+ if (text.includes('nexowatt eos') || text.includes('energy operation system')) return;
13
+ element.classList.add(HIDDEN_CLASS);
14
+ element.setAttribute('aria-hidden', 'true');
15
+ element.setAttribute('inert', '');
16
+ element.querySelectorAll?.('a,button,[role="button"],input,select,textarea').forEach(control => {
17
+ control.setAttribute('tabindex', '-1');
18
+ control.setAttribute('aria-hidden', 'true');
19
+ });
20
+ };
21
+
22
+ const directChild = (container, node) => {
23
+ let current = node;
24
+ while (current?.parentElement && current.parentElement !== container) current = current.parentElement;
25
+ return current?.parentElement === container ? current : null;
26
+ };
27
+
28
+ const cleanToolbar = toolbar => {
29
+ if (!toolbar) return;
30
+ const children = Array.from(toolbar.children || []);
31
+ children.forEach((child, index) => {
32
+ if (!child?.querySelector || child.matches(PRIMARY_SELECTOR) || child.querySelector(PRIMARY_SELECTOR)) return;
33
+ const easy = child.querySelector('a[href*="#easy"], a[href*="/easy"]');
34
+ if (!easy) return;
35
+ hide(child);
36
+
37
+ const previous = children[index - 1];
38
+ if (previous && !previous.matches(PRIMARY_SELECTOR) && !previous.querySelector?.(PRIMARY_SELECTOR)) {
39
+ const rect = previous.getBoundingClientRect?.();
40
+ const isSmallControl = previous.matches?.('button,.MuiIconButton-root') || !!previous.querySelector?.('button,.MuiIconButton-root');
41
+ const hasMenuOrChevron = !!previous.querySelector?.('svg[data-testid="MenuIcon"],svg[data-testid="ChevronLeftIcon"],svg[data-testid="ChevronRightIcon"]');
42
+ if (isSmallControl && (hasMenuOrChevron || !rect || (rect.width <= 72 && rect.height <= 72))) hide(previous);
43
+ }
44
+ });
45
+ };
46
+
47
+ const cleanDrawer = drawer => {
48
+ if (!drawer) return;
49
+ drawer.querySelectorAll('a[href*="#easy"], a[href*="/easy"]').forEach(link => {
50
+ const child = directChild(drawer, link);
51
+ if (!child || child.classList?.contains('MuiList-root') || child.querySelector?.('.MuiListItemButton-root')) return;
52
+ hide(child);
53
+ });
54
+ };
55
+
56
+ const cleanByGeometry = () => {
57
+ if (!window.matchMedia('(min-width: 901px)').matches) return;
58
+ document.querySelectorAll('a[href*="#easy"], a[href*="/easy"]').forEach(link => {
59
+ if (link.closest(PRIMARY_SELECTOR)) return;
60
+ const rect = link.getBoundingClientRect?.();
61
+ const alt = Array.from(link.querySelectorAll?.('img') || []).map(img => img.alt || '').join(' ').toLowerCase();
62
+ const text = `${link.textContent || ''} ${alt}`.trim().toLowerCase();
63
+ if (!rect || rect.top > 105 || rect.left > 240 || rect.width > 220 || rect.height > 90) return;
64
+ if (text.includes('nexowatt eos') || text.includes('energy operation system')) return;
65
+ let candidate = link;
66
+ for (let i = 0; i < 5 && candidate.parentElement; i += 1) {
67
+ const parent = candidate.parentElement;
68
+ if (parent.matches(PRIMARY_SELECTOR) || parent.querySelector(PRIMARY_SELECTOR)) break;
69
+ const r = parent.getBoundingClientRect?.();
70
+ if (!r || r.top > 105 || r.left > 240 || r.width > 240 || r.height > 95) break;
71
+ candidate = parent;
72
+ if (parent.matches('.MuiToolbar-root,.MuiDrawer-paper,.MuiAppBar-root')) break;
73
+ }
74
+ if (!candidate.matches('.MuiToolbar-root,.MuiDrawer-paper,.MuiAppBar-root')) hide(candidate);
75
+ });
76
+ };
77
+
78
+ let scheduled = false;
79
+ const run = () => {
80
+ scheduled = false;
81
+ if (!document.getElementById('app-paper')) return;
82
+ document.querySelectorAll('.MuiAppBar-root .MuiToolbar-root, header .MuiToolbar-root').forEach(cleanToolbar);
83
+ document.querySelectorAll('.MuiDrawer-paper, .MuiSwipeableDrawer-paper').forEach(cleanDrawer);
84
+ cleanByGeometry();
85
+ };
86
+ const schedule = () => {
87
+ if (scheduled) return;
88
+ scheduled = true;
89
+ requestAnimationFrame(run);
90
+ };
91
+
92
+ if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', schedule, { once: true });
93
+ else schedule();
94
+
95
+ const observer = new MutationObserver(schedule);
96
+ observer.observe(document.documentElement, { childList: true, subtree: true });
97
+ window.addEventListener('resize', schedule, { passive: true });
98
+ window.addEventListener('hashchange', schedule, { passive: true });
99
+ setTimeout(schedule, 250);
100
+ setTimeout(schedule, 1000);
101
+ setTimeout(schedule, 3000);
102
+ })();
package/io-package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "eos-admin",
4
- "version": "7.9.67",
4
+ "version": "7.9.69",
5
5
  "titleLang": {
6
6
  "en": "NexoWatt EOS Admin",
7
7
  "de": "NexoWatt EOS Admin",
@@ -259,7 +259,7 @@
259
259
  "icon": "admin.svg",
260
260
  "messagebox": true,
261
261
  "enabled": true,
262
- "extIcon": "https://unpkg.com/iobroker.eos-admin@7.9.67/admin/admin.svg",
262
+ "extIcon": "https://unpkg.com/iobroker.eos-admin@7.9.69/admin/admin.svg",
263
263
  "keywords": [
264
264
  "NexoWatt",
265
265
  "EOS",
@@ -270,7 +270,7 @@
270
270
  "licensed"
271
271
  ],
272
272
  "compact": true,
273
- "readme": "https://unpkg.com/iobroker.eos-admin@7.9.67/README.md",
273
+ "readme": "https://unpkg.com/iobroker.eos-admin@7.9.69/README.md",
274
274
  "authors": [
275
275
  "bluefox <bluefox@ccu.io>",
276
276
  "hobbyquaker <hq@ccu.io>"
@@ -339,7 +339,7 @@
339
339
  "nondeletable": false,
340
340
  "allowAdapterUpdate": true,
341
341
  "allowAdapterDelete": false,
342
- "meta": "https://unpkg.com/iobroker.eos-admin@7.9.67/io-package.json",
342
+ "meta": "https://unpkg.com/iobroker.eos-admin@7.9.69/io-package.json",
343
343
  "npmPackage": "iobroker.eos-admin",
344
344
  "packetName": "iobroker.eos-admin"
345
345
  },
@@ -1018,5 +1018,5 @@
1018
1018
  }
1019
1019
  }
1020
1020
  },
1021
- "version": "7.9.64"
1021
+ "version": "7.9.69"
1022
1022
  }
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.67",
4
+ "version": "7.9.69",
5
5
  "contributors": [
6
6
  "bluefox <dogafox@gmail.com>",
7
7
  "apollon77",
@@ -81,7 +81,7 @@ for (const asset of [
81
81
  if (!new RegExp(`${escaped}\\?v=${cacheTag}(?:["'])`).test(adminIndex)) fail(`adminWww/index.html cache tag is stale for ${asset}`);
82
82
  if (!new RegExp(`${escaped}\\?v=${cacheTag}(?:["'])`).test(sourceIndex)) fail(`src-admin/index.html cache tag is stale for ${asset}`);
83
83
  }
84
- for (const entry of ['hostInit-v61.js', 'index-CQZugZ1z-v67.js']) {
84
+ for (const entry of ['hostInit-v61.js', 'index-CQZugZ1z-v69.js']) {
85
85
  const escaped = entry.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
86
86
  if (!new RegExp(`${escaped}\\?v=${cacheTag}(?:["'])`).test(adminIndex)) fail(`adminWww/index.html entry cache tag is stale for ${entry}`);
87
87
  }
@@ -117,29 +117,27 @@ if (!branding.includes('isAdapterConfigSurface')) fail('eos-branding.js lacks na
117
117
  if (!branding.includes('Adapter UIs must remain 100% functional')) fail('eos-branding.js lacks native adapter config interaction guard');
118
118
  if (!branding.includes('v38: All native Admin dialogs') || !branding.includes('ensurePopupCompatibility')) fail('eos-branding.js lacks v38 popup compatibility guard');
119
119
 
120
- if (!branding.includes('eos-native-drawer-header-hidden') || !branding.includes("header.setAttribute('inert', '')")) fail('eos-branding.js lacks the native drawer-header guard');
121
- if (!branding.includes('removeStrayNativeDrawerHeaders') || !branding.includes('a[href=\"/#easy\"]')) fail('eos-branding.js lacks structural native drawer-header cleanup');
122
- if (!branding.includes('ensureStandaloneNavToggle')) fail('eos-branding.js lacks the independent EOS navigation toggle');
120
+ if (!branding.includes('patchDrawerHeader') || !branding.includes('ensureStandaloneNavToggle')) fail('eos-branding.js lacks the known-good v57 shell controls');
121
+ if (!branding.includes('removeSmallTopLeftNativeNexoWattTab') || !branding.includes('eos-small-top-left-native-tab-hidden')) fail('eos-branding.js lacks the bounded small top-left tab fallback');
123
122
  const activeGraph = [
124
- fs.readFileSync(path.join(root, 'adminWww/assets/index-CQZugZ1z-v67.js'), 'utf8'),
125
- fs.readFileSync(path.join(root, 'adminWww/assets/bootstrap-COulQZax-v67.js'), 'utf8'),
123
+ fs.readFileSync(path.join(root, 'adminWww/assets/index-CQZugZ1z-v69.js'), 'utf8'),
124
+ fs.readFileSync(path.join(root, 'adminWww/assets/bootstrap-COulQZax-v69.js'), 'utf8'),
126
125
  fs.readFileSync(path.join(root, 'adminWww/remoteEntry-v61.js'), 'utf8'),
127
126
  ].join('\n');
128
- if (/bootstrap-COulQZax-v61\.js|(?:AdapterUpdateDialog|Adapters|Config|CustomTab|DeviceManager|EasyMode|Enums|Fields|Files|Hosts|Instances|Intro|Logs|Objects|Users)-[^\"']+-v61\.js/.test(activeGraph)) fail('active v67 frontend graph still imports a v61 application runtime/route chunk');
127
+ if (/bootstrap-COulQZax-v61\.js|(?:AdapterUpdateDialog|Adapters|Config|CustomTab|DeviceManager|EasyMode|Enums|Fields|Files|Hosts|Instances|Intro|Logs|Objects|Users)-[^"']+-v61\.js/.test(activeGraph)) fail('active v69 frontend graph still imports a v61 application runtime/route chunk');
129
128
 
130
129
  const drawerSource = fs.readFileSync(path.join(root, 'src-admin/src/components/Drawer.tsx'), 'utf8');
131
- const activeBootstrap = fs.readFileSync(path.join(root, 'adminWww/assets/bootstrap-COulQZax-v67.js'), 'utf8');
130
+ const activeBootstrap = fs.readFileSync(path.join(root, 'adminWww/assets/bootstrap-COulQZax-v69.js'), 'utf8');
132
131
  const brandingCss = fs.readFileSync(path.join(root, 'adminWww/css/eos-branding.css'), 'utf8');
133
- if (!drawerSource.includes('if (!this.isSwipeable())') || !drawerSource.includes('return null;')) fail('Drawer.tsx still renders the native desktop drawer header');
134
- if (!activeBootstrap.includes('getHeader(){if(!this.isSwipeable())return null;')) fail('active bootstrap still renders the native desktop drawer header');
135
- if (!brandingCss.includes('a[href=\"/#easy\"]') || !brandingCss.includes('data-eos-native-drawer-header-hidden')) fail('branding CSS lacks structural native drawer-header fallback');
132
+ if (!drawerSource.includes('getHeader(): JSX.Element {') || drawerSource.includes('getHeader(): JSX.Element | null')) fail('Drawer.tsx is not restored to the v57 header baseline');
133
+ if (!activeBootstrap.includes('getHeader(){const{state:e,handleNavigation:a}=this.props;')) fail('active bootstrap is not restored to the v57 Drawer.getHeader baseline');
134
+ if (!brandingCss.includes('v32: keep arrow button, remove empty left tile') || !brandingCss.includes('eos-small-top-left-native-tab-hidden')) fail('branding CSS lacks the v57 header baseline or narrow fallback');
136
135
 
137
136
  const appSource = fs.readFileSync(path.join(root, 'src-admin/src/App.tsx'), 'utf8');
138
- if (!branding.includes('eos-primary-brand') || !branding.includes('toolbar.firstElementChild')) fail('branding lacks robust primary EOS brand insertion');
139
- if (!branding.includes('removeNativeTopLeftGhost') || !branding.includes('eos-native-top-left-ghost-hidden')) fail('branding lacks exact native top-left ghost removal');
140
- if (!brandingCss.includes('data-eos-primary-brand') || !brandingCss.includes('data-eos-native-top-left-ghost')) fail('branding CSS lacks primary-brand/ghost safeguards');
141
- if (!activeBootstrap.includes('getHeader(){if(!this.isSwipeable())return null;')) fail('fresh v67 bootstrap still renders desktop Drawer.getHeader()');
142
- if (!activeBootstrap.includes('children:[jsxRuntimeExports.jsx(')) fail('v67 bootstrap did not restore the normal toolbar structure required by the EOS brand injector');
137
+ if (!appSource.includes('!small && this.state.drawerState !== DrawerStates.closed ? styles.hide : undefined')) fail('App.tsx is not restored to the v57 toolbar baseline');
138
+ if (!activeBootstrap.includes('style:{...styles.menuButton,...!e&&this.state.drawerState!==STATES.closed?styles.hide:void 0}')) fail('active bootstrap is not restored to the v57 desktop MenuIcon behavior');
139
+ if (!activeBootstrap.includes('this.renderLoggedUser(),this.state.drawerState!==STATES.opened')) fail('active bootstrap is not restored to the v57 compact identity behavior');
140
+ if (!activeBootstrap.includes('const version$b="7.9.69"')) fail('v69 bootstrap frontend version marker is stale');
143
141
 
144
142
  for (const file of [
145
143
  'AdapterUpdateDialog-BMg84Hpf-v67.js', 'Adapters-B5_jQ7DE-v67.js', 'Config-hHK2UzGP-v67.js',
@@ -148,7 +146,7 @@ for (const file of [
148
146
  'Hosts-Bg8QzW5i-v67.js', 'Instances-YdaGnS5a-v67.js', 'Intro-DkwRiz1n-v67.js',
149
147
  'Logs-CsVPSLJH-v67.js', 'Objects-DPan0bzw-v67.js', 'Users-BgnBRgwU-v67.js',
150
148
  ]) {
151
- if (!exists(path.join('adminWww/assets', file))) fail(`missing fresh v67 route chunk: ${file}`);
149
+ if (!exists(path.join('adminWww/assets', file))) fail(`missing compatible route chunk: ${file}`);
152
150
  const chunk = fs.readFileSync(path.join(root, 'adminWww/assets', file), 'utf8');
153
151
  if (chunk.includes('bootstrap-COulQZax-v61.js')) fail(`${file} still imports bootstrap-v61`);
154
152
  }