11import { useState , useEffect , useCallback } from "react"
2- import { DotsHorizontalIcon } from "@radix-ui/react-icons"
3- import { DropdownMenuItemProps } from "@radix-ui/react-dropdown-menu"
2+ import { CheckIcon , Cross2Icon } from "@radix-ui/react-icons"
43
54import { vscode } from "../../../utils/vscode"
65
7- import {
8- Button ,
9- DropdownMenu ,
10- DropdownMenuTrigger ,
11- DropdownMenuContent ,
12- DropdownMenuItem ,
13- DropdownMenuShortcut ,
14- } from "@/components/ui"
6+ import { Button , Popover , PopoverContent , PopoverTrigger } from "@/components/ui"
157
168type CheckpointMenuProps = {
179 ts : number
@@ -20,21 +12,21 @@ type CheckpointMenuProps = {
2012
2113export const CheckpointMenu = ( { ts, commitHash } : CheckpointMenuProps ) => {
2214 const [ portalContainer , setPortalContainer ] = useState < HTMLElement > ( )
23-
24- const onTaskDiff = useCallback ( ( ) => {
25- vscode . postMessage ( { type : "checkpointDiff" , payload : { ts, commitHash, mode : "full" } } )
26- } , [ ts , commitHash ] )
15+ const [ isOpen , setIsOpen ] = useState ( false )
16+ const [ isConfirming , setIsConfirming ] = useState ( false )
2717
2818 const onCheckpointDiff = useCallback ( ( ) => {
2919 vscode . postMessage ( { type : "checkpointDiff" , payload : { ts, commitHash, mode : "checkpoint" } } )
3020 } , [ ts , commitHash ] )
3121
3222 const onPreview = useCallback ( ( ) => {
3323 vscode . postMessage ( { type : "checkpointRestore" , payload : { ts, commitHash, mode : "preview" } } )
24+ setIsOpen ( false )
3425 } , [ ts , commitHash ] )
3526
3627 const onRestore = useCallback ( ( ) => {
3728 vscode . postMessage ( { type : "checkpointRestore" , payload : { ts, commitHash, mode : "restore" } } )
29+ setIsOpen ( false )
3830 } , [ ts , commitHash ] )
3931
4032 useEffect ( ( ) => {
@@ -47,34 +39,66 @@ export const CheckpointMenu = ({ ts, commitHash }: CheckpointMenuProps) => {
4739 } , [ ] )
4840
4941 return (
50- < DropdownMenu >
51- < DropdownMenuTrigger asChild >
52- < Button variant = "ghost" size = "icon" >
53- < DotsHorizontalIcon />
54- </ Button >
55- </ DropdownMenuTrigger >
56- < DropdownMenuContent container = { portalContainer } align = "end" >
57- < CheckpointMenuItem label = "Checkpoint Diff" icon = "diff-single" onClick = { onCheckpointDiff } />
58- < CheckpointMenuItem label = "Task Diff" icon = "diff-multiple" onClick = { onTaskDiff } />
59- < CheckpointMenuItem label = "Preview" icon = "open-preview" onClick = { onPreview } />
60- < CheckpointMenuItem label = "Restore" icon = "history" onClick = { onRestore } />
61- </ DropdownMenuContent >
62- </ DropdownMenu >
42+ < div className = "flex flex-row gap-1" >
43+ < Button variant = "ghost" size = "icon" onClick = { onCheckpointDiff } >
44+ < span className = "codicon codicon-diff-single" />
45+ </ Button >
46+ < Popover
47+ open = { isOpen }
48+ onOpenChange = { ( open ) => {
49+ setIsOpen ( open )
50+ setIsConfirming ( false )
51+ } } >
52+ < PopoverTrigger asChild >
53+ < Button variant = "ghost" size = "icon" >
54+ < span className = "codicon codicon-history" />
55+ </ Button >
56+ </ PopoverTrigger >
57+ < PopoverContent align = "end" container = { portalContainer } >
58+ < div className = "flex flex-col gap-2" >
59+ < div className = "flex flex-col gap-1 group hover:text-foreground" >
60+ < Button variant = "secondary" onClick = { onPreview } >
61+ Restore Files
62+ </ Button >
63+ < div className = "text-muted transition-colors group-hover:text-foreground" >
64+ Restores your project's files back to a snapshot taken at this point.
65+ </ div >
66+ </ div >
67+ < div className = "flex flex-col gap-1 group hover:text-foreground" >
68+ < div className = "flex flex-col gap-1 group hover:text-foreground" >
69+ { ! isConfirming ? (
70+ < Button variant = "secondary" onClick = { ( ) => setIsConfirming ( true ) } >
71+ Restore Files & Task
72+ </ Button >
73+ ) : (
74+ < >
75+ < Button variant = "default" onClick = { onRestore } className = "grow" >
76+ < div className = "flex flex-row gap-1" >
77+ < CheckIcon />
78+ < div > Confirm</ div >
79+ </ div >
80+ </ Button >
81+ < Button variant = "secondary" onClick = { ( ) => setIsConfirming ( false ) } >
82+ < div className = "flex flex-row gap-1" >
83+ < Cross2Icon />
84+ < div > Cancel</ div >
85+ </ div >
86+ </ Button >
87+ </ >
88+ ) }
89+ { isConfirming ? (
90+ < div className = "text-destructive font-bold" > This action cannot be undone.</ div >
91+ ) : (
92+ < div className = "text-muted transition-colors group-hover:text-foreground" >
93+ Restores your project's files back to a snapshot taken at this point and deletes
94+ all messages after this point.
95+ </ div >
96+ ) }
97+ </ div >
98+ </ div >
99+ </ div >
100+ </ PopoverContent >
101+ </ Popover >
102+ </ div >
63103 )
64104}
65-
66- type CheckpointMenuItemProps = DropdownMenuItemProps & {
67- label : React . ReactNode
68- icon : "diff-single" | "diff-multiple" | "open-preview" | "history"
69- }
70-
71- const CheckpointMenuItem = ( { label, icon, ...props } : CheckpointMenuItemProps ) => (
72- < DropdownMenuItem { ...props } >
73- < div className = "flex flex-row-reverse gap-1" >
74- < div > { label } </ div >
75- < DropdownMenuShortcut >
76- < span className = { `codicon codicon-${ icon } ` } />
77- </ DropdownMenuShortcut >
78- </ div >
79- </ DropdownMenuItem >
80- )
0 commit comments