import { Alert, Box, Button, CircularProgress } from "@mui/material"; import { useEffect, useRef, useState } from "react"; enum State { Loading, Ready, Error, } export function AsyncWidget(p: { loadKey: any; load: () => Promise; errMsg: string; build: () => React.ReactElement; ready?: boolean; errAdditionalElement?: () => React.ReactElement; }): React.ReactElement { const [state, setState] = useState(State.Loading); const counter = useRef(null); const load = async () => { try { setState(State.Loading); await p.load(); setState(State.Ready); } catch (e) { console.error(e); setState(State.Error); } }; useEffect(() => { if (counter.current === p.loadKey) return; counter.current = p.loadKey; load(); }); if (state === State.Error) return ( theme.palette.mode === "light" ? theme.palette.grey[100] : theme.palette.grey[900], }} > {p.errMsg} {p.errAdditionalElement && p.errAdditionalElement()} ); if (state === State.Loading || p.ready === false) return ( theme.palette.mode === "light" ? theme.palette.grey[100] : theme.palette.grey[900], }} > ); return p.build(); }