Add some adjustments to the parallel onboarding elements (#53449)

Danilo Leal created

- Hopefully, making the "Try Now" button within the announcement toast
effectively get the layout switched to agent
- Don't dismiss the announcement toast when clicking on "Learn More"
- Add a Learn More button in the agent panel, too
- Hide the "Collab with Agents" card in the launchpad page

Release Notes:

- N/A

Change summary

crates/ai_onboarding/src/ai_onboarding.rs   | 10 +++++++++-
crates/auto_update_ui/src/auto_update_ui.rs | 14 +++++++-------
crates/client/src/zed_urls.rs               |  5 +++++
crates/workspace/src/welcome.rs             |  6 ++++--
4 files changed, 25 insertions(+), 10 deletions(-)

Detailed changes

crates/ai_onboarding/src/ai_onboarding.rs 🔗

@@ -455,7 +455,7 @@ impl Render for AgentLayoutOnboarding {
     fn render(&mut self, _window: &mut ui::Window, _cx: &mut Context<Self>) -> impl IntoElement {
         let description = "With the new Threads Sidebar, you can manage multiple agents across several projects, all in one window.";
 
-        let dismiss_button = div().absolute().top_1().right_1().child(
+        let dismiss_button = div().absolute().top_0().right_0().child(
             IconButton::new("dismiss", IconName::Close)
                 .icon_size(IconSize::Small)
                 .on_click({
@@ -520,6 +520,14 @@ impl Render for AgentLayoutOnboarding {
                     .gap_1()
                     .flex_wrap()
                     .justify_end()
+                    .child(
+                        Button::new("learn", "Learn More")
+                            .label_size(LabelSize::Small)
+                            .style(ButtonStyle::OutlinedGhost)
+                            .on_click(move |_, _, cx| {
+                                cx.open_url(&zed_urls::parallel_agents_blog(cx))
+                            }),
+                    )
                     .child(primary_button),
             )
             .child(dismiss_button);

crates/auto_update_ui/src/auto_update_ui.rs 🔗

@@ -16,7 +16,7 @@ use smol::io::AsyncReadExt;
 use ui::{AnnouncementToast, ListBulletItem, ParallelAgentsIllustration, prelude::*};
 use util::{ResultExt as _, maybe};
 use workspace::{
-    ToggleWorkspaceSidebar, Workspace,
+    FocusWorkspaceSidebar, Workspace,
     notifications::{
         ErrorMessagePrompt, Notification, NotificationId, SuppressEvent, show_app_notification,
         simple_message_notification::MessageNotification,
@@ -192,9 +192,6 @@ fn announcement_for_version(version: &Version, cx: &App) -> Option<AnnouncementC
                 None
             } else {
                 let fs = <dyn Fs>::global(cx);
-                let already_agent_layout =
-                    matches!(AgentSettings::get_layout(cx), WindowLayout::Agent(_));
-
                 Some(AnnouncementContent {
                     heading: "Introducing Parallel Agents".into(),
                     description: "Run multiple agent threads simultaneously across projects."
@@ -207,10 +204,14 @@ fn announcement_for_version(version: &Version, cx: &App) -> Option<AnnouncementC
                     primary_action_label: "Try Now".into(),
                     primary_action_url: None,
                     primary_action_callback: Some(Arc::new(move |window, cx| {
+                        let already_agent_layout =
+                            matches!(AgentSettings::get_layout(cx), WindowLayout::Agent(_));
+
                         if !already_agent_layout {
                             AgentSettings::set_layout(WindowLayout::Agent(None), fs.clone(), cx);
                         }
-                        window.dispatch_action(Box::new(ToggleWorkspaceSidebar), cx);
+
+                        window.dispatch_action(Box::new(FocusWorkspaceSidebar), cx);
                         window.dispatch_action(Box::new(zed_actions::assistant::ToggleFocus), cx);
                     })),
                     on_dismiss: Some(Arc::new(|cx| {
@@ -284,12 +285,11 @@ impl Render for AnnouncementToastNotification {
             }))
             .secondary_on_click(cx.listener({
                 let url = self.content.secondary_action_url.clone();
-                move |this, _, _window, cx| {
+                move |_, _, _window, cx| {
                     telemetry::event!("Parallel Agent Announcement Secondary Click");
                     if let Some(url) = &url {
                         cx.open_url(url);
                     }
-                    this.dismiss(cx);
                 }
             }))
             .dismiss_on_click(cx.listener(|this, _, _window, cx| {

crates/client/src/zed_urls.rs 🔗

@@ -60,6 +60,11 @@ pub fn acp_registry_blog(cx: &App) -> String {
     )
 }
 
+/// Returns the URL to Zed's Parallel Agents blog post.
+pub fn parallel_agents_blog(cx: &App) -> String {
+    format!("{server_url}/blog", server_url = server_url(cx))
+}
+
 pub fn shared_agent_thread_url(session_id: &str) -> String {
     format!("zed://agent/shared/{}", session_id)
 }

crates/workspace/src/welcome.rs 🔗

@@ -445,7 +445,9 @@ impl Render for WelcomePage {
             })
             .collect::<Vec<_>>();
 
-        let second_section = if self.fallback_to_recent_projects && !recent_projects.is_empty() {
+        let showing_recent_projects =
+            self.fallback_to_recent_projects && !recent_projects.is_empty();
+        let second_section = if showing_recent_projects {
             self.render_recent_project_section(recent_projects)
                 .into_any_element()
         } else {
@@ -496,7 +498,7 @@ impl Render for WelcomePage {
                     )
                     .child(first_section.render(Default::default(), &self.focus_handle))
                     .child(second_section)
-                    .when(ai_enabled, |this| {
+                    .when(ai_enabled && !showing_recent_projects, |this| {
                         let agent_tab_index = next_tab_index;
                         next_tab_index += 1;
                         this.child(self.render_agent_card(agent_tab_index, cx))