diff --git a/components/dashboard/src/components/Pagination.tsx b/components/dashboard/src/Pagination/Pagination.tsx
similarity index 73%
rename from components/dashboard/src/components/Pagination.tsx
rename to components/dashboard/src/Pagination/Pagination.tsx
index a59614a8ff2863..eaf6cb149c24c6 100644
--- a/components/dashboard/src/components/Pagination.tsx
+++ b/components/dashboard/src/Pagination/Pagination.tsx
@@ -4,18 +4,18 @@
* See License-AGPL.txt in the project root for license information.
*/
-import { usePagination } from "../custom-hooks/usePagination";
-import Arrow from "./Arrow";
+import { getPaginationNumbers } from "./getPagination";
+import Arrow from "../components/Arrow";
-function Pagination(props: {
+interface PaginationProps {
totalResults: number;
totalNumberOfPages: number;
currentPage: number;
setCurrentPage: any;
- resultsPerPage: number;
-}) {
- const { totalResults, totalNumberOfPages, currentPage, setCurrentPage, resultsPerPage } = props;
- const calculatedPagination = usePagination({ totalResults, totalNumberOfPages, currentPage, resultsPerPage });
+}
+
+function Pagination({ totalNumberOfPages, currentPage, setCurrentPage }: PaginationProps) {
+ const calculatedPagination = getPaginationNumbers(totalNumberOfPages, currentPage);
const nextPage = () => {
if (currentPage !== totalNumberOfPages) setCurrentPage(currentPage + 1);
@@ -42,12 +42,11 @@ function Pagination(props: {
Previous
- {calculatedPagination &&
- calculatedPagination.map((pn) => (
-
- setCurrentPage(pn)}>{pn}
-
- ))}
+ {calculatedPagination.map((pn) => (
+
+ setCurrentPage(pn)}>{pn}
+
+ ))}
{
+ const totalNumberOfPages = 15;
+ const currentPage = 1;
+
+ expect(getPaginationNumbers(totalNumberOfPages, currentPage)).toStrictEqual([1, 2, 3, "...", 15]);
+
+ expect(getPaginationNumbers(37, 4)).toStrictEqual([1, "...", 3, 4, 5, "...", 37]);
+
+ expect(getPaginationNumbers(28, 7)).toStrictEqual([1, "...", 6, 7, 8, "...", 28]);
+
+ expect(getPaginationNumbers(5, 1)).toStrictEqual([1, 2, 3, 4, 5]);
+});
diff --git a/components/dashboard/src/Pagination/getPagination.ts b/components/dashboard/src/Pagination/getPagination.ts
new file mode 100644
index 00000000000000..6834c00cc02a36
--- /dev/null
+++ b/components/dashboard/src/Pagination/getPagination.ts
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2022 Gitpod GmbH. All rights reserved.
+ * Licensed under the GNU Affero General Public License (AGPL).
+ * See License-AGPL.txt in the project root for license information.
+ */
+
+export function getPaginationNumbers(totalNumberOfPages: number, currentPage: number) {
+ const adjacentToCurrentPage = 1; // This is the number(s) we see next to the currentPage
+ const totalNumbersShownInPagination = 6;
+ let calculatedPagination: number[] = [];
+
+ const pageNumbersAsArray = (startRange: number, endRange: number) => {
+ return [...Array(endRange + 1).keys()].slice(startRange);
+ };
+
+ const minimumAmountInBetweenToShowEllipsis = 2;
+ // Without ellipsis aka normal case
+ if (totalNumberOfPages <= totalNumbersShownInPagination) {
+ return (calculatedPagination = pageNumbersAsArray(1, totalNumberOfPages));
+ }
+
+ // Otherwise, we show the ellipses
+ const toTheRightOfCurrent = Math.min(currentPage + adjacentToCurrentPage, totalNumberOfPages);
+ const toTheLeftOfCurrent = Math.max(currentPage - adjacentToCurrentPage, 1);
+
+ const showRightEllipsis = toTheRightOfCurrent < totalNumberOfPages - minimumAmountInBetweenToShowEllipsis; // e.g. "1 2 3 ... 7"
+ const showLeftEllipsis = toTheLeftOfCurrent > minimumAmountInBetweenToShowEllipsis; // e.g. 1 ... 5 6 7"
+
+ if (showRightEllipsis && !showLeftEllipsis) {
+ let leftSideNumbers = 3;
+ let leftPageNumbersAsArray = pageNumbersAsArray(1, leftSideNumbers);
+ return [...leftPageNumbersAsArray, "...", totalNumberOfPages];
+ }
+
+ if (showLeftEllipsis && !showRightEllipsis) {
+ let rightSideNumbers = 3;
+ let rightPageNumbersAsArray = pageNumbersAsArray(totalNumberOfPages - rightSideNumbers, totalNumberOfPages);
+ return [1, "...", ...rightPageNumbersAsArray];
+ }
+
+ if (showRightEllipsis && showLeftEllipsis) {
+ let middleNumbers = pageNumbersAsArray(toTheLeftOfCurrent, toTheRightOfCurrent);
+ return [1, "...", ...middleNumbers, "...", totalNumberOfPages];
+ }
+
+ return calculatedPagination;
+}
diff --git a/components/dashboard/src/custom-hooks/usePagination.ts b/components/dashboard/src/custom-hooks/usePagination.ts
deleted file mode 100644
index 41e2f811324255..00000000000000
--- a/components/dashboard/src/custom-hooks/usePagination.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * Copyright (c) 2022 Gitpod GmbH. All rights reserved.
- * Licensed under the GNU Affero General Public License (AGPL).
- * See License-AGPL.txt in the project root for license information.
- */
-
-import { useMemo } from "react";
-
-export const usePagination = (props: {
- totalResults: number;
- totalNumberOfPages: number;
- currentPage: number;
- resultsPerPage: number;
-}) => {
- const { totalResults, totalNumberOfPages, currentPage, resultsPerPage } = props;
- const adjacentToCurrentPage = 1; // This is the number(s) we see next to the currentPage
- const totalNumbersShownInPagination = 6;
-
- const pageNumbersAsArray = (startRange: number, endRange: number) => {
- return [...Array(endRange + 1).keys()].slice(startRange);
- };
-
- const calculatedPagination = useMemo(() => {
- const minimumAmountInBetweenToShowEllipsis = 2;
- // Without ellipsis aka normal case
- if (totalNumberOfPages <= totalNumbersShownInPagination) {
- return pageNumbersAsArray(1, totalNumberOfPages);
- }
-
- // Otherwise, we show the ellipses
- const toTheRightOfCurrent = Math.min(currentPage + adjacentToCurrentPage, totalNumberOfPages);
- const toTheLeftOfCurrent = Math.max(currentPage - adjacentToCurrentPage, 1);
-
- const showRightEllipsis = toTheRightOfCurrent < totalNumberOfPages - minimumAmountInBetweenToShowEllipsis; // e.g. "1 2 3 ... 7"
- const showLeftEllipsis = toTheLeftOfCurrent > minimumAmountInBetweenToShowEllipsis; // e.g. 1 ... 5 6 7"
-
- if (showRightEllipsis && !showLeftEllipsis) {
- let leftSideNumbers = 3;
- let leftPageNumbersAsArray = pageNumbersAsArray(1, leftSideNumbers);
- return [...leftPageNumbersAsArray, "...", totalNumberOfPages];
- }
-
- if (showLeftEllipsis && !showRightEllipsis) {
- let rightSideNumbers = 3;
- let rightPageNumbersAsArray = pageNumbersAsArray(totalNumberOfPages - rightSideNumbers, totalNumberOfPages);
- return [1, "...", ...rightPageNumbersAsArray];
- }
-
- if (showRightEllipsis && showLeftEllipsis) {
- let middleNumbers = pageNumbersAsArray(toTheLeftOfCurrent, toTheRightOfCurrent);
- return [1, "...", ...middleNumbers, "...", totalNumberOfPages];
- }
- }, [totalResults, totalNumberOfPages, currentPage, adjacentToCurrentPage, pageNumbersAsArray, resultsPerPage]);
-
- return calculatedPagination;
-};
diff --git a/components/dashboard/src/teams/TeamUsage.tsx b/components/dashboard/src/teams/TeamUsage.tsx
index 423ce3cbba9a7c..5407314b63bf25 100644
--- a/components/dashboard/src/teams/TeamUsage.tsx
+++ b/components/dashboard/src/teams/TeamUsage.tsx
@@ -17,7 +17,7 @@ import {
import { AttributionId } from "@gitpod/gitpod-protocol/lib/attribution";
import { Item, ItemField, ItemsList } from "../components/ItemsList";
import moment from "moment";
-import Pagination from "../components/Pagination";
+import Pagination from "../Pagination/Pagination";
import Header from "../components/Header";
import { ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error";
import { FeatureFlagContext } from "../contexts/FeatureFlagContext";
@@ -240,7 +240,6 @@ function TeamUsage() {
currentPage={currentPage}
setCurrentPage={setCurrentPage}
totalNumberOfPages={totalNumberOfPages}
- resultsPerPage={resultsPerPage}
/>
)}