From 230e2e4107d4b22afcce552788845f73445f935a Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Mon, 10 Mar 2025 00:08:10 -0700 Subject: [PATCH] Restore git panel header (#26354) Let's play around with it. This should not be added to tomorrow's preview. Release Notes: - Git Beta: Added a panel header with an open diff and stage/unstage all buttons. --- crates/git_ui/src/git_panel.rs | 47 ++++++++++++++++++++++++++++++++-- crates/git_ui/src/git_ui.rs | 16 ++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/crates/git_ui/src/git_panel.rs b/crates/git_ui/src/git_panel.rs index b9418af604..4274a17682 100644 --- a/crates/git_ui/src/git_panel.rs +++ b/crates/git_ui/src/git_panel.rs @@ -1,6 +1,7 @@ use crate::askpass_modal::AskPassModal; use crate::commit_modal::CommitModal; use crate::git_panel_settings::StatusStyle; +use crate::project_diff::Diff; use crate::remote_output_toast::{RemoteAction, RemoteOutputToast}; use crate::repository_selector::filtered_repository_entries; use crate::{branch_picker, render_remote_button}; @@ -231,6 +232,7 @@ pub struct GitPanel { fs: Arc, hide_scrollbar_task: Option>, new_count: usize, + entry_count: usize, new_staged_count: usize, pending: Vec, pending_commit: Option>, @@ -381,6 +383,7 @@ impl GitPanel { context_menu: None, workspace, modal_open: false, + entry_count: 0, }; git_panel.schedule_update(false, window, cx); git_panel.show_scrollbar = git_panel.should_show_scrollbar(cx); @@ -1078,7 +1081,7 @@ impl GitPanel { }); } - fn stage_all(&mut self, _: &StageAll, _window: &mut Window, cx: &mut Context) { + pub fn stage_all(&mut self, _: &StageAll, _window: &mut Window, cx: &mut Context) { let entries = self .entries .iter() @@ -1089,7 +1092,7 @@ impl GitPanel { self.change_file_stage(true, entries, cx); } - fn unstage_all(&mut self, _: &UnstageAll, _window: &mut Window, cx: &mut Context) { + pub fn unstage_all(&mut self, _: &UnstageAll, _window: &mut Window, cx: &mut Context) { let entries = self .entries .iter() @@ -2137,10 +2140,12 @@ impl GitPanel { self.tracked_count = 0; self.new_staged_count = 0; self.tracked_staged_count = 0; + self.entry_count = 0; for entry in &self.entries { let Some(status_entry) = entry.status_entry() else { continue; }; + self.entry_count += 1; if repo.has_conflict(&status_entry.repo_path) { self.conflicted_count += 1; if self.entry_staging(status_entry).has_staged() { @@ -2402,6 +2407,43 @@ impl GitPanel { }) } + fn render_panel_header(&self, window: &mut Window, cx: &mut Context) -> impl IntoElement { + let text; + let action; + let tooltip; + if self.total_staged_count() == self.entry_count { + text = "Unstage All"; + action = git::UnstageAll.boxed_clone(); + tooltip = "git reset"; + } else { + text = "Stage All"; + action = git::StageAll.boxed_clone(); + tooltip = "git add --all ." + } + + self.panel_header_container(window, cx) + .child( + Button::new("diff", "Open diff") + .tooltip(Tooltip::for_action_title("Open diff", &Diff)) + .on_click(|_, _, cx| { + cx.defer(|cx| { + cx.dispatch_action(&Diff); + }) + }), + ) + .child(div().flex_grow()) // spacer + .child( + Button::new("stage-unstage-all", text) + .tooltip(Tooltip::for_action_title(tooltip, action.as_ref())) + .on_click(move |_, _, cx| { + let action = action.boxed_clone(); + cx.defer(move |cx| { + cx.dispatch_action(action.as_ref()); + }) + }), + ) + } + pub fn render_footer( &self, window: &mut Window, @@ -3166,6 +3208,7 @@ impl Render for GitPanel { .child( v_flex() .size_full() + .child(self.render_panel_header(window, cx)) .map(|this| { if has_entries { this.child(self.render_entries(has_write_access, window, cx)) diff --git a/crates/git_ui/src/git_ui.rs b/crates/git_ui/src/git_ui.rs index 80ac9c113c..2036deca29 100644 --- a/crates/git_ui/src/git_ui.rs +++ b/crates/git_ui/src/git_ui.rs @@ -64,6 +64,22 @@ pub fn init(cx: &mut App) { panel.pull(window, cx); }); }); + workspace.register_action(|workspace, action: &git::StageAll, window, cx| { + let Some(panel) = workspace.panel::(cx) else { + return; + }; + panel.update(cx, |panel, cx| { + panel.stage_all(action, window, cx); + }); + }); + workspace.register_action(|workspace, action: &git::UnstageAll, window, cx| { + let Some(panel) = workspace.panel::(cx) else { + return; + }; + panel.update(cx, |panel, cx| { + panel.unstage_all(action, window, cx); + }); + }); }) .detach(); }