@postgres.ai/shared 4.0.0-pr-1042.2 → 4.0.0-pr-1043
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
5
5
|
* Unauthorized copying of this file, via any small is strictly prohibited
|
|
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 { Checkbox, FormControlLabel, Typography, Snackbar, makeStyles, Button, } from '@material-ui/core';
|
|
@@ -20,7 +20,7 @@ import { useForm } from './useForm';
|
|
|
20
20
|
import { ResponseMessage } from './ResponseMessage';
|
|
21
21
|
import { ConfigSectionTitle, Header, ModalTitle } from './Header';
|
|
22
22
|
import { dockerImageOptions, imagePgOptions } from './configOptions';
|
|
23
|
-
import { uniqueChipValue, customOrGenericImage,
|
|
23
|
+
import { uniqueChipValue, customOrGenericImage, createEnhancedDockerImages, } from './utils';
|
|
24
24
|
import { SelectWithTooltip, InputWithChip, InputWithTooltip, } from './InputWithTooltip';
|
|
25
25
|
import styles from './styles.module.scss';
|
|
26
26
|
import { formatTuningParams, formatTuningParamsToObj, } from '@postgres.ai/shared/types/api/endpoints/testDbSource';
|
|
@@ -108,6 +108,25 @@ export const Configuration = observer(({ instanceId, switchActiveTab, reload, is
|
|
|
108
108
|
});
|
|
109
109
|
};
|
|
110
110
|
const [{ formik, connectionData, isConnectionDataValid }] = useForm(onSubmit);
|
|
111
|
+
// Memoized enhanced Docker images to avoid recreation on every render
|
|
112
|
+
// This combines predefined images with any custom image from configuration
|
|
113
|
+
const enhancedDockerImages = useMemo(() => {
|
|
114
|
+
return createEnhancedDockerImages((configData === null || configData === void 0 ? void 0 : configData.dockerImageType) === 'Generic Postgres' ? configData === null || configData === void 0 ? void 0 : configData.dockerPath : undefined, (configData === null || configData === void 0 ? void 0 : configData.dockerImageType) === 'Generic Postgres' ? configData === null || configData === void 0 ? void 0 : configData.dockerTag : undefined);
|
|
115
|
+
}, [configData === null || configData === void 0 ? void 0 : configData.dockerPath, configData === null || configData === void 0 ? void 0 : configData.dockerTag, configData === null || configData === void 0 ? void 0 : configData.dockerImageType]);
|
|
116
|
+
// Memoized computed values from enhanced images
|
|
117
|
+
const dockerImageVersions = useMemo(() => {
|
|
118
|
+
return enhancedDockerImages
|
|
119
|
+
.map((image) => image.pg_major_version)
|
|
120
|
+
.filter((value, index, self) => self.indexOf(value) === index)
|
|
121
|
+
.sort((a, b) => Number(a) - Number(b));
|
|
122
|
+
}, [enhancedDockerImages]);
|
|
123
|
+
// Memoized tags and locations for performance
|
|
124
|
+
const dockerTags = useMemo(() => {
|
|
125
|
+
return enhancedDockerImages.map((image) => image.tag);
|
|
126
|
+
}, [enhancedDockerImages]);
|
|
127
|
+
const dockerLocations = useMemo(() => {
|
|
128
|
+
return enhancedDockerImages.map((image) => image.location);
|
|
129
|
+
}, [enhancedDockerImages]);
|
|
111
130
|
const scrollToField = () => {
|
|
112
131
|
const errorElement = document.querySelector('.Mui-error');
|
|
113
132
|
if (errorElement) {
|
|
@@ -310,28 +329,21 @@ export const Configuration = observer(({ instanceId, switchActiveTab, reload, is
|
|
|
310
329
|
};
|
|
311
330
|
const handleDockerImageSelect = (e) => {
|
|
312
331
|
if (e.target.value === 'Generic Postgres') {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
.filter((value, index, self) => self.indexOf(value) === index)
|
|
316
|
-
.sort((a, b) => Number(a) - Number(b));
|
|
317
|
-
const currentDockerImage = genericImageVersions.slice(-1)[0];
|
|
332
|
+
// Use memoized enhanced list for better performance
|
|
333
|
+
const currentDockerImage = dockerImageVersions.slice(-1)[0];
|
|
318
334
|
setDockerState({
|
|
319
335
|
...dockerState,
|
|
320
|
-
tags:
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
.map((image) => image.location)
|
|
325
|
-
.filter((location) => location === null || location === void 0 ? void 0 : location.includes(currentDockerImage)),
|
|
326
|
-
images: genericImageVersions,
|
|
327
|
-
data: genericDockerImages,
|
|
336
|
+
tags: dockerTags.filter((tag) => tag.startsWith(currentDockerImage)),
|
|
337
|
+
locations: dockerLocations.filter((location) => location === null || location === void 0 ? void 0 : location.includes(currentDockerImage)),
|
|
338
|
+
images: dockerImageVersions,
|
|
339
|
+
data: enhancedDockerImages,
|
|
328
340
|
});
|
|
329
341
|
formik.setValues({
|
|
330
342
|
...formik.values,
|
|
331
343
|
dockerImage: currentDockerImage,
|
|
332
344
|
dockerImageType: e.target.value,
|
|
333
|
-
dockerTag:
|
|
334
|
-
dockerPath:
|
|
345
|
+
dockerTag: dockerTags[0],
|
|
346
|
+
dockerPath: dockerLocations[0],
|
|
335
347
|
sharedPreloadLibraries: 'pg_stat_statements,pg_stat_kcache,pg_cron,pgaudit,anon',
|
|
336
348
|
});
|
|
337
349
|
}
|
|
@@ -367,13 +379,26 @@ export const Configuration = observer(({ instanceId, switchActiveTab, reload, is
|
|
|
367
379
|
...dockerState,
|
|
368
380
|
tags: updatedDockerTags,
|
|
369
381
|
});
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
382
|
+
// Add safety check for empty array
|
|
383
|
+
const firstTag = updatedDockerTags[0];
|
|
384
|
+
if (firstTag) {
|
|
385
|
+
const currentLocation = (_a = dockerState.data.find((image) => image.tag === firstTag)) === null || _a === void 0 ? void 0 : _a.location;
|
|
386
|
+
formik.setValues({
|
|
387
|
+
...formik.values,
|
|
388
|
+
dockerTag: firstTag,
|
|
389
|
+
dockerImage: e.target.value,
|
|
390
|
+
dockerPath: currentLocation || '',
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
// Fallback when no matching tags found
|
|
395
|
+
formik.setValues({
|
|
396
|
+
...formik.values,
|
|
397
|
+
dockerImage: e.target.value,
|
|
398
|
+
dockerTag: '',
|
|
399
|
+
dockerPath: '',
|
|
400
|
+
});
|
|
401
|
+
}
|
|
377
402
|
}
|
|
378
403
|
else {
|
|
379
404
|
formik.setValues({
|
|
@@ -395,22 +420,32 @@ export const Configuration = observer(({ instanceId, switchActiveTab, reload, is
|
|
|
395
420
|
}
|
|
396
421
|
if (customOrGenericImage(configData === null || configData === void 0 ? void 0 : configData.dockerImageType)) {
|
|
397
422
|
if ((configData === null || configData === void 0 ? void 0 : configData.dockerImageType) === 'Generic Postgres') {
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
423
|
+
// Use memoized enhanced list for better performance
|
|
424
|
+
const currentDockerImage = enhancedDockerImages.find((image) => image.location === (configData === null || configData === void 0 ? void 0 : configData.dockerPath) || image.tag === (configData === null || configData === void 0 ? void 0 : configData.dockerTag));
|
|
425
|
+
if (currentDockerImage) {
|
|
426
|
+
setDockerState({
|
|
427
|
+
...dockerState,
|
|
428
|
+
tags: dockerTags.filter((tag) => tag.startsWith(currentDockerImage.pg_major_version)),
|
|
429
|
+
images: dockerImageVersions,
|
|
430
|
+
data: enhancedDockerImages,
|
|
431
|
+
});
|
|
432
|
+
formik.setFieldValue('dockerTag', currentDockerImage.tag);
|
|
433
|
+
formik.setFieldValue('dockerImage', currentDockerImage.pg_major_version);
|
|
434
|
+
formik.setFieldValue('dockerPath', currentDockerImage.location);
|
|
435
|
+
}
|
|
436
|
+
else {
|
|
437
|
+
// Fallback: shouldn't happen with enhancedDockerImages, but keep for safety
|
|
438
|
+
const fallbackVersion = dockerImageVersions.slice(-1)[0];
|
|
439
|
+
setDockerState({
|
|
440
|
+
...dockerState,
|
|
441
|
+
tags: dockerTags.filter((tag) => tag.startsWith(fallbackVersion)),
|
|
442
|
+
images: dockerImageVersions,
|
|
443
|
+
data: enhancedDockerImages,
|
|
444
|
+
});
|
|
445
|
+
formik.setFieldValue('dockerTag', (configData === null || configData === void 0 ? void 0 : configData.dockerTag) || '');
|
|
446
|
+
formik.setFieldValue('dockerImage', fallbackVersion);
|
|
447
|
+
formik.setFieldValue('dockerPath', (configData === null || configData === void 0 ? void 0 : configData.dockerPath) || '');
|
|
448
|
+
}
|
|
414
449
|
}
|
|
415
450
|
else {
|
|
416
451
|
formik.setFieldValue('dockerImage', configData === null || configData === void 0 ? void 0 : configData.dockerPath);
|
|
@@ -418,7 +453,7 @@ export const Configuration = observer(({ instanceId, switchActiveTab, reload, is
|
|
|
418
453
|
}
|
|
419
454
|
}
|
|
420
455
|
}
|
|
421
|
-
}, [config]);
|
|
456
|
+
}, [config, configData === null || configData === void 0 ? void 0 : configData.dockerPath, configData === null || configData === void 0 ? void 0 : configData.dockerTag, configData === null || configData === void 0 ? void 0 : configData.dockerImageType]);
|
|
422
457
|
useEffect(() => {
|
|
423
458
|
getEngine(instanceId).then((res) => {
|
|
424
459
|
setDledition(String(res === null || res === void 0 ? void 0 : res.edition));
|
|
@@ -19,4 +19,7 @@ export declare const formatDatabases: (databases: DatabaseType | null) => string
|
|
|
19
19
|
export declare const formatDumpCustomOptions: (options: string[] | null) => string;
|
|
20
20
|
export declare const postUniqueCustomOptions: (options: string) => string[];
|
|
21
21
|
export declare const customOrGenericImage: (dockerImage: string | undefined) => boolean;
|
|
22
|
+
export declare const createFallbackDockerImage: (dockerPath: string, dockerTag: string) => DockerImage;
|
|
23
|
+
export declare const createEnhancedDockerImages: (configDockerPath?: string, configDockerTag?: string) => DockerImage[];
|
|
24
|
+
export declare const isConfigLoadedImage: (dockerPath: string, dockerTag: string) => boolean;
|
|
22
25
|
export {};
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { dockerImageOptions } from '../configOptions';
|
|
2
2
|
const seContainerRegistry = 'se-images';
|
|
3
3
|
const genericImagePrefix = 'postgresai/extended-postgres';
|
|
4
|
-
//
|
|
4
|
+
// Predefined list of Docker images for UI display
|
|
5
|
+
// This list is shown to users for convenient selection
|
|
6
|
+
// IMPORTANT: if user specified an image in config that's not in this list,
|
|
7
|
+
// it will be automatically added via createEnhancedDockerImages()
|
|
5
8
|
const dockerImagesConfig = {
|
|
6
9
|
'9.6': ['0.5.3', '0.5.2', '0.5.1'],
|
|
7
10
|
'10': ['0.5.3', '0.5.2', '0.5.1'],
|
|
@@ -73,11 +76,23 @@ export const getImageType = (imageUrl) => {
|
|
|
73
76
|
}
|
|
74
77
|
};
|
|
75
78
|
export const getImageMajorVersion = (pgImage) => {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
if (!pgImage)
|
|
80
|
+
return undefined;
|
|
81
|
+
try {
|
|
82
|
+
const pgImageVersion = pgImage.split(':')[1];
|
|
83
|
+
if (!pgImageVersion)
|
|
84
|
+
return undefined;
|
|
85
|
+
const pgServerVersion = pgImageVersion.split('-')[0];
|
|
86
|
+
if (!pgServerVersion)
|
|
87
|
+
return undefined;
|
|
88
|
+
return pgServerVersion.includes('.')
|
|
89
|
+
? pgServerVersion.split('.')[0]
|
|
90
|
+
: pgServerVersion;
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
// Return undefined for malformed image strings
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
81
96
|
};
|
|
82
97
|
export const formatDatabases = (databases) => {
|
|
83
98
|
let formattedDatabases = '';
|
|
@@ -103,3 +118,53 @@ export const postUniqueCustomOptions = (options) => {
|
|
|
103
118
|
return uniqueOptions;
|
|
104
119
|
};
|
|
105
120
|
export const customOrGenericImage = (dockerImage) => dockerImage === 'Generic Postgres' || dockerImage === 'custom';
|
|
121
|
+
export const createFallbackDockerImage = (dockerPath, dockerTag) => {
|
|
122
|
+
const majorVersion = getImageMajorVersion(dockerPath) || '16'; // Default to 16 if version can't be extracted
|
|
123
|
+
return {
|
|
124
|
+
package_group: 'postgresai',
|
|
125
|
+
pg_major_version: majorVersion,
|
|
126
|
+
tag: dockerTag || `${majorVersion}-custom`,
|
|
127
|
+
location: dockerPath,
|
|
128
|
+
};
|
|
129
|
+
};
|
|
130
|
+
// Creates enhanced list of Docker images, including image from configuration
|
|
131
|
+
export const createEnhancedDockerImages = (configDockerPath, configDockerTag) => {
|
|
132
|
+
let enhancedImages = [...genericDockerImages];
|
|
133
|
+
// If there's an image in config, check if we need to add it
|
|
134
|
+
if (configDockerPath && configDockerTag) {
|
|
135
|
+
const existingImage = genericDockerImages.find((image) => image.location === configDockerPath || image.tag === configDockerTag);
|
|
136
|
+
// If image not found in predefined list, add it
|
|
137
|
+
if (!existingImage) {
|
|
138
|
+
// Check if this is a Generic Postgres image
|
|
139
|
+
if (configDockerPath.includes(genericImagePrefix)) {
|
|
140
|
+
// For Generic Postgres images create proper structure
|
|
141
|
+
const majorVersion = getImageMajorVersion(configDockerPath);
|
|
142
|
+
if (majorVersion) {
|
|
143
|
+
const configImage = {
|
|
144
|
+
package_group: 'postgresai',
|
|
145
|
+
pg_major_version: majorVersion,
|
|
146
|
+
tag: configDockerTag,
|
|
147
|
+
location: configDockerPath,
|
|
148
|
+
};
|
|
149
|
+
enhancedImages.push(configImage);
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
// Fallback if version extraction failed
|
|
153
|
+
const configImage = createFallbackDockerImage(configDockerPath, configDockerTag);
|
|
154
|
+
enhancedImages.push(configImage);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
// For custom images use fallback
|
|
159
|
+
const configImage = createFallbackDockerImage(configDockerPath, configDockerTag);
|
|
160
|
+
enhancedImages.push(configImage);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return enhancedImages;
|
|
165
|
+
};
|
|
166
|
+
// Checks if image is loaded from configuration (not from predefined list)
|
|
167
|
+
export const isConfigLoadedImage = (dockerPath, dockerTag) => {
|
|
168
|
+
const existingImage = genericDockerImages.find((image) => image.location === dockerPath || image.tag === dockerTag);
|
|
169
|
+
return !existingImage;
|
|
170
|
+
};
|
|
@@ -7,12 +7,15 @@ export const formatConfig = (config) => {
|
|
|
7
7
|
debug: (_b = config.global) === null || _b === void 0 ? void 0 : _b.debug,
|
|
8
8
|
dockerImage: isSeDockerImage(dockerImage)
|
|
9
9
|
? getImageMajorVersion(dockerImage)
|
|
10
|
-
: dockerImage
|
|
10
|
+
: dockerImage && getImageType(dockerImage) === 'Generic Postgres'
|
|
11
|
+
? getImageMajorVersion(dockerImage) || dockerImage
|
|
12
|
+
: dockerImage,
|
|
11
13
|
...(dockerImage && {
|
|
12
14
|
dockerImageType: getImageType(dockerImage),
|
|
13
15
|
}),
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
// Extract dockerTag for both SE images and Generic Postgres images
|
|
17
|
+
...(dockerImage && dockerImage.includes(':') && {
|
|
18
|
+
dockerTag: dockerImage.split(':')[1],
|
|
16
19
|
}),
|
|
17
20
|
dockerPath: dockerImage,
|
|
18
21
|
tuningParams: formatTuningParams((_c = config.databaseConfigs) === null || _c === void 0 ? void 0 : _c.configs),
|