1+ import { useState } from "react"
12import { useNavigate } from "react-router-dom"
2- import { Modal } from "antd"
3- import { Info } from "@phosphor-icons/react"
3+ import { message , Modal } from "antd"
4+ import { CopySimpleIcon } from "@phosphor-icons/react"
5+ import clsx from "clsx"
46
57import { useAppStore } from "../../../store"
68import ErrorIcon from "../../../assets/ErrorIcon.svg"
9+ import { getLogTextColor , getLogLevelClass } from "../../../utils/utils"
710
811const TestConnectionFailureModal = ( {
912 fromSources,
@@ -16,30 +19,57 @@ const TestConnectionFailureModal = ({
1619 sourceTestConnectionError,
1720 destinationTestConnectionError,
1821 } = useAppStore ( )
22+ const [ isExpanded , setIsExpanded ] = useState ( false )
1923 const navigate = useNavigate ( )
2024
2125 const handleCancel = ( ) => {
2226 setShowFailureModal ( false )
27+ setIsExpanded ( false )
2328 }
2429
2530 const handleBackToPath = ( ) => {
2631 setShowFailureModal ( false )
32+ setIsExpanded ( false )
2733 if ( fromSources ) {
2834 navigate ( "/sources" )
2935 } else {
3036 navigate ( "/destinations" )
3137 }
3238 }
3339
40+ const handleReadMore = ( ) => setIsExpanded ( ! isExpanded )
41+
42+ const handleCopyLogs = async ( ) => {
43+ try {
44+ await navigator . clipboard . writeText (
45+ JSON . stringify (
46+ fromSources
47+ ? sourceTestConnectionError ?. logs || [ ]
48+ : destinationTestConnectionError ?. logs || [ ] ,
49+ null ,
50+ 4 ,
51+ ) ,
52+ )
53+ message . success ( "Logs copied to clipboard!" )
54+ } catch {
55+ message . error ( "Failed to copy logs" )
56+ }
57+ }
58+
3459 return (
3560 < Modal
3661 open = { showFailureModal }
3762 footer = { null }
3863 closable = { false }
3964 centered
40- width = { 420 }
65+ width = { isExpanded ? 980 : 680 }
66+ className = "transition-all duration-300"
4167 >
42- < div className = "flex flex-col items-center justify-center gap-7 py-6" >
68+ < div
69+ className = { `flex flex-col items-center justify-start gap-7 overflow-hidden pb-6 transition-all duration-300 ease-in-out ${
70+ isExpanded ? "w-full pt-6" : "mx-auto max-w-[680px] pt-16"
71+ } `}
72+ >
4373 < div className = "relative" >
4474 < div >
4575 < img
@@ -48,21 +78,76 @@ const TestConnectionFailureModal = ({
4878 />
4979 </ div >
5080 </ div >
51- < div className = "flex flex-col items-center" >
81+ < div className = "flex w-full flex-col items-center" >
5282 < p className = "text-sm text-text-tertiary" > Failed</ p >
53- < h2 className = "text-center text-lg font-medium" >
83+ < h2 className = "text-center text-xl font-medium" >
5484 Your test connection has failed
5585 </ h2 >
56- < div className = "mt-2 flex w-[360px] items-center gap-1 overflow-scroll rounded-xl bg-gray-50 p-3 text-xs" >
57- < Info
58- weight = "bold"
59- className = "size-4 flex-shrink-0 text-danger"
60- />
61- < span className = "break-words" >
62- { fromSources
63- ? sourceTestConnectionError
64- : destinationTestConnectionError }
65- </ span >
86+ < div className = "mt-4 flex w-full flex-col rounded-md border border-neutral-300 text-sm" >
87+ < div className = "flex w-full items-center justify-between border-b border-neutral-300 px-3 py-2" >
88+ < div className = "font-bold" > Error </ div >
89+ { isExpanded && (
90+ < CopySimpleIcon
91+ onClick = { handleCopyLogs }
92+ className = "size-[14px] flex-shrink-0 cursor-pointer"
93+ />
94+ ) }
95+ </ div >
96+ < div
97+ className = { `flex flex-col px-3 py-2 text-neutral-500 ${
98+ isExpanded ? "h-[300px] overflow-auto" : "h-auto"
99+ } `}
100+ >
101+ { ! isExpanded ? (
102+ < div className = "max-h-[150px] overflow-auto text-red-500" >
103+ { fromSources
104+ ? sourceTestConnectionError ?. message || ""
105+ : destinationTestConnectionError ?. message || "" }
106+ </ div >
107+ ) : (
108+ < table className = "min-w-full" >
109+ < tbody >
110+ { ( fromSources
111+ ? sourceTestConnectionError ?. logs || [ ]
112+ : destinationTestConnectionError ?. logs || [ ]
113+ ) . map ( ( jobLog , index ) => (
114+ < tr key = { index } >
115+ < td className = "w-24 px-4 py-1 text-sm" >
116+ < span
117+ className = { clsx (
118+ "rounded-xl px-2 py-[5px] text-xs capitalize" ,
119+ getLogLevelClass ( jobLog . level ) ,
120+ ) }
121+ >
122+ { jobLog . level }
123+ </ span >
124+ </ td >
125+ < td
126+ className = { clsx (
127+ "whitespace-pre-wrap break-words px-4 py-3 text-sm text-gray-700" ,
128+ getLogTextColor ( jobLog . level ) ,
129+ ) }
130+ >
131+ { jobLog . message }
132+ </ td >
133+ </ tr >
134+ ) ) }
135+ </ tbody >
136+ </ table >
137+ ) }
138+
139+ { ! isExpanded && (
140+ < button
141+ type = "button"
142+ onClick = { handleReadMore }
143+ aria-label = "Read more"
144+ aria-expanded = { isExpanded }
145+ className = "mt-2 text-left text-blue-600 hover:underline"
146+ >
147+ Read more
148+ </ button >
149+ ) }
150+ </ div >
66151 </ div >
67152 </ div >
68153 < div className = "flex items-center gap-4" >
0 commit comments