assistant: Refine workflow step labels (#16161)
https://github.com/user-attachments/assets/f6325507-091a-482e-ac28-dd09877ebaa2 Release Notes: - N/A --------- Co-authored-by: Danilo <daniloleal09@gmail.com>
This commit is contained in:
parent
82529499df
commit
0dbecee03f
5 changed files with 101 additions and 73 deletions
|
@ -1 +0,0 @@
|
||||||
<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-text-search"><path d="M21 6H3"/><path d="M10 12H3"/><path d="M10 18H3"/><circle cx="17" cy="15" r="3"/><path d="m21 19-1.9-1.9"/></svg>
|
|
Before Width: | Height: | Size: 338 B |
|
@ -365,7 +365,8 @@ impl AssistantPanel {
|
||||||
pane.set_should_display_tab_bar(|_| true);
|
pane.set_should_display_tab_bar(|_| true);
|
||||||
pane.set_render_tab_bar_buttons(cx, move |pane, cx| {
|
pane.set_render_tab_bar_buttons(cx, move |pane, cx| {
|
||||||
let focus_handle = pane.focus_handle(cx);
|
let focus_handle = pane.focus_handle(cx);
|
||||||
let left_children = IconButton::new("history", IconName::TextSearch)
|
let left_children = IconButton::new("history", IconName::HistoryRerun)
|
||||||
|
.icon_size(IconSize::Small)
|
||||||
.on_click(cx.listener({
|
.on_click(cx.listener({
|
||||||
let focus_handle = focus_handle.clone();
|
let focus_handle = focus_handle.clone();
|
||||||
move |_, _, cx| {
|
move |_, _, cx| {
|
||||||
|
@ -377,7 +378,7 @@ impl AssistantPanel {
|
||||||
cx.new_view(|cx| {
|
cx.new_view(|cx| {
|
||||||
let keybind =
|
let keybind =
|
||||||
KeyBinding::for_action_in(&DeployHistory, &focus_handle, cx);
|
KeyBinding::for_action_in(&DeployHistory, &focus_handle, cx);
|
||||||
Tooltip::new("History").key_binding(keybind)
|
Tooltip::new("Open History").key_binding(keybind)
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
|
@ -1458,12 +1459,14 @@ impl WorkflowStepStatus {
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
match self {
|
match self {
|
||||||
WorkflowStepStatus::Resolving => Icon::new(IconName::ArrowCircle)
|
WorkflowStepStatus::Resolving => Label::new("Resolving")
|
||||||
.size(IconSize::Small)
|
.size(LabelSize::Small)
|
||||||
.with_animation(
|
.with_animation(
|
||||||
("resolving-suggestion-label", id),
|
("resolving-suggestion-animation", id),
|
||||||
Animation::new(Duration::from_secs(2)).repeat(),
|
Animation::new(Duration::from_secs(2))
|
||||||
|icon, delta| icon.transform(Transformation::rotate(percentage(delta))),
|
.repeat()
|
||||||
|
.with_easing(pulsating_between(0.2, 1.0)),
|
||||||
|
|label, delta| label.alpha(delta),
|
||||||
)
|
)
|
||||||
.into_any_element(),
|
.into_any_element(),
|
||||||
|
|
||||||
|
@ -1539,51 +1542,61 @@ impl WorkflowStepStatus {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into_any_element(),
|
.into_any_element(),
|
||||||
WorkflowStepStatus::Pending => Button::new(("stop-transformation", id), "Stop")
|
WorkflowStepStatus::Pending => h_flex()
|
||||||
.icon(IconName::Stop)
|
.items_center()
|
||||||
.icon_position(IconPosition::Start)
|
.gap_2()
|
||||||
.icon_size(IconSize::Small)
|
.child(
|
||||||
.label_size(LabelSize::Small)
|
Label::new("Applying...")
|
||||||
.style(ButtonStyle::Tinted(TintColor::Negative))
|
.size(LabelSize::Small)
|
||||||
.tooltip({
|
.with_animation(
|
||||||
let step_range = step_range.clone();
|
("applying-step-transformation-label", id),
|
||||||
let editor = editor.clone();
|
Animation::new(Duration::from_secs(2))
|
||||||
move |cx| {
|
.repeat()
|
||||||
cx.new_view(|cx| {
|
.with_easing(pulsating_between(0.2, 1.0)),
|
||||||
let tooltip = Tooltip::new("Stop Transformation");
|
|label, delta| label.alpha(delta),
|
||||||
if display_keybind_in_tooltip(&step_range, &editor, cx) {
|
),
|
||||||
tooltip.key_binding(KeyBinding::for_action_in(
|
)
|
||||||
&editor::actions::Cancel,
|
.child(
|
||||||
&focus_handle,
|
IconButton::new(("stop-transformation", id), IconName::Stop)
|
||||||
cx,
|
.icon_size(IconSize::Small)
|
||||||
))
|
.style(ButtonStyle::Tinted(TintColor::Negative))
|
||||||
} else {
|
.tooltip({
|
||||||
tooltip
|
let step_range = step_range.clone();
|
||||||
|
let editor = editor.clone();
|
||||||
|
move |cx| {
|
||||||
|
cx.new_view(|cx| {
|
||||||
|
let tooltip = Tooltip::new("Stop Transformation");
|
||||||
|
if display_keybind_in_tooltip(&step_range, &editor, cx) {
|
||||||
|
tooltip.key_binding(KeyBinding::for_action_in(
|
||||||
|
&editor::actions::Cancel,
|
||||||
|
&focus_handle,
|
||||||
|
cx,
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
tooltip
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into()
|
.on_click({
|
||||||
}
|
let editor = editor.clone();
|
||||||
})
|
let step_range = step_range.clone();
|
||||||
.on_click({
|
move |_, cx| {
|
||||||
let editor = editor.clone();
|
editor
|
||||||
let step_range = step_range.clone();
|
.update(cx, |this, cx| {
|
||||||
move |_, cx| {
|
this.stop_workflow_step(step_range.clone(), cx)
|
||||||
editor
|
})
|
||||||
.update(cx, |this, cx| {
|
.ok();
|
||||||
this.stop_workflow_step(step_range.clone(), cx)
|
}
|
||||||
})
|
}),
|
||||||
.ok();
|
)
|
||||||
}
|
|
||||||
})
|
|
||||||
.into_any_element(),
|
.into_any_element(),
|
||||||
WorkflowStepStatus::Done => h_flex()
|
WorkflowStepStatus::Done => h_flex()
|
||||||
.gap_1()
|
.gap_1()
|
||||||
.child(
|
.child(
|
||||||
Button::new(("stop-transformation", id), "Reject")
|
IconButton::new(("stop-transformation", id), IconName::Close)
|
||||||
.icon(IconName::Close)
|
|
||||||
.icon_position(IconPosition::Start)
|
|
||||||
.icon_size(IconSize::Small)
|
.icon_size(IconSize::Small)
|
||||||
.label_size(LabelSize::Small)
|
|
||||||
.style(ButtonStyle::Tinted(TintColor::Negative))
|
.style(ButtonStyle::Tinted(TintColor::Negative))
|
||||||
.tooltip({
|
.tooltip({
|
||||||
let focus_handle = focus_handle.clone();
|
let focus_handle = focus_handle.clone();
|
||||||
|
@ -1664,7 +1677,6 @@ impl WorkflowStepStatus {
|
||||||
.icon_position(IconPosition::Start)
|
.icon_position(IconPosition::Start)
|
||||||
.icon_size(IconSize::Small)
|
.icon_size(IconSize::Small)
|
||||||
.label_size(LabelSize::Small)
|
.label_size(LabelSize::Small)
|
||||||
.tooltip(|cx| Tooltip::text("Undo Transformation", cx))
|
|
||||||
.on_click({
|
.on_click({
|
||||||
let editor = editor.clone();
|
let editor = editor.clone();
|
||||||
let step_range = step_range.clone();
|
let step_range = step_range.clone();
|
||||||
|
@ -2519,6 +2531,17 @@ impl ContextEditor {
|
||||||
} else {
|
} else {
|
||||||
theme.info_border
|
theme.info_border
|
||||||
};
|
};
|
||||||
|
let step_index = weak_self.update(&mut **cx, |this, cx| {
|
||||||
|
let snapshot = this.editor.read(cx).buffer().read(cx).as_singleton()?.read(cx).text_snapshot();
|
||||||
|
let start_offset = step_range.start.to_offset(&snapshot);
|
||||||
|
let parent_message = this.context.read(cx).messages_for_offsets([start_offset], cx);
|
||||||
|
debug_assert_eq!(parent_message.len(), 1);
|
||||||
|
let parent_message = parent_message.first()?;
|
||||||
|
|
||||||
|
let index_of_current_step = this.workflow_steps.keys().filter(|workflow_step_range| workflow_step_range.start.cmp(&parent_message.anchor, &snapshot).is_ge() && workflow_step_range.end.cmp(&step_range.end, &snapshot).is_le()).count();
|
||||||
|
Some(index_of_current_step)
|
||||||
|
}).ok().flatten();
|
||||||
|
|
||||||
let debug_header = weak_self
|
let debug_header = weak_self
|
||||||
.update(&mut **cx, |this, _| {
|
.update(&mut **cx, |this, _| {
|
||||||
if let Some(inspector) = this.debug_inspector.as_mut() {
|
if let Some(inspector) = this.debug_inspector.as_mut() {
|
||||||
|
@ -2528,6 +2551,17 @@ impl ContextEditor {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
let step_label = if let Some(index) = step_index {
|
||||||
|
|
||||||
|
Label::new(format!("Step {index}")).size(LabelSize::Small)
|
||||||
|
} else {
|
||||||
|
Label::new("Step").size(LabelSize::Small)
|
||||||
|
};
|
||||||
|
let step_label = if current_status.as_ref().is_some_and(|status| status.is_confirmed()) {
|
||||||
|
h_flex().items_center().gap_2().child(step_label.strikethrough(true).color(Color::Muted)).child(Icon::new(IconName::Check).size(IconSize::Small).color(Color::Created))
|
||||||
|
} else {
|
||||||
|
div().child(step_label)
|
||||||
|
};
|
||||||
div()
|
div()
|
||||||
.w_full()
|
.w_full()
|
||||||
.px(cx.gutter_dimensions.full_width())
|
.px(cx.gutter_dimensions.full_width())
|
||||||
|
@ -2536,11 +2570,12 @@ impl ContextEditor {
|
||||||
.w_full()
|
.w_full()
|
||||||
.border_b_1()
|
.border_b_1()
|
||||||
.border_color(border_color)
|
.border_color(border_color)
|
||||||
.pb_1()
|
.pb_1p5()
|
||||||
.justify_between()
|
.justify_between()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
.children(debug_header.map(|is_active| {
|
.child(h_flex().justify_start().gap_2().child(step_label).children(
|
||||||
h_flex().justify_start().child(
|
debug_header.map(|is_active| {
|
||||||
|
|
||||||
Button::new("debug-workflows-toggle", "Debug")
|
Button::new("debug-workflows-toggle", "Debug")
|
||||||
.icon_color(Color::Hidden)
|
.icon_color(Color::Hidden)
|
||||||
.color(Color::Hidden)
|
.color(Color::Hidden)
|
||||||
|
@ -2571,10 +2606,10 @@ impl ContextEditor {
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
}),
|
})
|
||||||
)
|
})
|
||||||
// .child(h_flex().w_full())
|
|
||||||
}))
|
))
|
||||||
.children(current_status.as_ref().map(|status| {
|
.children(current_status.as_ref().map(|status| {
|
||||||
h_flex().w_full().justify_end().child(
|
h_flex().w_full().justify_end().child(
|
||||||
status.into_element(
|
status.into_element(
|
||||||
|
@ -2618,9 +2653,7 @@ impl ContextEditor {
|
||||||
div()
|
div()
|
||||||
.w_full()
|
.w_full()
|
||||||
.px(cx.gutter_dimensions.full_width())
|
.px(cx.gutter_dimensions.full_width())
|
||||||
.child(
|
.child(h_flex().h(px(1.)).bg(border_color))
|
||||||
h_flex().w_full().border_t_1().border_color(border_color),
|
|
||||||
)
|
|
||||||
.into_any()
|
.into_any()
|
||||||
}),
|
}),
|
||||||
disposition: BlockDisposition::Below,
|
disposition: BlockDisposition::Below,
|
||||||
|
|
|
@ -1252,7 +1252,10 @@ impl Context {
|
||||||
|
|
||||||
if let Some(step_end_index) = line.find("</step>") {
|
if let Some(step_end_index) = line.find("</step>") {
|
||||||
if in_step {
|
if in_step {
|
||||||
let step_open_tag_end_ix = step_open_tag_start_ix + "<step>".len();
|
let mut step_open_tag_end_ix = step_open_tag_start_ix + "<step>".len();
|
||||||
|
if buffer.chars_at(step_open_tag_end_ix).next() == Some('\n') {
|
||||||
|
step_open_tag_end_ix += 1;
|
||||||
|
}
|
||||||
let mut step_end_tag_start_ix = line_start_offset + step_end_index;
|
let mut step_end_tag_start_ix = line_start_offset + step_end_index;
|
||||||
let step_end_tag_end_ix = step_end_tag_start_ix + "</step>".len();
|
let step_end_tag_end_ix = step_end_tag_start_ix + "</step>".len();
|
||||||
if buffer.reversed_chars_at(step_end_tag_start_ix).next() == Some('\n') {
|
if buffer.reversed_chars_at(step_end_tag_start_ix).next() == Some('\n') {
|
||||||
|
@ -3098,12 +3101,12 @@ mod tests {
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
Point::new(response_start_row + 2, 0)
|
Point::new(response_start_row + 2, 0)
|
||||||
..Point::new(response_start_row + 13, 3),
|
..Point::new(response_start_row + 12, 3),
|
||||||
WorkflowStepTestStatus::Pending
|
WorkflowStepTestStatus::Pending
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
Point::new(response_start_row + 15, 0)
|
Point::new(response_start_row + 14, 0)
|
||||||
..Point::new(response_start_row + 26, 3),
|
..Point::new(response_start_row + 24, 3),
|
||||||
WorkflowStepTestStatus::Pending
|
WorkflowStepTestStatus::Pending
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
@ -3135,12 +3138,12 @@ mod tests {
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
Point::new(response_start_row + 2, 0)
|
Point::new(response_start_row + 2, 0)
|
||||||
..Point::new(response_start_row + 13, 3),
|
..Point::new(response_start_row + 12, 3),
|
||||||
WorkflowStepTestStatus::Resolved
|
WorkflowStepTestStatus::Resolved
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
Point::new(response_start_row + 15, 0)
|
Point::new(response_start_row + 14, 0)
|
||||||
..Point::new(response_start_row + 26, 3),
|
..Point::new(response_start_row + 24, 3),
|
||||||
WorkflowStepTestStatus::Pending
|
WorkflowStepTestStatus::Pending
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -8,7 +8,7 @@ use editor::{
|
||||||
use gpui::{AppContext, Model, View};
|
use gpui::{AppContext, Model, View};
|
||||||
use text::{ToOffset, ToPoint};
|
use text::{ToOffset, ToPoint};
|
||||||
use ui::{
|
use ui::{
|
||||||
div, h_flex, Color, Element as _, ParentElement as _, Styled, ViewContext, WindowContext,
|
div, h_flex, px, Color, Element as _, ParentElement as _, Styled, ViewContext, WindowContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Context, ResolvedWorkflowStep, WorkflowSuggestion};
|
use crate::{Context, ResolvedWorkflowStep, WorkflowSuggestion};
|
||||||
|
@ -109,12 +109,7 @@ impl ContextInspector {
|
||||||
div()
|
div()
|
||||||
.w_full()
|
.w_full()
|
||||||
.px(cx.gutter_dimensions.full_width())
|
.px(cx.gutter_dimensions.full_width())
|
||||||
.child(
|
.child(h_flex().h(px(1.)).bg(Color::Warning.color(cx)))
|
||||||
h_flex()
|
|
||||||
.w_full()
|
|
||||||
.border_t_1()
|
|
||||||
.border_color(Color::Warning.color(cx)),
|
|
||||||
)
|
|
||||||
.into_any()
|
.into_any()
|
||||||
}),
|
}),
|
||||||
disposition: BlockDisposition::Below,
|
disposition: BlockDisposition::Below,
|
||||||
|
|
|
@ -254,7 +254,6 @@ pub enum IconName {
|
||||||
Tab,
|
Tab,
|
||||||
Terminal,
|
Terminal,
|
||||||
TextCursor,
|
TextCursor,
|
||||||
TextSearch,
|
|
||||||
Trash,
|
Trash,
|
||||||
TriangleRight,
|
TriangleRight,
|
||||||
Undo,
|
Undo,
|
||||||
|
@ -418,7 +417,6 @@ impl IconName {
|
||||||
IconName::Tab => "icons/tab.svg",
|
IconName::Tab => "icons/tab.svg",
|
||||||
IconName::Terminal => "icons/terminal.svg",
|
IconName::Terminal => "icons/terminal.svg",
|
||||||
IconName::TextCursor => "icons/text-cursor.svg",
|
IconName::TextCursor => "icons/text-cursor.svg",
|
||||||
IconName::TextSearch => "icons/text-search.svg",
|
|
||||||
IconName::Trash => "icons/trash.svg",
|
IconName::Trash => "icons/trash.svg",
|
||||||
IconName::TriangleRight => "icons/triangle_right.svg",
|
IconName::TriangleRight => "icons/triangle_right.svg",
|
||||||
IconName::Update => "icons/update.svg",
|
IconName::Update => "icons/update.svg",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue