Files
mai-bot/dashboard/dist/assets/restart-overlay-B44c6hlE.js

2 lines
7.5 KiB
JavaScript

import{r as d,j as e}from"./router-zNjPR4CY.js";import{P as R}from"./progress-C6-hh8fF.js";import{u as I,B as N,g as _}from"./index-CuOHsLf7.js";import{r as A}from"./system-api-DeeJapvB.js";import{R as S,a7 as L,W as P,e as D,L as C}from"./icons-DTcdLw9j.js";const y={INITIAL_DELAY:3e3,CHECK_INTERVAL:2e3,CHECK_TIMEOUT:3e3,MAX_ATTEMPTS:60,PROGRESS_INTERVAL:200,SUCCESS_REDIRECT_DELAY:1500},w=d.createContext(null);function q({children:u,onRestartComplete:m,onRestartFailed:p,healthCheckUrl:s="/api/webui/system/status",maxAttempts:a=y.MAX_ATTEMPTS}){const[l,i]=d.useState({status:"idle",progress:0,elapsedTime:0,checkAttempts:0,maxAttempts:a}),n=d.useRef({}),r=d.useCallback(()=>{const t=n.current;t.progress&&(clearInterval(t.progress),t.progress=void 0),t.elapsed&&(clearInterval(t.elapsed),t.elapsed=void 0),t.check&&(clearTimeout(t.check),t.check=void 0)},[]),g=d.useCallback(()=>{r(),i({status:"idle",progress:0,elapsedTime:0,checkAttempts:0,maxAttempts:a})},[r,a]),T=d.useCallback(async()=>{try{const t=new AbortController,x=setTimeout(()=>t.abort(),y.CHECK_TIMEOUT),j=await fetch(s,{method:"GET",headers:{"Content-Type":"application/json"},credentials:"include",signal:t.signal});return clearTimeout(x),j.ok}catch{return!1}},[s]),h=d.useCallback(()=>{let t=0;const x=async()=>{if(t++,i(f=>({...f,status:"checking",checkAttempts:t})),await T())r(),i(f=>({...f,status:"success",progress:100})),setTimeout(()=>{m?.(),window.location.href="/auth"},y.SUCCESS_REDIRECT_DELAY);else if(t>=a){r();const f=`健康检查超时 (${t}/${a})`;i(v=>({...v,status:"failed",error:f})),p?.(f)}else{const f=setTimeout(x,y.CHECK_INTERVAL);n.current.check=f}};x()},[T,r,a,m,p]),c=d.useCallback(()=>{i(t=>({...t,status:"checking",checkAttempts:0,error:void 0})),h()},[h]),b=d.useCallback(async t=>{const{delay:x=0,skipApiCall:j=!1}=t??{};if(l.status!=="idle"&&l.status!=="failed")return;if(r(),i({status:"requesting",progress:0,elapsedTime:0,checkAttempts:0,maxAttempts:a}),x>0&&await new Promise(o=>setTimeout(o,x)),j)i(o=>({...o,status:"restarting"}));else try{i(o=>({...o,status:"restarting"})),await Promise.race([A(),new Promise(o=>setTimeout(o,5e3))])}catch{}const f=setInterval(()=>{i(o=>({...o,progress:o.progress>=90?o.progress:o.progress+1}))},y.PROGRESS_INTERVAL),v=setInterval(()=>{i(o=>({...o,elapsedTime:o.elapsedTime+1}))},1e3);n.current.progress=f,n.current.elapsed=v,setTimeout(()=>{h()},y.INITIAL_DELAY)},[l.status,r,a,h]),k={state:l,isRestarting:l.status!=="idle",triggerRestart:b,resetState:g,retryHealthCheck:c};return e.jsx(w,{value:k,children:u})}function H(){const u=d.useContext(w);if(!u)throw new Error("useRestart must be used within a RestartProvider");return u}function M(){try{return H()}catch{return null}}const O=(u,m,p,s,a,l)=>({idle:{icon:null,title:"",description:"",tip:""},requesting:{icon:e.jsx(C,{className:"h-16 w-16 text-primary animate-spin"}),title:a??s("restart.preparing"),description:l??s("restart.preparingDesc"),tip:s("restart.preparingTip")},restarting:{icon:e.jsx(C,{className:"h-16 w-16 text-primary animate-spin"}),title:a??s("restart.restarting"),description:l??s("restart.restartingDesc"),tip:s("restart.restartingTip")},checking:{icon:e.jsx(C,{className:"h-16 w-16 text-primary animate-spin"}),title:s("restart.checking"),description:s("restart.checkingDesc",{current:m,max:p}),tip:s("restart.checkingTip")},success:{icon:e.jsx(D,{className:"h-16 w-16 text-green-500"}),title:s("restart.success"),description:s("restart.successDesc"),tip:s("restart.successTip")},failed:{icon:e.jsx(P,{className:"h-16 w-16 text-destructive"}),title:s("restart.failed"),description:s("restart.failedDesc"),tip:s("restart.failedTip")}})[u];function z({visible:u,onComplete:m,onFailed:p,title:s,description:a,showAnimation:l=!0,className:i}){const n=M();return(n?n.isRestarting:u)?n?e.jsx(E,{state:n.state,onRetry:n.retryHealthCheck,onComplete:m,onFailed:p,title:s,description:a,showAnimation:l,className:i}):e.jsx(V,{onComplete:m,onFailed:p,title:s,description:a,showAnimation:l,className:i}):null}function E({state:u,onRetry:m,onComplete:p,onFailed:s,title:a,description:l,showAnimation:i,className:n}){const{status:r,progress:g,elapsedTime:T,checkAttempts:h,maxAttempts:c}=u,{t:b}=I();d.useEffect(()=>{r==="success"&&p?p():r==="failed"&&s&&s()},[r,p,s]);const k=O(r,h,c,b,a,l),t=x=>{const j=Math.floor(x/60),f=x%60;return`${j}:${f.toString().padStart(2,"0")}`};return e.jsxs("div",{className:_("fixed inset-0 bg-background/95 backdrop-blur-sm z-50 flex items-center justify-center",n),children:[i&&e.jsx(G,{}),e.jsxs("div",{className:"max-w-md w-full mx-4 space-y-8 relative z-10",children:[e.jsxs("div",{className:"flex flex-col items-center space-y-4",children:[e.jsxs("div",{className:"relative",children:[k.icon,(r==="restarting"||r==="checking")&&e.jsx("div",{className:"absolute inset-0 rounded-full bg-primary/20 animate-ping"})]}),e.jsx("h2",{className:"text-2xl font-bold",children:k.title}),e.jsx("p",{className:"text-muted-foreground text-center",children:k.description})]}),r!=="failed"&&r!=="idle"&&e.jsxs("div",{className:"space-y-2",children:[e.jsx(R,{value:g,className:"h-2"}),e.jsxs("div",{className:"flex justify-between text-sm text-muted-foreground",children:[e.jsxs("span",{children:[g,"%"]}),e.jsxs("span",{children:[b("restart.elapsed")," ",t(T)]})]})]}),e.jsx("div",{className:"bg-muted/50 rounded-lg p-4",children:e.jsx("p",{className:"text-sm text-muted-foreground",children:k.tip})}),r==="failed"&&e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(N,{onClick:()=>window.location.reload(),variant:"default",className:"flex-1",children:[e.jsx(S,{className:"mr-2 h-4 w-4"}),b("restart.refreshPage")]}),e.jsxs(N,{onClick:m,variant:"secondary",className:"flex-1",children:[e.jsx(L,{className:"mr-2 h-4 w-4"}),b("restart.retryCheck")]})]})]})]})}function V({onComplete:u,onFailed:m,title:p,description:s,showAnimation:a,className:l}){const[i,n]=d.useState({status:"restarting",progress:0,elapsedTime:0,checkAttempts:0,maxAttempts:60}),r=d.useCallback(()=>{let g=0;const T=60,h=async()=>{g++,n(c=>({...c,status:"checking",checkAttempts:g}));try{if((await fetch("/api/webui/system/status",{method:"GET",signal:AbortSignal.timeout(3e3)})).ok){n(b=>({...b,status:"success",progress:100})),setTimeout(()=>{u?.(),window.location.href="/auth"},1500);return}}catch{}g>=T?(n(c=>({...c,status:"failed"})),m?.()):setTimeout(h,2e3)};h()},[u,m]);return d.useEffect(()=>{const g=setInterval(()=>{n(c=>({...c,progress:c.progress>=90?c.progress:c.progress+1}))},200),T=setInterval(()=>{n(c=>({...c,elapsedTime:c.elapsedTime+1}))},1e3),h=setTimeout(()=>{r()},3e3);return()=>{clearInterval(g),clearInterval(T),clearTimeout(h)}},[r]),e.jsx(E,{state:i,onRetry:r,onComplete:u,onFailed:m,title:p,description:s,showAnimation:a,className:l})}function G(){return e.jsxs("div",{className:"absolute inset-0 overflow-hidden pointer-events-none",children:[e.jsxs("div",{className:"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] h-[600px]",children:[e.jsx("div",{className:"absolute inset-0 rounded-full border border-primary/10 animate-[ping_3s_ease-in-out_infinite]"}),e.jsx("div",{className:"absolute inset-8 rounded-full border border-primary/10 animate-[ping_3s_ease-in-out_infinite_0.5s]"}),e.jsx("div",{className:"absolute inset-16 rounded-full border border-primary/10 animate-[ping_3s_ease-in-out_infinite_1s]"})]}),e.jsx("div",{className:"absolute top-1/4 left-1/4 w-2 h-2 bg-primary/20 rounded-full animate-bounce"}),e.jsx("div",{className:"absolute top-3/4 right-1/4 w-3 h-3 bg-primary/15 rounded-full animate-bounce delay-150"}),e.jsx("div",{className:"absolute top-1/2 right-1/3 w-2 h-2 bg-primary/20 rounded-full animate-bounce delay-300"})]})}export{q as R,z as a,H as u};