Mirrored from GitHub
github.com/roostorg/osprey
1import * as React from 'react';
2import { App as AntdApp, ConfigProvider, Spin, theme } from 'antd';
3import { Router, Switch, Route } from 'react-router-dom';
4
5import { getApplicationConfig } from './actions/ConfigActions';
6import UdfDocsView from './components/docs/UdfDocsView';
7import BulkJobHistoryView from './components/bulk_job_history/BulkJobHistory';
8import { FeaturesPage } from './components/features/FeaturesPage';
9import { RulesPage } from './components/rules/RulesPage';
10import RulesVisualizerView from './components/rules_visualizer/RulesVisualizer';
11import EntityViewBar from './components/entities/EntityViewBar';
12import EventPage from './components/event_stream/EventPage';
13import NavBar from './components/navigation/NavBar';
14import QueryHistory from './components/query_history/QueryHistory';
15import QueryView from './components/query_view/QueryView';
16import SavedQueries from './components/saved_queries/SavedQueries';
17import SavedQueryBar from './components/saved_queries/SavedQueryBar';
18import usePromiseResult from './hooks/usePromiseResult';
19import useApplicationConfigStore from './stores/ApplicationConfigStore';
20import useThemeStore from './stores/ThemeStore';
21import { history } from './stores/QueryStore';
22import { renderFromPromiseResult } from './utils/PromiseResultUtils';
23
24import './stores/SearchParamsStateListener';
25
26import { Routes } from './Constants';
27import styles from './App.module.css';
28import { BulkActionPage } from './components/bulk_actions/BulkActionPage';
29
30const AppRouter: React.FC = () => {
31 const updateApplicationConfig = useApplicationConfigStore((state) => state.updateApplicationConfig);
32 const themeMode = useThemeStore((state) => {
33 return state.mode;
34 });
35
36 const applicationConfigResult = usePromiseResult(async () => {
37 const appConfig = await getApplicationConfig();
38 updateApplicationConfig(appConfig);
39 });
40
41 const isDark = themeMode === 'dark';
42 // Mirror of CSS tokens in Colors.module.css. Antd's algorithm needs concrete
43 // color strings at render time to compute its derivatives, so we can't pass
44 // var(--*) directly. Keep these literals in sync with their tokens:
45 // colorPrimary ↔ --brand-primary
46 // Menu.itemSelectedColor ↔ --text-dark-primary
47 const themeConfig = React.useMemo(() => {
48 return {
49 token: { colorPrimary: isDark ? '#4858e0' : '#1227ce' },
50 algorithm: isDark ? theme.darkAlgorithm : theme.defaultAlgorithm,
51 components: {
52 Menu: {
53 collapsedWidth: 56,
54 ...(isDark ? { itemSelectedColor: '#ebebeb' } : {}),
55 },
56 },
57 };
58 }, [isDark]);
59
60 React.useLayoutEffect(() => {
61 // Cold-start theme is set by the inline script in public/index.html so the
62 // first paint matches the stored preference. This effect keeps the class in
63 // sync when the user toggles themes.
64 const root = document.documentElement;
65 if (isDark) {
66 root.classList.add('dark-theme');
67 } else {
68 root.classList.remove('dark-theme');
69 }
70 }, [isDark]);
71
72 return (
73 <ConfigProvider theme={themeConfig}>
74 {renderFromPromiseResult(applicationConfigResult, () => (
75 <AntdApp>
76 <Router history={history}>
77 <Switch>
78 <Route path="/events/:eventId">
79 <EventPage />
80 </Route>
81 <Route>
82 <NavBar>
83 <Route exact path={[Routes.SAVED_QUERY, Routes.SAVED_QUERY_LATEST]}>
84 <SavedQueryBar />
85 </Route>
86 <Route exact path={Routes.ENTITY}>
87 <EntityViewBar />
88 </Route>
89 <Switch>
90 <Route path={Routes.QUERY_HISTORY}>
91 <QueryHistory />
92 </Route>
93 <Route path={Routes.SAVED_QUERIES}>
94 <SavedQueries />
95 </Route>
96 <Route path={Routes.DOCS_UDFS}>
97 <UdfDocsView />
98 </Route>
99 <Route path={Routes.BULK_JOB_HISTORY}>
100 <BulkJobHistoryView />
101 </Route>
102 <Route path={Routes.RULES_VISUALIZER}>
103 <RulesVisualizerView />
104 </Route>
105 <Route path={Routes.FEATURES}>
106 <FeaturesPage />
107 </Route>
108 <Route path={Routes.RULES}>
109 <RulesPage />
110 </Route>
111 <Route exact path={[Routes.ENTITY, Routes.HOME, Routes.SAVED_QUERY]}>
112 <QueryView />
113 </Route>
114 <Route exact path={Routes.SAVED_QUERY_LATEST}>
115 <div className={styles.spinner}>
116 <Spin size="large" />
117 </div>
118 </Route>
119 <Route exact path={Routes.BULK_ACTION} component={BulkActionPage} />
120 </Switch>
121 </NavBar>
122 </Route>
123 </Switch>
124 </Router>
125 </AntdApp>
126 ))}
127 </ConfigProvider>
128 );
129};
130
131export default AppRouter;