@@ -19,21 +19,17 @@ import {
1919 ModalHeader ,
2020 Tooltip ,
2121} from '@/components/emcn'
22- import { useSession } from '@/lib/auth/auth-client'
23- import { consumeOAuthReturnContext , writeOAuthReturnContext } from '@/lib/credentials/client-state'
24- import {
25- getCanonicalScopesForProvider ,
26- getProviderIdFromServiceId ,
27- type OAuthProvider ,
28- } from '@/lib/oauth'
22+ import { consumeOAuthReturnContext } from '@/lib/credentials/client-state'
23+ import { getProviderIdFromServiceId , type OAuthProvider } from '@/lib/oauth'
2924import { ConnectorSelectorField } from '@/app/workspace/[workspaceId]/knowledge/[id]/components/add-connector-modal/components/connector-selector-field'
30- import { OAuthRequiredModal } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/credential-selector/components/oauth-required -modal'
25+ import { ConnectCredentialModal } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/credential-selector/components/connect-credential -modal'
3126import { getDependsOnFields } from '@/blocks/utils'
3227import { CONNECTOR_REGISTRY } from '@/connectors/registry'
3328import type { ConnectorConfig , ConnectorConfigField } from '@/connectors/types'
3429import { useCreateConnector } from '@/hooks/queries/kb/connectors'
3530import { useOAuthCredentials } from '@/hooks/queries/oauth/oauth-credentials'
3631import type { SelectorKey } from '@/hooks/selectors/types'
32+ import { useCredentialRefreshTriggers } from '@/hooks/use-credential-refresh-triggers'
3733
3834const SYNC_INTERVALS = [
3935 { label : 'Every hour' , value : 60 } ,
@@ -69,7 +65,6 @@ export function AddConnectorModal({ open, onOpenChange, knowledgeBaseId }: AddCo
6965 const [ searchTerm , setSearchTerm ] = useState ( '' )
7066
7167 const { workspaceId } = useParams < { workspaceId : string } > ( )
72- const { data : session } = useSession ( )
7368 const { mutate : createConnector , isPending : isCreating } = useCreateConnector ( )
7469
7570 const connectorConfig = selectedType ? CONNECTOR_REGISTRY [ selectedType ] : null
@@ -82,10 +77,16 @@ export function AddConnectorModal({ open, onOpenChange, knowledgeBaseId }: AddCo
8277 [ connectorConfig ]
8378 )
8479
85- const { data : credentials = [ ] , isLoading : credentialsLoading } = useOAuthCredentials (
86- connectorProviderId ?? undefined ,
87- { enabled : Boolean ( connectorConfig ) && ! isApiKeyMode , workspaceId }
88- )
80+ const {
81+ data : credentials = [ ] ,
82+ isLoading : credentialsLoading ,
83+ refetch : refetchCredentials ,
84+ } = useOAuthCredentials ( connectorProviderId ?? undefined , {
85+ enabled : Boolean ( connectorConfig ) && ! isApiKeyMode ,
86+ workspaceId,
87+ } )
88+
89+ useCredentialRefreshTriggers ( refetchCredentials , connectorProviderId ?? undefined , workspaceId )
8990
9091 const effectiveCredentialId =
9192 selectedCredentialId ?? ( credentials . length === 1 ? credentials [ 0 ] . id : null )
@@ -263,51 +264,9 @@ export function AddConnectorModal({ open, onOpenChange, knowledgeBaseId }: AddCo
263264 )
264265 }
265266
266- const handleConnectNewAccount = useCallback ( async ( ) => {
267- if ( ! connectorConfig || ! connectorProviderId || ! workspaceId ) return
268-
269- const userName = session ?. user ?. name
270- const integrationName = connectorConfig . name
271- const displayName = userName ? `${ userName } 's ${ integrationName } ` : integrationName
272-
273- try {
274- const res = await fetch ( '/api/credentials/draft' , {
275- method : 'POST' ,
276- headers : { 'Content-Type' : 'application/json' } ,
277- body : JSON . stringify ( {
278- workspaceId,
279- providerId : connectorProviderId ,
280- displayName,
281- } ) ,
282- } )
283- if ( ! res . ok ) {
284- setError ( 'Failed to prepare credential. Please try again.' )
285- return
286- }
287- } catch {
288- setError ( 'Failed to prepare credential. Please try again.' )
289- return
290- }
291-
292- writeOAuthReturnContext ( {
293- origin : 'kb-connectors' ,
294- knowledgeBaseId,
295- displayName,
296- providerId : connectorProviderId ,
297- preCount : credentials . length ,
298- workspaceId,
299- requestedAt : Date . now ( ) ,
300- } )
301-
267+ const handleConnectNewAccount = useCallback ( ( ) => {
302268 setShowOAuthModal ( true )
303- } , [
304- connectorConfig ,
305- connectorProviderId ,
306- workspaceId ,
307- session ?. user ?. name ,
308- knowledgeBaseId ,
309- credentials . length ,
310- ] )
269+ } , [ ] )
311270
312271 const filteredEntries = useMemo ( ( ) => {
313272 const term = searchTerm . toLowerCase ( ) . trim ( )
@@ -396,40 +355,40 @@ export function AddConnectorModal({ open, onOpenChange, knowledgeBaseId }: AddCo
396355 ) : (
397356 < div className = 'flex flex-col gap-2' >
398357 < Label > Account</ Label >
399- { credentialsLoading ? (
400- < div className = 'flex items-center gap-2 text-[var(--text-muted)] text-small' >
401- < Loader2 className = 'h-4 w-4 animate-spin' />
402- Loading credentials...
403- </ div >
404- ) : (
405- < Combobox
406- size = 'sm'
407- options = { [
408- ...credentials . map (
409- ( cred ) : ComboboxOption => ( {
410- label : cred . name || cred . provider ,
411- value : cred . id ,
412- icon : connectorConfig . icon ,
413- } )
414- ) ,
415- {
416- label : 'Connect new account' ,
417- value : '__connect_new__' ,
418- icon : Plus ,
419- onSelect : ( ) => {
420- void handleConnectNewAccount ( )
421- } ,
358+ < Combobox
359+ size = 'sm'
360+ options = { [
361+ ...credentials . map (
362+ ( cred ) : ComboboxOption => ( {
363+ label : cred . name || cred . provider ,
364+ value : cred . id ,
365+ icon : connectorConfig . icon ,
366+ } )
367+ ) ,
368+ {
369+ label :
370+ credentials . length > 0
371+ ? `Connect another ${ connectorConfig . name } account`
372+ : `Connect ${ connectorConfig . name } account` ,
373+ value : '__connect_new__' ,
374+ icon : Plus ,
375+ onSelect : ( ) => {
376+ void handleConnectNewAccount ( )
422377 } ,
423- ] }
424- value = { effectiveCredentialId ?? undefined }
425- onChange = { ( value ) => setSelectedCredentialId ( value ) }
426- placeholder = {
427- credentials . length === 0
428- ? `No ${ connectorConfig . name } accounts`
429- : 'Select account'
430- }
431- />
432- ) }
378+ } ,
379+ ] }
380+ value = { effectiveCredentialId ?? undefined }
381+ onChange = { ( value ) => setSelectedCredentialId ( value ) }
382+ onOpenChange = { ( isOpen ) => {
383+ if ( isOpen ) void refetchCredentials ( )
384+ } }
385+ placeholder = {
386+ credentials . length === 0
387+ ? `No ${ connectorConfig . name } accounts`
388+ : 'Select account'
389+ }
390+ isLoading = { credentialsLoading }
391+ />
433392 </ div >
434393 ) }
435394
@@ -590,20 +549,23 @@ export function AddConnectorModal({ open, onOpenChange, knowledgeBaseId }: AddCo
590549 ) }
591550 </ ModalContent >
592551 </ Modal >
593- { connectorConfig && connectorConfig . auth . mode === 'oauth' && connectorProviderId && (
594- < OAuthRequiredModal
595- isOpen = { showOAuthModal }
596- onClose = { ( ) => {
597- consumeOAuthReturnContext ( )
598- setShowOAuthModal ( false )
599- } }
600- provider = { connectorProviderId }
601- toolName = { connectorConfig . name }
602- requiredScopes = { getCanonicalScopesForProvider ( connectorProviderId ) }
603- newScopes = { [ ] }
604- serviceId = { connectorConfig . auth . provider }
605- />
606- ) }
552+ { showOAuthModal &&
553+ connectorConfig &&
554+ connectorConfig . auth . mode === 'oauth' &&
555+ connectorProviderId && (
556+ < ConnectCredentialModal
557+ isOpen = { showOAuthModal }
558+ onClose = { ( ) => {
559+ consumeOAuthReturnContext ( )
560+ setShowOAuthModal ( false )
561+ } }
562+ provider = { connectorProviderId }
563+ serviceId = { connectorConfig . auth . provider }
564+ workspaceId = { workspaceId }
565+ knowledgeBaseId = { knowledgeBaseId }
566+ credentialCount = { credentials . length }
567+ />
568+ ) }
607569 </ >
608570 )
609571}
0 commit comments