agent: Add button to continue iterating once all reviews are done (#28027)

This PR adds a button on the review tab empty state that toggles the
focus back to the agent panel so that users can keep iterating on the
thread that's active in the panel.

<img
src="https://github.com/user-attachments/assets/ace5cf93-8869-49bb-8106-e03a9e3c90f2"
width="700"/>

Release Notes:

- N/A
This commit is contained in:
Danilo Leal 2025-04-03 12:32:02 -03:00 committed by GitHub
parent c674e8d62d
commit 9986a21970
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 36 additions and 12 deletions

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-forward-icon lucide-forward"><polyline points="15 17 20 12 15 7"/><path d="M4 18v-2a4 4 0 0 1 4-4h12"/></svg>

After

Width:  |  Height:  |  Size: 312 B

View file

@ -1,4 +1,4 @@
use crate::{Thread, ThreadEvent};
use crate::{Keep, Reject, Thread, ThreadEvent};
use anyhow::Result;
use buffer_diff::DiffHunkStatus;
use collections::HashSet;
@ -26,6 +26,7 @@ use workspace::{
item::{BreadcrumbText, ItemEvent, TabContentParams},
searchable::SearchableItemHandle,
};
use zed_actions::assistant::ToggleFocus;
pub struct AgentDiff {
multibuffer: Entity<MultiBuffer>,
@ -553,11 +554,12 @@ impl Item for AgentDiff {
}
impl Render for AgentDiff {
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let is_empty = self.multibuffer.read(cx).is_empty();
let focus_handle = &self.focus_handle;
div()
.track_focus(&self.focus_handle)
.track_focus(focus_handle)
.key_context(if is_empty { "EmptyPane" } else { "AgentDiff" })
.on_action(cx.listener(Self::keep))
.on_action(cx.listener(Self::reject))
@ -568,7 +570,32 @@ impl Render for AgentDiff {
.items_center()
.justify_center()
.size_full()
.when(is_empty, |el| el.child("No changes to review"))
.when(is_empty, |el| {
el.child(
v_flex()
.items_center()
.gap_2()
.child("No changes to review")
.child(
Button::new("continue-iterating", "Continue Iterating")
.style(ButtonStyle::Filled)
.icon(IconName::ForwardArrow)
.icon_position(IconPosition::Start)
.icon_size(IconSize::Small)
.icon_color(Color::Muted)
.full_width()
.key_binding(KeyBinding::for_action_in(
&ToggleFocus,
&focus_handle.clone(),
window,
cx,
))
.on_click(|_event, window, cx| {
window.dispatch_action(ToggleFocus.boxed_clone(), cx)
}),
),
)
})
.when(!is_empty, |el| el.child(self.editor.clone()))
}
}
@ -604,7 +631,7 @@ fn render_diff_hunk_controls(
.disabled(is_created_file)
.key_binding(
KeyBinding::for_action_in(
&crate::Reject,
&Reject,
&editor.read(cx).focus_handle(cx),
window,
cx,
@ -625,12 +652,7 @@ fn render_diff_hunk_controls(
}),
Button::new(("keep", row as u64), "Keep")
.key_binding(
KeyBinding::for_action_in(
&crate::Keep,
&editor.read(cx).focus_handle(cx),
window,
cx,
)
KeyBinding::for_action_in(&Keep, &editor.read(cx).focus_handle(cx), window, cx)
.map(|kb| kb.size(rems_from_px(12.))),
)
.on_click({

View file

@ -122,6 +122,7 @@ pub enum IconName {
Font,
FontSize,
FontWeight,
ForwardArrow,
GenericClose,
GenericMaximize,
GenericMinimize,