iobroker.eos-admin 7.10.0 → 7.10.1

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 (53) hide show
  1. package/INSTALL_TEST_V7.10.1.md +10 -0
  2. package/MERGE_UPDATE_README_V7.10.1.md +10 -0
  3. package/NEXOWATT_EOS_BUILD_INFO.json +20 -21
  4. package/PUBLISH_STABLE_V7.10.1.md +10 -0
  5. package/README.md +16 -6
  6. package/README_STABILITY_V7.10.1.md +10 -0
  7. package/RELEASE_ACCEPTANCE_V7.10.1.md +10 -0
  8. package/RELEASE_NOTES_V7.10.1.md +10 -0
  9. package/adminWww/assets/Intro-DkwRiz1n-v84.js +1 -1
  10. package/adminWww/assets/bootstrap-COulQZax-v84.js +2 -2
  11. package/adminWww/css/eos-ems-overview.css +5 -3
  12. package/adminWww/css/nexowatt-native-shell.css +85 -413
  13. package/adminWww/index.html +20 -21
  14. package/adminWww/js/eos-account-management.js +28 -19
  15. package/adminWww/js/eos-assistant.js +1 -1
  16. package/adminWww/js/eos-ems-overview.js +1 -1
  17. package/adminWww/js/eos-role-bootstrap.js +17 -80
  18. package/adminWww/js/eos-role-ui.js +28 -4
  19. package/adminWww/js/nexowatt-native-shell.js +1 -1
  20. package/adminWww/static/js/nexowatt-stable-login.js +43 -70
  21. package/adminWww/static/js/nexowatt-stable-v7101.js +27 -0
  22. package/build/lib/web.js +159 -283
  23. package/build/main.js +39 -67
  24. package/io-package.json +17 -7
  25. package/package.json +15 -22
  26. package/tools/nexowatt-account-management-selftest.cjs +15 -19
  27. package/tools/nexowatt-account-password-flow-selftest.cjs +15 -0
  28. package/tools/nexowatt-apply-ems-overview.cjs +4 -2
  29. package/tools/nexowatt-clean-legacy-runtime.cjs +1 -1
  30. package/tools/nexowatt-ems-overview-selftest.cjs +1 -1
  31. package/tools/nexowatt-ensure-release-defaults.cjs +1 -1
  32. package/tools/nexowatt-login-layout-selftest.cjs +9 -13
  33. package/tools/nexowatt-merge-update-selftest.cjs +1 -1
  34. package/tools/nexowatt-modern-ui-selftest.cjs +10 -46
  35. package/tools/nexowatt-password-write-selftest.cjs +46 -16
  36. package/tools/nexowatt-release-defaults-selftest.cjs +1 -1
  37. package/tools/nexowatt-runtime-cleanup-selftest.cjs +6 -8
  38. package/tools/nexowatt-stable-v7101-selftest.cjs +15 -0
  39. package/tools/nexowatt-sync-release-version.cjs +43 -5
  40. package/tools/nexowatt-ui-overview-runtime-selftest.cjs +2 -3
  41. package/tools/nexowatt-validate-package.cjs +27 -26
  42. package/tools/nexowatt-version-sync-selftest.cjs +18 -1
  43. package/INSTALL_TEST_V7.10.0.md +0 -11
  44. package/MERGE_UPDATE_README_V7.10.0.md +0 -5
  45. package/PUBLISH_STABLE_V7.10.0.md +0 -15
  46. package/README_STABILITY_V7.10.0.md +0 -3
  47. package/RELEASE_ACCEPTANCE_V7.10.0.md +0 -11
  48. package/RELEASE_NOTES_V7.10.0.md +0 -17
  49. package/adminWww/static/js/nexowatt-stable-v7100.js +0 -111
  50. package/src/lib/eosAutoUpdate.ts +0 -320
  51. package/tools/nexowatt-cache-update-selftest.cjs +0 -12
  52. package/tools/nexowatt-request-security-selftest.cjs +0 -11
  53. package/tools/nexowatt-stable-v7100-selftest.cjs +0 -17
@@ -0,0 +1,10 @@
1
+ # NexoWatt EOS Admin 7.10.1
2
+
3
+ - Basis: veröffentlichte 7.9.98-Stable-Repository-ZIP.
4
+ - Keine erzwungene EOS-Erstpasswortseite und kein eigener EOS-Passwortreset.
5
+ - Standardpasswort `nexowatt` nur bei neu angelegten oder wirklich passwortlosen Konten.
6
+ - Passwortänderung unter Zugänge & Rechte über die native ioBroker-Passwortfunktion.
7
+ - Dauerhafter vertikaler Cockpit-Scrollbereich.
8
+ - Bearbeiten-Stift innerhalb des untersten Kartenrasters.
9
+ - Nicht vorhandener Link zur vollständigen EMS-Diagnose entfernt.
10
+ - Automatische Stable-Updates nur für installierte NexoWatt-Adapter, standardmäßig aktiv und durch Admin/Service abschaltbar.
@@ -0,0 +1,10 @@
1
+ # NexoWatt EOS Admin 7.10.1
2
+
3
+ - Basis: veröffentlichte 7.9.98-Stable-Repository-ZIP.
4
+ - Keine erzwungene EOS-Erstpasswortseite und kein eigener EOS-Passwortreset.
5
+ - Standardpasswort `nexowatt` nur bei neu angelegten oder wirklich passwortlosen Konten.
6
+ - Passwortänderung unter Zugänge & Rechte über die native ioBroker-Passwortfunktion.
7
+ - Dauerhafter vertikaler Cockpit-Scrollbereich.
8
+ - Bearbeiten-Stift innerhalb des untersten Kartenrasters.
9
+ - Nicht vorhandener Link zur vollständigen EMS-Diagnose entfernt.
10
+ - Automatische Stable-Updates nur für installierte NexoWatt-Adapter, standardmäßig aktiv und durch Admin/Service abschaltbar.
@@ -1,29 +1,28 @@
1
1
  {
2
- "version": "7.10.0",
2
+ "version": "7.10.1",
3
3
  "channel": "stable-latest",
4
- "baseFrontend": "validated Admin 7 runtime with native NexoWatt stable auto updates, fixed Intro scrollbar, clean login and verified user passwords",
4
+ "baseFrontend": "validated Admin 7 runtime with scrollable native cockpit, clean placeholder login and verified ioBroker password writes",
5
5
  "runtimeEntry": "v84",
6
- "releaseType": "stable-candidate-scroll-login-password-auto-update",
7
- "release": "stable-candidate-scroll-login-password-auto-update",
8
- "label": "v7100",
6
+ "releaseType": "stable-native-account-scroll-auto-update",
7
+ "release": "stable-native-account-scroll-auto-update",
8
+ "label": "v7-10-1",
9
9
  "notes": [
10
- "Installed NexoWatt adapters use native stable auto updates by default and can be disabled.",
11
- "The Cockpit/Intro surface has a permanent visible vertical scrollbar while header and navigation remain fixed.",
12
- "The product login uses one compact MUI Paper card with permanently notched labels and no overlap.",
13
- "First-login and reset passwords use canonical ioBroker user IDs first with a legacy short-name fallback.",
14
- "Passwords are accepted only after the user-object hash changes and the new credential is verified.",
15
- "Release assets are tagged 7100 and delivered with no-store handling through the existing release watcher."
10
+ "Built directly from the known 7.9.98 stable repository baseline.",
11
+ "The forced EOS first-password and custom reset surfaces are disabled; native ioBroker password management is used.",
12
+ "Installer, customer and guest accounts receive nexowatt only when first created or genuinely passwordless.",
13
+ "The cockpit keeps a persistent visible scrollbar and the edit control lives inside the lowest card grid.",
14
+ "Installed NexoWatt stable adapters use native automatic upgrades by default and can be disabled by Admin/Service."
16
15
  ],
17
16
  "changes": [
18
- "Restored the scroll surface in CSS and the productive stable runtime.",
19
- "Removed the fixed login minimum height and corrected MUI label/notch geometry.",
20
- "Corrected login Paper ownership to prevent nested form sizing.",
21
- "Strengthened password writes with four controller API variants and explicit backend error codes.",
22
- "Kept the NexoWatt stable auto-update manager and its default-enabled toggle unchanged."
17
+ "Normalized system.user.* ids to the short account names expected by setPasswordAsync and checkPasswordAsync.",
18
+ "Separated password hash writes from EOS native metadata updates to prevent stale object replacement.",
19
+ "Relaxed same-host origin handling for reverse proxies while rejecting cross-site requests.",
20
+ "Added a stable vertical scroll surface to the overview and preserved the working EMS live diagnosis.",
21
+ "Removed floating login labels from the productive bundle and introduced clean accessible placeholders."
23
22
  ],
24
- "brandingCacheVersion": 7100,
25
- "shellCacheVersion": 7100,
26
- "nativeShellVersion": 7100,
27
- "shellCacheTag": "7100",
28
- "repositoryEntry": "nexowatt-eos-admin-repository-entry-v7100.json"
23
+ "brandingCacheVersion": 7101,
24
+ "shellCacheVersion": 7101,
25
+ "nativeShellVersion": 7101,
26
+ "shellCacheTag": "7101",
27
+ "repositoryEntry": "nexowatt-eos-admin-repository-entry-v7-10-1.json"
29
28
  }
@@ -0,0 +1,10 @@
1
+ # NexoWatt EOS Admin 7.10.1
2
+
3
+ - Basis: veröffentlichte 7.9.98-Stable-Repository-ZIP.
4
+ - Keine erzwungene EOS-Erstpasswortseite und kein eigener EOS-Passwortreset.
5
+ - Standardpasswort `nexowatt` nur bei neu angelegten oder wirklich passwortlosen Konten.
6
+ - Passwortänderung unter Zugänge & Rechte über die native ioBroker-Passwortfunktion.
7
+ - Dauerhafter vertikaler Cockpit-Scrollbereich.
8
+ - Bearbeiten-Stift innerhalb des untersten Kartenrasters.
9
+ - Nicht vorhandener Link zur vollständigen EMS-Diagnose entfernt.
10
+ - Automatische Stable-Updates nur für installierte NexoWatt-Adapter, standardmäßig aktiv und durch Admin/Service abschaltbar.
package/README.md CHANGED
@@ -13,11 +13,15 @@ Standard-Port: 8081
13
13
 
14
14
  Damit überschreibt der Adapter den offiziellen `admin`-Adapter nicht mehr. Die alte ioBroker-Admin-Oberfläche kann parallel vorhanden bleiben, während NexoWatt-Systeme über `eos-admin.0` die EOS-Oberfläche nutzen.
15
15
 
16
- ## Aktuelle Stable 7.9.89
16
+ ## Aktueller Stable-Verkaufskandidat 7.9.98
17
17
 
18
- Die Verkaufsversion 7.9.89 verwendet die aktuelle **Übersicht** als Startseite, integriert EOS Assist in den Header und führt Zugangsverwaltung ausschließlich unter **Zugänge & Rechte**. Installer und Guest aktivieren ihr Konto beim ersten Login im normalen Anmeldeformular einmalig ohne Startpasswort und vergeben anschließend ein persönliches Passwort. Admin / Service bleibt unverändert.
18
+ Version 7.9.98 verwendet die native **Übersicht** als Startseite und ergänzt dort die ausschließlich lesende EMS-Live-Diagnose. Der Inhaltsbereich ist vertikal scrollbar, während Header und Hauptnavigation stehen bleiben.
19
19
 
20
- Der interne Admin und die interne BackItUp-Notfallreserve bleiben installiert, sind aber ausschließlich für Admin / Service sichtbar. Für den regulären Betrieb wird die NexoWatt Sicherung verwendet.
20
+ Verwaltete Installateur- und Endkundenkonten verwenden das Startpasswort `nexowatt`. Nach der ersten Anmeldung beziehungsweise nach einem Reset muss unmittelbar ein persönliches Passwort vergeben werden. Der Reset und die persönliche Passwortvergabe schreiben das reale ioBroker-Benutzerkennwort; EOS-Metadaten werden davon getrennt aktualisiert.
21
+
22
+ Admin/Service darf verwaltete Installateur- und Endkundenkonten zurücksetzen. Installateure dürfen ausschließlich ausdrücklich zugeordnete Endkundenkonten zurücksetzen. Admin-, Eigen-, deaktivierte und nicht verwaltete Konten bleiben geschützt.
23
+
24
+ EOS Assist ist in diesem Stand bewusst deaktiviert. Der interne Admin und die interne BackItUp-Notfallreserve bleiben installiert und sind ausschließlich für Admin/Service sichtbar. Für den regulären Betrieb wird die NexoWatt Sicherung verwendet.
21
25
 
22
26
  ## Installation über das NexoWatt Repository
23
27
 
@@ -29,7 +33,7 @@ Minimaler Repository-Eintrag:
29
33
  {
30
34
  "eos-admin": {
31
35
  "name": "eos-admin",
32
- "version": "7.9.89",
36
+ "version": "7.9.98",
33
37
  "title": "NexoWatt EOS Admin",
34
38
  "desc": {
35
39
  "de": "NexoWatt EOS Administrationsoberfläche als eigenständiger Adapter.",
@@ -126,12 +130,18 @@ iobroker restart eos-admin.0
126
130
 
127
131
  ## Veröffentlichung auf npm
128
132
 
133
+ Vor der Veröffentlichung müssen Paket- und Stabilitätsprüfung vollständig grün sein:
134
+
129
135
  ```bash
130
136
  npm login
131
- npm publish
137
+ npm whoami
138
+ npm run sync:eos-version
139
+ npm run check:eos-release
140
+ npm publish --dry-run --tag latest
141
+ npm publish --tag latest
132
142
  ```
133
143
 
134
- Die Version muss vor jedem erneuten Publish erhöht werden.
144
+ Die Version muss vor jedem erneuten Publish erhöht werden. Für 7.9.98 ist die Veröffentlichung des separat geprüften `iobroker.eos-admin-7.9.98.tgz` der sicherste Weg.
135
145
 
136
146
  ## Lizenz
137
147
 
@@ -0,0 +1,10 @@
1
+ # NexoWatt EOS Admin 7.10.1
2
+
3
+ - Basis: veröffentlichte 7.9.98-Stable-Repository-ZIP.
4
+ - Keine erzwungene EOS-Erstpasswortseite und kein eigener EOS-Passwortreset.
5
+ - Standardpasswort `nexowatt` nur bei neu angelegten oder wirklich passwortlosen Konten.
6
+ - Passwortänderung unter Zugänge & Rechte über die native ioBroker-Passwortfunktion.
7
+ - Dauerhafter vertikaler Cockpit-Scrollbereich.
8
+ - Bearbeiten-Stift innerhalb des untersten Kartenrasters.
9
+ - Nicht vorhandener Link zur vollständigen EMS-Diagnose entfernt.
10
+ - Automatische Stable-Updates nur für installierte NexoWatt-Adapter, standardmäßig aktiv und durch Admin/Service abschaltbar.
@@ -0,0 +1,10 @@
1
+ # NexoWatt EOS Admin 7.10.1
2
+
3
+ - Basis: veröffentlichte 7.9.98-Stable-Repository-ZIP.
4
+ - Keine erzwungene EOS-Erstpasswortseite und kein eigener EOS-Passwortreset.
5
+ - Standardpasswort `nexowatt` nur bei neu angelegten oder wirklich passwortlosen Konten.
6
+ - Passwortänderung unter Zugänge & Rechte über die native ioBroker-Passwortfunktion.
7
+ - Dauerhafter vertikaler Cockpit-Scrollbereich.
8
+ - Bearbeiten-Stift innerhalb des untersten Kartenrasters.
9
+ - Nicht vorhandener Link zur vollständigen EMS-Diagnose entfernt.
10
+ - Automatische Stable-Updates nur für installierte NexoWatt-Adapter, standardmäßig aktiv und durch Admin/Service abschaltbar.
@@ -0,0 +1,10 @@
1
+ # NexoWatt EOS Admin 7.10.1
2
+
3
+ - Basis: veröffentlichte 7.9.98-Stable-Repository-ZIP.
4
+ - Keine erzwungene EOS-Erstpasswortseite und kein eigener EOS-Passwortreset.
5
+ - Standardpasswort `nexowatt` nur bei neu angelegten oder wirklich passwortlosen Konten.
6
+ - Passwortänderung unter Zugänge & Rechte über die native ioBroker-Passwortfunktion.
7
+ - Dauerhafter vertikaler Cockpit-Scrollbereich.
8
+ - Bearbeiten-Stift innerhalb des untersten Kartenrasters.
9
+ - Nicht vorhandener Link zur vollständigen EMS-Diagnose entfernt.
10
+ - Automatische Stable-Updates nur für installierte NexoWatt-Adapter, standardmäßig aktiv und durch Admin/Service abschaltbar.
@@ -1,2 +1,2 @@
1
- import{j as s}from"./DefaultPropsProvider-BiXBMQYQ.js";import{i as _,a as B}from"./iobroker_admin__loadShare__react__loadShare__-LM7uyL45.js";import{b as S,r as J,c as P,s as w}from"./bootstrap-COulQZax-v84.js";import{i as n,a as f}from"./iobroker_admin__loadShare___mf_0_mui_mf_1_icons_mf_2_material__loadShare__-CJO5yP3h.js";import{i as v}from"./iobroker_admin__loadShare___mf_0_iobroker_mf_1_adapter_mf_2_react_mf_2_v5__loadShare__-LFZoiUTt.js";import{b as $}from"./blue-CagzI6CQ.js";import{g as b,v as M}from"./createTheme-DFX8CY6F.js";import"./_commonjsHelpers-CE1G-McA.js";import"./iobroker_admin__mf_v__runtimeInit__mf_v__-g2X2zhAf.js";import"./emotion-serialize.esm-Q4o_CgeF.js";import"./iobroker_admin__loadShare___mf_0_emotion_mf_1_react__loadShare__-BywLg1Xe.js";import"./ace-DEUjyTIn.js";import"./iobroker_admin__loadShare___mf_0_iobroker_mf_1_json_mf_2_config__loadShare__-CpA7pnS5.js";import"./iobroker_admin__loadShare__leaflet__loadShare__-CNUAG3AH.js";import"./ext-language_tools-ylAoucDh.js";import"./iobroker_admin__loadShare__react_mf_2_dropzone__loadShare__-CwjnV48g.js";import"./iobroker_admin__loadShare__react_mf_2_dom__loadShare__-CVeAXnkk.js";import"./preload-helper-BDBacUwf.js";import"./sdk-C-e-e2gd.js";import"./extends-CF3RwP-h.js";import"./assertThisInitialized-B0aQ9eG_.js";import"./useTheme-Bl-M1DYp.js";import"./index-DcK0RDrH.js";import"./ThemeProvider-BOFFjWAF.js";import"./emotion-cache.browser.esm-BgJfNZJN.js";import"./setYear-3ufv5yRD.js";import"./en-US-DBFJNIH6.js";const L="0 2px 2px 0 rgba(0, 0, 0, .14),0 3px 1px -2px rgba(0, 0, 0, .12),0 1px 5px 0 rgba(0, 0, 0, .2)",A="0 8px 17px 0 rgba(0, 0, 0, .2),0 6px 20px 0 rgba(0, 0, 0, .19)",x={root:g=>({padding:".75rem",[g.breakpoints.up("xl")]:{flex:"0 1 20%"}}),card:{display:"flex",minHeight:"235px",position:"relative",overflow:"hidden",maxHeight:"235p","&:hover":{overflowY:"auto",boxShadow:A}},cardInfo:{display:"flex",minHeight:"235px",position:"relative",overflow:"initial",maxHeight:"235p",flexDirection:"column","&:hover":{boxShadow:A}},cardInfoHead:g=>({position:"sticky",top:0,background:g.palette.background.default,display:"flex",width:"100%",justifyContent:"space-between",borderBottom:"1px solid",padding:"5px 5px 0px 5px"}),edit:{opacity:.6,userSelect:"none",pointerEvents:"none"},media:g=>({backgroundColor:g.palette.mode==="dark"?"#535353":"#e2e2e2",maxWidth:"30%"}),img:{width:120,height:"auto",padding:"2rem .5rem",maxWidth:"100%"},contentContainer:{display:"flex",flexDirection:"column",flex:1},content:{height:"170px",flexGrow:1,overflowY:"hidden"},action:{minHeight:"49px",padding:"16px 24px"},expand:{position:"absolute",right:"10px",bottom:"10px"},collapse:{minHeight:"100%",backgroundColor:"#ffffff",position:"absolute",width:"100%"},enabled:{color:"#ffffff",backgroundColor:$[500],position:"absolute",top:8,right:8,boxShadow:L,"&:hover":{backgroundColor:$[300]},"&:focus":{backgroundColor:$[500]}},disabled:{color:"#ffffff",backgroundColor:b[500],position:"absolute",top:8,right:8,boxShadow:L,"&:hover":{backgroundColor:b[300]},"&:focus":{backgroundColor:b[500]}},editButton:{color:"#ffffff",backgroundColor:b[500],position:"absolute",top:64,right:8,boxShadow:L,"&:hover":{backgroundColor:b[300]},"&:focus":{backgroundColor:b[500]}},deleteButton:{color:"#ffffff",backgroundColor:M[500],position:"absolute",top:120,right:8,boxShadow:L,"&:hover":{backgroundColor:M[300]},"&:focus":{backgroundColor:M[500]}},contentGrid:{height:"100%"},colorOrange:{color:"#ffcc80"},tooltip:{pointerEvents:"none"}};class O extends _.Component{constructor(t){super(t),this.state={expanded:!1}}static getDerivedStateFromProps(t){return t.edit?{expanded:!1}:null}handleExpandClick(){this.setState({expanded:!this.state.expanded})}renderContent(){return this.props.children}openDialog(){}renderDialogs(){return null}render(){var o,i;const t=this.props.edit?x.edit:void 0;let e=this.props.action.text||this.props.t("Link");return typeof e=="object"&&(e=e[this.props.lang]||e.en),s.jsx(n.Grid2,{size:{xs:12,sm:6,md:4,lg:3,xl:2},sx:v.Utils.getStyle(this.props.theme,x.root,this.props.style),style:{maxWidth:500},children:s.jsx(n.Link,{href:!this.props.edit&&this.props.action&&this.props.action.link?this.props.action.link:null,underline:"none",target:"_blank",rel:"noopener noreferrer",children:s.jsxs(n.Card,{sx:x.card,onClick:d=>{d.stopPropagation(),this.openDialog()},children:[this.props.showInfo&&!this.props.offline&&s.jsx(n.Button,{style:{...x.expand,...t},variant:"contained",size:"small",disabled:this.props.disabled,onClick:()=>this.handleExpandClick(),color:"primary",children:this.props.t("Info")}),s.jsxs(n.Box,{component:"div",sx:v.Utils.getStyle(this.props.theme,x.media,t,this.props.color&&{backgroundColor:this.props.color},{display:"flex",flexDirection:"column"}),children:[s.jsx(n.CardMedia,{style:x.img,component:"img",image:this.props.image}),s.jsx("div",{style:{flex:1,display:"flex",paddingBottom:"5px",paddingLeft:"5px"},children:this.props.warning?s.jsx(n.Tooltip,{title:this.props.warning,slotProps:{popper:{sx:x.tooltip}},children:s.jsx(f.Warning,{style:{alignSelf:"end",fontSize:36}})}):null})]}),s.jsxs("div",{style:{...x.contentContainer,...t},children:[s.jsx(n.CardContent,{style:x.content,children:s.jsxs(n.Grid2,{container:!0,direction:"column",wrap:"nowrap",style:x.contentGrid,children:[s.jsx(n.Typography,{gutterBottom:!0,variant:"h5",component:"h5",children:this.props.title}),this.renderContent()]})}),((o=this.props.action)==null?void 0:o.link)&&s.jsx(n.Divider,{}),((i=this.props.action)==null?void 0:i.link)&&s.jsx(n.CardActions,{style:x.action,children:s.jsx("div",{style:x.colorOrange,children:S.getText(e,this.props.lang)})})]}),this.props.showInfo&&s.jsx(n.Collapse,{style:x.collapse,in:this.state.expanded,timeout:"auto",unmountOnExit:!0,children:s.jsxs(n.Card,{sx:x.cardInfo,children:[s.jsxs(n.Box,{component:"div",sx:x.cardInfoHead,children:[s.jsx(n.Typography,{gutterBottom:!0,variant:"h5",component:"h5",children:this.props.t("Info")}),s.jsxs("div",{children:[s.jsx(n.IconButton,{size:"small",onClick:()=>{this.props.getHostDescriptionAll&&v.Utils.copyToClipboard(this.props.getHostDescriptionAll().text),this.props.openSnackBarFunc&&this.props.openSnackBarFunc()},children:s.jsx(v.IconCopy,{})}),s.jsx(n.IconButton,{size:"small",onClick:()=>this.handleExpandClick(),children:s.jsx(f.Close,{})})]})]}),s.jsx(n.CardContent,{children:this.props.getHostDescriptionAll().el})]})}),this.props.edit&&this.props.toggleActivation&&s.jsx(n.IconButton,{size:"large",sx:this.props.enabled?x.enabled:x.disabled,onClick:()=>this.props.toggleActivation(),children:s.jsx(f.Check,{})}),this.props.edit&&this.props.onEdit&&s.jsx(n.IconButton,{size:"large",sx:x.editButton,onClick:()=>this.props.onEdit(),children:s.jsx(f.Create,{})}),this.props.edit&&this.props.onRemove&&s.jsx(n.IconButton,{size:"large",sx:x.deleteButton,onClick:()=>this.props.onRemove(),children:s.jsx(f.Delete,{})}),this.renderDialogs()]})})})}}const I={closeButton:g=>({position:"absolute",right:8,top:8,color:g.palette.grey[500]}),paper:{},typography:{paddingRight:30},img:{width:"100%",height:"100%",objectFit:"contain"}};class R extends _.Component{cameraUpdateTimer;cameraRef;constructor(t){super(t),this.cameraUpdateTimer=null,this.cameraRef=_.createRef()}componentDidMount(){this.props.camera&&this.props.camera!=="text"&&(this.cameraUpdateTimer=setInterval(()=>this.updateCamera(),Math.max(parseInt(this.props.interval,10),500)),this.updateCamera())}componentWillUnmount(){this.cameraUpdateTimer&&(clearInterval(this.cameraUpdateTimer),this.cameraUpdateTimer=null)}updateCamera(){if(this.cameraRef.current)if(this.props.camera==="custom"){let t=this.props.cameraUrl;this.props.addTs&&(t.includes("?")?t+=`&ts=${Date.now()}`:t+=`?ts=${Date.now()}`),this.cameraRef.current.src=t}else{const t=this.props.camera.split("."),e=t.shift(),o=t.shift();this.props.socket.sendTo(`${e}.${o}`,"image",{name:t.pop(),width:this.cameraRef.current.width}).then(i=>{i&&i.data&&this.cameraRef.current&&(this.cameraRef.current.src=`data:image/jpeg;base64,${i.data}`)})}}render(){return s.jsxs(n.Dialog,{onClose:()=>this.props.onClose(),open:!0,maxWidth:"xl",fullWidth:!0,fullScreen:!0,sx:{"& .MuiDialog-paper":I.paper},children:[s.jsx(n.DialogTitle,{children:s.jsxs(n.Typography,{component:"h2",variant:"h6",sx:{"&.MuiTypography-root":I.typography},children:[this.props.name,s.jsx(n.IconButton,{size:"large",sx:I.closeButton,onClick:()=>this.props.onClose(),children:s.jsx(f.Close,{})})]})}),s.jsx(n.DialogContent,{dividers:!0,children:s.jsx("img",{style:I.img,src:"",alt:"camera",ref:this.cameraRef})}),s.jsx(n.DialogActions,{children:s.jsx(n.Button,{variant:"contained",autoFocus:!0,onClick:t=>{t.stopPropagation(),this.props.onClose()},color:"primary",startIcon:s.jsx(f.Close,{}),children:this.props.t("Close")})})]})}}const D={cameraImg:{width:"100%",height:"100%",maxWidth:200,maxHeight:200,objectFit:"contain"},imgContainer:{height:"100%"},hidden:{display:"none"},imgSkeleton:{transform:"initial"}};class E extends O{cameraRef;cameraUpdateTimer;interval;constructor(t){super(t),Object.assign(this.state,{error:!1,dialog:!1,loaded:!1}),this.cameraRef=_.createRef(),this.cameraUpdateTimer=null,this.interval=t.interval}updateCamera(){if(this.cameraRef.current)if(this.props.camera==="custom"){let t=this.props.cameraUrl;this.props.addTs&&(t.includes("?")?t+=`&ts=${Date.now()}`:t+=`?ts=${Date.now()}`),this.cameraRef.current.src=t}else{const t=this.props.camera.split("."),e=t.shift(),o=t.shift();this.props.socket.sendTo(`${e}.${o}`,"image",{name:t.pop(),width:this.cameraRef.current.width}).then(i=>{i!=null&&i.data&&this.cameraRef.current&&(this.cameraRef.current.src=`data:image/jpeg;base64,${i.data}`)}).catch(i=>window.alert(`Cannot send to instance: ${i}`))}}componentDidMount(){this.props.camera&&this.props.camera!=="text"&&(this.cameraUpdateTimer=setInterval(()=>this.updateCamera(),Math.max(parseInt(this.props.interval,10),500)),this.updateCamera())}componentWillUnmount(){this.cameraUpdateTimer&&(clearInterval(this.cameraUpdateTimer),this.cameraUpdateTimer=null)}renderDialogs(){return this.state.dialog?s.jsx(R,{socket:this.props.socket,camera:this.props.camera,name:this.props.title,t:this.props.t,onClose:()=>{this.props.camera&&this.props.camera!=="text"&&(this.cameraUpdateTimer&&clearInterval(this.cameraUpdateTimer),this.cameraUpdateTimer=setInterval(()=>this.updateCamera(),Math.max(parseInt(this.props.interval,10),500)),this.updateCamera()),this.setState({dialog:!1})},cameraUrl:this.props.cameraUrl}):null}handleImageLoad(){this.state.loaded||this.setState({loaded:!0,error:!1})}handleImageError(){this.state.error||this.setState({loaded:!1,error:!0})}renderContent(){if(this.props.camera==="custom"){let t=this.props.cameraUrl;return this.props.addTs&&(t.includes("?")?t+=`&ts=${Date.now()}`:t+=`?ts=${Date.now()}`),s.jsxs(n.Grid2,{container:!0,style:D.imgContainer,justifyContent:"center",alignItems:"center",children:[s.jsx("img",{ref:this.cameraRef,src:t,alt:"Camera",style:this.state.loaded&&!this.state.error?D.cameraImg:D.hidden,onLoad:()=>this.handleImageLoad(),onError:()=>this.handleImageError()}),!this.state.loaded&&!this.state.error&&s.jsx(n.Skeleton,{height:"100%",width:"100%",animation:"wave",style:D.imgSkeleton}),this.state.error&&s.jsx(f.Error,{fontSize:"large"})]})}return this.props.camera.startsWith("cameras.")?s.jsx("img",{ref:this.cameraRef,src:"",alt:"camera",style:D.cameraImg}):null}render(){return this.props.camera&&this.props.camera!=="text"?this.interval!==this.props.interval&&(this.interval=this.props.interval,this.cameraUpdateTimer&&clearInterval(this.cameraUpdateTimer),this.cameraUpdateTimer=setInterval(()=>this.updateCamera(),Math.max(parseInt(this.props.interval,10),500))):this.cameraUpdateTimer&&(clearInterval(this.cameraUpdateTimer),this.cameraUpdateTimer=null),super.render()}}const y={formControl:{marginTop:32},rootGrid:{flexGrow:1},closeButton:g=>({position:"absolute",right:8,top:8,color:g.palette.grey[500]}),paper:{},typography:{paddingRight:30},editItem:{marginTop:8},editItemSlider:{marginTop:24},labelSlider:{marginTop:16,fontSize:"1rem"},editColor:{width:"100%"}};class U extends _.Component{constructor(t){super(t),this.state={image:"",name:t.t("New link"),link:"http://",linkName:"",color:"",desc:"",addTs:!0,interval:5e3,camera:"text",cameraList:[],...t.link}}componentDidMount(){this.getCamerasInstances()}getCamerasInstances(){this.props.socket.getAdapterInstances("cameras",!0).then(t=>{const e=[],o=[];t.forEach(i=>{const d=i._id.replace("system.adapter.","");i.common&&i.common.enabled&&o.push(this.props.socket.getState(`${i._id}.alive`).then(r=>r&&r.val&&this.props.socket.sendTo(d,"list",null)).then(r=>r&&r.list&&r.list.forEach(a=>e.push({id:a.id,name:`${a.desc} [${d}/${a.name}]`}))))}),Promise.all(o).then(()=>this.setState({cameraList:e}))})}static getLinkNameFromLink(t){const e=t.trim().match(/^https?:\/\/([^/:]+)(:\d+)?/);return e?e[1]+(e[2]||""):""}render(){return s.jsxs(n.Dialog,{onClose:()=>this.props.onClose(),open:!0,maxWidth:"md",fullWidth:!0,sx:{"& .MuiDialog-paper":y.paper},children:[s.jsx(n.DialogTitle,{children:s.jsxs(n.Typography,{component:"h2",variant:"h6",sx:{"&.MuiTypography-root":y.typography},children:[this.props.isNew?this.props.t("Add new link: "):this.props.t("Edit link"),s.jsx(n.IconButton,{size:"large",sx:y.closeButton,onClick:()=>this.props.onClose(),children:s.jsx(f.Close,{})})]})}),s.jsx(n.DialogContent,{dividers:!0,children:s.jsxs(n.Grid2,{style:y.rootGrid,container:!0,direction:"row",children:[s.jsx(n.Grid2,{size:{xs:12,sm:6,md:8,lg:9},children:s.jsxs(n.Grid2,{container:!0,direction:"column",children:[s.jsxs(n.FormControl,{variant:"standard",style:y.formControl,children:[s.jsx(n.InputLabel,{id:"select-helper-label",children:this.props.t("Link type")}),s.jsxs(n.Select,{variant:"standard",labelId:"select-helper-label",value:this.state.camera,onChange:t=>this.setState({camera:t.target.value}),children:[s.jsx(n.MenuItem,{value:"text",children:s.jsx("em",{children:this.props.t("Description")})},"desc"),this.state.cameraList.map(t=>s.jsx(n.MenuItem,{value:t.id,children:t.name},t.id)),s.jsx(n.MenuItem,{value:"custom",children:this.props.t("Custom camera URL")},"custom")]})]}),s.jsx(n.TextField,{variant:"standard",label:this.props.t("URL"),value:this.state.link,style:y.editItem,onChange:t=>{const e=U.getLinkNameFromLink(this.state.link);e&&(!this.state.linkName||e===this.state.linkName)?this.setState({link:t.target.value,linkName:U.getLinkNameFromLink(t.target.value)}):this.setState({link:t.target.value})},slotProps:{input:{endAdornment:this.state.link?s.jsx(n.InputAdornment,{position:"end",children:s.jsx(n.IconButton,{tabIndex:-1,size:"small",onClick:()=>this.setState({link:""}),children:s.jsx(f.Close,{})})}):null}}}),s.jsx(n.TextField,{variant:"standard",style:y.editItem,label:this.props.t("Name"),value:this.state.name||"",onChange:t=>this.setState({name:t.target.value}),slotProps:{input:{endAdornment:this.state.name?s.jsx(n.InputAdornment,{position:"end",children:s.jsx(n.IconButton,{tabIndex:-1,size:"small",onClick:()=>this.setState({name:""}),children:s.jsx(f.Close,{})})}):null}}}),this.state.link?s.jsx(n.TextField,{variant:"standard",style:y.editItem,label:this.props.t("Link name"),value:this.state.linkName||"",onChange:t=>this.setState({linkName:t.target.value}),slotProps:{input:{endAdornment:this.state.linkName?s.jsx(n.InputAdornment,{position:"end",children:s.jsx(n.IconButton,{tabIndex:-1,size:"small",onClick:()=>this.setState({linkName:""}),children:s.jsx(f.Close,{})})}):null}}}):null,this.state.camera==="custom"||this.state.camera==="text"?s.jsx(n.TextField,{variant:"standard",style:y.editItem,label:this.state.camera==="custom"?this.props.t("Camera URL"):this.props.t("Description"),value:this.state.desc||"",onChange:t=>this.setState({desc:t.target.value}),slotProps:{input:{endAdornment:this.state.desc?s.jsx(n.InputAdornment,{position:"end",children:s.jsx(n.IconButton,{tabIndex:-1,size:"small",onClick:()=>this.setState({desc:""}),children:s.jsx(f.Close,{})})}):null}}}):null,this.state.camera==="custom"?s.jsx(n.FormControlLabel,{style:y.editItem,control:s.jsx(n.Checkbox,{checked:this.state.addTs,onChange:t=>this.setState({addTs:t.target.checked})}),label:this.props.t("Add timestamp to URL")}):null,this.state.camera!=="text"?s.jsx(n.Typography,{style:y.labelSlider,gutterBottom:!0,children:"Polling interval in ms"}):null,this.state.camera!=="text"?s.jsx(n.Slider,{style:y.editItemSlider,value:this.state.interval,getAriaValueText:()=>`${this.state.interval}ms`,onChange:(t,e)=>this.setState({interval:e}),step:100,min:500,max:6e4,valueLabelDisplay:"on"}):null,s.jsx("div",{style:{...y.editItem,width:50},children:s.jsx(n.TextField,{variant:"standard",fullWidth:!0,label:this.props.t("Color"),style:y.editColor,type:"color",value:this.state.color,onChange:t=>this.setState({color:t.target.value})})}),s.jsx(v.UploadImage,{disabled:!1,crop:!0,maxSize:256*1024,icon:this.state.image,removeIconFunc:()=>this.setState({image:""}),onChange:t=>this.setState({image:t})})]})}),s.jsx(n.Grid2,{size:{xs:12,sm:6,md:4,lg:3},children:this.state.camera==="text"?s.jsx(O,{image:this.state.image,title:this.state.name,action:{link:this.state.link,text:this.state.linkName},t:this.props.t,lang:this.props.lang,style:{width:"100% !important",maxWidth:"100% !important",marginLeft:"8px"},color:this.state.color,enabled:!0,theme:this.props.theme,children:this.state.desc}):s.jsx(E,{interval:this.state.interval,camera:this.state.camera,addTs:this.state.addTs,style:{width:"100% !important",maxWidth:"100% !important",marginLeft:"8px"},image:this.state.image,title:this.state.name,socket:this.props.socket,action:{link:this.state.link,text:this.state.linkName},t:this.props.t,lang:this.props.lang,color:this.state.color,enabled:!0,cameraUrl:this.state.desc,theme:this.props.theme})})]})}),s.jsxs(n.DialogActions,{children:[s.jsx(n.Button,{variant:"contained",autoFocus:!0,onClick:()=>{this.props.onClose({link:this.state.link,name:this.state.name,desc:this.state.desc,linkName:this.state.linkName,color:this.state.color,image:this.state.image,addTs:this.state.addTs,camera:this.state.camera,interval:this.state.interval})},color:"primary",startIcon:this.props.isNew?s.jsx(f.Add,{}):s.jsx(f.Check,{}),children:this.props.isNew?this.props.t("Add"):this.props.t("Save")}),s.jsx(n.Button,{variant:"contained",onClick:()=>this.props.onClose(),color:"grey",startIcon:s.jsx(f.Close,{}),children:this.props.t("Close")})]})]})}}class W extends B.Component{constructor(t){super(t),this.state={inProgress:!1,success:!1,error:"",finished:!1}}render(){return s.jsxs(n.Dialog,{open:!0,maxWidth:"lg",fullWidth:!0,children:[s.jsx(n.DialogTitle,{children:v.I18n.t("Node.js upgrade")}),s.jsxs(n.DialogContent,{style:{height:100,padding:"0 20px",overflow:"hidden"},children:[this.state.finished?null:s.jsx(n.Typography,{children:v.I18n.t("Performing this update will restart the js-controller afterwards!")}),this.state.inProgress?s.jsx(n.Box,{sx:{display:"flex",justifyContent:"center"},children:s.jsx(n.CircularProgress,{})}):null,this.state.success?s.jsx(n.Typography,{children:v.I18n.t("Node.js update successful, restarting controller now!")}):null,this.state.error?s.jsx(n.Typography,{sx:{color:"red"},children:v.I18n.t("Node.js update failed: %s",this.state.error)}):null]}),s.jsxs(n.DialogActions,{children:[s.jsx(n.Button,{disabled:this.state.inProgress||this.state.finished,color:"primary",variant:"contained",startIcon:s.jsx(f.Refresh,{}),onClick:()=>this.updateNodeJsVersion(),children:v.I18n.t("Upgrade")}),s.jsx(n.Button,{disabled:this.state.inProgress,variant:"contained",onClick:()=>{this.props.onClose()},color:"primary",startIcon:s.jsx(f.Close,{}),children:v.I18n.t("Close")})]})]})}async updateNodeJsVersion(){this.setState({inProgress:!0});const t=await this.props.socket.upgradeOsPackages(this.props.hostId,[{name:"nodejs"}],!0);this.setState({inProgress:!1,success:t.success,error:t.error,finished:!0})}}const m={button:{position:"static",margin:0},saveButton:g=>({backgroundColor:g.palette.success.main,right:80,"&:hover":{backgroundColor:g.palette.success.dark}}),addButton:g=>({backgroundColor:g.palette.secondary.main,right:144,"&:hover":{backgroundColor:g.palette.secondary.dark}}),closeButton:g=>({backgroundColor:g.palette.error.main,"&:hover":{backgroundColor:g.palette.error.dark}}),bold:{fontWeight:"bold"},hostOffline:{color:"#bb0000"},updateExists:{color:"#c28700",marginRight:4},updateNo:{color:"#00b204",marginRight:4},nodeUpdate:{opacity:.6},instanceNumber:{opacity:.7,fontSize:16},updateIcon:{cursor:"pointer",fontSize:16},tooltip:{pointerEvents:"none"},viewModeDiv:{position:"relative",display:"flex",flexFlow:"wrap",width:"100%",minHeight:80,paddingBottom:80,overflow:"visible",justifyContent:"left"}},T={Uptime:S.formatSeconds,"System uptime":S.formatSeconds,RAM:S.formatRam,Speed:S.formatSpeed,"Disk size":S.formatBytes,"Disk free":S.formatBytes};class C extends B.Component{#t=1800*1e3;#e=300*1e3;#s=60*1e3;introLinksOriginal;deactivatedOriginal;t;getDataTimeout;constructor(t){super(t),this.state={instances:null,deactivated:[],edit:!1,link:null,introLinks:[],editLink:!1,editLinkIndex:-1,openSnackBar:!1,hasUnsavedChanges:!1,reverseProxy:null,alive:{},hostsData:{},hosts:null,hostTimeDiffMap:new Map,hostDataTimestampMap:new Map,nodeUpdateSupported:!1,nodeUpdateDialog:null},this.t=t.t}checkBackendTime(){const t=this.state.hostTimeDiffMap,e=this.state.hostDataTimestampMap,o=Date.now();for(const[i,d]of Object.entries(this.state.hostsData)){const r=Math.abs(d.time-o);t.set(i,r),e.set(i,o)}this.setState({hostTimeDiffMap:t,hostDataTimestampMap:e})}async componentDidMount(){var i;window.NEXOWATT_EOS_ADMIN_SOCKET=this.props.socket,window.NEXOWATT_EOS_SOCKET=this.props.socket,window.dispatchEvent(new CustomEvent("nexowatt-eos-admin-socket-ready"));let t=null,e=!1;try{[t,e]=await Promise.all([this.props.socket.getObject(`system.adapter.${this.props.adminInstance}`),this.props.socket.checkFeatureSupported("CONTROLLER_OS_PACKAGE_UPGRADE")])}catch(d){if(String(window.NEXOWATT_EOS_ACCESS_ROLE||"unknown").toLowerCase()==="admin")throw d}const o=((i=t==null?void 0:t.native)==null?void 0:i.reverseProxy)||[];await new Promise(d=>this.setState({reverseProxy:o,nodeUpdateSupported:e},()=>d())),await this.getData(),this.props.instancesWorker.registerHandler(this.getDataDelayed),this.props.hostsWorker.registerHandler(this.updateHosts),this.props.hostsWorker.registerAliveHandler(this.updateHostsAlive),this.checkBackendTime()}componentWillUnmount(){this.getDataTimeout&&(clearTimeout(this.getDataTimeout),this.getDataTimeout=void 0),this.props.instancesWorker.unregisterHandler(this.getDataDelayed),this.props.hostsWorker.unregisterHandler(this.updateHosts),this.props.hostsWorker.unregisterAliveHandler(this.updateHostsAlive)}updateHostsAlive=async t=>{const e=JSON.parse(JSON.stringify(this.state.alive)),o=[];if(t.find(i=>i.type==="deleted")){this.getDataDelayed();return}if(t.forEach(i=>{!!e[i.id]!=!!i.alive&&(e[i.id]=i.alive,o.push(i.id))}),o.length){const i=JSON.parse(JSON.stringify(this.state.hostsData)),d=new Map(this.state.hostDataTimestampMap),r=Date.now();(await Promise.all(o.map(l=>this.getHostData(l,e[l])))).forEach(l=>{i[l.id]=C.preprocessHostData(l.data),d.set(l.id,r)}),this.setState({alive:e,hostsData:i,hostDataTimestampMap:d},()=>this.checkBackendTime())}};updateHosts=t=>{let e=[];if(t.find(o=>!o.obj)){this.getDataDelayed();return}if(e=t.map(o=>o.id),e.length){const o=JSON.parse(JSON.stringify(this.state.hostsData)),i=new Map(this.state.hostDataTimestampMap),d=Date.now();Promise.all(e.map(r=>this.getHostData(r))).then(r=>{r.forEach(a=>{o[a.id]=C.preprocessHostData(a.data),i.set(a.id,d)}),this.setState({hostsData:o,hostDataTimestampMap:i})})}};async activateEditMode(){var i;const t=await this.props.socket.getSystemConfig(!0),e=await this.getInstances(!0,null,t),o=(i=t==null?void 0:t.native)!=null&&i.introLinks?t.native.introLinks:[];this.introLinksOriginal=JSON.stringify(o),this.deactivatedOriginal=JSON.parse(JSON.stringify(e.deactivated)),this.setState({instances:e.instances,deactivated:e.deactivated,edit:!0,introLinks:o,hasUnsavedChanges:!1})}deactivateEditMode(){this.state.hasUnsavedChanges,this.setState({deactivated:this.deactivatedOriginal,introLinks:JSON.parse(this.introLinksOriginal),hasUnsavedChanges:!1,edit:!1},()=>{this.deactivatedOriginal=null,this.introLinksOriginal=null})}toggleCard(t,e){if(!this.state.instances||!this.state.instances.length)return;const o=JSON.parse(JSON.stringify(this.state.deactivated)),i=o.indexOf(`${t}_${e}`);i!==-1?o.splice(i,1):(o.push(`${t}_${e}`),o.sort());const d=JSON.stringify(o)!==JSON.stringify(this.deactivatedOriginal)||JSON.stringify(this.state.introLinks)!==this.introLinksOriginal;this.setState({deactivated:o,hasUnsavedChanges:d})}getInstancesCards(){var t;return(t=this.state.instances)==null?void 0:t.map(e=>{var i,d;const o=String(window.NEXOWATT_EOS_ACCESS_ROLE||"admin").toLowerCase()!=="admin"&&String(window.NEXOWATT_EOS_ACCESS_ROLE||"admin").toLowerCase()!=="service"&&/^nexowatt-ui(?:\.|$)/i.test(e.id)||!((i=this.state.deactivated)!=null&&i.includes(`${e.id}_${e.linkName}`));if(o||this.state.edit){let r=e.link?e.link.replace(/^https?:\/\//,""):"";if(r=r.split("/")[0],e.id===this.props.adminInstance)return null;let a=window.isFinite(e.id.split(".").pop());a&&(a=!!((d=this.state.instances)!=null&&d.find(k=>k.id!==e.id&&e.name===k.name&&e.id.split(".")[0]===k.id.split(".")[0])));const l=this.state.hostsData?this.state.hostsData[e.id]:null,h=this.state.hostTimeDiffMap.get(e.id)??0,p=this.state.hostDataTimestampMap.get(e.id)??0,u=Date.now()-p<this.#e;return s.jsx(O,{image:e.image,title:s.jsxs(s.Fragment,{children:[s.jsx("span",{style:e.name&&e.name.length>12?{fontSize:"1rem"}:void 0,children:e.name}),a?s.jsxs("span",{style:m.instanceNumber,children:[".",e.id.split(".").pop()]}):null]}),action:{link:e.link,text:r},t:this.props.t,lang:this.props.lang,color:e.color,showInfo:!!e.info,edit:this.state.edit,offline:l&&l.alive===!1,warning:h>this.#t&&u?this.t("Backend time differs by %s minutes",Math.round(h/this.#s).toString()):null,enabled:o,disabled:!l||typeof l!="object",getHostDescriptionAll:()=>this.getHostDescriptionAll(e.id),toggleActivation:()=>this.toggleCard(e.id,e.linkName),openSnackBarFunc:()=>this.setState({openSnackBar:!0}),theme:this.props.theme,children:e.description||this.getHostDescription(e.id)},`${e.id}_${e.link}`)}return null})}toggleLinkCard(t){const e=JSON.parse(JSON.stringify(this.state.introLinks));e[t].enabled=!e[t].enabled;const o=JSON.stringify(this.state.deactivated)!==JSON.stringify(this.deactivatedOriginal)||JSON.stringify(e)!==this.introLinksOriginal;this.setState({introLinks:e,hasUnsavedChanges:o})}getLinkCards(){var t;return(t=this.state.introLinks)==null?void 0:t.map((e,o)=>!e.enabled&&!this.state.edit?null:e.camera==="custom"?s.jsx(E,{image:e.image,title:e.name,action:{link:e.link,text:e.linkName},t:this.props.t,socket:this.props.socket,color:e.color,edit:this.state.edit,interval:e.interval,camera:e.camera,addTs:e.addTs,onEdit:()=>{var i;return this.setState({editLink:!0,editLinkIndex:o,link:JSON.parse(JSON.stringify((i=this.state.introLinks)==null?void 0:i[o]))})},onRemove:()=>{const i=JSON.parse(JSON.stringify(this.state.introLinks));i.splice(o,1);const d=JSON.stringify(this.state.deactivated)!==JSON.stringify(this.deactivatedOriginal)||JSON.stringify(i)!==this.introLinksOriginal;this.setState({introLinks:i,hasUnsavedChanges:d})},enabled:e.enabled,lang:this.props.lang,toggleActivation:()=>this.toggleLinkCard(o),cameraUrl:e.desc,theme:this.props.theme},`link${o}`):s.jsx(O,{image:e.image,title:e.name,action:{link:e.link,text:e.linkName},t:this.props.t,color:e.color,edit:this.state.edit,onEdit:()=>{var i;return this.setState({editLink:!0,editLinkIndex:o,link:JSON.parse(JSON.stringify((i=this.state.introLinks)==null?void 0:i[o]))})},onRemove:()=>{const i=JSON.parse(JSON.stringify(this.state.introLinks));i.splice(o,1);const d=JSON.stringify(this.state.deactivated)!==JSON.stringify(this.deactivatedOriginal)||JSON.stringify(i)!==this.introLinksOriginal;this.setState({introLinks:i,hasUnsavedChanges:d})},enabled:e.enabled,lang:this.props.lang,toggleActivation:()=>this.toggleLinkCard(o),theme:this.props.theme,children:e.desc||""},`link${o}`))}editLinkCard(){return this.state.editLink?s.jsx(U,{link:this.state.link,socket:this.props.socket,isNew:this.state.editLinkIndex===-1,t:this.props.t,lang:this.props.lang,theme:this.props.theme,onClose:t=>{if(t){const e=JSON.parse(JSON.stringify(this.state.introLinks));this.state.editLinkIndex===-1?(t.enabled=!0,e.push(t)):(t.enabled=e[this.state.editLinkIndex].enabled,e[this.state.editLinkIndex]=t);const o=JSON.stringify(this.state.deactivated)!==JSON.stringify(this.deactivatedOriginal)||JSON.stringify(e)!==this.introLinksOriginal;this.setState({introLinks:e,editLink:!1,hasUnsavedChanges:o,link:null})}else this.setState({editLink:!1})}}):null}getButtons(){const t=[];return this.state.edit?(t.push(s.jsx(n.Fab,{color:"primary",size:"small",sx:v.Utils.getStyle(this.props.theme,m.button,m.addButton),onClick:()=>this.setState({editLink:!0,editLinkIndex:-1,link:{}}),children:s.jsx(f.Add,{})},"add")),t.push(s.jsx(n.Fab,{size:"small",color:"primary",disabled:!this.state.hasUnsavedChanges,sx:v.Utils.getStyle(this.props.theme,m.button,m.saveButton),onClick:()=>this.saveCards(),children:s.jsx(f.Check,{})},"save")),t.push(s.jsx(n.Fab,{size:"small",color:"primary",sx:v.Utils.getStyle(this.props.theme,m.button,m.closeButton),onClick:()=>this.deactivateEditMode(),children:s.jsx(f.Close,{})},"close"))):t.push(s.jsx(n.Fab,{color:"primary",size:"small",style:m.button,onClick:()=>this.activateEditMode(),children:s.jsx(f.Create,{})},"edit")),t}async saveCards(){const t=await this.props.socket.getSystemConfig(!0);let e=!1;JSON.stringify(t.common.intro)!==JSON.stringify(this.state.deactivated)&&(t.common.intro=this.state.deactivated,e=!0),!e&&JSON.stringify(t.native.introLinks)!==JSON.stringify(this.state.introLinks)&&(e=!0,t.native.introLinks=this.state.introLinks),e?this.props.socket.setSystemConfig(t).then(()=>this.props.showAlert("Updated","success")).catch(o=>{console.log(o),this.props.showAlert(o,"error")}).then(()=>this.setState({edit:!1})):this.setState({edit:!1})}async getHostData(t,e){let o;if(e!==void 0)o={val:e};else try{o=await this.props.socket.getState(`${t}.alive`)}catch(r){console.error(`Cannot get state ${t}.alive: ${r}`),o={val:!1}}let i={alive:!1};if(o!=null&&o.val)try{i=await this.props.socket.getHostInfo(t,!1,1e4),i&&typeof i=="object"&&i.alive!==!1&&(i.alive=!0)}catch(r){console.error(`Cannot get host info for ${t}: ${r}`),i={alive:!1}}else i={alive:!1};const d=await this.props.socket.getForeignStates(`${t}.versions.*`);return Object.keys(d).forEach(r=>i[`_${r.split(".").pop()}`]=d[r].val),{id:t,data:i}}async getHostsData(t){const e=t.map(l=>this.getHostData(l._id)),o=await Promise.all(e),i={},d={},r=new Map(this.state.hostDataTimestampMap),a=Date.now();return o.forEach(l=>{i[l.id]=C.preprocessHostData(l.data),d[l.id]=l.data.alive,r.set(l.id,a)}),this.setState({hostDataTimestampMap:r}),{hostsData:i,alive:d}}addLinks(t,e,o,i,d,r){const a={id:t.id,name:t.name,description:t.description,color:t.color,image:t.icon,info:""},l=J(t.link,e.name,o,{instances:i,hostname:this.props.hostname,adminInstance:this.props.adminInstance,hosts:d}),h=this.state.reverseProxy;let p=null;if(h!=null&&h.length){const c=window.location.pathname;p=h.find(u=>{if(!u.globalPath)return!1;const k=u.globalPath.endsWith("/")?u.globalPath:`${u.globalPath}/`;return c===k||c.startsWith(k)})||null}if(l.length===1){a.link=l[0].url,a.port=l[0].port,a.link=P(a.link,a.id,i,p)||a.link;const c=r.find(u=>u.link===a.link);c?console.log(`Double links: "${a.id}" and "${c.id}"`):r.push(a)}else l.length>1&&l.forEach(c=>{const u=r.find(k=>k.link===c.url);if(u)console.log(`Double links: "${a.id}" and "${u.id}"`);else{const k={...a,link:c.url,port:c.port};k.link=P(k.link,a.id,i,p)||k.link,r.push(k)}})}static getText(t,e){return t?typeof t=="object"?t[e]||t.en||"":t||"":""}static normalizeLinks(t,e,o){if(!t.common.localLinks&&!t.common.localLink&&!t.common.welcomeScreen&&!t.common.welcomeScreenPro)return null;const i={id:t._id.replace("system.adapter.",""),link:"",name:C.getText(t.common.titleLang||t.common.title||t.common.name,e),order:t.common.order||1e3,intro:!0,description:C.getText(t.common.desc,e),icon:t.common.icon?`adapter/${t.common.name}/${t.common.icon}`:"img/no-image.svg"};let d=[];if(t.common.localLink)if(typeof t.common.localLink=="string")d.push({...i,link:t.common.localLink});else{const r=t.common.localLink;if(r.link){const a={...i,link:r.link};r.color&&(a.color=r.color),r.order!==void 0&&typeof r.order=="number"&&(a.order=r.order),r.icon&&r.img&&(a.icon=r.icon||r.img),d.push(a)}else console.warn(`Unknown localLink structure: ${JSON.stringify(t.common.localLink)}`)}if(t.common.localLinks&&typeof t.common.localLinks=="object"&&Object.keys(t.common.localLinks).forEach(r=>{const a=t.common.localLinks[r];if(typeof a=="string")d.push({...i,link:a});else{const l=a;if(l.link){const h={...i,id:t._id.replace("system.adapter.","")+(r==="_default"?"":` ${r}`),link:l.link,name:i.name+(r==="_default"?"":` ${r}`)};l.color&&(h.color=l.color),l.order!==void 0&&(h.order=parseInt(l.order,10)||1e3),l.icon&&l.img&&(h.icon=l.icon||l.img),l.description&&(h.description=C.getText(l.description,e)),l.pro!==void 0&&(typeof l.pro=="string"?h.pro=l.pro:h.pro=`${t.common.name}/index.html`),l.cloud!==void 0&&(h.cloud=l.cloud),l.intro!==void 0&&(h.intro=l.intro===!0),l.name&&(h.name=C.getText(l.name,e)),r==="_default"&&(h.default=!0),d.push(h)}else console.warn(`Unknown localLinks structure: ${JSON.stringify(a)}`)}}),t.common.welcomeScreen&&typeof t.common.welcomeScreen=="object"&&((Array.isArray(t.common.welcomeScreen)?t.common.welcomeScreen:[t.common.welcomeScreen]).forEach(a=>{if(a.link){const l={...i,id:`${t._id.replace("system.adapter.","")} cloud`,link:`%web_protocol%://%web_bind%:%web_port%/${a.link}`,cloud:a.link};if(a.color&&(l.color=a.color),a.order!==void 0&&typeof a.order=="number"&&(l.order=a.order),a.icon&&a.img&&(l.icon=a.icon||a.img),a.localLinks){const h=t.common.localLinks[a.localLinks];h&&typeof h=="string"?l.link=h:h&&typeof h=="object"&&h.link&&(l.link=h.link)}a.name&&(l.name=C.getText(a.name,e)),d.push(l)}}),t.common.welcomeScreenPro&&typeof t.common.welcomeScreenPro=="object"&&(Array.isArray(t.common.welcomeScreenPro)?t.common.welcomeScreenPro:[t.common.welcomeScreenPro]).forEach(l=>{if(l.link){const h={...i,id:`${t._id.replace("system.adapter.","")} pro`,link:`%web_protocol%://%web_bind%:%web_port%/${l.link}`,pro:l.link};if(l.color&&(h.color=l.color),l.order!==void 0&&typeof l.order=="number"&&(h.order=l.order),l.icon&&l.img&&(h.icon=l.icon||l.img),l.localLinks){const p=t.common.localLinks[l.localLinks];p&&typeof p=="string"?h.link=p:p&&typeof p=="object"&&p.link&&(h.link=p.link)}l.name&&(h.name=C.getText(l.name,e)),d.push(h)}})),d.forEach(r=>{!r.icon.startsWith("adapter/")&&!r.icon.startsWith("data:image/")&&!r.icon.startsWith("http://")&&!r.icon.startsWith("https://")&&r.icon!=="img/no-image.svg"&&(r.icon=`adapter/${t.common.name}/${r.icon}`)}),o){const r={};d.forEach(a=>{r[a.link]?(a.color&&(r[a.link].color=a.color),a.icon&&(r[a.link].icon=a.icon),a.cloud&&(r[a.link].cloud=a.cloud),a.pro&&(r[a.link].pro=a.pro),a.intro!==void 0&&(r[a.link].intro=a.intro),a.name&&typeof a.name=="object"&&(r[a.link].name=a.name),a.order!==void 0&&(r[a.link].order=a.order),a.default&&(r[a.link].default=a.default)):r[a.link]=a}),d=Object.values(r)}return d.sort((r,a)=>r.default===void 0&&a.default===void 0?r.order===void 0&&a.order===void 0?0:r.order===void 0?-1:a.order===void 0?1:r.order-a.order:r.default===void 0?-1:a.default===void 0?1:r.order===void 0&&a.order===void 0?0:r.order===void 0?-1:a.order===void 0?1:r.order-a.order),d}async getInstances(t,e,o){e=e||this.state.hosts;const i={};e.forEach(d=>i[d._id]=d);try{const d=await this.props.socket.getAdapterInstances("",t);let r=o.common.intro||[];Array.isArray(r)||(r=Object.keys(r),r.sort());const a=[],l={};d.forEach(p=>l[p._id]=p),d.forEach(p=>{if(!p)return;const c=p.common||null,u=p._id.split("."),k=parseInt(u.pop(),10);let j;if(c!=null&&c.name&&typeof c.name=="object"){const N=c==null?void 0:c.name;j=N[this.props.lang]||N.en}else j=(c==null?void 0:c.name)||"";if(!(j==="admin"&&c.localLink===(this.props.hostname||""))&&j!=="web"&&!(j&&j!=="vis-web-admin"&&j.match(/^vis-/)&&j!=="vis-2")&&!(j!=null&&j.match(/^icons-/))&&c&&(c.enabled||c.onlyWWW)){const N=C.normalizeLinks(p,this.props.lang,!0);N&&N.forEach(H=>this.addLinks(H,c,k,l,i,a))}}),a.forEach(p=>{p.link&&(p.linkName=p.link.replace("https://","").replace("http://","").replace(/^[^_]+:/,""))}),a.sort((p,c)=>{if(p.order!==void 0||c.order!==void 0){if(p.order=p.order===void 0?1e3:p.order,c.order=c.order===void 0?1e3:c.order,p.order<c.order)return-1;if(p.order>c.order)return 1}return p.id>c.id?1:p.id<c.id?-1:0}),e==null||e.forEach(p=>{const c=p==null?void 0:p.common;let u=c==null?void 0:c.name;if(typeof u=="object"&&u&&(u=u[this.props.lang]||u.en),c){const k={id:p._id,name:u||"",color:"",image:c.icon||"img/no-image.svg",info:this.t("Info"),linkName:""};a.push(k)}});const h=[];return r.forEach(p=>{a.find(c=>p===`${c.id}_${c.linkName}`)&&h.push(p)}),r=h,{instances:a,deactivated:r}}catch(d){return console.log(d),{instances:[],deactivated:[]}}}getHostDescription(t){const e=this.state.hostsData?this.state.hostsData[t]:null;if(e&&e.alive===!1)return s.jsx("div",{style:m.hostOffline,children:this.props.t("Offline")});let o="",i="";if(e){try{e._nodeNewest&&e["Node.js"]&&w.gt(e._nodeNewest,e["Node.js"].replace(/^v/,""))&&(o=e._nodeNewest)}catch{}try{e._nodeNewest!==e._nodeNewestNext&&e._nodeNewestNext&&e["Node.js"]&&e._nodeNewest&&w.gt(e._nodeNewestNext,e["Node.js"].replace(/^v/,""))&&w.gt(e._nodeNewestNext,e._nodeNewest)&&(o+=(o?" / ":"")+e._nodeNewestNext)}catch{}if(o){const d=this.state.nodeUpdateSupported&&e.Platform==="linux";o=s.jsx(n.Tooltip,{title:this.props.t("Some updates available"),slotProps:{popper:{sx:m.tooltip}},children:s.jsxs("span",{style:{...m.nodeUpdate,display:"inline-flex"},children:["(",o,")",d?s.jsx(f.Refresh,{style:m.updateIcon,onClick:()=>this.setState({nodeUpdateDialog:{hostId:t,version:e._nodeNewestNext}})}):null]})})}try{e._npmNewest&&e.NPM&&w.gt(e._npmNewest,e.NPM)&&(i=e._npmNewest)}catch{}try{e._npmNewest!==e._npmNewestNext&&e._npmNewestNext&&e.NPM&&e._npmNewest&&w.gt(e._npmNewestNext,e.NPM)&&w.gt(e._npmNewestNext,e._npmNewest)&&(i+=(i?" / ":"")+e._npmNewestNext)}catch{}i&&(i=s.jsx(n.Tooltip,{title:this.props.t("Some updates available"),slotProps:{popper:{sx:m.tooltip}},children:s.jsxs("span",{style:m.nodeUpdate,children:["(",i,")"]})}))}return e&&typeof e=="object"?s.jsxs("ul",{style:{textTransform:"none"},children:[s.jsx("li",{children:s.jsxs("span",{children:[s.jsxs("span",{style:m.bold,children:[this.t("Platform"),": "]}),e.Platform||"--"]})}),s.jsx("li",{children:s.jsxs("span",{children:[s.jsxs("span",{style:m.bold,children:[this.t("RAM"),": "]}),T.RAM(e.RAM)]})}),s.jsx("li",{children:s.jsxs("span",{children:[s.jsxs("span",{style:m.bold,children:[this.t("Node.js"),": "]}),s.jsx("span",{style:o?m.updateExists:m.updateNo,children:e["Node.js"]||"--"}),o]})}),s.jsx("li",{children:s.jsxs("span",{children:[s.jsxs("span",{style:m.bold,children:[this.t("NPM"),": "]}),s.jsx("span",{className:i?m.updateExists:m.updateNo,children:e.NPM||"--"}),i]})})]}):s.jsxs("ul",{children:[s.jsx(n.Skeleton,{}),s.jsx(n.Skeleton,{}),s.jsx(n.Skeleton,{}),s.jsx(n.Skeleton,{})]})}getHostDescriptionAll(t){const e=this.state.hostsData?this.state.hostsData[t]:null;return{el:s.jsx("ul",{style:{textTransform:"none"},children:e&&typeof e=="object"&&Object.keys(e).filter(o=>!o.startsWith("_")&&e[o]!==null&&e[o]!==void 0).map(o=>s.jsx("li",{children:e&&typeof e=="object"?s.jsxs("span",{children:[s.jsxs("span",{style:m.bold,children:[this.t(o),": "]}),T[o]?T[o](e[o],this.t):(typeof e[o]=="object"?JSON.stringify(e[o]):e[o].toString())||"--"]}):s.jsx(n.Skeleton,{})},o))}),text:e&&typeof e=="object"?Object.keys(e).reduce((o,i)=>`${o}${this.t(i)}:${T[i]?T[i](e[i],this.t):(typeof e[i]=="object"?JSON.stringify(e[i]):e[i])||"--"}
1
+ import{j as s}from"./DefaultPropsProvider-BiXBMQYQ.js";import{i as _,a as B}from"./iobroker_admin__loadShare__react__loadShare__-LM7uyL45.js";import{b as S,r as J,c as P,s as w}from"./bootstrap-COulQZax-v84.js";import{i as n,a as f}from"./iobroker_admin__loadShare___mf_0_mui_mf_1_icons_mf_2_material__loadShare__-CJO5yP3h.js";import{i as v}from"./iobroker_admin__loadShare___mf_0_iobroker_mf_1_adapter_mf_2_react_mf_2_v5__loadShare__-LFZoiUTt.js";import{b as $}from"./blue-CagzI6CQ.js";import{g as b,v as M}from"./createTheme-DFX8CY6F.js";import"./_commonjsHelpers-CE1G-McA.js";import"./iobroker_admin__mf_v__runtimeInit__mf_v__-g2X2zhAf.js";import"./emotion-serialize.esm-Q4o_CgeF.js";import"./iobroker_admin__loadShare___mf_0_emotion_mf_1_react__loadShare__-BywLg1Xe.js";import"./ace-DEUjyTIn.js";import"./iobroker_admin__loadShare___mf_0_iobroker_mf_1_json_mf_2_config__loadShare__-CpA7pnS5.js";import"./iobroker_admin__loadShare__leaflet__loadShare__-CNUAG3AH.js";import"./ext-language_tools-ylAoucDh.js";import"./iobroker_admin__loadShare__react_mf_2_dropzone__loadShare__-CwjnV48g.js";import"./iobroker_admin__loadShare__react_mf_2_dom__loadShare__-CVeAXnkk.js";import"./preload-helper-BDBacUwf.js";import"./sdk-C-e-e2gd.js";import"./extends-CF3RwP-h.js";import"./assertThisInitialized-B0aQ9eG_.js";import"./useTheme-Bl-M1DYp.js";import"./index-DcK0RDrH.js";import"./ThemeProvider-BOFFjWAF.js";import"./emotion-cache.browser.esm-BgJfNZJN.js";import"./setYear-3ufv5yRD.js";import"./en-US-DBFJNIH6.js";const L="0 2px 2px 0 rgba(0, 0, 0, .14),0 3px 1px -2px rgba(0, 0, 0, .12),0 1px 5px 0 rgba(0, 0, 0, .2)",A="0 8px 17px 0 rgba(0, 0, 0, .2),0 6px 20px 0 rgba(0, 0, 0, .19)",x={root:g=>({padding:".75rem",[g.breakpoints.up("xl")]:{flex:"0 1 20%"}}),card:{display:"flex",minHeight:"235px",position:"relative",overflow:"hidden",maxHeight:"235p","&:hover":{overflowY:"auto",boxShadow:A}},cardInfo:{display:"flex",minHeight:"235px",position:"relative",overflow:"initial",maxHeight:"235p",flexDirection:"column","&:hover":{boxShadow:A}},cardInfoHead:g=>({position:"sticky",top:0,background:g.palette.background.default,display:"flex",width:"100%",justifyContent:"space-between",borderBottom:"1px solid",padding:"5px 5px 0px 5px"}),edit:{opacity:.6,userSelect:"none",pointerEvents:"none"},media:g=>({backgroundColor:g.palette.mode==="dark"?"#535353":"#e2e2e2",maxWidth:"30%"}),img:{width:120,height:"auto",padding:"2rem .5rem",maxWidth:"100%"},contentContainer:{display:"flex",flexDirection:"column",flex:1},content:{height:"170px",flexGrow:1,overflowY:"hidden"},action:{minHeight:"49px",padding:"16px 24px"},expand:{position:"absolute",right:"10px",bottom:"10px"},collapse:{minHeight:"100%",backgroundColor:"#ffffff",position:"absolute",width:"100%"},enabled:{color:"#ffffff",backgroundColor:$[500],position:"absolute",top:8,right:8,boxShadow:L,"&:hover":{backgroundColor:$[300]},"&:focus":{backgroundColor:$[500]}},disabled:{color:"#ffffff",backgroundColor:b[500],position:"absolute",top:8,right:8,boxShadow:L,"&:hover":{backgroundColor:b[300]},"&:focus":{backgroundColor:b[500]}},editButton:{color:"#ffffff",backgroundColor:b[500],position:"absolute",top:64,right:8,boxShadow:L,"&:hover":{backgroundColor:b[300]},"&:focus":{backgroundColor:b[500]}},deleteButton:{color:"#ffffff",backgroundColor:M[500],position:"absolute",top:120,right:8,boxShadow:L,"&:hover":{backgroundColor:M[300]},"&:focus":{backgroundColor:M[500]}},contentGrid:{height:"100%"},colorOrange:{color:"#ffcc80"},tooltip:{pointerEvents:"none"}};class O extends _.Component{constructor(t){super(t),this.state={expanded:!1}}static getDerivedStateFromProps(t){return t.edit?{expanded:!1}:null}handleExpandClick(){this.setState({expanded:!this.state.expanded})}renderContent(){return this.props.children}openDialog(){}renderDialogs(){return null}render(){var o,i;const t=this.props.edit?x.edit:void 0;let e=this.props.action.text||this.props.t("Link");return typeof e=="object"&&(e=e[this.props.lang]||e.en),s.jsx(n.Grid2,{size:{xs:12,sm:6,md:4,lg:3,xl:2},sx:v.Utils.getStyle(this.props.theme,x.root,this.props.style),style:{maxWidth:500},children:s.jsx(n.Link,{href:!this.props.edit&&this.props.action&&this.props.action.link?this.props.action.link:null,underline:"none",target:"_blank",rel:"noopener noreferrer",children:s.jsxs(n.Card,{sx:x.card,onClick:d=>{d.stopPropagation(),this.openDialog()},children:[this.props.showInfo&&!this.props.offline&&s.jsx(n.Button,{style:{...x.expand,...t},variant:"contained",size:"small",disabled:this.props.disabled,onClick:()=>this.handleExpandClick(),color:"primary",children:this.props.t("Info")}),s.jsxs(n.Box,{component:"div",sx:v.Utils.getStyle(this.props.theme,x.media,t,this.props.color&&{backgroundColor:this.props.color},{display:"flex",flexDirection:"column"}),children:[s.jsx(n.CardMedia,{style:x.img,component:"img",image:this.props.image}),s.jsx("div",{style:{flex:1,display:"flex",paddingBottom:"5px",paddingLeft:"5px"},children:this.props.warning?s.jsx(n.Tooltip,{title:this.props.warning,slotProps:{popper:{sx:x.tooltip}},children:s.jsx(f.Warning,{style:{alignSelf:"end",fontSize:36}})}):null})]}),s.jsxs("div",{style:{...x.contentContainer,...t},children:[s.jsx(n.CardContent,{style:x.content,children:s.jsxs(n.Grid2,{container:!0,direction:"column",wrap:"nowrap",style:x.contentGrid,children:[s.jsx(n.Typography,{gutterBottom:!0,variant:"h5",component:"h5",children:this.props.title}),this.renderContent()]})}),((o=this.props.action)==null?void 0:o.link)&&s.jsx(n.Divider,{}),((i=this.props.action)==null?void 0:i.link)&&s.jsx(n.CardActions,{style:x.action,children:s.jsx("div",{style:x.colorOrange,children:S.getText(e,this.props.lang)})})]}),this.props.showInfo&&s.jsx(n.Collapse,{style:x.collapse,in:this.state.expanded,timeout:"auto",unmountOnExit:!0,children:s.jsxs(n.Card,{sx:x.cardInfo,children:[s.jsxs(n.Box,{component:"div",sx:x.cardInfoHead,children:[s.jsx(n.Typography,{gutterBottom:!0,variant:"h5",component:"h5",children:this.props.t("Info")}),s.jsxs("div",{children:[s.jsx(n.IconButton,{size:"small",onClick:()=>{this.props.getHostDescriptionAll&&v.Utils.copyToClipboard(this.props.getHostDescriptionAll().text),this.props.openSnackBarFunc&&this.props.openSnackBarFunc()},children:s.jsx(v.IconCopy,{})}),s.jsx(n.IconButton,{size:"small",onClick:()=>this.handleExpandClick(),children:s.jsx(f.Close,{})})]})]}),s.jsx(n.CardContent,{children:this.props.getHostDescriptionAll().el})]})}),this.props.edit&&this.props.toggleActivation&&s.jsx(n.IconButton,{size:"large",sx:this.props.enabled?x.enabled:x.disabled,onClick:()=>this.props.toggleActivation(),children:s.jsx(f.Check,{})}),this.props.edit&&this.props.onEdit&&s.jsx(n.IconButton,{size:"large",sx:x.editButton,onClick:()=>this.props.onEdit(),children:s.jsx(f.Create,{})}),this.props.edit&&this.props.onRemove&&s.jsx(n.IconButton,{size:"large",sx:x.deleteButton,onClick:()=>this.props.onRemove(),children:s.jsx(f.Delete,{})}),this.renderDialogs()]})})})}}const I={closeButton:g=>({position:"absolute",right:8,top:8,color:g.palette.grey[500]}),paper:{},typography:{paddingRight:30},img:{width:"100%",height:"100%",objectFit:"contain"}};class R extends _.Component{cameraUpdateTimer;cameraRef;constructor(t){super(t),this.cameraUpdateTimer=null,this.cameraRef=_.createRef()}componentDidMount(){this.props.camera&&this.props.camera!=="text"&&(this.cameraUpdateTimer=setInterval(()=>this.updateCamera(),Math.max(parseInt(this.props.interval,10),500)),this.updateCamera())}componentWillUnmount(){this.cameraUpdateTimer&&(clearInterval(this.cameraUpdateTimer),this.cameraUpdateTimer=null)}updateCamera(){if(this.cameraRef.current)if(this.props.camera==="custom"){let t=this.props.cameraUrl;this.props.addTs&&(t.includes("?")?t+=`&ts=${Date.now()}`:t+=`?ts=${Date.now()}`),this.cameraRef.current.src=t}else{const t=this.props.camera.split("."),e=t.shift(),o=t.shift();this.props.socket.sendTo(`${e}.${o}`,"image",{name:t.pop(),width:this.cameraRef.current.width}).then(i=>{i&&i.data&&this.cameraRef.current&&(this.cameraRef.current.src=`data:image/jpeg;base64,${i.data}`)})}}render(){return s.jsxs(n.Dialog,{onClose:()=>this.props.onClose(),open:!0,maxWidth:"xl",fullWidth:!0,fullScreen:!0,sx:{"& .MuiDialog-paper":I.paper},children:[s.jsx(n.DialogTitle,{children:s.jsxs(n.Typography,{component:"h2",variant:"h6",sx:{"&.MuiTypography-root":I.typography},children:[this.props.name,s.jsx(n.IconButton,{size:"large",sx:I.closeButton,onClick:()=>this.props.onClose(),children:s.jsx(f.Close,{})})]})}),s.jsx(n.DialogContent,{dividers:!0,children:s.jsx("img",{style:I.img,src:"",alt:"camera",ref:this.cameraRef})}),s.jsx(n.DialogActions,{children:s.jsx(n.Button,{variant:"contained",autoFocus:!0,onClick:t=>{t.stopPropagation(),this.props.onClose()},color:"primary",startIcon:s.jsx(f.Close,{}),children:this.props.t("Close")})})]})}}const D={cameraImg:{width:"100%",height:"100%",maxWidth:200,maxHeight:200,objectFit:"contain"},imgContainer:{height:"100%"},hidden:{display:"none"},imgSkeleton:{transform:"initial"}};class E extends O{cameraRef;cameraUpdateTimer;interval;constructor(t){super(t),Object.assign(this.state,{error:!1,dialog:!1,loaded:!1}),this.cameraRef=_.createRef(),this.cameraUpdateTimer=null,this.interval=t.interval}updateCamera(){if(this.cameraRef.current)if(this.props.camera==="custom"){let t=this.props.cameraUrl;this.props.addTs&&(t.includes("?")?t+=`&ts=${Date.now()}`:t+=`?ts=${Date.now()}`),this.cameraRef.current.src=t}else{const t=this.props.camera.split("."),e=t.shift(),o=t.shift();this.props.socket.sendTo(`${e}.${o}`,"image",{name:t.pop(),width:this.cameraRef.current.width}).then(i=>{i!=null&&i.data&&this.cameraRef.current&&(this.cameraRef.current.src=`data:image/jpeg;base64,${i.data}`)}).catch(i=>window.alert(`Cannot send to instance: ${i}`))}}componentDidMount(){this.props.camera&&this.props.camera!=="text"&&(this.cameraUpdateTimer=setInterval(()=>this.updateCamera(),Math.max(parseInt(this.props.interval,10),500)),this.updateCamera())}componentWillUnmount(){this.cameraUpdateTimer&&(clearInterval(this.cameraUpdateTimer),this.cameraUpdateTimer=null)}renderDialogs(){return this.state.dialog?s.jsx(R,{socket:this.props.socket,camera:this.props.camera,name:this.props.title,t:this.props.t,onClose:()=>{this.props.camera&&this.props.camera!=="text"&&(this.cameraUpdateTimer&&clearInterval(this.cameraUpdateTimer),this.cameraUpdateTimer=setInterval(()=>this.updateCamera(),Math.max(parseInt(this.props.interval,10),500)),this.updateCamera()),this.setState({dialog:!1})},cameraUrl:this.props.cameraUrl}):null}handleImageLoad(){this.state.loaded||this.setState({loaded:!0,error:!1})}handleImageError(){this.state.error||this.setState({loaded:!1,error:!0})}renderContent(){if(this.props.camera==="custom"){let t=this.props.cameraUrl;return this.props.addTs&&(t.includes("?")?t+=`&ts=${Date.now()}`:t+=`?ts=${Date.now()}`),s.jsxs(n.Grid2,{container:!0,style:D.imgContainer,justifyContent:"center",alignItems:"center",children:[s.jsx("img",{ref:this.cameraRef,src:t,alt:"Camera",style:this.state.loaded&&!this.state.error?D.cameraImg:D.hidden,onLoad:()=>this.handleImageLoad(),onError:()=>this.handleImageError()}),!this.state.loaded&&!this.state.error&&s.jsx(n.Skeleton,{height:"100%",width:"100%",animation:"wave",style:D.imgSkeleton}),this.state.error&&s.jsx(f.Error,{fontSize:"large"})]})}return this.props.camera.startsWith("cameras.")?s.jsx("img",{ref:this.cameraRef,src:"",alt:"camera",style:D.cameraImg}):null}render(){return this.props.camera&&this.props.camera!=="text"?this.interval!==this.props.interval&&(this.interval=this.props.interval,this.cameraUpdateTimer&&clearInterval(this.cameraUpdateTimer),this.cameraUpdateTimer=setInterval(()=>this.updateCamera(),Math.max(parseInt(this.props.interval,10),500))):this.cameraUpdateTimer&&(clearInterval(this.cameraUpdateTimer),this.cameraUpdateTimer=null),super.render()}}const y={formControl:{marginTop:32},rootGrid:{flexGrow:1},closeButton:g=>({position:"absolute",right:8,top:8,color:g.palette.grey[500]}),paper:{},typography:{paddingRight:30},editItem:{marginTop:8},editItemSlider:{marginTop:24},labelSlider:{marginTop:16,fontSize:"1rem"},editColor:{width:"100%"}};class U extends _.Component{constructor(t){super(t),this.state={image:"",name:t.t("New link"),link:"http://",linkName:"",color:"",desc:"",addTs:!0,interval:5e3,camera:"text",cameraList:[],...t.link}}componentDidMount(){this.getCamerasInstances()}getCamerasInstances(){this.props.socket.getAdapterInstances("cameras",!0).then(t=>{const e=[],o=[];t.forEach(i=>{const d=i._id.replace("system.adapter.","");i.common&&i.common.enabled&&o.push(this.props.socket.getState(`${i._id}.alive`).then(r=>r&&r.val&&this.props.socket.sendTo(d,"list",null)).then(r=>r&&r.list&&r.list.forEach(a=>e.push({id:a.id,name:`${a.desc} [${d}/${a.name}]`}))))}),Promise.all(o).then(()=>this.setState({cameraList:e}))})}static getLinkNameFromLink(t){const e=t.trim().match(/^https?:\/\/([^/:]+)(:\d+)?/);return e?e[1]+(e[2]||""):""}render(){return s.jsxs(n.Dialog,{onClose:()=>this.props.onClose(),open:!0,maxWidth:"md",fullWidth:!0,sx:{"& .MuiDialog-paper":y.paper},children:[s.jsx(n.DialogTitle,{children:s.jsxs(n.Typography,{component:"h2",variant:"h6",sx:{"&.MuiTypography-root":y.typography},children:[this.props.isNew?this.props.t("Add new link: "):this.props.t("Edit link"),s.jsx(n.IconButton,{size:"large",sx:y.closeButton,onClick:()=>this.props.onClose(),children:s.jsx(f.Close,{})})]})}),s.jsx(n.DialogContent,{dividers:!0,children:s.jsxs(n.Grid2,{style:y.rootGrid,container:!0,direction:"row",children:[s.jsx(n.Grid2,{size:{xs:12,sm:6,md:8,lg:9},children:s.jsxs(n.Grid2,{container:!0,direction:"column",children:[s.jsxs(n.FormControl,{variant:"standard",style:y.formControl,children:[s.jsx(n.InputLabel,{id:"select-helper-label",children:this.props.t("Link type")}),s.jsxs(n.Select,{variant:"standard",labelId:"select-helper-label",value:this.state.camera,onChange:t=>this.setState({camera:t.target.value}),children:[s.jsx(n.MenuItem,{value:"text",children:s.jsx("em",{children:this.props.t("Description")})},"desc"),this.state.cameraList.map(t=>s.jsx(n.MenuItem,{value:t.id,children:t.name},t.id)),s.jsx(n.MenuItem,{value:"custom",children:this.props.t("Custom camera URL")},"custom")]})]}),s.jsx(n.TextField,{variant:"standard",label:this.props.t("URL"),value:this.state.link,style:y.editItem,onChange:t=>{const e=U.getLinkNameFromLink(this.state.link);e&&(!this.state.linkName||e===this.state.linkName)?this.setState({link:t.target.value,linkName:U.getLinkNameFromLink(t.target.value)}):this.setState({link:t.target.value})},slotProps:{input:{endAdornment:this.state.link?s.jsx(n.InputAdornment,{position:"end",children:s.jsx(n.IconButton,{tabIndex:-1,size:"small",onClick:()=>this.setState({link:""}),children:s.jsx(f.Close,{})})}):null}}}),s.jsx(n.TextField,{variant:"standard",style:y.editItem,label:this.props.t("Name"),value:this.state.name||"",onChange:t=>this.setState({name:t.target.value}),slotProps:{input:{endAdornment:this.state.name?s.jsx(n.InputAdornment,{position:"end",children:s.jsx(n.IconButton,{tabIndex:-1,size:"small",onClick:()=>this.setState({name:""}),children:s.jsx(f.Close,{})})}):null}}}),this.state.link?s.jsx(n.TextField,{variant:"standard",style:y.editItem,label:this.props.t("Link name"),value:this.state.linkName||"",onChange:t=>this.setState({linkName:t.target.value}),slotProps:{input:{endAdornment:this.state.linkName?s.jsx(n.InputAdornment,{position:"end",children:s.jsx(n.IconButton,{tabIndex:-1,size:"small",onClick:()=>this.setState({linkName:""}),children:s.jsx(f.Close,{})})}):null}}}):null,this.state.camera==="custom"||this.state.camera==="text"?s.jsx(n.TextField,{variant:"standard",style:y.editItem,label:this.state.camera==="custom"?this.props.t("Camera URL"):this.props.t("Description"),value:this.state.desc||"",onChange:t=>this.setState({desc:t.target.value}),slotProps:{input:{endAdornment:this.state.desc?s.jsx(n.InputAdornment,{position:"end",children:s.jsx(n.IconButton,{tabIndex:-1,size:"small",onClick:()=>this.setState({desc:""}),children:s.jsx(f.Close,{})})}):null}}}):null,this.state.camera==="custom"?s.jsx(n.FormControlLabel,{style:y.editItem,control:s.jsx(n.Checkbox,{checked:this.state.addTs,onChange:t=>this.setState({addTs:t.target.checked})}),label:this.props.t("Add timestamp to URL")}):null,this.state.camera!=="text"?s.jsx(n.Typography,{style:y.labelSlider,gutterBottom:!0,children:"Polling interval in ms"}):null,this.state.camera!=="text"?s.jsx(n.Slider,{style:y.editItemSlider,value:this.state.interval,getAriaValueText:()=>`${this.state.interval}ms`,onChange:(t,e)=>this.setState({interval:e}),step:100,min:500,max:6e4,valueLabelDisplay:"on"}):null,s.jsx("div",{style:{...y.editItem,width:50},children:s.jsx(n.TextField,{variant:"standard",fullWidth:!0,label:this.props.t("Color"),style:y.editColor,type:"color",value:this.state.color,onChange:t=>this.setState({color:t.target.value})})}),s.jsx(v.UploadImage,{disabled:!1,crop:!0,maxSize:256*1024,icon:this.state.image,removeIconFunc:()=>this.setState({image:""}),onChange:t=>this.setState({image:t})})]})}),s.jsx(n.Grid2,{size:{xs:12,sm:6,md:4,lg:3},children:this.state.camera==="text"?s.jsx(O,{image:this.state.image,title:this.state.name,action:{link:this.state.link,text:this.state.linkName},t:this.props.t,lang:this.props.lang,style:{width:"100% !important",maxWidth:"100% !important",marginLeft:"8px"},color:this.state.color,enabled:!0,theme:this.props.theme,children:this.state.desc}):s.jsx(E,{interval:this.state.interval,camera:this.state.camera,addTs:this.state.addTs,style:{width:"100% !important",maxWidth:"100% !important",marginLeft:"8px"},image:this.state.image,title:this.state.name,socket:this.props.socket,action:{link:this.state.link,text:this.state.linkName},t:this.props.t,lang:this.props.lang,color:this.state.color,enabled:!0,cameraUrl:this.state.desc,theme:this.props.theme})})]})}),s.jsxs(n.DialogActions,{children:[s.jsx(n.Button,{variant:"contained",autoFocus:!0,onClick:()=>{this.props.onClose({link:this.state.link,name:this.state.name,desc:this.state.desc,linkName:this.state.linkName,color:this.state.color,image:this.state.image,addTs:this.state.addTs,camera:this.state.camera,interval:this.state.interval})},color:"primary",startIcon:this.props.isNew?s.jsx(f.Add,{}):s.jsx(f.Check,{}),children:this.props.isNew?this.props.t("Add"):this.props.t("Save")}),s.jsx(n.Button,{variant:"contained",onClick:()=>this.props.onClose(),color:"grey",startIcon:s.jsx(f.Close,{}),children:this.props.t("Close")})]})]})}}class W extends B.Component{constructor(t){super(t),this.state={inProgress:!1,success:!1,error:"",finished:!1}}render(){return s.jsxs(n.Dialog,{open:!0,maxWidth:"lg",fullWidth:!0,children:[s.jsx(n.DialogTitle,{children:v.I18n.t("Node.js upgrade")}),s.jsxs(n.DialogContent,{style:{height:100,padding:"0 20px",overflow:"hidden"},children:[this.state.finished?null:s.jsx(n.Typography,{children:v.I18n.t("Performing this update will restart the js-controller afterwards!")}),this.state.inProgress?s.jsx(n.Box,{sx:{display:"flex",justifyContent:"center"},children:s.jsx(n.CircularProgress,{})}):null,this.state.success?s.jsx(n.Typography,{children:v.I18n.t("Node.js update successful, restarting controller now!")}):null,this.state.error?s.jsx(n.Typography,{sx:{color:"red"},children:v.I18n.t("Node.js update failed: %s",this.state.error)}):null]}),s.jsxs(n.DialogActions,{children:[s.jsx(n.Button,{disabled:this.state.inProgress||this.state.finished,color:"primary",variant:"contained",startIcon:s.jsx(f.Refresh,{}),onClick:()=>this.updateNodeJsVersion(),children:v.I18n.t("Upgrade")}),s.jsx(n.Button,{disabled:this.state.inProgress,variant:"contained",onClick:()=>{this.props.onClose()},color:"primary",startIcon:s.jsx(f.Close,{}),children:v.I18n.t("Close")})]})]})}async updateNodeJsVersion(){this.setState({inProgress:!0});const t=await this.props.socket.upgradeOsPackages(this.props.hostId,[{name:"nodejs"}],!0);this.setState({inProgress:!1,success:t.success,error:t.error,finished:!0})}}const m={button:{position:"absolute",bottom:16,right:16},saveButton:g=>({backgroundColor:g.palette.success.main,right:80,"&:hover":{backgroundColor:g.palette.success.dark}}),addButton:g=>({backgroundColor:g.palette.secondary.main,right:144,"&:hover":{backgroundColor:g.palette.secondary.dark}}),closeButton:g=>({backgroundColor:g.palette.error.main,"&:hover":{backgroundColor:g.palette.error.dark}}),bold:{fontWeight:"bold"},hostOffline:{color:"#bb0000"},updateExists:{color:"#c28700",marginRight:4},updateNo:{color:"#00b204",marginRight:4},nodeUpdate:{opacity:.6},instanceNumber:{opacity:.7,fontSize:16},updateIcon:{cursor:"pointer",fontSize:16},tooltip:{pointerEvents:"none"},viewModeDiv:{position:"relative",display:"flex",flexFlow:"wrap",width:"100%",minHeight:72,paddingBottom:72,overflow:"visible",justifyContent:"left"}},T={Uptime:S.formatSeconds,"System uptime":S.formatSeconds,RAM:S.formatRam,Speed:S.formatSpeed,"Disk size":S.formatBytes,"Disk free":S.formatBytes};class C extends B.Component{#t=1800*1e3;#e=300*1e3;#s=60*1e3;introLinksOriginal;deactivatedOriginal;t;getDataTimeout;constructor(t){super(t),this.state={instances:null,deactivated:[],edit:!1,link:null,introLinks:[],editLink:!1,editLinkIndex:-1,openSnackBar:!1,hasUnsavedChanges:!1,reverseProxy:null,alive:{},hostsData:{},hosts:null,hostTimeDiffMap:new Map,hostDataTimestampMap:new Map,nodeUpdateSupported:!1,nodeUpdateDialog:null},this.t=t.t}checkBackendTime(){const t=this.state.hostTimeDiffMap,e=this.state.hostDataTimestampMap,o=Date.now();for(const[i,d]of Object.entries(this.state.hostsData)){const r=Math.abs(d.time-o);t.set(i,r),e.set(i,o)}this.setState({hostTimeDiffMap:t,hostDataTimestampMap:e})}async componentDidMount(){var i;window.NEXOWATT_EOS_ADMIN_SOCKET=this.props.socket,window.NEXOWATT_EOS_SOCKET=this.props.socket,window.dispatchEvent(new CustomEvent("nexowatt-eos-admin-socket-ready"));let t=null,e=!1;try{[t,e]=await Promise.all([this.props.socket.getObject(`system.adapter.${this.props.adminInstance}`),this.props.socket.checkFeatureSupported("CONTROLLER_OS_PACKAGE_UPGRADE")])}catch(d){if(String(window.NEXOWATT_EOS_ACCESS_ROLE||"unknown").toLowerCase()==="admin")throw d}const o=((i=t==null?void 0:t.native)==null?void 0:i.reverseProxy)||[];await new Promise(d=>this.setState({reverseProxy:o,nodeUpdateSupported:e},()=>d())),await this.getData(),this.props.instancesWorker.registerHandler(this.getDataDelayed),this.props.hostsWorker.registerHandler(this.updateHosts),this.props.hostsWorker.registerAliveHandler(this.updateHostsAlive),this.checkBackendTime()}componentWillUnmount(){this.getDataTimeout&&(clearTimeout(this.getDataTimeout),this.getDataTimeout=void 0),this.props.instancesWorker.unregisterHandler(this.getDataDelayed),this.props.hostsWorker.unregisterHandler(this.updateHosts),this.props.hostsWorker.unregisterAliveHandler(this.updateHostsAlive)}updateHostsAlive=async t=>{const e=JSON.parse(JSON.stringify(this.state.alive)),o=[];if(t.find(i=>i.type==="deleted")){this.getDataDelayed();return}if(t.forEach(i=>{!!e[i.id]!=!!i.alive&&(e[i.id]=i.alive,o.push(i.id))}),o.length){const i=JSON.parse(JSON.stringify(this.state.hostsData)),d=new Map(this.state.hostDataTimestampMap),r=Date.now();(await Promise.all(o.map(l=>this.getHostData(l,e[l])))).forEach(l=>{i[l.id]=C.preprocessHostData(l.data),d.set(l.id,r)}),this.setState({alive:e,hostsData:i,hostDataTimestampMap:d},()=>this.checkBackendTime())}};updateHosts=t=>{let e=[];if(t.find(o=>!o.obj)){this.getDataDelayed();return}if(e=t.map(o=>o.id),e.length){const o=JSON.parse(JSON.stringify(this.state.hostsData)),i=new Map(this.state.hostDataTimestampMap),d=Date.now();Promise.all(e.map(r=>this.getHostData(r))).then(r=>{r.forEach(a=>{o[a.id]=C.preprocessHostData(a.data),i.set(a.id,d)}),this.setState({hostsData:o,hostDataTimestampMap:i})})}};async activateEditMode(){var i;const t=await this.props.socket.getSystemConfig(!0),e=await this.getInstances(!0,null,t),o=(i=t==null?void 0:t.native)!=null&&i.introLinks?t.native.introLinks:[];this.introLinksOriginal=JSON.stringify(o),this.deactivatedOriginal=JSON.parse(JSON.stringify(e.deactivated)),this.setState({instances:e.instances,deactivated:e.deactivated,edit:!0,introLinks:o,hasUnsavedChanges:!1})}deactivateEditMode(){this.state.hasUnsavedChanges,this.setState({deactivated:this.deactivatedOriginal,introLinks:JSON.parse(this.introLinksOriginal),hasUnsavedChanges:!1,edit:!1},()=>{this.deactivatedOriginal=null,this.introLinksOriginal=null})}toggleCard(t,e){if(!this.state.instances||!this.state.instances.length)return;const o=JSON.parse(JSON.stringify(this.state.deactivated)),i=o.indexOf(`${t}_${e}`);i!==-1?o.splice(i,1):(o.push(`${t}_${e}`),o.sort());const d=JSON.stringify(o)!==JSON.stringify(this.deactivatedOriginal)||JSON.stringify(this.state.introLinks)!==this.introLinksOriginal;this.setState({deactivated:o,hasUnsavedChanges:d})}getInstancesCards(){var t;return(t=this.state.instances)==null?void 0:t.map(e=>{var i,d;const o=String(window.NEXOWATT_EOS_ACCESS_ROLE||"admin").toLowerCase()!=="admin"&&String(window.NEXOWATT_EOS_ACCESS_ROLE||"admin").toLowerCase()!=="service"&&/^nexowatt-ui(?:\.|$)/i.test(e.id)||!((i=this.state.deactivated)!=null&&i.includes(`${e.id}_${e.linkName}`));if(o||this.state.edit){let r=e.link?e.link.replace(/^https?:\/\//,""):"";if(r=r.split("/")[0],e.id===this.props.adminInstance)return null;let a=window.isFinite(e.id.split(".").pop());a&&(a=!!((d=this.state.instances)!=null&&d.find(k=>k.id!==e.id&&e.name===k.name&&e.id.split(".")[0]===k.id.split(".")[0])));const l=this.state.hostsData?this.state.hostsData[e.id]:null,h=this.state.hostTimeDiffMap.get(e.id)??0,p=this.state.hostDataTimestampMap.get(e.id)??0,u=Date.now()-p<this.#e;return s.jsx(O,{image:e.image,title:s.jsxs(s.Fragment,{children:[s.jsx("span",{style:e.name&&e.name.length>12?{fontSize:"1rem"}:void 0,children:e.name}),a?s.jsxs("span",{style:m.instanceNumber,children:[".",e.id.split(".").pop()]}):null]}),action:{link:e.link,text:r},t:this.props.t,lang:this.props.lang,color:e.color,showInfo:!!e.info,edit:this.state.edit,offline:l&&l.alive===!1,warning:h>this.#t&&u?this.t("Backend time differs by %s minutes",Math.round(h/this.#s).toString()):null,enabled:o,disabled:!l||typeof l!="object",getHostDescriptionAll:()=>this.getHostDescriptionAll(e.id),toggleActivation:()=>this.toggleCard(e.id,e.linkName),openSnackBarFunc:()=>this.setState({openSnackBar:!0}),theme:this.props.theme,children:e.description||this.getHostDescription(e.id)},`${e.id}_${e.link}`)}return null})}toggleLinkCard(t){const e=JSON.parse(JSON.stringify(this.state.introLinks));e[t].enabled=!e[t].enabled;const o=JSON.stringify(this.state.deactivated)!==JSON.stringify(this.deactivatedOriginal)||JSON.stringify(e)!==this.introLinksOriginal;this.setState({introLinks:e,hasUnsavedChanges:o})}getLinkCards(){var t;return(t=this.state.introLinks)==null?void 0:t.map((e,o)=>!e.enabled&&!this.state.edit?null:e.camera==="custom"?s.jsx(E,{image:e.image,title:e.name,action:{link:e.link,text:e.linkName},t:this.props.t,socket:this.props.socket,color:e.color,edit:this.state.edit,interval:e.interval,camera:e.camera,addTs:e.addTs,onEdit:()=>{var i;return this.setState({editLink:!0,editLinkIndex:o,link:JSON.parse(JSON.stringify((i=this.state.introLinks)==null?void 0:i[o]))})},onRemove:()=>{const i=JSON.parse(JSON.stringify(this.state.introLinks));i.splice(o,1);const d=JSON.stringify(this.state.deactivated)!==JSON.stringify(this.deactivatedOriginal)||JSON.stringify(i)!==this.introLinksOriginal;this.setState({introLinks:i,hasUnsavedChanges:d})},enabled:e.enabled,lang:this.props.lang,toggleActivation:()=>this.toggleLinkCard(o),cameraUrl:e.desc,theme:this.props.theme},`link${o}`):s.jsx(O,{image:e.image,title:e.name,action:{link:e.link,text:e.linkName},t:this.props.t,color:e.color,edit:this.state.edit,onEdit:()=>{var i;return this.setState({editLink:!0,editLinkIndex:o,link:JSON.parse(JSON.stringify((i=this.state.introLinks)==null?void 0:i[o]))})},onRemove:()=>{const i=JSON.parse(JSON.stringify(this.state.introLinks));i.splice(o,1);const d=JSON.stringify(this.state.deactivated)!==JSON.stringify(this.deactivatedOriginal)||JSON.stringify(i)!==this.introLinksOriginal;this.setState({introLinks:i,hasUnsavedChanges:d})},enabled:e.enabled,lang:this.props.lang,toggleActivation:()=>this.toggleLinkCard(o),theme:this.props.theme,children:e.desc||""},`link${o}`))}editLinkCard(){return this.state.editLink?s.jsx(U,{link:this.state.link,socket:this.props.socket,isNew:this.state.editLinkIndex===-1,t:this.props.t,lang:this.props.lang,theme:this.props.theme,onClose:t=>{if(t){const e=JSON.parse(JSON.stringify(this.state.introLinks));this.state.editLinkIndex===-1?(t.enabled=!0,e.push(t)):(t.enabled=e[this.state.editLinkIndex].enabled,e[this.state.editLinkIndex]=t);const o=JSON.stringify(this.state.deactivated)!==JSON.stringify(this.deactivatedOriginal)||JSON.stringify(e)!==this.introLinksOriginal;this.setState({introLinks:e,editLink:!1,hasUnsavedChanges:o,link:null})}else this.setState({editLink:!1})}}):null}getButtons(){const t=[];return this.state.edit?(t.push(s.jsx(n.Fab,{color:"primary",size:"small",sx:v.Utils.getStyle(this.props.theme,m.button,m.addButton),onClick:()=>this.setState({editLink:!0,editLinkIndex:-1,link:{}}),children:s.jsx(f.Add,{})},"add")),t.push(s.jsx(n.Fab,{size:"small",color:"primary",disabled:!this.state.hasUnsavedChanges,sx:v.Utils.getStyle(this.props.theme,m.button,m.saveButton),onClick:()=>this.saveCards(),children:s.jsx(f.Check,{})},"save")),t.push(s.jsx(n.Fab,{size:"small",color:"primary",sx:v.Utils.getStyle(this.props.theme,m.button,m.closeButton),onClick:()=>this.deactivateEditMode(),children:s.jsx(f.Close,{})},"close"))):t.push(s.jsx(n.Fab,{color:"primary",size:"small",style:m.button,onClick:()=>this.activateEditMode(),children:s.jsx(f.Create,{})},"edit")),t}async saveCards(){const t=await this.props.socket.getSystemConfig(!0);let e=!1;JSON.stringify(t.common.intro)!==JSON.stringify(this.state.deactivated)&&(t.common.intro=this.state.deactivated,e=!0),!e&&JSON.stringify(t.native.introLinks)!==JSON.stringify(this.state.introLinks)&&(e=!0,t.native.introLinks=this.state.introLinks),e?this.props.socket.setSystemConfig(t).then(()=>this.props.showAlert("Updated","success")).catch(o=>{console.log(o),this.props.showAlert(o,"error")}).then(()=>this.setState({edit:!1})):this.setState({edit:!1})}async getHostData(t,e){let o;if(e!==void 0)o={val:e};else try{o=await this.props.socket.getState(`${t}.alive`)}catch(r){console.error(`Cannot get state ${t}.alive: ${r}`),o={val:!1}}let i={alive:!1};if(o!=null&&o.val)try{i=await this.props.socket.getHostInfo(t,!1,1e4),i&&typeof i=="object"&&i.alive!==!1&&(i.alive=!0)}catch(r){console.error(`Cannot get host info for ${t}: ${r}`),i={alive:!1}}else i={alive:!1};const d=await this.props.socket.getForeignStates(`${t}.versions.*`);return Object.keys(d).forEach(r=>i[`_${r.split(".").pop()}`]=d[r].val),{id:t,data:i}}async getHostsData(t){const e=t.map(l=>this.getHostData(l._id)),o=await Promise.all(e),i={},d={},r=new Map(this.state.hostDataTimestampMap),a=Date.now();return o.forEach(l=>{i[l.id]=C.preprocessHostData(l.data),d[l.id]=l.data.alive,r.set(l.id,a)}),this.setState({hostDataTimestampMap:r}),{hostsData:i,alive:d}}addLinks(t,e,o,i,d,r){const a={id:t.id,name:t.name,description:t.description,color:t.color,image:t.icon,info:""},l=J(t.link,e.name,o,{instances:i,hostname:this.props.hostname,adminInstance:this.props.adminInstance,hosts:d}),h=this.state.reverseProxy;let p=null;if(h!=null&&h.length){const c=window.location.pathname;p=h.find(u=>{if(!u.globalPath)return!1;const k=u.globalPath.endsWith("/")?u.globalPath:`${u.globalPath}/`;return c===k||c.startsWith(k)})||null}if(l.length===1){a.link=l[0].url,a.port=l[0].port,a.link=P(a.link,a.id,i,p)||a.link;const c=r.find(u=>u.link===a.link);c?console.log(`Double links: "${a.id}" and "${c.id}"`):r.push(a)}else l.length>1&&l.forEach(c=>{const u=r.find(k=>k.link===c.url);if(u)console.log(`Double links: "${a.id}" and "${u.id}"`);else{const k={...a,link:c.url,port:c.port};k.link=P(k.link,a.id,i,p)||k.link,r.push(k)}})}static getText(t,e){return t?typeof t=="object"?t[e]||t.en||"":t||"":""}static normalizeLinks(t,e,o){if(!t.common.localLinks&&!t.common.localLink&&!t.common.welcomeScreen&&!t.common.welcomeScreenPro)return null;const i={id:t._id.replace("system.adapter.",""),link:"",name:C.getText(t.common.titleLang||t.common.title||t.common.name,e),order:t.common.order||1e3,intro:!0,description:C.getText(t.common.desc,e),icon:t.common.icon?`adapter/${t.common.name}/${t.common.icon}`:"img/no-image.svg"};let d=[];if(t.common.localLink)if(typeof t.common.localLink=="string")d.push({...i,link:t.common.localLink});else{const r=t.common.localLink;if(r.link){const a={...i,link:r.link};r.color&&(a.color=r.color),r.order!==void 0&&typeof r.order=="number"&&(a.order=r.order),r.icon&&r.img&&(a.icon=r.icon||r.img),d.push(a)}else console.warn(`Unknown localLink structure: ${JSON.stringify(t.common.localLink)}`)}if(t.common.localLinks&&typeof t.common.localLinks=="object"&&Object.keys(t.common.localLinks).forEach(r=>{const a=t.common.localLinks[r];if(typeof a=="string")d.push({...i,link:a});else{const l=a;if(l.link){const h={...i,id:t._id.replace("system.adapter.","")+(r==="_default"?"":` ${r}`),link:l.link,name:i.name+(r==="_default"?"":` ${r}`)};l.color&&(h.color=l.color),l.order!==void 0&&(h.order=parseInt(l.order,10)||1e3),l.icon&&l.img&&(h.icon=l.icon||l.img),l.description&&(h.description=C.getText(l.description,e)),l.pro!==void 0&&(typeof l.pro=="string"?h.pro=l.pro:h.pro=`${t.common.name}/index.html`),l.cloud!==void 0&&(h.cloud=l.cloud),l.intro!==void 0&&(h.intro=l.intro===!0),l.name&&(h.name=C.getText(l.name,e)),r==="_default"&&(h.default=!0),d.push(h)}else console.warn(`Unknown localLinks structure: ${JSON.stringify(a)}`)}}),t.common.welcomeScreen&&typeof t.common.welcomeScreen=="object"&&((Array.isArray(t.common.welcomeScreen)?t.common.welcomeScreen:[t.common.welcomeScreen]).forEach(a=>{if(a.link){const l={...i,id:`${t._id.replace("system.adapter.","")} cloud`,link:`%web_protocol%://%web_bind%:%web_port%/${a.link}`,cloud:a.link};if(a.color&&(l.color=a.color),a.order!==void 0&&typeof a.order=="number"&&(l.order=a.order),a.icon&&a.img&&(l.icon=a.icon||a.img),a.localLinks){const h=t.common.localLinks[a.localLinks];h&&typeof h=="string"?l.link=h:h&&typeof h=="object"&&h.link&&(l.link=h.link)}a.name&&(l.name=C.getText(a.name,e)),d.push(l)}}),t.common.welcomeScreenPro&&typeof t.common.welcomeScreenPro=="object"&&(Array.isArray(t.common.welcomeScreenPro)?t.common.welcomeScreenPro:[t.common.welcomeScreenPro]).forEach(l=>{if(l.link){const h={...i,id:`${t._id.replace("system.adapter.","")} pro`,link:`%web_protocol%://%web_bind%:%web_port%/${l.link}`,pro:l.link};if(l.color&&(h.color=l.color),l.order!==void 0&&typeof l.order=="number"&&(h.order=l.order),l.icon&&l.img&&(h.icon=l.icon||l.img),l.localLinks){const p=t.common.localLinks[l.localLinks];p&&typeof p=="string"?h.link=p:p&&typeof p=="object"&&p.link&&(h.link=p.link)}l.name&&(h.name=C.getText(l.name,e)),d.push(h)}})),d.forEach(r=>{!r.icon.startsWith("adapter/")&&!r.icon.startsWith("data:image/")&&!r.icon.startsWith("http://")&&!r.icon.startsWith("https://")&&r.icon!=="img/no-image.svg"&&(r.icon=`adapter/${t.common.name}/${r.icon}`)}),o){const r={};d.forEach(a=>{r[a.link]?(a.color&&(r[a.link].color=a.color),a.icon&&(r[a.link].icon=a.icon),a.cloud&&(r[a.link].cloud=a.cloud),a.pro&&(r[a.link].pro=a.pro),a.intro!==void 0&&(r[a.link].intro=a.intro),a.name&&typeof a.name=="object"&&(r[a.link].name=a.name),a.order!==void 0&&(r[a.link].order=a.order),a.default&&(r[a.link].default=a.default)):r[a.link]=a}),d=Object.values(r)}return d.sort((r,a)=>r.default===void 0&&a.default===void 0?r.order===void 0&&a.order===void 0?0:r.order===void 0?-1:a.order===void 0?1:r.order-a.order:r.default===void 0?-1:a.default===void 0?1:r.order===void 0&&a.order===void 0?0:r.order===void 0?-1:a.order===void 0?1:r.order-a.order),d}async getInstances(t,e,o){e=e||this.state.hosts;const i={};e.forEach(d=>i[d._id]=d);try{const d=await this.props.socket.getAdapterInstances("",t);let r=o.common.intro||[];Array.isArray(r)||(r=Object.keys(r),r.sort());const a=[],l={};d.forEach(p=>l[p._id]=p),d.forEach(p=>{if(!p)return;const c=p.common||null,u=p._id.split("."),k=parseInt(u.pop(),10);let j;if(c!=null&&c.name&&typeof c.name=="object"){const N=c==null?void 0:c.name;j=N[this.props.lang]||N.en}else j=(c==null?void 0:c.name)||"";if(!(j==="admin"&&c.localLink===(this.props.hostname||""))&&j!=="web"&&!(j&&j!=="vis-web-admin"&&j.match(/^vis-/)&&j!=="vis-2")&&!(j!=null&&j.match(/^icons-/))&&c&&(c.enabled||c.onlyWWW)){const N=C.normalizeLinks(p,this.props.lang,!0);N&&N.forEach(H=>this.addLinks(H,c,k,l,i,a))}}),a.forEach(p=>{p.link&&(p.linkName=p.link.replace("https://","").replace("http://","").replace(/^[^_]+:/,""))}),a.sort((p,c)=>{if(p.order!==void 0||c.order!==void 0){if(p.order=p.order===void 0?1e3:p.order,c.order=c.order===void 0?1e3:c.order,p.order<c.order)return-1;if(p.order>c.order)return 1}return p.id>c.id?1:p.id<c.id?-1:0}),e==null||e.forEach(p=>{const c=p==null?void 0:p.common;let u=c==null?void 0:c.name;if(typeof u=="object"&&u&&(u=u[this.props.lang]||u.en),c){const k={id:p._id,name:u||"",color:"",image:c.icon||"img/no-image.svg",info:this.t("Info"),linkName:""};a.push(k)}});const h=[];return r.forEach(p=>{a.find(c=>p===`${c.id}_${c.linkName}`)&&h.push(p)}),r=h,{instances:a,deactivated:r}}catch(d){return console.log(d),{instances:[],deactivated:[]}}}getHostDescription(t){const e=this.state.hostsData?this.state.hostsData[t]:null;if(e&&e.alive===!1)return s.jsx("div",{style:m.hostOffline,children:this.props.t("Offline")});let o="",i="";if(e){try{e._nodeNewest&&e["Node.js"]&&w.gt(e._nodeNewest,e["Node.js"].replace(/^v/,""))&&(o=e._nodeNewest)}catch{}try{e._nodeNewest!==e._nodeNewestNext&&e._nodeNewestNext&&e["Node.js"]&&e._nodeNewest&&w.gt(e._nodeNewestNext,e["Node.js"].replace(/^v/,""))&&w.gt(e._nodeNewestNext,e._nodeNewest)&&(o+=(o?" / ":"")+e._nodeNewestNext)}catch{}if(o){const d=this.state.nodeUpdateSupported&&e.Platform==="linux";o=s.jsx(n.Tooltip,{title:this.props.t("Some updates available"),slotProps:{popper:{sx:m.tooltip}},children:s.jsxs("span",{style:{...m.nodeUpdate,display:"inline-flex"},children:["(",o,")",d?s.jsx(f.Refresh,{style:m.updateIcon,onClick:()=>this.setState({nodeUpdateDialog:{hostId:t,version:e._nodeNewestNext}})}):null]})})}try{e._npmNewest&&e.NPM&&w.gt(e._npmNewest,e.NPM)&&(i=e._npmNewest)}catch{}try{e._npmNewest!==e._npmNewestNext&&e._npmNewestNext&&e.NPM&&e._npmNewest&&w.gt(e._npmNewestNext,e.NPM)&&w.gt(e._npmNewestNext,e._npmNewest)&&(i+=(i?" / ":"")+e._npmNewestNext)}catch{}i&&(i=s.jsx(n.Tooltip,{title:this.props.t("Some updates available"),slotProps:{popper:{sx:m.tooltip}},children:s.jsxs("span",{style:m.nodeUpdate,children:["(",i,")"]})}))}return e&&typeof e=="object"?s.jsxs("ul",{style:{textTransform:"none"},children:[s.jsx("li",{children:s.jsxs("span",{children:[s.jsxs("span",{style:m.bold,children:[this.t("Platform"),": "]}),e.Platform||"--"]})}),s.jsx("li",{children:s.jsxs("span",{children:[s.jsxs("span",{style:m.bold,children:[this.t("RAM"),": "]}),T.RAM(e.RAM)]})}),s.jsx("li",{children:s.jsxs("span",{children:[s.jsxs("span",{style:m.bold,children:[this.t("Node.js"),": "]}),s.jsx("span",{style:o?m.updateExists:m.updateNo,children:e["Node.js"]||"--"}),o]})}),s.jsx("li",{children:s.jsxs("span",{children:[s.jsxs("span",{style:m.bold,children:[this.t("NPM"),": "]}),s.jsx("span",{className:i?m.updateExists:m.updateNo,children:e.NPM||"--"}),i]})})]}):s.jsxs("ul",{children:[s.jsx(n.Skeleton,{}),s.jsx(n.Skeleton,{}),s.jsx(n.Skeleton,{}),s.jsx(n.Skeleton,{})]})}getHostDescriptionAll(t){const e=this.state.hostsData?this.state.hostsData[t]:null;return{el:s.jsx("ul",{style:{textTransform:"none"},children:e&&typeof e=="object"&&Object.keys(e).filter(o=>!o.startsWith("_")&&e[o]!==null&&e[o]!==void 0).map(o=>s.jsx("li",{children:e&&typeof e=="object"?s.jsxs("span",{children:[s.jsxs("span",{style:m.bold,children:[this.t(o),": "]}),T[o]?T[o](e[o],this.t):(typeof e[o]=="object"?JSON.stringify(e[o]):e[o].toString())||"--"]}):s.jsx(n.Skeleton,{})},o))}),text:e&&typeof e=="object"?Object.keys(e).reduce((o,i)=>`${o}${this.t(i)}:${T[i]?T[i](e[i],this.t):(typeof e[i]=="object"?JSON.stringify(e[i]):e[i])||"--"}
2
2
  `):""}}getDataDelayed=t=>{this.getDataTimeout&&clearTimeout(this.getDataTimeout),this.getDataTimeout=setTimeout(()=>{this.getDataTimeout=void 0,this.getData(!0).catch(e=>console.error(`Cannot get data: ${e}`))},300)};async getData(t){try{const e=await this.props.socket.getSystemConfig(t),o=await this.props.socket.getCompactHosts(t),i=await this.getInstances(t,o,e);this.setState({instances:i.instances,hosts:o,deactivated:i.deactivated,introLinks:e&&e.native&&e.native.introLinks?e.native.introLinks:[]});const d=await this.getHostsData(o);await new Promise(r=>{this.setState(d,()=>r())})}catch(e){const o=String(window.NEXOWATT_EOS_ACCESS_ROLE||"unknown").toLowerCase();if(o!=="admin"){try{const i=await this.getInstances(t,[],{common:{intro:[]},native:{introLinks:[]}});this.setState({instances:i.instances,hosts:[],deactivated:i.deactivated,introLinks:[],hostsData:{},alive:{}});return}catch{}this.setState({instances:[],hosts:[],deactivated:[],introLinks:[],hostsData:{},alive:{}});return}window.alert(`Cannot get data: ${e}`)}}renderCopiedToast(){return s.jsx(n.Snackbar,{anchorOrigin:{vertical:"bottom",horizontal:"left"},open:this.state.openSnackBar,autoHideDuration:3e3,onClose:()=>this.setState({openSnackBar:!1}),message:this.t("copied")})}render(){return this.state.instances?s.jsxs(v.TabContainer,{elevation:0,overflow:"visible",children:[this.renderCopiedToast(),this.state.nodeUpdateDialog?s.jsx(W,{onClose:()=>this.setState({nodeUpdateDialog:null}),socket:this.props.socket,...this.state.nodeUpdateDialog}):null,s.jsxs("div",{style:m.viewModeDiv,className:"eos-native-intro-grid",children:[this.getInstancesCards(),this.getLinkCards(),String(window.NEXOWATT_EOS_ACCESS_ROLE||"admin").toLowerCase()==="admin"?s.jsx("div",{className:"eos-overview-edit-controls",children:this.getButtons()}):null]}),String(window.NEXOWATT_EOS_ACCESS_ROLE||"admin").toLowerCase()==="admin"?this.editLinkCard():null]}):s.jsx(n.LinearProgress,{})}static preprocessHostData(t){var e;if((e=t.dockerInformation)!=null&&e.isDocker){let o=t.dockerInformation.isOfficial?"official image":"unofficial image";t.dockerInformation.isOfficial&&(o+=` - ${t.dockerInformation.officialVersion}`),t.Platform=`${t.Platform} (${o})`}return delete t.dockerInformation,t}}export{C as default};