diff --git a/frontend/src/hooks/api/folderCommits/queries.tsx b/frontend/src/hooks/api/folderCommits/queries.tsx index 785c13ad2..1bca7ce9a 100644 --- a/frontend/src/hooks/api/folderCommits/queries.tsx +++ b/frontend/src/hooks/api/folderCommits/queries.tsx @@ -1,8 +1,9 @@ -import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { useInfiniteQuery, useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { format } from "date-fns"; import { apiRequest } from "@app/config/request"; -import { CommitHistoryItem, CommitWithChanges, RollbackPreview } from "./types"; +import { Commit, CommitHistoryItem, CommitWithChanges, RollbackPreview } from "./types"; export const commitKeys = { count: ({ @@ -242,7 +243,6 @@ export const useGetFolderCommitHistory = ({ workspaceId, environment, directory, - offset = 0, limit = 20, search, sort = "desc" @@ -250,23 +250,33 @@ export const useGetFolderCommitHistory = ({ workspaceId: string; environment: string; directory: string; - offset?: number; limit?: number; search?: string; sort?: "asc" | "desc"; }) => { - return useQuery({ - queryKey: [ - commitKeys.history({ workspaceId, environment, directory }), - offset, - limit, - search, - sort - ], - queryFn: () => - fetchFolderCommitHistory(workspaceId, environment, directory, offset, limit, search, sort), + return useInfiniteQuery({ + initialPageParam: 0, + queryKey: [commitKeys.history({ workspaceId, environment, directory }), limit, search, sort], + queryFn: ({ pageParam }) => + fetchFolderCommitHistory(workspaceId, environment, directory, pageParam, limit, search, sort), enabled: Boolean(workspaceId && environment), - placeholderData: (prev) => prev + select: (data) => { + return (data?.pages ?? []) + ?.map((page) => page.commits) + .flat() + .reduce( + (acc, commit) => { + const date = format(new Date(commit.createdAt), "MMM d, yyyy"); + if (!acc[date]) { + acc[date] = []; + } + acc[date].push(commit); + return acc; + }, + {} as Record + ); + }, + getNextPageParam: (lastPage, pages) => (lastPage.hasMore ? pages.length * limit : undefined) }); }; diff --git a/frontend/src/hooks/api/folderCommits/types.ts b/frontend/src/hooks/api/folderCommits/types.ts index 878e3224d..a5f4e6df6 100644 --- a/frontend/src/hooks/api/folderCommits/types.ts +++ b/frontend/src/hooks/api/folderCommits/types.ts @@ -62,3 +62,16 @@ export type RollbackPreview = { folderPath: string; changes: RollbackChange[]; }; + +interface CommitActorMetadata { + email?: string; + name?: string; +} + +export interface Commit { + id: string; + message: string; + createdAt: string; + actorType: string; + actorMetadata?: CommitActorMetadata; +} diff --git a/frontend/src/pages/secret-manager/CommitDetailsPage/components/CommitDetailsTab/CommitDetailsTab.tsx b/frontend/src/pages/secret-manager/CommitDetailsPage/components/CommitDetailsTab/CommitDetailsTab.tsx index f1d6d8f7e..4fb7182a2 100644 --- a/frontend/src/pages/secret-manager/CommitDetailsPage/components/CommitDetailsTab/CommitDetailsTab.tsx +++ b/frontend/src/pages/secret-manager/CommitDetailsPage/components/CommitDetailsTab/CommitDetailsTab.tsx @@ -291,10 +291,10 @@ export const CommitDetailsTab = ({ Restore Options - + {!parsedCommitDetails.changes.isLatest && ( goToRollbackPreview()} >
@@ -311,7 +311,7 @@ export const CommitDetailsTab = ({ )} handlePopUpOpen("revertChanges")} >
diff --git a/frontend/src/pages/secret-manager/CommitsPage/components/CommitHistoryTab/CommitHistoryTab.tsx b/frontend/src/pages/secret-manager/CommitsPage/components/CommitHistoryTab/CommitHistoryTab.tsx index b5ae9d0c4..58191f389 100644 --- a/frontend/src/pages/secret-manager/CommitsPage/components/CommitHistoryTab/CommitHistoryTab.tsx +++ b/frontend/src/pages/secret-manager/CommitsPage/components/CommitHistoryTab/CommitHistoryTab.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; import { faArrowDownWideShort, faArrowUpWideShort, @@ -7,24 +7,11 @@ import { faSearch } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { format, formatDistanceToNow } from "date-fns"; +import { formatDistanceToNow } from "date-fns"; import { Button, ContentLoader, EmptyState, IconButton, Input } from "@app/components/v2"; import { CopyButton } from "@app/components/v2/CopyButton"; -import { useGetFolderCommitHistory } from "@app/hooks/api/folderCommits"; - -interface CommitActorMetadata { - email?: string; - name?: string; -} - -interface Commit { - id: string; - message: string; - createdAt: string; - actorType: string; - actorMetadata?: CommitActorMetadata; -} +import { Commit, useGetFolderCommitHistory } from "@app/hooks/api/folderCommits"; const formatTimeAgo = (timestamp: string): string => { return formatDistanceToNow(new Date(timestamp), { addSuffix: true }); @@ -50,10 +37,10 @@ const CommitItem = ({ className="w-full border border-b-0 border-mineshaft-600 bg-mineshaft-800 first:rounded-t-md last:rounded-b-md last:border-b" >
-
- +
+

{commit.message} - +

{commit.actorMetadata?.email || commit.actorMetadata?.name || commit.actorType}{" "} committed @@ -122,8 +109,6 @@ export const CommitHistoryTab = ({ const [searchTerm, setSearchTerm] = useState(""); const [debouncedSearchTerm, setDebouncedSearchTerm] = useState(""); const [sortDirection, setSortDirection] = useState<"asc" | "desc">("desc"); - const [offset, setOffset] = useState(0); - const [allCommits, setAllCommits] = useState([]); const debounceTimeoutRef = useRef(); const limit = 10; @@ -145,55 +130,20 @@ export const CommitHistoryTab = ({ }, [searchTerm]); const { - data: response, + data: groupedCommits, isLoading, - isFetching + fetchNextPage, + isFetchingNextPage, + hasNextPage } = useGetFolderCommitHistory({ workspaceId: projectId, environment, directory: secretPath, - offset, limit, search: debouncedSearchTerm, sort: sortDirection }); - const commits = response?.commits || []; - const hasMore = response?.hasMore || false; - - // Reset accumulated commits when search or sort changes - useEffect(() => { - setAllCommits([]); - setOffset(0); - }, [debouncedSearchTerm, sortDirection]); - - // Accumulate commits instead of replacing them - useEffect(() => { - if (commits.length > 0) { - if (offset === 0) { - // First load or after search/sort change - replace all commits - setAllCommits(commits); - } else { - // Subsequent loads - append new commits - setAllCommits((prev) => [...prev, ...commits]); - } - } - }, [commits, offset]); - - const groupedCommits = useMemo(() => { - return allCommits.reduce( - (acc, commit) => { - const date = format(new Date(commit.createdAt), "MMM d, yyyy"); - if (!acc[date]) { - acc[date] = []; - } - acc[date].push(commit); - return acc; - }, - {} as Record - ); - }, [allCommits]); - const handleSort = useCallback(() => { setSortDirection((prev) => (prev === "desc" ? "asc" : "desc")); }, []); @@ -202,12 +152,6 @@ export const CommitHistoryTab = ({ setSearchTerm(value); }, []); - const loadMoreCommits = useCallback(() => { - if (hasMore && !isFetching) { - setOffset((prev) => prev + limit); - } - }, [hasMore, isFetching, limit]); - return (

Commit History

@@ -236,11 +180,11 @@ export const CommitHistoryTab = ({
- {isLoading && offset === 0 ? ( + {isLoading ? ( ) : (
- {Object.keys(groupedCommits).length > 0 ? ( + {groupedCommits && Object.keys(groupedCommits).length > 0 ? ( <> {Object.entries(groupedCommits).map(([date, dateCommits]) => ( )} - - {hasMore && ( + {hasNextPage && (