From fb575dcc38a912b27231fc917a2ddca79ff622c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20=C5=A0onovsk=C3=BD?= <stepan.sonovsky@inqool.cz> Date: Mon, 12 Aug 2024 14:08:00 +0200 Subject: [PATCH] feat: added pagination --- src/app/components/CommitList.tsx | 48 +++++++++++++++------ src/app/csvDownload/CsvButtons.tsx | 68 ++++++++++++++++++------------ src/app/hooks/useCommits.ts | 33 ++++++++++++++- 3 files changed, 106 insertions(+), 43 deletions(-) diff --git a/src/app/components/CommitList.tsx b/src/app/components/CommitList.tsx index 83f67c2..af79ad9 100644 --- a/src/app/components/CommitList.tsx +++ b/src/app/components/CommitList.tsx @@ -1,9 +1,10 @@ -import React from 'react'; -import useCommits from "@/app/hooks/useCommits"; +import React, { useState } from 'react'; +import {useCommitsPagination} from "@/app/hooks/useCommits"; import CsvButtons from "@/app/csvDownload/CsvButtons"; const CommitList = ({ projectId, token, host, onCommitClick }) => { - const { commits, loading, error } = useCommits(projectId, token, host); + const [page, setPage] = useState(1); + const { commits, loading, error, totalPages } = useCommitsPagination(projectId, token, host, page); if (loading) return <p>Loading...</p>; if (error) return <p>Error: {error.message}</p>; @@ -11,21 +12,40 @@ const CommitList = ({ projectId, token, host, onCommitClick }) => { return ( <div className="bg-white shadow-md rounded-lg p-4"> {commits ? ( - <ul className="bg-white shadow-md rounded-lg p-4"> - {commits.map(commit => ( - <li - key={commit.id} - className="cursor-pointer py-2 px-4 hover:bg-gray-100" - onClick={() => onCommitClick(commit.id)} + <> + <ul className="bg-white shadow-md rounded-lg p-4"> + {commits.map(commit => ( + <li + key={commit.id} + className="cursor-pointer py-2 px-4 hover:bg-gray-100" + onClick={() => onCommitClick(commit.id)} + > + {commit.title} + </li> + ))} + </ul> + <div className="flex justify-between mt-4"> + <button + disabled={page <= 1} + onClick={() => setPage(page - 1)} + className="px-4 py-2 bg-blue-500 text-white rounded" > - {commit.title} - </li> - ))} - </ul> + Previous + </button> + <span>Page {page} of {totalPages}</span> + <button + disabled={page >= totalPages} + onClick={() => setPage(page + 1)} + className="px-4 py-2 bg-blue-500 text-white rounded" + > + Next + </button> + </div> + <CsvButtons projectId={projectId} token={token} host={host}/> + </> ) : ( <p>No commits found</p> )} - <CsvButtons commits={commits} projectId={projectId} token={token}/> </div> ); }; diff --git a/src/app/csvDownload/CsvButtons.tsx b/src/app/csvDownload/CsvButtons.tsx index 469236c..c40622c 100644 --- a/src/app/csvDownload/CsvButtons.tsx +++ b/src/app/csvDownload/CsvButtons.tsx @@ -1,40 +1,54 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import CsvDownloadPositivity from "@/app/csvDownload/CsvDownload"; import CsvDownloadSize from "@/app/csvDownload/CsvDownloadSize"; +import { useCommitsAll } from "@/app/hooks/useCommits"; -const CsvButtons = ({ commits, projectId, token }) => { +const CsvButtons = ({ projectId, token, host }) => { const [showCsvDownloadPositivity, setShowCsvDownloadPositivity] = useState(false); const [showCsvDownloadSize, setShowCsvDownloadSize] = useState(false); + const [fetchCommits, setFetchCommits] = useState(false); + + const { commits, loading, error } = useCommitsAll(projectId, token, host, fetchCommits); + + const handleFetchSize = () => { + setShowCsvDownloadSize(true); + setFetchCommits(true); + }; + + const handleFetchPositivity = () => { + setShowCsvDownloadPositivity(true); + setFetchCommits(true); + }; return ( <> {!showCsvDownloadSize ? ( - <button - onClick={() => setShowCsvDownloadSize(prev => !prev)} - className="mt-4 bg-blue-500 text-white font-bold py-2 px-4 rounded hover:bg-blue-700 m-2" - > - Fetch CSV commits size - </button> -) : ( - <div className="mt-4"> - <CsvDownloadSize commits={commits} projectId={projectId} token={token}/> - </div> -)} + <button + onClick={handleFetchSize} + className="mt-4 bg-blue-500 text-white font-bold py-2 px-4 rounded hover:bg-blue-700 m-2" + > + Fetch CSV commits size + </button> + ) : ( + <div className="mt-4"> + <CsvDownloadSize commits={commits} projectId={projectId} token={token}/> + </div> + )} - {!showCsvDownloadPositivity ? ( - <button - onClick={() => setShowCsvDownloadPositivity(true)} - className="mt-4 bg-blue-500 text-white font-bold py-2 px-4 rounded hover:bg-blue-700 m-2" - > - Fetch CSV commits positivity - </button> - ) : ( - <div className="mt-4"> - <CsvDownloadPositivity commits={commits} projectId={projectId} token={token}/> - </div> - )} - </> -); + {!showCsvDownloadPositivity ? ( + <button + onClick={handleFetchPositivity} + className="mt-4 bg-blue-500 text-white font-bold py-2 px-4 rounded hover:bg-blue-700 m-2" + > + Fetch CSV commits positivity + </button> + ) : ( + <div className="mt-4"> + <CsvDownloadPositivity commits={commits} projectId={projectId} token={token}/> + </div> + )} + </> + ); }; export default CsvButtons; diff --git a/src/app/hooks/useCommits.ts b/src/app/hooks/useCommits.ts index 1d09c5f..e61a716 100644 --- a/src/app/hooks/useCommits.ts +++ b/src/app/hooks/useCommits.ts @@ -1,7 +1,7 @@ import { useState, useEffect } from 'react'; import axios from 'axios'; -const useCommits = (projectId: string, token: string, host: string) => { +export const useCommitsAll = (projectId: string, token: string, host: string) => { const [commits, setCommits] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); @@ -31,4 +31,33 @@ const useCommits = (projectId: string, token: string, host: string) => { return { commits, loading, error }; }; -export default useCommits; + +export const useCommitsPagination = (projectId, token, host, page = 1, perPage = 10) => { + const [commits, setCommits] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const [totalPages, setTotalPages] = useState(1); + + useEffect(() => { + const fetchCommits = async () => { + setLoading(true); + try { + const response = await axios.get(`${host}/api/v4/projects/${projectId}/repository/commits`, { + headers: { 'PRIVATE-TOKEN': token }, + params: { page, per_page: perPage } + }); + setCommits(response.data); + setTotalPages(parseInt(response.headers['x-total-pages'], 10)); + } catch (err) { + setError(err); + } finally { + setLoading(false); + } + }; + + fetchCommits(); + }, [host, projectId, token, page, perPage]); + + return { commits, loading, error, totalPages }; +}; + -- GitLab