react-router-dom#matchPath TypeScript Examples
The following examples show how to use
react-router-dom#matchPath.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: SideBarItem.tsx From bee-dashboard with BSD 3-Clause "New" or "Revised" License | 6 votes |
export default function SideBarItem({ iconStart, iconEnd, path, label }: Props): ReactElement {
const classes = useStyles()
const location = useLocation()
const isSelected = Boolean(path && matchPath(location.pathname, path))
return (
<StyledListItem button selected={isSelected} disableRipple>
<ListItemIcon className={isSelected ? classes.activeIcon : classes.icon}>{iconStart}</ListItemIcon>
<ListItemText primary={label} />
<ListItemIcon className={isSelected ? classes.activeIcon : classes.icon}>{iconEnd}</ListItemIcon>
</StyledListItem>
)
}
Example #2
Source File: utils.ts From ovineherd with Apache License 2.0 | 6 votes |
getOrgId = (): string => {
const matched = matchPath(window.location.pathname, {
path: '/platform/center/org/:orgId',
})
return get(matched, 'params.orgId') || ''
}
Example #3
Source File: path.ts From mail-my-ballot with Apache License 2.0 | 6 votes |
rawToPath = <P extends Path>(
url: string,
pathEnum: PathEnum,
query: QueryParams,
exact = false
): P | null => {
const { path } = pathData[pathEnum]
const match = matchPath<P>(url, { path, exact })
if (!match) return null
return {
type: pathEnum,
...match.params,
// In Jest testing, URLSearchParams are always undefined so just don't use
scroll: query['scroll'],
}
}
Example #4
Source File: index.tsx From react-amis-admin with Apache License 2.0 | 6 votes |
function isActive(link: any, location: any) {
const ret = matchPath(location.pathname, {
path: link ? link.replace(/\?.*$/, '') : '',
exact: true,
strict: true
});
return !!ret;
}
Example #5
Source File: formatRoutes.tsx From icejs with MIT License | 6 votes |
function getComponentByPath(routes, currPath) {
function findMatchRoute(routeList) {
const matchedRoute = routeList.find(route => {
return matchPath(currPath, route);
});
return matchedRoute.children ? findMatchRoute(matchedRoute.children) : matchedRoute;
}
const matchedRoute = findMatchRoute(routes);
return matchedRoute && matchedRoute.component;
}
Example #6
Source File: index.ts From multisig-react with MIT License | 6 votes |
safeParamAddressFromStateSelector = (state: AppReduxState): string => {
const match = matchPath<{ safeAddress: string }>(state.router.location.pathname, {
path: `${SAFELIST_ADDRESS}/:safeAddress`,
})
if (match) {
return checksumAddress(match.params.safeAddress)
}
return ''
}
Example #7
Source File: NodeLink.tsx From firebase-tools-ui with Apache License 2.0 | 6 votes |
/**
* Creates a href that replaces the `/:path*` part of the current `<Route>`
*
* e.g. `/database/sample/data/a/b/c` -> `/database/sample/data/x/y/z`
*/
function useHrefWithinSameRoute(absolutePath: string) {
const match = useRouteMatch();
// remove the wildcard :path param, so we can append it manually
const withoutPath = match.path.replace('/:path*', '');
const result = matchPath(match.url, { path: withoutPath, strict: true });
const baseUrl = result?.url || '';
return baseUrl === '/' ? absolutePath : `${baseUrl}${absolutePath}`;
}
Example #8
Source File: SideBarStatus.tsx From bee-dashboard with BSD 3-Clause "New" or "Revised" License | 6 votes |
export default function SideBarItem({ path }: Props): ReactElement {
const { status, isLoading } = useContext(Context)
const classes = useStyles()
const location = useLocation()
const isSelected = Boolean(path && matchPath(location.pathname, path))
return (
<ListItem
button
classes={{ root: `${classes.root} ${status.all ? '' : classes.rootError}`, button: classes.button }}
selected={isSelected}
disableRipple
>
<ListItemIcon style={{ marginLeft: '30px' }}>
<StatusIcon checkState={status.all} isLoading={isLoading} />
</ListItemIcon>
<ListItemText primary={<Typography className={classes.smallerText}>{`Node ${status.all}`}</Typography>} />
<ListItemIcon className={classes.icon}>
{status.all ? null : <ArrowRight className={classes.iconSmall} />}
</ListItemIcon>
</ListItem>
)
}
Example #9
Source File: GameStateRedirects.tsx From fishbowl with MIT License | 6 votes |
function GameStateRedirects(props: { joinCode: string }) {
const location = useLocation()
const currentGame = React.useContext(CurrentGameContext)
if (
matchPath(location.pathname, { path: routes.game.pending, exact: true }) ||
matchPath(location.pathname, { path: routes.game.settings, exact: true })
) {
return null
}
const pair = stateRoutePairs.find((pair) => pair.state === currentGame.state)
if (
pair?.state &&
!matchPath(location.pathname, {
path: pair.route,
exact: true,
})
) {
return (
<Redirect
to={generatePath(pair.route, {
joinCode: props.joinCode,
})}
></Redirect>
)
} else {
return null
}
}
Example #10
Source File: routing.ts From metaflow-ui with Apache License 2.0 | 6 votes |
/**
* Returns parameters from given path (if matching to our defined routes)
* @param pathname location.pathname
*/
export function getRouteMatch(pathname: string): match<KnownURLParams> | null {
return matchPath<KnownURLParams>(
pathname,
Object.keys(SHORT_PATHS).map((key) => SHORT_PATHS[key as keyof PathDefinition]),
);
}
Example #11
Source File: BreadcrumbContext.tsx From one-platform with MIT License | 5 votes |
BreadcrumbProvider = ({ children }: Props): JSX.Element => {
// load it up
const [dynamicCrumbs, setDynamicCrumbs] = useState<Record<string, Breadcrumb>>();
const [breadcrumbs, setBreadcrumbs] = useState<Breadcrumb[]>([]);
const { pathname } = useLocation();
const handleDynamicCrumbs = useCallback((crumb: Record<string, Breadcrumb>): void => {
// save recent visit to quick link
setDynamicCrumbs((state) => ({ ...state, ...crumb }));
}, []);
useEffect(() => {
const path = pathname.replace(config.baseURL, '');
const matchedPath = (Object.keys(BREADCRUMB_USERFLOW) as ApiCatalogLinks[]).find((pattern) =>
Boolean(matchPath(pattern, path))
);
if (matchedPath) {
const crumbs = BREADCRUMB_USERFLOW[matchedPath]
.map((userflow) =>
LOOK_UP_TABLE?.[userflow] ? LOOK_UP_TABLE?.[userflow] : dynamicCrumbs?.[userflow]
)
.filter((crumb) => Boolean(crumb)) as Breadcrumb[];
setBreadcrumbs(crumbs);
} else {
setBreadcrumbs([]);
}
}, [pathname, dynamicCrumbs]);
/**
* Context value to access glabally from anywhere
* Memo to optimize at best
*/
const value = useMemo(
() => ({
breadcrumbs,
handleDynamicCrumbs,
}),
[breadcrumbs, handleDynamicCrumbs]
);
return <BreadcrumbContext.Provider value={value}>{children}</BreadcrumbContext.Provider>;
}
Example #12
Source File: AppBar.tsx From firebase-tools-ui with Apache License 2.0 | 5 votes |
AppBar: React.FC<React.PropsWithChildren<Props>> = ({
routes,
}) => {
let location = useLocation();
const navRoutes = routes.filter((r) => r.showInNav);
const tabs = navRoutes.map(({ path, label }: Route) => (
<Tab
key={label}
className="mdc-tab--min-width"
{...{ tag: Link, to: path }}
>
{label}
</Tab>
));
const activeTabIndex = navRoutes.findIndex((r) =>
matchPath(location.pathname, {
path: r.path,
exact: r.exact,
})
);
return (
<ThemeProvider
options={{
primary: navBarPrimary,
surface: navBarSurface,
onSurface: navBarOnSurface,
}}
wrap
>
<TopAppBar fixed className="AppBar" theme="surface">
<div className="AppBar-title-row">
<div className="AppBar-logo-lockup">
<Logo />
<Typography use="headline5" className="AppBar-title" tag="h1">
Firebase Emulator Suite
</Typography>
</div>
</div>
<TabBar theme="onSurface" activeTabIndex={activeTabIndex}>
{tabs}
</TabBar>
</TopAppBar>
</ThemeProvider>
);
}
Example #13
Source File: index.tsx From firebase-tools-ui with Apache License 2.0 | 5 votes |
Firestore: React.FC<React.PropsWithChildren<unknown>> = React.memo(
() => {
const location = useLocation();
const history = useHistory();
const [isRefreshing, setIsRefreshing] = useState(false);
const eject = useEjector();
// TODO: do something better here!
const path = location.pathname.replace(/^\/firestore\/data/, '');
const showCollectionShell = path.split('/').length < 2;
const showDocumentShell = path.split('/').length < 3;
const subTabs = firestoreRoutes.map(
({ path, label }: FirestoreTabRoute) => (
<Tab
key={label}
className="mdc-tab--min-width"
{...{ tag: Link, to: path }}
>
{label}
</Tab>
)
);
const activeTabIndex = firestoreRoutes.findIndex((r) =>
matchPath(location.pathname, {
path: r.path,
exact: r.exact,
})
);
async function handleClearData() {
const shouldNuke = await promptClearAll();
if (!shouldNuke) return;
setIsRefreshing(true);
await eject();
handleNavigate();
setIsRefreshing(false);
}
function handleNavigate(path?: string) {
// TODO: move to routing constants
const root = '/firestore/data';
if (path === undefined) {
history.push(root);
} else {
history.push(`${root}/${path}`);
}
}
return isRefreshing ? (
<Spinner span={12} data-testid="firestore-loading" />
) : (
<FirestoreStore>
<GridCell span={12} className="Firestore">
<div className="Firestore-sub-tabs">
<TabBar theme="onSurface" activeTabIndex={activeTabIndex}>
{subTabs}
</TabBar>
</div>
<Switch>
<Route path="/firestore/data">
<FirestoreDataCard
path={path}
handleClearData={handleClearData}
handleNavigate={handleNavigate}
showCollectionShell={showCollectionShell}
showDocumentShell={showDocumentShell}
/>
</Route>
<Route path="/firestore/requests">
<FirestoreRequestsCard />
</Route>
<Redirect from="/firestore" to="/firestore/data" />
</Switch>
</GridCell>
</FirestoreStore>
);
}
)
Example #14
Source File: PageTabs.tsx From frontegg-react with MIT License | 5 votes |
findMatchPath = (pathname: string, tabs: { route: string }[]) => {
const activeTab = tabs.findIndex(({ route }) => matchPath(pathname, { path: route, exact: true }));
return activeTab === -1 ? 0 : activeTab;
}
Example #15
Source File: App.tsx From iot-center-v2 with MIT License | 5 votes |
getPageHelp = (url: string) =>
PAGE_HELP.filter(({matcher}) => matchPath(url, matcher)).map(
({file}) => file
)[0]
Example #16
Source File: GameLayout.tsx From fishbowl with MIT License | 5 votes |
function GameLayout(props: { children: React.ReactNode; joinCode: string }) {
const currentPlayer = React.useContext(CurrentPlayerContext)
const location = useLocation()
const history = useHistory()
const inSettings = matchPath(location.pathname, {
path: routes.game.settings,
exact: true,
})
const showFabOnThisRoute = !some(
[routes.game.pending, routes.game.lobby, routes.game.ended],
(route) => {
return matchPath(location.pathname, {
path: route,
exact: true,
})
}
)
return (
<Box>
<Box>{props.children}</Box>
{showFabOnThisRoute && currentPlayer.role === PlayerRole.Host && (
<Box display="flex" flexDirection="row-reverse" pb={2} pt={6}>
<Fab
color="default"
size="small"
onClick={() => {
if (inSettings) {
history.goBack()
} else {
history.push(
generatePath(routes.game.settings, {
joinCode: props.joinCode.toLocaleUpperCase(),
})
)
}
}}
>
{inSettings ? <CloseIcon /> : <SettingsIcon />}
</Fab>
</Box>
)}
</Box>
)
}
Example #17
Source File: breadcrumb.tsx From erda-ui with GNU Affero General Public License v3.0 | 4 votes |
ErdaBreadcrumb = () => {
const [currentApp] = layoutStore.useStore((s) => [s.currentApp]);
const routes: IRoute[] = routeInfoStore.useStore((s) => s.routes);
const [pageName, setPageName] = React.useState<string>();
const infoMap = breadcrumbStore.useStore((s) => s.infoMap);
const [query] = routeInfoStore.useStore((s) => [s.query]);
const [allRoutes, setAllRoutes] = React.useState<IRoute[]>([]);
const [params, setParams] = React.useState<Obj<string>>({});
const [pageNameInfo, setPageNameInfo] = React.useState<Function>();
const checkHasTemplate = React.useCallback(
(breadcrumbName: string) => {
const replacePattern = /\{([\w.])+\}/g;
let _breadcrumbName = breadcrumbName || '';
const matches = _breadcrumbName.match(replacePattern);
if (!matches) {
return _breadcrumbName;
}
matches.forEach((match: string) => {
const [type, key] = match.slice(1, -1).split('.'); // match: {params.id}
let value;
if (type === 'params') {
value = params[key];
} else if (type === 'query') {
value = decodeURIComponent(query[key]);
} else {
value = infoMap[type];
}
_breadcrumbName = _breadcrumbName.replace(match, value);
});
if (_breadcrumbName === 'undefined') {
_breadcrumbName = '';
}
return _breadcrumbName;
},
[infoMap, params, query],
);
const getBreadcrumbTitle = React.useCallback(
(route: IRoute, isBreadcrumb = false) => {
const { breadcrumbName, pageName } = route;
let _title = '';
if (!isBreadcrumb && pageName) {
_title = isFunction(pageName)
? breadcrumbName({ infoMap, route, params, query })
: checkHasTemplate(pageName as string);
} else {
_title = isFunction(breadcrumbName)
? breadcrumbName({ infoMap, route, params, query })
: checkHasTemplate(breadcrumbName as string);
}
return _title;
},
[checkHasTemplate, infoMap, params, query],
);
React.useEffect(() => {
if (allRoutes.length) {
const lastRoute = allRoutes[allRoutes.length - 1];
const _title = getBreadcrumbTitle(lastRoute);
setPageNameInfo(() => lastRoute?.pageNameInfo);
setPageName(_title);
}
}, [allRoutes, getBreadcrumbTitle]);
React.useEffect(() => {
document.title = pageName ? `${pageName} · Erda` : 'Erda';
}, [pageName]);
React.useEffect(() => {
let _params: Obj<string> = {};
// get params from path
if (routes.length > 0) {
const match = matchPath(window.location.pathname, {
path: routes[0].path,
exact: true,
strict: false,
});
if (match) {
_params = match.params;
setParams(_params);
}
}
const filteredRoutes = routes.filter((route) => {
return route.path && (route.breadcrumbName || route.pageName || typeof route.breadcrumbName === 'function');
});
if (!isEmpty(currentApp)) {
const eternalApp = {
key: currentApp.key,
eternal: currentApp.href,
breadcrumbName: currentApp.breadcrumbName,
path: typeof currentApp.path === 'function' ? currentApp.path(_params || {}, routes) : currentApp.href,
} as IRoute;
filteredRoutes.reverse().splice(1, 0, eternalApp);
setAllRoutes(filteredRoutes.slice(0, -1));
}
}, [currentApp, routes]);
const paths: string[] = [];
const usefullBreadcrumb = allRoutes.filter((item) => {
if (!item.breadcrumbName) {
return false;
}
return !!getBreadcrumbTitle(item, true);
});
return (
<div className="flex items-center flex-shrink-0 h-9 text-xs">
{usefullBreadcrumb.map((item, i) => {
const isLast = i === usefullBreadcrumb.length - 1;
paths.push(getPath(item.path, params));
const _title = getBreadcrumbTitle(item, true);
return (
<div key={item.key}>
<BreadcrumbItem paths={[...paths]} route={item} params={params} title={_title} isLast={isLast} />
{!isLast && <ErdaIcon className="align-middle mx-1 text-sub" type="right" size="14px" />}
</div>
);
})}
</div>
);
}
Example #18
Source File: header.tsx From erda-ui with GNU Affero General Public License v3.0 | 4 votes |
Header = ({ layout }: { layout?: RouteConfigItem_Layout }) => {
const { hideSidebar } = layout || {};
const [currentApp, topButtonsWidth] = layoutStore.useStore((s) => [s.currentApp, s.topButtonsWidth]);
const [routes, markedRoutePreview] = routeInfoStore.useStore((s) => [s.routes, s.markedRoutePreview]);
const [pageName, setPageName] = React.useState<string>();
const [backToUp, setBackToUp] = React.useState(0);
const infoMap = breadcrumbStore.useStore((s) => s.infoMap);
const [query] = routeInfoStore.useStore((s) => [s.query]);
const [backToUpKey, setBackToUpKey] = React.useState('');
const [allRoutes, setAllRoutes] = React.useState<IRoute[]>([]);
const [params, setParams] = React.useState<Obj<string>>({});
const [pageNameInfo, setPageNameInfo] = React.useState<Function>();
const checkHasTemplate = React.useCallback(
(breadcrumbName: string) => {
const replacePattern = /\{([\w.])+\}/g;
let _breadcrumbName = breadcrumbName || '';
const matches = _breadcrumbName.match(replacePattern);
if (!matches) {
return _breadcrumbName;
}
matches.forEach((match: string) => {
const [type, key] = match.slice(1, -1).split('.'); // match: {params.id}
let value;
if (type === 'params') {
value = params[key];
} else if (type === 'query') {
value = decodeURIComponent(query[key]);
} else {
value = infoMap[type];
}
_breadcrumbName = _breadcrumbName.replace(match, value);
});
if (_breadcrumbName === 'undefined') {
_breadcrumbName = '';
}
return _breadcrumbName;
},
[infoMap, params, query],
);
const getBreadcrumbTitle = React.useCallback(
(route: IRoute, isBreadcrumb = false) => {
const { breadcrumbName, pageName } = route;
let _title = '';
if (!isBreadcrumb && pageName) {
_title = isFunction(pageName)
? breadcrumbName({ infoMap, route, params, query })
: checkHasTemplate(pageName as string);
} else {
_title = isFunction(breadcrumbName)
? breadcrumbName({ infoMap, route, params, query })
: checkHasTemplate(breadcrumbName as string);
}
return _title;
},
[checkHasTemplate, infoMap, params, query],
);
React.useEffect(() => {
if (allRoutes.length) {
const lastRoute = allRoutes[allRoutes.length - 1];
const _title = getBreadcrumbTitle(lastRoute);
setPageNameInfo(() => lastRoute?.pageNameInfo);
setPageName(_title);
}
}, [allRoutes, getBreadcrumbTitle]);
React.useEffect(() => {
document.title = pageName ? `${pageName} · Erda` : 'Erda';
}, [pageName]);
React.useEffect(() => {
let _params: Obj<string> = {};
// get params from path
if (routes.length > 0) {
const match = matchPath(window.location.pathname, {
path: routes[0].path,
exact: true,
strict: false,
});
if (match) {
_params = match.params;
setParams(_params);
}
let backToUpLevel = 0;
const currentRoute = routes[0];
if (currentRoute.backToUp) {
const targetRoute = routes.find((a) => a.mark === currentRoute.backToUp);
if (targetRoute) {
backToUpLevel = location.pathname.split('/').length - targetRoute.path.split('/').length;
}
}
setBackToUpKey(currentRoute.backToUp);
setBackToUp(backToUpLevel);
}
const filteredRoutes = routes.filter((route) => {
return route.path && (route.breadcrumbName || route.pageName || typeof route.breadcrumbName === 'function');
});
if (!isEmpty(currentApp)) {
const eternalApp = {
key: currentApp.key,
eternal: currentApp.href,
breadcrumbName: currentApp.breadcrumbName,
path: typeof currentApp.path === 'function' ? currentApp.path(_params || {}, routes) : currentApp.href,
};
filteredRoutes.reverse().splice(1, 0, eternalApp as IRoute);
setAllRoutes(filteredRoutes);
}
}, [currentApp, routes]);
const displayPageName = () => {
if (typeof pageNameInfo === 'function') {
const Comp = pageNameInfo;
return <Comp />;
}
if (backToUp) {
const search = markedRoutePreview[backToUpKey];
const _query = search ? { ...parse(search, { arrayFormat: 'bracket' }) } : undefined;
return (
<div
className="text-xl truncate inline-flex items-center cursor-pointer"
onClick={() => goTo('../'.repeat(backToUp), { query: _query })}
>
<ErdaIcon type="arrow-left" className="mr-1" />
{allWordsFirstLetterUpper(pageName as string)}
</div>
);
}
return <div className="text-xl truncate">{allWordsFirstLetterUpper(pageName as string)}</div>;
};
return (
<div className="erda-header" style={{ marginRight: topButtonsWidth }}>
<div className={`erda-header-title-con inline-flex ${hideSidebar ? 'ml-4' : ''}`}>
{pageName && displayPageName()}
</div>
<Tab />
</div>
);
}
Example #19
Source File: App.tsx From back-home-safe with GNU General Public License v3.0 | 4 votes |
App = () => {
useMigration();
const [finishedTutorial, setFinishedTutorial] = useLocalStorage(
"finished_tutorial",
false
);
const [confirmPageIcon, setConfirmPageIcon] = useLocalStorage<string | null>(
"confirmPageIcon",
null
);
const { lockStore, unlocked, isEncrypted } = useData();
const { pathname } = useLocation();
const browserHistory = useHistory();
const handleBlur = useCallback(() => {
if (pathname !== "/qrReader" && pathname !== "/cameraSetting") lockStore();
}, [lockStore, pathname]);
useEffect(() => {
window.addEventListener("blur", handleBlur);
return () => {
window.removeEventListener("blur", handleBlur);
};
}, [handleBlur]);
const pageMap = useMemo<
{ route: RouteProps; component: React.ReactNode; privateRoute: boolean }[]
>(
() => [
{
privateRoute: false,
route: { exact: true, path: "/tutorial" },
component: <Tutorial setFinishedTutorial={setFinishedTutorial} />,
},
{
privateRoute: false,
route: { exact: true, path: "/login" },
component: <Login />,
},
{
privateRoute: true,
route: {
exact: true,
path: "/",
},
component: <MainScreen />,
},
{
privateRoute: true,
route: {
exact: true,
path: "/confirm/:id",
},
component: <Confirm confirmPageIcon={confirmPageIcon} />,
},
{
privateRoute: true,
route: {
exact: true,
path: "/qrGenerator",
},
component: <QRGenerator />,
},
{
privateRoute: true,
route: {
exact: true,
path: "/disclaimer",
},
component: <Disclaimer />,
},
{
privateRoute: true,
route: {
exact: true,
path: "/qrReader",
},
component: <QRReader />,
},
{
privateRoute: true,
route: {
exact: true,
path: "/cameraSetting",
},
component: <CameraSetting />,
},
{
privateRoute: true,
route: {
exact: true,
path: "/confirmPageSetting",
},
component: (
<ConfirmPageSetting
confirmPageIcon={confirmPageIcon}
setConfirmPageIcon={setConfirmPageIcon}
/>
),
},
{
privateRoute: true,
route: {
exact: true,
path: "/vaccinationQRReader",
},
component: <VaccinationQRReader />,
},
],
[confirmPageIcon, setConfirmPageIcon, setFinishedTutorial]
);
// transition group cannot use switch component, thus need manual redirect handling
// ref: https://reactcommunity.org/react-transition-group/with-react-router
useEffect(() => {
if (!unlocked && pathname !== "/login") {
browserHistory.replace("/login");
}
if (unlocked && pathname === "/login") {
browserHistory.replace("/");
}
}, [isEncrypted, unlocked, browserHistory, pathname]);
useEffect(() => {
if (!finishedTutorial && pathname !== "/tutorial") {
browserHistory.replace("/tutorial");
}
if (finishedTutorial && pathname === "/tutorial") {
browserHistory.replace("/");
}
}, [finishedTutorial, browserHistory, pathname]);
useEffect(() => {
const hasMatch = any(({ route }) => {
if (!route.path) return false;
return !isNil(matchPath(pathname, route));
}, pageMap);
if (!hasMatch) {
browserHistory.replace("/");
}
}, [browserHistory, pathname, pageMap]);
return (
<>
<GlobalStyle />
{pageMap.map(({ route, component, privateRoute }) =>
privateRoute && !unlocked ? (
<React.Fragment key={String(route.path)} />
) : (
<Route {...route} key={String(route.path)}>
{({ match }) => (
<CSSTransition
in={match != null}
timeout={300}
classNames="page"
unmountOnExit
>
<div className="page">
<Suspense fallback={<PageLoading />}>{component}</Suspense>
</div>
</CSSTransition>
)}
</Route>
)
)}
</>
);
}
Example #20
Source File: App.tsx From iot-center-v2 with MIT License | 4 votes |
App: FunctionComponent<RouteComponentProps> = (props) => {
const [helpCollapsed, setHelpCollapsed] = useHelpCollapsed()
const [helpText, setHelpText] = useState('')
const mqttEnabled = useFetchBoolean('/mqtt/enabled')
const help = getPageHelp(props.location.pathname)
useEffect(() => {
setHelpText('')
if (help) {
// load markdown from file
;(async () => {
try {
const response = await fetch(help)
const txt = await response.text()
setHelpText((txt ?? '').startsWith('<!') ? 'HELP NOT FOUND' : txt)
} catch (e) {
console.error(e)
}
})()
}
}, [help])
return (
<div className="App">
<Layout style={{minHeight: '100vh'}}>
<Sider>
<Menu
theme="dark"
selectedKeys={[
props.location.pathname,
...(matchPath(props.location.pathname, '/dashboard/:device')
? ['/dashboard/:device']
: []),
...(matchPath(props.location.pathname, '/realtime/:device')
? ['/realtime/:device']
: []),
...(matchPath(props.location.pathname, '/dynamic/:device')
? ['/dynamic/:device']
: []),
]}
mode="inline"
>
<Menu.Item key="/home" icon={<IconHome />}>
<NavLink to="/home">Home</NavLink>
</Menu.Item>
<Menu.Item key="/devices" icon={<IconDeviceRegistration />}>
<NavLink to="/devices">Device Registrations</NavLink>
</Menu.Item>
<Menu.Item
key="/devices/virtual_device"
icon={<IconVirtualDevice />}
>
<NavLink to="/devices/virtual_device">Virtual Device</NavLink>
</Menu.Item>
<Menu.Item key="/dashboard/:device" icon={<IconDashboard />}>
<NavLink to="/dashboard">Dashboard</NavLink>
</Menu.Item>
<Menu.Item
style={mqttEnabled === true ? {} : {color: 'gray'}}
key="/realtime/:device"
icon={<IconRealtimeDashboard />}
>
<NavLink
style={mqttEnabled === true ? {} : {color: 'gray'}}
to="/realtime"
>
Realtime
</NavLink>
</Menu.Item>
<Menu.Item key="/dynamic/:device" icon={<IconDynamicDashboard />}>
<NavLink to="/dynamic">Dynamic</NavLink>
</Menu.Item>
</Menu>
</Sider>
<Switch>
<Redirect exact from="/" to="/home" />
<Route exact path="/home" component={HomePage} />
<Route
exact
path="/devices"
render={(props) => (
<DevicesPage {...props} helpCollapsed={helpCollapsed} />
)}
/>
<Route
exact
path="/devices/:deviceId"
render={(props) => (
<DevicePage {...props} {...{helpCollapsed, mqttEnabled}} />
)}
/>
<Redirect
exact
from="/dashboard"
to={`/dashboard/${VIRTUAL_DEVICE}`}
/>
<Route
exact
path="/dashboard/:deviceId"
render={(props) => (
<DashboardPage {...props} helpCollapsed={helpCollapsed} />
)}
/>
<Redirect exact from="/realtime" to={`/realtime/${VIRTUAL_DEVICE}`} />
<Route
exact
path="/realtime/:deviceId"
render={(props) => (
<RealTimePage {...props} {...{helpCollapsed, mqttEnabled}} />
)}
/>
<Redirect exact from="/dynamic" to={`/dynamic/demo`} />
<Route
exact
path="/dynamic/:dashboard/:clientId?"
render={(props) => (
<DynamicDashboardPage
{...props}
{...{helpCollapsed, mqttEnabled}}
/>
)}
/>
<Route path="*" component={NotFoundPage} />
</Switch>
{helpText ? (
<Sider
reverseArrow
collapsible
collapsed={helpCollapsed}
onCollapse={() => setHelpCollapsed(!helpCollapsed)}
collapsedWidth={30}
theme="light"
width={'20vw'}
breakpoint="sm"
>
<div style={{paddingLeft: 10, paddingRight: 10}}>
<Markdown source={helpText && !helpCollapsed ? helpText : ''} />
</div>
</Sider>
) : undefined}
</Layout>
</div>
)
}
Example #21
Source File: index.tsx From ExpressLRS-Configurator with GNU General Public License v3.0 | 4 votes |
Sidebar: FunctionComponent = () => {
const location = useLocation();
const configuratorActive =
matchPath(location.pathname, '/configurator') !== null;
const backpackActive = matchPath(location.pathname, '/backpack') !== null;
// const settingsActive = matchPath(location.pathname, '/settings') !== null;
const logsActive = matchPath(location.pathname, '/logs') !== null;
const serialMonitorActive =
matchPath(location.pathname, '/serial-monitor') !== null;
const supportActive = matchPath(location.pathname, '/support') !== null;
const { appStatus } = useAppState();
const navigationEnabled = appStatus !== AppStatus.Busy;
return (
<Drawer sx={styles.drawer} variant="permanent">
<Toolbar />
<Divider />
<Box sx={styles.drawerContainer}>
<List>
<ListItem
component={Link}
to="/configurator"
selected={configuratorActive}
sx={styles.menuItem}
button
disabled={!navigationEnabled}
>
<ListItemIcon>
<BuildIcon />
</ListItemIcon>
<ListItemText primary="Configurator" />
</ListItem>
<ListItem
component={Link}
to="/backpack"
selected={backpackActive}
sx={styles.menuItem}
button
disabled={!navigationEnabled}
>
<ListItemIcon>
<BackpackIcon />
</ListItemIcon>
<ListItemText primary="Backpack" />
</ListItem>
{/* <ListItem */}
{/* component={Link} */}
{/* to="/settings" */}
{/* selected={settingsActive} */}
{/* sx={styles.menuItem} */}
{/* button */}
{/* > */}
{/* <ListItemIcon> */}
{/* <SettingsIcon /> */}
{/* </ListItemIcon> */}
{/* <ListItemText primary="Settings" /> */}
{/* </ListItem> */}
<ListItem
component={Link}
to="/logs"
selected={logsActive}
sx={styles.menuItem}
button
disabled={!navigationEnabled}
>
<ListItemIcon>
<ListIcon />
</ListItemIcon>
<ListItemText primary="Logs" />
</ListItem>
<ListItem
component={Link}
to="/serial-monitor"
selected={serialMonitorActive}
sx={styles.menuItem}
button
disabled={!navigationEnabled}
>
<ListItemIcon>
<DvrIcon />
</ListItemIcon>
<ListItemText primary="Serial Monitor" />
</ListItem>
<ListItem
component={Link}
to="/support"
selected={supportActive}
sx={styles.menuItem}
button
disabled={!navigationEnabled}
>
<ListItemIcon>
<HelpIcon />
</ListItemIcon>
<ListItemText primary="Support" />
</ListItem>
</List>
</Box>
</Drawer>
);
}