Correctly reset server state when the URL is changed

This commit is contained in:
Dane Everitt 2020-04-12 16:19:43 -07:00
parent b9239594ca
commit fc31d6347e
No known key found for this signature in database
GPG Key ID: EEA66103B3D71F53
2 changed files with 81 additions and 60 deletions

View File

@ -11,6 +11,7 @@ import { Server } from '@/api/server/getServer';
import { ApplicationStore } from '@/state'; import { ApplicationStore } from '@/state';
import { httpErrorToHuman } from '@/api/http'; import { httpErrorToHuman } from '@/api/http';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import styled from 'styled-components';
type Props = RequiredModalProps; type Props = RequiredModalProps;
@ -18,6 +19,19 @@ interface Values {
term: string; term: string;
} }
const ServerResult = styled(Link)`
${tw`flex items-center bg-neutral-900 p-4 rounded border-l-4 border-neutral-900 no-underline`};
transition: all 250ms linear;
&:hover {
${tw`shadow border-cyan-500`};
}
&:not(:last-of-type) {
${tw`mb-2`};
}
`;
const SearchWatcher = () => { const SearchWatcher = () => {
const { values, submitForm } = useFormikContext<Values>(); const { values, submitForm } = useFormikContext<Values>();
@ -91,10 +105,9 @@ export default ({ ...props }: Props) => {
<div className={'mt-6'}> <div className={'mt-6'}>
{ {
servers.map(server => ( servers.map(server => (
<Link <ServerResult
key={server.uuid} key={server.uuid}
to={`/server/${server.id}`} to={`/server/${server.id}`}
className={'flex items-center block bg-neutral-900 p-4 rounded border-l-4 border-neutral-900 no-underline hover:shadow hover:border-cyan-500 transition-colors duration-250'}
onClick={() => props.onDismissed()} onClick={() => props.onDismissed()}
> >
<div> <div>
@ -112,7 +125,7 @@ export default ({ ...props }: Props) => {
{server.node} {server.node}
</span> </span>
</div> </div>
</Link> </ServerResult>
)) ))
} }
</div> </div>

View File

@ -3,7 +3,6 @@ import { NavLink, Route, RouteComponentProps, Switch } from 'react-router-dom';
import NavigationBar from '@/components/NavigationBar'; import NavigationBar from '@/components/NavigationBar';
import ServerConsole from '@/components/server/ServerConsole'; import ServerConsole from '@/components/server/ServerConsole';
import TransitionRouter from '@/TransitionRouter'; import TransitionRouter from '@/TransitionRouter';
import Spinner from '@/components/elements/Spinner';
import WebsocketHandler from '@/components/server/WebsocketHandler'; import WebsocketHandler from '@/components/server/WebsocketHandler';
import { ServerContext } from '@/state/server'; import { ServerContext } from '@/state/server';
import DatabasesContainer from '@/components/server/databases/DatabasesContainer'; import DatabasesContainer from '@/components/server/databases/DatabasesContainer';
@ -17,74 +16,83 @@ import ScheduleEditContainer from '@/components/server/schedules/ScheduleEditCon
import UsersContainer from '@/components/server/users/UsersContainer'; import UsersContainer from '@/components/server/users/UsersContainer';
import Can from '@/components/elements/Can'; import Can from '@/components/elements/Can';
import BackupContainer from '@/components/server/backups/BackupContainer'; import BackupContainer from '@/components/server/backups/BackupContainer';
import Spinner from '@/components/elements/Spinner';
const ServerRouter = ({ match, location }: RouteComponentProps<{ id: string }>) => { const ServerRouter = ({ match, location }: RouteComponentProps<{ id: string }>) => {
const server = ServerContext.useStoreState(state => state.server.data); const server = ServerContext.useStoreState(state => state.server.data);
const getServer = ServerContext.useStoreActions(actions => actions.server.getServer); const getServer = ServerContext.useStoreActions(actions => actions.server.getServer);
const clearServerState = ServerContext.useStoreActions(actions => actions.clearServerState); const clearServerState = ServerContext.useStoreActions(actions => actions.clearServerState);
if (!server) { useEffect(() => () => {
getServer(match.params.id); clearServerState();
} }, []);
useEffect(() => () => clearServerState(), [ clearServerState ]); useEffect(() => {
getServer(match.params.id);
return () => {
clearServerState();
};
}, [ match.params.id ]);
return ( return (
<React.Fragment key={'server-router'}> <React.Fragment key={'server-router'}>
<NavigationBar/> <NavigationBar/>
<CSSTransition timeout={250} classNames={'fade'} appear={true} in={true}> {!server ?
<div id={'sub-navigation'}> <div className={'flex justify-center m-20'}>
<div className={'items'}> <Spinner size={'large'}/>
<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>
<Can action={[ 'settings.*', 'file.sftp' ]} matchAny={true}>
<NavLink to={`${match.url}/settings`}>Settings</NavLink>
</Can>
</div>
</div> </div>
</CSSTransition> :
<WebsocketHandler/> <>
<TransitionRouter> <CSSTransition timeout={250} classNames={'fade'} appear={true} in={true}>
{!server ? <div id={'sub-navigation'}>
<div className={'flex justify-center m-20'}> <div className={'items'}>
<Spinner size={'large'}/> <NavLink to={`${match.url}`} exact>Console</NavLink>
</div> <Can action={'file.*'}>
: <NavLink to={`${match.url}/files`}>File Manager</NavLink>
<Switch location={location}> </Can>
<Route path={`${match.path}`} component={ServerConsole} exact/> <Can action={'database.*'}>
<Route path={`${match.path}/files`} component={FileManagerContainer} exact/> <NavLink to={`${match.url}/databases`}>Databases</NavLink>
<Route </Can>
path={`${match.path}/files/:action(edit|new)`} <Can action={'schedule.*'}>
render={props => ( <NavLink to={`${match.url}/schedules`}>Schedules</NavLink>
<SuspenseSpinner> </Can>
<FileEditContainer {...props as any}/> <Can action={'user.*'}>
</SuspenseSpinner> <NavLink to={`${match.url}/users`}>Users</NavLink>
)} </Can>
exact <Can action={'backup.*'}>
/> <NavLink to={`${match.url}/backups`}>Backups</NavLink>
<Route path={`${match.path}/databases`} component={DatabasesContainer} exact/> </Can>
<Route path={`${match.path}/schedules`} component={ScheduleContainer} exact/> <Can action={[ 'settings.*', 'file.sftp' ]} matchAny={true}>
<Route path={`${match.path}/schedules/:id`} component={ScheduleEditContainer} exact/> <NavLink to={`${match.url}/settings`}>Settings</NavLink>
<Route path={`${match.path}/users`} component={UsersContainer} exact/> </Can>
<Route path={`${match.path}/backups`} component={BackupContainer} exact/> </div>
<Route path={`${match.path}/settings`} component={SettingsContainer} exact/> </div>
</Switch> </CSSTransition>
} <WebsocketHandler/>
</TransitionRouter> <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/>
</Switch>
</TransitionRouter>
</>
}
</React.Fragment> </React.Fragment>
); );
}; };