screenshot-to-code/frontend/src/components/history/HistoryDisplay.tsx
2024-08-22 13:51:40 -04:00

128 lines
4.1 KiB
TypeScript

import toast from "react-hot-toast";
import classNames from "classnames";
import { Badge } from "../ui/badge";
import { summarizeHistoryItem } from "./utils";
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "../ui/collapsible";
import { Button } from "../ui/button";
import { CaretSortIcon } from "@radix-ui/react-icons";
import { useProjectStore } from "../../store/project-store";
interface Props {
shouldDisableReverts: boolean;
}
export default function HistoryDisplay({ shouldDisableReverts }: Props) {
const { commits, head, setHead } = useProjectStore();
// TODO: Clean this up
const newHistory = Object.values(commits).flatMap((commit) => {
if (
commit.type === "ai_create" ||
commit.type === "ai_edit" ||
commit.type === "code_create"
) {
return {
type: commit.type,
hash: commit.hash,
summary: summarizeHistoryItem(commit),
parentHash: commit.parentHash,
code: commit.variants[commit.selectedVariantIndex].code,
inputs: commit.inputs,
date_created: commit.date_created,
};
}
return [];
});
// Sort by date created
newHistory.sort(
(a, b) =>
new Date(a.date_created).getTime() - new Date(b.date_created).getTime()
);
const setParentVersion = (
parentHash: string | null,
currentHash: string | null
) => {
if (!parentHash) return null;
const parentIndex = newHistory.findIndex(
(item) => item.hash === parentHash
);
const currentIndex = newHistory.findIndex(
(item) => item.hash === currentHash
);
return parentIndex !== -1 && parentIndex != currentIndex - 1
? parentIndex + 1
: null;
};
// Update newHistory to include the parent version
const updatedHistory = newHistory.map((item) => ({
...item,
parentVersion: setParentVersion(item.parentHash, item.hash),
}));
return updatedHistory.length === 0 ? null : (
<div className="flex flex-col h-screen">
<h1 className="font-bold mb-2">Versions</h1>
<ul className="space-y-0 flex flex-col-reverse">
{updatedHistory.map((item, index) => (
<li key={index}>
<Collapsible>
<div
className={classNames(
"flex items-center justify-between space-x-2 w-full pr-2",
"border-b cursor-pointer",
{
" hover:bg-black hover:text-white": item.hash === head,
"bg-slate-500 text-white": item.hash === head,
}
)}
>
<div
className="flex justify-between truncate flex-1 p-2"
onClick={() =>
shouldDisableReverts
? toast.error(
"Please wait for code generation to complete before viewing an older version."
)
: setHead(item.hash)
}
>
<div className="flex gap-x-1 truncate">
<h2 className="text-sm truncate">{item.summary}</h2>
{item.parentVersion !== null && (
<h2 className="text-sm">
(parent: v{item.parentVersion})
</h2>
)}
</div>
<h2 className="text-sm">v{index + 1}</h2>
</div>
<CollapsibleTrigger asChild>
<Button variant="ghost" size="sm" className="h-6">
<CaretSortIcon className="h-4 w-4" />
<span className="sr-only">Toggle</span>
</Button>
</CollapsibleTrigger>
</div>
<CollapsibleContent className="w-full bg-slate-300 p-2">
<div>Full prompt: {item.summary}</div>
<div className="flex justify-end">
<Badge>{item.type}</Badge>
</div>
</CollapsibleContent>
</Collapsible>
</li>
))}
</ul>
</div>
);
}