diff --git a/reana-ui/src/client.js b/reana-ui/src/client.js
index a635bbe5..d7083021 100644
--- a/reana-ui/src/client.js
+++ b/reana-ui/src/client.js
@@ -175,8 +175,10 @@ class Client {
});
}
- getGitlabProjects({ search } = {}) {
- return this._request(GITLAB_PROJECTS_URL({ search }));
+ getGitlabProjects({ search, pagination } = {}) {
+ return this._request(
+ GITLAB_PROJECTS_URL({ ...(pagination ?? {}), search }),
+ );
}
toggleGitlabProject(method, data) {
diff --git a/reana-ui/src/pages/profile/components/GitLabProjects.js b/reana-ui/src/pages/profile/components/GitLabProjects.js
index bd3bfde8..65f26f5d 100644
--- a/reana-ui/src/pages/profile/components/GitLabProjects.js
+++ b/reana-ui/src/pages/profile/components/GitLabProjects.js
@@ -13,14 +13,18 @@ import { useEffect, useState, useRef } from "react";
import { Button, List, Loader, Radio, Message, Icon } from "semantic-ui-react";
import client, { GITLAB_AUTH_URL } from "~/client";
-import { Search } from "~/components";
+import { Search, Pagination } from "~/components";
import styles from "./GitLabProjects.module.scss";
export default function GitLabProjects() {
+ const DEFAULT_PAGINATION = { page: 1, size: 10 };
+
const [projects, setProjects] = useState(null);
const [fetchingProjects, setFetchingProjects] = useState(false);
const [searchFilter, setSearchFilter] = useState(null);
+ const [pagination, setPagination] = useState(DEFAULT_PAGINATION);
+ const [totalPages, setTotalPages] = useState(0);
// keep track of last fetch request in order to avoid
// updating the state with out-of-order responses
@@ -29,7 +33,10 @@ export default function GitLabProjects() {
useEffect(() => {
// Fetch project list
setFetchingProjects(true);
- let request = client.getGitlabProjects({ search: searchFilter });
+ let request = client.getGitlabProjects({
+ pagination,
+ search: searchFilter,
+ });
lastFetchRequest.current = request;
request
@@ -39,10 +46,17 @@ export default function GitLabProjects() {
return;
}
let newProjects = {};
- for (const [id, details] of Object.entries(res.data)) {
- newProjects[id] = { ...details, toggling: false };
+ for (const project of res.data.items) {
+ newProjects[project.id] = { ...project, toggling: false };
}
setProjects(newProjects);
+ const newTotalPages =
+ res.data.total != null
+ ? Math.ceil(res.data.total / pagination.size)
+ : res.data.has_next
+ ? pagination.page + 1
+ : pagination.page;
+ setTotalPages(newTotalPages);
setFetchingProjects(false);
})
.catch((e) => {
@@ -51,9 +65,10 @@ export default function GitLabProjects() {
return;
}
setProjects(null);
+ setTotalPages(0);
setFetchingProjects(false);
});
- }, [searchFilter]);
+ }, [searchFilter, pagination]);
const setToggling = (projectId, toggling) => {
setProjects((currentProjects) => ({
@@ -101,6 +116,12 @@ export default function GitLabProjects() {
});
};
+ const onSearchFilterChange = (value) => {
+ // reset pagination if search filter changes
+ setPagination(DEFAULT_PAGINATION);
+ setSearchFilter(value);
+ };
+
if (fetchingProjects && projects === null) {
// projects were never fetched before, show spinner
return (
@@ -136,7 +157,7 @@ export default function GitLabProjects() {
} else {
return (
<>
-
@@ -167,6 +188,16 @@ export default function GitLabProjects() {
},
)}
+