Branch menu UI and remote branch checkout
Add UI improvements and switching state for branch menu and implement remote-branch-aware checkout logic. Frontend: add CSS for disabled branch items, compact branch name layout, subtitles and messages; show switching indicator and disable branch actions while switching; display local/remote names and remote subtitles; surface branch switch errors and in-progress messages. Add state.branches.switchingTo and update event handlers to set/clear it. Backend (tauri): extend LocalRepoBranch with is_remote, remote_name, local_name; add git_ref_exists helper; enhance checkout_branch to detect local vs remote refs and automatically checkout or create tracking branches for remotes; parse refs to include remote branches (skip ones with existing local counterparts) and sort branches with current/local/remote order. Minor formatting tweaks.
This commit is contained in:
+31
-8
@@ -254,6 +254,7 @@ function currentRepositoryName() {
|
||||
}
|
||||
|
||||
function currentBranchName() {
|
||||
if (getState().sync.isDetached) return "Detached HEAD";
|
||||
return getState().workingTree.branch || getState().viewer.branch || defaultBranchName;
|
||||
}
|
||||
|
||||
@@ -543,10 +544,23 @@ function diffTemplate(diffResult) {
|
||||
return `<div class="diff-preview diff-preview-inline">${renderDiff(diffResult.diff || "")}</div>`;
|
||||
}
|
||||
|
||||
function branchOptionTemplate(branch) {
|
||||
return `<button class="branch-menu-item ${branch.current ? "active" : ""}" data-branch-name="${escapeHtml(branch.name)}" type="button">
|
||||
<span>${escapeHtml(branch.name)}</span>
|
||||
${branch.current ? `<span class="branch-current-mark">Current</span>` : ""}
|
||||
function branchDisplayName(branch) {
|
||||
return branch.localName || branch.name;
|
||||
}
|
||||
|
||||
function branchOptionTemplate(branch, switchingTo = "") {
|
||||
const displayName = branchDisplayName(branch);
|
||||
const isSwitching = switchingTo === branch.name || switchingTo === displayName;
|
||||
const status = isSwitching ? "Switching..." : branch.current ? "Current" : branch.isRemote ? (branch.remoteName || "Remote") : "";
|
||||
const title = branch.isRemote
|
||||
? `Checkout ${displayName} as a local branch tracking ${branch.name}`
|
||||
: `Checkout ${displayName}`;
|
||||
return `<button class="branch-menu-item ${branch.current ? "active" : ""}" data-branch-name="${escapeHtml(branch.name)}" type="button" title="${escapeHtml(title)}" ${switchingTo ? "disabled" : ""}>
|
||||
<span class="branch-menu-name">
|
||||
<span>${escapeHtml(displayName)}</span>
|
||||
${branch.isRemote ? `<span class="branch-menu-subtitle">Remote: ${escapeHtml(branch.name)}</span>` : ""}
|
||||
</span>
|
||||
${status ? `<span class="branch-current-mark">${escapeHtml(status)}</span>` : ""}
|
||||
</button>`;
|
||||
}
|
||||
|
||||
@@ -1413,7 +1427,7 @@ function dashboardView() {
|
||||
</span>
|
||||
</button>
|
||||
<div class="gd-branch-wrap">
|
||||
<button id="branch-menu-btn" class="gd-toolbar-cell gd-branch-toolbar" type="button" ${!hasLocalRepo || state.branches.loading ? "disabled" : ""} title="${escapeHtml(displayBranchName)}">
|
||||
<button id="branch-menu-btn" class="gd-toolbar-cell gd-branch-toolbar" type="button" ${!hasLocalRepo || state.branches.loading || state.branches.switchingTo ? "disabled" : ""} title="${escapeHtml(displayBranchName)}">
|
||||
<span class="gd-cell-icon">${BRANCH_ICON}</span>
|
||||
<span class="gd-cell-copy">
|
||||
<span class="gd-cell-label">Current branch</span>
|
||||
@@ -1424,11 +1438,13 @@ function dashboardView() {
|
||||
${state.branches.menuOpen ? `<div class="branch-menu">
|
||||
<div class="branch-menu-section">
|
||||
<div class="branch-menu-label">Switch Branch</div>
|
||||
${(state.branches.items.length ? state.branches.items : [{ name: displayBranchName, current: true }]).map(branchOptionTemplate).join("")}
|
||||
${state.branches.error ? `<div class="branch-menu-message danger-subtle">${escapeHtml(state.branches.error)}</div>` : ""}
|
||||
${state.branches.switchingTo ? `<div class="branch-menu-message">Switching to ${escapeHtml(state.branches.switchingTo)}...</div>` : ""}
|
||||
${(state.branches.items.length ? state.branches.items : [{ name: displayBranchName, localName: displayBranchName, current: true }]).map((branch) => branchOptionTemplate(branch, state.branches.switchingTo)).join("")}
|
||||
</div>
|
||||
<div class="branch-menu-section">
|
||||
<button class="branch-menu-action" data-branch-action="create" type="button">Create new branch…</button>
|
||||
<button class="branch-menu-action" data-branch-action="rename" data-branch-name="${escapeHtml(displayBranchName)}" type="button" ${!displayBranchName ? "disabled" : ""}>Rename current branch…</button>
|
||||
<button class="branch-menu-action" data-branch-action="rename" data-branch-name="${escapeHtml(displayBranchName)}" type="button" ${!displayBranchName || state.sync.isDetached ? "disabled" : ""}>Rename current branch…</button>
|
||||
<button class="branch-menu-action danger-subtle" data-branch-action="delete" type="button">Delete branch…</button>
|
||||
</div>
|
||||
</div>` : ""}
|
||||
@@ -2599,15 +2615,22 @@ function bindDashboardEvents() {
|
||||
render();
|
||||
return;
|
||||
}
|
||||
const selectedBranch = state.branches.items.find((item) => item.name === branch);
|
||||
const displayName = selectedBranch ? branchDisplayName(selectedBranch) : branch;
|
||||
state.branches.switchingTo = displayName;
|
||||
render();
|
||||
try {
|
||||
const result = await checkoutBranch(state.selectedRepoPath, branch, selectedGitPath());
|
||||
gitOutput = `${result.command}\n\n${result.stdout || "Branch switched."}\n${result.stderr || ""}`;
|
||||
gitOutput = `${result.command}\n\n${result.stdout || `Switched to ${displayName}.`}\n${result.stderr || ""}`;
|
||||
state.branches.menuOpen = false;
|
||||
await refreshRepoData();
|
||||
} catch (error) {
|
||||
gitOutput = `Branch switch failed: ${errorMessage(error)}`;
|
||||
state.branches.menuOpen = false;
|
||||
render();
|
||||
} finally {
|
||||
state.branches.switchingTo = "";
|
||||
render();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -57,6 +57,7 @@ const state = {
|
||||
items: [],
|
||||
createName: "",
|
||||
menuOpen: false,
|
||||
switchingTo: "",
|
||||
dialog: {
|
||||
mode: "",
|
||||
target: "",
|
||||
|
||||
Reference in New Issue
Block a user