diff --git a/app/src/workspace/view.rs b/app/src/workspace/view.rs index 1805ccbd80d..501f4908be4 100644 --- a/app/src/workspace/view.rs +++ b/app/src/workspace/view.rs @@ -4011,6 +4011,14 @@ impl Workspace { .get(self.active_tab_index) .and_then(|tab| tab.group_id); + // A tab that joins a group in the loop below expands it, so re-collapse these afterwards. + let collapsed_groups: Vec = self + .tab_groups + .iter() + .filter(|(_, group)| group.collapsed) + .map(|(id, _)| *id) + .collect(); + window .tabs .iter() @@ -4034,6 +4042,12 @@ impl Workspace { .and_then(|group_index| group_ids.get(group_index).copied().flatten()); }); + for group_id in &collapsed_groups { + if let Some(group) = self.tab_groups.get_mut(group_id) { + group.collapsed = true; + } + } + // A pinned group makes its members effectively pinned, and the pinned // region is a prefix of the tab list. The inserts above ran while the // tabs were still ungrouped, so `NewTabPlacement` could leave the block diff --git a/app/src/workspace/view_tests.rs b/app/src/workspace/view_tests.rs index 19da532594e..853e2798659 100644 --- a/app/src/workspace/view_tests.rs +++ b/app/src/workspace/view_tests.rs @@ -48,6 +48,9 @@ use crate::cloud_object::model::view::CloudViewModel; use crate::context_chips::prompt::Prompt; use crate::editor::Event; use crate::gpu_state::GPUState; +use crate::launch_configs::launch_config::{ + PaneMode, PaneTemplateType, TabGroupTemplate, TabTemplate, +}; use crate::menu::MenuAction; use crate::network::NetworkStatus; use crate::notebooks::editor::keys::NotebookKeybindings; @@ -5272,6 +5275,97 @@ fn test_new_tab_in_group_expands_collapsed_group_member_active() { }); } +fn launch_config_tab(group: Option) -> TabTemplate { + TabTemplate { + title: None, + layout: PaneTemplateType::PaneTemplate { + cwd: std::env::temp_dir(), + commands: vec![], + is_focused: Some(true), + pane_mode: PaneMode::Terminal, + shell: None, + }, + commands: vec![], + color: None, + group, + } +} + +#[test] +fn test_launch_config_keeps_tab_group_collapsed() { + let _grouped_tabs_guard = FeatureFlag::GroupedTabs.override_enabled(true); + + App::test((), |mut app| async move { + initialize_app(&mut app); + + let workspace = mock_workspace(&mut app); + workspace.update(&mut app, |workspace, ctx| { + let window = WindowTemplate { + active_tab_index: Some(0), + tabs: vec![launch_config_tab(Some(0)), launch_config_tab(Some(0))], + tab_groups: vec![TabGroupTemplate { + name: Some("Collapsed group".to_string()), + color: None, + collapsed: true, + pinned: false, + }], + }; + workspace.open_launch_config_window(window, ctx); + + let group_id = workspace + .tabs + .iter() + .find_map(|tab| tab.group_id) + .expect("launch config should create the group"); + assert_eq!( + workspace + .tabs + .iter() + .filter(|tab| tab.group_id == Some(group_id)) + .count(), + 2 + ); + assert!( + workspace.tab_groups[&group_id].collapsed, + "group saved as collapsed should open collapsed" + ); + }); + }); +} + +#[test] +fn test_launch_config_keeps_active_collapsed_group_collapsed() { + let _grouped_tabs_guard = FeatureFlag::GroupedTabs.override_enabled(true); + + App::test((), |mut app| async move { + initialize_app(&mut app); + + let workspace = mock_workspace(&mut app); + workspace.update(&mut app, |workspace, ctx| { + workspace.handle_action( + &WorkspaceAction::SelectNewSessionMenuItem(NewSessionMenuItem::CreateNewTabGroup), + ctx, + ); + let group_id = workspace.tabs[workspace.active_tab_index()] + .group_id + .expect("active tab should be in a group"); + workspace.handle_action(&WorkspaceAction::ToggleTabGroupCollapsed(group_id), ctx); + + let window = WindowTemplate { + active_tab_index: Some(0), + tabs: vec![launch_config_tab(None)], + tab_groups: vec![], + }; + workspace.open_launch_config_window(window, ctx); + + assert!( + workspace.tab_groups[&group_id].collapsed, + "opening a launch config should not expand an existing group" + ); + }); + }); +} + #[test] fn test_pin_unpin_ungrouped_tab_moves_to_and_from_boundary() { let _pinned_guard = FeatureFlag::PinnedTabs.override_enabled(true);