mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-14 03:05:56 +08:00
fix(FE): AppRoutes is refactored (#260)
* react-app-env.d.ts is moved to the typings * webpack config for development and production is updated * extra browser router component is removed * loable component is made * spinner component is updated * route are updated * routes are imported is Loadable fashion with chunkName * AppRoute is updated * AppWrapper is changed to AppRouter * merge conflits are resolved * Loadable component is updated Co-authored-by: Ankit Nayan <ankit@signoz.io>
This commit is contained in:
parent
f394f72bfb
commit
9008d19a7b
43
frontend/src/AppRoutes/index.tsx
Normal file
43
frontend/src/AppRoutes/index.tsx
Normal file
@ -0,0 +1,43 @@
|
||||
import React, { Suspense } from "react";
|
||||
import ROUTES from "constants/routes";
|
||||
import { BrowserRouter, Route, Switch, Redirect } from "react-router-dom";
|
||||
import Spinner from "components/Spinner";
|
||||
import NotFound from "components/NotFound";
|
||||
|
||||
import { IS_LOGGED_IN } from "constants/auth";
|
||||
|
||||
import AppLayout from "modules/AppLayout";
|
||||
import { RouteProvider } from "modules/RouteProvider";
|
||||
import routes from "./routes";
|
||||
|
||||
const App = () => (
|
||||
<BrowserRouter basename="/">
|
||||
<RouteProvider>
|
||||
<AppLayout>
|
||||
<Suspense fallback={<Spinner size="large" tip="Loading..." />}>
|
||||
<Switch>
|
||||
{routes.map(({ path, component, exact }) => {
|
||||
return <Route exact={exact} path={path} component={component} />;
|
||||
})}
|
||||
|
||||
{/* This logic should be moved to app layout */}
|
||||
<Route
|
||||
path="/"
|
||||
exact
|
||||
render={() => {
|
||||
return localStorage.getItem(IS_LOGGED_IN) === "yes" ? (
|
||||
<Redirect to={ROUTES.APPLICATION} />
|
||||
) : (
|
||||
<Redirect to={ROUTES.SIGN_UP} />
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<Route path="*" component={NotFound} />
|
||||
</Switch>
|
||||
</Suspense>
|
||||
</AppLayout>
|
||||
</RouteProvider>
|
||||
</BrowserRouter>
|
||||
);
|
||||
|
||||
export default App;
|
70
frontend/src/AppRoutes/routes.ts
Normal file
70
frontend/src/AppRoutes/routes.ts
Normal file
@ -0,0 +1,70 @@
|
||||
import {
|
||||
ServiceMetricsPage,
|
||||
ServiceMapPage,
|
||||
TraceDetailPage,
|
||||
TraceGraphPage,
|
||||
UsageExplorerPage,
|
||||
ServicesTablePage,
|
||||
SignupPage,
|
||||
SettingsPage,
|
||||
InstrumentationPage,
|
||||
} from "pages";
|
||||
import ROUTES from "constants/routes";
|
||||
import { RouteProps } from "react-router-dom";
|
||||
|
||||
const routes: AppRoutes[] = [
|
||||
{
|
||||
component: SignupPage,
|
||||
path: ROUTES.SIGN_UP,
|
||||
exact: true,
|
||||
},
|
||||
{
|
||||
component: ServicesTablePage,
|
||||
path: ROUTES.APPLICATION,
|
||||
exact: true,
|
||||
},
|
||||
{
|
||||
path: ROUTES.SERVICE_METRICS,
|
||||
exact: true,
|
||||
component: ServiceMetricsPage,
|
||||
},
|
||||
{
|
||||
path: ROUTES.SERVICE_MAP,
|
||||
component: ServiceMapPage,
|
||||
exact: true,
|
||||
},
|
||||
{
|
||||
path: ROUTES.TRACE_GRAPH,
|
||||
exact: true,
|
||||
component: TraceGraphPage,
|
||||
},
|
||||
{
|
||||
path: ROUTES.SETTINGS,
|
||||
exact: true,
|
||||
component: SettingsPage,
|
||||
},
|
||||
{
|
||||
path: ROUTES.USAGE_EXPLORER,
|
||||
exact: true,
|
||||
component: UsageExplorerPage,
|
||||
},
|
||||
{
|
||||
path: ROUTES.INSTRUMENTATION,
|
||||
exact: true,
|
||||
component: InstrumentationPage,
|
||||
},
|
||||
{
|
||||
path: ROUTES.TRACES,
|
||||
exact: true,
|
||||
component: TraceDetailPage,
|
||||
},
|
||||
];
|
||||
|
||||
interface AppRoutes {
|
||||
component: RouteProps["component"];
|
||||
path: RouteProps["path"];
|
||||
exact: RouteProps["exact"];
|
||||
isPrivate?: boolean;
|
||||
}
|
||||
|
||||
export default routes;
|
17
frontend/src/components/Loadable/index.tsx
Normal file
17
frontend/src/components/Loadable/index.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
import { lazy, ComponentType } from "react";
|
||||
|
||||
function Loadable(importPath: {
|
||||
(): LoadableProps;
|
||||
}): React.LazyExoticComponent<LazyComponent> {
|
||||
const LazyComponent = lazy(() => importPath());
|
||||
|
||||
return LazyComponent;
|
||||
}
|
||||
|
||||
type LazyComponent = ComponentType<Record<string, unknown>>;
|
||||
|
||||
type LoadableProps = Promise<{
|
||||
default: LazyComponent;
|
||||
}>;
|
||||
|
||||
export default Loadable;
|
@ -1,42 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Spin } from 'antd';
|
||||
import styled from "styled-components";
|
||||
import { LoadingOutlined } from '@ant-design/icons';
|
||||
const antIcon = <LoadingOutlined style={{ fontSize: 24 }} spin />;
|
||||
|
||||
const SpinerStyle = styled.div`
|
||||
position: fixed;
|
||||
z-index: 999;
|
||||
height: 4em;
|
||||
// width: 4em;
|
||||
overflow: visible;
|
||||
margin: auto;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
`;
|
||||
|
||||
export const CustomSpinner = ({
|
||||
size,
|
||||
tip,
|
||||
}:{
|
||||
size:string,
|
||||
tip:string,
|
||||
})=>{
|
||||
return(
|
||||
<>
|
||||
<SpinerStyle>
|
||||
<Spin size={size} tip={tip} indicator={antIcon}/>
|
||||
</SpinerStyle>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export const DefaultSpinner = ()=>{
|
||||
return(
|
||||
<>
|
||||
<Spin indicator={antIcon}/>
|
||||
</>
|
||||
)
|
||||
}
|
19
frontend/src/components/Spinner/index.tsx
Normal file
19
frontend/src/components/Spinner/index.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import React from "react";
|
||||
import { Spin, SpinProps } from "antd";
|
||||
import { LoadingOutlined } from "@ant-design/icons";
|
||||
|
||||
import { SpinerStyle } from "./styles";
|
||||
|
||||
const Spinner = ({ size, tip, height }: SpinnerProps): JSX.Element => (
|
||||
<SpinerStyle height={height}>
|
||||
<Spin spinning size={size} tip={tip} indicator={<LoadingOutlined spin />} />
|
||||
</SpinerStyle>
|
||||
);
|
||||
|
||||
interface SpinnerProps {
|
||||
size?: SpinProps["size"];
|
||||
tip?: SpinProps["tip"];
|
||||
height?: React.CSSProperties["height"];
|
||||
}
|
||||
|
||||
export default Spinner;
|
16
frontend/src/components/Spinner/styles.ts
Normal file
16
frontend/src/components/Spinner/styles.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
interface Props {
|
||||
height: React.CSSProperties["height"];
|
||||
}
|
||||
|
||||
export const SpinerStyle = styled.div<Props>`
|
||||
z-index: 999;
|
||||
overflow: visible;
|
||||
margin: auto;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: ${({ height = "100vh" }) => height};
|
||||
`;
|
@ -3,18 +3,15 @@ import ReactDOM from "react-dom";
|
||||
import { Provider } from "react-redux";
|
||||
import { ThemeSwitcherProvider } from "react-css-theme-switcher";
|
||||
import store from "store";
|
||||
import AppWrapper from "modules/AppWrapper";
|
||||
import AppRoutes from "AppRoutes";
|
||||
import "assets/index.css";
|
||||
import { BrowserRouter as Router } from "react-router-dom";
|
||||
import themes from "themes";
|
||||
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
<React.StrictMode>
|
||||
<ThemeSwitcherProvider themeMap={themes} defaultTheme="dark">
|
||||
<Router basename="/">
|
||||
<AppWrapper />
|
||||
</Router>
|
||||
<AppRoutes />
|
||||
</ThemeSwitcherProvider>
|
||||
</React.StrictMode>
|
||||
</Provider>,
|
||||
|
@ -1,70 +0,0 @@
|
||||
import React, { Suspense } from "react";
|
||||
import { useThemeSwitcher } from "react-css-theme-switcher";
|
||||
import ROUTES from "constants/routes";
|
||||
import { IS_LOGGED_IN } from "constants/auth";
|
||||
import { BrowserRouter, Route, Switch, Redirect } from "react-router-dom";
|
||||
import { CustomSpinner } from "components/Spiner";
|
||||
|
||||
import BaseLayout from "./BaseLayout";
|
||||
import {
|
||||
ServiceMetrics,
|
||||
ServiceMap,
|
||||
TraceDetail,
|
||||
TraceGraph,
|
||||
UsageExplorer,
|
||||
ServicesTable,
|
||||
Signup,
|
||||
SettingsPage,
|
||||
InstrumentationPage,
|
||||
} from "pages";
|
||||
import { RouteProvider } from "./RouteProvider";
|
||||
import NotFound from "components/NotFound";
|
||||
|
||||
const App = () => {
|
||||
const { status } = useThemeSwitcher();
|
||||
|
||||
if (status === "loading") {
|
||||
return <CustomSpinner size="large" tip="Loading..." />;
|
||||
}
|
||||
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<RouteProvider>
|
||||
<BaseLayout>
|
||||
<Suspense fallback={<CustomSpinner size="large" tip="Loading..." />}>
|
||||
<Switch>
|
||||
<Route path={ROUTES.SIGN_UP} exact component={Signup} />
|
||||
<Route path={ROUTES.APPLICATION} exact component={ServicesTable} />
|
||||
<Route path={ROUTES.SERVICE_METRICS} exact component={ServiceMetrics} />
|
||||
<Route path={ROUTES.SERVICE_MAP} exact component={ServiceMap} />
|
||||
<Route path={ROUTES.TRACES} exact component={TraceDetail} />
|
||||
<Route path={ROUTES.TRACE_GRAPH} exact component={TraceGraph} />
|
||||
<Route path={ROUTES.SETTINGS} exact component={SettingsPage} />
|
||||
<Route
|
||||
path={ROUTES.INSTRUMENTATION}
|
||||
exact
|
||||
component={InstrumentationPage}
|
||||
/>
|
||||
<Route path={ROUTES.USAGE_EXPLORER} exact component={UsageExplorer} />
|
||||
<Route
|
||||
path="/"
|
||||
exact
|
||||
render={() => {
|
||||
return localStorage.getItem(IS_LOGGED_IN) === "yes" ? (
|
||||
<Redirect to={ROUTES.APPLICATION} />
|
||||
) : (
|
||||
<Redirect to={ROUTES.SIGN_UP} />
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
||||
<Route path="*" exact component={NotFound} />
|
||||
</Switch>
|
||||
</Suspense>
|
||||
</BaseLayout>
|
||||
</RouteProvider>
|
||||
</BrowserRouter>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
@ -3,13 +3,13 @@ import { NavLink } from "react-router-dom";
|
||||
import { Button, Space, Table } from "antd";
|
||||
import styled from "styled-components";
|
||||
import { connect } from "react-redux";
|
||||
import Spinner from "components/Spinner";
|
||||
import { SKIP_ONBOARDING } from "constants/onboarding";
|
||||
import ROUTES from "constants/routes";
|
||||
import { getServicesList, GlobalTime } from "store/actions";
|
||||
import { servicesListItem } from "store/actions/MetricsActions";
|
||||
import { StoreState } from "store/reducers";
|
||||
import { CustomModal } from "components/Modal";
|
||||
import { CustomSpinner, DefaultSpinner } from "components/Spiner";
|
||||
|
||||
interface ServicesTableProps {
|
||||
servicesList: servicesListItem[];
|
||||
@ -124,7 +124,7 @@ const _ServicesTable = (props: ServicesTableProps) => {
|
||||
}, [props.servicesList, errorObject]);
|
||||
|
||||
if (!initialDataFetch) {
|
||||
return <CustomSpinner size="large" tip="Fetching data..." />;
|
||||
return <Spinner height="90vh" size="large" tip="Fetching data..." />;
|
||||
}
|
||||
|
||||
if (refetchFromBackend && !skipOnboarding) {
|
||||
@ -150,7 +150,7 @@ const _ServicesTable = (props: ServicesTableProps) => {
|
||||
allowFullScreen
|
||||
></iframe>
|
||||
<div style={{ margin: "20px 0" }}>
|
||||
<DefaultSpinner />
|
||||
<Spinner />
|
||||
</div>
|
||||
<div>
|
||||
No instrumentation data.
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { RouteComponentProps } from "react-router-dom";
|
||||
import { RouteComponentProps, withRouter } from "react-router-dom";
|
||||
import {
|
||||
GlobalTime,
|
||||
serviceMapStore,
|
||||
@ -13,8 +13,8 @@ import { StoreState } from "store/reducers";
|
||||
import { getZoomPx, getGraphData, getTooltip, transformLabel } from "./utils";
|
||||
import SelectService from "./SelectService";
|
||||
import { ForceGraph2D } from "react-force-graph";
|
||||
import Spinner from "components/Spinner";
|
||||
import { useRoute } from "modules/RouteProvider";
|
||||
import { CustomSpinner } from "components/Spiner";
|
||||
|
||||
const Container = styled.div`
|
||||
.force-graph-container .graph-tooltip {
|
||||
@ -78,7 +78,7 @@ const ServiceMap = (props: ServiceMapProps) => {
|
||||
fgRef.current && fgRef.current.d3Force("charge").strength(-400);
|
||||
});
|
||||
if (!serviceMap.items.length || !serviceMap.services.length) {
|
||||
return <CustomSpinner size="large" tip="Loading..." />;
|
||||
return <Spinner size="large" tip="Loading..." />;
|
||||
}
|
||||
|
||||
const zoomToService = (value: string) => {
|
||||
@ -150,7 +150,9 @@ const mapStateToProps = (
|
||||
};
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, {
|
||||
export default withRouter(
|
||||
connect(mapStateToProps, {
|
||||
getServiceMapItems: getServiceMapItems,
|
||||
getDetailedServiceMapItems: getDetailedServiceMapItems,
|
||||
})(ServiceMap);
|
||||
})(ServiceMap),
|
||||
);
|
||||
|
@ -1,28 +1,61 @@
|
||||
import React from "react";
|
||||
import Loadable from "./components/Loadable";
|
||||
|
||||
export const ServiceMetrics = React.lazy(
|
||||
() => import("modules/Metrics/ServiceMetricsDef"),
|
||||
);
|
||||
export const ServiceMap = React.lazy(
|
||||
() => import("modules/Servicemap/ServiceMap"),
|
||||
);
|
||||
export const TraceDetail = React.lazy(
|
||||
() => import("modules/Traces/TraceDetail"),
|
||||
);
|
||||
export const TraceGraph = React.lazy(
|
||||
() => import("modules/Traces/TraceGraphDef"),
|
||||
);
|
||||
export const UsageExplorer = React.lazy(
|
||||
() => import("modules/Usage/UsageExplorerDef"),
|
||||
);
|
||||
export const ServicesTable = React.lazy(
|
||||
() => import("modules/Metrics/ServicesTableDef"),
|
||||
);
|
||||
export const Signup = React.lazy(() => import("modules/Auth/Signup"));
|
||||
export const SettingsPage = React.lazy(
|
||||
() => import("modules/Settings/settingsPage"),
|
||||
export const ServiceMetricsPage = Loadable(
|
||||
() =>
|
||||
import(
|
||||
/* webpackChunkName: "ServiceMetricsPage" */ "modules/Metrics/ServiceMetricsDef"
|
||||
),
|
||||
);
|
||||
|
||||
export const InstrumentationPage = React.lazy(
|
||||
() => import("modules/add-instrumentation/instrumentationPage"),
|
||||
export const ServiceMapPage = Loadable(
|
||||
() =>
|
||||
import(
|
||||
/* webpackChunkName: "ServiceMapPage" */ "modules/Servicemap/ServiceMap"
|
||||
),
|
||||
);
|
||||
|
||||
export const TraceDetailPage = Loadable(
|
||||
() =>
|
||||
import(
|
||||
/* webpackChunkName: "TraceDetailPage" */ "modules/Traces/TraceDetail"
|
||||
),
|
||||
);
|
||||
|
||||
export const TraceGraphPage = Loadable(
|
||||
() =>
|
||||
import(
|
||||
/* webpackChunkName: "TraceGraphPage" */ "modules/Traces/TraceGraphDef"
|
||||
),
|
||||
);
|
||||
|
||||
export const UsageExplorerPage = Loadable(
|
||||
() =>
|
||||
import(
|
||||
/* webpackChunkName: "UsageExplorerPage" */ "modules/Usage/UsageExplorerDef"
|
||||
),
|
||||
);
|
||||
|
||||
export const ServicesTablePage = Loadable(
|
||||
() =>
|
||||
import(
|
||||
/* webpackChunkName: "ServicesTablePage" */ "modules/Metrics/ServicesTableDef"
|
||||
),
|
||||
);
|
||||
|
||||
export const SignupPage = Loadable(
|
||||
() => import(/* webpackChunkName: "SignupPage" */ "modules/Auth/Signup"),
|
||||
);
|
||||
|
||||
export const SettingsPage = Loadable(
|
||||
() =>
|
||||
import(
|
||||
/* webpackChunkName: "SettingsPage" */ "modules/Settings/settingsPage"
|
||||
),
|
||||
);
|
||||
|
||||
export const InstrumentationPage = Loadable(
|
||||
() =>
|
||||
import(
|
||||
/* webpackChunkName: "InstrumentationPage" */ "modules/add-instrumentation/instrumentationPage"
|
||||
),
|
||||
);
|
||||
|
@ -29,7 +29,9 @@ module.exports = {
|
||||
port: portFinderSync.getPort(3000),
|
||||
},
|
||||
output: {
|
||||
filename: "js/bundle.[chunkhash].min.js",
|
||||
filename: ({ chunk: { name, hash } }) => {
|
||||
return `js/${name}-${hash}.js`;
|
||||
},
|
||||
path: resolve(__dirname, "./build"),
|
||||
publicPath: "/",
|
||||
},
|
||||
|
@ -11,7 +11,9 @@ module.exports = {
|
||||
devtool: "source-map",
|
||||
entry: resolve(__dirname, "./src/index.tsx"),
|
||||
output: {
|
||||
filename: "js/bundle.[chunkhash].min.js",
|
||||
filename: ({ chunk: { name, hash } }) => {
|
||||
return `js/${name}-${hash}.js`;
|
||||
},
|
||||
path: resolve(__dirname, "./build"),
|
||||
publicPath: "/",
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user