import { Component, useState, type ErrorInfo, type ReactNode } from "react"; import { useOpenGeniText } from "../messages/runtime"; type ConversationRenderBoundaryProps = { /** A change (another session or workspace) clears a previous failure. */ resetKey: string; children: ReactNode; }; type BoundaryState = { failed: boolean; resetKey: string }; /** * Contains a rendering error inside the chat. Without it, one bad payload or * an incompatible host response unmounts the whole embedding page (a blank * Site or dashboard). Try again remounts the chat with fresh data. */ export function ConversationRenderBoundary({ resetKey, children, }: ConversationRenderBoundaryProps) { const [attempt, setAttempt] = useState(0); return ( setAttempt((value) => value + 1)}> {children} ); } class Boundary extends Component< { resetKey: string; onRetry: () => void; children: ReactNode }, BoundaryState > { state: BoundaryState = { failed: false, resetKey: this.props.resetKey }; static getDerivedStateFromError(): Partial { return { failed: true }; } static getDerivedStateFromProps( props: { resetKey: string }, state: BoundaryState, ): Partial | null { return props.resetKey !== state.resetKey ? { failed: false, resetKey: props.resetKey } : null; } componentDidCatch(error: unknown, info: ErrorInfo): void { console.error("Opengeni chat failed to render", error, info.componentStack); } render(): ReactNode { return this.state.failed ? ( ) : ( this.props.children ); } } function ConversationRenderError({ onRetry }: { onRetry: () => void }) { const t = useOpenGeniText(); return (

{t("conversationRenderBoundary.chatUnavailable")}

); }