import React, { Suspense } from "react"; import { BrowserRouter as Router, Switch, Route } from "react-router-dom"; import { ProgressIndicator, styled } from "@fluentui/react"; import { get, isArray, isNil, flattenDeep } from "lodash"; import path from "path"; import { AutoSwitchLayout } from "./components/layout"; import { AuthorizedRoute, RouteIndexList, ComingSoon, NoMatch, } from "./components/route"; import { hierarchize } from "./global/hierarchical"; import routes from "./routes"; const keyName = "key"; const pathName = "path"; const uniqueKeyName = "uniqueKey"; function generateRoutePath(node, parent) { const parentUniqueKey = get(parent, uniqueKeyName); const uniqueKey = parentUniqueKey ? parentUniqueKey + "." + node[keyName] : node[keyName]; const parentPath = get(parent, pathName, ""); const routePath = get(node, pathName, path.join(parentPath, node[keyName])); node[uniqueKeyName] = uniqueKey; node[pathName] = routePath; } function renderRoute(route) { const isGroup = isArray(route.children); const PageComponent = isNil(route.component) ? isGroup ? RouteIndexList : ComingSoon : route.component; const routeComponent = ( <AuthorizedRoute key={route.uniqueKey} path={route.path} exact={route.exact || isArray(route.children)} strict={route.strict} isPublic={route.isPublic} > <PageComponent route={route} /> </AuthorizedRoute> ); const childComponents = isGroup ? route.children.map(renderRoute) : []; return [routeComponent, ...childComponents]; } function App({ theme }) { const { semanticColors } = theme; React.useLayoutEffect(() => { document.body.style.backgroundColor = semanticColors.bodyBackground; document.body.style.color = semanticColors.bodyText; }, [semanticColors]); const routeList = hierarchize(routes, null, generateRoutePath); const routeComponents = renderRoute(routeList); const flatRouteComponents = flattenDeep(routeComponents); return ( <Router basename="/fluentui-starter"> <AutoSwitchLayout> <Suspense fallback={<ProgressIndicator label="Page loading..." />}> <Switch> {flatRouteComponents} <Route path="*"> <NoMatch /> </Route> </Switch> </Suspense> </AutoSwitchLayout> </Router> ); } export default styled(App);