From 9baaccb4be40b5dba1e2cf76db5ebd182f683abf Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Sun, 9 Mar 2025 16:49:38 -0700 Subject: [PATCH] improvement(ui): fixed some styling for credential selector --- .../components/credential-selector.tsx | 61 +++++++++++++++---- components/ui/oauth-required-modal.tsx | 26 ++++++-- lib/oauth.ts | 10 +++ 3 files changed, 79 insertions(+), 18 deletions(-) diff --git a/app/w/[id]/components/workflow-block/components/sub-block/components/credential-selector.tsx b/app/w/[id]/components/workflow-block/components/sub-block/components/credential-selector.tsx index 565093319..c543c832d 100644 --- a/app/w/[id]/components/workflow-block/components/sub-block/components/credential-selector.tsx +++ b/app/w/[id]/components/workflow-block/components/sub-block/components/credential-selector.tsx @@ -21,6 +21,7 @@ import { getProviderIdFromServiceId, getServiceByProviderAndId, getServiceIdFromScopes, + parseProvider, } from '@/lib/oauth' import { saveToStorage } from '@/stores/workflows/persistence' @@ -168,26 +169,62 @@ export function CredentialSelector({ // Get provider icon const getProviderIcon = (providerName: OAuthProvider) => { - const providerConfig = OAUTH_PROVIDERS[providerName] - if (providerConfig) { - return providerConfig.icon({ className: 'h-4 w-4' }) + const { baseProvider } = parseProvider(providerName) + const baseProviderConfig = OAUTH_PROVIDERS[baseProvider] + + if (!baseProviderConfig) { + return } - return + + // For compound providers, find the specific service + if (providerName.includes('-')) { + for (const service of Object.values(baseProviderConfig.services)) { + if (service.providerId === providerName) { + return service.icon({ className: 'h-4 w-4' }) + } + } + } + + // Fallback to base provider icon + return baseProviderConfig.icon({ className: 'h-4 w-4' }) } // Get provider name const getProviderName = (providerName: OAuthProvider) => { const effectiveServiceId = getServiceId() try { + // First try to get the service by provider and service ID const service = getServiceByProviderAndId(providerName, effectiveServiceId) return service.name } catch (error) { - // Fallback to provider name if service not found - const providerConfig = OAUTH_PROVIDERS[providerName] - if (providerConfig) { - return providerConfig.name + // If that fails, try to get the service by parsing the provider + try { + const { baseProvider } = parseProvider(providerName) + const baseProviderConfig = OAUTH_PROVIDERS[baseProvider] + + // For compound providers like 'google-sheets', try to find the specific service + if (providerName.includes('-')) { + const serviceKey = providerName.split('-')[1] || '' + for (const [key, service] of Object.entries(baseProviderConfig?.services || {})) { + if (key === serviceKey || key === providerName || service.providerId === providerName) { + return service.name + } + } + } + + // Fallback to provider name if service not found + if (baseProviderConfig) { + return baseProviderConfig.name + } + } catch (parseError) { + // Ignore parse error and continue to final fallback } + + // Final fallback: capitalize the provider name return providerName + .split('-') + .map((part) => part.charAt(0).toUpperCase() + part.slice(1)) + .join(' ') } } @@ -209,8 +246,8 @@ export function CredentialSelector({ ) : (
- - {label} + {getProviderIcon(provider)} + {label}
)} @@ -228,7 +265,7 @@ export function CredentialSelector({ ) : (
-

No credentials found.

+

No credentials found.

Connect a new account to continue.

@@ -255,7 +292,7 @@ export function CredentialSelector({
- + {getProviderIcon(provider)} Connect {getProviderName(provider)} account
diff --git a/components/ui/oauth-required-modal.tsx b/components/ui/oauth-required-modal.tsx index ed5100bfc..589c3cacb 100644 --- a/components/ui/oauth-required-modal.tsx +++ b/components/ui/oauth-required-modal.tsx @@ -16,6 +16,7 @@ import { OAuthProvider, getProviderIdFromServiceId, getServiceIdFromScopes, + parseProvider, } from '@/lib/oauth' import { saveToStorage } from '@/stores/workflows/persistence' @@ -60,10 +61,25 @@ export function OAuthRequiredModal({ requiredScopes = [], serviceId, }: OAuthRequiredModalProps) { - // Get provider configuration - const providerConfig = OAUTH_PROVIDERS[provider] - const providerName = providerConfig?.name || provider - const ProviderIcon = providerConfig?.icon || (() => null) + // Get provider configuration and service + const effectiveServiceId = serviceId || getServiceIdFromScopes(provider, requiredScopes) + const { baseProvider } = parseProvider(provider) + const baseProviderConfig = OAUTH_PROVIDERS[baseProvider] + + // Default to base provider name and icon + let providerName = baseProviderConfig?.name || provider + let ProviderIcon = baseProviderConfig?.icon || (() => null) + + // Try to find the specific service + if (baseProviderConfig) { + for (const service of Object.values(baseProviderConfig.services)) { + if (service.id === effectiveServiceId || service.providerId === provider) { + providerName = service.name + ProviderIcon = service.icon + break + } + } + } // Filter out userinfo scopes as they're not relevant to show to users const displayScopes = requiredScopes.filter( @@ -73,7 +89,6 @@ export function OAuthRequiredModal({ const handleRedirectToSettings = () => { try { // Determine the appropriate serviceId and providerId - const effectiveServiceId = serviceId || getServiceIdFromScopes(provider, requiredScopes) const providerId = getProviderIdFromServiceId(effectiveServiceId) // Store information about the required connection @@ -98,7 +113,6 @@ export function OAuthRequiredModal({ const handleConnectDirectly = async () => { try { // Determine the appropriate serviceId and providerId - const effectiveServiceId = serviceId || getServiceIdFromScopes(provider, requiredScopes) const providerId = getProviderIdFromServiceId(effectiveServiceId) // Store information about the required connection diff --git a/lib/oauth.ts b/lib/oauth.ts index 6c1fe5af7..2c0aa6ec0 100644 --- a/lib/oauth.ts +++ b/lib/oauth.ts @@ -39,6 +39,7 @@ export interface OAuthServiceConfig { description: string providerId: string icon: (props: { className?: string }) => ReactNode + baseProviderIcon: (props: { className?: string }) => ReactNode scopes: string[] } @@ -55,6 +56,7 @@ export const OAUTH_PROVIDERS: Record = { description: 'Automate email workflows and enhance communication efficiency.', providerId: 'google-email', icon: (props) => GmailIcon(props), + baseProviderIcon: (props) => GoogleIcon(props), scopes: [ 'https://www.googleapis.com/auth/gmail.send', 'https://www.googleapis.com/auth/gmail.readonly', @@ -66,6 +68,7 @@ export const OAUTH_PROVIDERS: Record = { description: 'Streamline file organization and document workflows.', providerId: 'google-drive', icon: (props) => GoogleDriveIcon(props), + baseProviderIcon: (props) => GoogleIcon(props), scopes: ['https://www.googleapis.com/auth/drive'], }, 'google-docs': { @@ -74,6 +77,7 @@ export const OAUTH_PROVIDERS: Record = { description: 'Create, read, and edit Google Documents programmatically.', providerId: 'google-docs', icon: (props) => GoogleDocsIcon(props), + baseProviderIcon: (props) => GoogleIcon(props), scopes: ['https://www.googleapis.com/auth/documents'], }, 'google-sheets': { @@ -82,6 +86,7 @@ export const OAUTH_PROVIDERS: Record = { description: 'Manage and analyze data with Google Sheets integration.', providerId: 'google-sheets', icon: (props) => GoogleSheetsIcon(props), + baseProviderIcon: (props) => GoogleIcon(props), scopes: ['https://www.googleapis.com/auth/spreadsheets'], }, 'google-calendar': { @@ -90,6 +95,7 @@ export const OAUTH_PROVIDERS: Record = { description: 'Schedule and manage events with Google Calendar.', providerId: 'google-calendar', icon: (props) => GoogleCalendarIcon(props), + baseProviderIcon: (props) => GoogleIcon(props), scopes: ['https://www.googleapis.com/auth/calendar'], }, }, @@ -106,6 +112,7 @@ export const OAUTH_PROVIDERS: Record = { description: 'Manage repositories, issues, and pull requests.', providerId: 'github-repo', icon: (props) => GithubIcon(props), + baseProviderIcon: (props) => GithubIcon(props), scopes: ['repo', 'user'], }, 'github-workflow': { @@ -114,6 +121,7 @@ export const OAUTH_PROVIDERS: Record = { description: 'Trigger and manage GitHub Actions workflows.', providerId: 'github-workflow', icon: (props) => GithubIcon(props), + baseProviderIcon: (props) => GithubIcon(props), scopes: ['repo', 'workflow'], }, }, @@ -130,6 +138,7 @@ export const OAUTH_PROVIDERS: Record = { description: 'Post tweets and interact with the X API.', providerId: 'x', icon: (props) => xIcon(props), + baseProviderIcon: (props) => xIcon(props), scopes: [], }, }, @@ -146,6 +155,7 @@ export const OAUTH_PROVIDERS: Record = { description: 'Connect to your Supabase projects and manage data.', providerId: 'supabase', icon: (props) => SupabaseIcon(props), + baseProviderIcon: (props) => SupabaseIcon(props), scopes: ['database.read', 'database.write', 'projects.read'], }, },