diff --git a/crates/client/src/user.rs b/crates/client/src/user.rs index e7a445c69a78ed3be5f062e3b3bb3aee9756b61d..885095017edf66a9e7a1edb7590e8ebc37e16fc9 100644 --- a/crates/client/src/user.rs +++ b/crates/client/src/user.rs @@ -690,6 +690,14 @@ impl UserStore { self.current_organization.clone() } + pub fn set_current_organization(&mut self, organization: Arc) { + self.current_organization.replace(organization); + } + + pub fn organizations(&self) -> &Vec> { + &self.organizations + } + pub fn plan(&self) -> Option { #[cfg(debug_assertions)] if let Ok(plan) = std::env::var("ZED_SIMULATE_PLAN").as_ref() { diff --git a/crates/title_bar/src/title_bar.rs b/crates/title_bar/src/title_bar.rs index 08ef3e76345832ea7d1a78738fd15176bf65308b..7a1f18e1f29584ed5b1f336128ecdf2603087dd5 100644 --- a/crates/title_bar/src/title_bar.rs +++ b/crates/title_bar/src/title_bar.rs @@ -24,9 +24,9 @@ use client::{Client, UserStore, zed_urls}; use cloud_api_types::Plan; use feature_flags::{AgentV2FeatureFlag, FeatureFlagAppExt}; use gpui::{ - Action, AnyElement, App, Context, Corner, Element, Entity, Focusable, InteractiveElement, - IntoElement, MouseButton, ParentElement, Render, StatefulInteractiveElement, Styled, - Subscription, WeakEntity, Window, actions, div, + Action, AnyElement, App, Context, Corner, Element, Empty, Entity, Focusable, + InteractiveElement, IntoElement, MouseButton, ParentElement, Render, + StatefulInteractiveElement, Styled, Subscription, WeakEntity, Window, actions, div, }; use onboarding_banner::OnboardingBanner; use project::{Project, git_store::GitStoreEvent, trusted_worktrees::TrustedWorktrees}; @@ -225,6 +225,7 @@ impl Render for TitleBar { user.is_none() && TitleBarSettings::get_global(cx).show_sign_in, |this| this.child(self.render_sign_in_button(cx)), ) + .child(self.render_organization_menu_button(cx)) .when(TitleBarSettings::get_global(cx).show_user_menu, |this| { this.child(self.render_user_menu_button(cx)) }) @@ -953,6 +954,61 @@ impl TitleBar { }) } + pub fn render_organization_menu_button(&mut self, cx: &mut Context) -> AnyElement { + let Some(organization) = self.user_store.read(cx).current_organization() else { + return Empty.into_any_element(); + }; + + PopoverMenu::new("organization-menu") + .anchor(Corner::TopRight) + .menu({ + let user_store = self.user_store.clone(); + move |window, cx| { + ContextMenu::build(window, cx, |mut menu, _window, cx| { + menu = menu.header("Organizations").separator(); + + for organization in user_store.read(cx).organizations() { + let organization = organization.clone(); + + menu = menu.custom_entry( + { + let organization = organization.clone(); + move |_window, _cx| { + h_flex() + .w_full() + .justify_between() + .child(Label::new(&organization.name)) + .into_any_element() + } + }, + { + let user_store = user_store.clone(); + let organization = organization.clone(); + move |_window, cx| { + user_store.update(cx, |user_store, _cx| { + user_store + .set_current_organization(organization.clone()); + }); + } + }, + ); + } + + menu + }) + .into() + } + }) + .trigger_with_tooltip( + Button::new("organization-menu", &organization.name) + .selected_style(ButtonStyle::Tinted(TintColor::Accent)) + .label_size(LabelSize::Small), + Tooltip::text("Toggle Organization Menu"), + ) + .anchor(gpui::Corner::TopRight) + .into_any_element() + } + pub fn render_user_menu_button(&mut self, cx: &mut Context) -> impl Element { let show_update_badge = self.update_version.read(cx).show_update_in_menu_bar();