Compare commits

..

3 Commits

Author SHA1 Message Date
Vikhyath Mondreti
7e889f5eec fix attempt 2 2026-01-13 00:04:15 -08:00
Vikhyath Mondreti
d8f3169256 fix 2026-01-12 23:54:50 -08:00
Vikhyath Mondreti
de2294f565 fix(slack): race condition in credential selection 2026-01-12 23:51:16 -08:00
2 changed files with 61 additions and 3 deletions

View File

@@ -1,6 +1,6 @@
'use client'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { createLogger } from '@sim/logger'
import { ExternalLink, Users } from 'lucide-react'
import { Button, Combobox } from '@/components/emcn/components'
@@ -29,6 +29,20 @@ import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
const logger = createLogger('CredentialSelector')
const isBillingEnabled = isTruthy(getEnv('NEXT_PUBLIC_BILLING_ENABLED'))
function useStableCredentialIds(credentials: Array<{ id: string }>) {
const knownIdsRef = useRef<Set<string>>(new Set())
for (const cred of credentials) {
knownIdsRef.current.add(cred.id)
}
const isKnownCredentialId = useCallback((id: string): boolean => {
return knownIdsRef.current.has(id)
}, [])
return { isKnownCredentialId }
}
interface CredentialSelectorProps {
blockId: string
subBlock: SubBlockConfig
@@ -92,6 +106,8 @@ export function CredentialSelector({
refetch: refetchCredentials,
} = useOAuthCredentials(effectiveProviderId, Boolean(effectiveProviderId))
const { isKnownCredentialId } = useStableCredentialIds(credentials)
const selectedCredential = useMemo(
() => credentials.find((cred) => cred.id === selectedId),
[credentials, selectedId]
@@ -140,7 +156,8 @@ export function CredentialSelector({
!selectedCredential &&
!hasForeignMeta &&
!credentialsLoading &&
!foreignMetaLoading
!foreignMetaLoading &&
!isKnownCredentialId(selectedId)
useEffect(() => {
if (!invalidSelection) return
@@ -348,10 +365,22 @@ export function CredentialSelector({
return
}
if (isKnownCredentialId(value)) {
handleSelect(value)
return
}
setIsEditing(true)
setInputValue(value)
},
[credentials, credentialSets, handleAddCredential, handleSelect, handleCredentialSetSelect]
[
credentials,
credentialSets,
handleAddCredential,
handleSelect,
handleCredentialSetSelect,
isKnownCredentialId,
]
)
return (

View File

@@ -35,6 +35,7 @@ import { getDependsOnFields } from '@/blocks/utils'
import { useKnowledgeBase } from '@/hooks/kb/use-knowledge'
import { useMcpServers, useMcpToolsQuery } from '@/hooks/queries/mcp'
import { useCredentialName } from '@/hooks/queries/oauth-credentials'
import { useCollaborativeWorkflow } from '@/hooks/use-collaborative-workflow'
import { useSelectorDisplayName } from '@/hooks/use-selector-display-name'
import { useVariablesStore } from '@/stores/panel'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
@@ -612,6 +613,34 @@ export const WorkflowBlock = memo(function WorkflowBlock({
[isDeploying, setDeploymentStatus, refetchDeployment]
)
const { collaborativeSetSubblockValue } = useCollaborativeWorkflow()
/**
* Clear credential-dependent fields when credential changes to prevent
* stale data from persisting with new credentials.
*/
const prevCredRef = useRef<string | undefined>(undefined)
useEffect(() => {
const activeWorkflowId = useWorkflowRegistry.getState().activeWorkflowId
if (!activeWorkflowId) return
const current = useSubBlockStore.getState().workflowValues[activeWorkflowId]?.[id]
if (!current) return
const credValue = current.credential
const cred =
typeof credValue === 'object' && credValue !== null && 'value' in credValue
? ((credValue as { value?: unknown }).value as string | undefined)
: (credValue as string | undefined)
if (prevCredRef.current !== cred) {
const hadPreviousCredential = prevCredRef.current !== undefined
prevCredRef.current = cred
if (hadPreviousCredential) {
const keys = Object.keys(current)
const dependentKeys = keys.filter((k) => k !== 'credential')
dependentKeys.forEach((k) => collaborativeSetSubblockValue(id, k, ''))
}
}
}, [id, collaborativeSetSubblockValue])
const currentStoreBlock = currentWorkflow.getBlockById(id)
const isStarterBlock = type === 'starter'