diff --git a/apps/web/src/components/session-card.tsx b/apps/web/src/components/session-card.tsx index 00aa0c3..b2ac9dc 100644 --- a/apps/web/src/components/session-card.tsx +++ b/apps/web/src/components/session-card.tsx @@ -75,7 +75,12 @@ export function SessionCard({ const isActive = ["running", "building", "starting", "probing", "pending", "unhealthy"].includes(session.status); return ( -
+
+ {isBusy && ( +
+ +
+ )}
diff --git a/apps/web/src/pages/dashboard.tsx b/apps/web/src/pages/dashboard.tsx index 3071d1f..1b6d99e 100644 --- a/apps/web/src/pages/dashboard.tsx +++ b/apps/web/src/pages/dashboard.tsx @@ -143,6 +143,7 @@ export const HomePage = () => { }; const handleStop = async (session: SessionView) => { + if (actionBusy === session.id) return; setActionBusy(session.id); try { await stopInstance(session.project_id, session.repository_id, session.id); @@ -153,6 +154,7 @@ export const HomePage = () => { }; const handleDelete = async (session: SessionView) => { + if (actionBusy === session.id) return; setActionBusy(session.id); try { await deleteInstance(session.project_id, session.repository_id, session.id); @@ -165,6 +167,7 @@ export const HomePage = () => { }; const handleRecreateTunnel = async (session: SessionView) => { + if (actionBusy === session.id) return; setActionBusy(session.id); try { await recreateInstanceTunnel(session.project_id, session.repository_id, session.id); @@ -175,6 +178,7 @@ export const HomePage = () => { }; const handleStart = async (session: SessionView) => { + if (actionBusy === session.id) return; setActionBusy(session.id); try { await startInstance(session.project_id, session.repository_id, session.id); diff --git a/apps/web/src/pages/sessions.tsx b/apps/web/src/pages/sessions.tsx index 11dba2a..22ac603 100644 --- a/apps/web/src/pages/sessions.tsx +++ b/apps/web/src/pages/sessions.tsx @@ -9,6 +9,7 @@ import { type Session, deleteInstance, stopInstance, + startInstance, checkInstanceHealth, recreateInstanceTunnel, } from "../api/sessions"; @@ -38,7 +39,6 @@ export const SessionsPage = () => { const [tunnelHealth, setTunnelHealth] = useState>({}); const [loadingSessionId, setLoadingSessionId] = useState(null); - const [loadingAction, setLoadingAction] = useState(""); const loadSessions = useCallback(async () => { setStatus("loading"); @@ -155,8 +155,8 @@ export const SessionsPage = () => { }; const handleStop = async (session: Session) => { + if (loadingSessionId === session.id) return; setLoadingSessionId(session.id); - setLoadingAction("Stopping..."); try { await stopInstance(session.project_id, session.repository_id, session.id); await loadSessions(); @@ -164,13 +164,12 @@ export const SessionsPage = () => { // ignore } finally { setLoadingSessionId(null); - setLoadingAction(""); } }; const handleDelete = async (session: Session) => { + if (loadingSessionId === session.id) return; setLoadingSessionId(session.id); - setLoadingAction("Deleting..."); try { await deleteInstance(session.project_id, session.repository_id, session.id); setDirtyDeleteSession(null); @@ -189,13 +188,12 @@ export const SessionsPage = () => { } } finally { setLoadingSessionId(null); - setLoadingAction(""); } }; const handleForceDelete = async (session: Session) => { + if (loadingSessionId === session.id) return; setLoadingSessionId(session.id); - setLoadingAction("Force deleting..."); try { await deleteInstance(session.project_id, session.repository_id, session.id, true); setDirtyDeleteSession(null); @@ -205,13 +203,12 @@ export const SessionsPage = () => { // ignore } finally { setLoadingSessionId(null); - setLoadingAction(""); } }; const handleRecreateTunnel = async (session: Session) => { + if (loadingSessionId === session.id) return; setLoadingSessionId(session.id); - setLoadingAction("Recreating tunnel..."); try { await recreateInstanceTunnel( session.project_id, @@ -224,7 +221,19 @@ export const SessionsPage = () => { // ignore } finally { setLoadingSessionId(null); - setLoadingAction(""); + } + }; + + const handleStart = async (session: Session) => { + if (loadingSessionId === session.id) return; + setLoadingSessionId(session.id); + try { + await startInstance(session.project_id, session.repository_id, session.id); + await loadSessions(); + } catch { + // ignore + } finally { + setLoadingSessionId(null); } }; @@ -273,18 +282,11 @@ export const SessionsPage = () => { )} {/* Session List */} -
- {loadingSessionId && ( -
-
- -

{loadingAction}

-
-
- )} +