2020-04-17 18:07:32 +00:00
|
|
|
import React, { useEffect, useState } from 'react';
|
2020-07-27 01:05:54 +00:00
|
|
|
import ReactGA from 'react-ga';
|
2019-06-29 05:49:08 +00:00
|
|
|
import { NavLink, Route, RouteComponentProps, Switch } from 'react-router-dom';
|
2019-06-29 05:17:29 +00:00
|
|
|
import NavigationBar from '@/components/NavigationBar';
|
|
|
|
import ServerConsole from '@/components/server/ServerConsole';
|
|
|
|
import TransitionRouter from '@/TransitionRouter';
|
2019-06-29 23:14:32 +00:00
|
|
|
import WebsocketHandler from '@/components/server/WebsocketHandler';
|
2019-07-10 04:25:57 +00:00
|
|
|
import { ServerContext } from '@/state/server';
|
2019-07-10 05:00:29 +00:00
|
|
|
import DatabasesContainer from '@/components/server/databases/DatabasesContainer';
|
2019-07-28 03:23:44 +00:00
|
|
|
import FileManagerContainer from '@/components/server/files/FileManagerContainer';
|
|
|
|
import { CSSTransition } from 'react-transition-group';
|
2019-09-28 21:59:05 +00:00
|
|
|
import SuspenseSpinner from '@/components/elements/SuspenseSpinner';
|
2019-10-19 22:31:02 +00:00
|
|
|
import FileEditContainer from '@/components/server/files/FileEditContainer';
|
2019-12-07 23:58:37 +00:00
|
|
|
import SettingsContainer from '@/components/server/settings/SettingsContainer';
|
2020-02-08 23:23:08 +00:00
|
|
|
import ScheduleContainer from '@/components/server/schedules/ScheduleContainer';
|
2020-03-18 06:33:53 +00:00
|
|
|
import ScheduleEditContainer from '@/components/server/schedules/ScheduleEditContainer';
|
2020-03-26 04:58:37 +00:00
|
|
|
import UsersContainer from '@/components/server/users/UsersContainer';
|
2020-03-29 00:25:04 +00:00
|
|
|
import Can from '@/components/elements/Can';
|
2020-04-04 17:59:25 +00:00
|
|
|
import BackupContainer from '@/components/server/backups/BackupContainer';
|
2020-04-12 23:19:43 +00:00
|
|
|
import Spinner from '@/components/elements/Spinner';
|
2020-04-17 18:07:32 +00:00
|
|
|
import ServerError from '@/components/screens/ServerError';
|
|
|
|
import { httpErrorToHuman } from '@/api/http';
|
2020-04-17 18:17:01 +00:00
|
|
|
import NotFound from '@/components/screens/NotFound';
|
2020-04-26 20:21:39 +00:00
|
|
|
import { useStoreState } from 'easy-peasy';
|
2020-04-17 21:43:03 +00:00
|
|
|
import ScreenBlock from '@/components/screens/ScreenBlock';
|
2020-07-04 22:40:41 +00:00
|
|
|
import SubNavigation from '@/components/elements/SubNavigation';
|
2020-07-10 02:56:46 +00:00
|
|
|
import NetworkContainer from '@/components/server/network/NetworkContainer';
|
2020-07-30 05:02:00 +00:00
|
|
|
import InstallListener from '@/components/server/InstallListener';
|
2020-08-22 22:43:28 +00:00
|
|
|
import StartupContainer from '@/components/server/startup/StartupContainer';
|
2020-08-23 02:01:29 +00:00
|
|
|
import requireServerPermission from '@/hoc/requireServerPermission';
|
2019-06-29 05:17:29 +00:00
|
|
|
|
2019-07-10 04:25:57 +00:00
|
|
|
const ServerRouter = ({ match, location }: RouteComponentProps<{ id: string }>) => {
|
2020-10-04 02:36:26 +00:00
|
|
|
const rootAdmin = useStoreState(state => state.user.data!.rootAdmin);
|
2020-04-17 18:07:32 +00:00
|
|
|
const [ error, setError ] = useState('');
|
|
|
|
const [ installing, setInstalling ] = useState(false);
|
2020-08-26 04:25:31 +00:00
|
|
|
|
|
|
|
const id = ServerContext.useStoreState(state => state.server.data?.id);
|
|
|
|
const uuid = ServerContext.useStoreState(state => state.server.data?.uuid);
|
|
|
|
const isInstalling = ServerContext.useStoreState(state => state.server.data?.isInstalling);
|
2019-07-10 04:25:57 +00:00
|
|
|
const getServer = ServerContext.useStoreActions(actions => actions.server.getServer);
|
|
|
|
const clearServerState = ServerContext.useStoreActions(actions => actions.clearServerState);
|
2019-06-29 23:14:32 +00:00
|
|
|
|
2020-04-12 23:19:43 +00:00
|
|
|
useEffect(() => () => {
|
|
|
|
clearServerState();
|
|
|
|
}, []);
|
|
|
|
|
2020-04-26 20:21:39 +00:00
|
|
|
useEffect(() => {
|
2020-08-26 04:25:31 +00:00
|
|
|
setInstalling(!!isInstalling);
|
|
|
|
}, [ isInstalling ]);
|
2020-04-26 20:21:39 +00:00
|
|
|
|
2020-04-12 23:19:43 +00:00
|
|
|
useEffect(() => {
|
2020-04-17 18:07:32 +00:00
|
|
|
setError('');
|
|
|
|
setInstalling(false);
|
|
|
|
getServer(match.params.id)
|
|
|
|
.catch(error => {
|
|
|
|
if (error.response?.status === 409) {
|
|
|
|
setInstalling(true);
|
|
|
|
} else {
|
|
|
|
console.error(error);
|
|
|
|
setError(httpErrorToHuman(error));
|
|
|
|
}
|
|
|
|
});
|
2019-06-29 23:14:32 +00:00
|
|
|
|
2020-04-12 23:19:43 +00:00
|
|
|
return () => {
|
|
|
|
clearServerState();
|
|
|
|
};
|
|
|
|
}, [ match.params.id ]);
|
2019-06-29 23:14:32 +00:00
|
|
|
|
2020-07-27 01:05:54 +00:00
|
|
|
useEffect(() => {
|
|
|
|
ReactGA.pageview(location.pathname);
|
|
|
|
}, [ location.pathname ]);
|
|
|
|
|
2019-06-29 23:14:32 +00:00
|
|
|
return (
|
2020-04-10 17:11:15 +00:00
|
|
|
<React.Fragment key={'server-router'}>
|
2019-06-29 23:14:32 +00:00
|
|
|
<NavigationBar/>
|
2020-08-26 04:25:31 +00:00
|
|
|
{(!uuid || !id) ?
|
2020-04-26 20:21:39 +00:00
|
|
|
error ?
|
|
|
|
<ServerError message={error}/>
|
2020-04-17 18:07:32 +00:00
|
|
|
:
|
2020-07-05 01:19:46 +00:00
|
|
|
<Spinner size={'large'} centered/>
|
2020-04-12 23:19:43 +00:00
|
|
|
:
|
|
|
|
<>
|
2020-07-05 20:56:04 +00:00
|
|
|
<CSSTransition timeout={150} classNames={'fade'} appear in>
|
2020-07-04 22:40:41 +00:00
|
|
|
<SubNavigation>
|
|
|
|
<div>
|
2020-04-12 23:19:43 +00:00
|
|
|
<NavLink to={`${match.url}`} exact>Console</NavLink>
|
|
|
|
<Can action={'file.*'}>
|
|
|
|
<NavLink to={`${match.url}/files`}>File Manager</NavLink>
|
|
|
|
</Can>
|
|
|
|
<Can action={'database.*'}>
|
|
|
|
<NavLink to={`${match.url}/databases`}>Databases</NavLink>
|
|
|
|
</Can>
|
|
|
|
<Can action={'schedule.*'}>
|
|
|
|
<NavLink to={`${match.url}/schedules`}>Schedules</NavLink>
|
|
|
|
</Can>
|
|
|
|
<Can action={'user.*'}>
|
|
|
|
<NavLink to={`${match.url}/users`}>Users</NavLink>
|
|
|
|
</Can>
|
|
|
|
<Can action={'backup.*'}>
|
|
|
|
<NavLink to={`${match.url}/backups`}>Backups</NavLink>
|
|
|
|
</Can>
|
2020-07-10 02:56:46 +00:00
|
|
|
<Can action={'allocations.*'}>
|
|
|
|
<NavLink to={`${match.url}/network`}>Network</NavLink>
|
|
|
|
</Can>
|
2020-08-22 22:43:28 +00:00
|
|
|
<Can action={'startup.*'}>
|
|
|
|
<NavLink to={`${match.url}/startup`}>Startup</NavLink>
|
|
|
|
</Can>
|
2020-07-05 01:30:50 +00:00
|
|
|
<Can action={[ 'settings.*', 'file.sftp' ]} matchAny>
|
2020-04-12 23:19:43 +00:00
|
|
|
<NavLink to={`${match.url}/settings`}>Settings</NavLink>
|
|
|
|
</Can>
|
|
|
|
</div>
|
2020-07-04 22:40:41 +00:00
|
|
|
</SubNavigation>
|
2020-04-12 23:19:43 +00:00
|
|
|
</CSSTransition>
|
2020-07-30 05:02:00 +00:00
|
|
|
<InstallListener/>
|
|
|
|
<WebsocketHandler/>
|
2020-08-26 04:25:31 +00:00
|
|
|
{(installing && (!rootAdmin || (rootAdmin && !location.pathname.endsWith(`/server/${id}`)))) ?
|
2020-04-26 20:21:39 +00:00
|
|
|
<ScreenBlock
|
|
|
|
title={'Your server is installing.'}
|
|
|
|
image={'/assets/svgs/server_installing.svg'}
|
|
|
|
message={'Please check back in a few minutes.'}
|
|
|
|
/>
|
|
|
|
:
|
|
|
|
<>
|
|
|
|
<TransitionRouter>
|
|
|
|
<Switch location={location}>
|
|
|
|
<Route path={`${match.path}`} component={ServerConsole} exact/>
|
2020-08-23 02:01:29 +00:00
|
|
|
<Route
|
|
|
|
path={`${match.path}/files`}
|
|
|
|
component={requireServerPermission(FileManagerContainer, 'file.*')}
|
|
|
|
exact
|
|
|
|
/>
|
2020-04-26 20:21:39 +00:00
|
|
|
<Route
|
|
|
|
path={`${match.path}/files/:action(edit|new)`}
|
|
|
|
render={props => (
|
|
|
|
<SuspenseSpinner>
|
|
|
|
<FileEditContainer {...props as any}/>
|
|
|
|
</SuspenseSpinner>
|
|
|
|
)}
|
|
|
|
exact
|
|
|
|
/>
|
2020-08-26 04:25:31 +00:00
|
|
|
<Route
|
|
|
|
path={`${match.path}/databases`}
|
|
|
|
component={requireServerPermission(DatabasesContainer, 'database.*')}
|
|
|
|
exact
|
|
|
|
/>
|
|
|
|
<Route
|
|
|
|
path={`${match.path}/schedules`}
|
|
|
|
component={requireServerPermission(ScheduleContainer, 'schedule.*')}
|
|
|
|
exact
|
|
|
|
/>
|
2020-04-26 20:21:39 +00:00
|
|
|
<Route
|
|
|
|
path={`${match.path}/schedules/:id`}
|
|
|
|
component={ScheduleEditContainer}
|
|
|
|
exact
|
|
|
|
/>
|
2020-08-26 04:25:31 +00:00
|
|
|
<Route
|
|
|
|
path={`${match.path}/users`}
|
|
|
|
component={requireServerPermission(UsersContainer, 'user.*')}
|
|
|
|
exact
|
|
|
|
/>
|
|
|
|
<Route
|
|
|
|
path={`${match.path}/backups`}
|
|
|
|
component={requireServerPermission(BackupContainer, 'backup.*')}
|
|
|
|
exact
|
|
|
|
/>
|
|
|
|
<Route
|
|
|
|
path={`${match.path}/network`}
|
|
|
|
component={requireServerPermission(NetworkContainer, 'allocation.*')}
|
|
|
|
exact
|
|
|
|
/>
|
|
|
|
<Route path={`${match.path}/startup`} component={StartupContainer} exact/>
|
2020-04-26 20:21:39 +00:00
|
|
|
<Route path={`${match.path}/settings`} component={SettingsContainer} exact/>
|
|
|
|
<Route path={'*'} component={NotFound}/>
|
|
|
|
</Switch>
|
|
|
|
</TransitionRouter>
|
|
|
|
</>
|
|
|
|
}
|
2020-04-12 23:19:43 +00:00
|
|
|
</>
|
|
|
|
}
|
2019-06-29 23:14:32 +00:00
|
|
|
</React.Fragment>
|
|
|
|
);
|
|
|
|
};
|
2019-07-10 04:25:57 +00:00
|
|
|
|
|
|
|
export default (props: RouteComponentProps<any>) => (
|
|
|
|
<ServerContext.Provider>
|
|
|
|
<ServerRouter {...props}/>
|
|
|
|
</ServerContext.Provider>
|
|
|
|
);
|