Files
mission-control-v2/frontend/dist/assets/Einstellungen-DTrnYy0G.js
T
HitonabiandClaude Opus 5.5 903fbbfbb9 homelab: Speicherpool, NAS und Sicherungen überwachen – mit Empfehlungen, was Platz bringt
User-Wunsch 25.09.: Speicherpool im Wächter (gelb ab 80 %, rot bei 10 % frei)
samt Empfehlungen, dazu das NAS (Backup-Ziel, per NFS auf dem Proxmox-Host).
- Ausführer: Thin-Pools mit echter Belegung je Volume (lvs), ungenutzte und
  verwaiste Platten, VM-Belegung über den Gast-Agenten, Discard je VM,
  Netzlaufwerke (df mit Zeitlimit, hängender harter NFS-Mount hält nichts auf),
  Sicherungsaufträge und jüngste Sicherung je Gast.
- Homelab-Teil: services/homelab/speicher.py (Auswertung, Empfehlungen,
  Wächter pruefe_speicher, NAS-Erreichbarkeit per TCP), GET /api/homelab/speicher;
  Gast-Plattenwächter nennt jetzt auch VMs richtig.
- Oberfläche: Karte „Speicher und Sicherungen“ im Homelab-Cockpit.
- deploy.sh und ausfuehrer-einrichten.sh warten, solange im Homelab ein Update
  oder „Alle aktualisieren“ läuft (der Neustart bräche den Lauf ab).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 11:15:06 +02:00

1 line
28 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import{i as e,n as t,r as n,s as r,t as i}from"./dist-D4CVSex9.js";import{Bt as a,Dt as o,J as s,Kt as c,L as l,M as u,Ut as d,V as f,Xt as p,Zt as m,at as h,f as g,ft as _,j as v,mt as y,tt as b,ut as x,yt as S,zt as C}from"./index-COh3_SSc.js";import{t as w}from"./button-D8rvET0Z.js";import{t as ee}from"./Bestaetigen-D8Dh5cqS.js";var T={name:`key-round`,size:24,node:[[`path`,{d:`M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z`,key:`1s6t7t`}],[`circle`,{cx:`16.5`,cy:`7.5`,r:`.5`,fill:`currentColor`,key:`w0ekpg`}]]};T.node;var E=c(T),D=t(),O=r(e(),1),k=n(),A=[`Montag`,`Dienstag`,`Mittwoch`,`Donnerstag`,`Freitag`,`Samstag`,`Sonntag`],j=Array.from({length:48},(e,t)=>`${String(Math.floor(t/2)).padStart(2,`0`)}:${t%2?`30`:`00`}`),M=new Intl.DateTimeFormat(`de-DE`,{day:`2-digit`,month:`2-digit`,year:`numeric`,hour:`2-digit`,minute:`2-digit`,timeZone:`Europe/Berlin`});function N(e){let t=e?new Date(e):null;return t&&!Number.isNaN(t.getTime())?M.format(t):`–`}function P(e,t){let n=Number(t.slice(0,2)),r=n*60+179,i=e;r>=1440&&(r-=1440,i=e%7+1);let a=e=>String(e).padStart(2,`0`),o=`${a(n)}:00`,s=`${a(Math.floor(r/60))}:${a(r%60)}`;return i===e?`${A[e-1]} ${o}–${s}`:`${A[e-1]} ${o} – ${A[i-1]} ${s}`}function F(e){let t=(0,D.c)(6),{titel:n,children:r}=e,i;t[0]===n?i=t[1]:(i=(0,k.jsx)(`h3`,{className:`schild text-sm tracking-[0.18em] text-text-2`,children:n}),t[0]=n,t[1]=i);let a;return t[2]!==r||t[3]!==i||t[4]!==n?(a=(0,k.jsxs)(`section`,{"aria-label":n,className:`flex flex-col gap-3 border-t border-linie pt-4 first:border-t-0 first:pt-0`,children:[i,r]}),t[2]=r,t[3]=i,t[4]=n,t[5]=a):a=t[5],a}function I(e){let t=(0,D.c)(19),{titel:n,text:r,farbe:a,children:o}=e,s=a===`box`?`bg-box`:a===`homelab`?`bg-lab`:`bg-linie-stark`,c=a===`box`?`text-box-text`:a===`homelab`?`text-lab-text`:`text-foreground`,l;t[0]===s?l=t[1]:(l=i(`absolute inset-x-0 top-0 h-1`,s),t[0]=s,t[1]=l);let u;t[2]===l?u=t[3]:(u=(0,k.jsx)(`span`,{"aria-hidden":!0,className:l}),t[2]=l,t[3]=u);let d;t[4]===c?d=t[5]:(d=i(`schild text-lg font-bold tracking-[0.22em]`,c),t[4]=c,t[5]=d);let f;t[6]!==d||t[7]!==n?(f=(0,k.jsx)(`h2`,{className:d,children:n}),t[6]=d,t[7]=n,t[8]=f):f=t[8];let p;t[9]===r?p=t[10]:(p=(0,k.jsx)(`p`,{className:`text-sm text-text-3`,children:r}),t[9]=r,t[10]=p);let m;t[11]!==f||t[12]!==p?(m=(0,k.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[f,p]}),t[11]=f,t[12]=p,t[13]=m):m=t[13];let h;return t[14]!==o||t[15]!==u||t[16]!==m||t[17]!==n?(h=(0,k.jsxs)(`section`,{"aria-label":n,className:`relative flex min-w-0 flex-col gap-4 overflow-hidden rounded-2xl border border-linie bg-panel p-5 sm:p-6`,children:[u,m,o]}),t[14]=o,t[15]=u,t[16]=m,t[17]=n,t[18]=h):h=t[18],h}function L(e){let t=(0,D.c)(2),{children:n}=e,r;return t[0]===n?r=t[1]:(r=(0,k.jsx)(`p`,{className:`text-sm text-bernstein`,children:n}),t[0]=n,t[1]=r),r}function R(e){let t=(0,D.c)(3),{laedt:n,fehler:r}=e;if(n){let e;return t[0]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,k.jsx)(`p`,{className:`text-sm text-text-2`,children:`Wird gelesen …`}),t[0]=e):e=t[0],e}let i=r?`: ${r}`:`.`,a;return t[1]===i?a=t[2]:(a=(0,k.jsxs)(`p`,{role:`alert`,className:`text-sm text-rot-text`,children:[`Lässt sich gerade nicht lesen`,i]}),t[1]=i,t[2]=a),a}function z({offen:e}){let t=m(),n=p({queryKey:[`geheimnisse`],queryFn:()=>C(`/api/maintenance/geheimnisse`),enabled:e}),[r,i]=(0,O.useState)(``),[s,c]=(0,O.useState)(!1),[l,u]=(0,O.useState)(!1);async function d(e){if(!s){c(!0),u(!1);try{await a(`/api/maintenance/geheimnisse`,{schluessel:`hf_token`,wert:e}),o(`erfolg`,e?`Hugging-Face-Zugang gespeichert.`:`Hugging-Face-Zugang gelöscht.`),i(``),t.invalidateQueries({queryKey:[`geheimnisse`]})}catch(e){o(`fehler`,e.message)}finally{c(!1)}}}let f=n.data,h;return h=n.isPending?`Wird gelesen …`:f?f.hf_token_gesetzt?`Ist hinterlegt.`:`Fehlt.`:`Lässt sich gerade nicht lesen${n.error?`: ${n.error.message}`:`.`}`,(0,k.jsxs)(F,{titel:`Hugging-Face-Zugang`,children:[(0,k.jsxs)(`p`,{className:`text-sm text-text-2`,"aria-live":`polite`,children:[(0,k.jsx)(`span`,{className:!f&&!n.isPending?`text-rot-text`:void 0,children:h}),` Nötig für gesperrte Modelle und schnellere Downloads.`,f?.hf_token_aus_env?` Er kommt aus der Dienst-Einstellung und lässt sich hier nicht löschen.`:``]}),f?.schreibbar===!1&&(0,k.jsx)(`p`,{className:`text-sm text-bernstein`,children:`Die Box kann den Zugang gerade nicht speichern: Ihre Ablage ist nicht beschreibbar.`}),(0,k.jsxs)(`form`,{className:`flex gap-2`,onSubmit:e=>{e.preventDefault(),r.trim()&&d(r.trim())},children:[(0,k.jsx)(`label`,{htmlFor:`hf-token`,className:`sr-only`,children:`Hugging-Face-Zugang`}),(0,k.jsx)(`input`,{id:`hf-token`,type:`password`,autoComplete:`off`,value:r,onChange:e=>i(e.target.value),placeholder:`hf_…`,className:`h-11 min-w-0 flex-1 rounded-lg border border-linie-stark bg-erhaben px-3 text-[15px] outline-none focus:border-cyan`}),(0,k.jsx)(w,{type:`submit`,disabled:!r.trim()||f?.schreibbar===!1||s,children:s?`Speichert …`:`Speichern`})]}),f?.hf_token_gesetzt&&!f.hf_token_aus_env&&(l?(0,k.jsxs)(`span`,{className:`flex flex-wrap gap-2`,children:[(0,k.jsx)(w,{variant:`gefahr`,size:`sm`,disabled:s,onClick:()=>d(null),children:`Wirklich löschen?`}),(0,k.jsx)(w,{variant:`ghost`,size:`sm`,onClick:()=>u(!1),children:`Nein`})]}):(0,k.jsx)(w,{variant:`ghost`,size:`sm`,className:`self-start`,disabled:s,onClick:()=>u(!0),children:`Zugang löschen`}))]})}function B(e){let t=(0,D.c)(24),{ziel:n,name:r}=e,i=_(),a=i.data,o=null;if(i.isPending){let e;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,k.jsx)(`p`,{role:`status`,className:`text-sm text-text-2`,children:`Sendet …`}),t[0]=e):e=t[0],o=e}else if(a?.gesendet){let e=a.weg===`hermes`?`über Hermes`:`direkt an die Telegram-Bot-API`,n=a.kennung?`, Kennung ${a.kennung}`:``,r;t[1]!==e||t[2]!==n?(r=(0,k.jsxs)(`p`,{role:`status`,className:`text-sm text-gruen`,children:[`Gesendet `,e,n,`. Schau in Telegram nach.`]}),t[1]=e,t[2]=n,t[3]=r):r=t[3],o=r}else if(a){let e=a.grund??a.detail??`ohne Angabe eines Grundes.`,n;t[4]===e?n=t[5]:(n=(0,k.jsxs)(`p`,{role:`alert`,className:`text-sm text-rot-text`,children:[`Nicht gesendet: `,e]}),t[4]=e,t[5]=n),o=n}else if(i.error){let e;t[6]===i.error.message?e=t[7]:(e=(0,k.jsx)(`p`,{role:`alert`,className:`text-sm text-rot-text`,children:i.error.message}),t[6]=i.error.message,t[7]=e),o=e}let s;t[8]===r?s=t[9]:(s=(0,k.jsx)(`span`,{className:`text-[15px]`,children:r}),t[8]=r,t[9]=s);let c;t[10]!==i||t[11]!==n?(c=()=>i.mutate(n),t[10]=i,t[11]=n,t[12]=c):c=t[12];let l=`Testmeldung von ${r} senden`,u=i.isPending?`Sendet …`:`Test senden`,d;t[13]!==c||t[14]!==l||t[15]!==u||t[16]!==i.isPending?(d=(0,k.jsx)(w,{variant:`outline`,size:`sm`,disabled:i.isPending,onClick:c,"aria-label":l,children:u}),t[13]=c,t[14]=l,t[15]=u,t[16]=i.isPending,t[17]=d):d=t[17];let f;t[18]!==s||t[19]!==d?(f=(0,k.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[s,d]}),t[18]=s,t[19]=d,t[20]=f):f=t[20];let p;return t[21]!==o||t[22]!==f?(p=(0,k.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[f,o]}),t[21]=o,t[22]=f,t[23]=p):p=t[23],p}function V(){let e=(0,D.c)(9),t=s().data,n=t?.rolle??`box`,r=n===`box`?`homelab`:`box`,i=t?.instanz??(n===`box`?`Box-Wart`:`Homelab`),a;e[0]!==r||e[1]!==n||e[2]!==t||e[3]!==i?(a=[{ziel:n,name:i}],t?.partner.eingerichtet&&a.push({ziel:r,name:t.partner.name}),a.sort(U),e[0]=r,e[1]=n,e[2]=t,e[3]=i,e[4]=a):a=e[4];let o,c;e[5]===Symbol.for(`react.memo_cache_sentinel`)?(o=(0,k.jsx)(`p`,{className:`text-sm text-text-2`,children:`Dringende Hinweise gehen zusätzlich per Telegram raus, alles andere bleibt hier; was nachts anfällt, kommt um 07:00 als eine Morgenmeldung. Einfache Probleme wie einen abgestürzten Dienst behebt der Wächter selbst und schreibt es in den Verlauf.`}),c=(0,k.jsx)(`p`,{className:`text-sm text-text-2`,children:`Der Test schickt eine kurze Meldung über den echten Meldeweg, als dringend, damit sie auch nachts sofort kommt.`}),e[5]=o,e[6]=c):(o=e[5],c=e[6]);let l;return e[7]===a?l=e[8]:(l=(0,k.jsxs)(F,{titel:`Telegram`,children:[o,c,a.map(H)]}),e[7]=a,e[8]=l),l}function H(e){return(0,k.jsx)(B,{ziel:e.ziel,name:e.name},e.ziel)}function U(e,t){return Number(e.ziel!==`box`)-Number(t.ziel!==`box`)}function W(e){let t=(0,D.c)(87),{e:n,laedt:r,fehler:i}=e,a=y(),[o,s]=(0,O.useState)(null),[c,l]=(0,O.useState)(!1);if(!n){let e;return t[0]!==i||t[1]!==r?(e=(0,k.jsx)(F,{titel:`Update-Zeitfenster`,children:(0,k.jsx)(R,{laedt:r,fehler:i})}),t[0]=i,t[1]=r,t[2]=e):e=t[2],e}let u=n.update_fenster,d,f,p,m,h,g,_,v,b,x,S,C,T,E,M,I,z;if(t[3]!==n.schaltbar||t[4]!==o||t[5]!==u.naechster_lauf||t[6]!==u.neustart_fenster||t[7]!==u.tag||t[8]!==u.tag_name||t[9]!==u.timer_aktiv||t[10]!==u.uhrzeit||t[11]!==u.wirksam){z=o??{tag:u.tag,uhrzeit:u.uhrzeit},f=z.tag!==u.tag||z.uhrzeit!==u.uhrzeit;let e=j.includes(z.uhrzeit)?j:[...j,z.uhrzeit].sort();d=F,h=`Update-Zeitfenster`;let r;t[29]===u.naechster_lauf?r=t[30]:(r=u.naechster_lauf?` (nächster Lauf ${N(u.naechster_lauf)})`:``,t[29]=u.naechster_lauf,t[30]=r),t[31]!==u.neustart_fenster||t[32]!==u.tag_name||t[33]!==u.uhrzeit||t[34]!==r?(g=(0,k.jsxs)(`p`,{className:`text-sm text-text-2`,children:[`Die Box aktualisiert sich jeden `,u.tag_name,` um `,u.uhrzeit,` Uhr`,r,`. Neu gestartet wird sie danach nur`,` `,u.neustart_fenster,`.`]}),t[31]=u.neustart_fenster,t[32]=u.tag_name,t[33]=u.uhrzeit,t[34]=r,t[35]=g):g=t[35],t[36]!==n.schaltbar||t[37]!==u.timer_aktiv?(_=n.schaltbar&&!u.timer_aktiv&&(0,k.jsx)(L,{children:`Der Update-Timer läuft gerade nicht; er übernimmt das Fenster beim nächsten Start.`}),t[36]=n.schaltbar,t[37]=u.timer_aktiv,t[38]=_):_=t[38],t[39]!==n.schaltbar||t[40]!==u.wirksam?(v=n.schaltbar&&!u.wirksam&&(0,k.jsx)(L,{children:`Der Timer läuft noch nach einem anderen Plan als eingestellt. Einmal speichern gleicht es an.`}),t[39]=n.schaltbar,t[40]=u.wirksam,t[41]=v):v=t[41],I=`flex flex-wrap items-end gap-2`;let i=z.tag,a;t[42]===Symbol.for(`react.memo_cache_sentinel`)?(a=A.map(K),t[42]=a):a=t[42],m=(0,k.jsxs)(`label`,{className:`flex flex-col gap-1 text-xs text-text-3`,children:[`Tag`,(0,k.jsx)(`select`,{className:`h-11 rounded-lg border border-linie-stark bg-erhaben px-3 text-[15px] text-foreground outline-none focus:border-cyan`,value:i,disabled:!n.schaltbar,"aria-label":`Wochentag`,onChange:e=>s({...z,tag:Number(e.target.value)}),children:a})]}),E=`flex flex-col gap-1 text-xs text-text-3`,M=`Uhrzeit`,p=`h-11 rounded-lg border border-linie-stark bg-erhaben px-3 text-[15px] text-foreground outline-none focus:border-cyan`,b=z.uhrzeit,x=!n.schaltbar,S=`Uhrzeit`,C=e=>s({...z,uhrzeit:e.target.value}),T=e.map(G),t[3]=n.schaltbar,t[4]=o,t[5]=u.naechster_lauf,t[6]=u.neustart_fenster,t[7]=u.tag,t[8]=u.tag_name,t[9]=u.timer_aktiv,t[10]=u.uhrzeit,t[11]=u.wirksam,t[12]=d,t[13]=f,t[14]=p,t[15]=m,t[16]=h,t[17]=g,t[18]=_,t[19]=v,t[20]=b,t[21]=x,t[22]=S,t[23]=C,t[24]=T,t[25]=E,t[26]=M,t[27]=I,t[28]=z}else d=t[12],f=t[13],p=t[14],m=t[15],h=t[16],g=t[17],_=t[18],v=t[19],b=t[20],x=t[21],S=t[22],C=t[23],T=t[24],E=t[25],M=t[26],I=t[27],z=t[28];let B;t[43]!==p||t[44]!==b||t[45]!==x||t[46]!==S||t[47]!==C||t[48]!==T?(B=(0,k.jsx)(`select`,{className:p,value:b,disabled:x,"aria-label":S,onChange:C,children:T}),t[43]=p,t[44]=b,t[45]=x,t[46]=S,t[47]=C,t[48]=T,t[49]=B):B=t[49];let V;t[50]!==B||t[51]!==E||t[52]!==M?(V=(0,k.jsxs)(`label`,{className:E,children:[M,B]}),t[50]=B,t[51]=E,t[52]=M,t[53]=V):V=t[53];let H=!n.schaltbar||a.isPending||!f&&u.wirksam,U;t[54]===Symbol.for(`react.memo_cache_sentinel`)?(U=()=>l(!0),t[54]=U):U=t[54];let W=a.isPending?`Speichert …`:`Speichern`,q;t[55]!==H||t[56]!==W?(q=(0,k.jsx)(w,{disabled:H,onClick:U,children:W}),t[55]=H,t[56]=W,t[57]=q):q=t[57];let J;t[58]!==m||t[59]!==V||t[60]!==q||t[61]!==I?(J=(0,k.jsxs)(`div`,{className:I,children:[m,V,q]}),t[58]=m,t[59]=V,t[60]=q,t[61]=I,t[62]=J):J=t[62];let Y=n.schaltbar?``:` Einstellen lässt es sich nur auf der Box.`,X;t[63]===Y?X=t[64]:(X=(0,k.jsxs)(`p`,{className:`text-xs text-text-3`,children:[`Am besten nachts nach der Sicherung (03:30) und vor der Morgenmeldung (07:00).`,Y]}),t[63]=Y,t[64]=X);let Z;t[65]!==z.tag||t[66]!==z.uhrzeit?(Z=P(z.tag,z.uhrzeit),t[65]=z.tag,t[66]=z.uhrzeit,t[67]=Z):Z=t[67];let te=`Der Update-Lauf startet ab jetzt jeden ${A[z.tag-1]} um ${z.uhrzeit} Uhr. Neu gestartet wird die Box nur ${Z}. Ein Termin, der dadurch schon vorbei ist, wird nicht nachgeholt: Der erste Lauf ist der nächste reguläre.`,ne;t[68]===Symbol.for(`react.memo_cache_sentinel`)?(ne=()=>l(!1),t[68]=ne):ne=t[68];let Q;t[69]!==c||t[70]!==a||t[71]!==z?(Q=()=>{c&&(a.mutate(z,{onSuccess:()=>s(null)}),l(!1))},t[69]=c,t[70]=a,t[71]=z,t[72]=Q):Q=t[72];let $;t[73]!==c||t[74]!==a.isPending||t[75]!==te||t[76]!==Q?($=(0,k.jsx)(ee,{offen:c,titel:`Update-Zeitfenster ändern?`,text:te,knopf:`Speichern`,gesperrt:a.isPending,onNein:ne,onJa:Q}),t[73]=c,t[74]=a.isPending,t[75]=te,t[76]=Q,t[77]=$):$=t[77];let re;return t[78]!==d||t[79]!==h||t[80]!==g||t[81]!==_||t[82]!==v||t[83]!==J||t[84]!==X||t[85]!==$?(re=(0,k.jsxs)(d,{titel:h,children:[g,_,v,J,X,$]}),t[78]=d,t[79]=h,t[80]=g,t[81]=_,t[82]=v,t[83]=J,t[84]=X,t[85]=$,t[86]=re):re=t[86],re}function G(e){return(0,k.jsx)(`option`,{value:e,children:e},e)}function K(e,t){return(0,k.jsx)(`option`,{value:t+1,children:e},e)}function q(e){let t=(0,D.c)(37),{e:n,laedt:r,fehler:i}=e,a=h(),[o,s]=(0,O.useState)(null);if(!n){let e;return t[0]!==i||t[1]!==r?(e=(0,k.jsx)(F,{titel:`Modell-Radar`,children:(0,k.jsx)(R,{laedt:r,fehler:i})}),t[0]=i,t[1]=r,t[2]=e):e=t[2],e}let c=n.radar,l=c.zustand===`an`||c.zustand===`unbekannt`&&c.an,u;t[3]===c.naechster_lauf?u=t[4]:(u=c.naechster_lauf?` (nächster Lauf ${N(c.naechster_lauf)})`:``,t[3]=c.naechster_lauf,t[4]=u);let d=`An. Es sucht jede Nacht ab 00:30 nach besseren Modellen${u}.`,f=c.an?`Eingeschaltet.`:`Ausgeschaltet.`,p;t[5]!==d||t[6]!==f?(p={an:d,schlaeft:`Schläft. Es sucht und testet keine Modelle, bis du es wieder einschaltest.`,aus:`Gestoppt, steht aber noch im Autostart: Nach einem Neustart der Box liefe es wieder.`,unbekannt:f},t[5]=d,t[6]=f,t[7]=p):p=t[7];let m=p[c.zustand],g;t[8]===m?g=t[9]:(g=(0,k.jsx)(`p`,{className:`text-sm text-text-2`,children:m}),t[8]=m,t[9]=g);let _;t[10]!==n.schaltbar||t[11]!==c.an||t[12]!==c.wirksam?(_=n.schaltbar&&!c.wirksam&&(0,k.jsxs)(L,{children:[`Eingestellt ist „`,c.an?`an`:`aus`,`“, systemd zeigt etwas anderes. Noch einmal schalten gleicht es an.`]}),t[10]=n.schaltbar,t[11]=c.an,t[12]=c.wirksam,t[13]=_):_=t[13];let v=l?`outline`:`default`,y=!n.schaltbar||a.isPending,b;t[14]===l?b=t[15]:(b=()=>s(!l),t[14]=l,t[15]=b);let x=a.isPending?`Schaltet …`:l?`Ausschalten`:`Einschalten`,S;t[16]!==b||t[17]!==x||t[18]!==v||t[19]!==y?(S=(0,k.jsx)(w,{variant:v,size:`sm`,className:`self-start`,disabled:y,onClick:b,children:x}),t[16]=b,t[17]=x,t[18]=v,t[19]=y,t[20]=S):S=t[20];let C=o!==null,T=o?`Modell-Radar einschalten?`:`Modell-Radar ausschalten?`,E=o?`Das Radar sucht ab heute Nacht um 00:30 wieder nach besseren Modellen und testet höchstens eines pro Woche. Ein verpasster Lauf wird nicht nachgeholt, tagsüber lädt es also nichts.`:`Das Radar sucht und testet dann keine neuen Modelle mehr, bis du es wieder einschaltest. Ein Nachttest, der gerade läuft, endet noch. Auch ein Deploy schaltet es nicht wieder ein.`,A=o?`Einschalten`:`Ausschalten`,j;t[21]===Symbol.for(`react.memo_cache_sentinel`)?(j=()=>s(null),t[21]=j):j=t[21];let M;t[22]!==o||t[23]!==a?(M=()=>{o!==null&&(a.mutate(o),s(null))},t[22]=o,t[23]=a,t[24]=M):M=t[24];let P;t[25]!==a.isPending||t[26]!==C||t[27]!==T||t[28]!==E||t[29]!==A||t[30]!==M?(P=(0,k.jsx)(ee,{offen:C,titel:T,text:E,knopf:A,gesperrt:a.isPending,onNein:j,onJa:M}),t[25]=a.isPending,t[26]=C,t[27]=T,t[28]=E,t[29]=A,t[30]=M,t[31]=P):P=t[31];let I;return t[32]!==S||t[33]!==P||t[34]!==g||t[35]!==_?(I=(0,k.jsxs)(F,{titel:`Modell-Radar`,children:[g,_,S,P]}),t[32]=S,t[33]=P,t[34]=g,t[35]=_,t[36]=I):I=t[36],I}function J(e){let t=(0,D.c)(25),{name:n,stand:r,laedt:i,fehler:a}=e,o;if(i){let e;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,k.jsx)(`span`,{className:`text-sm text-text-2`,children:`Wird gelesen …`}),t[0]=e):e=t[0],o=e}else if(a){let e;t[1]===a?e=t[2]:(e=(0,k.jsxs)(`span`,{className:`text-sm text-rot-text`,children:[`Nicht lesbar: `,a]}),t[1]=a,t[2]=e),o=e}else if(r?.commit){let e;t[4]===r.commit?e=t[5]:(e=(0,k.jsx)(`span`,{className:`ziffern text-foreground`,children:r.commit}),t[4]=r.commit,t[5]=e);let n=r.betreff?` · ${r.betreff}`:``,i;t[6]!==e||t[7]!==n?(i=(0,k.jsxs)(`span`,{className:`text-sm text-text-2`,children:[e,n]}),t[6]=e,t[7]=n,t[8]=i):i=t[8];let a;t[9]!==r.deploy_zeit||t[10]!==r.quelle?(a=r.quelle===`deploy`?`Live seit ${N(r.deploy_zeit)}`:`Aus git gelesen, ohne Deploy`,t[9]=r.deploy_zeit,t[10]=r.quelle,t[11]=a):a=t[11];let s;t[12]===r.commit_datum?s=t[13]:(s=r.commit_datum?` · Commit vom ${N(r.commit_datum)}`:``,t[12]=r.commit_datum,t[13]=s);let c;t[14]!==a||t[15]!==s?(c=(0,k.jsxs)(`span`,{className:`text-xs text-text-3`,children:[a,s]}),t[14]=a,t[15]=s,t[16]=c):c=t[16];let l;t[17]!==i||t[18]!==c?(l=(0,k.jsxs)(k.Fragment,{children:[i,c]}),t[17]=i,t[18]=c,t[19]=l):l=t[19],o=l}else{let e;t[3]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,k.jsx)(`span`,{className:`text-sm text-text-2`,children:`Unbekannt: keine Stand-Datei und kein git.`}),t[3]=e):e=t[3],o=e}let s;t[20]===n?s=t[21]:(s=(0,k.jsx)(`span`,{className:`text-[15px]`,children:n}),t[20]=n,t[21]=s);let c;return t[22]!==o||t[23]!==s?(c=(0,k.jsxs)(`div`,{className:`flex flex-col gap-0.5`,children:[s,o]}),t[22]=o,t[23]=s,t[24]=c):c=t[24],c}function Y(e,t){return!e||!t?null:e.startsWith(t)||t.startsWith(e)}function X(e){let t=(0,D.c)(21),{offen:n}=e,r=s().data,i=!!r?.partner.eingerichtet,[a,o]=x(n,i),c=a.data?.stand?.commit,l=o.data?.stand?.commit,u;t[0]!==c||t[1]!==l?(u=Y(c,l),t[0]=c,t[1]=l,t[2]=u):u=t[2];let d=u,f=a.data?.instanz??r?.instanz??`Diese Instanz`,p=a.data?.stand,m=a.error?.message,h;t[3]!==a.isPending||t[4]!==f||t[5]!==p||t[6]!==m?(h=(0,k.jsx)(J,{name:f,stand:p,laedt:a.isPending,fehler:m}),t[3]=a.isPending,t[4]=f,t[5]=p,t[6]=m,t[7]=h):h=t[7];let g;t[8]!==r?.partner||t[9]!==o.data?.instanz||t[10]!==o.data?.stand||t[11]!==o.error?.message||t[12]!==o.isPending||t[13]!==i?(g=i&&(0,k.jsx)(J,{name:o.data?.instanz??r?.partner.name??`Partner`,stand:o.data?.stand,laedt:o.isPending,fehler:o.error?.message}),t[8]=r?.partner,t[9]=o.data?.instanz,t[10]=o.data?.stand,t[11]=o.error?.message,t[12]=o.isPending,t[13]=i,t[14]=g):g=t[14];let _;t[15]===d?_=t[16]:(_=d===!1&&(0,k.jsx)(L,{children:`Die beiden Instanzen laufen mit verschiedenen Ständen. Der nächste Deploy der Box zieht den Homelab-Teil mit.`}),t[15]=d,t[16]=_);let v;return t[17]!==h||t[18]!==g||t[19]!==_?(v=(0,k.jsxs)(F,{titel:`Instanzen`,children:[h,g,_]}),t[17]=h,t[18]=g,t[19]=_,t[20]=v):v=t[20],v}function Z(e){let t=(0,D.c)(52),{h:n}=e,r=u(),i=v(),[a,o]=(0,O.useState)(``),[s,c]=(0,O.useState)(!1),[l,f]=(0,O.useState)(null),p=n.arcane,m;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(m={hinterlegt:(0,k.jsx)(g,{art:`gruen`,children:`hinterlegt`}),umgebung:(0,k.jsx)(g,{art:`gruen`,children:`aus der Dienst-Einstellung`}),fehlt:(0,k.jsx)(g,{art:`bernstein`,children:`fehlt`})},t[0]=m):m=t[0];let h=m[p.schluessel],_;t[1]===p.url?_=t[2]:(_=p.url&&(0,k.jsxs)(`a`,{href:p.url,target:`_blank`,rel:`noopener`,className:`ml-auto inline-flex items-center gap-1 text-cyan hover:underline`,children:[`Arcane öffnen `,(0,k.jsx)(d,{className:`size-3.5`,"aria-hidden":!0})]}),t[1]=p.url,t[2]=_);let y;t[3]!==h||t[4]!==_?(y=(0,k.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 text-sm text-text-2`,children:[`API-Schlüssel `,h,_]}),t[3]=h,t[4]=_,t[5]=y):y=t[5];let b;t[6]===Symbol.for(`react.memo_cache_sentinel`)?(b=(0,k.jsx)(`p`,{className:`text-sm text-text-2`,children:`Mit Schlüssel sieht der Orchestrator, welche Docker-Images neuer sind. Anlegen in Arcane unter Einstellungen → API-Schlüssel; Lesen reicht, solange Docker-Updates nur als Probelauf laufen.`}),t[6]=b):b=t[6];let x;t[7]!==p.schluessel||t[8]!==r||t[9]!==a?(x=p.schluessel!==`umgebung`&&(0,k.jsxs)(`form`,{className:`flex gap-2`,onSubmit:e=>{e.preventDefault(),a.trim()&&r.mutate(a.trim(),{onSuccess:()=>o(``)})},children:[(0,k.jsx)(`label`,{htmlFor:`arcane-schluessel`,className:`sr-only`,children:`Arcane-API-Schlüssel`}),(0,k.jsxs)(`span`,{className:`relative min-w-0 flex-1`,children:[(0,k.jsx)(E,{className:`pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2 text-text-3`,"aria-hidden":!0}),(0,k.jsx)(`input`,{id:`arcane-schluessel`,type:`password`,autoComplete:`off`,value:a,onChange:e=>o(e.target.value),placeholder:p.schluessel===`hinterlegt`?`Neuen Schlüssel eintragen …`:`Schlüssel aus Arcane einfügen …`,className:`h-11 w-full rounded-lg border border-linie-stark bg-erhaben pr-3 pl-9 text-[15px] outline-none focus:border-lab`})]}),(0,k.jsx)(w,{type:`submit`,disabled:!a.trim()||r.isPending,children:r.isPending?`Prüft …`:`Prüfen und speichern`})]}),t[7]=p.schluessel,t[8]=r,t[9]=a,t[10]=x):x=t[10];let S;t[11]===Symbol.for(`react.memo_cache_sentinel`)?(S=(0,k.jsx)(`p`,{className:`text-xs text-text-3`,children:`Der Schlüssel wird vor dem Speichern an Arcane geprüft und nie wieder angezeigt. Er liegt nur im Homelab-Teil.`}),t[11]=S):S=t[11];let C;t[12]!==p.schluessel||t[13]!==s||t[14]!==r?(C=p.schluessel===`hinterlegt`&&(s?(0,k.jsxs)(`span`,{className:`flex flex-wrap gap-2`,children:[(0,k.jsx)(w,{variant:`gefahr`,size:`sm`,disabled:r.isPending,onClick:()=>{r.mutate(null),c(!1)},children:`Wirklich entfernen?`}),(0,k.jsx)(w,{variant:`ghost`,size:`sm`,onClick:()=>c(!1),children:`Nein`})]}):(0,k.jsx)(w,{variant:`ghost`,size:`sm`,className:`self-start`,onClick:()=>c(!0),children:`Schlüssel entfernen`})),t[12]=p.schluessel,t[13]=s,t[14]=r,t[15]=C):C=t[15];let T;t[16]!==y||t[17]!==x||t[18]!==C?(T=(0,k.jsxs)(F,{titel:`Arcane (Docker)`,children:[y,b,x,S,C]}),t[16]=y,t[17]=x,t[18]=C,t[19]=T):T=t[19];let A=p.echt?`Echt: „Jetzt updaten“ bei Arcane zieht neue Images und startet die Container neu.`:`Probelauf: Arcane zeigt nur, was es tun würde — kein Container wird angefasst.`,j=p.echt_quelle===`umgebung`?` Festgelegt in der Dienst-Einstellung (MC_ARCANE_ECHT).`:``,M;t[20]!==A||t[21]!==j?(M=(0,k.jsxs)(`p`,{className:`text-sm text-text-2`,children:[A,j]}),t[20]=A,t[21]=j,t[22]=M):M=t[22];let N=p.echt?`outline`:`default`,P=p.echt_quelle===`umgebung`||i.isPending||p.schluessel===`fehlt`,I;t[23]===p.echt?I=t[24]:(I=()=>f(!p.echt),t[23]=p.echt,t[24]=I);let L=i.isPending?`Schaltet …`:p.echt?`Zurück auf Probelauf`:`Echt schalten`,R;t[25]!==N||t[26]!==P||t[27]!==I||t[28]!==L?(R=(0,k.jsx)(w,{variant:N,size:`sm`,className:`self-start`,disabled:P,onClick:I,children:L}),t[25]=N,t[26]=P,t[27]=I,t[28]=L,t[29]=R):R=t[29];let z;t[30]===p.schluessel?z=t[31]:(z=p.schluessel===`fehlt`&&(0,k.jsx)(`p`,{className:`text-xs text-text-3`,children:`Erst den Schlüssel eintragen.`}),t[30]=p.schluessel,t[31]=z);let B=l!==null,V=l?`Docker-Updates echt ausführen?`:`Zurück auf Probelauf?`,H=l?`Ab jetzt zieht „Jetzt updaten“ bei Arcane neue Images und startet die betroffenen Container neu. Vorher wird ein Snapshot der VM angelegt, soweit möglich. Das lässt sich hier jederzeit zurückschalten.`:`Docker-Updates zeigen dann wieder nur, was Arcane tun würde.`,U=l?`Echt schalten`:`Probelauf`,W=!!l,G;t[32]===Symbol.for(`react.memo_cache_sentinel`)?(G=()=>f(null),t[32]=G):G=t[32];let K;t[33]!==i||t[34]!==l?(K=()=>{l!==null&&(i.mutate(l),f(null))},t[33]=i,t[34]=l,t[35]=K):K=t[35];let q;t[36]!==i.isPending||t[37]!==B||t[38]!==V||t[39]!==H||t[40]!==U||t[41]!==W||t[42]!==K?(q=(0,k.jsx)(ee,{offen:B,titel:V,text:H,knopf:U,gefahr:W,gesperrt:i.isPending,onNein:G,onJa:K}),t[36]=i.isPending,t[37]=B,t[38]=V,t[39]=H,t[40]=U,t[41]=W,t[42]=K,t[43]=q):q=t[43];let J;t[44]!==M||t[45]!==R||t[46]!==z||t[47]!==q?(J=(0,k.jsxs)(F,{titel:`Docker-Updates`,children:[M,R,z,q]}),t[44]=M,t[45]=R,t[46]=z,t[47]=q,t[48]=J):J=t[48];let Y;return t[49]!==J||t[50]!==T?(Y=(0,k.jsxs)(k.Fragment,{children:[T,J]}),t[49]=J,t[50]=T,t[51]=Y):Y=t[51],Y}function te(e){let t=(0,D.c)(21),{h:n}=e,r=n.ausfuehrer,i;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(i=(0,k.jsx)(`dt`,{className:`text-text-3`,children:`Ausführer`}),t[0]=i):i=t[0];let a=r.verbunden?`text-gruen-text`:`text-rot-text`,o=r.verbunden?`verbunden`:`meldet sich nicht`,s;t[1]===r.zuletzt?s=t[2]:(s=r.zuletzt?` · zuletzt ${S(new Date(r.zuletzt*1e3).toISOString()).toLowerCase()}`:``,t[1]=r.zuletzt,t[2]=s);let c;t[3]!==a||t[4]!==o||t[5]!==s?(c=(0,k.jsxs)(`dd`,{className:a,children:[o,s]}),t[3]=a,t[4]=o,t[5]=s,t[6]=c):c=t[6];let l;t[7]===Symbol.for(`react.memo_cache_sentinel`)?(l=(0,k.jsx)(`dt`,{className:`text-text-3`,children:`Modus`}),t[7]=l):l=t[7];let u=r.nur_lesen?`nur lesen — Updates sind gesperrt`:`voll: Snapshots, Sicherungen und Updates`,d;t[8]===u?d=t[9]:(d=(0,k.jsx)(`dd`,{className:`text-text-2`,children:u}),t[8]=u,t[9]=d);let f;t[10]===Symbol.for(`react.memo_cache_sentinel`)?(f=(0,k.jsx)(`dt`,{className:`text-text-3`,children:`Sicherungen`}),t[10]=f):f=t[10];let p=r.sicherung_speicher?`auf „${r.sicherung_speicher}“ (wo kein Snapshot geht)`:`kein Speicher gefunden`,m;t[11]===p?m=t[12]:(m=(0,k.jsx)(`dd`,{className:`text-text-2`,children:p}),t[11]=p,t[12]=m);let h;t[13]===Symbol.for(`react.memo_cache_sentinel`)?(h=(0,k.jsx)(`dt`,{className:`text-text-3`,children:`Wartezeit`}),t[13]=h):h=t[13];let g=n.karenz_h>0?`${n.karenz_h} Stunden nach einer Änderung am Update-Skript einer App`:`aus`,_;t[14]===g?_=t[15]:(_=(0,k.jsx)(`dd`,{className:`text-text-2`,children:g}),t[14]=g,t[15]=_);let v;return t[16]!==m||t[17]!==_||t[18]!==c||t[19]!==d?(v=(0,k.jsx)(F,{titel:`Ausführer und Updates`,children:(0,k.jsxs)(`dl`,{className:`grid grid-cols-[auto_minmax(0,1fr)] gap-x-4 gap-y-2 text-sm`,children:[i,c,l,d,f,m,h,_]})}),t[16]=m,t[17]=_,t[18]=c,t[19]=d,t[20]=v):v=t[20],v}function ne(){let e=(0,D.c)(8),t=s().data,n=b().data,r=t?.rolle===`homelab`||!!(n?.eingerichtet&&n.erreichbar),i=f(r),a;if(!r){let t;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t=(0,k.jsx)(`p`,{className:`text-sm text-text-2`,children:`Der Homelab-Teil antwortet gerade nicht.`}),e[0]=t):t=e[0],a=t}else if(i.data){let t;e[4]===i.data?t=e[5]:(t=(0,k.jsxs)(k.Fragment,{children:[(0,k.jsx)(Z,{h:i.data}),(0,k.jsx)(te,{h:i.data})]}),e[4]=i.data,e[5]=t),a=t}else{let t=i.error?.message,n;e[1]!==i.isPending||e[2]!==t?(n=(0,k.jsx)(R,{laedt:i.isPending,fehler:t}),e[1]=i.isPending,e[2]=t,e[3]=n):n=e[3],a=n}let o;return e[6]===a?o=e[7]:(o=(0,k.jsx)(I,{titel:`Homelab`,farbe:`homelab`,text:`Arcane und Docker, der Ausführer auf dem Proxmox-Host, Rückwege.`,children:a}),e[6]=a,e[7]=o),o}function Q(){let e=(0,D.c)(17),t=l(!0),n=t.error?.message,r;e[0]!==t.data||e[1]!==t.isPending||e[2]!==n?(r={e:t.data,laedt:t.isPending,fehler:n},e[0]=t.data,e[1]=t.isPending,e[2]=n,e[3]=r):r=e[3];let i=r,a,o;e[4]===i?(a=e[5],o=e[6]):(a=(0,k.jsx)(W,{...i}),o=(0,k.jsx)(q,{...i}),e[4]=i,e[5]=a,e[6]=o);let s;e[7]===Symbol.for(`react.memo_cache_sentinel`)?(s=(0,k.jsx)(z,{offen:!0}),e[7]=s):s=e[7];let c;e[8]===Symbol.for(`react.memo_cache_sentinel`)?(c=(0,k.jsxs)(F,{titel:`Hermes`,children:[(0,k.jsxs)(`a`,{href:`/hermes-ui/`,target:`_blank`,rel:`noopener`,className:`flex h-11 items-center gap-2 self-start rounded-lg border border-linie-stark bg-erhaben px-4 text-[15px] hover:border-text-3`,children:[(0,k.jsx)(d,{className:`size-4`,"aria-hidden":!0}),` Hermes-Dashboard öffnen`]}),(0,k.jsx)(`p`,{className:`text-xs text-text-3`,children:`Chat, Sitzungen und Cron-Jobs verwaltet Hermes selbst. Es fragt nach seiner eigenen Anmeldung.`})]}),e[8]=c):c=e[8];let u;e[9]!==a||e[10]!==o?(u=(0,k.jsxs)(I,{titel:`KI-Box`,farbe:`box`,text:`Wann sie sich aktualisiert, das Modell-Radar und Zugänge.`,children:[a,o,s,c]}),e[9]=a,e[10]=o,e[11]=u):u=e[11];let f;e[12]===Symbol.for(`react.memo_cache_sentinel`)?(f=(0,k.jsx)(ne,{}),e[12]=f):f=e[12];let p;e[13]===Symbol.for(`react.memo_cache_sentinel`)?(p=(0,k.jsx)(I,{titel:`Meldungen`,text:`Telegram, Morgenmeldung und was sofort kommt.`,children:(0,k.jsx)(V,{})}),e[13]=p):p=e[13];let m;e[14]===Symbol.for(`react.memo_cache_sentinel`)?(m=(0,k.jsx)(I,{titel:`Software-Stand`,text:`Welcher Stand auf beiden Instanzen läuft.`,children:(0,k.jsx)(X,{offen:!0})}),e[14]=m):m=e[14];let h;return e[15]===u?h=e[16]:(h=(0,k.jsxs)(`div`,{className:`grid gap-5 md:gap-6 xl:grid-cols-2`,children:[u,f,p,m]}),e[15]=u,e[16]=h),h}export{Q as EinstellungenSeite};