1
1
import React , { useState , useEffect } from "react" ;
2
2
import { ClusterConfig } from "../../../contexts/ConfigContext" ;
3
- import {
4
- XCircle ,
5
- CheckCircle ,
6
- Loader2 ,
7
- AlertTriangle ,
8
- ChevronRight ,
9
- } from "lucide-react" ;
3
+ import { XCircle , CheckCircle , Loader2 , AlertTriangle , ChevronRight } from "lucide-react" ;
10
4
import { useQuery , useMutation } from "@tanstack/react-query" ;
11
5
import Button from "../../common/Button" ;
12
6
@@ -44,10 +38,8 @@ interface InstallationConfigResponse {
44
38
state : "Failed" | "Succeeded" | "Running" ;
45
39
}
46
40
47
- const LinuxPreflightCheck : React . FC < LinuxPreflightCheckProps > = ( {
48
- onComplete,
49
- } ) => {
50
- const [ isChecking , setIsChecking ] = useState ( false ) ;
41
+ const LinuxPreflightCheck : React . FC < LinuxPreflightCheckProps > = ( { onComplete } ) => {
42
+ const [ isPreflightsPolling , setIsPreflightsPolling ] = useState ( false ) ;
51
43
const [ isConfigPolling , setIsConfigPolling ] = useState ( true ) ;
52
44
53
45
// Mutation to run preflight checks
@@ -67,10 +59,10 @@ const LinuxPreflightCheck: React.FC<LinuxPreflightCheckProps> = ({
67
59
return response . json ( ) as Promise < PreflightResponse > ;
68
60
} ,
69
61
onSuccess : ( ) => {
70
- setIsChecking ( true ) ;
62
+ setIsPreflightsPolling ( true ) ;
71
63
} ,
72
64
onError : ( ) => {
73
- setIsChecking ( false ) ;
65
+ setIsPreflightsPolling ( false ) ;
74
66
onComplete ( false ) ;
75
67
} ,
76
68
} ) ;
@@ -100,10 +92,10 @@ const LinuxPreflightCheck: React.FC<LinuxPreflightCheckProps> = ({
100
92
} ) ;
101
93
102
94
// Query to poll installation config status
103
- const {
104
- data : installationConfigStatus ,
105
- isLoading : isInstallationConfigPolling ,
106
- } = useQuery < InstallationConfigResponse , Error > ( {
95
+ const { data : installationConfigStatus , isLoading : isInstallationConfigPolling } = useQuery <
96
+ InstallationConfigResponse ,
97
+ Error
98
+ > ( {
107
99
queryKey : [ "installationConfigStatus" ] ,
108
100
queryFn : async ( ) => {
109
101
const response = await fetch ( "/api/install/installation/status" , {
@@ -138,43 +130,38 @@ const LinuxPreflightCheck: React.FC<LinuxPreflightCheckProps> = ({
138
130
}
139
131
return response . json ( ) as Promise < PreflightResponse > ;
140
132
} ,
141
- enabled : isChecking ,
133
+ enabled : isPreflightsPolling ,
142
134
refetchInterval : 1000 ,
143
135
} ) ;
144
136
145
137
// Handle preflight status changes
146
138
useEffect ( ( ) => {
147
- if (
148
- preflightResponse ?. status ?. state === "Succeeded" ||
149
- preflightResponse ?. status ?. state === "Failed"
150
- ) {
151
- setIsChecking ( false ) ;
139
+ if ( preflightResponse ?. status ?. state === "Succeeded" || preflightResponse ?. status ?. state === "Failed" ) {
140
+ setIsPreflightsPolling ( false ) ;
152
141
// Consider it successful if there are no failures
153
142
const hasFailures = ( preflightResponse . output ?. fail ?. length ?? 0 ) > 0 ;
154
143
onComplete ( ! hasFailures ) ;
155
144
}
156
145
} , [ preflightResponse , onComplete ] ) ;
157
146
158
147
useEffect ( ( ) => {
148
+ console . log ( installationConfigStatus ?. state , "installationConfigStatus" ) ;
159
149
if ( installationConfigStatus ?. state === "Failed" ) {
160
150
setIsConfigPolling ( false ) ;
161
151
return ; // Prevent running preflights if failed
162
152
}
163
153
if ( installationConfigStatus ?. state === "Succeeded" ) {
164
154
runPreflights ( ) ;
165
- setIsChecking ( true ) ;
155
+ setIsPreflightsPolling ( true ) ;
166
156
}
167
157
} , [ installationConfigStatus , runPreflights ] ) ;
168
158
169
- const renderCheckStatus = (
170
- result : PreflightResult ,
171
- type : "pass" | "warn" | "fail"
172
- ) => {
159
+ const renderCheckStatus = ( result : PreflightResult , type : "pass" | "warn" | "fail" ) => {
173
160
let Icon = Loader2 ;
174
161
let statusColor = "text-blue-500" ;
175
162
let iconClasses = "animate-spin" ;
176
163
177
- if ( ! isChecking ) {
164
+ if ( ! setIsPreflightsPolling ) {
178
165
switch ( type ) {
179
166
case "pass" :
180
167
Icon = CheckCircle ;
@@ -199,16 +186,10 @@ const LinuxPreflightCheck: React.FC<LinuxPreflightCheckProps> = ({
199
186
< Icon className = { `w-5 h-5 ${ iconClasses } ` } />
200
187
</ div >
201
188
< div className = "ml-3" >
202
- < h4 className = "text-sm font-medium text-gray-900" >
203
- { result . title }
204
- </ h4 >
189
+ < h4 className = "text-sm font-medium text-gray-900" > { result . title } </ h4 >
205
190
< p
206
191
className = { `mt-1 text-sm ${
207
- type === "pass"
208
- ? "text-gray-500"
209
- : type === "warn"
210
- ? "text-yellow-600"
211
- : "text-red-600"
192
+ type === "pass" ? "text-gray-500" : type === "warn" ? "text-yellow-600" : "text-red-600"
212
193
} `}
213
194
>
214
195
{ result . message }
@@ -224,140 +205,120 @@ const LinuxPreflightCheck: React.FC<LinuxPreflightCheckProps> = ({
224
205
{ isInstallationConfigPolling && (
225
206
< div className = "flex flex-col items-center justify-center border rounded-xl bg-white py-16 px-8 w-full max-w-2xl mx-auto shadow-sm" >
226
207
< Loader2 className = "w-10 h-10 text-blue-500 animate-spin mb-6" />
227
- < div className = "text-2xl font-bold text-gray-900 mb-2" >
228
- Validating host requirements...
229
- </ div >
230
- < div className = "text-gray-500 text-base" >
231
- Please wait while we check your system.
232
- </ div >
208
+ < div className = "text-2xl font-bold text-gray-900 mb-2" > Validating host requirements...</ div >
209
+ < div className = "text-gray-500 text-base" > Please wait while we check your system.</ div >
233
210
</ div >
234
211
) }
235
212
{ ! isInstallationConfigPolling && (
236
213
< >
237
214
{ /* Header for Host Requirements Not Met */ }
238
- { ! isChecking &&
239
- ( preflightResponse ?. output ?. fail ?. length ?? 0 ) > 0 && (
240
- < div className = "mb-6" >
241
- < div className = "flex items-center mb-2" >
242
- < XCircle className = "w-7 h-7 text-red-500 mr-2" />
243
- < span className = "text-xl font-semibold text-gray-900" >
244
- Host Requirements Not Met
245
- </ span >
215
+ { ! setIsPreflightsPolling && ( preflightResponse ?. output ?. fail ?. length ?? 0 ) > 0 && (
216
+ < div className = "mb-6" >
217
+ < div className = "flex items-center mb-2" >
218
+ < XCircle className = "w-7 h-7 text-red-500 mr-2" />
219
+ < span className = "text-xl font-semibold text-gray-900" > Host Requirements Not Met</ span >
220
+ </ div >
221
+ < div className = "text-gray-600 text-sm mb-2" >
222
+ We found some issues that need to be resolved before proceeding with the installation.
223
+ </ div >
224
+ </ div >
225
+ ) } { " " }
226
+ { isConfigPolling && (
227
+ < div className = "py-3" >
228
+ < div className = "flex items-start" >
229
+ < div className = "flex-shrink-0 text-blue-500" >
230
+ < Loader2 className = "w-5 h-5 animate-spin" />
246
231
</ div >
247
- < div className = "text-gray-600 text-sm mb-2 " >
248
- We found some issues that need to be resolved before
249
- proceeding with the installation.
232
+ < div className = "ml-3 " >
233
+ < h4 className = "text-sm font-medium text-gray-900" > Validating host requirements... </ h4 >
234
+ < p > Please wait while we check your system. </ p >
250
235
</ div >
251
236
</ div >
252
- ) }
253
- < h3 className = "text-lg font-medium text-gray-900 mb-4" >
254
- System Requirements Check
255
- </ h3 >
237
+ </ div >
238
+ ) } { " " }
256
239
< div className = "space-y-2 divide-y divide-gray-200" >
257
- { isChecking ? (
240
+ { isPreflightsPolling && (
258
241
< div className = "py-3" >
259
242
< div className = "flex items-start" >
260
243
< div className = "flex-shrink-0 text-blue-500" >
261
244
< Loader2 className = "w-5 h-5 animate-spin" />
262
245
</ div >
263
246
< div className = "ml-3" >
264
- < h4 className = "text-sm font-medium text-gray-900" >
265
- Running checks...
266
- </ h4 >
247
+ < h4 className = "text-sm font-medium text-gray-900" > Running checks...</ h4 >
267
248
</ div >
268
249
</ div >
269
250
</ div >
270
- ) : preflightResponse ?. output ? (
251
+ ) } { " " }
252
+ { preflightResponse ?. output && (
271
253
< >
272
254
{ /* Failures Box */ }
273
- { preflightResponse . output . fail &&
274
- preflightResponse . output . fail . length > 0 && (
275
- < div className = "mb-6 border border-red-200 bg-red-50 rounded-lg p-4" >
276
- { preflightResponse . output . fail . map (
277
- ( result : PreflightResult , index : number ) => (
278
- < div
279
- key = { `fail-${ index } ` }
280
- className = "py-3 border-b last:border-b-0 border-red-100 flex items-start"
281
- >
282
- < div className = "flex-shrink-0 text-red-500 mt-1" >
283
- < XCircle className = "w-5 h-5" />
284
- </ div >
285
- < div className = "ml-3" >
286
- < h4 className = "text-sm font-semibold text-gray-900" >
287
- { result . title }
288
- </ h4 >
289
- < p className = "mt-1 text-sm text-red-600" >
290
- { result . message }
291
- </ p >
292
- </ div >
293
- </ div >
294
- )
295
- ) }
296
- </ div >
297
- ) }
298
- { /* Passes and Warnings */ }
299
- { preflightResponse . output . pass ?. map (
300
- ( result : PreflightResult , index : number ) => (
301
- < div key = { `pass-${ index } ` } >
302
- { renderCheckStatus ( result , "pass" ) }
303
- </ div >
304
- )
305
- ) }
306
- { preflightResponse . output . warn ?. map (
307
- ( result : PreflightResult , index : number ) => (
308
- < div key = { `warn-${ index } ` } >
309
- { renderCheckStatus ( result , "warn" ) }
310
- </ div >
311
- )
255
+ { preflightResponse . output . fail && preflightResponse . output . fail . length > 0 && (
256
+ < div className = "mb-6 border border-red-200 bg-red-50 rounded-lg p-4" >
257
+ { preflightResponse . output . fail . map ( ( result : PreflightResult , index : number ) => (
258
+ < div
259
+ key = { `fail-${ index } ` }
260
+ className = "py-3 border-b last:border-b-0 border-red-100 flex items-start"
261
+ >
262
+ < div className = "flex-shrink-0 text-red-500 mt-1" >
263
+ < XCircle className = "w-5 h-5" />
264
+ </ div >
265
+ < div className = "ml-3" >
266
+ < h4 className = "text-sm font-semibold text-gray-900" > { result . title } </ h4 >
267
+ < p className = "mt-1 text-sm text-red-600" > { result . message } </ p >
268
+ </ div >
269
+ </ div >
270
+ ) ) }
271
+ </ div >
312
272
) }
273
+ { /* Passes and Warnings */ }
274
+ { preflightResponse . output . pass ?. map ( ( result : PreflightResult , index : number ) => (
275
+ < div key = { `pass-${ index } ` } > { renderCheckStatus ( result , "pass" ) } </ div >
276
+ ) ) }
277
+ { preflightResponse . output . warn ?. map ( ( result : PreflightResult , index : number ) => (
278
+ < div key = { `warn-${ index } ` } > { renderCheckStatus ( result , "warn" ) } </ div >
279
+ ) ) }
313
280
</ >
314
- ) : (
281
+ ) }
282
+ { installationConfigStatus ?. state === "Failed" && (
315
283
< div className = "py-3" >
316
284
< div className = "flex items-start" >
317
285
< div className = "flex-shrink-0 text-red-500" >
318
286
< XCircle className = "w-5 h-5" />
319
287
</ div >
320
288
< div className = "ml-3" >
321
- < h4 className = "text-sm font-medium text-gray-900" >
322
- Failed to run checks
323
- </ h4 >
324
- < p className = "mt-1 text-sm text-red-600" >
325
- Unable to complete system requirement checks
326
- </ p >
289
+ < h4 className = "text-sm font-medium text-gray-900" > Failed to run checks</ h4 >
290
+ < p className = "mt-1 text-sm text-red-600" > Unable to complete system requirement checks</ p >
291
+ < p className = "mt-1 text-sm text-red-600" > { installationConfigStatus ?. description } </ p >
327
292
</ div >
328
293
</ div >
329
294
</ div >
330
295
) }
331
296
</ div >
332
297
{ /* What's Next Section - always at the bottom if there are failures */ }
333
- { preflightResponse ?. output ?. fail &&
334
- preflightResponse . output . fail . length > 0 && (
335
- < div className = "mt-8 bg-gray-50 border border-gray-200 rounded-lg p-4 w-full" >
336
- < div className = "font-semibold mb-2" > What's Next?</ div >
337
- < ul className = "list-disc list-inside text-sm text-gray-700 space-y-1" >
338
- < li > Review and address each failed requirement</ li >
339
- < li > Click "Back" to modify your setup if needed</ li >
340
- < li > Re-run the validation once issues are addressed</ li >
341
- </ ul >
342
- < button
343
- className = "mt-4 px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition"
344
- onClick = { ( ) => runPreflights ( ) }
345
- >
346
- Run Validation Again
347
- </ button >
348
- </ div >
349
- ) }
298
+ { preflightResponse ?. output ?. fail && preflightResponse . output . fail . length > 0 && (
299
+ < div className = "mt-8 bg-gray-50 border border-gray-200 rounded-lg p-4 w-full" >
300
+ < div className = "font-semibold mb-2" > What's Next?</ div >
301
+ < ul className = "list-disc list-inside text-sm text-gray-700 space-y-1" >
302
+ < li > Review and address each failed requirement</ li >
303
+ < li > Click "Back" to modify your setup if needed</ li >
304
+ < li > Re-run the validation once issues are addressed</ li >
305
+ </ ul >
306
+ < button
307
+ className = "mt-4 px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition"
308
+ onClick = { ( ) => runPreflights ( ) }
309
+ >
310
+ Run Validation Again
311
+ </ button >
312
+ </ div >
313
+ ) }
350
314
</ >
351
315
) }
352
- { /* doesn't matter if preflights is running or not, show install btn */ }
353
- { ! isChecking && (
354
- < Button
355
- onClick = { runInstall }
356
- icon = { < ChevronRight className = "w-5 h-5" /> }
357
- >
316
+ { /* doesn't matter if preflights is running or not, show install btn
317
+ {!setIsPreflightsPolling && (
318
+ <Button onClick={runInstall} icon={<ChevronRight className="w-5 h-5" />}>
358
319
{isSubmitting ? "Setting up..." : "Start Installation"}
359
320
</Button>
360
- ) }
321
+ )} */ }
361
322
</ div >
362
323
) ;
363
324
} ;
0 commit comments