Bin
2025-12-17 2b99d77d73ba568beff0a549534017caaad8a6de
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import { observer, Provider } from "mobx-react";
import React from "react";
import clsx from "clsx";
import { SDKProvider } from "../../providers/SDKProvider";
import { cn } from "../../utils/bem";
import { Spinner } from "../Common/Spinner";
import { DataManager } from "../DataManager/DataManager";
import { Labeling } from "../Label/Label";
import "./App.scss";
import { QueryClientProvider } from "@tanstack/react-query";
import { queryClient } from "@humansignal/core/lib/utils/query-client";
import { AuthProvider } from "@humansignal/core/providers/AuthProvider";
 
interface ErrorBoundaryProps {
  children: React.ReactNode;
}
 
interface ErrorBoundaryState {
  error: Error | null;
}
 
class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {
  state: ErrorBoundaryState = {
    error: null,
  };
 
  componentDidCatch(error: Error): void {
    this.setState({ error });
  }
 
  render(): React.ReactNode {
    return this.state.error ? <div className="error">{this.state.error.toString()}</div> : this.props.children;
  }
}
 
interface AppComponentProps {
  app: {
    SDK: {
      mode: string;
    };
    crashed: boolean;
    loading: boolean;
    isLabeling: boolean;
  };
}
 
/**
 * Main Component
 */
const AppComponent: React.FC<AppComponentProps> = ({ app }) => {
  const rootCN = cn("root");
  const rootClassName = rootCN.mod({ mode: app.SDK.mode }).toString();
 
  return (
    <ErrorBoundary>
      <QueryClientProvider client={queryClient}>
        <AuthProvider>
          <Provider store={app}>
            <SDKProvider sdk={app.SDK}>
              <div className={rootClassName}>
                {app.crashed ? (
                  <div className={clsx(rootCN.toString(), rootClassName)}>
                    <span className={rootCN.elem("header").toString()}>糟糕...</span>
                    <span className={rootCN.elem("description").toString()}>
                      项目已被删除或尚未创建。
                    </span>
                  </div>
                ) : app.loading ? (
                  <div className={cn("app-loader").toString()}>
                    <Spinner size="large" />
                  </div>
                ) : app.isLabeling ? (
                  <Labeling />
                ) : (
                  <DataManager />
                )}
                <div className={cn("offscreen").toString()} />
              </div>
            </SDKProvider>
          </Provider>
        </AuthProvider>
      </QueryClientProvider>
    </ErrorBoundary>
  );
};
 
export const App = observer(AppComponent);