iobroker.eos-admin 7.9.68 → 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 -1
  2. package/adminWww/assets/bootstrap-COulQZax-v55.js +1 -1
  3. package/adminWww/assets/bootstrap-COulQZax-v56.js +1 -1
  4. package/adminWww/assets/bootstrap-COulQZax-v57.js +1 -1
  5. package/adminWww/assets/bootstrap-COulQZax-v58.js +1 -1
  6. package/adminWww/assets/bootstrap-COulQZax-v59.js +1 -1
  7. package/adminWww/assets/bootstrap-COulQZax-v60.js +1 -1
  8. package/adminWww/assets/bootstrap-COulQZax-v61.js +1 -1
  9. package/adminWww/assets/bootstrap-COulQZax-v67.js +1 -1
  10. package/adminWww/assets/bootstrap-COulQZax-v68.js +1 -317
  11. package/adminWww/assets/bootstrap-COulQZax-v69.js +317 -0
  12. package/adminWww/assets/bootstrap-COulQZax.js +1 -1
  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 -1
  21. package/adminWww/assets/index-CQZugZ1z-v68.js +1 -2
  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 -141
  25. package/adminWww/index.html +11 -10
  26. package/adminWww/js/eos-branding.js +114 -172
  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 +14 -19
@@ -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.68",
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.68/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.68/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.68/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.68"
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.68",
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-v68.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,32 +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-v68.js'), 'utf8'),
125
- fs.readFileSync(path.join(root, 'adminWww/assets/bootstrap-COulQZax-v68.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-v68.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('a[href=\"/#easy\"]')) fail('branding lacks exact native toolbar ghost removal');
140
- if (!brandingCss.includes('data-eos-primary-brand') || !brandingCss.includes('v7.9.68: exact native desktop toolbar ghost removal')) fail('branding CSS lacks primary-brand/exact-toolbar safeguards');
141
- if (!activeBootstrap.includes('getHeader(){if(!this.isSwipeable())return null;')) fail('fresh v68 bootstrap still renders desktop Drawer.getHeader()');
142
- if (!appSource.includes('{small && (') || !appSource.includes('{small &&\n this.state.drawerState')) fail('App.tsx still renders native desktop toolbar identity controls');
143
- if (!activeBootstrap.includes('children:[e&&jsxRuntimeExports.jsx(')) fail('v68 bootstrap still renders native desktop MenuIcon');
144
- if (!activeBootstrap.includes('this.renderLoggedUser(),e&&this.state.drawerState')) fail('v68 bootstrap still renders the native desktop compact identity block');
145
- if (!activeBootstrap.includes('const version$b=\"7.9.68\"')) fail('v68 bootstrap frontend version marker is stale');
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');
146
141
 
147
142
  for (const file of [
148
143
  'AdapterUpdateDialog-BMg84Hpf-v67.js', 'Adapters-B5_jQ7DE-v67.js', 'Config-hHK2UzGP-v67.js',