Skip to content

Commit fc31d63

Browse files
committed
Correctly reset server state when the URL is changed
1 parent b923959 commit fc31d63

File tree

2 files changed

+80
-59
lines changed

2 files changed

+80
-59
lines changed

resources/scripts/components/dashboard/search/SearchModal.tsx

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,27 @@ import { Server } from '@/api/server/getServer';
1111
import { ApplicationStore } from '@/state';
1212
import { httpErrorToHuman } from '@/api/http';
1313
import { Link } from 'react-router-dom';
14+
import styled from 'styled-components';
1415

1516
type Props = RequiredModalProps;
1617

1718
interface Values {
1819
term: string;
1920
}
2021

22+
const ServerResult = styled(Link)`
23+
${tw`flex items-center bg-neutral-900 p-4 rounded border-l-4 border-neutral-900 no-underline`};
24+
transition: all 250ms linear;
25+
26+
&:hover {
27+
${tw`shadow border-cyan-500`};
28+
}
29+
30+
&:not(:last-of-type) {
31+
${tw`mb-2`};
32+
}
33+
`;
34+
2135
const SearchWatcher = () => {
2236
const { values, submitForm } = useFormikContext<Values>();
2337

@@ -91,10 +105,9 @@ export default ({ ...props }: Props) => {
91105
<div className={'mt-6'}>
92106
{
93107
servers.map(server => (
94-
<Link
108+
<ServerResult
95109
key={server.uuid}
96110
to={`/server/${server.id}`}
97-
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'}
98111
onClick={() => props.onDismissed()}
99112
>
100113
<div>
@@ -112,7 +125,7 @@ export default ({ ...props }: Props) => {
112125
{server.node}
113126
</span>
114127
</div>
115-
</Link>
128+
</ServerResult>
116129
))
117130
}
118131
</div>

resources/scripts/routers/ServerRouter.tsx

Lines changed: 64 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { NavLink, Route, RouteComponentProps, Switch } from 'react-router-dom';
33
import NavigationBar from '@/components/NavigationBar';
44
import ServerConsole from '@/components/server/ServerConsole';
55
import TransitionRouter from '@/TransitionRouter';
6-
import Spinner from '@/components/elements/Spinner';
76
import WebsocketHandler from '@/components/server/WebsocketHandler';
87
import { ServerContext } from '@/state/server';
98
import DatabasesContainer from '@/components/server/databases/DatabasesContainer';
@@ -17,74 +16,83 @@ import ScheduleEditContainer from '@/components/server/schedules/ScheduleEditCon
1716
import UsersContainer from '@/components/server/users/UsersContainer';
1817
import Can from '@/components/elements/Can';
1918
import BackupContainer from '@/components/server/backups/BackupContainer';
19+
import Spinner from '@/components/elements/Spinner';
2020

2121
const ServerRouter = ({ match, location }: RouteComponentProps<{ id: string }>) => {
2222
const server = ServerContext.useStoreState(state => state.server.data);
2323
const getServer = ServerContext.useStoreActions(actions => actions.server.getServer);
2424
const clearServerState = ServerContext.useStoreActions(actions => actions.clearServerState);
2525

26-
if (!server) {
26+
useEffect(() => () => {
27+
clearServerState();
28+
}, []);
29+
30+
useEffect(() => {
2731
getServer(match.params.id);
28-
}
2932

30-
useEffect(() => () => clearServerState(), [ clearServerState ]);
33+
return () => {
34+
clearServerState();
35+
};
36+
}, [ match.params.id ]);
3137

3238
return (
3339
<React.Fragment key={'server-router'}>
3440
<NavigationBar/>
35-
<CSSTransition timeout={250} classNames={'fade'} appear={true} in={true}>
36-
<div id={'sub-navigation'}>
37-
<div className={'items'}>
38-
<NavLink to={`${match.url}`} exact>Console</NavLink>
39-
<Can action={'file.*'}>
40-
<NavLink to={`${match.url}/files`}>File Manager</NavLink>
41-
</Can>
42-
<Can action={'database.*'}>
43-
<NavLink to={`${match.url}/databases`}>Databases</NavLink>
44-
</Can>
45-
<Can action={'schedule.*'}>
46-
<NavLink to={`${match.url}/schedules`}>Schedules</NavLink>
47-
</Can>
48-
<Can action={'user.*'}>
49-
<NavLink to={`${match.url}/users`}>Users</NavLink>
50-
</Can>
51-
<Can action={'backup.*'}>
52-
<NavLink to={`${match.url}/backups`}>Backups</NavLink>
53-
</Can>
54-
<Can action={[ 'settings.*', 'file.sftp' ]} matchAny={true}>
55-
<NavLink to={`${match.url}/settings`}>Settings</NavLink>
56-
</Can>
57-
</div>
41+
{!server ?
42+
<div className={'flex justify-center m-20'}>
43+
<Spinner size={'large'}/>
5844
</div>
59-
</CSSTransition>
60-
<WebsocketHandler/>
61-
<TransitionRouter>
62-
{!server ?
63-
<div className={'flex justify-center m-20'}>
64-
<Spinner size={'large'}/>
65-
</div>
66-
:
67-
<Switch location={location}>
68-
<Route path={`${match.path}`} component={ServerConsole} exact/>
69-
<Route path={`${match.path}/files`} component={FileManagerContainer} exact/>
70-
<Route
71-
path={`${match.path}/files/:action(edit|new)`}
72-
render={props => (
73-
<SuspenseSpinner>
74-
<FileEditContainer {...props as any}/>
75-
</SuspenseSpinner>
76-
)}
77-
exact
78-
/>
79-
<Route path={`${match.path}/databases`} component={DatabasesContainer} exact/>
80-
<Route path={`${match.path}/schedules`} component={ScheduleContainer} exact/>
81-
<Route path={`${match.path}/schedules/:id`} component={ScheduleEditContainer} exact/>
82-
<Route path={`${match.path}/users`} component={UsersContainer} exact/>
83-
<Route path={`${match.path}/backups`} component={BackupContainer} exact/>
84-
<Route path={`${match.path}/settings`} component={SettingsContainer} exact/>
85-
</Switch>
86-
}
87-
</TransitionRouter>
45+
:
46+
<>
47+
<CSSTransition timeout={250} classNames={'fade'} appear={true} in={true}>
48+
<div id={'sub-navigation'}>
49+
<div className={'items'}>
50+
<NavLink to={`${match.url}`} exact>Console</NavLink>
51+
<Can action={'file.*'}>
52+
<NavLink to={`${match.url}/files`}>File Manager</NavLink>
53+
</Can>
54+
<Can action={'database.*'}>
55+
<NavLink to={`${match.url}/databases`}>Databases</NavLink>
56+
</Can>
57+
<Can action={'schedule.*'}>
58+
<NavLink to={`${match.url}/schedules`}>Schedules</NavLink>
59+
</Can>
60+
<Can action={'user.*'}>
61+
<NavLink to={`${match.url}/users`}>Users</NavLink>
62+
</Can>
63+
<Can action={'backup.*'}>
64+
<NavLink to={`${match.url}/backups`}>Backups</NavLink>
65+
</Can>
66+
<Can action={[ 'settings.*', 'file.sftp' ]} matchAny={true}>
67+
<NavLink to={`${match.url}/settings`}>Settings</NavLink>
68+
</Can>
69+
</div>
70+
</div>
71+
</CSSTransition>
72+
<WebsocketHandler/>
73+
<TransitionRouter>
74+
<Switch location={location}>
75+
<Route path={`${match.path}`} component={ServerConsole} exact/>
76+
<Route path={`${match.path}/files`} component={FileManagerContainer} exact/>
77+
<Route
78+
path={`${match.path}/files/:action(edit|new)`}
79+
render={props => (
80+
<SuspenseSpinner>
81+
<FileEditContainer {...props as any}/>
82+
</SuspenseSpinner>
83+
)}
84+
exact
85+
/>
86+
<Route path={`${match.path}/databases`} component={DatabasesContainer} exact/>
87+
<Route path={`${match.path}/schedules`} component={ScheduleContainer} exact/>
88+
<Route path={`${match.path}/schedules/:id`} component={ScheduleEditContainer} exact/>
89+
<Route path={`${match.path}/users`} component={UsersContainer} exact/>
90+
<Route path={`${match.path}/backups`} component={BackupContainer} exact/>
91+
<Route path={`${match.path}/settings`} component={SettingsContainer} exact/>
92+
</Switch>
93+
</TransitionRouter>
94+
</>
95+
}
8896
</React.Fragment>
8997
);
9098
};

0 commit comments

Comments
 (0)