Path: blob/1.0-develop/resources/scripts/routers/ServerRouter.tsx
7458 views
import TransferListener from '@/components/server/TransferListener';1import React, { useEffect, useState } from 'react';2import { NavLink, Route, Switch, useRouteMatch } from 'react-router-dom';3import NavigationBar from '@/components/NavigationBar';4import TransitionRouter from '@/TransitionRouter';5import WebsocketHandler from '@/components/server/WebsocketHandler';6import { ServerContext } from '@/state/server';7import { CSSTransition } from 'react-transition-group';8import Can from '@/components/elements/Can';9import Spinner from '@/components/elements/Spinner';10import { NotFound, ServerError } from '@/components/elements/ScreenBlock';11import { httpErrorToHuman } from '@/api/http';12import { useStoreState } from 'easy-peasy';13import SubNavigation from '@/components/elements/SubNavigation';14import InstallListener from '@/components/server/InstallListener';15import ErrorBoundary from '@/components/elements/ErrorBoundary';16import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';17import { faExternalLinkAlt } from '@fortawesome/free-solid-svg-icons';18import { useLocation } from 'react-router';19import ConflictStateRenderer from '@/components/server/ConflictStateRenderer';20import PermissionRoute from '@/components/elements/PermissionRoute';21import routes from '@/routers/routes';2223export default () => {24const match = useRouteMatch<{ id: string }>();25const location = useLocation();2627const rootAdmin = useStoreState((state) => state.user.data!.rootAdmin);28const [error, setError] = useState('');2930const id = ServerContext.useStoreState((state) => state.server.data?.id);31const uuid = ServerContext.useStoreState((state) => state.server.data?.uuid);32const inConflictState = ServerContext.useStoreState((state) => state.server.inConflictState);33const serverId = ServerContext.useStoreState((state) => state.server.data?.internalId);34const getServer = ServerContext.useStoreActions((actions) => actions.server.getServer);35const clearServerState = ServerContext.useStoreActions((actions) => actions.clearServerState);3637const to = (value: string, url = false) => {38if (value === '/') {39return url ? match.url : match.path;40}41return `${(url ? match.url : match.path).replace(/\/*$/, '')}/${value.replace(/^\/+/, '')}`;42};4344useEffect(45() => () => {46clearServerState();47},48[]49);5051useEffect(() => {52setError('');5354getServer(match.params.id).catch((error) => {55console.error(error);56setError(httpErrorToHuman(error));57});5859return () => {60clearServerState();61};62}, [match.params.id]);6364return (65<React.Fragment key={'server-router'}>66<NavigationBar />67{!uuid || !id ? (68error ? (69<ServerError message={error} />70) : (71<Spinner size={'large'} centered />72)73) : (74<>75<CSSTransition timeout={150} classNames={'fade'} appear in>76<SubNavigation>77<div>78{routes.server79.filter((route) => !!route.name)80.map((route) =>81route.permission ? (82<Can key={route.path} action={route.permission} matchAny>83<NavLink to={to(route.path, true)} exact={route.exact}>84{route.name}85</NavLink>86</Can>87) : (88<NavLink key={route.path} to={to(route.path, true)} exact={route.exact}>89{route.name}90</NavLink>91)92)}93{rootAdmin && (94// eslint-disable-next-line react/jsx-no-target-blank95<a href={`/admin/servers/view/${serverId}`} target={'_blank'}>96<FontAwesomeIcon icon={faExternalLinkAlt} />97</a>98)}99</div>100</SubNavigation>101</CSSTransition>102<InstallListener />103<TransferListener />104<WebsocketHandler />105{inConflictState && (!rootAdmin || (rootAdmin && !location.pathname.endsWith(`/server/${id}`))) ? (106<ConflictStateRenderer />107) : (108<ErrorBoundary>109<TransitionRouter>110<Switch location={location}>111{routes.server.map(({ path, permission, component: Component }) => (112<PermissionRoute key={path} permission={permission} path={to(path)} exact>113<Spinner.Suspense>114<Component />115</Spinner.Suspense>116</PermissionRoute>117))}118<Route path={'*'} component={NotFound} />119</Switch>120</TransitionRouter>121</ErrorBoundary>122)}123</>124)}125</React.Fragment>126);127};128129130