5
5
*--------------------------------------------------------------------------
6
6
*/
7
7
8
- import { useState , useEffect } from 'react'
8
+ import { useState , useEffect , useMemo } from 'react'
9
9
import { observer } from 'mobx-react-lite'
10
10
import Editor from '@monaco-editor/react'
11
11
import {
@@ -35,6 +35,9 @@ import {
35
35
uniqueChipValue ,
36
36
customOrGenericImage ,
37
37
genericDockerImages ,
38
+ getImageMajorVersion ,
39
+ createFallbackDockerImage ,
40
+ createEnhancedDockerImages ,
38
41
} from './utils'
39
42
import {
40
43
SelectWithTooltip ,
@@ -194,6 +197,32 @@ export const Configuration = observer(
194
197
const [ { formik, connectionData, isConnectionDataValid } ] =
195
198
useForm ( onSubmit )
196
199
200
+ // Memoized enhanced Docker images to avoid recreation on every render
201
+ // This combines predefined images with any custom image from configuration
202
+ const enhancedDockerImages = useMemo ( ( ) => {
203
+ return createEnhancedDockerImages (
204
+ configData ?. dockerImageType === 'Generic Postgres' ? configData ?. dockerPath : undefined ,
205
+ configData ?. dockerImageType === 'Generic Postgres' ? configData ?. dockerTag : undefined
206
+ )
207
+ } , [ configData ?. dockerPath , configData ?. dockerTag , configData ?. dockerImageType ] )
208
+
209
+ // Memoized computed values from enhanced images
210
+ const dockerImageVersions = useMemo ( ( ) => {
211
+ return enhancedDockerImages
212
+ . map ( ( image ) => image . pg_major_version )
213
+ . filter ( ( value , index , self ) => self . indexOf ( value ) === index )
214
+ . sort ( ( a , b ) => Number ( a ) - Number ( b ) )
215
+ } , [ enhancedDockerImages ] )
216
+
217
+ // Memoized tags and locations for performance
218
+ const dockerTags = useMemo ( ( ) => {
219
+ return enhancedDockerImages . map ( ( image ) => image . tag )
220
+ } , [ enhancedDockerImages ] )
221
+
222
+ const dockerLocations = useMemo ( ( ) => {
223
+ return enhancedDockerImages . map ( ( image ) => image . location )
224
+ } , [ enhancedDockerImages ] )
225
+
197
226
const scrollToField = ( ) => {
198
227
const errorElement = document . querySelector ( '.Mui-error' )
199
228
if ( errorElement ) {
@@ -457,30 +486,23 @@ export const Configuration = observer(
457
486
e : React . ChangeEvent < HTMLInputElement > ,
458
487
) => {
459
488
if ( e . target . value === 'Generic Postgres' ) {
460
- const genericImageVersions = genericDockerImages
461
- . map ( ( image ) => image . pg_major_version )
462
- . filter ( ( value , index , self ) => self . indexOf ( value ) === index )
463
- . sort ( ( a , b ) => Number ( a ) - Number ( b ) )
464
- const currentDockerImage = genericImageVersions . slice ( - 1 ) [ 0 ]
489
+ // Use memoized enhanced list for better performance
490
+ const currentDockerImage = dockerImageVersions . slice ( - 1 ) [ 0 ]
465
491
466
492
setDockerState ( {
467
493
...dockerState ,
468
- tags : genericDockerImages
469
- . map ( ( image ) => image . tag )
470
- . filter ( ( tag ) => tag . startsWith ( currentDockerImage ) ) ,
471
- locations : genericDockerImages
472
- . map ( ( image ) => image . location )
473
- . filter ( ( location ) => location ?. includes ( currentDockerImage ) ) ,
474
- images : genericImageVersions ,
475
- data : genericDockerImages ,
494
+ tags : dockerTags . filter ( ( tag ) => tag . startsWith ( currentDockerImage ) ) ,
495
+ locations : dockerLocations . filter ( ( location ) => location ?. includes ( currentDockerImage ) ) ,
496
+ images : dockerImageVersions ,
497
+ data : enhancedDockerImages ,
476
498
} )
477
499
478
500
formik . setValues ( {
479
501
...formik . values ,
480
502
dockerImage : currentDockerImage ,
481
503
dockerImageType : e . target . value ,
482
- dockerTag : genericDockerImages . map ( ( image ) => image . tag ) [ 0 ] ,
483
- dockerPath : genericDockerImages . map ( ( image ) => image . location ) [ 0 ] ,
504
+ dockerTag : dockerTags [ 0 ] ,
505
+ dockerPath : dockerLocations [ 0 ] ,
484
506
sharedPreloadLibraries :
485
507
'pg_stat_statements,pg_stat_kcache,pg_cron,pgaudit,anon' ,
486
508
} )
@@ -520,16 +542,28 @@ export const Configuration = observer(
520
542
tags : updatedDockerTags ,
521
543
} )
522
544
523
- const currentLocation = dockerState . data . find (
524
- ( image ) => image . tag === updatedDockerTags [ 0 ] ,
525
- ) ?. location as string
545
+ // Add safety check for empty array
546
+ const firstTag = updatedDockerTags [ 0 ]
547
+ if ( firstTag ) {
548
+ const currentLocation = dockerState . data . find (
549
+ ( image ) => image . tag === firstTag ,
550
+ ) ?. location
526
551
527
- formik . setValues ( {
528
- ...formik . values ,
529
- dockerTag : updatedDockerTags [ 0 ] ,
530
- dockerImage : e . target . value ,
531
- dockerPath : currentLocation ,
532
- } )
552
+ formik . setValues ( {
553
+ ...formik . values ,
554
+ dockerTag : firstTag ,
555
+ dockerImage : e . target . value ,
556
+ dockerPath : currentLocation || '' ,
557
+ } )
558
+ } else {
559
+ // Fallback when no matching tags found
560
+ formik . setValues ( {
561
+ ...formik . values ,
562
+ dockerImage : e . target . value ,
563
+ dockerTag : '' ,
564
+ dockerPath : '' ,
565
+ } )
566
+ }
533
567
} else {
534
568
formik . setValues ( {
535
569
...formik . values ,
@@ -553,41 +587,46 @@ export const Configuration = observer(
553
587
554
588
if ( customOrGenericImage ( configData ?. dockerImageType ) ) {
555
589
if ( configData ?. dockerImageType === 'Generic Postgres' ) {
556
- const genericImageVersions = genericDockerImages
557
- . map ( ( image ) => image . pg_major_version )
558
- . filter ( ( value , index , self ) => self . indexOf ( value ) === index )
559
- . sort ( ( a , b ) => Number ( a ) - Number ( b ) )
560
- const currentDockerImage =
561
- genericDockerImages . filter (
562
- ( image ) => image . location === configData ?. dockerPath ,
563
- ) [ 0 ] ||
564
- genericDockerImages . filter ( ( image ) =>
565
- configData ?. dockerPath ?. includes ( image . pg_major_version ) ,
566
- ) [ 0 ]
590
+ // Use memoized enhanced list for better performance
591
+ const currentDockerImage = enhancedDockerImages . find (
592
+ ( image ) => image . location === configData ?. dockerPath || image . tag === configData ?. dockerTag
593
+ )
567
594
568
- setDockerState ( {
569
- ...dockerState ,
570
- tags : genericDockerImages
571
- . map ( ( image ) => image . tag )
572
- . filter ( ( tag ) =>
595
+ if ( currentDockerImage ) {
596
+ setDockerState ( {
597
+ ...dockerState ,
598
+ tags : dockerTags . filter ( ( tag ) =>
573
599
tag . startsWith ( currentDockerImage . pg_major_version ) ,
574
600
) ,
575
- images : genericImageVersions ,
576
- data : genericDockerImages ,
577
- } )
601
+ images : dockerImageVersions ,
602
+ data : enhancedDockerImages ,
603
+ } )
578
604
579
- formik . setFieldValue ( 'dockerTag' , currentDockerImage ?. tag )
580
- formik . setFieldValue (
581
- 'dockerImage' ,
582
- currentDockerImage . pg_major_version ,
583
- )
605
+ formik . setFieldValue ( 'dockerTag' , currentDockerImage . tag )
606
+ formik . setFieldValue ( 'dockerImage' , currentDockerImage . pg_major_version )
607
+ formik . setFieldValue ( 'dockerPath' , currentDockerImage . location )
608
+ } else {
609
+ // Fallback: shouldn't happen with enhancedDockerImages, but keep for safety
610
+ const fallbackVersion = dockerImageVersions . slice ( - 1 ) [ 0 ]
611
+
612
+ setDockerState ( {
613
+ ...dockerState ,
614
+ tags : dockerTags . filter ( ( tag ) => tag . startsWith ( fallbackVersion ) ) ,
615
+ images : dockerImageVersions ,
616
+ data : enhancedDockerImages ,
617
+ } )
618
+
619
+ formik . setFieldValue ( 'dockerTag' , configData ?. dockerTag || '' )
620
+ formik . setFieldValue ( 'dockerImage' , fallbackVersion )
621
+ formik . setFieldValue ( 'dockerPath' , configData ?. dockerPath || '' )
622
+ }
584
623
} else {
585
624
formik . setFieldValue ( 'dockerImage' , configData ?. dockerPath )
586
625
}
587
626
}
588
627
}
589
628
}
590
- } , [ config ] )
629
+ } , [ config , configData ?. dockerPath , configData ?. dockerTag , configData ?. dockerImageType ] )
591
630
592
631
useEffect ( ( ) => {
593
632
getEngine ( instanceId ) . then ( ( res ) => {
0 commit comments