Show cloud switcher and option to add a team when logged in (#8291)

This commit is contained in:
Matt Rubens 2025-09-24 16:42:06 -04:00 committed by GitHub
parent 25f61943ca
commit d3d0967fc3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 84 additions and 22 deletions

View file

@ -89,7 +89,6 @@ export const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
clineMessages,
commands,
cloudUserInfo,
cloudOrganizations,
} = useExtensionState()
// Find the ID and display text for the currently selected API configuration.
@ -1238,9 +1237,7 @@ export const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
<div
className={cn(
"flex flex-shrink-0 items-center gap-0.5",
!isEditMode && cloudOrganizations && cloudOrganizations.length > 0 && cloudUserInfo
? ""
: "pr-2",
!isEditMode && cloudUserInfo ? "" : "pr-2",
)}>
{isTtsPlaying && (
<StandardTooltip content={t("chat:stopTts")}>
@ -1263,9 +1260,7 @@ export const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
</StandardTooltip>
)}
{!isEditMode ? <IndexingStatusBadge /> : null}
{!isEditMode && cloudOrganizations && cloudOrganizations.length > 0 && cloudUserInfo && (
<CloudAccountSwitcher />
)}
{!isEditMode && cloudUserInfo && <CloudAccountSwitcher />}
</div>
</div>
</div>

View file

@ -1,5 +1,5 @@
import { useState, useEffect } from "react"
import { Building2 } from "lucide-react"
import { Building2, Plus } from "lucide-react"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectSeparator } from "@/components/ui/select"
import { useAppTranslation } from "@src/i18n/TranslationContext"
import { vscode } from "@src/utils/vscode"
@ -8,7 +8,7 @@ import { cn } from "@src/lib/utils"
export const CloudAccountSwitcher = () => {
const { t } = useAppTranslation()
const { cloudUserInfo, cloudOrganizations = [] } = useExtensionState()
const { cloudUserInfo, cloudOrganizations = [], cloudApiUrl } = useExtensionState()
const [selectedOrgId, setSelectedOrgId] = useState<string | null>(cloudUserInfo?.organizationId || null)
const [isLoading, setIsLoading] = useState(false)
@ -17,12 +17,21 @@ export const CloudAccountSwitcher = () => {
setSelectedOrgId(cloudUserInfo?.organizationId || null)
}, [cloudUserInfo?.organizationId])
// Don't show the switcher if user has no organizations
if (!cloudOrganizations || cloudOrganizations.length === 0 || !cloudUserInfo) {
// Show the switcher whenever user is authenticated
if (!cloudUserInfo) {
return null
}
const handleOrganizationChange = async (value: string) => {
// Handle "Create Team Account" option
if (value === "create-team") {
if (cloudApiUrl) {
const billingUrl = `${cloudApiUrl}/billing`
vscode.postMessage({ type: "openExternal", url: billingUrl })
}
return
}
const newOrgId = value === "personal" ? null : value
// Don't do anything if selecting the same organization
@ -139,6 +148,19 @@ export const CloudAccountSwitcher = () => {
</div>
</SelectItem>
))}
{/* Only show Create Team Account if user has no organizations */}
{cloudOrganizations.length === 0 && (
<>
<SelectSeparator />
<SelectItem value="create-team">
<div className="flex items-center gap-2">
<Plus className="w-4.5 h-4.5" />
<span>{t("cloud:createTeamAccount")}</span>
</div>
</SelectItem>
</>
)}
</SelectContent>
</Select>
</div>

View file

@ -190,11 +190,13 @@ export const CloudView = ({ userInfo, isAuthenticated, cloudApiUrl, onDone, orga
)}
{/* Organization Switcher - moved below email */}
{organizations && organizations.length > 0 && (
<div className="w-full max-w-60 mt-4">
<OrganizationSwitcher userInfo={userInfo} organizations={organizations} />
</div>
)}
<div className="w-full max-w-60 mt-4">
<OrganizationSwitcher
userInfo={userInfo}
organizations={organizations}
cloudApiUrl={cloudApiUrl}
/>
</div>
</div>
)}

View file

@ -1,5 +1,5 @@
import { useState, useEffect } from "react"
import { Building2, User } from "lucide-react"
import { Building2, User, Plus } from "lucide-react"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, SelectSeparator } from "@/components/ui/select"
import { type CloudUserInfo, type CloudOrganizationMembership } from "@roo-code/types"
import { useAppTranslation } from "@src/i18n/TranslationContext"
@ -10,9 +10,15 @@ type OrganizationSwitcherProps = {
userInfo: CloudUserInfo
organizations: CloudOrganizationMembership[]
onOrganizationChange?: (organizationId: string | null) => void
cloudApiUrl?: string
}
export const OrganizationSwitcher = ({ userInfo, organizations, onOrganizationChange }: OrganizationSwitcherProps) => {
export const OrganizationSwitcher = ({
userInfo,
organizations,
onOrganizationChange,
cloudApiUrl,
}: OrganizationSwitcherProps) => {
const { t } = useAppTranslation()
const [selectedOrgId, setSelectedOrgId] = useState<string | null>(userInfo.organizationId || null)
const [isLoading, setIsLoading] = useState(false)
@ -45,6 +51,15 @@ export const OrganizationSwitcher = ({ userInfo, organizations, onOrganizationCh
}, [userInfo.organizationId])
const handleOrganizationChange = async (value: string) => {
// Handle "Create Team Account" option
if (value === "create-team") {
if (cloudApiUrl) {
const billingUrl = `${cloudApiUrl}/billing`
vscode.postMessage({ type: "openExternal", url: billingUrl })
}
return
}
const newOrgId = value === "personal" ? null : value
// Don't do anything if selecting the same organization
@ -69,10 +84,7 @@ export const OrganizationSwitcher = ({ userInfo, organizations, onOrganizationCh
}
}
// If user has no organizations, don't show the switcher
if (!organizations || organizations.length === 0) {
return null
}
// Always show the switcher when user is authenticated
const currentValue = selectedOrgId || "personal"
@ -139,6 +151,19 @@ export const OrganizationSwitcher = ({ userInfo, organizations, onOrganizationCh
</div>
</SelectItem>
))}
{/* Only show Create Team Account if user has no organizations */}
{organizations.length === 0 && (
<>
<SelectSeparator />
<SelectItem value="create-team">
<div className="flex items-center gap-2">
<Plus className="w-4.5 h-4.5" />
<span>{t("cloud:createTeamAccount")}</span>
</div>
</SelectItem>
</>
)}
</SelectContent>
</Select>
</div>

View file

@ -24,6 +24,7 @@
"pasteCallbackUrl": "Copia l'URL de redirect del teu navegador i enganxa-la aquí:",
"startOver": "Torna a començar",
"personalAccount": "Compte Personal",
"createTeamAccount": "Crear Compte d'Equip",
"switchAccount": "Canviar Compte de Roo Code Cloud",
"upsell": {
"autoApprovePowerUser": "Donant-li una mica d'independència a Roo? Controla'l des de qualsevol lloc amb Roo Code Cloud. <learnMoreLink>Més informació</learnMoreLink>.",

View file

@ -24,6 +24,7 @@
"startOver": "Von vorne beginnen",
"personalAccount": "Persönliches Konto",
"switchAccount": "Roo Code Cloud Konto wechseln",
"createTeamAccount": "Team-Konto erstellen",
"cloudUrlPillLabel": "Roo Code Cloud URL",
"upsell": {
"autoApprovePowerUser": "Roo etwas Unabhängigkeit geben? Kontrolliere es von überall mit Roo Code Cloud. <learnMoreLink>Mehr erfahren</learnMoreLink>.",

View file

@ -25,6 +25,7 @@
"startOver": "Start over",
"personalAccount": "Personal Account",
"switchAccount": "Switch Roo Code Cloud Account",
"createTeamAccount": "Create Team Account",
"upsell": {
"autoApprovePowerUser": "Giving Roo some independence? Control it from anywhere with Roo Code Cloud. <learnMoreLink>Learn more</learnMoreLink>.",
"longRunningTask": "This might take a while. Continue from anywhere with Cloud.",

View file

@ -24,6 +24,7 @@
"startOver": "Empezar de nuevo",
"personalAccount": "Cuenta Personal",
"switchAccount": "Cambiar Cuenta de Roo Code Cloud",
"createTeamAccount": "Crear Cuenta de Equipo",
"cloudUrlPillLabel": "URL de Roo Code Cloud",
"upsell": {
"autoApprovePowerUser": "¿Dándole a Roo un poco de independencia? Contrólalo desde cualquier lugar con Roo Code Cloud. <learnMoreLink>Saber más</learnMoreLink>.",

View file

@ -24,6 +24,7 @@
"startOver": "Recommencer",
"personalAccount": "Compte Personnel",
"switchAccount": "Changer de Compte Roo Code Cloud",
"createTeamAccount": "Créer un Compte d'Équipe",
"cloudUrlPillLabel": "URL de Roo Code Cloud",
"upsell": {
"autoApprovePowerUser": "Donner à Roo un peu d'indépendance ? Contrôlez-le de n'importe où avec Roo Code Cloud. <learnMoreLink>En savoir plus</learnMoreLink>.",

View file

@ -24,6 +24,7 @@
"startOver": "फिर से शुरू करें",
"personalAccount": "व्यक्तिगत खाता",
"switchAccount": "Roo Code Cloud खाता बदलें",
"createTeamAccount": "टीम खाता बनाएं",
"cloudUrlPillLabel": "Roo Code Cloud URL",
"upsell": {
"autoApprovePowerUser": "रू को थोड़ी स्वतंत्रता दे रहे हैं? रू कोड क्लाउड के साथ इसे कहीं से भी नियंत्रित करें। <learnMoreLink>और जानें</learnMoreLink>।",

View file

@ -24,6 +24,7 @@
"startOver": "Mulai dari awal",
"personalAccount": "Akun Pribadi",
"switchAccount": "Ganti Akun Roo Code Cloud",
"createTeamAccount": "Buat Akun Tim",
"cloudUrlPillLabel": "URL Roo Code Cloud",
"upsell": {
"autoApprovePowerUser": "Memberi Roo sedikit kebebasan? Kendalikan dari mana saja dengan Roo Code Cloud. <learnMoreLink>Pelajari lebih lanjut</learnMoreLink>.",

View file

@ -24,6 +24,7 @@
"startOver": "Ricomincia",
"personalAccount": "Account Personale",
"switchAccount": "Cambia Account Roo Code Cloud",
"createTeamAccount": "Crea Account del Team",
"cloudUrlPillLabel": "URL di Roo Code Cloud",
"upsell": {
"autoApprovePowerUser": "Vuoi dare un po' di indipendenza a Roo? Controllalo da qualsiasi luogo con Roo Code Cloud. <learnMoreLink>Scopri di più</learnMoreLink>.",

View file

@ -24,6 +24,7 @@
"startOver": "最初からやり直す",
"personalAccount": "個人アカウント",
"switchAccount": "Roo Code Cloud アカウントを切り替え",
"createTeamAccount": "チームアカウントを作成",
"cloudUrlPillLabel": "Roo Code Cloud URL",
"upsell": {
"autoApprovePowerUser": "Rooに少し独立性を与えませんかRoo Code Cloudでどこからでもコントロールできます。<learnMoreLink>詳細</learnMoreLink>。",

View file

@ -24,6 +24,7 @@
"startOver": "다시 시작",
"personalAccount": "개인 계정",
"switchAccount": "Roo Code Cloud 계정 전환",
"createTeamAccount": "팀 계정 만들기",
"cloudUrlPillLabel": "Roo Code Cloud URL",
"upsell": {
"autoApprovePowerUser": "Roo에게 약간의 독립성을 부여하시겠습니까? Roo Code Cloud로 어디서든 제어하세요. <learnMoreLink>더 알아보기</learnMoreLink>.",

View file

@ -24,6 +24,7 @@
"startOver": "Opnieuw beginnen",
"personalAccount": "Persoonlijk Account",
"switchAccount": "Wissel van Roo Code Cloud Account",
"createTeamAccount": "Teamaccount aanmaken",
"cloudUrlPillLabel": "Roo Code Cloud URL",
"upsell": {
"autoApprovePowerUser": "Roo wat onafhankelijkheid geven? Bedien het overal met Roo Code Cloud. <learnMoreLink>Meer informatie</learnMoreLink>.",

View file

@ -24,6 +24,7 @@
"startOver": "Zacznij od nowa",
"personalAccount": "Konto Osobiste",
"switchAccount": "Przełącz Konto Roo Code Cloud",
"createTeamAccount": "Utwórz Konto Zespołu",
"cloudUrlPillLabel": "URL Roo Code Cloud",
"upsell": {
"autoApprovePowerUser": "Dać Roo trochę niezależności? Kontroluj go z dowolnego miejsca dzięki Roo Code Cloud. <learnMoreLink>Dowiedz się więcej</learnMoreLink>.",

View file

@ -24,6 +24,7 @@
"startOver": "Recomeçar",
"personalAccount": "Conta Pessoal",
"switchAccount": "Alternar Conta do Roo Code Cloud",
"createTeamAccount": "Criar Conta de Equipe",
"cloudUrlPillLabel": "URL do Roo Code Cloud ",
"upsell": {
"autoApprovePowerUser": "Dando um pouco de independência ao Roo? Controle-o de qualquer lugar com o Roo Code Cloud. <learnMoreLink>Saiba mais</learnMoreLink>.",

View file

@ -24,6 +24,7 @@
"startOver": "Начать заново",
"personalAccount": "Личный аккаунт",
"switchAccount": "Переключить аккаунт Roo Code Cloud",
"createTeamAccount": "Создать командный аккаунт",
"cloudUrlPillLabel": "URL Roo Code Cloud",
"upsell": {
"autoApprovePowerUser": "Предоставить Roo немного независимости? Управляйте им из любого места с помощью Roo Code Cloud. <learnMoreLink>Узнать больше</learnMoreLink>.",

View file

@ -24,6 +24,7 @@
"startOver": "Baştan başla",
"personalAccount": "Kişisel Hesap",
"switchAccount": "Roo Code Cloud Hesabını Değiştir",
"createTeamAccount": "Takım Hesabı Oluştur",
"cloudUrlPillLabel": "Roo Code Cloud URL'si",
"upsell": {
"autoApprovePowerUser": "Roo'ya biraz bağımsızlık mı veriyorsunuz? Roo Code Cloud ile onu her yerden kontrol edin. <learnMoreLink>Daha fazla bilgi edinin</learnMoreLink>.",

View file

@ -24,6 +24,7 @@
"startOver": "Bắt đầu lại",
"personalAccount": "Tài Khoản Cá Nhân",
"switchAccount": "Chuyển Tài Khoản Roo Code Cloud",
"createTeamAccount": "Tạo Tài Khoản Nhóm",
"cloudUrlPillLabel": "URL Roo Code Cloud",
"upsell": {
"autoApprovePowerUser": "Trao cho Roo một chút độc lập? Kiểm soát nó từ mọi nơi với Roo Code Cloud. <learnMoreLink>Tìm hiểu thêm</learnMoreLink>.",

View file

@ -24,6 +24,7 @@
"startOver": "重新开始",
"personalAccount": "个人账户",
"switchAccount": "切换 Roo Code Cloud 账户",
"createTeamAccount": "创建团队账户",
"cloudUrlPillLabel": "Roo Code Cloud URL",
"upsell": {
"autoApprovePowerUser": "给 Roo 一些独立性?使用 Roo Code Cloud 从任何地方控制它。 <learnMoreLink>了解更多</learnMoreLink>。",

View file

@ -24,6 +24,7 @@
"startOver": "重新開始",
"personalAccount": "個人帳戶",
"switchAccount": "切換 Roo Code Cloud 帳戶",
"createTeamAccount": "創建團隊帳戶",
"cloudUrlPillLabel": "Roo Code Cloud URL",
"upsell": {
"autoApprovePowerUser": "給 Roo 一點獨立性?使用 Roo Code Cloud 隨時隨地控制它。<learnMoreLink>了解更多</learnMoreLink>。",