Skip to content

Commit 6898013

Browse files
refactor: [UIE-8245] - DBaaS: Replace Select component with Autocomplete (#11245)
* change: [UIE-8245] - DBaaS: replace Select with Autocomplete * change: [UIE-8245] - DBaaS: replace Select with Autocomplete (Settings Tab) * Added changeset: Replace Select component with Autocomplete * change: [UIE-8245] - review fix, show default engine
1 parent 727dc75 commit 6898013

File tree

7 files changed

+145
-154
lines changed

7 files changed

+145
-154
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@linode/manager": Changed
3+
---
4+
5+
Replace Select component with Autocomplete in DBaaS ([#11245](https://github.com/linode/manager/pull/11245))

packages/manager/src/features/Databases/DatabaseCreate/DatabaseClusterData.tsx

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,15 @@ import { Divider } from '@linode/ui';
22
import Grid from '@mui/material/Unstable_Grid2';
33
import React from 'react';
44

5-
import Select from 'src/components/EnhancedSelect';
6-
import { _SingleValue } from 'src/components/EnhancedSelect/components/SingleValue';
75
import { RegionSelect } from 'src/components/RegionSelect/RegionSelect';
86
import { RegionHelperText } from 'src/components/SelectRegionPanel/RegionHelperText';
97
import { Typography } from 'src/components/Typography';
108
import {
119
StyledLabelTooltip,
1210
StyledTextField,
1311
} from 'src/features/Databases/DatabaseCreate/DatabaseCreate.style';
14-
import { EngineOption } from 'src/features/Databases/DatabaseCreate/EngineOption';
12+
import { DatabaseEngineSelect } from 'src/features/Databases/DatabaseCreate/DatabaseEngineSelect';
1513
import { useRestrictedGlobalGrantCheck } from 'src/hooks/useRestrictedGlobalGrantCheck';
16-
import { getSelectedOptionFromGroupedOptions } from 'src/utilities/getSelectedOptionFromGroupedOptions';
17-
18-
import { getEngineOptions } from './utilities';
1914

2015
import type {
2116
ClusterSize,
@@ -27,7 +22,6 @@ import type {
2722
ReplicationCommitTypes,
2823
} from '@linode/api-v4';
2924
import type { FormikErrors } from 'formik';
30-
import type { Item } from 'src/components/EnhancedSelect';
3125
export interface DatabaseCreateValues {
3226
allow_list: {
3327
address: string;
@@ -59,13 +53,6 @@ export const DatabaseClusterData = (props: Props) => {
5953
globalGrantType: 'add_databases',
6054
});
6155

62-
const engineOptions = React.useMemo(() => {
63-
if (!engines) {
64-
return [];
65-
}
66-
return getEngineOptions(engines);
67-
}, [engines]);
68-
6956
const labelToolTip = (
7057
<StyledLabelTooltip>
7158
<strong>Label must:</strong>
@@ -94,22 +81,11 @@ export const DatabaseClusterData = (props: Props) => {
9481
<Divider spacingBottom={12} spacingTop={38} />
9582
<Grid>
9683
<Typography variant="h2">Select Engine and Region</Typography>
97-
{/* TODO: use Autocomplete instead of Select */}
98-
<Select
99-
onChange={(selected: Item<string>) => {
100-
onChange('engine', selected.value);
101-
}}
102-
value={getSelectedOptionFromGroupedOptions(
103-
values.engine,
104-
engineOptions
105-
)}
106-
components={{ Option: EngineOption, SingleValue: _SingleValue }}
107-
disabled={isRestricted}
84+
<DatabaseEngineSelect
85+
engines={engines}
10886
errorText={errors.engine}
109-
isClearable={false}
110-
label="Database Engine"
111-
options={engineOptions}
112-
placeholder="Select a Database Engine"
87+
onChange={onChange}
88+
value={values.engine}
11389
/>
11490
</Grid>
11591
<Grid>

packages/manager/src/features/Databases/DatabaseCreate/DatabaseCreate.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ const DatabaseCreate = () => {
158158
},
159159
],
160160
cluster_size: -1 as ClusterSize,
161-
engine: 'mysql' as Engine,
161+
engine: 'mysql/8' as Engine,
162162
label: '',
163163
region: '',
164164
type: '',
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { Box } from '@linode/ui';
2+
import Grid from '@mui/material/Unstable_Grid2';
3+
import React from 'react';
4+
5+
import { Autocomplete } from 'src/components/Autocomplete/Autocomplete';
6+
import { getEngineOptions } from 'src/features/Databases/DatabaseCreate/utilities';
7+
import { useRestrictedGlobalGrantCheck } from 'src/hooks/useRestrictedGlobalGrantCheck';
8+
9+
import type { DatabaseEngine } from '@linode/api-v4';
10+
11+
interface Props {
12+
engines: DatabaseEngine[] | undefined;
13+
errorText: string | undefined;
14+
onChange: (filed: string, value: any) => void;
15+
value: string;
16+
}
17+
18+
export const DatabaseEngineSelect = (props: Props) => {
19+
const { engines, errorText, onChange, value } = props;
20+
const isRestricted = useRestrictedGlobalGrantCheck({
21+
globalGrantType: 'add_databases',
22+
});
23+
24+
const engineOptions = React.useMemo(() => {
25+
if (!engines) {
26+
return [];
27+
}
28+
return getEngineOptions(engines);
29+
}, [engines]);
30+
31+
const selectedEngine = React.useMemo(() => {
32+
return engineOptions.find((val) => val.value === value);
33+
}, [value, engineOptions]);
34+
35+
return (
36+
<Autocomplete
37+
groupBy={(option) => {
38+
if (option.engine.match(/mysql/i)) {
39+
return 'MySQL';
40+
}
41+
if (option.engine.match(/postgresql/i)) {
42+
return 'PostgreSQL';
43+
}
44+
if (option.engine.match(/mongodb/i)) {
45+
return 'MongoDB';
46+
}
47+
if (option.engine.match(/redis/i)) {
48+
return 'Redis';
49+
}
50+
return 'Other';
51+
}}
52+
onChange={(_, selected) => {
53+
onChange('engine', selected.value);
54+
}}
55+
renderOption={(props, option) => {
56+
const { key, ...rest } = props;
57+
return (
58+
<li {...rest} data-testid="db-engine-option" key={key}>
59+
<Grid
60+
alignItems="center"
61+
container
62+
direction="row"
63+
justifyContent="flex-start"
64+
spacing={2}
65+
>
66+
<Grid className="py0">{option.flag}</Grid>
67+
<Grid>{option.label}</Grid>
68+
</Grid>
69+
</li>
70+
);
71+
}}
72+
textFieldProps={{
73+
InputProps: {
74+
startAdornment: (
75+
<Box sx={{ pr: 1, pt: 0.7 }}>{selectedEngine?.flag}</Box>
76+
),
77+
},
78+
}}
79+
autoHighlight
80+
disableClearable
81+
disabled={isRestricted}
82+
errorText={errorText}
83+
isOptionEqualToValue={(option, value) => option.value === value.value}
84+
label="Database Engine"
85+
options={engineOptions ?? []}
86+
placeholder="Select a Database Engine"
87+
value={selectedEngine}
88+
/>
89+
);
90+
};

packages/manager/src/features/Databases/DatabaseCreate/EngineOption.tsx

Lines changed: 0 additions & 54 deletions
This file was deleted.

packages/manager/src/features/Databases/DatabaseCreate/utilities.tsx

Lines changed: 12 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { groupBy } from 'ramda';
21
import React from 'react';
32

43
import MongoDBIcon from 'src/assets/icons/mongodb.svg';
@@ -68,48 +67,17 @@ export const engineIcons: EngineIconsProps = {
6867
postgresql: <PostgreSQLIcon height="24" width="24" />,
6968
redis: null,
7069
};
70+
7171
export const getEngineOptions = (engines: DatabaseEngine[]) => {
72-
const groupedEngines = groupBy<DatabaseEngine>((engineObject) => {
73-
if (engineObject.engine.match(/mysql/i)) {
74-
return 'MySQL';
75-
}
76-
if (engineObject.engine.match(/postgresql/i)) {
77-
return 'PostgreSQL';
78-
}
79-
if (engineObject.engine.match(/mongodb/i)) {
80-
return 'MongoDB';
81-
}
82-
if (engineObject.engine.match(/redis/i)) {
83-
return 'Redis';
84-
}
85-
return 'Other';
86-
}, engines);
87-
return ['MySQL', 'PostgreSQL', 'MongoDB', 'Redis', 'Other'].reduce(
88-
(accum, thisGroup) => {
89-
if (
90-
!groupedEngines[thisGroup] ||
91-
groupedEngines[thisGroup].length === 0
92-
) {
93-
return accum;
94-
}
95-
return [
96-
...accum,
97-
{
98-
label: thisGroup,
99-
options: groupedEngines[thisGroup]
100-
.map((engineObject) => ({
101-
...engineObject,
102-
flag: engineIcons[engineObject.engine],
103-
label: getDatabasesDescription({
104-
engine: engineObject.engine,
105-
version: engineObject.version,
106-
}),
107-
value: `${engineObject.engine}/${engineObject.version}`,
108-
}))
109-
.sort((a, b) => (a.version > b.version ? -1 : 1)),
110-
},
111-
];
112-
},
113-
[]
114-
);
72+
return engines.map((e) => {
73+
return {
74+
engine: e.engine,
75+
flag: engineIcons[e.engine],
76+
label: getDatabasesDescription({
77+
engine: e.engine,
78+
version: e.version,
79+
}),
80+
value: `${e.engine}/${e.version}`,
81+
};
82+
});
11583
};

0 commit comments

Comments
 (0)