Просмотр исходного кода

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

Matt Rubens 3 месяцев назад
Родитель
Сommit
d3d0967fc3

+ 2 - 7
webview-ui/src/components/chat/ChatTextArea.tsx

@@ -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>

+ 26 - 4
webview-ui/src/components/cloud/CloudAccountSwitcher.tsx

@@ -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>

+ 7 - 5
webview-ui/src/components/cloud/CloudView.tsx

@@ -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>
 						)}
 

+ 31 - 6
webview-ui/src/components/cloud/OrganizationSwitcher.tsx

@@ -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>

+ 1 - 0
webview-ui/src/i18n/locales/ca/cloud.json

@@ -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>.",

+ 1 - 0
webview-ui/src/i18n/locales/de/cloud.json

@@ -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>.",

+ 1 - 0
webview-ui/src/i18n/locales/en/cloud.json

@@ -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.",

+ 1 - 0
webview-ui/src/i18n/locales/es/cloud.json

@@ -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>.",

+ 1 - 0
webview-ui/src/i18n/locales/fr/cloud.json

@@ -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>.",

+ 1 - 0
webview-ui/src/i18n/locales/hi/cloud.json

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

+ 1 - 0
webview-ui/src/i18n/locales/id/cloud.json

@@ -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>.",

+ 1 - 0
webview-ui/src/i18n/locales/it/cloud.json

@@ -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>.",

+ 1 - 0
webview-ui/src/i18n/locales/ja/cloud.json

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

+ 1 - 0
webview-ui/src/i18n/locales/ko/cloud.json

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

+ 1 - 0
webview-ui/src/i18n/locales/nl/cloud.json

@@ -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>.",

+ 1 - 0
webview-ui/src/i18n/locales/pl/cloud.json

@@ -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>.",

+ 1 - 0
webview-ui/src/i18n/locales/pt-BR/cloud.json

@@ -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>.",

+ 1 - 0
webview-ui/src/i18n/locales/ru/cloud.json

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

+ 1 - 0
webview-ui/src/i18n/locales/tr/cloud.json

@@ -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>.",

+ 1 - 0
webview-ui/src/i18n/locales/vi/cloud.json

@@ -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>.",

+ 1 - 0
webview-ui/src/i18n/locales/zh-CN/cloud.json

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

+ 1 - 0
webview-ui/src/i18n/locales/zh-TW/cloud.json

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