agent: Refine rules library window design (#31994)
Just polishing up a bit the Rules Library design. I think the most confusing part here was the icon that was being used to tag a rule as default; I've heard feedback more than once saying that was confusing, so I'm now switching to a rather standard star icon, which I'd assume is well-understood as a "favoriting" affordance. Release Notes: - N/A
This commit is contained in:
parent
dea0a58727
commit
e793740168
3 changed files with 195 additions and 206 deletions
|
@ -261,6 +261,7 @@ impl PickerDelegate for RulePickerDelegate {
|
|||
let rule = self.matches.get(ix)?;
|
||||
let default = rule.default;
|
||||
let prompt_id = rule.id;
|
||||
|
||||
let element = ListItem::new(ix)
|
||||
.inset(true)
|
||||
.spacing(ListItemSpacing::Sparse)
|
||||
|
@ -272,9 +273,10 @@ impl PickerDelegate for RulePickerDelegate {
|
|||
.child(Label::new(rule.title.clone().unwrap_or("Untitled".into()))),
|
||||
)
|
||||
.end_slot::<IconButton>(default.then(|| {
|
||||
IconButton::new("toggle-default-rule", IconName::SparkleFilled)
|
||||
IconButton::new("toggle-default-rule", IconName::StarFilled)
|
||||
.toggle_state(true)
|
||||
.icon_color(Color::Accent)
|
||||
.icon_size(IconSize::Small)
|
||||
.shape(IconButtonShape::Square)
|
||||
.tooltip(Tooltip::text("Remove from Default Rules"))
|
||||
.on_click(cx.listener(move |_, _, _, cx| {
|
||||
|
@ -283,7 +285,7 @@ impl PickerDelegate for RulePickerDelegate {
|
|||
}))
|
||||
.end_hover_slot(
|
||||
h_flex()
|
||||
.gap_2()
|
||||
.gap_1()
|
||||
.child(if prompt_id.is_built_in() {
|
||||
div()
|
||||
.id("built-in-rule")
|
||||
|
@ -299,8 +301,9 @@ impl PickerDelegate for RulePickerDelegate {
|
|||
})
|
||||
.into_any()
|
||||
} else {
|
||||
IconButton::new("delete-rule", IconName::Trash)
|
||||
IconButton::new("delete-rule", IconName::TrashAlt)
|
||||
.icon_color(Color::Muted)
|
||||
.icon_size(IconSize::Small)
|
||||
.shape(IconButtonShape::Square)
|
||||
.tooltip(Tooltip::text("Delete Rule"))
|
||||
.on_click(cx.listener(move |_, _, _, cx| {
|
||||
|
@ -309,16 +312,27 @@ impl PickerDelegate for RulePickerDelegate {
|
|||
.into_any_element()
|
||||
})
|
||||
.child(
|
||||
IconButton::new("toggle-default-rule", IconName::Sparkle)
|
||||
IconButton::new("toggle-default-rule", IconName::Star)
|
||||
.toggle_state(default)
|
||||
.selected_icon(IconName::SparkleFilled)
|
||||
.selected_icon(IconName::StarFilled)
|
||||
.icon_color(if default { Color::Accent } else { Color::Muted })
|
||||
.icon_size(IconSize::Small)
|
||||
.shape(IconButtonShape::Square)
|
||||
.tooltip(Tooltip::text(if default {
|
||||
"Remove from Default Rules"
|
||||
} else {
|
||||
"Add to Default Rules"
|
||||
}))
|
||||
.map(|this| {
|
||||
if default {
|
||||
this.tooltip(Tooltip::text("Remove from Default Rules"))
|
||||
} else {
|
||||
this.tooltip(move |window, cx| {
|
||||
Tooltip::with_meta(
|
||||
"Add to Default Rules",
|
||||
None,
|
||||
"Always included in every thread.",
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
}
|
||||
})
|
||||
.on_click(cx.listener(move |_, _, _, cx| {
|
||||
cx.emit(RulePickerEvent::ToggledDefault { prompt_id })
|
||||
})),
|
||||
|
@ -1008,216 +1022,180 @@ impl RulesLibrary {
|
|||
.size_full()
|
||||
.relative()
|
||||
.overflow_hidden()
|
||||
.pl(DynamicSpacing::Base16.rems(cx))
|
||||
.pt(DynamicSpacing::Base08.rems(cx))
|
||||
.on_click(cx.listener(move |_, _, window, _| {
|
||||
window.focus(&focus_handle);
|
||||
}))
|
||||
.child(
|
||||
h_flex()
|
||||
.group("active-editor-header")
|
||||
.pr(DynamicSpacing::Base16.rems(cx))
|
||||
.pt(DynamicSpacing::Base02.rems(cx))
|
||||
.pb(DynamicSpacing::Base08.rems(cx))
|
||||
.pt_2()
|
||||
.px_2p5()
|
||||
.gap_2()
|
||||
.justify_between()
|
||||
.child(
|
||||
h_flex().gap_1().child(
|
||||
div()
|
||||
.max_w_80()
|
||||
.on_action(cx.listener(Self::move_down_from_title))
|
||||
.border_1()
|
||||
.border_color(transparent_black())
|
||||
.rounded_sm()
|
||||
.group_hover("active-editor-header", |this| {
|
||||
this.border_color(
|
||||
cx.theme().colors().border_variant,
|
||||
)
|
||||
})
|
||||
.child(EditorElement::new(
|
||||
&rule_editor.title_editor,
|
||||
EditorStyle {
|
||||
background: cx.theme().system().transparent,
|
||||
local_player: cx.theme().players().local(),
|
||||
text: TextStyle {
|
||||
color: cx
|
||||
.theme()
|
||||
.colors()
|
||||
.editor_foreground,
|
||||
font_family: settings
|
||||
.ui_font
|
||||
.family
|
||||
.clone(),
|
||||
font_features: settings
|
||||
.ui_font
|
||||
.features
|
||||
.clone(),
|
||||
font_size: HeadlineSize::Large
|
||||
.rems()
|
||||
.into(),
|
||||
font_weight: settings.ui_font.weight,
|
||||
line_height: relative(
|
||||
settings.buffer_line_height.value(),
|
||||
),
|
||||
..Default::default()
|
||||
},
|
||||
scrollbar_width: Pixels::ZERO,
|
||||
syntax: cx.theme().syntax().clone(),
|
||||
status: cx.theme().status().clone(),
|
||||
inlay_hints_style:
|
||||
editor::make_inlay_hints_style(cx),
|
||||
inline_completion_styles:
|
||||
editor::make_suggestion_styles(cx),
|
||||
..EditorStyle::default()
|
||||
div()
|
||||
.w_full()
|
||||
.on_action(cx.listener(Self::move_down_from_title))
|
||||
.border_1()
|
||||
.border_color(transparent_black())
|
||||
.rounded_sm()
|
||||
.group_hover("active-editor-header", |this| {
|
||||
this.border_color(cx.theme().colors().border_variant)
|
||||
})
|
||||
.child(EditorElement::new(
|
||||
&rule_editor.title_editor,
|
||||
EditorStyle {
|
||||
background: cx.theme().system().transparent,
|
||||
local_player: cx.theme().players().local(),
|
||||
text: TextStyle {
|
||||
color: cx.theme().colors().editor_foreground,
|
||||
font_family: settings.ui_font.family.clone(),
|
||||
font_features: settings
|
||||
.ui_font
|
||||
.features
|
||||
.clone(),
|
||||
font_size: HeadlineSize::Large.rems().into(),
|
||||
font_weight: settings.ui_font.weight,
|
||||
line_height: relative(
|
||||
settings.buffer_line_height.value(),
|
||||
),
|
||||
..Default::default()
|
||||
},
|
||||
)),
|
||||
),
|
||||
scrollbar_width: Pixels::ZERO,
|
||||
syntax: cx.theme().syntax().clone(),
|
||||
status: cx.theme().status().clone(),
|
||||
inlay_hints_style: editor::make_inlay_hints_style(
|
||||
cx,
|
||||
),
|
||||
inline_completion_styles:
|
||||
editor::make_suggestion_styles(cx),
|
||||
..EditorStyle::default()
|
||||
},
|
||||
)),
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
.h_full()
|
||||
.child(
|
||||
h_flex()
|
||||
.h_full()
|
||||
.gap(DynamicSpacing::Base16.rems(cx))
|
||||
.child(div()),
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
.h_full()
|
||||
.gap(DynamicSpacing::Base16.rems(cx))
|
||||
.children(rule_editor.token_count.map(
|
||||
|token_count| {
|
||||
let token_count: SharedString =
|
||||
token_count.to_string().into();
|
||||
let label_token_count: SharedString =
|
||||
token_count.to_string().into();
|
||||
.flex_shrink_0()
|
||||
.gap(DynamicSpacing::Base04.rems(cx))
|
||||
.children(rule_editor.token_count.map(|token_count| {
|
||||
let token_count: SharedString =
|
||||
token_count.to_string().into();
|
||||
let label_token_count: SharedString =
|
||||
token_count.to_string().into();
|
||||
|
||||
h_flex()
|
||||
.id("token_count")
|
||||
.tooltip(move |window, cx| {
|
||||
let token_count =
|
||||
token_count.clone();
|
||||
|
||||
Tooltip::with_meta(
|
||||
format!(
|
||||
"{} tokens",
|
||||
token_count.clone()
|
||||
),
|
||||
None,
|
||||
format!(
|
||||
"Model: {}",
|
||||
model
|
||||
.as_ref()
|
||||
.map(|model| model
|
||||
.name()
|
||||
.0)
|
||||
.unwrap_or_default()
|
||||
),
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.child(
|
||||
Label::new(format!(
|
||||
"{} tokens",
|
||||
label_token_count.clone()
|
||||
))
|
||||
.color(Color::Muted),
|
||||
)
|
||||
},
|
||||
))
|
||||
.child(if prompt_id.is_built_in() {
|
||||
div()
|
||||
.id("built-in-rule")
|
||||
.child(
|
||||
Icon::new(IconName::FileLock)
|
||||
.color(Color::Muted),
|
||||
)
|
||||
.tooltip(move |window, cx| {
|
||||
Tooltip::with_meta(
|
||||
"Built-in rule",
|
||||
None,
|
||||
BUILT_IN_TOOLTIP_TEXT,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.into_any()
|
||||
} else {
|
||||
IconButton::new("delete-rule", IconName::Trash)
|
||||
.size(ButtonSize::Large)
|
||||
.style(ButtonStyle::Transparent)
|
||||
.shape(IconButtonShape::Square)
|
||||
.size(ButtonSize::Large)
|
||||
.tooltip(move |window, cx| {
|
||||
Tooltip::for_action(
|
||||
"Delete Rule",
|
||||
&DeleteRule,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.on_click(|_, window, cx| {
|
||||
window.dispatch_action(
|
||||
Box::new(DeleteRule),
|
||||
cx,
|
||||
);
|
||||
})
|
||||
.into_any_element()
|
||||
div()
|
||||
.id("token_count")
|
||||
.mr_1()
|
||||
.flex_shrink_0()
|
||||
.tooltip(move |window, cx| {
|
||||
Tooltip::with_meta(
|
||||
"Token Estimation",
|
||||
None,
|
||||
format!(
|
||||
"Model: {}",
|
||||
model
|
||||
.as_ref()
|
||||
.map(|model| model.name().0)
|
||||
.unwrap_or_default()
|
||||
),
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.child(
|
||||
IconButton::new(
|
||||
"duplicate-rule",
|
||||
IconName::BookCopy,
|
||||
)
|
||||
.size(ButtonSize::Large)
|
||||
.style(ButtonStyle::Transparent)
|
||||
.shape(IconButtonShape::Square)
|
||||
.size(ButtonSize::Large)
|
||||
.tooltip(move |window, cx| {
|
||||
Tooltip::for_action(
|
||||
"Duplicate Rule",
|
||||
&DuplicateRule,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.on_click(|_, window, cx| {
|
||||
window.dispatch_action(
|
||||
Box::new(DuplicateRule),
|
||||
cx,
|
||||
);
|
||||
}),
|
||||
)
|
||||
.child(
|
||||
IconButton::new(
|
||||
"toggle-default-rule",
|
||||
IconName::Sparkle,
|
||||
)
|
||||
.style(ButtonStyle::Transparent)
|
||||
.toggle_state(rule_metadata.default)
|
||||
.selected_icon(IconName::SparkleFilled)
|
||||
.icon_color(if rule_metadata.default {
|
||||
Color::Accent
|
||||
} else {
|
||||
Color::Muted
|
||||
})
|
||||
.shape(IconButtonShape::Square)
|
||||
.size(ButtonSize::Large)
|
||||
.tooltip(Tooltip::text(
|
||||
if rule_metadata.default {
|
||||
"Remove from Default Rules"
|
||||
} else {
|
||||
"Add to Default Rules"
|
||||
},
|
||||
Label::new(format!(
|
||||
"{} tokens",
|
||||
label_token_count.clone()
|
||||
))
|
||||
.on_click(|_, window, cx| {
|
||||
window.dispatch_action(
|
||||
Box::new(ToggleDefaultRule),
|
||||
cx,
|
||||
);
|
||||
}),
|
||||
),
|
||||
.color(Color::Muted),
|
||||
)
|
||||
}))
|
||||
.child(if prompt_id.is_built_in() {
|
||||
div()
|
||||
.id("built-in-rule")
|
||||
.child(
|
||||
Icon::new(IconName::FileLock)
|
||||
.color(Color::Muted),
|
||||
)
|
||||
.tooltip(move |window, cx| {
|
||||
Tooltip::with_meta(
|
||||
"Built-in rule",
|
||||
None,
|
||||
BUILT_IN_TOOLTIP_TEXT,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.into_any()
|
||||
} else {
|
||||
IconButton::new("delete-rule", IconName::TrashAlt)
|
||||
.icon_size(IconSize::Small)
|
||||
.tooltip(move |window, cx| {
|
||||
Tooltip::for_action(
|
||||
"Delete Rule",
|
||||
&DeleteRule,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.on_click(|_, window, cx| {
|
||||
window
|
||||
.dispatch_action(Box::new(DeleteRule), cx);
|
||||
})
|
||||
.into_any_element()
|
||||
})
|
||||
.child(
|
||||
IconButton::new("duplicate-rule", IconName::BookCopy)
|
||||
.icon_size(IconSize::Small)
|
||||
.tooltip(move |window, cx| {
|
||||
Tooltip::for_action(
|
||||
"Duplicate Rule",
|
||||
&DuplicateRule,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.on_click(|_, window, cx| {
|
||||
window.dispatch_action(
|
||||
Box::new(DuplicateRule),
|
||||
cx,
|
||||
);
|
||||
}),
|
||||
)
|
||||
.child(
|
||||
IconButton::new("toggle-default-rule", IconName::Star)
|
||||
.icon_size(IconSize::Small)
|
||||
.toggle_state(rule_metadata.default)
|
||||
.selected_icon(IconName::StarFilled)
|
||||
.icon_color(if rule_metadata.default {
|
||||
Color::Accent
|
||||
} else {
|
||||
Color::Muted
|
||||
})
|
||||
.map(|this| {
|
||||
if rule_metadata.default {
|
||||
this.tooltip(Tooltip::text(
|
||||
"Remove from Default Rules",
|
||||
))
|
||||
} else {
|
||||
this.tooltip(move |window, cx| {
|
||||
Tooltip::with_meta(
|
||||
"Add to Default Rules",
|
||||
None,
|
||||
"Always included in every thread.",
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
}
|
||||
})
|
||||
.on_click(|_, window, cx| {
|
||||
window.dispatch_action(
|
||||
Box::new(ToggleDefaultRule),
|
||||
cx,
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
@ -1228,7 +1206,14 @@ impl RulesLibrary {
|
|||
.on_action(cx.listener(Self::move_up_from_body))
|
||||
.flex_grow()
|
||||
.h_full()
|
||||
.child(rule_editor.body_editor.clone()),
|
||||
.child(
|
||||
h_flex()
|
||||
.py_2()
|
||||
.pl_2p5()
|
||||
.h_full()
|
||||
.flex_1()
|
||||
.child(rule_editor.body_editor.clone()),
|
||||
),
|
||||
),
|
||||
)
|
||||
}))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue