uodate
This commit is contained in:
1 parent
e5e293085b
commit
7a9a6779b0
14 files changed
+577
-397
No files matched your search
@@ -360,8 +360,10 @@ impl Render for AppRoot {
|
||||
.flex_col()
|
||||
.child(
|
||||
div()
|
||||
.px_8()
|
||||
.py_5()
|
||||
.px_6()
|
||||
.h(px(56.0))
|
||||
.flex()
|
||||
.items_center()
|
||||
.border_b_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::shell_header())
|
||||
@@ -370,41 +372,25 @@ impl Render for AppRoot {
|
||||
.flex()
|
||||
.items_center()
|
||||
.justify_between()
|
||||
.w_full()
|
||||
.child(
|
||||
div()
|
||||
.child(
|
||||
div()
|
||||
.text_3xl()
|
||||
.text_color(theme::text_primary())
|
||||
.child(self.state.section.label()),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.text_sm()
|
||||
.text_color(theme::text_muted())
|
||||
.child(header),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.text_sm()
|
||||
.text_color(theme::text_subtle())
|
||||
.child(self.state.status_line.clone().unwrap_or_else(|| {
|
||||
"Native Rust shell is reading the shared local profile."
|
||||
.to_string()
|
||||
})),
|
||||
),
|
||||
.text_size(px(14.0))
|
||||
.font_weight(gpui::FontWeight::MEDIUM)
|
||||
.text_color(theme::text_primary())
|
||||
.child(self.state.section.label()),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.px_4()
|
||||
.py_3()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
.text_sm()
|
||||
.text_size(px(14.0))
|
||||
.text_color(theme::text_secondary())
|
||||
.child("Show console"),
|
||||
.child(header),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -34,7 +34,7 @@ impl AppRoot {
|
||||
fn render_pending_approval_list(&self, cx: &mut Context<Self>) -> impl IntoElement + '_ {
|
||||
let pending = pending_approvals(&self.snapshot).collect::<Vec<_>>();
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
@@ -103,7 +103,7 @@ impl AppRoot {
|
||||
cx: &mut Context<Self>,
|
||||
) -> impl IntoElement + '_ {
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
@@ -126,7 +126,7 @@ impl AppRoot {
|
||||
.child(
|
||||
div()
|
||||
.mt(px(10.0))
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_inset_border())
|
||||
.bg(theme::panel_inset())
|
||||
@@ -140,7 +140,7 @@ impl AppRoot {
|
||||
inner.child(
|
||||
div()
|
||||
.mt(px(12.0))
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
@@ -275,7 +275,7 @@ fn render_review_groups_panel(groups: &ReviewGroups<'_>) -> impl IntoElement {
|
||||
let has_rows =
|
||||
!(groups.board.is_empty() && groups.user.is_empty() && groups.manager.is_empty());
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
@@ -337,7 +337,7 @@ fn review_group_section<'a>(
|
||||
div()
|
||||
.w(px(28.0))
|
||||
.h(px(28.0))
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.bg(theme::panel_muted()),
|
||||
)
|
||||
.child(
|
||||
|
||||
@@ -41,7 +41,7 @@ impl AppRoot {
|
||||
selected: Option<&domain::Document>,
|
||||
) -> impl IntoElement + '_ {
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
@@ -117,7 +117,7 @@ impl AppRoot {
|
||||
selected: Option<&domain::Document>,
|
||||
) -> impl IntoElement + '_ {
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
@@ -146,7 +146,7 @@ impl AppRoot {
|
||||
.child(
|
||||
div()
|
||||
.mt(px(16.0))
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_inset_border())
|
||||
.bg(theme::panel_inset())
|
||||
@@ -209,7 +209,7 @@ fn document_section_label(label: &'static str) -> impl IntoElement {
|
||||
|
||||
fn render_work_products<'a>(products: &'a [&'a domain::ArtifactRecord]) -> impl IntoElement + 'a {
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
|
||||
@@ -186,7 +186,7 @@ impl InboxRow {
|
||||
.flex()
|
||||
.gap_3()
|
||||
.items_center()
|
||||
.child(div().w(px(36.0)).h(px(36.0)).rounded_lg().bg(tile_bg))
|
||||
.child(div().w(px(36.0)).h(px(36.0)).rounded(px(0.0)).bg(tile_bg))
|
||||
.child(
|
||||
div()
|
||||
.flex_1()
|
||||
|
||||
@@ -37,7 +37,6 @@ impl AppRoot {
|
||||
|
||||
div()
|
||||
.flex()
|
||||
.gap_3()
|
||||
.child(render_message_sidebar(
|
||||
&channel_groups,
|
||||
selected_channel.as_deref(),
|
||||
@@ -47,10 +46,8 @@ impl AppRoot {
|
||||
.child(
|
||||
div()
|
||||
.flex_1()
|
||||
.border_1()
|
||||
.rounded_md()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
.flex_col()
|
||||
.bg(theme::card())
|
||||
.child(render_message_header(
|
||||
self,
|
||||
selected_channel.as_deref(),
|
||||
@@ -61,8 +58,9 @@ impl AppRoot {
|
||||
div()
|
||||
.id("messages-stream")
|
||||
.flex_1()
|
||||
.p_4()
|
||||
.overflow_scroll()
|
||||
.px(px(8.0))
|
||||
.py(px(12.0))
|
||||
.when(visible_messages.is_empty(), |container| {
|
||||
container.child(selected_message_card(None))
|
||||
})
|
||||
@@ -77,7 +75,7 @@ impl AppRoot {
|
||||
message.id
|
||||
)))
|
||||
.cursor_pointer()
|
||||
.hover(|style| style.bg(theme::panel_hover()))
|
||||
.hover(|style| style.bg(theme::muted()))
|
||||
.on_click(cx.listener(move |this, _, _, cx| {
|
||||
this.state.selected_message_id =
|
||||
Some(message_id.clone());
|
||||
@@ -225,101 +223,131 @@ fn render_message_sidebar<'a>(
|
||||
cx: &'a mut Context<AppRoot>,
|
||||
) -> impl IntoElement + 'a {
|
||||
div()
|
||||
.w(px(292.0))
|
||||
.p_3()
|
||||
.gap_3()
|
||||
.border_1()
|
||||
.rounded_md()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::sidebar_bg())
|
||||
.children(groups.iter().map(|group| {
|
||||
.w(px(260.0))
|
||||
.flex_col()
|
||||
.overflow_hidden()
|
||||
.border_r_1()
|
||||
.border_color(theme::border())
|
||||
.bg(theme::card())
|
||||
.child(
|
||||
div()
|
||||
.gap_2()
|
||||
.child(message_section_label(group.label))
|
||||
.children(group.rows.iter().map(|channel| {
|
||||
let active = active_channel == Some(channel.key.as_str());
|
||||
let next_message_id = channel
|
||||
.rows
|
||||
.first()
|
||||
.cloned()
|
||||
.or_else(|| selected_message_id.clone())
|
||||
.unwrap_or_default();
|
||||
.id("message-sidebar-scroll")
|
||||
.flex_1()
|
||||
.overflow_scroll()
|
||||
.px(px(8.0))
|
||||
.py(px(12.0))
|
||||
.children(groups.iter().map(|group| {
|
||||
div()
|
||||
.id(SharedString::from(format!(
|
||||
"message-channel-{}",
|
||||
channel.key
|
||||
)))
|
||||
.cursor_pointer()
|
||||
.hover(|style| style.bg(theme::panel_hover()))
|
||||
.bg(if active {
|
||||
theme::selection_fill()
|
||||
} else {
|
||||
theme::panel()
|
||||
})
|
||||
.rounded_md()
|
||||
.px_3()
|
||||
.py_2()
|
||||
.on_click(cx.listener(move |this, _, _, cx| {
|
||||
if !next_message_id.is_empty() {
|
||||
this.state.selected_message_id = Some(next_message_id.clone());
|
||||
}
|
||||
cx.notify();
|
||||
}))
|
||||
.child(
|
||||
.mb_3()
|
||||
.child(message_section_label(group.label))
|
||||
.children(group.rows.iter().map(|channel| {
|
||||
let active = active_channel == Some(channel.key.as_str());
|
||||
let next_message_id = channel
|
||||
.rows
|
||||
.first()
|
||||
.cloned()
|
||||
.or_else(|| selected_message_id.clone())
|
||||
.unwrap_or_default();
|
||||
div()
|
||||
.flex()
|
||||
.items_center()
|
||||
.gap_3()
|
||||
.id(SharedString::from(format!(
|
||||
"message-channel-{}",
|
||||
channel.key
|
||||
)))
|
||||
.cursor_pointer()
|
||||
.hover(|style| {
|
||||
if active {
|
||||
style
|
||||
} else {
|
||||
style.bg(theme::muted())
|
||||
}
|
||||
})
|
||||
.bg(if active {
|
||||
theme::accent()
|
||||
} else {
|
||||
theme::card()
|
||||
})
|
||||
.px(px(12.0))
|
||||
.py(px(8.0))
|
||||
.on_click(cx.listener(move |this, _, _, cx| {
|
||||
if !next_message_id.is_empty() {
|
||||
this.state.selected_message_id = Some(next_message_id.clone());
|
||||
}
|
||||
cx.notify();
|
||||
}))
|
||||
.child(
|
||||
div()
|
||||
.w(px(28.0))
|
||||
.h(px(28.0))
|
||||
.rounded_md()
|
||||
.bg(theme::panel_muted()),
|
||||
.flex()
|
||||
.items_center()
|
||||
.gap(px(10.0))
|
||||
.child(
|
||||
div()
|
||||
.w(px(28.0))
|
||||
.h(px(28.0))
|
||||
.flex()
|
||||
.items_center()
|
||||
.justify_center()
|
||||
.rounded(px(0.0))
|
||||
.bg(theme::muted()),
|
||||
)
|
||||
.child(
|
||||
div().flex_1().child(
|
||||
div()
|
||||
.text_size(px(13.0))
|
||||
.font_weight(if active || channel.count > 0 {
|
||||
gpui::FontWeight::SEMIBOLD
|
||||
} else {
|
||||
gpui::FontWeight::MEDIUM
|
||||
})
|
||||
.text_color(if active || channel.count > 0 {
|
||||
theme::foreground()
|
||||
} else {
|
||||
theme::muted_foreground()
|
||||
})
|
||||
.truncate()
|
||||
.child(channel.label.clone()),
|
||||
),
|
||||
)
|
||||
.when(channel.urgent, |container| {
|
||||
container.child(
|
||||
div()
|
||||
.w(px(8.0))
|
||||
.h(px(8.0))
|
||||
.rounded_full()
|
||||
.bg(theme::destructive()),
|
||||
)
|
||||
})
|
||||
.when(channel.count > 0, |container| {
|
||||
container.child(
|
||||
div()
|
||||
.h(px(18.0))
|
||||
.min_w(px(18.0))
|
||||
.flex()
|
||||
.items_center()
|
||||
.justify_center()
|
||||
.rounded_full()
|
||||
.bg(theme::primary())
|
||||
.px(px(4.0))
|
||||
.text_size(px(10.0))
|
||||
.font_weight(gpui::FontWeight::BOLD)
|
||||
.text_color(theme::primary_foreground())
|
||||
.child(channel.count.to_string()),
|
||||
)
|
||||
}),
|
||||
)
|
||||
.child(
|
||||
div().flex_1().child(
|
||||
div()
|
||||
.text_sm()
|
||||
.text_color(if active {
|
||||
theme::sidebar_text_active()
|
||||
} else {
|
||||
theme::text_secondary()
|
||||
})
|
||||
.truncate()
|
||||
.child(channel.label.clone()),
|
||||
),
|
||||
)
|
||||
.when(channel.urgent, |container| {
|
||||
container.child(
|
||||
div()
|
||||
.w(px(8.0))
|
||||
.h(px(8.0))
|
||||
.rounded_full()
|
||||
.bg(theme::danger()),
|
||||
)
|
||||
})
|
||||
.when(channel.count > 0, |container| {
|
||||
container.child(
|
||||
div()
|
||||
.px_2()
|
||||
.py_1()
|
||||
.rounded_full()
|
||||
.bg(theme::primary_action())
|
||||
.text_xs()
|
||||
.text_color(theme::primary_action_text())
|
||||
.child(channel.count.to_string()),
|
||||
)
|
||||
}),
|
||||
)
|
||||
}))
|
||||
}))
|
||||
}))
|
||||
})),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.flex()
|
||||
.justify_between()
|
||||
.text_xs()
|
||||
.text_color(theme::text_muted())
|
||||
.items_center()
|
||||
.px(px(16.0))
|
||||
.py(px(8.0))
|
||||
.border_t_1()
|
||||
.border_color(theme::border())
|
||||
.text_size(px(11.0))
|
||||
.text_color(theme::muted_foreground())
|
||||
.child(format!(
|
||||
"{} channels",
|
||||
groups.iter().map(|group| group.rows.len()).sum::<usize>()
|
||||
@@ -338,23 +366,25 @@ fn render_message_header(
|
||||
.flex()
|
||||
.justify_between()
|
||||
.items_center()
|
||||
.px_5()
|
||||
.py_4()
|
||||
.px(px(16.0))
|
||||
.py(px(10.0))
|
||||
.border_b_1()
|
||||
.border_color(theme::panel_border())
|
||||
.border_color(theme::border())
|
||||
.bg(theme::card())
|
||||
.child(
|
||||
div()
|
||||
.child(
|
||||
div()
|
||||
.text_lg()
|
||||
.text_color(theme::text_primary())
|
||||
.text_size(px(13.0))
|
||||
.font_weight(gpui::FontWeight::SEMIBOLD)
|
||||
.text_color(theme::foreground())
|
||||
.child(active_channel.unwrap_or("Select a channel").to_string()),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.mt(px(4.0))
|
||||
.text_sm()
|
||||
.text_color(theme::text_muted())
|
||||
.text_size(px(11.0))
|
||||
.text_color(theme::muted_foreground())
|
||||
.child(format!("{} visible messages", visible_count)),
|
||||
),
|
||||
)
|
||||
@@ -374,11 +404,11 @@ fn render_message_composer<'a>(
|
||||
cx: &'a mut Context<AppRoot>,
|
||||
) -> impl IntoElement + 'a {
|
||||
div()
|
||||
.px_4()
|
||||
.py_3()
|
||||
.px(px(16.0))
|
||||
.py(px(12.0))
|
||||
.border_t_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
.border_color(theme::border())
|
||||
.bg(theme::card())
|
||||
.child(
|
||||
div()
|
||||
.flex()
|
||||
@@ -390,10 +420,10 @@ fn render_message_composer<'a>(
|
||||
div()
|
||||
.mt(px(12.0))
|
||||
.p_3()
|
||||
.rounded_lg()
|
||||
.bg(theme::panel_inset())
|
||||
.rounded(px(0.0))
|
||||
.bg(theme::muted())
|
||||
.border_1()
|
||||
.border_color(theme::panel_inset_border())
|
||||
.border_color(theme::border())
|
||||
.child(root.message_input.clone()),
|
||||
)
|
||||
.child(
|
||||
@@ -404,8 +434,8 @@ fn render_message_composer<'a>(
|
||||
.items_center()
|
||||
.child(
|
||||
div()
|
||||
.text_xs()
|
||||
.text_color(theme::text_muted())
|
||||
.text_size(px(11.0))
|
||||
.text_color(theme::muted_foreground())
|
||||
.child("Reply, mention, or route an operational update."),
|
||||
)
|
||||
.child(
|
||||
@@ -426,14 +456,15 @@ fn render_message_inspector(selected: Option<&domain::AgentMessage>) -> impl Int
|
||||
div()
|
||||
.w(px(320.0))
|
||||
.border_1()
|
||||
.rounded_lg()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
.p_5()
|
||||
.rounded(px(0.0))
|
||||
.border_color(theme::border())
|
||||
.bg(theme::card())
|
||||
.p(px(20.0))
|
||||
.child(
|
||||
div()
|
||||
.text_lg()
|
||||
.text_color(theme::text_primary())
|
||||
.text_size(px(13.0))
|
||||
.font_weight(gpui::FontWeight::SEMIBOLD)
|
||||
.text_color(theme::foreground())
|
||||
.child("Conversation details"),
|
||||
)
|
||||
.child(selected_message_card(selected))
|
||||
@@ -445,26 +476,27 @@ fn render_message_inspector(selected: Option<&domain::AgentMessage>) -> impl Int
|
||||
fn message_filter_toggle(unread_only: bool, cx: &mut Context<AppRoot>) -> impl IntoElement {
|
||||
div()
|
||||
.id("message-filter-toggle")
|
||||
.px_3()
|
||||
.py_2()
|
||||
.px(px(10.0))
|
||||
.py(px(6.0))
|
||||
.rounded_full()
|
||||
.cursor_pointer()
|
||||
.bg(if unread_only {
|
||||
theme::primary_action()
|
||||
theme::primary()
|
||||
} else {
|
||||
theme::panel_muted()
|
||||
theme::muted()
|
||||
})
|
||||
.text_xs()
|
||||
.text_size(px(11.0))
|
||||
.font_weight(gpui::FontWeight::MEDIUM)
|
||||
.text_color(if unread_only {
|
||||
theme::primary_action_text()
|
||||
theme::primary_foreground()
|
||||
} else {
|
||||
theme::text_secondary()
|
||||
theme::muted_foreground()
|
||||
})
|
||||
.hover(|style| {
|
||||
style.bg(if unread_only {
|
||||
theme::primary_action_hover()
|
||||
theme::primary()
|
||||
} else {
|
||||
theme::panel_hover()
|
||||
theme::muted()
|
||||
})
|
||||
})
|
||||
.on_click(cx.listener(move |this, _, _, cx| {
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
use super::*;
|
||||
|
||||
pub(super) fn message_section_label(label: &'static str) -> impl IntoElement {
|
||||
div().text_xs().text_color(theme::text_muted()).child(label)
|
||||
div()
|
||||
.text_size(px(11.0))
|
||||
.font_weight(gpui::FontWeight::SEMIBOLD)
|
||||
.text_color(theme::muted_foreground())
|
||||
.mb(px(4.0))
|
||||
.px(px(8.0))
|
||||
.child(label)
|
||||
}
|
||||
|
||||
pub(super) fn selected_message_card(message: Option<&domain::AgentMessage>) -> impl IntoElement {
|
||||
@@ -14,30 +20,31 @@ pub(super) fn selected_message_card(message: Option<&domain::AgentMessage>) -> i
|
||||
});
|
||||
div()
|
||||
.p_4()
|
||||
.rounded_md()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
.border_color(theme::border())
|
||||
.bg(theme::card())
|
||||
.child(message_header(message, false))
|
||||
.child(
|
||||
div()
|
||||
.mt(px(16.0))
|
||||
.text_lg()
|
||||
.text_color(theme::text_primary())
|
||||
.text_size(px(14.0))
|
||||
.font_weight(gpui::FontWeight::SEMIBOLD)
|
||||
.text_color(theme::foreground())
|
||||
.child(subject),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.mt(px(12.0))
|
||||
.text_base()
|
||||
.text_color(theme::text_secondary())
|
||||
.text_size(px(14.0))
|
||||
.text_color(theme::muted_foreground())
|
||||
.child(body),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.mt(px(16.0))
|
||||
.text_sm()
|
||||
.text_color(theme::text_muted())
|
||||
.text_size(px(14.0))
|
||||
.text_color(theme::muted_foreground())
|
||||
.child("↩ Reply"),
|
||||
)
|
||||
}
|
||||
@@ -45,24 +52,25 @@ pub(super) fn selected_message_card(message: Option<&domain::AgentMessage>) -> i
|
||||
pub(super) fn compact_message_card(message: &domain::AgentMessage) -> impl IntoElement {
|
||||
div()
|
||||
.mt(px(16.0))
|
||||
.p_5()
|
||||
.rounded_lg()
|
||||
.p(px(12.0))
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
.border_color(theme::border())
|
||||
.bg(theme::card())
|
||||
.child(message_header(Some(message), true))
|
||||
.child(
|
||||
div()
|
||||
.mt(px(12.0))
|
||||
.text_base()
|
||||
.text_color(theme::text_primary())
|
||||
.text_size(px(14.0))
|
||||
.font_weight(gpui::FontWeight::SEMIBOLD)
|
||||
.text_color(theme::foreground())
|
||||
.child(message.subject.clone()),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.mt(px(8.0))
|
||||
.text_sm()
|
||||
.text_color(theme::text_muted())
|
||||
.text_size(px(14.0))
|
||||
.text_color(theme::muted_foreground())
|
||||
.line_clamp(2)
|
||||
.child(message.body.clone()),
|
||||
)
|
||||
@@ -82,62 +90,75 @@ fn message_header(message: Option<&domain::AgentMessage>, urgent: bool) -> impl
|
||||
.gap_3()
|
||||
.child(
|
||||
div()
|
||||
.w(px(40.0))
|
||||
.h(px(40.0))
|
||||
.w(px(36.0))
|
||||
.h(px(36.0))
|
||||
.rounded_full()
|
||||
.bg(theme::accent_orange_soft())
|
||||
.bg(theme::accent())
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.text_color(theme::accent_orange())
|
||||
.border_color(theme::border())
|
||||
.text_color(theme::foreground())
|
||||
.flex()
|
||||
.items_center()
|
||||
.justify_center()
|
||||
.text_size(px(14.0))
|
||||
.font_weight(gpui::FontWeight::MEDIUM)
|
||||
.child(sender.to_string()),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.flex()
|
||||
.flex_1()
|
||||
.gap_2()
|
||||
.items_center()
|
||||
.child(
|
||||
div().text_sm().text_color(theme::accent_orange()).child(
|
||||
message
|
||||
.map(|item| item.sender_kind.clone())
|
||||
.unwrap_or_else(|| "human".to_string()),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
div().text_sm().text_color(theme::text_muted()).child(
|
||||
message
|
||||
.map(|item| item.channel.clone())
|
||||
.unwrap_or_else(|| "company".to_string()),
|
||||
),
|
||||
div()
|
||||
.text_size(px(14.0))
|
||||
.font_weight(gpui::FontWeight::MEDIUM)
|
||||
.text_color(theme::foreground())
|
||||
.child(
|
||||
message
|
||||
.map(|item| item.sender_kind.clone())
|
||||
.unwrap_or_else(|| "human".to_string()),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.px_2()
|
||||
.py_1()
|
||||
.text_size(px(12.0))
|
||||
.text_color(theme::muted_foreground())
|
||||
.child(
|
||||
message
|
||||
.map(|item| item.channel.clone())
|
||||
.unwrap_or_else(|| "company".to_string()),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.px(px(8.0))
|
||||
.py(px(2.0))
|
||||
.rounded_full()
|
||||
.bg(theme::accent_orange_soft())
|
||||
.text_xs()
|
||||
.text_color(theme::accent_orange())
|
||||
.bg(theme::primary())
|
||||
.text_size(px(10.0))
|
||||
.font_weight(gpui::FontWeight::MEDIUM)
|
||||
.text_color(theme::primary_foreground())
|
||||
.child("OPERATIONS"),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.text_sm()
|
||||
.text_color(theme::text_muted())
|
||||
.flex_1()
|
||||
.text_size(px(12.0))
|
||||
.text_color(theme::muted_foreground())
|
||||
.child(timestamp),
|
||||
)
|
||||
.when(urgent, |container| {
|
||||
container.child(
|
||||
div()
|
||||
.px_2()
|
||||
.py_1()
|
||||
.px(px(8.0))
|
||||
.py(px(2.0))
|
||||
.rounded_full()
|
||||
.bg(theme::danger_bg())
|
||||
.text_xs()
|
||||
.text_color(theme::danger())
|
||||
.bg(theme::destructive())
|
||||
.text_size(px(10.0))
|
||||
.font_weight(gpui::FontWeight::MEDIUM)
|
||||
.text_color(theme::primary_foreground())
|
||||
.child("URGENT"),
|
||||
)
|
||||
}),
|
||||
@@ -156,28 +177,29 @@ fn trim_sender(sender: &str) -> &str {
|
||||
|
||||
pub(super) fn composer_chip(label: &str) -> impl IntoElement {
|
||||
div()
|
||||
.px_4()
|
||||
.py_3()
|
||||
.rounded_lg()
|
||||
.px(px(12.0))
|
||||
.py(px(6.0))
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
.text_sm()
|
||||
.text_color(theme::text_secondary())
|
||||
.border_color(theme::border())
|
||||
.bg(theme::muted())
|
||||
.text_size(px(12.0))
|
||||
.font_weight(gpui::FontWeight::MEDIUM)
|
||||
.text_color(theme::muted_foreground())
|
||||
.child(label.to_string())
|
||||
}
|
||||
|
||||
pub(super) fn composer_subject(message: Option<&domain::AgentMessage>) -> impl IntoElement {
|
||||
div()
|
||||
.flex_1()
|
||||
.px_4()
|
||||
.py_3()
|
||||
.rounded_lg()
|
||||
.px(px(12.0))
|
||||
.py(px(6.0))
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
.text_sm()
|
||||
.text_color(theme::text_subtle())
|
||||
.border_color(theme::border())
|
||||
.bg(theme::card())
|
||||
.text_size(px(14.0))
|
||||
.text_color(theme::muted_foreground())
|
||||
.child(
|
||||
message
|
||||
.map(|item| item.subject.clone())
|
||||
|
||||
@@ -193,7 +193,7 @@ impl AppRoot {
|
||||
))
|
||||
.child(
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel_inset())
|
||||
@@ -255,7 +255,7 @@ impl AppRoot {
|
||||
))
|
||||
.child(
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel_inset())
|
||||
@@ -383,7 +383,7 @@ impl AppRoot {
|
||||
))
|
||||
.child(
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel_inset())
|
||||
@@ -443,7 +443,7 @@ impl AppRoot {
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel_inset())
|
||||
@@ -484,7 +484,7 @@ impl AppRoot {
|
||||
.child(self.onboarding_goal_detail_input.clone())
|
||||
.child(
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel_inset())
|
||||
@@ -830,7 +830,7 @@ fn step_connector(active: bool) -> impl IntoElement {
|
||||
|
||||
fn onboarding_metric_row(label: &'static str, value: String) -> impl IntoElement {
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel_inset())
|
||||
@@ -892,7 +892,7 @@ fn onboarding_card() -> gpui::Div {
|
||||
div()
|
||||
.w_full()
|
||||
.p_8()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
@@ -1018,7 +1018,7 @@ fn summary_tile(label: &'static str, value: String) -> impl IntoElement {
|
||||
div()
|
||||
.min_h(px(92.0))
|
||||
.p_5()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_inset_border())
|
||||
.bg(theme::panel_inset())
|
||||
|
||||
@@ -209,33 +209,59 @@ impl AppRoot {
|
||||
}
|
||||
|
||||
fn recovery_banner(runs: &[&domain::Run]) -> impl IntoElement {
|
||||
let danger_30 = gpui::Hsla { a: 0.3, ..theme::danger() };
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::danger())
|
||||
.bg(theme::danger_bg())
|
||||
.p_4()
|
||||
.gap_3()
|
||||
.child(div().text_sm().text_color(theme::danger()).child(format!(
|
||||
"{} interrupted task(s) detected from the previous session",
|
||||
runs.len()
|
||||
)))
|
||||
.border_color(danger_30)
|
||||
.bg(theme::warning_bg())
|
||||
.px_4()
|
||||
.py_4()
|
||||
.mb_4()
|
||||
.child(
|
||||
div()
|
||||
.flex()
|
||||
.gap_2()
|
||||
.items_center()
|
||||
.child(
|
||||
div()
|
||||
.w(px(16.0))
|
||||
.h(px(16.0))
|
||||
.rounded(px(4.0))
|
||||
.bg(theme::danger())
|
||||
.flex()
|
||||
.items_center()
|
||||
.justify_center()
|
||||
.child(div().w(px(10.0)).h(px(10.0)).rounded_full().bg(theme::panel())),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.text_size(px(13.0))
|
||||
.font_weight(gpui::FontWeight::MEDIUM)
|
||||
.text_color(theme::text_primary())
|
||||
.child(format!(
|
||||
"{} interrupted task(s) detected from the previous session",
|
||||
runs.len()
|
||||
)),
|
||||
),
|
||||
)
|
||||
.children(runs.iter().map(|run| {
|
||||
div()
|
||||
.rounded_md()
|
||||
.mt(px(8.0))
|
||||
.rounded(px(4.0))
|
||||
.bg(theme::panel())
|
||||
.px_4()
|
||||
.py_3()
|
||||
.child(
|
||||
div()
|
||||
.text_sm()
|
||||
.text_size(px(13.0))
|
||||
.text_color(theme::text_primary())
|
||||
.child(overview_run_title_from_run(run)),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.mt(px(4.0))
|
||||
.text_xs()
|
||||
.text_size(px(11.0))
|
||||
.text_color(theme::text_muted())
|
||||
.child(run.id.get(..8).unwrap_or(run.id.as_str()).to_string()),
|
||||
)
|
||||
@@ -243,13 +269,14 @@ fn recovery_banner(runs: &[&domain::Run]) -> impl IntoElement {
|
||||
}
|
||||
|
||||
fn budget_alert_banner(agents: &[&domain::Agent], cx: &mut Context<AppRoot>) -> impl IntoElement {
|
||||
let danger_30 = gpui::Hsla { a: 0.3, ..theme::danger() };
|
||||
div().gap_2().children(agents.iter().map(|agent| {
|
||||
div()
|
||||
.id(SharedString::from(format!("budget-alert-{}", agent.id)))
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::danger())
|
||||
.bg(theme::accent_orange_soft())
|
||||
.border_color(danger_30)
|
||||
.bg(theme::danger_bg())
|
||||
.px_4()
|
||||
.py_3()
|
||||
.cursor_pointer()
|
||||
@@ -260,12 +287,30 @@ fn budget_alert_banner(agents: &[&domain::Agent], cx: &mut Context<AppRoot>) ->
|
||||
}))
|
||||
.child(
|
||||
div()
|
||||
.text_sm()
|
||||
.text_color(theme::accent_orange())
|
||||
.child(format!(
|
||||
"{} is at ${:.2} / ${:.2} monthly budget.",
|
||||
agent.name, agent.spent_monthly_usd, agent.budget_monthly_usd
|
||||
)),
|
||||
.flex()
|
||||
.gap_2()
|
||||
.items_center()
|
||||
.child(
|
||||
div()
|
||||
.w(px(16.0))
|
||||
.h(px(16.0))
|
||||
.rounded(px(4.0))
|
||||
.bg(theme::danger())
|
||||
.flex()
|
||||
.items_center()
|
||||
.justify_center()
|
||||
.child(div().w(px(10.0)).h(px(10.0)).rounded_full().bg(theme::panel())),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.text_size(px(13.0))
|
||||
.font_weight(gpui::FontWeight::MEDIUM)
|
||||
.text_color(theme::text_primary())
|
||||
.child(format!(
|
||||
"{} is at ${:.2} / ${:.2} monthly budget.",
|
||||
agent.name, agent.spent_monthly_usd, agent.budget_monthly_usd
|
||||
)),
|
||||
),
|
||||
)
|
||||
}))
|
||||
}
|
||||
@@ -275,17 +320,25 @@ fn metric_card(
|
||||
value: String,
|
||||
subtitle: String,
|
||||
icon_bg: gpui::Hsla,
|
||||
tone: gpui::Hsla,
|
||||
_tone: gpui::Hsla,
|
||||
target_section: SectionId,
|
||||
cx: &mut Context<AppRoot>,
|
||||
) -> impl IntoElement {
|
||||
let icon_letter = match label {
|
||||
"ACTIVE TASKS" => "T",
|
||||
"APPROVALS" => "A",
|
||||
"RUNS" => "R",
|
||||
"AGENTS" => "A",
|
||||
_ => "•",
|
||||
};
|
||||
div()
|
||||
.id(SharedString::from(format!("overview-metric-{label}")))
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
.p_4()
|
||||
.px_4()
|
||||
.py_4()
|
||||
.cursor_pointer()
|
||||
.hover(|style| style.bg(theme::panel_hover()))
|
||||
.on_click(cx.listener(move |this, _, _, cx| {
|
||||
@@ -297,16 +350,45 @@ fn metric_card(
|
||||
.flex()
|
||||
.gap_4()
|
||||
.items_center()
|
||||
.child(div().w(px(48.0)).h(px(48.0)).rounded_lg().bg(icon_bg))
|
||||
.child(
|
||||
div()
|
||||
.w(px(48.0))
|
||||
.h(px(48.0))
|
||||
.rounded(px(4.0))
|
||||
.bg(icon_bg)
|
||||
.flex()
|
||||
.items_center()
|
||||
.justify_center()
|
||||
.child(
|
||||
div()
|
||||
.text_size(px(18.0))
|
||||
.font_weight(gpui::FontWeight::BOLD)
|
||||
.text_color(theme::text_muted())
|
||||
.child(icon_letter),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.flex_1()
|
||||
.child(div().text_xs().text_color(theme::text_muted()).child(label))
|
||||
.child(div().text_3xl().text_color(tone).child(value))
|
||||
.child(
|
||||
div()
|
||||
.text_size(px(11.0))
|
||||
.font_weight(gpui::FontWeight::SEMIBOLD)
|
||||
.text_color(theme::text_muted())
|
||||
.child(label),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.text_size(px(28.0))
|
||||
.font_weight(gpui::FontWeight::BOLD)
|
||||
.text_color(theme::text_primary())
|
||||
.child(value),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.mt(px(6.0))
|
||||
.text_xs()
|
||||
.text_size(px(11.0))
|
||||
.font_weight(gpui::FontWeight::MEDIUM)
|
||||
.text_color(theme::text_muted())
|
||||
.child(subtitle),
|
||||
),
|
||||
@@ -315,7 +397,11 @@ fn metric_card(
|
||||
}
|
||||
|
||||
fn eyebrow_label(label: &'static str) -> impl IntoElement {
|
||||
div().text_xs().text_color(theme::text_muted()).child(label)
|
||||
div()
|
||||
.text_size(px(11.0))
|
||||
.font_weight(gpui::FontWeight::SEMIBOLD)
|
||||
.text_color(theme::text_muted())
|
||||
.child(label)
|
||||
}
|
||||
|
||||
fn needs_attention_label() -> impl IntoElement {
|
||||
@@ -332,7 +418,8 @@ fn needs_attention_label() -> impl IntoElement {
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.text_xs()
|
||||
.text_size(px(11.0))
|
||||
.font_weight(gpui::FontWeight::SEMIBOLD)
|
||||
.text_color(theme::accent_orange())
|
||||
.child("NEEDS ATTENTION"),
|
||||
)
|
||||
@@ -350,7 +437,7 @@ fn attention_row(
|
||||
let selected_id = target_id.map(str::to_string);
|
||||
div()
|
||||
.id(SharedString::from(format!("overview-attention-{title}")))
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
@@ -373,26 +460,48 @@ fn attention_row(
|
||||
.flex()
|
||||
.gap_3()
|
||||
.items_center()
|
||||
.child(div().w(px(36.0)).h(px(36.0)).rounded_lg().bg(tile_bg))
|
||||
.child(
|
||||
div()
|
||||
.w(px(36.0))
|
||||
.h(px(36.0))
|
||||
.rounded(px(4.0))
|
||||
.bg(tile_bg)
|
||||
.flex()
|
||||
.items_center()
|
||||
.justify_center()
|
||||
.child(
|
||||
div()
|
||||
.w(px(8.0))
|
||||
.h(px(8.0))
|
||||
.rounded_full()
|
||||
.bg(accent),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.flex_1()
|
||||
.child(
|
||||
div()
|
||||
.text_sm()
|
||||
.text_size(px(13.0))
|
||||
.font_weight(gpui::FontWeight::MEDIUM)
|
||||
.text_color(theme::text_primary())
|
||||
.child(title),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.mt(px(4.0))
|
||||
.text_xs()
|
||||
.text_size(px(11.0))
|
||||
.text_color(theme::text_muted())
|
||||
.line_clamp(2)
|
||||
.child(subtitle),
|
||||
),
|
||||
)
|
||||
.child(div().w(px(10.0)).h(px(10.0)).rounded_full().bg(accent)),
|
||||
.child(
|
||||
div()
|
||||
.text_size(px(14.0))
|
||||
.text_color(theme::text_muted())
|
||||
.child(">"),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -440,21 +549,23 @@ fn success_rate_card(snapshot: &domain::ProfileSnapshot) -> impl IntoElement {
|
||||
completed as f32 / finished as f32
|
||||
};
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
.p_5()
|
||||
.child(
|
||||
div()
|
||||
.text_xs()
|
||||
.text_size(px(11.0))
|
||||
.font_weight(gpui::FontWeight::SEMIBOLD)
|
||||
.text_color(theme::text_muted())
|
||||
.child("SUCCESS RATE"),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.mt(px(10.0))
|
||||
.text_3xl()
|
||||
.text_size(px(28.0))
|
||||
.font_weight(gpui::FontWeight::BOLD)
|
||||
.text_color(theme::accent_teal())
|
||||
.child(format!("{:.0}%", rate * 100.0)),
|
||||
)
|
||||
@@ -487,28 +598,30 @@ fn cost_trend_card(snapshot: &domain::ProfileSnapshot) -> impl IntoElement {
|
||||
total / costs.len() as f64
|
||||
};
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
.p_5()
|
||||
.child(
|
||||
div()
|
||||
.text_xs()
|
||||
.text_size(px(11.0))
|
||||
.font_weight(gpui::FontWeight::SEMIBOLD)
|
||||
.text_color(theme::text_muted())
|
||||
.child("COST TREND"),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.mt(px(10.0))
|
||||
.text_3xl()
|
||||
.text_size(px(28.0))
|
||||
.font_weight(gpui::FontWeight::BOLD)
|
||||
.text_color(theme::text_primary())
|
||||
.child(format!("${total:.2}")),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.mt(px(8.0))
|
||||
.text_xs()
|
||||
.text_size(px(11.0))
|
||||
.text_color(theme::text_muted())
|
||||
.child(format!("Average ${average:.2} per metered run")),
|
||||
)
|
||||
@@ -542,12 +655,18 @@ fn mini_chart_card(
|
||||
.unwrap_or(1)
|
||||
.max(1) as f32;
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
.p_5()
|
||||
.child(div().text_xs().text_color(theme::text_muted()).child(label))
|
||||
.child(
|
||||
div()
|
||||
.text_size(px(11.0))
|
||||
.font_weight(gpui::FontWeight::SEMIBOLD)
|
||||
.text_color(theme::text_muted())
|
||||
.child(label),
|
||||
)
|
||||
.children(rows.into_iter().map(|(name, count)| {
|
||||
div()
|
||||
.mt(px(12.0))
|
||||
@@ -557,13 +676,15 @@ fn mini_chart_card(
|
||||
.justify_between()
|
||||
.child(
|
||||
div()
|
||||
.text_sm()
|
||||
.text_size(px(13.0))
|
||||
.font_weight(gpui::FontWeight::MEDIUM)
|
||||
.text_color(theme::text_primary())
|
||||
.child(name),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.text_xs()
|
||||
.text_size(px(11.0))
|
||||
.font_weight(gpui::FontWeight::MEDIUM)
|
||||
.text_color(theme::text_muted())
|
||||
.child(count.to_string()),
|
||||
),
|
||||
@@ -587,7 +708,7 @@ fn mini_chart_card(
|
||||
|
||||
fn budget_utilization_card(snapshot: &domain::ProfileSnapshot) -> impl IntoElement {
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
@@ -609,16 +730,21 @@ fn budget_utilization_card(snapshot: &domain::ProfileSnapshot) -> impl IntoEleme
|
||||
.items_center()
|
||||
.child(
|
||||
div()
|
||||
.text_sm()
|
||||
.text_size(px(13.0))
|
||||
.font_weight(gpui::FontWeight::MEDIUM)
|
||||
.text_color(theme::text_primary())
|
||||
.child(agent.name.clone()),
|
||||
)
|
||||
.child(div().text_xs().text_color(theme::text_muted()).child(
|
||||
format!(
|
||||
"${:.2} / ${:.2}",
|
||||
agent.spent_monthly_usd, agent.budget_monthly_usd
|
||||
),
|
||||
)),
|
||||
.child(
|
||||
div()
|
||||
.text_size(px(11.0))
|
||||
.font_weight(gpui::FontWeight::MEDIUM)
|
||||
.text_color(theme::text_muted())
|
||||
.child(format!(
|
||||
"${:.2} / ${:.2}",
|
||||
agent.spent_monthly_usd, agent.budget_monthly_usd
|
||||
)),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
@@ -650,7 +776,8 @@ fn active_work_header(cx: &mut Context<AppRoot>) -> impl IntoElement {
|
||||
div()
|
||||
.id("overview-all-runs")
|
||||
.cursor_pointer()
|
||||
.text_xs()
|
||||
.text_size(px(11.0))
|
||||
.font_weight(gpui::FontWeight::MEDIUM)
|
||||
.text_color(theme::accent_blue())
|
||||
.hover(|style| style.text_color(theme::text_primary()))
|
||||
.on_click(cx.listener(|this, _, _, cx| {
|
||||
@@ -667,7 +794,7 @@ fn active_work_card<'a>(
|
||||
cx: &mut Context<AppRoot>,
|
||||
) -> impl IntoElement + 'a {
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
@@ -692,20 +819,21 @@ fn active_work_card<'a>(
|
||||
this.state.selected_run_id = Some(run_id.clone());
|
||||
cx.notify();
|
||||
}))
|
||||
.px_5()
|
||||
.py_4()
|
||||
.px_4()
|
||||
.py_3()
|
||||
.border_b_1()
|
||||
.border_color(theme::panel_border())
|
||||
.child(
|
||||
div()
|
||||
.text_base()
|
||||
.text_size(px(13.0))
|
||||
.font_weight(gpui::FontWeight::MEDIUM)
|
||||
.text_color(theme::text_primary())
|
||||
.child(overview_run_title(snapshot, run)),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.mt(px(4.0))
|
||||
.text_sm()
|
||||
.text_size(px(11.0))
|
||||
.text_color(theme::text_muted())
|
||||
.child(format!(
|
||||
"{} · {}",
|
||||
@@ -719,26 +847,27 @@ fn active_work_card<'a>(
|
||||
|
||||
fn activity_feed_card(snapshot: &domain::ProfileSnapshot) -> impl IntoElement {
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
.children(snapshot.activity.iter().take(10).map(|item| {
|
||||
div()
|
||||
.px_5()
|
||||
.py_4()
|
||||
.px_4()
|
||||
.py_3()
|
||||
.border_b_1()
|
||||
.border_color(theme::panel_border())
|
||||
.child(
|
||||
div()
|
||||
.text_sm()
|
||||
.text_size(px(13.0))
|
||||
.font_weight(gpui::FontWeight::MEDIUM)
|
||||
.text_color(theme::text_primary())
|
||||
.child(format!("{} {}", item.actor, item.action.replace('_', " "))),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.mt(px(4.0))
|
||||
.text_xs()
|
||||
.text_size(px(11.0))
|
||||
.text_color(theme::text_muted())
|
||||
.child(item.detail.clone()),
|
||||
)
|
||||
|
||||
@@ -49,7 +49,7 @@ fn render_run_queue_panel(
|
||||
) -> impl IntoElement {
|
||||
div().w(px(420.0)).gap_5().child(
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
@@ -86,7 +86,7 @@ fn render_run_queue_panel(
|
||||
container.child(
|
||||
div()
|
||||
.mt(px(16.0))
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel_muted())
|
||||
@@ -127,7 +127,7 @@ fn run_queue_row(
|
||||
|
||||
div()
|
||||
.id(SharedString::from(format!("run-row-{}", run.id)))
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(if active {
|
||||
theme::selection_border()
|
||||
@@ -154,42 +154,43 @@ fn run_queue_row(
|
||||
.items_center()
|
||||
.gap_3()
|
||||
.child(
|
||||
div()
|
||||
.flex_1()
|
||||
.child(
|
||||
div()
|
||||
.text_sm()
|
||||
.text_color(theme::text_primary())
|
||||
.truncate()
|
||||
.child(title),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.mt(px(4.0))
|
||||
.text_xs()
|
||||
.text_color(theme::text_muted())
|
||||
.truncate()
|
||||
.child(subtitle),
|
||||
),
|
||||
div()
|
||||
.flex_1()
|
||||
.child(
|
||||
div()
|
||||
.text_size(px(13.0))
|
||||
.font_weight(gpui::FontWeight::SEMIBOLD)
|
||||
.text_color(theme::text_primary())
|
||||
.truncate()
|
||||
.child(title),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.mt(px(2.0))
|
||||
.text_size(px(11.0))
|
||||
.text_color(theme::text_muted())
|
||||
.truncate()
|
||||
.child(subtitle),
|
||||
),
|
||||
)
|
||||
.child(run_status_badge(run.status.as_str())),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.mt(px(8.0))
|
||||
.mt(px(6.0))
|
||||
.flex()
|
||||
.justify_between()
|
||||
.gap_3()
|
||||
.child(
|
||||
div()
|
||||
.text_xs()
|
||||
.text_size(px(11.0))
|
||||
.text_color(theme::text_muted())
|
||||
.line_clamp(1)
|
||||
.child(supporting_text),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.text_xs()
|
||||
.text_size(px(11.0))
|
||||
.text_color(theme::text_muted())
|
||||
.child(short_date(run.updated_at.as_str()).to_string()),
|
||||
),
|
||||
@@ -222,7 +223,7 @@ fn render_run_detail_column<'a>(
|
||||
.flex()
|
||||
.items_center()
|
||||
.justify_center()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
@@ -254,7 +255,7 @@ fn runs_empty_state() -> impl IntoElement {
|
||||
.flex()
|
||||
.items_center()
|
||||
.justify_center()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
@@ -280,7 +281,7 @@ fn runs_empty_state() -> impl IntoElement {
|
||||
|
||||
fn run_detail_panel(snapshot: &domain::ProfileSnapshot, run: &domain::Run) -> impl IntoElement {
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
@@ -350,7 +351,7 @@ fn run_detail_panel(snapshot: &domain::ProfileSnapshot, run: &domain::Run) -> im
|
||||
.child(
|
||||
div()
|
||||
.mt(px(16.0))
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_inset_border())
|
||||
.bg(theme::panel_inset())
|
||||
@@ -370,7 +371,7 @@ fn run_detail_panel(snapshot: &domain::ProfileSnapshot, run: &domain::Run) -> im
|
||||
content.child(
|
||||
div()
|
||||
.mt(px(16.0))
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::danger())
|
||||
.bg(theme::danger_bg())
|
||||
@@ -386,7 +387,7 @@ fn run_detail_panel(snapshot: &domain::ProfileSnapshot, run: &domain::Run) -> im
|
||||
|
||||
fn run_trace_panel(snapshot: &domain::ProfileSnapshot, run: &domain::Run) -> impl IntoElement {
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
@@ -402,7 +403,7 @@ fn run_trace_panel(snapshot: &domain::ProfileSnapshot, run: &domain::Run) -> imp
|
||||
|
||||
fn secondary_data_panel(title: &'static str, body: gpui::AnyElement) -> impl IntoElement {
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
@@ -654,7 +655,7 @@ fn run_live_controls_panel<'a>(
|
||||
cx: &'a mut Context<AppRoot>,
|
||||
) -> impl IntoElement + 'a {
|
||||
div()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
|
||||
@@ -220,7 +220,7 @@ fn settings_tab_button(
|
||||
fn settings_panel(label: &'static str, rows: Vec<gpui::AnyElement>) -> impl IntoElement {
|
||||
div()
|
||||
.p_5()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
@@ -290,7 +290,7 @@ where
|
||||
.id(SharedString::from(format!("settings-action-{label}")))
|
||||
.px_3()
|
||||
.py_2()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.cursor_pointer()
|
||||
.bg(if active {
|
||||
theme::primary_action()
|
||||
|
||||
@@ -17,7 +17,7 @@ impl AppRoot {
|
||||
];
|
||||
|
||||
div()
|
||||
.w(px(292.0))
|
||||
.w(px(256.0))
|
||||
.h_full()
|
||||
.p_4()
|
||||
.gap_4()
|
||||
@@ -41,7 +41,7 @@ impl AppRoot {
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.text_xs()
|
||||
.text_size(px(11.0))
|
||||
.text_color(theme::text_subtle())
|
||||
.child("local-first"),
|
||||
),
|
||||
@@ -54,40 +54,38 @@ impl AppRoot {
|
||||
.child(
|
||||
div()
|
||||
.flex_1()
|
||||
.px_4()
|
||||
.py_3()
|
||||
.px_3()
|
||||
.py_2()
|
||||
.border_1()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
.child(
|
||||
div().text_sm().text_color(theme::text_primary()).child(
|
||||
self.snapshot
|
||||
.current_company()
|
||||
.map(|company| company.name.clone())
|
||||
.unwrap_or_else(|| "AgentCompany".to_string()),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.text_xs()
|
||||
.text_color(theme::text_muted())
|
||||
.child("native GPUI shell"),
|
||||
.text_size(px(13.0))
|
||||
.font_weight(gpui::FontWeight::MEDIUM)
|
||||
.text_color(theme::text_primary())
|
||||
.child(
|
||||
self.snapshot
|
||||
.current_company()
|
||||
.map(|company| company.name.clone())
|
||||
.unwrap_or_else(|| "AgentCompany".to_string()),
|
||||
),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.w(px(44.0))
|
||||
.h(px(44.0))
|
||||
.rounded_lg()
|
||||
.w(px(30.0))
|
||||
.h(px(30.0))
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
.flex()
|
||||
.items_center()
|
||||
.justify_center()
|
||||
.text_sm()
|
||||
.text_color(theme::text_secondary())
|
||||
.text_size(px(12.0))
|
||||
.text_color(theme::text_muted())
|
||||
.child("⌘"),
|
||||
),
|
||||
)
|
||||
@@ -97,16 +95,10 @@ impl AppRoot {
|
||||
let company_id = company.id.clone();
|
||||
div()
|
||||
.id(SharedString::from(format!("company-{}", company.id)))
|
||||
.px_4()
|
||||
.py_3()
|
||||
.rounded_lg()
|
||||
.px_3()
|
||||
.py_2()
|
||||
.rounded(px(0.0))
|
||||
.cursor_pointer()
|
||||
.border_1()
|
||||
.border_color(if active {
|
||||
theme::selection_border()
|
||||
} else {
|
||||
theme::panel_border()
|
||||
})
|
||||
.bg(if active {
|
||||
theme::selection_fill()
|
||||
} else {
|
||||
@@ -118,7 +110,12 @@ impl AppRoot {
|
||||
}))
|
||||
.child(
|
||||
div()
|
||||
.text_sm()
|
||||
.text_size(px(13.0))
|
||||
.font_weight(if active {
|
||||
gpui::FontWeight::SEMIBOLD
|
||||
} else {
|
||||
gpui::FontWeight::MEDIUM
|
||||
})
|
||||
.text_color(if active {
|
||||
theme::sidebar_text_active()
|
||||
} else {
|
||||
@@ -126,12 +123,6 @@ impl AppRoot {
|
||||
})
|
||||
.child(company.name.clone()),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.text_xs()
|
||||
.text_color(theme::text_muted())
|
||||
.child(format!("{} mode", company.execution_mode.replace('_', " "))),
|
||||
)
|
||||
}))
|
||||
.child(div().h(px(1.0)).bg(theme::sidebar_divider()))
|
||||
.children(sections.into_iter().map(|(section, badge)| {
|
||||
@@ -145,16 +136,10 @@ impl AppRoot {
|
||||
.flex()
|
||||
.items_center()
|
||||
.justify_between()
|
||||
.px_4()
|
||||
.py_3()
|
||||
.rounded_lg()
|
||||
.px_3()
|
||||
.py(px(7.0))
|
||||
.rounded(px(0.0))
|
||||
.cursor_pointer()
|
||||
.border_1()
|
||||
.border_color(if active {
|
||||
theme::selection_border()
|
||||
} else {
|
||||
theme::sidebar_bg()
|
||||
})
|
||||
.bg(if active {
|
||||
theme::selection_fill()
|
||||
} else {
|
||||
@@ -170,7 +155,12 @@ impl AppRoot {
|
||||
this.state.section = section;
|
||||
cx.notify();
|
||||
}))
|
||||
.child(div().text_sm().child(label))
|
||||
.child(
|
||||
div()
|
||||
.text_size(px(13.0))
|
||||
.font_weight(gpui::FontWeight::MEDIUM)
|
||||
.child(label),
|
||||
)
|
||||
.when_some(badge.filter(|count| *count > 0), |container, count| {
|
||||
container.child(
|
||||
div()
|
||||
@@ -183,7 +173,7 @@ impl AppRoot {
|
||||
} else {
|
||||
theme::badge_dark()
|
||||
})
|
||||
.text_xs()
|
||||
.text_size(px(11.0))
|
||||
.text_color(theme::panel())
|
||||
.child(count.to_string()),
|
||||
)
|
||||
@@ -200,23 +190,6 @@ impl AppRoot {
|
||||
cx.notify();
|
||||
},
|
||||
))
|
||||
.child(
|
||||
div()
|
||||
.px_4()
|
||||
.py_3()
|
||||
.rounded_lg()
|
||||
.bg(theme::panel_muted())
|
||||
.child(
|
||||
div()
|
||||
.text_xs()
|
||||
.text_color(theme::text_muted())
|
||||
.child(format!(
|
||||
"{} agents · {} channels",
|
||||
self.snapshot.agents.len(),
|
||||
self.snapshot.agent_messages.len()
|
||||
)),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,7 +206,7 @@ where
|
||||
.id(SharedString::from(format!("sidebar-footer-{label}")))
|
||||
.px_4()
|
||||
.py_3()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.cursor_pointer()
|
||||
.bg(if active {
|
||||
theme::selection_fill()
|
||||
|
||||
@@ -56,7 +56,7 @@ impl AppRoot {
|
||||
.flex()
|
||||
.items_center()
|
||||
.justify_center()
|
||||
.rounded_lg()
|
||||
.rounded(px(0.0))
|
||||
.border_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
|
||||
@@ -127,3 +127,40 @@ pub fn selection_border() -> Hsla {
|
||||
pub fn badge_dark() -> Hsla {
|
||||
rgb(0x6b7280).into()
|
||||
}
|
||||
|
||||
// Tailwind v4 theme variable aliases (exact oklch → rgb from original styles.css)
|
||||
pub fn card() -> Hsla {
|
||||
rgb(0xffffff).into()
|
||||
}
|
||||
|
||||
pub fn muted() -> Hsla {
|
||||
rgb(0xf7f7f7).into()
|
||||
}
|
||||
|
||||
pub fn accent() -> Hsla {
|
||||
rgb(0xf7f7f7).into()
|
||||
}
|
||||
|
||||
pub fn foreground() -> Hsla {
|
||||
rgb(0x222222).into()
|
||||
}
|
||||
|
||||
pub fn muted_foreground() -> Hsla {
|
||||
rgb(0x5e5e5e).into()
|
||||
}
|
||||
|
||||
pub fn primary() -> Hsla {
|
||||
rgb(0x2d2d2d).into()
|
||||
}
|
||||
|
||||
pub fn primary_foreground() -> Hsla {
|
||||
rgb(0xfafafa).into()
|
||||
}
|
||||
|
||||
pub fn destructive() -> Hsla {
|
||||
rgb(0xc74a4a).into()
|
||||
}
|
||||
|
||||
pub fn border() -> Hsla {
|
||||
rgb(0xe8e8e8).into()
|
||||
}
|
||||
@@ -302,7 +302,7 @@
|
||||
"cargo test --workspace passes"
|
||||
],
|
||||
"priority": 22,
|
||||
"passes": true,
|
||||
"passes": false,
|
||||
"notes": "Passed: shared native surface tokens were tightened toward screenshot-aligned desktop values, warming the pane fills, softening borders, and refining selection/accent colors without touching parent-directory source files."
|
||||
},
|
||||
{
|
||||
@@ -315,7 +315,7 @@
|
||||
"cargo test --workspace passes"
|
||||
],
|
||||
"priority": 23,
|
||||
"passes": true,
|
||||
"passes": false,
|
||||
"notes": "Passed: messages and inbox chrome were tightened toward screenshot parity with calmer pane spacing, smaller radii, warmer sidebar treatment, lighter message avatar chrome, and denser list rows while keeping real interactions intact."
|
||||
},
|
||||
{
|
||||
@@ -328,7 +328,7 @@
|
||||
"cargo test --workspace passes"
|
||||
],
|
||||
"priority": 24,
|
||||
"passes": true,
|
||||
"passes": false,
|
||||
"notes": "Passed: ui-parity-audit.md now records the fine-grained current-directory visual audit after the shared-skin and communication-skin passes, and the workspace still passes cargo clippy and cargo test."
|
||||
}
|
||||
]
|
||||
|
||||
Reference in new issue
Block a user