Add a little padding to the cloudview (#7954)

This commit is contained in:
Matt Rubens 2025-09-12 23:35:27 -04:00 committed by GitHub
parent c4c478023d
commit 72bc790d6a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -11,6 +11,8 @@ import { ToggleSwitch } from "@/components/ui/toggle-switch"
import { renderCloudBenefitsContent } from "./CloudUpsellDialog"
import { TriangleAlert } from "lucide-react"
import { cn } from "@/lib/utils"
import { Tab, TabContent, TabHeader } from "../common/Tab"
import { Button } from "@/components/ui/button"
// Define the production URL constant locally to avoid importing from cloud package in tests
const PRODUCTION_ROO_CODE_API_URL = "https://app.roocode.com"
@ -153,186 +155,187 @@ export const CloudView = ({ userInfo, isAuthenticated, cloudApiUrl, onDone }: Cl
}
return (
<div className="flex flex-col h-full">
<div className="flex justify-between items-center mb-6">
<h1 className="text-xl font-medium text-vscode-foreground">{isAuthenticated && t("cloud:title")}</h1>
<VSCodeButton appearance="secondary" onClick={onDone}>
{t("settings:common.done")}
</VSCodeButton>
</div>
{isAuthenticated ? (
<>
{userInfo && (
<div className="flex flex-col items-center mb-6">
<div className="w-16 h-16 mb-3 rounded-full overflow-hidden">
{userInfo?.picture ? (
<img
src={userInfo.picture}
alt={t("cloud:profilePicture")}
className="w-full h-full object-cover"
/>
) : (
<div className="w-full h-full flex items-center justify-center bg-vscode-button-background text-vscode-button-foreground text-xl">
{userInfo?.name?.charAt(0) || userInfo?.email?.charAt(0) || "?"}
</div>
)}
</div>
{userInfo.name && (
<h2 className="text-lg font-medium text-vscode-foreground my-0">{userInfo.name}</h2>
)}
{userInfo?.email && (
<p className="text-sm text-vscode-descriptionForeground my-0">{userInfo?.email}</p>
)}
{userInfo?.organizationName && (
<div className="flex items-center gap-2 text-sm text-vscode-descriptionForeground mt-2">
{userInfo.organizationImageUrl && (
<Tab>
<TabHeader className="flex justify-between items-center">
<h3 className="text-vscode-foreground m-0">{isAuthenticated && t("cloud:title")}</h3>
<Button onClick={onDone}>{t("settings:common.done")}</Button>
</TabHeader>
<TabContent>
{isAuthenticated ? (
<>
{userInfo && (
<div className="flex flex-col items-center mb-6">
<div className="w-16 h-16 mb-3 rounded-full overflow-hidden">
{userInfo?.picture ? (
<img
src={userInfo.organizationImageUrl}
alt={userInfo.organizationName}
className="w-4 h-4 rounded object-cover"
src={userInfo.picture}
alt={t("cloud:profilePicture")}
className="w-full h-full object-cover"
/>
)}
<span>{userInfo.organizationName}</span>
</div>
)}
</div>
)}
{/* Task Sync Toggle - Always shown when authenticated */}
<div className="border-t border-vscode-widget-border pt-4 mt-4">
<div className="flex items-center gap-3 mb-2">
<ToggleSwitch
checked={taskSyncEnabled}
onChange={handleTaskSyncToggle}
size="medium"
aria-label={t("cloud:taskSync")}
data-testid="task-sync-toggle"
disabled={!!userInfo?.organizationId}
/>
<span className="font-medium text-vscode-foreground">{t("cloud:taskSync")}</span>
</div>
<div className="text-vscode-descriptionForeground text-sm mt-1 mb-4 ml-8">
{t("cloud:taskSyncDescription")}
</div>
{userInfo?.organizationId && (
<div className="text-vscode-descriptionForeground text-sm mt-1 mb-4 ml-8 italic">
{t("cloud:taskSyncManagedByOrganization")}
</div>
)}
{/* Remote Control Toggle - Only shown when both extensionBridgeEnabled and featureRoomoteControlEnabled are true */}
{userInfo?.extensionBridgeEnabled && featureRoomoteControlEnabled && (
<>
<div className="flex items-center gap-3 mb-2">
<ToggleSwitch
checked={remoteControlEnabled}
onChange={handleRemoteControlToggle}
size="medium"
aria-label={t("cloud:remoteControl")}
data-testid="remote-control-toggle"
disabled={!taskSyncEnabled}
/>
<span className="font-medium text-vscode-foreground">
{t("cloud:remoteControl")}
</span>
</div>
<div className="text-vscode-descriptionForeground text-sm mt-1 mb-4 ml-8">
{t("cloud:remoteControlDescription")}
{!taskSyncEnabled && (
<div className="text-vscode-errorForeground mt-2">
{t("cloud:remoteControlRequiresTaskSync")}
) : (
<div className="w-full h-full flex items-center justify-center bg-vscode-button-background text-vscode-button-foreground text-xl">
{userInfo?.name?.charAt(0) || userInfo?.email?.charAt(0) || "?"}
</div>
)}
</div>
</>
)}
{/* Info text about usage metrics */}
<div className="text-vscode-descriptionForeground text-sm mt-4 mb-4 ml-8 italic">
{t("cloud:usageMetricsAlwaysReported")}
</div>
<hr className="border-vscode-widget-border mb-4" />
</div>
<div className="flex flex-col gap-2 mt-4">
<VSCodeButton appearance="secondary" onClick={handleVisitCloudWebsite} className="w-full">
{t("cloud:visitCloudWebsite")}
</VSCodeButton>
<VSCodeButton appearance="secondary" onClick={handleLogoutClick} className="w-full">
{t("cloud:logOut")}
</VSCodeButton>
</div>
</>
) : (
<>
<div className="flex flex-col items-start gap-4 px-8">
<div className={cn(authInProgress && "opacity-50")}>{renderCloudBenefitsContent(t)}</div>
{!authInProgress && (
<VSCodeButton appearance="primary" onClick={handleConnectClick} className="w-full">
{t("cloud:connect")}
</VSCodeButton>
)}
{/* Manual entry section */}
{authInProgress && !showManualEntry && (
// Timeout message with "Having trouble?" link
<div className="flex flex-col items-start gap-1">
<div className="flex items-center gap-2 text-base text-vscode-descriptionForeground">
<VSCodeProgressRing className="size-3 text-vscode-foreground" />
{t("cloud:authWaiting")}
</div>
{!showManualEntry && (
<button
onClick={handleShowManualEntry}
className="text-base ml-5 text-vscode-textLink-foreground hover:text-vscode-textLink-activeForeground underline cursor-pointer bg-transparent border-none p-0">
{t("cloud:havingTrouble")}
</button>
{userInfo.name && (
<h2 className="text-lg font-medium text-vscode-foreground my-0">{userInfo.name}</h2>
)}
{userInfo?.email && (
<p className="text-sm text-vscode-descriptionForeground my-0">{userInfo?.email}</p>
)}
{userInfo?.organizationName && (
<div className="flex items-center gap-2 text-sm text-vscode-descriptionForeground mt-2">
{userInfo.organizationImageUrl && (
<img
src={userInfo.organizationImageUrl}
alt={userInfo.organizationName}
className="w-4 h-4 rounded object-cover"
/>
)}
<span>{userInfo.organizationName}</span>
</div>
)}
</div>
)}
{showManualEntry && (
// Manual URL entry form
<div className="space-y-2 max-w-72">
<p className="text-base text-vscode-descriptionForeground">
{t("cloud:pasteCallbackUrl")}
</p>
<VSCodeTextField
ref={manualUrlInputRef as any}
value={manualUrl}
onChange={handleManualUrlChange}
onKeyDown={handleKeyDown}
placeholder="vscode://RooVeterinaryInc.roo-cline/auth/clerk/callback?state=..."
className="w-full"
{/* Task Sync Toggle - Always shown when authenticated */}
<div className="border-t border-vscode-widget-border pt-4 mt-4">
<div className="flex items-center gap-3 mb-2">
<ToggleSwitch
checked={taskSyncEnabled}
onChange={handleTaskSyncToggle}
size="medium"
aria-label={t("cloud:taskSync")}
data-testid="task-sync-toggle"
disabled={!!userInfo?.organizationId}
/>
<p className="mt-1">
or{" "}
<button
onClick={handleReset}
className="text-base text-vscode-textLink-foreground hover:text-vscode-textLink-activeForeground underline cursor-pointer bg-transparent border-none p-0">
{t("cloud:startOver")}
</button>
</p>
<span className="font-medium text-vscode-foreground">{t("cloud:taskSync")}</span>
</div>
)}
<div className="text-vscode-descriptionForeground text-sm mt-1 mb-4 ml-8">
{t("cloud:taskSyncDescription")}
</div>
{userInfo?.organizationId && (
<div className="text-vscode-descriptionForeground text-sm mt-1 mb-4 ml-8 italic">
{t("cloud:taskSyncManagedByOrganization")}
</div>
)}
{/* Remote Control Toggle - Only shown when both extensionBridgeEnabled and featureRoomoteControlEnabled are true */}
{userInfo?.extensionBridgeEnabled && featureRoomoteControlEnabled && (
<>
<div className="flex items-center gap-3 mb-2">
<ToggleSwitch
checked={remoteControlEnabled}
onChange={handleRemoteControlToggle}
size="medium"
aria-label={t("cloud:remoteControl")}
data-testid="remote-control-toggle"
disabled={!taskSyncEnabled}
/>
<span className="font-medium text-vscode-foreground">
{t("cloud:remoteControl")}
</span>
</div>
<div className="text-vscode-descriptionForeground text-sm mt-1 mb-4 ml-8">
{t("cloud:remoteControlDescription")}
{!taskSyncEnabled && (
<div className="text-vscode-errorForeground mt-2">
{t("cloud:remoteControlRequiresTaskSync")}
</div>
)}
</div>
</>
)}
{/* Info text about usage metrics */}
<div className="text-vscode-descriptionForeground text-sm mt-4 mb-4 ml-8 italic">
{t("cloud:usageMetricsAlwaysReported")}
</div>
<hr className="border-vscode-widget-border mb-4" />
</div>
<div className="flex flex-col gap-2 mt-4">
<VSCodeButton appearance="secondary" onClick={handleVisitCloudWebsite} className="w-full">
{t("cloud:visitCloudWebsite")}
</VSCodeButton>
<VSCodeButton appearance="secondary" onClick={handleLogoutClick} className="w-full">
{t("cloud:logOut")}
</VSCodeButton>
</div>
</>
) : (
<>
<div className="flex flex-col items-start gap-4 px-8">
<div className={cn(authInProgress && "opacity-50")}>{renderCloudBenefitsContent(t)}</div>
{!authInProgress && (
<VSCodeButton appearance="primary" onClick={handleConnectClick} className="w-full">
{t("cloud:connect")}
</VSCodeButton>
)}
{/* Manual entry section */}
{authInProgress && !showManualEntry && (
// Timeout message with "Having trouble?" link
<div className="flex flex-col items-start gap-1">
<div className="flex items-center gap-2 text-base text-vscode-descriptionForeground">
<VSCodeProgressRing className="size-3 text-vscode-foreground" />
{t("cloud:authWaiting")}
</div>
{!showManualEntry && (
<button
onClick={handleShowManualEntry}
className="text-base ml-5 text-vscode-textLink-foreground hover:text-vscode-textLink-activeForeground underline cursor-pointer bg-transparent border-none p-0">
{t("cloud:havingTrouble")}
</button>
)}
</div>
)}
{showManualEntry && (
// Manual URL entry form
<div className="space-y-2 max-w-72">
<p className="text-base text-vscode-descriptionForeground">
{t("cloud:pasteCallbackUrl")}
</p>
<VSCodeTextField
ref={manualUrlInputRef as any}
value={manualUrl}
onChange={handleManualUrlChange}
onKeyDown={handleKeyDown}
placeholder="vscode://RooVeterinaryInc.roo-cline/auth/clerk/callback?state=..."
className="w-full"
/>
<p className="mt-1">
or{" "}
<button
onClick={handleReset}
className="text-base text-vscode-textLink-foreground hover:text-vscode-textLink-activeForeground underline cursor-pointer bg-transparent border-none p-0">
{t("cloud:startOver")}
</button>
</p>
</div>
)}
</div>
</>
)}
{cloudApiUrl && cloudApiUrl !== PRODUCTION_ROO_CODE_API_URL && (
<div className="ml-8 mt-6 flex justify-start">
<div className="inline-flex items-center gap-2 text-xs">
<TriangleAlert className="size-4 text-vscode-descriptionForeground" />
<span className="text-vscode-foreground/75">{t("cloud:cloudUrlPillLabel")}: </span>
<button
onClick={handleOpenCloudUrl}
className="text-vscode-textLink-foreground hover:text-vscode-textLink-activeForeground underline cursor-pointer bg-transparent border-none p-0">
{cloudApiUrl}
</button>
</div>
</div>
</>
)}
{cloudApiUrl && cloudApiUrl !== PRODUCTION_ROO_CODE_API_URL && (
<div className="ml-8 mt-6 flex justify-start">
<div className="inline-flex items-center gap-2 text-xs">
<TriangleAlert className="size-4 text-vscode-descriptionForeground" />
<span className="text-vscode-foreground/75">{t("cloud:cloudUrlPillLabel")}: </span>
<button
onClick={handleOpenCloudUrl}
className="text-vscode-textLink-foreground hover:text-vscode-textLink-activeForeground underline cursor-pointer bg-transparent border-none p-0">
{cloudApiUrl}
</button>
</div>
</div>
)}
</div>
)}
</TabContent>
</Tab>
)
}