@@ -15,35 +15,45 @@ type CheckpointMenuBaseProps = {
1515 checkpoint : Checkpoint
1616}
1717type CheckpointMenuControlledProps = {
18- open : boolean
1918 onOpenChange : ( open : boolean ) => void
2019}
2120type CheckpointMenuUncontrolledProps = {
22- open ?: undefined
2321 onOpenChange ?: undefined
2422}
2523type CheckpointMenuProps = CheckpointMenuBaseProps & ( CheckpointMenuControlledProps | CheckpointMenuUncontrolledProps )
2624
27- export const CheckpointMenu = ( {
28- ts,
29- commitHash,
30- currentHash,
31- checkpoint,
32- open,
33- onOpenChange,
34- } : CheckpointMenuProps ) => {
25+ export const CheckpointMenu = ( { ts, commitHash, currentHash, checkpoint, onOpenChange } : CheckpointMenuProps ) => {
3526 const { t } = useTranslation ( )
36- const [ internalOpen , setInternalOpen ] = useState ( false )
37- const [ isConfirming , setIsConfirming ] = useState ( false )
38- const [ isDiffOpen , setIsDiffOpen ] = useState ( false )
27+ const [ internalRestoreOpen , setInternalRestoreOpen ] = useState ( false )
28+ const [ restoreConfirming , setRestoreIsConfirming ] = useState ( false )
29+ const [ internalMoreOpen , setInternalMoreOpen ] = useState ( false )
3930 const portalContainer = useRooPortal ( "roo-portal" )
4031
4132 const isCurrent = currentHash === commitHash
4233
4334 const previousCommitHash = checkpoint ?. from
4435
45- const isOpen = open ?? internalOpen
46- const setOpen = onOpenChange ?? setInternalOpen
36+ const restoreOpen = internalRestoreOpen
37+ const moreOpen = internalMoreOpen
38+ const setRestoreOpen = useCallback (
39+ ( open : boolean ) => {
40+ setInternalRestoreOpen ( open )
41+ if ( onOpenChange ) {
42+ onOpenChange ( open )
43+ }
44+ } ,
45+ [ onOpenChange ] ,
46+ )
47+
48+ const setMoreOpen = useCallback (
49+ ( open : boolean ) => {
50+ setInternalMoreOpen ( open )
51+ if ( onOpenChange ) {
52+ onOpenChange ( open )
53+ }
54+ } ,
55+ [ onOpenChange ] ,
56+ )
4757
4858 const onCheckpointDiff = useCallback ( ( ) => {
4959 vscode . postMessage ( {
@@ -68,22 +78,22 @@ export const CheckpointMenu = ({
6878
6979 const onPreview = useCallback ( ( ) => {
7080 vscode . postMessage ( { type : "checkpointRestore" , payload : { ts, commitHash, mode : "preview" } } )
71- setOpen ( false )
72- } , [ ts , commitHash , setOpen ] )
81+ setRestoreOpen ( false )
82+ } , [ ts , commitHash , setRestoreOpen ] )
7383
7484 const onRestore = useCallback ( ( ) => {
7585 vscode . postMessage ( { type : "checkpointRestore" , payload : { ts, commitHash, mode : "restore" } } )
76- setOpen ( false )
77- } , [ ts , commitHash , setOpen ] )
86+ setRestoreOpen ( false )
87+ } , [ ts , commitHash , setRestoreOpen ] )
7888
7989 const handleOpenChange = useCallback (
8090 ( open : boolean ) => {
81- setOpen ( open )
91+ setRestoreOpen ( open )
8292 if ( ! open ) {
83- setIsConfirming ( false )
93+ setRestoreIsConfirming ( false )
8494 }
8595 } ,
86- [ setOpen ] ,
96+ [ setRestoreOpen ] ,
8797 )
8898
8999 return (
@@ -93,7 +103,13 @@ export const CheckpointMenu = ({
93103 < span className = "codicon codicon-diff-single" />
94104 </ Button >
95105 </ StandardTooltip >
96- < Popover open = { isOpen } onOpenChange = { handleOpenChange } >
106+ < Popover
107+ open = { restoreOpen }
108+ onOpenChange = { ( open ) => {
109+ handleOpenChange ( open )
110+ setRestoreIsConfirming ( false )
111+ } }
112+ data-testid = "restore-popover" >
97113 < StandardTooltip content = { t ( "chat:checkpoint.menu.restore" ) } >
98114 < PopoverTrigger asChild >
99115 < Button variant = "ghost" size = "icon" aria-label = { t ( "chat:checkpoint.menu.restore" ) } >
@@ -113,54 +129,52 @@ export const CheckpointMenu = ({
113129 </ div >
114130 </ div >
115131 ) }
116- { ! isCurrent && (
132+ < div className = "flex flex-col gap-1 group hover:text-foreground" >
117133 < div className = "flex flex-col gap-1 group hover:text-foreground" >
118- < div className = "flex flex-col gap-1 group hover:text-foreground" >
119- { ! isConfirming ? (
134+ { ! restoreConfirming ? (
135+ < Button
136+ variant = "secondary"
137+ onClick = { ( ) => setRestoreIsConfirming ( true ) }
138+ data-testid = "restore-files-and-task-btn" >
139+ { t ( "chat:checkpoint.menu.restoreFilesAndTask" ) }
140+ </ Button >
141+ ) : (
142+ < >
120143 < Button
121- variant = "secondary"
122- onClick = { ( ) => setIsConfirming ( true ) }
123- data-testid = "restore-files-and-task-btn" >
124- { t ( "chat:checkpoint.menu.restoreFilesAndTask" ) }
144+ variant = "default"
145+ onClick = { onRestore }
146+ className = "grow"
147+ data-testid = "confirm-restore-btn" >
148+ < div className = "flex flex-row gap-1" >
149+ < CheckIcon />
150+ < div > { t ( "chat:checkpoint.menu.confirm" ) } </ div >
151+ </ div >
125152 </ Button >
126- ) : (
127- < >
128- < Button
129- variant = "default"
130- onClick = { onRestore }
131- className = "grow"
132- data-testid = "confirm-restore-btn" >
133- < div className = "flex flex-row gap-1" >
134- < CheckIcon />
135- < div > { t ( "chat:checkpoint.menu.confirm" ) } </ div >
136- </ div >
137- </ Button >
138- < Button variant = "secondary" onClick = { ( ) => setIsConfirming ( false ) } >
139- < div className = "flex flex-row gap-1" >
140- < Cross2Icon />
141- < div > { t ( "chat:checkpoint.menu.cancel" ) } </ div >
142- </ div >
143- </ Button >
144- </ >
145- ) }
146- { isConfirming ? (
147- < div
148- data-testid = "checkpoint-confirm-warning"
149- className = "text-destructive font-bold" >
150- { t ( "chat:checkpoint.menu.cannotUndo" ) }
151- </ div >
152- ) : (
153- < div className = "text-muted transition-colors group-hover:text-foreground" >
154- { t ( "chat:checkpoint.menu.restoreFilesAndTaskDescription" ) }
155- </ div >
156- ) }
157- </ div >
153+ < Button variant = "secondary" onClick = { ( ) => setRestoreIsConfirming ( false ) } >
154+ < div className = "flex flex-row gap-1" >
155+ < Cross2Icon />
156+ < div > { t ( "chat:checkpoint.menu.cancel" ) } </ div >
157+ </ div >
158+ </ Button >
159+ </ >
160+ ) }
161+ { restoreConfirming ? (
162+ < div
163+ data-testid = "checkpoint-confirm-warning"
164+ className = "text-destructive font-bold" >
165+ { t ( "chat:checkpoint.menu.cannotUndo" ) }
166+ </ div >
167+ ) : (
168+ < div className = "text-muted transition-colors group-hover:text-foreground" >
169+ { t ( "chat:checkpoint.menu.restoreFilesAndTaskDescription" ) }
170+ </ div >
171+ ) }
158172 </ div >
159- ) }
173+ </ div >
160174 </ div >
161175 </ PopoverContent >
162176 </ Popover >
163- < Popover open = { isDiffOpen } onOpenChange = { ( open ) => setIsDiffOpen ( open ) } >
177+ < Popover open = { moreOpen } onOpenChange = { ( open ) => setMoreOpen ( open ) } data-testid = "more-popover" >
164178 < StandardTooltip content = { t ( "chat:task.seeMore" ) } >
165179 < PopoverTrigger asChild >
166180 < Button variant = "ghost" size = "icon" aria-label = { t ( "chat:checkpoint.menu.more" ) } >
@@ -171,19 +185,19 @@ export const CheckpointMenu = ({
171185 < PopoverContent align = "end" container = { portalContainer } >
172186 < div className = "flex flex-col gap-2" >
173187 < Button
174- variant = "ghost "
188+ variant = "secondary "
175189 onClick = { ( ) => {
176190 onDiffFromInit ( )
177- setIsDiffOpen ( false )
191+ setMoreOpen ( false )
178192 } } >
179193 < span className = "codicon codicon-versions mr-2" />
180194 { t ( "chat:checkpoint.menu.viewDiffFromInit" ) }
181195 </ Button >
182196 < Button
183- variant = "ghost "
197+ variant = "secondary "
184198 onClick = { ( ) => {
185199 onDiffWithCurrent ( )
186- setIsDiffOpen ( false )
200+ setMoreOpen ( false )
187201 } } >
188202 < span className = "codicon codicon-diff mr-2" />
189203 { t ( "chat:checkpoint.menu.viewDiffWithCurrent" ) }
0 commit comments