mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-21 02:49:06 +00:00
improvements: revise commit history and commit details UI
This commit is contained in:
+56
-99
@@ -2,13 +2,14 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import {
|
||||
faArrowDownWideShort,
|
||||
faArrowUpWideShort,
|
||||
faCodeCommit,
|
||||
faCopy,
|
||||
faSearch
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { format, formatDistanceToNow } from "date-fns";
|
||||
|
||||
import { Button, Input, Spinner } from "@app/components/v2";
|
||||
import { Button, ContentLoader, EmptyState, IconButton, Input } from "@app/components/v2";
|
||||
import { CopyButton } from "@app/components/v2/CopyButton";
|
||||
import { useGetFolderCommitHistory } from "@app/hooks/api/folderCommits";
|
||||
|
||||
@@ -40,58 +41,40 @@ const CommitItem = ({
|
||||
onSelectCommit: (commitId: string, tab: string) => void;
|
||||
}) => {
|
||||
return (
|
||||
<div className="border-b border-zinc-800 last:border-b-0">
|
||||
<div className="px-4 py-4 transition-colors duration-200 hover:bg-zinc-800">
|
||||
<div className="flex flex-col sm:flex-row sm:justify-between">
|
||||
<div className="w-5/6 flex-1">
|
||||
<div className="flex items-center">
|
||||
<Button
|
||||
variant="link"
|
||||
className="truncate text-left text-white hover:underline"
|
||||
isFullWidth
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onSelectCommit(commit.id, "tab-commit-details");
|
||||
}}
|
||||
>
|
||||
{commit.message}
|
||||
</Button>
|
||||
</div>
|
||||
<p className="text-white-400 mt-2 flex flex-wrap items-center gap-4 text-sm">
|
||||
<span className="flex items-center text-mineshaft-300">
|
||||
{commit.actorMetadata?.email || commit.actorMetadata?.name || commit.actorType}
|
||||
<p className="ml-1 mr-1">committed</p>
|
||||
<time dateTime={commit.createdAt}>{formatTimeAgo(commit.createdAt)}</time>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-2 flex w-1/6 items-center justify-end sm:mt-0">
|
||||
<div className="flex items-center space-x-1">
|
||||
<Button
|
||||
variant="link"
|
||||
className="text-white hover:underline"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onSelectCommit(commit.id, "tab-commit-details");
|
||||
}}
|
||||
>
|
||||
<code className="text-white-400 px-3 py-1 font-mono text-sm">
|
||||
{commit.id?.substring(0, 11)}
|
||||
</code>
|
||||
</Button>
|
||||
<CopyButton
|
||||
value={commit.id}
|
||||
name={commit.id}
|
||||
size="sm"
|
||||
variant="plain"
|
||||
color="text-mineshaft-400"
|
||||
icon={faCopy}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onSelectCommit(commit.id, "tab-commit-details");
|
||||
}}
|
||||
className="w-full border border-b-0 border-mineshaft-600 bg-mineshaft-800 first:rounded-t-md last:rounded-b-md last:border-b"
|
||||
>
|
||||
<div className="flex gap-2 px-4 py-3 transition-colors duration-200 hover:bg-zinc-800">
|
||||
<div className="flex flex-1 flex-col items-start">
|
||||
<span className="w-min whitespace-nowrap text-sm text-mineshaft-100">
|
||||
{commit.message}
|
||||
</span>
|
||||
<p className="text-left text-xs text-mineshaft-300">
|
||||
{commit.actorMetadata?.email || commit.actorMetadata?.name || commit.actorType}{" "}
|
||||
committed <time dateTime={commit.createdAt}>{formatTimeAgo(commit.createdAt)}</time>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center space-x-2">
|
||||
<code className="mt-0.5 font-mono text-xs text-mineshaft-400">
|
||||
{commit.id?.substring(0, 11)}
|
||||
</code>
|
||||
<CopyButton
|
||||
value={commit.id}
|
||||
name={commit.id}
|
||||
size="xs"
|
||||
variant="plain"
|
||||
color="text-mineshaft-400"
|
||||
icon={faCopy}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -108,24 +91,16 @@ const DateGroup = ({
|
||||
onSelectCommit: (commitId: string, tab: string) => void;
|
||||
}) => {
|
||||
return (
|
||||
<div className="mb-8 last:mb-0 last:pb-2">
|
||||
<div className="mb-4 flex items-center">
|
||||
<div className="relative mr-3 flex h-6 w-6 items-center justify-center">
|
||||
<div className="z-10 h-3 w-3 rounded-full border-2 border-mineshaft-600 bg-bunker-800" />
|
||||
<div className="absolute left-0 right-0 top-1/2 h-0.5 -translate-y-1/2 bg-mineshaft-600" />
|
||||
</div>
|
||||
<h2 className="text-sm text-white">Commits on {date}</h2>
|
||||
<div className="mt-4 first:mt-0">
|
||||
<div className="mb-4 ml-[0.15rem] flex items-center">
|
||||
<FontAwesomeIcon icon={faCodeCommit} className="text-mineshaft-400" />
|
||||
<h2 className="ml-4 text-sm text-mineshaft-400">Commits on {date}</h2>
|
||||
</div>
|
||||
|
||||
<div className="relative">
|
||||
<div className="absolute bottom-0 left-3 top-0 w-0.5 bg-mineshaft-600" />
|
||||
<div className="absolute bottom-0 left-3 top-0 w-[0.1rem] bg-mineshaft-500" />
|
||||
<div className="ml-10">
|
||||
{commits.map((commit) => (
|
||||
<div key={commit.id} className="relative mb-3 pb-1">
|
||||
<div className="overflow-hidden rounded-md border border-solid border-mineshaft-600">
|
||||
<CommitItem commit={commit} onSelectCommit={onSelectCommit} />
|
||||
</div>
|
||||
</div>
|
||||
<CommitItem key={commit.id} commit={commit} onSelectCommit={onSelectCommit} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
@@ -150,7 +125,7 @@ export const CommitHistoryTab = ({
|
||||
const [offset, setOffset] = useState(0);
|
||||
const [allCommits, setAllCommits] = useState<Commit[]>([]);
|
||||
const debounceTimeoutRef = useRef<NodeJS.Timeout>();
|
||||
const limit = 5;
|
||||
const limit = 10;
|
||||
|
||||
// Debounce search term
|
||||
useEffect(() => {
|
||||
@@ -234,42 +209,37 @@ export const CommitHistoryTab = ({
|
||||
}, [hasMore, isFetching, limit]);
|
||||
|
||||
return (
|
||||
<div className="w-full">
|
||||
<div className="mt-4 w-full rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<p className="mb-4 text-xl font-semibold text-mineshaft-100">Commit History</p>
|
||||
<div className="mb-4 flex flex-col sm:flex-row sm:justify-end">
|
||||
<div className="flex w-full flex-wrap items-center gap-2">
|
||||
<div className="relative flex-grow">
|
||||
<Input
|
||||
leftIcon={<FontAwesomeIcon icon={faSearch} aria-hidden="true" />}
|
||||
placeholder="Search commits..."
|
||||
className="h-10 w-full rounded-md border-transparent bg-zinc-800 pl-9 pr-3 text-sm text-white placeholder-gray-400 focus:border-gray-600 focus:ring-primary-500/20"
|
||||
onChange={(e) => handleSearch(e.target.value)}
|
||||
value={searchTerm}
|
||||
aria-label="Search commits"
|
||||
/>
|
||||
<div className="absolute left-3 top-1/2 -translate-y-1/2 transform text-gray-400">
|
||||
<FontAwesomeIcon icon={faSearch} aria-hidden="true" />
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
<IconButton
|
||||
variant="outline_bg"
|
||||
size="md"
|
||||
className="flex h-10 items-center justify-center gap-2 rounded-md bg-zinc-800 px-4 py-2 text-sm text-white transition-colors duration-200 hover:bg-zinc-700 focus:outline-none focus:ring-2 focus:ring-primary-500"
|
||||
size="sm"
|
||||
className="flex h-[2.4rem] items-center justify-center gap-2 rounded-md"
|
||||
onClick={handleSort}
|
||||
aria-label={`Sort by date ${sortDirection === "desc" ? "ascending" : "descending"}`}
|
||||
ariaLabel={`Sort by date ${sortDirection === "desc" ? "ascending" : "descending"}`}
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
icon={sortDirection === "desc" ? faArrowDownWideShort : faArrowUpWideShort}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</Button>
|
||||
</IconButton>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isLoading && offset === 0 ? (
|
||||
<div className="flex h-64 items-center justify-center">
|
||||
<Spinner size="lg" aria-label="Loading commits" />
|
||||
</div>
|
||||
<ContentLoader className="h-80" />
|
||||
) : (
|
||||
<div className="space-y-8">
|
||||
<div className="">
|
||||
{Object.keys(groupedCommits).length > 0 ? (
|
||||
<>
|
||||
{Object.entries(groupedCommits).map(([date, dateCommits]) => (
|
||||
@@ -282,34 +252,21 @@ export const CommitHistoryTab = ({
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
<div className="text-white-400 flex min-h-40 flex-col items-center justify-center rounded-lg bg-zinc-900 py-8 text-center">
|
||||
<FontAwesomeIcon
|
||||
icon={faSearch}
|
||||
className="text-white-500 mb-3 text-3xl"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<p>No matching commits found. Try a different search term.</p>
|
||||
</div>
|
||||
<EmptyState title="No commits found." icon={faCodeCommit} />
|
||||
)}
|
||||
|
||||
{hasMore && (
|
||||
<div className="flex justify-center pb-2">
|
||||
<Button
|
||||
variant="outline_bg"
|
||||
size="md"
|
||||
className="rounded-md bg-zinc-900 px-6 py-2 text-sm font-medium text-white transition-colors duration-200 hover:bg-zinc-800 focus:outline-none focus:ring-2 focus:ring-primary-500"
|
||||
size="sm"
|
||||
className="ml-10 mt-4 w-full"
|
||||
onClick={loadMoreCommits}
|
||||
disabled={isFetching}
|
||||
isLoading={isFetching}
|
||||
aria-label="Load more commits"
|
||||
>
|
||||
{isFetching ? (
|
||||
<>
|
||||
<Spinner size="sm" className="mr-2" />
|
||||
Loading...
|
||||
</>
|
||||
) : (
|
||||
"Load more commits"
|
||||
)}
|
||||
Load More Commits
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user