返回 DeepSeek-Reasonix
ManagementSurface.tsx
根目录 / desktop / frontend / src / components / ManagementSurface.tsx
1 import { Component, Suspense, lazy, useState, type ComponentType, type ReactNode } from "react";
2 import { useT } from "../lib/i18n";
3 class SurfaceBoundary extends Component<{ fallback: ReactNode; children: ReactNode }, { failed: boolean }> {
4 state = { failed: false };
5 static getDerivedStateFromError() { return { failed: true }; }
6 render() { return this.state.failed ? this.props.fallback : this.props.children; }
7 }
8 /** Recreate the lazy loader on retry; a rejected React.lazy promise is cached. */
9 export function ManagementSurface<P extends object>({ loader, surfaceProps, active, onBack }: {
10 loader: () => Promise<{ default: ComponentType<P> }>; surfaceProps: P; active: boolean; onBack: () => void;
11 }) {
12 const t = useT();
13 const [attempt, setAttempt] = useState(() => ({ key: 0, View: lazy(loader) }));
14 const { View } = attempt;
15 const fallback = (failed: boolean) => active ? <section aria-label={t("settings.title")} style={{ position: "fixed", inset: 0, zIndex: "var(--z-modal)", background: "var(--bg-soft)", padding: "60px 24px", color: "var(--fg)" }}>
16 <button className="btn" onClick={onBack}>{t("settings.backToWorkspace")}</button>
17 <p role={failed ? "alert" : "status"}>{t(failed ? "settings.loadFailed" : "common.loading")}</p>
18 {failed && <button className="btn" onClick={() => setAttempt((value) => ({ key: value.key + 1, View: lazy(loader) }))}>{t("common.retry")}</button>}
19 </section> : null;
20 return <SurfaceBoundary key={attempt.key} fallback={fallback(true)}><Suspense fallback={fallback(false)}><View {...surfaceProps} /></Suspense></SurfaceBoundary>;
21 }
22
22 lines Plain Text