mirror of https://github.com/coder/coder.git
fix(site): display not found page when pagination page is invalid (#12611)
This commit is contained in:
parent
b121f407f5
commit
c84d96b747
|
@ -53,6 +53,10 @@ describe(buildPagedList.name, () => {
|
|||
expect(uniqueCount).toEqual(result.length);
|
||||
}
|
||||
});
|
||||
|
||||
it("works for invalid active page number", () => {
|
||||
expect(buildPagedList(2, 4)).toEqual([1, 2]);
|
||||
});
|
||||
});
|
||||
|
||||
describe(getOffset.name, () => {
|
||||
|
|
|
@ -33,9 +33,14 @@ export const buildPagedList = (
|
|||
return range(1, numPages);
|
||||
}
|
||||
|
||||
const isInvalidActivePage = activePage > numPages || activePage < 1;
|
||||
const pageBeforeLast = numPages - 1;
|
||||
const startPage = Math.max(activePage - PAGE_NEIGHBORS, 2);
|
||||
const endPage = Math.min(activePage + PAGE_NEIGHBORS, pageBeforeLast);
|
||||
const startPage = isInvalidActivePage
|
||||
? 1 + PAGE_NEIGHBORS
|
||||
: Math.max(activePage - PAGE_NEIGHBORS, 2);
|
||||
const endPage = isInvalidActivePage
|
||||
? numPages - PAGE_NEIGHBORS
|
||||
: Math.min(activePage + PAGE_NEIGHBORS, pageBeforeLast);
|
||||
|
||||
let pages: ReturnType<typeof buildPagedList> = range(startPage, endPage);
|
||||
|
||||
|
|
|
@ -270,3 +270,12 @@ export const Error: Story = {
|
|||
error: mockApiError({ message: "Something went wrong" }),
|
||||
},
|
||||
};
|
||||
|
||||
export const InvalidPageNumber: Story = {
|
||||
args: {
|
||||
workspaces: [],
|
||||
count: 200,
|
||||
limit: 25,
|
||||
page: 1000,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -4,12 +4,14 @@ import KeyboardArrowDownOutlined from "@mui/icons-material/KeyboardArrowDownOutl
|
|||
import PlayArrowOutlined from "@mui/icons-material/PlayArrowOutlined";
|
||||
import StopOutlined from "@mui/icons-material/StopOutlined";
|
||||
import LoadingButton from "@mui/lab/LoadingButton";
|
||||
import Button from "@mui/material/Button";
|
||||
import Divider from "@mui/material/Divider";
|
||||
import type { ComponentProps } from "react";
|
||||
import type { UseQueryResult } from "react-query";
|
||||
import { hasError, isApiValidationError } from "api/errors";
|
||||
import type { Template, Workspace } from "api/typesGenerated";
|
||||
import { ErrorAlert } from "components/Alert/ErrorAlert";
|
||||
import { EmptyState } from "components/EmptyState/EmptyState";
|
||||
import { Margins } from "components/Margins/Margins";
|
||||
import {
|
||||
MoreMenu,
|
||||
|
@ -85,6 +87,11 @@ export const WorkspacesPageView = ({
|
|||
canCreateTemplate,
|
||||
canChangeVersions,
|
||||
}: WorkspacesPageViewProps) => {
|
||||
// Let's say the user has 5 workspaces, but tried to hit page 100, which does
|
||||
// not exist. In this case, the page is not valid and we want to show a better
|
||||
// error message.
|
||||
const invalidPageNumber = page !== 1 && workspaces?.length === 0;
|
||||
|
||||
return (
|
||||
<Margins>
|
||||
<PageHeader
|
||||
|
@ -168,26 +175,48 @@ export const WorkspacesPageView = ({
|
|||
</MoreMenu>
|
||||
</>
|
||||
) : (
|
||||
<PaginationHeader
|
||||
paginationUnitLabel="workspaces"
|
||||
limit={limit}
|
||||
totalRecords={count}
|
||||
currentOffsetStart={(page - 1) * limit + 1}
|
||||
css={{ paddingBottom: "0" }}
|
||||
/>
|
||||
!invalidPageNumber && (
|
||||
<PaginationHeader
|
||||
paginationUnitLabel="workspaces"
|
||||
limit={limit}
|
||||
totalRecords={count}
|
||||
currentOffsetStart={(page - 1) * limit + 1}
|
||||
css={{ paddingBottom: "0" }}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</TableToolbar>
|
||||
|
||||
<WorkspacesTable
|
||||
canCreateTemplate={canCreateTemplate}
|
||||
workspaces={workspaces}
|
||||
isUsingFilter={filterProps.filter.used}
|
||||
onUpdateWorkspace={onUpdateWorkspace}
|
||||
checkedWorkspaces={checkedWorkspaces}
|
||||
onCheckChange={onCheckChange}
|
||||
canCheckWorkspaces={canCheckWorkspaces}
|
||||
templates={templates}
|
||||
/>
|
||||
{invalidPageNumber ? (
|
||||
<EmptyState
|
||||
css={(theme) => ({
|
||||
border: `1px solid ${theme.palette.divider}`,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
})}
|
||||
message="Page not found"
|
||||
description="The page you are trying to access does not exist."
|
||||
cta={
|
||||
<Button
|
||||
onClick={() => {
|
||||
onPageChange(1);
|
||||
}}
|
||||
>
|
||||
Back to the first page
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<WorkspacesTable
|
||||
canCreateTemplate={canCreateTemplate}
|
||||
workspaces={workspaces}
|
||||
isUsingFilter={filterProps.filter.used}
|
||||
onUpdateWorkspace={onUpdateWorkspace}
|
||||
checkedWorkspaces={checkedWorkspaces}
|
||||
onCheckChange={onCheckChange}
|
||||
canCheckWorkspaces={canCheckWorkspaces}
|
||||
templates={templates}
|
||||
/>
|
||||
)}
|
||||
|
||||
{count !== undefined && (
|
||||
// Temporary styling stopgap before component is migrated to using
|
||||
|
|
Loading…
Reference in New Issue