Show console when an admin is viewing an installing server
This commit is contained in:
parent
446dc8b33d
commit
6056b6f45d
4 changed files with 130 additions and 88 deletions
|
@ -12,6 +12,7 @@ import SuspenseSpinner from '@/components/elements/SuspenseSpinner';
|
|||
import TitledGreyBox from '@/components/elements/TitledGreyBox';
|
||||
import Can from '@/components/elements/Can';
|
||||
import PageContentBlock from '@/components/elements/PageContentBlock';
|
||||
import ContentContainer from '@/components/elements/ContentContainer';
|
||||
|
||||
type PowerAction = 'start' | 'stop' | 'restart' | 'kill';
|
||||
|
||||
|
@ -123,36 +124,47 @@ export default () => {
|
|||
<span className={'text-neutral-500'}> / {server.limits.disk} MB</span>
|
||||
</p>
|
||||
</TitledGreyBox>
|
||||
<Can action={[ 'control.start', 'control.stop', 'control.restart' ]} matchAny={true}>
|
||||
<div className={'grey-box justify-center'}>
|
||||
<Can action={'control.start'}>
|
||||
<button
|
||||
className={'btn btn-secondary btn-green btn-xs mr-2'}
|
||||
disabled={status !== 'offline'}
|
||||
onClick={e => {
|
||||
e.preventDefault();
|
||||
sendPowerCommand('start');
|
||||
}}
|
||||
>
|
||||
Start
|
||||
</button>
|
||||
</Can>
|
||||
<Can action={'control.restart'}>
|
||||
<button
|
||||
className={'btn btn-secondary btn-primary btn-xs mr-2'}
|
||||
onClick={e => {
|
||||
e.preventDefault();
|
||||
sendPowerCommand('restart');
|
||||
}}
|
||||
>
|
||||
Restart
|
||||
</button>
|
||||
</Can>
|
||||
<Can action={'control.stop'}>
|
||||
<StopOrKillButton onPress={action => sendPowerCommand(action)}/>
|
||||
</Can>
|
||||
{!server.isInstalling ?
|
||||
<Can action={[ 'control.start', 'control.stop', 'control.restart' ]} matchAny={true}>
|
||||
<div className={'grey-box justify-center'}>
|
||||
<Can action={'control.start'}>
|
||||
<button
|
||||
className={'btn btn-secondary btn-green btn-xs mr-2'}
|
||||
disabled={status !== 'offline'}
|
||||
onClick={e => {
|
||||
e.preventDefault();
|
||||
sendPowerCommand('start');
|
||||
}}
|
||||
>
|
||||
Start
|
||||
</button>
|
||||
</Can>
|
||||
<Can action={'control.restart'}>
|
||||
<button
|
||||
className={'btn btn-secondary btn-primary btn-xs mr-2'}
|
||||
onClick={e => {
|
||||
e.preventDefault();
|
||||
sendPowerCommand('restart');
|
||||
}}
|
||||
>
|
||||
Restart
|
||||
</button>
|
||||
</Can>
|
||||
<Can action={'control.stop'}>
|
||||
<StopOrKillButton onPress={action => sendPowerCommand(action)}/>
|
||||
</Can>
|
||||
</div>
|
||||
</Can>
|
||||
:
|
||||
<div className={'mt-4 rounded bg-yellow-500 p-3'}>
|
||||
<ContentContainer>
|
||||
<p className={'text-sm text-yellow-900'}>
|
||||
This server is currently running its installation process and most actions are
|
||||
unavailable.
|
||||
</p>
|
||||
</ContentContainer>
|
||||
</div>
|
||||
</Can>
|
||||
}
|
||||
</div>
|
||||
<div className={'flex-1 ml-4'}>
|
||||
<SuspenseSpinner>
|
||||
|
|
|
@ -20,12 +20,16 @@ import Spinner from '@/components/elements/Spinner';
|
|||
import ServerError from '@/components/screens/ServerError';
|
||||
import { httpErrorToHuman } from '@/api/http';
|
||||
import NotFound from '@/components/screens/NotFound';
|
||||
import { useStoreState } from 'easy-peasy';
|
||||
import ServerInstallingBar from '@/components/elements/ServerInstallingBar';
|
||||
import useServer from '@/plugins/useServer';
|
||||
import ScreenBlock from '@/components/screens/ScreenBlock';
|
||||
|
||||
const ServerRouter = ({ match, location }: RouteComponentProps<{ id: string }>) => {
|
||||
const { rootAdmin } = useStoreState(state => state.user.data!);
|
||||
const [ error, setError ] = useState('');
|
||||
const [ installing, setInstalling ] = useState(false);
|
||||
const server = ServerContext.useStoreState(state => state.server.data);
|
||||
const server = useServer();
|
||||
const getServer = ServerContext.useStoreActions(actions => actions.server.getServer);
|
||||
const clearServerState = ServerContext.useStoreActions(actions => actions.clearServerState);
|
||||
|
||||
|
@ -33,6 +37,10 @@ const ServerRouter = ({ match, location }: RouteComponentProps<{ id: string }>)
|
|||
clearServerState();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setInstalling(server?.isInstalling !== false);
|
||||
}, [ server?.isInstalling ]);
|
||||
|
||||
useEffect(() => {
|
||||
setError('');
|
||||
setInstalling(false);
|
||||
|
@ -55,19 +63,12 @@ const ServerRouter = ({ match, location }: RouteComponentProps<{ id: string }>)
|
|||
<React.Fragment key={'server-router'}>
|
||||
<NavigationBar/>
|
||||
{!server ?
|
||||
!installing ?
|
||||
error ?
|
||||
<ServerError message={error}/>
|
||||
:
|
||||
<div className={'flex justify-center m-20'}>
|
||||
<Spinner size={'large'}/>
|
||||
</div>
|
||||
error ?
|
||||
<ServerError message={error}/>
|
||||
:
|
||||
<ScreenBlock
|
||||
title={'Your server is installing.'}
|
||||
image={'/assets/svgs/server_installing.svg'}
|
||||
message={'Please check back in a few minutes.'}
|
||||
/>
|
||||
<div className={'flex justify-center m-20'}>
|
||||
<Spinner size={'large'}/>
|
||||
</div>
|
||||
:
|
||||
<>
|
||||
<CSSTransition timeout={250} classNames={'fade'} appear={true} in={true}>
|
||||
|
@ -95,29 +96,43 @@ const ServerRouter = ({ match, location }: RouteComponentProps<{ id: string }>)
|
|||
</div>
|
||||
</div>
|
||||
</CSSTransition>
|
||||
<WebsocketHandler/>
|
||||
<TransitionRouter>
|
||||
<Switch location={location}>
|
||||
<Route path={`${match.path}`} component={ServerConsole} exact/>
|
||||
<Route path={`${match.path}/files`} component={FileManagerContainer} exact/>
|
||||
<Route
|
||||
path={`${match.path}/files/:action(edit|new)`}
|
||||
render={props => (
|
||||
<SuspenseSpinner>
|
||||
<FileEditContainer {...props as any}/>
|
||||
</SuspenseSpinner>
|
||||
)}
|
||||
exact
|
||||
/>
|
||||
<Route path={`${match.path}/databases`} component={DatabasesContainer} exact/>
|
||||
<Route path={`${match.path}/schedules`} component={ScheduleContainer} exact/>
|
||||
<Route path={`${match.path}/schedules/:id`} component={ScheduleEditContainer} exact/>
|
||||
<Route path={`${match.path}/users`} component={UsersContainer} exact/>
|
||||
<Route path={`${match.path}/backups`} component={BackupContainer} exact/>
|
||||
<Route path={`${match.path}/settings`} component={SettingsContainer} exact/>
|
||||
<Route path={'*'} component={NotFound}/>
|
||||
</Switch>
|
||||
</TransitionRouter>
|
||||
{(installing && (!rootAdmin || (rootAdmin && !location.pathname.endsWith(`/server/${server.id}`)))) ?
|
||||
<ScreenBlock
|
||||
title={'Your server is installing.'}
|
||||
image={'/assets/svgs/server_installing.svg'}
|
||||
message={'Please check back in a few minutes.'}
|
||||
/>
|
||||
:
|
||||
<>
|
||||
<WebsocketHandler/>
|
||||
<TransitionRouter>
|
||||
<Switch location={location}>
|
||||
<Route path={`${match.path}`} component={ServerConsole} exact/>
|
||||
<Route path={`${match.path}/files`} component={FileManagerContainer} exact/>
|
||||
<Route
|
||||
path={`${match.path}/files/:action(edit|new)`}
|
||||
render={props => (
|
||||
<SuspenseSpinner>
|
||||
<FileEditContainer {...props as any}/>
|
||||
</SuspenseSpinner>
|
||||
)}
|
||||
exact
|
||||
/>
|
||||
<Route path={`${match.path}/databases`} component={DatabasesContainer} exact/>
|
||||
<Route path={`${match.path}/schedules`} component={ScheduleContainer} exact/>
|
||||
<Route
|
||||
path={`${match.path}/schedules/:id`}
|
||||
component={ScheduleEditContainer}
|
||||
exact
|
||||
/>
|
||||
<Route path={`${match.path}/users`} component={UsersContainer} exact/>
|
||||
<Route path={`${match.path}/backups`} component={BackupContainer} exact/>
|
||||
<Route path={`${match.path}/settings`} component={SettingsContainer} exact/>
|
||||
<Route path={'*'} component={NotFound}/>
|
||||
</Switch>
|
||||
</TransitionRouter>
|
||||
</>
|
||||
}
|
||||
</>
|
||||
}
|
||||
</React.Fragment>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue