2020-12-16 23:55:44 +00:00
import TransferListener from '@/components/server/TransferListener' ;
2020-04-17 18:07:32 +00:00
import React , { useEffect , useState } from 'react' ;
2020-10-13 03:59:11 +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-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' ;
2021-01-31 02:01:32 +00:00
import ScreenBlock , { NotFound , ServerError } from '@/components/elements/ScreenBlock' ;
2020-04-17 18:07:32 +00:00
import { httpErrorToHuman } from '@/api/http' ;
2020-04-26 20:21:39 +00:00
import { useStoreState } from 'easy-peasy' ;
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-10-23 04:18:46 +00:00
import ErrorBoundary from '@/components/elements/ErrorBoundary' ;
2020-11-02 05:14:02 +00:00
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' ;
import { faExternalLinkAlt } from '@fortawesome/free-solid-svg-icons' ;
2021-01-01 17:21:13 +00:00
import RequireServerPermission from '@/hoc/RequireServerPermission' ;
2021-01-31 02:01:32 +00:00
import ServerInstallSvg from '@/assets/images/server_installing.svg' ;
import ServerRestoreSvg from '@/assets/images/server_restore.svg' ;
2021-02-18 04:58:47 +00:00
import ServerErrorSvg from '@/assets/images/server_error.svg' ;
2021-01-31 02:01:32 +00:00
const ConflictStateRenderer = ( ) = > {
const status = ServerContext . useStoreState ( state = > state . server . data ? . status || null ) ;
const isTransferring = ServerContext . useStoreState ( state = > state . server . data ? . isTransferring || false ) ;
return (
status === 'installing' || status === 'install_failed' ?
< ScreenBlock
title = { 'Running Installer' }
image = { ServerInstallSvg }
message = { 'Your server should be ready soon, please try again in a few minutes.' }
/ >
:
2021-02-18 04:58:47 +00:00
status === 'suspended' ?
< ScreenBlock
title = { 'Server Suspended' }
image = { ServerErrorSvg }
message = { 'This server is suspended and cannot be accessed.' }
/ >
:
< ScreenBlock
title = { isTransferring ? 'Transferring' : 'Restoring from Backup' }
image = { ServerRestoreSvg }
message = { isTransferring ? 'Your server is being transfered to a new node, please check back later.' : 'Your server is currently being restored from a backup, please check back in a few minutes.' }
/ >
2021-01-31 02:01:32 +00:00
) ;
} ;
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 ( '' ) ;
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 ) ;
2021-01-31 02:01:32 +00:00
const inConflictState = ServerContext . useStoreState ( state = > state . server . inConflictState ) ;
2020-11-08 21:18:15 +00:00
const serverId = ServerContext . useStoreState ( state = > state . server . data ? . internalId ) ;
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 ( ) ;
} , [ ] ) ;
useEffect ( ( ) = > {
2020-04-17 18:07:32 +00:00
setError ( '' ) ;
2020-12-16 16:34:47 +00:00
2020-04-17 18:07:32 +00:00
getServer ( match . params . id )
. catch ( error = > {
2021-01-31 02:01:32 +00:00
console . error ( error ) ;
setError ( httpErrorToHuman ( error ) ) ;
2020-04-17 18:07:32 +00:00
} ) ;
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
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-11-02 05:49:07 +00:00
< Can action = { 'allocation.*' } >
2020-07-10 02:56:46 +00:00
< 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 >
2020-11-02 05:14:02 +00:00
{ rootAdmin &&
2021-07-17 20:33:03 +00:00
< a href = { '/admin/servers/' + serverId } rel = "noreferrer" target = { '_blank' } >
2020-11-08 21:18:15 +00:00
< FontAwesomeIcon icon = { faExternalLinkAlt } / >
< / a >
2020-11-02 05:14:02 +00:00
}
2020-04-12 23:19:43 +00:00
< / 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 / >
2020-12-16 23:55:44 +00:00
< TransferListener / >
2020-07-30 05:02:00 +00:00
< WebsocketHandler / >
2021-01-31 02:01:32 +00:00
{ ( inConflictState && ( ! rootAdmin || ( rootAdmin && ! location . pathname . endsWith ( ` /server/ ${ id } ` ) ) ) ) ?
< ConflictStateRenderer / >
2020-04-26 20:21:39 +00:00
:
2020-10-23 04:18:46 +00:00
< ErrorBoundary >
2020-04-26 20:21:39 +00:00
< TransitionRouter >
< Switch location = { location } >
< Route path = { ` ${ match . path } ` } component = { ServerConsole } exact / >
2021-01-01 17:21:13 +00:00
< Route path = { ` ${ match . path } /files ` } exact >
< RequireServerPermission permissions = { 'file.*' } >
2021-01-31 02:01:32 +00:00
< FileManagerContainer / >
2021-01-01 17:21:13 +00:00
< / RequireServerPermission >
< / Route >
< Route path = { ` ${ match . path } /files/:action(edit|new) ` } exact >
2021-05-16 19:35:49 +00:00
< Spinner.Suspense >
2021-01-31 02:01:32 +00:00
< FileEditContainer / >
2021-05-16 19:35:49 +00:00
< / Spinner.Suspense >
2021-01-01 17:21:13 +00:00
< / Route >
< Route path = { ` ${ match . path } /databases ` } exact >
< RequireServerPermission permissions = { 'database.*' } >
2021-01-31 02:01:32 +00:00
< DatabasesContainer / >
2021-01-01 17:21:13 +00:00
< / RequireServerPermission >
< / Route >
< Route path = { ` ${ match . path } /schedules ` } exact >
< RequireServerPermission permissions = { 'schedule.*' } >
2021-01-31 02:01:32 +00:00
< ScheduleContainer / >
2021-01-01 17:21:13 +00:00
< / RequireServerPermission >
< / Route >
< Route path = { ` ${ match . path } /schedules/:id ` } exact >
< ScheduleEditContainer / >
< / Route >
< Route path = { ` ${ match . path } /users ` } exact >
< RequireServerPermission permissions = { 'user.*' } >
2021-01-31 02:01:32 +00:00
< UsersContainer / >
2021-01-01 17:21:13 +00:00
< / RequireServerPermission >
< / Route >
< Route path = { ` ${ match . path } /backups ` } exact >
< RequireServerPermission permissions = { 'backup.*' } >
2021-01-31 02:01:32 +00:00
< BackupContainer / >
2021-01-01 17:21:13 +00:00
< / RequireServerPermission >
< / Route >
< Route path = { ` ${ match . path } /network ` } exact >
< RequireServerPermission permissions = { 'allocation.*' } >
2021-01-31 02:01:32 +00:00
< NetworkContainer / >
2021-01-01 17:21:13 +00:00
< / RequireServerPermission >
< / Route >
2020-08-26 04:25:31 +00:00
< 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-10-23 04:18:46 +00:00
< / ErrorBoundary >
2020-04-26 20:21:39 +00:00
}
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 >
) ;