|
|
import { useCallback, useState } from "react"; |
|
|
import { FormData } from "../types"; |
|
|
import { |
|
|
createStartDemoPayload, |
|
|
readFileAsText, |
|
|
startDemo, |
|
|
} from "../utils/api"; |
|
|
import { useHealthCheck } from "./useHealthCheck"; |
|
|
|
|
|
interface HealthCheckProgress { |
|
|
attempt: number; |
|
|
maxAttempts: number; |
|
|
} |
|
|
|
|
|
interface UseStartDemoOptions { |
|
|
onSuccess?: () => void; |
|
|
onError?: (error: Error) => void; |
|
|
} |
|
|
|
|
|
interface UseStartDemoReturn { |
|
|
|
|
|
isStarting: boolean; |
|
|
iframeUrl: string; |
|
|
iframeLoading: boolean; |
|
|
healthCheckProgress: HealthCheckProgress | null; |
|
|
|
|
|
|
|
|
startDemoSession: ( |
|
|
formData: FormData, |
|
|
loginLabel: string, |
|
|
accessToken: string | null, |
|
|
options?: UseStartDemoOptions & { logPrefix?: string } |
|
|
) => Promise<void>; |
|
|
resetDemo: () => void; |
|
|
setIframeLoaded: () => void; |
|
|
} |
|
|
|
|
|
export const useStartDemo = (): UseStartDemoReturn => { |
|
|
const [isStarting, setIsStarting] = useState<boolean>(false); |
|
|
const [iframeUrl, setIframeUrl] = useState<string>(""); |
|
|
const [iframeLoading, setIframeLoading] = useState<boolean>(false); |
|
|
|
|
|
const { healthCheckProgress, startHealthCheck } = useHealthCheck(); |
|
|
|
|
|
const startDemoSession = useCallback(async ( |
|
|
formData: FormData, |
|
|
loginLabel: string, |
|
|
accessToken: string | null, |
|
|
options: UseStartDemoOptions & { logPrefix?: string } = {} |
|
|
) => { |
|
|
const { |
|
|
onSuccess, |
|
|
onError, |
|
|
logPrefix = "Demo startup" |
|
|
} = options; |
|
|
|
|
|
setIsStarting(true); |
|
|
setIframeLoading(true); |
|
|
|
|
|
try { |
|
|
|
|
|
const mcpText = formData.mcpFile |
|
|
? await readFileAsText(formData.mcpFile) |
|
|
: null; |
|
|
|
|
|
|
|
|
const payload = createStartDemoPayload( |
|
|
formData.model, |
|
|
formData.provider, |
|
|
loginLabel, |
|
|
mcpText, |
|
|
); |
|
|
|
|
|
const result = await startDemo(payload, accessToken); |
|
|
setIframeUrl(result.iframe_url); |
|
|
|
|
|
|
|
|
await startHealthCheck(result.health_url, { |
|
|
logPrefix: `${logPrefix} health check`, |
|
|
onSuccess: () => { |
|
|
setIframeLoading(false); |
|
|
if (onSuccess) { |
|
|
onSuccess(); |
|
|
} |
|
|
}, |
|
|
onError: (healthCheckError) => { |
|
|
setIframeLoading(false); |
|
|
if (onError) { |
|
|
onError(new Error("Server startup timed out. The application may still be loading in the background.")); |
|
|
} |
|
|
}, |
|
|
}); |
|
|
} catch (error) { |
|
|
console.error(`${logPrefix} failed:`, error); |
|
|
setIsStarting(false); |
|
|
setIframeLoading(false); |
|
|
|
|
|
if (onError) { |
|
|
onError(error as Error); |
|
|
} |
|
|
} finally { |
|
|
setIsStarting(false); |
|
|
} |
|
|
}, [startHealthCheck]); |
|
|
|
|
|
const resetDemo = useCallback(() => { |
|
|
setIframeUrl(""); |
|
|
setIframeLoading(false); |
|
|
setIsStarting(false); |
|
|
}, []); |
|
|
|
|
|
const setIframeLoaded = useCallback(() => { |
|
|
setIframeLoading(false); |
|
|
}, []); |
|
|
|
|
|
return { |
|
|
|
|
|
isStarting, |
|
|
iframeUrl, |
|
|
iframeLoading, |
|
|
healthCheckProgress, |
|
|
|
|
|
|
|
|
startDemoSession, |
|
|
resetDemo, |
|
|
setIframeLoaded, |
|
|
}; |
|
|
}; |
|
|
|