|
|
@@ -14,25 +14,43 @@ type CheckpointMenuBaseProps = {
|
|
|
checkpoint: Checkpoint
|
|
|
}
|
|
|
type CheckpointMenuControlledProps = {
|
|
|
- open: boolean
|
|
|
onOpenChange: (open: boolean) => void
|
|
|
}
|
|
|
type CheckpointMenuUncontrolledProps = {
|
|
|
- open?: undefined
|
|
|
onOpenChange?: undefined
|
|
|
}
|
|
|
type CheckpointMenuProps = CheckpointMenuBaseProps & (CheckpointMenuControlledProps | CheckpointMenuUncontrolledProps)
|
|
|
|
|
|
-export const CheckpointMenu = ({ ts, commitHash, checkpoint, open, onOpenChange }: CheckpointMenuProps) => {
|
|
|
+export const CheckpointMenu = ({ ts, commitHash, checkpoint, onOpenChange }: CheckpointMenuProps) => {
|
|
|
const { t } = useTranslation()
|
|
|
- const [internalOpen, setInternalOpen] = useState(false)
|
|
|
- const [isConfirming, setIsConfirming] = useState(false)
|
|
|
+ const [internalRestoreOpen, setInternalRestoreOpen] = useState(false)
|
|
|
+ const [restoreConfirming, setRestoreConfirming] = useState(false)
|
|
|
+ const [internalMoreOpen, setInternalMoreOpen] = useState(false)
|
|
|
const portalContainer = useRooPortal("roo-portal")
|
|
|
|
|
|
const previousCommitHash = checkpoint?.from
|
|
|
|
|
|
- const isOpen = open ?? internalOpen
|
|
|
- const setOpen = onOpenChange ?? setInternalOpen
|
|
|
+ const restoreOpen = internalRestoreOpen
|
|
|
+ const moreOpen = internalMoreOpen
|
|
|
+ const setRestoreOpen = useCallback(
|
|
|
+ (open: boolean) => {
|
|
|
+ setInternalRestoreOpen(open)
|
|
|
+ if (onOpenChange) {
|
|
|
+ onOpenChange(open)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ [onOpenChange],
|
|
|
+ )
|
|
|
+
|
|
|
+ const setMoreOpen = useCallback(
|
|
|
+ (open: boolean) => {
|
|
|
+ setInternalMoreOpen(open)
|
|
|
+ if (onOpenChange) {
|
|
|
+ onOpenChange(open)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ [onOpenChange],
|
|
|
+ )
|
|
|
|
|
|
const onCheckpointDiff = useCallback(() => {
|
|
|
vscode.postMessage({
|
|
|
@@ -41,24 +59,38 @@ export const CheckpointMenu = ({ ts, commitHash, checkpoint, open, onOpenChange
|
|
|
})
|
|
|
}, [ts, previousCommitHash, commitHash])
|
|
|
|
|
|
+ const onDiffFromInit = useCallback(() => {
|
|
|
+ vscode.postMessage({
|
|
|
+ type: "checkpointDiff",
|
|
|
+ payload: { ts, commitHash, mode: "from-init" },
|
|
|
+ })
|
|
|
+ }, [ts, commitHash])
|
|
|
+
|
|
|
+ const onDiffWithCurrent = useCallback(() => {
|
|
|
+ vscode.postMessage({
|
|
|
+ type: "checkpointDiff",
|
|
|
+ payload: { ts, commitHash, mode: "to-current" },
|
|
|
+ })
|
|
|
+ }, [ts, commitHash])
|
|
|
+
|
|
|
const onPreview = useCallback(() => {
|
|
|
vscode.postMessage({ type: "checkpointRestore", payload: { ts, commitHash, mode: "preview" } })
|
|
|
- setOpen(false)
|
|
|
- }, [ts, commitHash, setOpen])
|
|
|
+ setRestoreOpen(false)
|
|
|
+ }, [ts, commitHash, setRestoreOpen])
|
|
|
|
|
|
const onRestore = useCallback(() => {
|
|
|
vscode.postMessage({ type: "checkpointRestore", payload: { ts, commitHash, mode: "restore" } })
|
|
|
- setOpen(false)
|
|
|
- }, [ts, commitHash, setOpen])
|
|
|
+ setRestoreOpen(false)
|
|
|
+ }, [ts, commitHash, setRestoreOpen])
|
|
|
|
|
|
const handleOpenChange = useCallback(
|
|
|
(open: boolean) => {
|
|
|
- setOpen(open)
|
|
|
+ setRestoreOpen(open)
|
|
|
if (!open) {
|
|
|
- setIsConfirming(false)
|
|
|
+ setRestoreConfirming(false)
|
|
|
}
|
|
|
},
|
|
|
- [setOpen],
|
|
|
+ [setRestoreOpen],
|
|
|
)
|
|
|
|
|
|
return (
|
|
|
@@ -68,7 +100,13 @@ export const CheckpointMenu = ({ ts, commitHash, checkpoint, open, onOpenChange
|
|
|
<span className="codicon codicon-diff-single" />
|
|
|
</Button>
|
|
|
</StandardTooltip>
|
|
|
- <Popover open={isOpen} onOpenChange={handleOpenChange}>
|
|
|
+ <Popover
|
|
|
+ open={restoreOpen}
|
|
|
+ onOpenChange={(open) => {
|
|
|
+ handleOpenChange(open)
|
|
|
+ setRestoreConfirming(false)
|
|
|
+ }}
|
|
|
+ data-testid="restore-popover">
|
|
|
<StandardTooltip content={t("chat:checkpoint.menu.restore")}>
|
|
|
<PopoverTrigger asChild>
|
|
|
<Button variant="ghost" size="icon" aria-label={t("chat:checkpoint.menu.restore")}>
|
|
|
@@ -87,10 +125,10 @@ export const CheckpointMenu = ({ ts, commitHash, checkpoint, open, onOpenChange
|
|
|
</div>
|
|
|
</div>
|
|
|
<div className="flex flex-col gap-1 group hover:text-foreground">
|
|
|
- {!isConfirming ? (
|
|
|
+ {!restoreConfirming ? (
|
|
|
<Button
|
|
|
variant="secondary"
|
|
|
- onClick={() => setIsConfirming(true)}
|
|
|
+ onClick={() => setRestoreConfirming(true)}
|
|
|
data-testid="restore-files-and-task-btn">
|
|
|
{t("chat:checkpoint.menu.restoreFilesAndTask")}
|
|
|
</Button>
|
|
|
@@ -106,7 +144,7 @@ export const CheckpointMenu = ({ ts, commitHash, checkpoint, open, onOpenChange
|
|
|
<div>{t("chat:checkpoint.menu.confirm")}</div>
|
|
|
</div>
|
|
|
</Button>
|
|
|
- <Button variant="secondary" onClick={() => setIsConfirming(false)}>
|
|
|
+ <Button variant="secondary" onClick={() => setRestoreConfirming(false)}>
|
|
|
<div className="flex flex-row gap-1">
|
|
|
<Cross2Icon />
|
|
|
<div>{t("chat:checkpoint.menu.cancel")}</div>
|
|
|
@@ -114,7 +152,7 @@ export const CheckpointMenu = ({ ts, commitHash, checkpoint, open, onOpenChange
|
|
|
</Button>
|
|
|
</>
|
|
|
)}
|
|
|
- {isConfirming ? (
|
|
|
+ {restoreConfirming ? (
|
|
|
<div data-testid="checkpoint-confirm-warning" className="text-destructive font-bold">
|
|
|
{t("chat:checkpoint.menu.cannotUndo")}
|
|
|
</div>
|
|
|
@@ -127,6 +165,37 @@ export const CheckpointMenu = ({ ts, commitHash, checkpoint, open, onOpenChange
|
|
|
</div>
|
|
|
</PopoverContent>
|
|
|
</Popover>
|
|
|
+ <Popover open={moreOpen} onOpenChange={(open) => setMoreOpen(open)} data-testid="more-popover">
|
|
|
+ <StandardTooltip content={t("chat:task.seeMore")}>
|
|
|
+ <PopoverTrigger asChild>
|
|
|
+ <Button variant="ghost" size="icon" aria-label={t("chat:checkpoint.menu.more")}>
|
|
|
+ <span className="codicon codicon-kebab-vertical" />
|
|
|
+ </Button>
|
|
|
+ </PopoverTrigger>
|
|
|
+ </StandardTooltip>
|
|
|
+ <PopoverContent align="end" container={portalContainer}>
|
|
|
+ <div className="flex flex-col gap-2">
|
|
|
+ <Button
|
|
|
+ variant="secondary"
|
|
|
+ onClick={() => {
|
|
|
+ onDiffFromInit()
|
|
|
+ setMoreOpen(false)
|
|
|
+ }}>
|
|
|
+ <span className="codicon codicon-versions mr-2" />
|
|
|
+ {t("chat:checkpoint.menu.viewDiffFromInit")}
|
|
|
+ </Button>
|
|
|
+ <Button
|
|
|
+ variant="secondary"
|
|
|
+ onClick={() => {
|
|
|
+ onDiffWithCurrent()
|
|
|
+ setMoreOpen(false)
|
|
|
+ }}>
|
|
|
+ <span className="codicon codicon-diff mr-2" />
|
|
|
+ {t("chat:checkpoint.menu.viewDiffWithCurrent")}
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ </PopoverContent>
|
|
|
+ </Popover>
|
|
|
</div>
|
|
|
)
|
|
|
}
|