Skip to content

Commit 29b4b52

Browse files
committed
Set the current page in the dashboard URL to allow easy refreshing; closes pterodactyl#2993
1 parent 7676f7d commit 29b4b52

File tree

3 files changed

+35
-7
lines changed

3 files changed

+35
-7
lines changed

resources/scripts/components/dashboard/AccountOverviewContainer.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import PageContentBlock from '@/components/elements/PageContentBlock';
77
import tw from 'twin.macro';
88
import { breakpoint } from '@/theme';
99
import styled from 'styled-components/macro';
10-
import { RouteComponentProps } from 'react-router';
1110
import MessageBox from '@/components/MessageBox';
11+
import { useLocation } from 'react-router-dom';
1212

1313
const Container = styled.div`
1414
${tw`flex flex-wrap`};
@@ -26,7 +26,9 @@ const Container = styled.div`
2626
}
2727
`;
2828

29-
export default ({ location: { state } }: RouteComponentProps) => {
29+
export default () => {
30+
const { state } = useLocation<undefined | { twoFactorRedirect?: boolean }>();
31+
3032
return (
3133
<PageContentBlock title={'Account Overview'}>
3234
{state?.twoFactorRedirect &&

resources/scripts/components/dashboard/DashboardContainer.tsx

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,14 @@ import tw from 'twin.macro';
1212
import useSWR from 'swr';
1313
import { PaginatedResult } from '@/api/http';
1414
import Pagination from '@/components/elements/Pagination';
15+
import { useLocation } from 'react-router-dom';
1516

1617
export default () => {
18+
const { search } = useLocation();
19+
const defaultPage = Number(new URLSearchParams(search).get('page') || '1');
20+
21+
const [ page, setPage ] = useState((!isNaN(defaultPage) && defaultPage > 0) ? defaultPage : 1);
1722
const { clearFlashes, clearAndAddHttpError } = useFlash();
18-
const [ page, setPage ] = useState(1);
1923
const uuid = useStoreState(state => state.user.data!.uuid);
2024
const rootAdmin = useStoreState(state => state.user.data!.rootAdmin);
2125
const [ showOnlyAdmin, setShowOnlyAdmin ] = usePersistedState(`${uuid}:show_all_servers`, false);
@@ -25,6 +29,20 @@ export default () => {
2529
() => getServers({ page, type: showOnlyAdmin ? 'admin' : undefined }),
2630
);
2731

32+
useEffect(() => {
33+
if (!servers) return;
34+
if (servers.pagination.currentPage > 1 && !servers.items.length) {
35+
setPage(1);
36+
}
37+
}, [ servers?.pagination.currentPage ]);
38+
39+
useEffect(() => {
40+
// Don't use react-router to handle changing this part of the URL, otherwise it
41+
// triggers a needless re-render. We just want to track this in the URL incase the
42+
// user refreshes the page.
43+
window.history.replaceState(null, document.title, `/${page <= 1 ? '' : `?page=${page}`}`);
44+
}, [ page ]);
45+
2846
useEffect(() => {
2947
if (error) clearAndAddHttpError({ key: 'dashboard', error });
3048
if (!error) clearFlashes('dashboard');

resources/scripts/routers/DashboardRouter.tsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,18 @@ export default ({ location }: RouteComponentProps) => (
2121
}
2222
<TransitionRouter>
2323
<Switch location={location}>
24-
<Route path={'/'} component={DashboardContainer} exact/>
25-
<Route path={'/account'} component={AccountOverviewContainer} exact/>
26-
<Route path={'/account/api'} component={AccountApiContainer} exact/>
27-
<Route path={'*'} component={NotFound}/>
24+
<Route path={'/'} exact>
25+
<DashboardContainer/>
26+
</Route>
27+
<Route path={'/account'} exact>
28+
<AccountOverviewContainer/>
29+
</Route>
30+
<Route path={'/account/api'} exact>
31+
<AccountApiContainer/>
32+
</Route>
33+
<Route path={'*'}>
34+
<NotFound/>
35+
</Route>
2836
</Switch>
2937
</TransitionRouter>
3038
</>

0 commit comments

Comments
 (0)