Skip to content

Commit

Permalink
Add progress indicator
Browse files Browse the repository at this point in the history
  • Loading branch information
pkukielka committed Nov 25, 2024
1 parent 605a72d commit ecf0cc7
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 48 deletions.
25 changes: 19 additions & 6 deletions vscode/webviews/components/AccountSwitcher.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
import { ChevronDown, ChevronRight, ChevronsUpDown, CircleMinus, Plus } from 'lucide-react'
import type * as React from 'react'
import {KeyboardEvent, useCallback, useState} from 'react'
import { type KeyboardEvent, useCallback, useState } from 'react'
import { isSourcegraphToken } from '../../src/chat/protocol'
import { Badge } from '../components/shadcn/ui/badge'
import { Form, FormControl, FormField, FormLabel, FormMessage, FormSubmit } from '../components/shadcn/ui/form'
import {
Form,
FormControl,
FormField,
FormLabel,
FormMessage,
FormSubmit,
} from '../components/shadcn/ui/form'
import { getVSCodeAPI } from '../utils/VSCodeApi'
import { Button } from './shadcn/ui/button'
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from './shadcn/ui/collapsible'
import { Popover, PopoverContent, PopoverTrigger } from './shadcn/ui/popover'

export const AccountSwitcher: React.FC<{ activeEndpoint: string; endpoints: string[] }> = ({
interface AccountSwitcherProps {
activeEndpoint: string
endpoints: string[]
setLoading: (loading: boolean) => void
}

export const AccountSwitcher: React.FC<AccountSwitcherProps> = ({
activeEndpoint,
endpoints,
setLoading,
}) => {
type PopoverView = 'switch' | 'remove' | 'add'
const [getPopoverView, serPopoverView] = useState<PopoverView>('switch')
Expand All @@ -23,14 +37,12 @@ export const AccountSwitcher: React.FC<{ activeEndpoint: string; endpoints: stri
accessToken: '',
})


const onKeyDownInPopoverContent = (event: KeyboardEvent<HTMLDivElement>): void => {
if (event.key === 'Escape' && isOpen) {
onOpenChange(false)
}
}


const onOpenChange = (open: boolean): void => {
setIsOpen(open)
if (!open) {
Expand All @@ -57,6 +69,7 @@ export const AccountSwitcher: React.FC<{ activeEndpoint: string; endpoints: stri
})
}
onOpenChange(false)
setLoading(true)
}}
>
{endpoint}
Expand Down Expand Up @@ -182,7 +195,7 @@ export const AccountSwitcher: React.FC<{ activeEndpoint: string; endpoints: stri
</Collapsible>
<FormSubmit asChild>
<Button
key={"add-account-confirmation-button"}
key={'add-account-confirmation-button'}
type="submit"
variant="ghost"
className="tw-w-full tw-bg-blue-500"
Expand Down
94 changes: 52 additions & 42 deletions vscode/webviews/tabs/AccountTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
type UserProductSubscription,
isCodyProUser,
} from '@sourcegraph/cody-shared'
import { useCallback } from 'react'
import { useCallback, useEffect, useState } from 'react'
import { URI } from 'vscode-uri'
import {
ACCOUNT_UPGRADE_URL,
Expand Down Expand Up @@ -40,12 +40,16 @@ export const AccountTab: React.FC<AccountTabProps> = ({
}

if (!authStatus.authenticated || userProductSubscription === undefined) {
return <div>Authenticating...</div>
return null
}

const [isLoading, setIsLoading] = useState(true)
useEffect(() => {
setIsLoading(!authStatus.authenticated)
}, [authStatus])

const { displayName, username, primaryEmail, endpoint } = authStatus as AuthenticatedAuthStatus
const isProUser = isCodyProUser(authStatus, userProductSubscription)
const actions: JSX.Element[] = []

function createButton(text: string, onClick: () => void) {
return (
Expand All @@ -61,50 +65,41 @@ export const AccountTab: React.FC<AccountTabProps> = ({
)
}

if (isDotComUser && !isProUser) {
actions.push(
createButton('Upgrade', () =>
getVSCodeAPI().postMessage({ command: 'links', value: ACCOUNT_UPGRADE_URL.toString() })
)
)
}
const endpoints: string[] = config.endpointHistory ?? []
const switchableEndpoints = endpoints.filter(e => e !== endpoint)
const accountSwitcher = (
<AccountSwitcher
activeEndpoint={endpoint}
endpoints={switchableEndpoints}
setLoading={setIsLoading}
/>
)

let accountSwitcher = <div />
if (clientCapabilities.accountSwitchingInWebview === 'enabled') {
const endpoints: string[] = config.endpointHistory ?? []
const switchableEndpoints = endpoints.filter(e => e !== endpoint)
accountSwitcher = <AccountSwitcher activeEndpoint={endpoint} endpoints={switchableEndpoints} />
}
const upgradeButton = createButton('Upgrade', () =>
getVSCodeAPI().postMessage({ command: 'links', value: ACCOUNT_UPGRADE_URL.toString() })
)

if (isDotComUser) {
actions.push(
createButton(
'Manage Account',
useCallback(() => {
if (username) {
const uri = URI.parse(ACCOUNT_USAGE_URL.toString()).with({
query: `cody_client_user=${encodeURIComponent(username)}`,
})
getVSCodeAPI().postMessage({ command: 'links', value: uri.toString() })
}
}, [username])
)
)
}
const manageAccountButton = createButton(
'Manage Account',
useCallback(() => {
if (username) {
const uri = URI.parse(ACCOUNT_USAGE_URL.toString()).with({
query: `cody_client_user=${encodeURIComponent(username)}`,
})
getVSCodeAPI().postMessage({ command: 'links', value: uri.toString() })
}
}, [username])
)

actions.push(
createButton('Settings', () =>
getVSCodeAPI().postMessage({ command: 'command', id: 'cody.status-bar.interacted' })
)
const settingButton = createButton('Settings', () =>
getVSCodeAPI().postMessage({ command: 'command', id: 'cody.status-bar.interacted' })
)

actions.push(
createButton('Sign Out', () => {
getVSCodeAPI().postMessage({ command: 'auth', authKind: 'signout' })
})
const signOutButton = createButton('Sign Out', () =>
getVSCodeAPI().postMessage({ command: 'auth', authKind: 'signout' })
)

return (
const accountPanelView = (
<div className="tw-overflow-auto tw-flex-1 tw-flex tw-flex-col tw-items-start tw-w-full tw-px-8 tw-py-6 tw-gap-6">
<h2>Account</h2>
<div className="tw-w-full tw-px-8 tw-py-4 tw-flex tw-flex-col tw-gap-4 tw-bg-popover tw-border tw-border-border tw-rounded-lg">
Expand All @@ -119,9 +114,10 @@ export const AccountTab: React.FC<AccountTabProps> = ({
<p className="tw-text-lg tw-font-semibold">{displayName ?? username}</p>
<p className="tw-text-sm tw-text-muted-foreground">{primaryEmail}</p>
</div>
{accountSwitcher}
{clientCapabilities.accountSwitchingInWebview === 'enabled' && accountSwitcher}
</div>
</div>
{isLoading && <div>LOADING...</div>}
<div className="tw-grid tw-grid-cols-5 tw-gap-4">
<div>Plan:</div>
<div className="tw-text-muted-foreground tw-col-span-4">
Expand All @@ -135,7 +131,21 @@ export const AccountTab: React.FC<AccountTabProps> = ({
</div>
</div>
</div>
<div className="tw-w-full">{actions}</div>
<div className="tw-w-full">
{isDotComUser && !isProUser && upgradeButton}
{isDotComUser && manageAccountButton}
{settingButton}
{signOutButton}
</div>
</div>
)

const loadingView = (
<div className="tw-flex tw-flex-col tw-items-center tw-justify-center tw-h-full tw-w-full tw-gap-2">
<div className="tw-h-[30px] tw-w-[30px] tw-animate-spin tw-rounded-full tw-border-[1px] tw-border-solid tw-border-current tw-border-e-transparent high-contrast-dark:tw-border-button-border high-contrast-dark:tw-border-e-transparent" />
<div className="tw-text-muted-foreground">Switching Account...</div>
</div>
)

return isLoading ? loadingView : accountPanelView
}

0 comments on commit ecf0cc7

Please sign in to comment.