refactor(app): remove file history panel and related logic
This commit is contained in:
+62
-120
@@ -20,7 +20,6 @@
|
||||
import CredentialDialog from "./lib/components/CredentialDialog.svelte";
|
||||
import DiscardConfirmDialog from "./lib/components/DiscardConfirmDialog.svelte";
|
||||
import ExplorerPanel from "./lib/components/ExplorerPanel.svelte";
|
||||
import FileHistoryPanel from "./lib/components/FileHistoryPanel.svelte";
|
||||
import HistoryPanel from "./lib/components/HistoryPanel.svelte";
|
||||
import NewBranchDialog from "./lib/components/NewBranchDialog.svelte";
|
||||
import RenameBranchDialog from "./lib/components/RenameBranchDialog.svelte";
|
||||
@@ -220,7 +219,6 @@
|
||||
const STASH_PANEL_COLLAPSED_KEY = "gitlite.stashPanelCollapsed.v2";
|
||||
const EXPLORER_PANEL_COLLAPSED_KEY = "gitlite.explorerPanelCollapsed.v1";
|
||||
const HISTORY_ASIDE_WIDTH_KEY = "gitlite.historyAsideWidth.v1";
|
||||
const FILE_HISTORY_WIDTH_KEY = "gitlite.fileHistoryWidth.v1";
|
||||
const COMMIT_PANEL_DEFAULT_HEIGHT = 220;
|
||||
const COMMIT_PANEL_MIN_HEIGHT = COMMIT_PANEL_DEFAULT_HEIGHT;
|
||||
const COMMIT_PANEL_MAX_HEIGHT = 640;
|
||||
@@ -237,9 +235,6 @@
|
||||
const HISTORY_ASIDE_DEFAULT_WIDTH = 620;
|
||||
const HISTORY_ASIDE_MIN_WIDTH = 560;
|
||||
const HISTORY_ASIDE_MAX_WIDTH = 920;
|
||||
const FILE_HISTORY_DEFAULT_WIDTH = 300;
|
||||
const FILE_HISTORY_MIN_WIDTH = 240;
|
||||
const FILE_HISTORY_MAX_WIDTH = 520;
|
||||
const ERROR_AUTO_HIDE_MS = 6000;
|
||||
const COMMIT_HISTORY_PAGE_SIZE = 50;
|
||||
|
||||
@@ -282,6 +277,8 @@
|
||||
let expandedCommitHashes = new Set<string>();
|
||||
let fileHistory: GitCommit[] = [];
|
||||
let fileHistoryLoading = false;
|
||||
let fileHistoryError = "";
|
||||
let fileHistoryDialogOpen = false;
|
||||
let fileHistoryRequestId = 0;
|
||||
let activeFileHistoryRequestId = "";
|
||||
let repoOpenRequestId = 0;
|
||||
@@ -414,11 +411,6 @@
|
||||
let resizingHistoryAside = false;
|
||||
let historyResizeStartX = 0;
|
||||
let historyResizeStartWidth = 0;
|
||||
let fileHistoryWidth = loadFileHistoryWidth();
|
||||
let resizingFileHistory = false;
|
||||
let fileHistoryResizeStartX = 0;
|
||||
let fileHistoryResizeStartWidth = 0;
|
||||
let fileHistoryCollapsed = true;
|
||||
let themeMediaQuery: MediaQueryList | undefined;
|
||||
let appVersion = "";
|
||||
|
||||
@@ -1512,28 +1504,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
function clampFileHistoryWidth(value: number): number {
|
||||
return Math.min(FILE_HISTORY_MAX_WIDTH, Math.max(FILE_HISTORY_MIN_WIDTH, Math.round(value)));
|
||||
}
|
||||
|
||||
function loadFileHistoryWidth(): number {
|
||||
try {
|
||||
const stored = Number(localStorage.getItem(FILE_HISTORY_WIDTH_KEY));
|
||||
if (Number.isFinite(stored) && stored > 0) return clampFileHistoryWidth(stored);
|
||||
} catch {
|
||||
// Fall through to the default below.
|
||||
}
|
||||
return FILE_HISTORY_DEFAULT_WIDTH;
|
||||
}
|
||||
|
||||
function persistFileHistoryWidth(value: number) {
|
||||
try {
|
||||
localStorage.setItem(FILE_HISTORY_WIDTH_KEY, String(value));
|
||||
} catch {
|
||||
// Local storage is best-effort only; resizing must keep working without it.
|
||||
}
|
||||
}
|
||||
|
||||
function startCommitPanelResize(event: PointerEvent) {
|
||||
event.preventDefault();
|
||||
resizingCommitPanel = true;
|
||||
@@ -1715,50 +1685,14 @@
|
||||
persistHistoryAsideWidth(historyAsideWidth);
|
||||
}
|
||||
|
||||
function startFileHistoryResize(event: PointerEvent) {
|
||||
if (fileHistoryCollapsed) return;
|
||||
event.preventDefault();
|
||||
resizingFileHistory = true;
|
||||
fileHistoryResizeStartX = event.clientX;
|
||||
fileHistoryResizeStartWidth = fileHistoryWidth;
|
||||
(event.currentTarget as HTMLElement).setPointerCapture(event.pointerId);
|
||||
}
|
||||
|
||||
function onFileHistoryResizeMove(event: PointerEvent) {
|
||||
if (!resizingFileHistory) return;
|
||||
fileHistoryWidth = clampFileHistoryWidth(fileHistoryResizeStartWidth + (fileHistoryResizeStartX - event.clientX));
|
||||
}
|
||||
|
||||
function endFileHistoryResize(event: PointerEvent) {
|
||||
if (!resizingFileHistory) return;
|
||||
resizingFileHistory = false;
|
||||
persistFileHistoryWidth(fileHistoryWidth);
|
||||
const target = event.currentTarget as HTMLElement;
|
||||
if (target.hasPointerCapture(event.pointerId)) target.releasePointerCapture(event.pointerId);
|
||||
}
|
||||
|
||||
function onFileHistoryResizeKeydown(event: KeyboardEvent) {
|
||||
if (fileHistoryCollapsed || (event.key !== "ArrowLeft" && event.key !== "ArrowRight")) return;
|
||||
event.preventDefault();
|
||||
fileHistoryWidth = clampFileHistoryWidth(fileHistoryWidth + (event.key === "ArrowLeft" ? 20 : -20));
|
||||
persistFileHistoryWidth(fileHistoryWidth);
|
||||
}
|
||||
|
||||
function toggleFileHistoryCollapsed() {
|
||||
fileHistoryCollapsed = !fileHistoryCollapsed;
|
||||
}
|
||||
|
||||
function revealFileHistory() {
|
||||
fileHistoryCollapsed = false;
|
||||
}
|
||||
|
||||
function hideAndResetFileHistory() {
|
||||
fileHistoryRequestId += 1;
|
||||
cancelActiveFileHistoryLoad();
|
||||
activeFileHistoryRequestId = "";
|
||||
fileHistoryLoading = false;
|
||||
fileHistoryError = "";
|
||||
fileHistory = [];
|
||||
fileHistoryCollapsed = true;
|
||||
fileHistoryDialogOpen = false;
|
||||
}
|
||||
|
||||
function rememberRecentRepo(path: string) {
|
||||
@@ -1833,6 +1767,9 @@
|
||||
expandedExplorerPaths = new Set();
|
||||
expandedCommitHashes = new Set();
|
||||
fileHistory = [];
|
||||
fileHistoryLoading = false;
|
||||
fileHistoryError = "";
|
||||
fileHistoryDialogOpen = false;
|
||||
compareFrom = "";
|
||||
compareTo = "";
|
||||
comparison = null;
|
||||
@@ -2004,10 +1941,7 @@
|
||||
if (selectedExplorerPath && !explorerPathExists(repoFiles, selectedExplorerPath)) {
|
||||
selectedExplorerPath = "";
|
||||
selectedExplorerKind = "file";
|
||||
cancelActiveFileHistoryLoad();
|
||||
activeFileHistoryRequestId = "";
|
||||
fileHistoryLoading = false;
|
||||
fileHistory = [];
|
||||
hideAndResetFileHistory();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2016,7 +1950,7 @@
|
||||
await refreshBranchList(path);
|
||||
await refreshTags(path);
|
||||
await refreshCommitHistory(path);
|
||||
if (lastFileHistoryHeadHash !== previousHeadHash && !fileHistoryCollapsed) {
|
||||
if (lastFileHistoryHeadHash !== previousHeadHash && fileHistoryDialogOpen) {
|
||||
await refreshFileHistory(path);
|
||||
}
|
||||
}
|
||||
@@ -2031,7 +1965,9 @@
|
||||
void cancelFileHistory(requestId).catch(() => {});
|
||||
}
|
||||
|
||||
async function refreshFileHistory(path = activeRepoPath, file = selectedExplorerPath) {
|
||||
async function refreshFileHistory(path = activeRepoPath, file = selectedExplorerPath, force = false) {
|
||||
if (!force && !fileHistoryDialogOpen && !globalSearchOpen) return;
|
||||
|
||||
const requestId = ++fileHistoryRequestId;
|
||||
cancelActiveFileHistoryLoad();
|
||||
|
||||
@@ -2045,6 +1981,7 @@
|
||||
const historyRequestId = `file-history-${requestId}-${Date.now()}`;
|
||||
activeFileHistoryRequestId = historyRequestId;
|
||||
fileHistoryLoading = true;
|
||||
fileHistoryError = "";
|
||||
fileHistory = [];
|
||||
|
||||
try {
|
||||
@@ -2056,7 +1993,10 @@
|
||||
const message = errorToMessage(error);
|
||||
if (requestId === fileHistoryRequestId && activeFileHistoryRequestId === historyRequestId) {
|
||||
fileHistory = [];
|
||||
if (!isCancellationMessage(message)) errorMessage = message;
|
||||
if (!isCancellationMessage(message)) {
|
||||
fileHistoryError = message;
|
||||
if (!fileHistoryDialogOpen) errorMessage = message;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (requestId === fileHistoryRequestId && activeFileHistoryRequestId === historyRequestId) {
|
||||
@@ -3718,19 +3658,37 @@
|
||||
return folders;
|
||||
}
|
||||
|
||||
// Loads history for a selected explorer node without blocking the rest of the UI
|
||||
// (isBusy/runOperation would disable every button in the app while this awaits).
|
||||
// A request id guards against a slower, stale request overwriting a newer selection.
|
||||
// Loads history without blocking the rest of the UI. A request id guards
|
||||
// against a slower, stale request overwriting a newer file selection.
|
||||
async function loadSelectedFileHistory(path: string, repo = activeRepoPath) {
|
||||
await refreshFileHistory(repo, path);
|
||||
await refreshFileHistory(repo, path, true);
|
||||
}
|
||||
|
||||
function openFileHistoryDialog(node: ExplorerNode) {
|
||||
if (!activeRepoPath || node.kind !== "file" || !node.tracked) return;
|
||||
selectedExplorerPath = node.path;
|
||||
selectedExplorerKind = "file";
|
||||
fileHistoryDialogOpen = true;
|
||||
fileHistoryError = "";
|
||||
void loadSelectedFileHistory(node.path);
|
||||
trackEvent("file_history_opened", {
|
||||
source: "explorer_context_menu",
|
||||
});
|
||||
}
|
||||
|
||||
function closeFileHistoryDialog() {
|
||||
fileHistoryRequestId += 1;
|
||||
cancelActiveFileHistoryLoad();
|
||||
activeFileHistoryRequestId = "";
|
||||
fileHistoryLoading = false;
|
||||
fileHistoryError = "";
|
||||
fileHistoryDialogOpen = false;
|
||||
}
|
||||
|
||||
async function selectExplorerNode(node: ExplorerNode) {
|
||||
if (!activeRepoPath) return;
|
||||
selectedExplorerPath = node.path;
|
||||
selectedExplorerKind = node.kind;
|
||||
revealFileHistory();
|
||||
void loadSelectedFileHistory(node.path);
|
||||
trackEvent("explorer_node_selected", {
|
||||
kind: node.kind,
|
||||
tracked: node.tracked ? 1 : 0,
|
||||
@@ -3742,7 +3700,6 @@
|
||||
selectedExplorerPath = file.path;
|
||||
selectedExplorerKind = "file";
|
||||
expandedExplorerPaths = new Set([...expandedExplorerPaths, ...explorerParentFolders(file.path)]);
|
||||
revealFileHistory();
|
||||
|
||||
void loadSelectedFileHistory(file.path);
|
||||
trackEvent("explorer_file_selected", {
|
||||
@@ -3767,8 +3724,6 @@
|
||||
if (!activeRepoPath || node.kind !== "file") return;
|
||||
selectedExplorerPath = node.path;
|
||||
selectedExplorerKind = "file";
|
||||
revealFileHistory();
|
||||
void loadSelectedFileHistory(node.path);
|
||||
|
||||
try {
|
||||
await openRepositoryFile(activeRepoPath, node.path);
|
||||
@@ -4012,7 +3967,8 @@
|
||||
helpOpen = false;
|
||||
return;
|
||||
}
|
||||
if (event.key === "Escape" && repoTabContextMenu) closeRepoTabContextMenu();
|
||||
if (event.key === "Escape" && fileHistoryDialogOpen && !isBusy) closeFileHistoryDialog();
|
||||
else if (event.key === "Escape" && repoTabContextMenu) closeRepoTabContextMenu();
|
||||
else if (event.key === "Escape" && pendingDiscard && !isBusy) closeDiscardConfirm();
|
||||
else if (event.key === "Escape" && compareDialogOpen) closeCompareDialog();
|
||||
else if (event.key === "Escape" && newBranchCommit) newBranchCommit = null;
|
||||
@@ -4374,7 +4330,7 @@
|
||||
<section
|
||||
class="workspace"
|
||||
aria-label="Git workspace"
|
||||
style="--left-sidebar-width: {leftSidebarWidth}px; --history-aside-width: {historyAsideWidth}px; --file-history-width: {fileHistoryWidth}px;"
|
||||
style="--left-sidebar-width: {leftSidebarWidth}px; --history-aside-width: {historyAsideWidth}px;"
|
||||
>
|
||||
|
||||
<!-- Left sidebar: branches + explorer -->
|
||||
@@ -4477,6 +4433,7 @@
|
||||
onCollapseAllFolders={collapseAllExplorerFolders}
|
||||
onSelectNode={selectExplorerNode}
|
||||
onOpenFile={openFileFromExplorer}
|
||||
onFileHistory={openFileHistoryDialog}
|
||||
onBlame={openBlame}
|
||||
collapsed={explorerPanelCollapsed}
|
||||
onToggleCollapsed={toggleExplorerPanelCollapsed}
|
||||
@@ -4601,8 +4558,8 @@
|
||||
onkeydown={onHistoryAsideResizeKeydown}
|
||||
></div>
|
||||
|
||||
<!-- Right sidebar: commit graph + file history -->
|
||||
<aside class="history-aside" class:file-history-collapsed={fileHistoryCollapsed} aria-label="Commit history">
|
||||
<!-- Right sidebar: commit graph -->
|
||||
<aside class="history-aside" aria-label="Commit history">
|
||||
<HistoryPanel
|
||||
{commits}
|
||||
{localBranchNames}
|
||||
@@ -4627,36 +4584,6 @@
|
||||
expandedCommitHashes = next;
|
||||
}}
|
||||
/>
|
||||
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
||||
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
|
||||
<div
|
||||
class="file-history-resize-handle"
|
||||
class:resizing={resizingFileHistory}
|
||||
role="separator"
|
||||
aria-orientation="vertical"
|
||||
aria-label="Resize file history width"
|
||||
aria-valuenow={fileHistoryWidth}
|
||||
aria-valuemin={FILE_HISTORY_MIN_WIDTH}
|
||||
aria-valuemax={FILE_HISTORY_MAX_WIDTH}
|
||||
tabindex={fileHistoryCollapsed ? -1 : 0}
|
||||
onpointerdown={startFileHistoryResize}
|
||||
onpointermove={onFileHistoryResizeMove}
|
||||
onpointerup={endFileHistoryResize}
|
||||
onpointercancel={endFileHistoryResize}
|
||||
onkeydown={onFileHistoryResizeKeydown}
|
||||
></div>
|
||||
<FileHistoryPanel
|
||||
{fileHistory}
|
||||
{selectedExplorerPath}
|
||||
selectedExplorerLabel={selectedExplorerPath ? `${selectedExplorerKind === "folder" ? "Folder" : "File"} history` : "File history"}
|
||||
{hasRepository}
|
||||
{isBusy}
|
||||
isLoading={fileHistoryLoading}
|
||||
onDiff={diffSelectedFileFromCommit}
|
||||
onRestore={restoreSelectedFileFromCommit}
|
||||
collapsed={fileHistoryCollapsed}
|
||||
onToggleCollapsed={toggleFileHistoryCollapsed}
|
||||
/>
|
||||
</aside>
|
||||
</section>
|
||||
{/if}
|
||||
@@ -4772,6 +4699,21 @@
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if fileHistoryDialogOpen}
|
||||
{#await import("./lib/components/FileHistoryDialog.svelte") then module}
|
||||
<module.default
|
||||
{fileHistory}
|
||||
filePath={selectedExplorerPath}
|
||||
{isBusy}
|
||||
isLoading={fileHistoryLoading}
|
||||
error={fileHistoryError}
|
||||
onDiff={diffSelectedFileFromCommit}
|
||||
onRestore={restoreSelectedFileFromCommit}
|
||||
onClose={closeFileHistoryDialog}
|
||||
/>
|
||||
{/await}
|
||||
{/if}
|
||||
|
||||
{#if globalSearchOpen}
|
||||
{#await import("./lib/components/GlobalSearchDialog.svelte") then module}
|
||||
<module.default
|
||||
|
||||
@@ -1,177 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { ChevronLeft, ChevronRight, GitCompare, History, RotateCcw } from "@lucide/svelte";
|
||||
import iconUrl from "../../../src-tauri/icons/icon.png";
|
||||
import type { GitCommit } from "../types";
|
||||
|
||||
const commitDateFormatter = new Intl.DateTimeFormat(undefined, {
|
||||
dateStyle: "medium",
|
||||
timeStyle: "short",
|
||||
});
|
||||
|
||||
interface Props {
|
||||
fileHistory: GitCommit[];
|
||||
selectedExplorerPath: string;
|
||||
selectedExplorerLabel: string;
|
||||
hasRepository: boolean;
|
||||
isBusy: boolean;
|
||||
isLoading?: boolean;
|
||||
onDiff: (commit: GitCommit) => void;
|
||||
onRestore: (commit: GitCommit) => void;
|
||||
collapsed?: boolean;
|
||||
onToggleCollapsed?: () => void;
|
||||
}
|
||||
|
||||
let {
|
||||
fileHistory = [],
|
||||
selectedExplorerPath = "",
|
||||
selectedExplorerLabel = "File history",
|
||||
hasRepository = false,
|
||||
isBusy = false,
|
||||
isLoading = false,
|
||||
onDiff = () => {},
|
||||
onRestore = () => {},
|
||||
collapsed = false,
|
||||
onToggleCollapsed = () => {},
|
||||
}: Props = $props();
|
||||
|
||||
function formatCommitDate(value: string): string {
|
||||
const date = new Date(value);
|
||||
if (Number.isNaN(date.getTime())) return value;
|
||||
return commitDateFormatter.format(date);
|
||||
}
|
||||
|
||||
function fileName(path: string): string {
|
||||
return path.split("/").pop() ?? path;
|
||||
}
|
||||
|
||||
function pathTooltip(node: HTMLElement, text: string) {
|
||||
let el: HTMLDivElement | null = null;
|
||||
|
||||
function show(e: MouseEvent) {
|
||||
if (!text || !text.includes("/")) return;
|
||||
el = document.createElement("div");
|
||||
el.className = "path-tooltip";
|
||||
el.textContent = text;
|
||||
document.body.appendChild(el);
|
||||
move(e);
|
||||
}
|
||||
|
||||
function move(e: MouseEvent) {
|
||||
if (!el) return;
|
||||
const tw = el.offsetWidth;
|
||||
const left = Math.max(8, Math.min(e.clientX - tw / 2, window.innerWidth - tw - 8));
|
||||
el.style.left = `${left}px`;
|
||||
el.style.top = `${e.clientY - 44}px`;
|
||||
}
|
||||
|
||||
function hide() {
|
||||
el?.remove();
|
||||
el = null;
|
||||
}
|
||||
|
||||
node.addEventListener("mouseenter", show);
|
||||
node.addEventListener("mousemove", move);
|
||||
node.addEventListener("mouseleave", hide);
|
||||
|
||||
return {
|
||||
update(v: string) { text = v; },
|
||||
destroy() {
|
||||
hide();
|
||||
node.removeEventListener("mouseenter", show);
|
||||
node.removeEventListener("mousemove", move);
|
||||
node.removeEventListener("mouseleave", hide);
|
||||
},
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<section class="panel file-history-panel grid grid-rows-[auto_1fr] overflow-hidden" class:collapsed aria-label="Selected file history">
|
||||
{#if collapsed}
|
||||
<button
|
||||
class="file-history-rail-toggle"
|
||||
type="button"
|
||||
onclick={onToggleCollapsed}
|
||||
aria-expanded={!collapsed}
|
||||
title="Expand file history"
|
||||
aria-label="Expand file history panel"
|
||||
>
|
||||
<ChevronLeft size={16} aria-hidden="true" />
|
||||
<span>File history</span>
|
||||
{#if selectedExplorerPath}
|
||||
<small>{fileHistory.length}</small>
|
||||
{/if}
|
||||
</button>
|
||||
{:else}
|
||||
<div class="section-head file-history-head">
|
||||
<div class="file-history-heading">
|
||||
<span class="eyebrow">{selectedExplorerLabel}</span>
|
||||
<h2
|
||||
class="file-history-name"
|
||||
use:pathTooltip={selectedExplorerPath}
|
||||
>{selectedExplorerPath ? fileName(selectedExplorerPath) : "No file"}</h2>
|
||||
</div>
|
||||
<div class="file-history-head-actions">
|
||||
<span class="pill pill-count file-history-count">{fileHistory.length}</span>
|
||||
<button
|
||||
class="file-history-toggle panel-collapse-toggle"
|
||||
type="button"
|
||||
onclick={onToggleCollapsed}
|
||||
aria-expanded={!collapsed}
|
||||
title="Collapse file history"
|
||||
aria-label="Collapse file history panel"
|
||||
>
|
||||
<ChevronRight size={14} aria-hidden="true" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if !hasRepository}
|
||||
<div class="blank-state">No repository loaded.</div>
|
||||
{:else if !selectedExplorerPath}
|
||||
<div class="blank-state">Select a file in Explorer.</div>
|
||||
{:else if isLoading}
|
||||
<div class="file-history-loading" role="status" aria-live="polite">
|
||||
<div class="file-history-loading-mark" aria-hidden="true">
|
||||
<span class="file-history-loading-halo"></span>
|
||||
<svg class="file-history-loading-traces" viewBox="0 0 120 120">
|
||||
<path class="fhl-trace fhl-trace-main" d="M14 82 C38 60, 48 58, 60 60 S84 66, 106 36" />
|
||||
<path class="fhl-trace fhl-trace-branch" d="M28 36 C52 48, 70 70, 91 94" />
|
||||
</svg>
|
||||
<img src={iconUrl} alt="" class="file-history-loading-icon" />
|
||||
</div>
|
||||
<span class="file-history-loading-label">Loading history…</span>
|
||||
<span class="file-history-loading-bar" aria-hidden="true"><span></span></span>
|
||||
</div>
|
||||
{:else if fileHistory.length === 0}
|
||||
<div class="blank-state">No history returned for this selection.</div>
|
||||
{:else}
|
||||
<div class="history-list overflow-auto p-2">
|
||||
{#each fileHistory as item (item.hash)}
|
||||
<article class="commit-row compact file-history-row">
|
||||
<div class="commit-line">
|
||||
<History size={16} aria-hidden="true" />
|
||||
<div class="commit-line-text">
|
||||
<strong title={item.summary}>{item.summary}</strong>
|
||||
<span>{item.short_hash} - {item.author_name}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="commit-actions file-history-actions">
|
||||
<time datetime={item.date}>{formatCommitDate(item.date)}</time>
|
||||
<div class="commit-action-buttons">
|
||||
<button class="btn-sm" type="button" onclick={() => onDiff(item)} disabled={isBusy} title="Show changes vs working tree">
|
||||
<GitCompare size={15} aria-hidden="true" />
|
||||
Diff
|
||||
</button>
|
||||
<button class="btn-sm" type="button" onclick={() => onRestore(item)} disabled={isBusy} title="Restore selected file from this commit">
|
||||
<RotateCcw size={15} aria-hidden="true" />
|
||||
Restore
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</section>
|
||||
Reference in New Issue
Block a user