@@ -45,6 +45,7 @@ import {
4545 MorphingDialogContainer
4646} from "@components/ui/morphing-dialog"
4747import { Tooltip } from "react-tooltip"
48+ import ModalDialog from "@components/ModalDialog"
4849
4950import IconBrandTodoist from "@components/icons/IconBrandTodoist"
5051
@@ -457,6 +458,7 @@ const IntegrationsPage = () => {
457458 const [ searchQuery , setSearchQuery ] = useState ( "" )
458459 const [ activeCategory , setActiveCategory ] = useState ( "All" )
459460 const [ selectedIntegration , setSelectedIntegration ] = useState ( null )
461+ const [ activeManualIntegration , setActiveManualIntegration ] = useState ( null )
460462 const [ whatsAppToConnect , setWhatsAppToConnect ] = useState ( null )
461463 const posthog = usePostHog ( )
462464
@@ -509,87 +511,87 @@ const IntegrationsPage = () => {
509511 }
510512 } , [ ] )
511513
512- const handleTrelloConnect = ( integration ) => {
513- const trelloApiKey = integration . client_id
514- if ( ! trelloApiKey ) {
515- toast . error (
516- "Trello API Key is not configured by the administrator."
517- )
518- return
519- }
514+ const handleTrelloConnect = ( integration ) => {
515+ const trelloApiKey = integration . client_id
516+ if ( ! trelloApiKey ) {
517+ toast . error (
518+ "Trello API Key is not configured by the administrator."
519+ )
520+ return
521+ }
520522
521- const returnUrl = `${ window . location . origin } /integrations`
522- const authUrl = `https://trello.com/1/authorize?expiration=never&name=Sentient&scope=read,write&response_type=token&key=${ trelloApiKey } &return_url=${ encodeURIComponent ( returnUrl ) } &callback_method=postMessage`
523+ const returnUrl = `${ window . location . origin } /integrations`
524+ const authUrl = `https://trello.com/1/authorize?expiration=never&name=Sentient&scope=read,write&response_type=token&key=${ trelloApiKey } &return_url=${ encodeURIComponent ( returnUrl ) } &callback_method=postMessage`
523525
524- const authWindow = window . open (
525- authUrl ,
526- "trelloAuth" ,
527- "width=600,height=700,noopener,noreferrer"
528- )
526+ const authWindow = window . open (
527+ authUrl ,
528+ "trelloAuth" ,
529+ "width=600,height=700,noopener,noreferrer"
530+ )
529531
530- // --- ADDED FOR DEBUGGING ---
531- // This listener will log EVERY message event that comes into the window,
532- // helping us see what Trello is sending back, even if it fails the security checks.
533- const debugListener = ( event ) => {
534- console . log ( "DEBUG: Received a postMessage event:" , event )
535- console . log ( "DEBUG: Event Origin:" , event . origin )
536- console . log ( "DEBUG: Event Data:" , event . data )
537- }
538- window . addEventListener ( "message" , debugListener )
539- // --- END OF DEBUGGING CODE ---
532+ // --- ADDED FOR DEBUGGING ---
533+ // This listener will log EVERY message event that comes into the window,
534+ // helping us see what Trello is sending back, even if it fails the security checks.
535+ const debugListener = ( event ) => {
536+ console . log ( "DEBUG: Received a postMessage event:" , event )
537+ console . log ( "DEBUG: Event Origin:" , event . origin )
538+ console . log ( "DEBUG: Event Data:" , event . data )
539+ }
540+ window . addEventListener ( "message" , debugListener )
541+ // --- END OF DEBUGGING CODE ---
540542
541- const handleMessage = async ( event ) => {
542- // Basic security checks
543- if (
544- event . source !== authWindow ||
545- event . origin !== "https://trello.com" ||
546- ! event . data
547- ) {
548- return
549- }
543+ const handleMessage = async ( event ) => {
544+ // Basic security checks
545+ if (
546+ event . source !== authWindow ||
547+ event . origin !== "https://trello.com" ||
548+ ! event . data
549+ ) {
550+ return
551+ }
550552
551- const token = event . data
552- // Trello tokens are 64-char hex strings
553- if ( token && / ^ [ 0 - 9 a - f ] { 64 } $ / . test ( token ) ) {
554- // --- ADDED FOR DEBUGGING ---
555- // Clean up both listeners once we have a valid token
556- window . removeEventListener ( "message" , debugListener )
557- // --- END OF DEBUGGING CODE ---
553+ const token = event . data
554+ // Trello tokens are 64-char hex strings
555+ if ( token && / ^ [ 0 - 9 a - f ] { 64 } $ / . test ( token ) ) {
556+ // --- ADDED FOR DEBUGGING ---
557+ // Clean up both listeners once we have a valid token
558+ window . removeEventListener ( "message" , debugListener )
559+ // --- END OF DEBUGGING CODE ---
558560
559- window . removeEventListener ( "message" , handleMessage )
560- authWindow . close ( )
561+ window . removeEventListener ( "message" , handleMessage )
562+ authWindow . close ( )
561563
562- setProcessingIntegration ( "trello" )
563- try {
564- const response = await fetch (
565- "/api/settings/integrations/connect/manual" ,
566- {
567- method : "POST" ,
568- headers : { "Content-Type" : "application/json" } ,
569- body : JSON . stringify ( {
570- service_name : "trello" ,
571- credentials : { token : token }
572- } )
573- }
564+ setProcessingIntegration ( "trello" )
565+ try {
566+ const response = await fetch (
567+ "/api/settings/integrations/connect/manual" ,
568+ {
569+ method : "POST" ,
570+ headers : { "Content-Type" : "application/json" } ,
571+ body : JSON . stringify ( {
572+ service_name : "trello" ,
573+ credentials : { token : token }
574+ } )
575+ }
576+ )
577+ if ( ! response . ok )
578+ throw new Error (
579+ ( await response . json ( ) ) . error ||
580+ "Failed to save Trello token."
574581 )
575- if ( ! response . ok )
576- throw new Error (
577- ( await response . json ( ) ) . error ||
578- "Failed to save Trello token."
579- )
580- toast . success ( "Trello connected successfully!" )
581- fetchIntegrations ( )
582- } catch ( error ) {
583- toast . error ( error . message )
584- } finally {
585- setProcessingIntegration ( null )
586- }
582+ toast . success ( "Trello connected successfully!" )
583+ fetchIntegrations ( )
584+ } catch ( error ) {
585+ toast . error ( error . message )
586+ } finally {
587+ setProcessingIntegration ( null )
587588 }
588589 }
589-
590- window . addEventListener ( "message" , handleMessage , false )
591590 }
592591
592+ window . addEventListener ( "message" , handleMessage , false )
593+ }
594+
593595 const handleConnect = ( integration ) => {
594596 if ( integration . name === "whatsapp" ) {
595597 setWhatsAppToConnect ( integration )
@@ -671,6 +673,7 @@ const IntegrationsPage = () => {
671673 )
672674 } else if ( integration . auth_type === "manual" ) {
673675 if ( MANUAL_INTEGRATION_CONFIGS [ integration . name ] ) {
676+ setActiveManualIntegration ( integration )
674677 } else {
675678 toast . error ( `UI for ${ integration . display_name } not found.` )
676679 }
@@ -1013,31 +1016,13 @@ const IntegrationsPage = () => {
10131016 </ main >
10141017 </ div >
10151018 < AnimatePresence >
1016- { activeManualIntegration && (
1017- < ManualTokenEntryModal
1018- integration = { activeManualIntegration }
1019- onClose = { ( ) => setActiveManualIntegration ( null ) }
1020- onSuccess = { fetchIntegrations }
1021- />
1022- ) }
10231019 { whatsAppToConnect && (
10241020 < WhatsAppConnectModal
10251021 integration = { whatsAppToConnect }
10261022 onClose = { ( ) => setWhatsAppToConnect ( null ) }
10271023 onSuccess = { fetchIntegrations }
10281024 />
10291025 ) }
1030- { selectedIntegration && (
1031- < IntegrationDetailsModal
1032- integration = { selectedIntegration }
1033- onClose = { ( ) => setSelectedIntegration ( null ) }
1034- onConnect = { handleConnect }
1035- onDisconnect = { handleDisconnect }
1036- isProcessing = {
1037- processingIntegration === selectedIntegration ?. name
1038- }
1039- />
1040- ) }
10411026 </ AnimatePresence >
10421027 </ div >
10431028 )
0 commit comments