assistant2: Adjust empty state layout (#25745)
Going for a different, arguably simpler design for the Assistant 2 empty state here. Also took the opportunity to adjust other elements like the toolbar, message editor, and some items in the configuration page. <img src="https://github.com/user-attachments/assets/03fd1d48-a675-4eac-b694-bbe4eeaf06e9" width="700px"/> Release Notes: - N/A
This commit is contained in:
parent
635b80ed51
commit
5c400dac8d
7 changed files with 189 additions and 139 deletions
|
@ -158,8 +158,16 @@ impl Render for AssistantConfiguration {
|
||||||
.child(
|
.child(
|
||||||
v_flex()
|
v_flex()
|
||||||
.p(DynamicSpacing::Base16.rems(cx))
|
.p(DynamicSpacing::Base16.rems(cx))
|
||||||
.gap_1()
|
.gap_2()
|
||||||
.child(Headline::new("Prompt Library").size(HeadlineSize::Small))
|
.child(
|
||||||
|
v_flex()
|
||||||
|
.gap_0p5()
|
||||||
|
.child(Headline::new("Prompt Library").size(HeadlineSize::Small))
|
||||||
|
.child(
|
||||||
|
Label::new("Create reusable prompts and tag which ones you want sent in every LLM interaction.")
|
||||||
|
.color(Color::Muted),
|
||||||
|
),
|
||||||
|
)
|
||||||
.child(
|
.child(
|
||||||
Button::new("open-prompt-library", "Open Prompt Library")
|
Button::new("open-prompt-library", "Open Prompt Library")
|
||||||
.style(ButtonStyle::Filled)
|
.style(ButtonStyle::Filled)
|
||||||
|
|
|
@ -14,7 +14,7 @@ use client::zed_urls;
|
||||||
use editor::Editor;
|
use editor::Editor;
|
||||||
use fs::Fs;
|
use fs::Fs;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
prelude::*, px, svg, Action, AnyElement, App, AsyncWindowContext, Corner, Entity, EventEmitter,
|
prelude::*, Action, AnyElement, App, AsyncWindowContext, Corner, Entity, EventEmitter,
|
||||||
FocusHandle, Focusable, FontWeight, Pixels, Subscription, Task, UpdateGlobal, WeakEntity,
|
FocusHandle, Focusable, FontWeight, Pixels, Subscription, Task, UpdateGlobal, WeakEntity,
|
||||||
};
|
};
|
||||||
use language::LanguageRegistry;
|
use language::LanguageRegistry;
|
||||||
|
@ -596,7 +596,6 @@ impl AssistantPanel {
|
||||||
|
|
||||||
h_flex()
|
h_flex()
|
||||||
.id("assistant-toolbar")
|
.id("assistant-toolbar")
|
||||||
.px(DynamicSpacing::Base08.rems(cx))
|
|
||||||
.h(Tab::container_height(cx))
|
.h(Tab::container_height(cx))
|
||||||
.flex_none()
|
.flex_none()
|
||||||
.justify_between()
|
.justify_between()
|
||||||
|
@ -604,72 +603,86 @@ impl AssistantPanel {
|
||||||
.bg(cx.theme().colors().tab_bar_background)
|
.bg(cx.theme().colors().tab_bar_background)
|
||||||
.border_b_1()
|
.border_b_1()
|
||||||
.border_color(cx.theme().colors().border)
|
.border_color(cx.theme().colors().border)
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.id("title")
|
||||||
|
.overflow_x_scroll()
|
||||||
|
.px(DynamicSpacing::Base08.rems(cx))
|
||||||
|
.child(Label::new(title).text_ellipsis()),
|
||||||
|
)
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
.w_full()
|
.h_full()
|
||||||
.gap_1()
|
.pl_2()
|
||||||
.justify_between()
|
.gap_2()
|
||||||
.child(Label::new(title))
|
.bg(cx.theme().colors().tab_bar_background)
|
||||||
.children(if matches!(self.active_view, ActiveView::PromptEditor) {
|
.children(if matches!(self.active_view, ActiveView::PromptEditor) {
|
||||||
self.context_editor
|
self.context_editor
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|editor| render_remaining_tokens(editor, cx))
|
.and_then(|editor| render_remaining_tokens(editor, cx))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}),
|
})
|
||||||
)
|
|
||||||
.child(
|
|
||||||
h_flex()
|
|
||||||
.h_full()
|
|
||||||
.pl_1p5()
|
|
||||||
.border_l_1()
|
|
||||||
.border_color(cx.theme().colors().border)
|
|
||||||
.gap(DynamicSpacing::Base02.rems(cx))
|
|
||||||
.child(
|
.child(
|
||||||
PopoverMenu::new("assistant-toolbar-new-popover-menu")
|
h_flex()
|
||||||
.trigger_with_tooltip(
|
.h_full()
|
||||||
IconButton::new("new", IconName::Plus)
|
.px(DynamicSpacing::Base08.rems(cx))
|
||||||
.icon_size(IconSize::Small)
|
.border_l_1()
|
||||||
.style(ButtonStyle::Subtle),
|
.border_color(cx.theme().colors().border)
|
||||||
Tooltip::text("New…"),
|
.gap(DynamicSpacing::Base02.rems(cx))
|
||||||
)
|
.child(
|
||||||
.anchor(Corner::TopRight)
|
PopoverMenu::new("assistant-toolbar-new-popover-menu")
|
||||||
.with_handle(self.new_item_context_menu_handle.clone())
|
.trigger_with_tooltip(
|
||||||
.menu(move |window, cx| {
|
IconButton::new("new", IconName::Plus)
|
||||||
Some(ContextMenu::build(window, cx, |menu, _window, _cx| {
|
.icon_size(IconSize::Small)
|
||||||
menu.action("New Thread", NewThread.boxed_clone())
|
.style(ButtonStyle::Subtle),
|
||||||
.action("New Prompt Editor", NewPromptEditor.boxed_clone())
|
Tooltip::text("New…"),
|
||||||
}))
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.child(
|
|
||||||
IconButton::new("open-history", IconName::HistoryRerun)
|
|
||||||
.icon_size(IconSize::Small)
|
|
||||||
.style(ButtonStyle::Subtle)
|
|
||||||
.tooltip({
|
|
||||||
let focus_handle = self.focus_handle(cx);
|
|
||||||
move |window, cx| {
|
|
||||||
Tooltip::for_action_in(
|
|
||||||
"History",
|
|
||||||
&OpenHistory,
|
|
||||||
&focus_handle,
|
|
||||||
window,
|
|
||||||
cx,
|
|
||||||
)
|
)
|
||||||
}
|
.anchor(Corner::TopRight)
|
||||||
})
|
.with_handle(self.new_item_context_menu_handle.clone())
|
||||||
.on_click(move |_event, window, cx| {
|
.menu(move |window, cx| {
|
||||||
window.dispatch_action(OpenHistory.boxed_clone(), cx);
|
Some(ContextMenu::build(
|
||||||
}),
|
window,
|
||||||
)
|
cx,
|
||||||
.child(
|
|menu, _window, _cx| {
|
||||||
IconButton::new("configure-assistant", IconName::Settings)
|
menu.action("New Thread", NewThread.boxed_clone())
|
||||||
.icon_size(IconSize::Small)
|
.action(
|
||||||
.style(ButtonStyle::Subtle)
|
"New Prompt Editor",
|
||||||
.tooltip(Tooltip::text("Assistant Settings"))
|
NewPromptEditor.boxed_clone(),
|
||||||
.on_click(move |_event, window, cx| {
|
)
|
||||||
window.dispatch_action(OpenConfiguration.boxed_clone(), cx);
|
},
|
||||||
}),
|
))
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
IconButton::new("open-history", IconName::HistoryRerun)
|
||||||
|
.icon_size(IconSize::Small)
|
||||||
|
.style(ButtonStyle::Subtle)
|
||||||
|
.tooltip({
|
||||||
|
let focus_handle = self.focus_handle(cx);
|
||||||
|
move |window, cx| {
|
||||||
|
Tooltip::for_action_in(
|
||||||
|
"History",
|
||||||
|
&OpenHistory,
|
||||||
|
&focus_handle,
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.on_click(move |_event, window, cx| {
|
||||||
|
window.dispatch_action(OpenHistory.boxed_clone(), cx);
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
IconButton::new("configure-assistant", IconName::Settings)
|
||||||
|
.icon_size(IconSize::Small)
|
||||||
|
.style(ButtonStyle::Subtle)
|
||||||
|
.tooltip(Tooltip::text("Assistant Settings"))
|
||||||
|
.on_click(move |_event, window, cx| {
|
||||||
|
window.dispatch_action(OpenConfiguration.boxed_clone(), cx);
|
||||||
|
}),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -711,12 +724,11 @@ impl AssistantPanel {
|
||||||
) -> impl IntoElement {
|
) -> impl IntoElement {
|
||||||
let recent_history = self
|
let recent_history = self
|
||||||
.history_store
|
.history_store
|
||||||
.update(cx, |this, cx| this.recent_entries(3, cx));
|
.update(cx, |this, cx| this.recent_entries(6, cx));
|
||||||
|
|
||||||
let create_welcome_heading = || {
|
let create_welcome_heading = || {
|
||||||
h_flex()
|
h_flex()
|
||||||
.w_full()
|
.w_full()
|
||||||
.justify_center()
|
|
||||||
.child(Headline::new("Welcome to the Assistant Panel").size(HeadlineSize::Small))
|
.child(Headline::new("Welcome to the Assistant Panel").size(HeadlineSize::Small))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -724,36 +736,27 @@ impl AssistantPanel {
|
||||||
let no_error = configuration_error.is_none();
|
let no_error = configuration_error.is_none();
|
||||||
|
|
||||||
v_flex()
|
v_flex()
|
||||||
.gap_2()
|
.p_1p5()
|
||||||
.child(
|
.size_full()
|
||||||
v_flex().w_full().child(
|
.justify_end()
|
||||||
svg()
|
.gap_1()
|
||||||
.path("icons/logo_96.svg")
|
|
||||||
.text_color(cx.theme().colors().text)
|
|
||||||
.w(px(40.))
|
|
||||||
.h(px(40.))
|
|
||||||
.mx_auto()
|
|
||||||
.mb_4(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.map(|parent| {
|
.map(|parent| {
|
||||||
match configuration_error {
|
match configuration_error {
|
||||||
Some(ConfigurationError::ProviderNotAuthenticated)
|
Some(ConfigurationError::ProviderNotAuthenticated)
|
||||||
| Some(ConfigurationError::NoProvider) => {
|
| Some(ConfigurationError::NoProvider) => {
|
||||||
parent.child(
|
parent.child(
|
||||||
v_flex()
|
v_flex()
|
||||||
|
.px_1p5()
|
||||||
.gap_0p5()
|
.gap_0p5()
|
||||||
.child(create_welcome_heading())
|
.child(create_welcome_heading())
|
||||||
.child(
|
.child(
|
||||||
h_flex().mb_2().w_full().justify_center().child(
|
Label::new(
|
||||||
Label::new(
|
"To start using the assistant, configure at least one LLM provider.",
|
||||||
"To start using the assistant, configure at least one LLM provider.",
|
)
|
||||||
)
|
.color(Color::Muted),
|
||||||
.color(Color::Muted),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
h_flex().w_full().justify_center().child(
|
h_flex().mt_1().w_full().child(
|
||||||
Button::new("open-configuration", "Configure a Provider")
|
Button::new("open-configuration", "Configure a Provider")
|
||||||
.size(ButtonSize::Compact)
|
.size(ButtonSize::Compact)
|
||||||
.icon(Some(IconName::Sliders))
|
.icon(Some(IconName::Sliders))
|
||||||
|
@ -767,7 +770,7 @@ impl AssistantPanel {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Some(ConfigurationError::ProviderPendingTermsAcceptance(provider)) => parent
|
Some(ConfigurationError::ProviderPendingTermsAcceptance(provider)) => parent
|
||||||
.child(v_flex().gap_0p5().child(create_welcome_heading()).children(
|
.child(v_flex().px_1p5().gap_0p5().child(create_welcome_heading()).children(
|
||||||
provider.render_accept_terms(
|
provider.render_accept_terms(
|
||||||
LanguageModelProviderTosView::ThreadEmptyState,
|
LanguageModelProviderTosView::ThreadEmptyState,
|
||||||
cx,
|
cx,
|
||||||
|
@ -778,21 +781,40 @@ impl AssistantPanel {
|
||||||
})
|
})
|
||||||
.when(recent_history.is_empty() && no_error, |parent| {
|
.when(recent_history.is_empty() && no_error, |parent| {
|
||||||
parent.child(v_flex().gap_0p5().child(create_welcome_heading()).child(
|
parent.child(v_flex().gap_0p5().child(create_welcome_heading()).child(
|
||||||
h_flex().w_full().justify_center().child(
|
Label::new("Start typing to chat with your codebase").color(Color::Muted),
|
||||||
Label::new("Start typing to chat with your codebase").color(Color::Muted),
|
|
||||||
),
|
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
.when(!recent_history.is_empty(), |parent| {
|
.when(!recent_history.is_empty(), |parent| {
|
||||||
parent
|
parent
|
||||||
.child(
|
.child(
|
||||||
h_flex().w_full().justify_center().child(
|
h_flex()
|
||||||
Label::new("Recent Threads:")
|
.pl_1p5()
|
||||||
.size(LabelSize::Small)
|
.pb_1()
|
||||||
.color(Color::Muted),
|
.w_full()
|
||||||
),
|
.justify_between()
|
||||||
|
.border_b_1()
|
||||||
|
.border_color(cx.theme().colors().border_variant)
|
||||||
|
.child(
|
||||||
|
Label::new("Past Interactions")
|
||||||
|
.size(LabelSize::Small)
|
||||||
|
.color(Color::Muted),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
Button::new("view-history", "View All")
|
||||||
|
.style(ButtonStyle::Subtle)
|
||||||
|
.label_size(LabelSize::Small)
|
||||||
|
.key_binding(KeyBinding::for_action_in(
|
||||||
|
&OpenHistory,
|
||||||
|
&self.focus_handle(cx),
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
))
|
||||||
|
.on_click(move |_event, window, cx| {
|
||||||
|
window.dispatch_action(OpenHistory.boxed_clone(), cx);
|
||||||
|
}),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.child(v_flex().mx_auto().w_4_5().gap_2().children(
|
.child(v_flex().gap_1().children(
|
||||||
recent_history.into_iter().map(|entry| {
|
recent_history.into_iter().map(|entry| {
|
||||||
// TODO: Add keyboard navigation.
|
// TODO: Add keyboard navigation.
|
||||||
match entry {
|
match entry {
|
||||||
|
@ -807,22 +829,6 @@ impl AssistantPanel {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
))
|
))
|
||||||
.child(
|
|
||||||
h_flex().w_full().justify_center().child(
|
|
||||||
Button::new("view-all-past-threads", "View All Past Threads")
|
|
||||||
.style(ButtonStyle::Subtle)
|
|
||||||
.label_size(LabelSize::Small)
|
|
||||||
.key_binding(KeyBinding::for_action_in(
|
|
||||||
&OpenHistory,
|
|
||||||
&self.focus_handle(cx),
|
|
||||||
window,
|
|
||||||
cx,
|
|
||||||
))
|
|
||||||
.on_click(move |_event, window, cx| {
|
|
||||||
window.dispatch_action(OpenHistory.boxed_clone(), cx);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -314,7 +314,7 @@ impl Render for MessageEditor {
|
||||||
.child(self.context_strip.clone())
|
.child(self.context_strip.clone())
|
||||||
.child(
|
.child(
|
||||||
v_flex()
|
v_flex()
|
||||||
.gap_4()
|
.gap_5()
|
||||||
.child({
|
.child({
|
||||||
let settings = ThemeSettings::get_global(cx);
|
let settings = ThemeSettings::get_global(cx);
|
||||||
let text_style = TextStyle {
|
let text_style = TextStyle {
|
||||||
|
|
|
@ -254,18 +254,28 @@ impl RenderOnce for PastThread {
|
||||||
);
|
);
|
||||||
|
|
||||||
ListItem::new(SharedString::from(self.thread.id.to_string()))
|
ListItem::new(SharedString::from(self.thread.id.to_string()))
|
||||||
.outlined()
|
.rounded()
|
||||||
.toggle_state(self.selected)
|
.toggle_state(self.selected)
|
||||||
.start_slot(
|
|
||||||
Icon::new(IconName::MessageCircle)
|
|
||||||
.size(IconSize::Small)
|
|
||||||
.color(Color::Muted),
|
|
||||||
)
|
|
||||||
.spacing(ListItemSpacing::Sparse)
|
.spacing(ListItemSpacing::Sparse)
|
||||||
.child(Label::new(summary).size(LabelSize::Small).text_ellipsis())
|
.start_slot(
|
||||||
|
div()
|
||||||
|
.max_w_4_5()
|
||||||
|
.child(Label::new(summary).size(LabelSize::Small).text_ellipsis()),
|
||||||
|
)
|
||||||
.end_slot(
|
.end_slot(
|
||||||
h_flex()
|
h_flex()
|
||||||
.gap_1p5()
|
.gap_1p5()
|
||||||
|
.child(
|
||||||
|
Label::new("Thread")
|
||||||
|
.color(Color::Muted)
|
||||||
|
.size(LabelSize::XSmall),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.size(px(3.))
|
||||||
|
.rounded_full()
|
||||||
|
.bg(cx.theme().colors().text_disabled),
|
||||||
|
)
|
||||||
.child(
|
.child(
|
||||||
Label::new(thread_timestamp)
|
Label::new(thread_timestamp)
|
||||||
.color(Color::Muted)
|
.color(Color::Muted)
|
||||||
|
@ -340,18 +350,28 @@ impl RenderOnce for PastContext {
|
||||||
ListItem::new(SharedString::from(
|
ListItem::new(SharedString::from(
|
||||||
self.context.path.to_string_lossy().to_string(),
|
self.context.path.to_string_lossy().to_string(),
|
||||||
))
|
))
|
||||||
.outlined()
|
.rounded()
|
||||||
.toggle_state(self.selected)
|
.toggle_state(self.selected)
|
||||||
.start_slot(
|
|
||||||
Icon::new(IconName::Code)
|
|
||||||
.size(IconSize::Small)
|
|
||||||
.color(Color::Muted),
|
|
||||||
)
|
|
||||||
.spacing(ListItemSpacing::Sparse)
|
.spacing(ListItemSpacing::Sparse)
|
||||||
.child(Label::new(summary).size(LabelSize::Small).text_ellipsis())
|
.start_slot(
|
||||||
|
div()
|
||||||
|
.max_w_4_5()
|
||||||
|
.child(Label::new(summary).size(LabelSize::Small).text_ellipsis()),
|
||||||
|
)
|
||||||
.end_slot(
|
.end_slot(
|
||||||
h_flex()
|
h_flex()
|
||||||
.gap_1p5()
|
.gap_1p5()
|
||||||
|
.child(
|
||||||
|
Label::new("Prompt Editor")
|
||||||
|
.color(Color::Muted)
|
||||||
|
.size(LabelSize::XSmall),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.size(px(3.))
|
||||||
|
.rounded_full()
|
||||||
|
.bg(cx.theme().colors().text_disabled),
|
||||||
|
)
|
||||||
.child(
|
.child(
|
||||||
Label::new(context_timestamp)
|
Label::new(context_timestamp)
|
||||||
.color(Color::Muted)
|
.color(Color::Muted)
|
||||||
|
|
|
@ -960,17 +960,30 @@ impl Render for ConfigurationView {
|
||||||
];
|
];
|
||||||
let env_var_set = self.state.read(cx).credentials_from_env;
|
let env_var_set = self.state.read(cx).credentials_from_env;
|
||||||
|
|
||||||
|
let bg_color = cx.theme().colors().editor_background;
|
||||||
|
let border_color = cx.theme().colors().border_variant;
|
||||||
|
let input_base_styles = || {
|
||||||
|
h_flex()
|
||||||
|
.w_full()
|
||||||
|
.px_2()
|
||||||
|
.py_1()
|
||||||
|
.bg(bg_color)
|
||||||
|
.border_1()
|
||||||
|
.border_color(border_color)
|
||||||
|
.rounded_md()
|
||||||
|
};
|
||||||
|
|
||||||
if self.load_credentials_task.is_some() {
|
if self.load_credentials_task.is_some() {
|
||||||
div().child(Label::new("Loading credentials...")).into_any()
|
div().child(Label::new("Loading credentials...")).into_any()
|
||||||
} else if self.should_render_editor(cx) {
|
} else if self.should_render_editor(cx) {
|
||||||
v_flex()
|
v_flex()
|
||||||
.size_full()
|
.size_full()
|
||||||
.on_action(cx.listener(Self::save_credentials))
|
.on_action(cx.listener(ConfigurationView::save_credentials))
|
||||||
.child(Label::new(INSTRUCTIONS[0]))
|
.child(Label::new(INSTRUCTIONS[0]))
|
||||||
.child(h_flex().child(Label::new(INSTRUCTIONS[1])).child(
|
.child(h_flex().child(Label::new(INSTRUCTIONS[1])).child(
|
||||||
Button::new("iam_console", IAM_CONSOLE_URL)
|
Button::new("iam_console", IAM_CONSOLE_URL)
|
||||||
.style(ButtonStyle::Subtle)
|
.style(ButtonStyle::Subtle)
|
||||||
.icon(IconName::ExternalLink)
|
.icon(IconName::ArrowUpRight)
|
||||||
.icon_size(IconSize::XSmall)
|
.icon_size(IconSize::XSmall)
|
||||||
.icon_color(Color::Muted)
|
.icon_color(Color::Muted)
|
||||||
.on_click(move |_, _window, cx| cx.open_url(IAM_CONSOLE_URL))
|
.on_click(move |_, _window, cx| cx.open_url(IAM_CONSOLE_URL))
|
||||||
|
@ -978,11 +991,12 @@ impl Render for ConfigurationView {
|
||||||
)
|
)
|
||||||
.child(Label::new(INSTRUCTIONS[2]))
|
.child(Label::new(INSTRUCTIONS[2]))
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
v_flex()
|
||||||
|
.my_2()
|
||||||
.gap_1()
|
.gap_1()
|
||||||
.child(self.render_aa_id_editor(cx))
|
.child(input_base_styles().child(self.render_aa_id_editor(cx)))
|
||||||
.child(self.render_sk_editor(cx))
|
.child(input_base_styles().child(self.render_sk_editor(cx)))
|
||||||
.child(self.render_region_editor(cx))
|
.child(input_base_styles().child(self.render_region_editor(cx)))
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
Label::new(
|
Label::new(
|
||||||
|
|
|
@ -386,17 +386,10 @@ fn render_accept_terms(
|
||||||
let form = v_flex()
|
let form = v_flex()
|
||||||
.w_full()
|
.w_full()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
.when(
|
|
||||||
view_kind == LanguageModelProviderTosView::ThreadEmptyState,
|
|
||||||
|form| form.items_center(),
|
|
||||||
)
|
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
.flex_wrap()
|
.flex_wrap()
|
||||||
.when(
|
.items_start()
|
||||||
view_kind == LanguageModelProviderTosView::ThreadEmptyState,
|
|
||||||
|form| form.justify_center(),
|
|
||||||
)
|
|
||||||
.child(Label::new(text))
|
.child(Label::new(text))
|
||||||
.child(terms_button),
|
.child(terms_button),
|
||||||
)
|
)
|
||||||
|
@ -416,9 +409,11 @@ fn render_accept_terms(
|
||||||
);
|
);
|
||||||
|
|
||||||
match view_kind {
|
match view_kind {
|
||||||
LanguageModelProviderTosView::ThreadEmptyState => button_container.justify_center(),
|
|
||||||
LanguageModelProviderTosView::PromptEditorPopup => button_container.justify_end(),
|
LanguageModelProviderTosView::PromptEditorPopup => button_container.justify_end(),
|
||||||
LanguageModelProviderTosView::Configuration => button_container.justify_start(),
|
LanguageModelProviderTosView::Configuration
|
||||||
|
| LanguageModelProviderTosView::ThreadEmptyState => {
|
||||||
|
button_container.justify_start()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ pub struct ListItem {
|
||||||
children: SmallVec<[AnyElement; 2]>,
|
children: SmallVec<[AnyElement; 2]>,
|
||||||
selectable: bool,
|
selectable: bool,
|
||||||
outlined: bool,
|
outlined: bool,
|
||||||
|
rounded: bool,
|
||||||
overflow_x: bool,
|
overflow_x: bool,
|
||||||
focused: Option<bool>,
|
focused: Option<bool>,
|
||||||
}
|
}
|
||||||
|
@ -63,6 +64,7 @@ impl ListItem {
|
||||||
children: SmallVec::new(),
|
children: SmallVec::new(),
|
||||||
selectable: true,
|
selectable: true,
|
||||||
outlined: false,
|
outlined: false,
|
||||||
|
rounded: false,
|
||||||
overflow_x: false,
|
overflow_x: false,
|
||||||
focused: None,
|
focused: None,
|
||||||
}
|
}
|
||||||
|
@ -147,6 +149,11 @@ impl ListItem {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn rounded(mut self) -> Self {
|
||||||
|
self.rounded = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn overflow_x(mut self) -> Self {
|
pub fn overflow_x(mut self) -> Self {
|
||||||
self.overflow_x = true;
|
self.overflow_x = true;
|
||||||
self
|
self
|
||||||
|
@ -210,13 +217,13 @@ impl RenderOnce for ListItem {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
.when(self.rounded, |this| this.rounded_md())
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
.id("inner_list_item")
|
.id("inner_list_item")
|
||||||
.group("list_item")
|
.group("list_item")
|
||||||
.w_full()
|
.w_full()
|
||||||
.relative()
|
.relative()
|
||||||
.items_center()
|
|
||||||
.gap_1()
|
.gap_1()
|
||||||
.px(DynamicSpacing::Base06.rems(cx))
|
.px(DynamicSpacing::Base06.rems(cx))
|
||||||
.map(|this| match self.spacing {
|
.map(|this| match self.spacing {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue