refine ui

restore in a Dialog
This commit is contained in:
Christoph Brandau
2026-06-29 17:53:02 +02:00
parent b0491d1479
commit 8d56c3f39f
8 changed files with 293 additions and 97 deletions
+40 -7
View File
@@ -22,6 +22,7 @@
compareCommits,
cancelCodeSearch,
diffFileAgainstWorkingTree,
compareFileToHead,
getStatus,
listBranches,
listCommits,
@@ -79,6 +80,7 @@
let comparison: GitCommitComparison | null = null;
let compareDialogOpen = false;
let selectedDiffPath = "";
let pendingRestoreFile: { commit: GitCommit; file: GitCommitFile } | null = null;
let globalSearchOpen = false;
let globalSearchResults: GitSearchHit[] = [];
let globalSearchBusy = false;
@@ -211,6 +213,7 @@
comparison = null;
compareDialogOpen = false;
selectedDiffPath = "";
pendingRestoreFile = null;
}
}
@@ -242,7 +245,7 @@
selectedExplorerPath = ""; selectedExplorerKind = "file";
expandedExplorerPaths = new Set(); expandedCommitHashes = new Set();
fileHistory = []; compareFrom = ""; compareTo = "";
comparison = null; compareDialogOpen = false; selectedDiffPath = "";
comparison = null; compareDialogOpen = false; selectedDiffPath = ""; pendingRestoreFile = null;
if (globalSearchBusy) void cancelGlobalSearch();
globalSearchResults = []; globalSearchOpen = false; globalSearchError = "";
resolveDialogOpen = false; conflictTarget = ""; conflict = null;
@@ -433,15 +436,30 @@
});
}
async function restoreCommitFile(target: GitCommit, file: GitCommitFile) {
if (!activeRepoPath) return;
async function restoreCommitFile(target: GitCommit, file: GitCommitFile): Promise<boolean> {
if (!activeRepoPath) return false;
const confirmed = window.confirm(`Restore ${file.path} from ${target.short_hash}?\n\nThis changes the file in your working tree so you can review and commit it.`);
if (!confirmed) return;
if (!confirmed) return false;
await runOperation(`Restoring ${file.path}`, async () => {
applyStatus(await restoreFileFromCommit(activeRepoPath, target.hash, file.path));
await refreshExplorerFiles(activeRepoPath);
await refreshFileHistory(activeRepoPath);
});
return !errorMessage;
}
async function previewCommitFileFromHistory(target: GitCommit, file: GitCommitFile) {
if (!activeRepoPath) return;
await runOperation(`Diffing ${file.path}`, async () => {
const result = await compareFileToHead(activeRepoPath, target.hash, file.path);
const matchingFile = result.files.find((diffFile) =>
diffFile.path === file.path || diffFile.old_path === file.old_path || diffFile.old_path === file.path,
);
comparison = result;
selectedDiffPath = matchingFile?.path ?? result.files[0]?.path ?? file.path;
pendingRestoreFile = { commit: target, file };
compareDialogOpen = true;
});
}
// ── Explorer interaction ───────────────────────────────────────────────────
@@ -482,6 +500,7 @@
const result = await compareCommits(activeRepoPath, compareFrom, compareTo);
comparison = result;
selectedDiffPath = result.files[0]?.path ?? "";
pendingRestoreFile = null;
compareDialogOpen = true;
});
}
@@ -492,6 +511,7 @@
const result = await diffFileAgainstWorkingTree(activeRepoPath, historyCommit.hash, selectedExplorerPath);
comparison = result;
selectedDiffPath = result.files[0]?.path ?? selectedExplorerPath;
pendingRestoreFile = null;
compareDialogOpen = true;
});
}
@@ -500,6 +520,17 @@
if (comparison) compareDialogOpen = true;
}
function closeCompareDialog() {
compareDialogOpen = false;
pendingRestoreFile = null;
}
async function restorePreviewedCommitFile() {
if (!pendingRestoreFile) return;
const restored = await restoreCommitFile(pendingRestoreFile.commit, pendingRestoreFile.file);
if (restored) closeCompareDialog();
}
function selectDiffFile(file: GitDiffFile) {
selectedDiffPath = file.path;
}
@@ -614,7 +645,7 @@
function submitRepo(event: SubmitEvent) { event.preventDefault(); void openRepo(); }
function handleWindowKeydown(event: KeyboardEvent) {
if (event.key === "Escape" && compareDialogOpen) compareDialogOpen = false;
if (event.key === "Escape" && compareDialogOpen) closeCompareDialog();
else if (event.key === "Escape" && globalSearchOpen) closeGlobalSearchDialog();
}
</script>
@@ -796,7 +827,7 @@
{isBusy}
{expandedCommitHashes}
onRestoreCommit={restoreCommit}
onRestoreCommitFile={restoreCommitFile}
onPreviewCommitFile={previewCommitFileFromHistory}
onToggleCommitFiles={(hash) => {
const next = new Set(expandedCommitHashes);
if (next.has(hash)) next.delete(hash); else next.add(hash);
@@ -823,7 +854,9 @@
{comparison}
{selectedDiffPath}
{isBusy}
onClose={() => { compareDialogOpen = false; }}
restoreLabel={pendingRestoreFile ? "Restore file" : ""}
onClose={closeCompareDialog}
onRestore={restorePreviewedCommitFile}
onSelectFile={selectDiffFile}
/>
{/if}