From 452696dcd394928a8034aa58083e06b02f533d6b Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Mon, 16 Feb 2026 21:19:04 -0500 Subject: [PATCH] client: Add organizations to `UserStore` (#49320) This PR adds the list of the user's organizations to the `UserStore`. Closes CLO-292. Release Notes: - N/A --- crates/client/src/test.rs | 1 + crates/client/src/user.rs | 15 ++++++++++++++- crates/cloud_api_types/src/cloud_api_types.rs | 13 +++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/crates/client/src/test.rs b/crates/client/src/test.rs index 26bd41ea2657aa99c2aa4562d5d5081e233c3b77..5102664a8c08ba336f3ae506aadb68eb2a537935 100644 --- a/crates/client/src/test.rs +++ b/crates/client/src/test.rs @@ -265,6 +265,7 @@ pub fn make_get_authenticated_user_response( accepted_tos_at: None, }, feature_flags: vec![], + organizations: vec![], plan: PlanInfo { plan: KnownOrUnknown::Known(Plan::ZedPro), subscription_period: None, diff --git a/crates/client/src/user.rs b/crates/client/src/user.rs index 53b6a630bb26ed893bb507156ebb46b05f4b0026..156739b1ab1f0ecedac1a4579f27b799d1911196 100644 --- a/crates/client/src/user.rs +++ b/crates/client/src/user.rs @@ -2,7 +2,7 @@ use super::{Client, Status, TypedEnvelope, proto}; use anyhow::{Context as _, Result}; use chrono::{DateTime, Utc}; use cloud_api_client::websocket_protocol::MessageToClient; -use cloud_api_client::{GetAuthenticatedUserResponse, Plan, PlanInfo}; +use cloud_api_client::{GetAuthenticatedUserResponse, Organization, Plan, PlanInfo}; use cloud_llm_client::{ EDIT_PREDICTIONS_USAGE_AMOUNT_HEADER_NAME, EDIT_PREDICTIONS_USAGE_LIMIT_HEADER_NAME, UsageLimit, }; @@ -109,6 +109,8 @@ pub struct UserStore { edit_prediction_usage: Option, plan_info: Option, current_user: watch::Receiver>>, + current_organization: Option>, + organizations: Vec>, contacts: Vec>, incoming_contact_requests: Vec>, outgoing_contact_requests: Vec>, @@ -178,6 +180,8 @@ impl UserStore { users: Default::default(), by_github_login: Default::default(), current_user: current_user_rx, + current_organization: None, + organizations: Vec::new(), plan_info: None, edit_prediction_usage: None, contacts: Default::default(), @@ -257,6 +261,7 @@ impl UserStore { Status::SignedOut => { current_user_tx.send(None).await.ok(); this.update(cx, |this, cx| { + this.clear_organizations(); this.clear_plan_and_usage(); cx.emit(Event::PrivateUserInfoUpdated); cx.notify(); @@ -731,6 +736,11 @@ impl UserStore { cx.notify(); } + pub fn clear_organizations(&mut self) { + self.organizations.clear(); + self.current_organization = None; + } + pub fn clear_plan_and_usage(&mut self) { self.plan_info = None; self.edit_prediction_usage = None; @@ -749,6 +759,9 @@ impl UserStore { .set_authenticated_user_info(Some(response.user.metrics_id.clone()), staff); } + self.organizations = response.organizations.into_iter().map(Arc::new).collect(); + self.current_organization = self.organizations.first().cloned(); + self.edit_prediction_usage = Some(EditPredictionUsage(RequestUsage { limit: response.plan.usage.edit_predictions.limit, amount: response.plan.usage.edit_predictions.used as i32, diff --git a/crates/cloud_api_types/src/cloud_api_types.rs b/crates/cloud_api_types/src/cloud_api_types.rs index df3ab9ddba8e05d98c25e18e82851c9911fbcd12..7cbf42eacdd56a61c71677f7ae3c123d680851e5 100644 --- a/crates/cloud_api_types/src/cloud_api_types.rs +++ b/crates/cloud_api_types/src/cloud_api_types.rs @@ -4,6 +4,8 @@ mod plan; mod timestamp; pub mod websocket_protocol; +use std::sync::Arc; + use serde::{Deserialize, Serialize}; pub use crate::extension::*; @@ -17,6 +19,8 @@ pub const ZED_SYSTEM_ID_HEADER_NAME: &str = "x-zed-system-id"; pub struct GetAuthenticatedUserResponse { pub user: AuthenticatedUser, pub feature_flags: Vec, + #[serde(default)] + pub organizations: Vec, pub plan: PlanInfo, } @@ -31,6 +35,15 @@ pub struct AuthenticatedUser { pub accepted_tos_at: Option, } +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +pub struct OrganizationId(Arc); + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub struct Organization { + pub id: OrganizationId, + pub name: Arc, +} + #[derive(Debug, PartialEq, Serialize, Deserialize)] pub struct AcceptTermsOfServiceResponse { pub user: AuthenticatedUser,