Skip to content

Commit fbdbdac

Browse files
committed
fix(ui): Improve configuration form (#470)
1 parent e09a7af commit fbdbdac

File tree

4 files changed

+127
-53
lines changed

4 files changed

+127
-53
lines changed

‎ui/packages/shared/pages/Configuration/InputWithTooltip/index.tsx

+65-28
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const useStyles = makeStyles(
1414
{
1515
textField: {
1616
'& .MuiOutlinedInput-notchedOutline': {
17-
borderColor: '#000 !important',
17+
borderColor: '#000',
1818
},
1919
},
2020
selectField: {
@@ -27,6 +27,12 @@ const useStyles = makeStyles(
2727
backgroundColor: 'inherit',
2828
},
2929
},
30+
label: {
31+
display: 'block',
32+
},
33+
error: {
34+
color: '#f44336',
35+
},
3036
},
3137
{ index: 1 },
3238
)
@@ -49,23 +55,35 @@ export const InputWithTooltip = ({
4955
const classes = useStyles()
5056

5157
return (
52-
<Box mt={2} mb={2} display="flex" alignItems="center">
53-
<TextField
54-
className={classNames(!disabled && classes.textField, styles.textField)}
55-
label={label}
56-
variant="outlined"
57-
size="small"
58-
value={value}
59-
error={Boolean(error)}
60-
onChange={onChange}
61-
disabled={disabled}
62-
InputLabelProps={{
63-
shrink: true,
64-
}}
65-
/>
66-
<Tooltip interactive content={<p>{tooltipText()}</p>}>
67-
<InfoIcon className={styles.infoIcon} />
68-
</Tooltip>
58+
<Box
59+
mt={2}
60+
mb={2}
61+
display="flex"
62+
flexDirection="column"
63+
justifyContent="flex-start"
64+
alignItems="flex-start"
65+
gap="5px"
66+
>
67+
<label className={classNames(error && classes.error, classes.label)}>
68+
{label}
69+
</label>
70+
<Box display="flex" alignItems="center" width="100%">
71+
<TextField
72+
className={classNames(
73+
!disabled && classes.textField,
74+
styles.textField,
75+
)}
76+
variant="outlined"
77+
size="small"
78+
value={value}
79+
error={Boolean(error)}
80+
onChange={onChange}
81+
disabled={disabled}
82+
/>
83+
<Tooltip interactive content={<p>{tooltipText()}</p>}>
84+
<InfoIcon className={styles.infoIcon} />
85+
</Tooltip>
86+
</Box>
6987
</Box>
7088
)
7189
}
@@ -94,8 +112,17 @@ export const InputWithChip = ({
94112
const classes = useStyles()
95113

96114
return (
97-
<Box mt={2} mb={1}>
98-
<Box display="flex" alignItems="center">
115+
<Box
116+
mt={2}
117+
mb={1}
118+
display="flex"
119+
flexDirection="column"
120+
justifyContent="flex-start"
121+
alignItems="flex-start"
122+
gap="5px"
123+
>
124+
<label className={classes.label}>{label}</label>
125+
<Box display="flex" alignItems="center" width="100%">
99126
<TextField
100127
className={classNames(
101128
!disabled && classes.textField,
@@ -106,7 +133,6 @@ export const InputWithChip = ({
106133
value={value}
107134
multiline
108135
disabled={disabled}
109-
label={label}
110136
inputProps={{
111137
name: id,
112138
id: id,
@@ -119,9 +145,9 @@ export const InputWithChip = ({
119145
<InfoIcon className={styles.infoIcon} />
120146
</Tooltip>
121147
</Box>
122-
<div className={styles.chipContainer}>
123-
{value &&
124-
uniqueChipValue(value)
148+
{value && (
149+
<div className={styles.chipContainer}>
150+
{uniqueChipValue(value)
125151
.split(' ')
126152
.map((uniqueValue, index) => {
127153
if (uniqueValue !== '') {
@@ -139,7 +165,8 @@ export const InputWithChip = ({
139165
)
140166
}
141167
})}
142-
</div>
168+
</div>
169+
)}
143170
</Box>
144171
)
145172
}
@@ -164,15 +191,25 @@ export const SelectWithTooltip = ({
164191
const classes = useStyles()
165192

166193
return (
167-
<Box mt={2} mb={2}>
168-
<Box mb={1} display="flex" alignItems="center">
194+
<Box
195+
mt={1}
196+
display="flex"
197+
flexDirection="column"
198+
justifyContent="flex-start"
199+
alignItems="flex-start"
200+
gap="5px"
201+
>
202+
<label className={classNames(error && classes.error, classes.label)}>
203+
{label}
204+
</label>
205+
<Box display="flex" alignItems="center" width="100%">
169206
<Select
170207
className={classNames(
171208
classes.selectField,
172209
!disabled && classes.textField,
173210
styles.textField,
174211
)}
175-
label={label}
212+
label=""
176213
error={error}
177214
value={value}
178215
disabled={disabled}

‎ui/packages/shared/pages/Configuration/index.tsx

+51-23
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ import {
1414
Typography,
1515
Snackbar,
1616
makeStyles,
17+
Button,
1718
} from '@material-ui/core'
1819
import Box from '@mui/material/Box'
1920

2021
import { Modal } from '@postgres.ai/shared/components/Modal'
2122
import { StubSpinner } from '@postgres.ai/shared/components/StubSpinner'
22-
import { Button } from '@postgres.ai/shared/components/Button'
2323
import { ExternalIcon } from '@postgres.ai/shared/icons/External'
2424
import { Spinner } from '@postgres.ai/shared/components/Spinner'
2525
import { useStores } from '@postgres.ai/shared/pages/Instance/context'
@@ -130,11 +130,26 @@ export const Configuration = observer(
130130
const [{ formik, connectionData, isConnectionDataValid }] =
131131
useForm(onSubmit)
132132

133+
const scrollToField = () => {
134+
const errorElement = document.querySelector('.Mui-error')
135+
if (errorElement) {
136+
errorElement.scrollIntoView({ behavior: 'smooth', block: 'center' })
137+
const inputElement = errorElement.querySelector('input')
138+
if (inputElement) {
139+
setTimeout(() => {
140+
inputElement.focus()
141+
}, 1000)
142+
}
143+
}
144+
}
145+
133146
const onTestConnectionClick = async () => {
134147
setConnectionRes(null)
135148
Object.keys(connectionData).map(function (key: string) {
136149
if (key !== 'password' && key !== 'db_list') {
137-
formik.validateField(key)
150+
formik.validateField(key).then(() => {
151+
scrollToField()
152+
})
138153
}
139154
})
140155
if (isConnectionDataValid) {
@@ -305,19 +320,19 @@ export const Configuration = observer(
305320
label={'Debug mode'}
306321
/>
307322
</Box>
308-
<Box mb={2}>
323+
<Box mb={2} mt={1}>
309324
<ConfigSectionTitle tag="databaseContainer" />
310325
<span
311326
className={classes.grayText}
312-
style={{ marginTop: '0.5rem', display: 'block' }}
327+
style={{ margin: '0.5rem 0 1rem 0', display: 'block' }}
313328
>
314329
DLE manages various database containers, such as clones. This
315330
section defines default container settings.
316331
</span>
317332
{dleEdition !== 'community' ? (
318333
<div>
319334
<SelectWithTooltip
320-
label="dockerImage - choose from the list"
335+
label="dockerImage - choose from the list *"
321336
value={formik.values.dockerImageType}
322337
error={Boolean(formik.errors.dockerImageType)}
323338
tooltipText={tooltipText.dockerImageType}
@@ -332,7 +347,7 @@ export const Configuration = observer(
332347
/>
333348
{formik.values.dockerImageType === 'custom' ? (
334349
<InputWithTooltip
335-
label="dockerImage"
350+
label="dockerImage *"
336351
value={formik.values.dockerImage}
337352
error={formik.errors.dockerImage}
338353
tooltipText={tooltipText.dockerImage}
@@ -343,7 +358,7 @@ export const Configuration = observer(
343358
/>
344359
) : (
345360
<SelectWithTooltip
346-
label="dockerImage - Postgres major version"
361+
label="dockerImage - Postgres major version *"
347362
value={formik.values.dockerImage}
348363
error={Boolean(formik.errors.dockerImage)}
349364
tooltipText={tooltipText.dockerImage}
@@ -425,7 +440,7 @@ export const Configuration = observer(
425440
Source database credentials and dumping options.
426441
</span>
427442
<InputWithTooltip
428-
label="source.connection.host"
443+
label="source.connection.host *"
429444
value={formik.values.host}
430445
error={formik.errors.host}
431446
tooltipText={tooltipText.host}
@@ -435,7 +450,7 @@ export const Configuration = observer(
435450
}
436451
/>
437452
<InputWithTooltip
438-
label="source.connection.port"
453+
label="source.connection.port *"
439454
value={formik.values.port}
440455
error={formik.errors.port}
441456
tooltipText={tooltipText.port}
@@ -445,7 +460,7 @@ export const Configuration = observer(
445460
}
446461
/>
447462
<InputWithTooltip
448-
label="source.connection.username"
463+
label="source.connection.username *"
449464
value={formik.values.username}
450465
error={formik.errors.username}
451466
tooltipText={tooltipText.username}
@@ -463,7 +478,7 @@ export const Configuration = observer(
463478
}
464479
/>
465480
<InputWithTooltip
466-
label="source.connection.dbname"
481+
label="source.connection.dbname *"
467482
value={formik.values.dbname}
468483
error={formik.errors.dbname}
469484
tooltipText={tooltipText.dbname}
@@ -472,6 +487,17 @@ export const Configuration = observer(
472487
formik.setFieldValue('dbname', e.target.value)
473488
}
474489
/>
490+
<InputWithChip
491+
id="databases"
492+
value={formik.values.databases}
493+
label="Databases"
494+
tooltipText={tooltipText.databases}
495+
handleDeleteChip={handleDeleteChip}
496+
disabled={isConfigurationDisabled}
497+
onChange={(e) =>
498+
formik.setFieldValue('databases', e.target.value)
499+
}
500+
/>
475501
<Box mt={2}>
476502
<InputWithChip
477503
value={formik.values.databases}
@@ -485,14 +511,12 @@ export const Configuration = observer(
485511
}
486512
/>
487513
</Box>
488-
<Box mt={2} mb={3}>
514+
<Box mt={3} mb={3}>
489515
<Button
490-
variant="primary"
491-
size="medium"
516+
variant="contained"
517+
color="secondary"
492518
onClick={onTestConnectionClick}
493-
isDisabled={
494-
isConnectionLoading || isConfigurationDisabled
495-
}
519+
disabled={isConnectionLoading || isConfigurationDisabled}
496520
>
497521
Test connection
498522
{isConnectionLoading && (
@@ -644,10 +668,14 @@ export const Configuration = observer(
644668
}}
645669
>
646670
<Button
647-
variant="primary"
648-
size="medium"
649-
onClick={formik.submitForm}
650-
isDisabled={formik.isSubmitting || isConfigurationDisabled}
671+
variant="contained"
672+
color="secondary"
673+
onClick={() => {
674+
formik.submitForm().then(() => {
675+
scrollToField()
676+
})
677+
}}
678+
disabled={formik.isSubmitting || isConfigurationDisabled}
651679
>
652680
Apply changes
653681
{formik.isSubmitting && (
@@ -656,8 +684,8 @@ export const Configuration = observer(
656684
</Button>
657685
<Box sx={{ px: 2 }}>
658686
<Button
659-
variant="secondary"
660-
size="medium"
687+
variant="outlined"
688+
color="secondary"
661689
onClick={() => switchActiveTab(null, 0)}
662690
>
663691
Cancel

‎ui/packages/shared/pages/Configuration/styles.module.scss

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
.textField {
2-
width: 350px;
2+
width: 400px;
33
max-width: 100%;
44

55
input,
@@ -16,6 +16,10 @@
1616
cursor: not-allowed;
1717
color: rgba(0, 0, 0, 0.38);
1818
}
19+
20+
@media (max-width: 600px) {
21+
width: 100%;
22+
}
1923
}
2024

2125
.chipContainer {

‎ui/packages/shared/pages/Configuration/useForm.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,18 @@ export const useForm = (onSubmit: (values: FormValues) => void) => {
8787
...(formik.values.databases && {
8888
db_list: formatDatabaseArray(formik.values.databases),
8989
}),
90+
...(formik.values.dockerImageType === 'custom' && {
91+
dockerImage: formik.values.dockerImage,
92+
}),
9093
}
9194

9295
const isConnectionDataValid =
9396
formik.values.host &&
9497
formik.values.port &&
9598
formik.values.username &&
96-
formik.values.dbname
99+
formik.values.dbname &&
100+
formik.values.dockerImageType === 'custom' &&
101+
formik.values.dockerImage
97102

98103
return [{ formik, connectionData, isConnectionDataValid }]
99104
}

0 commit comments

Comments
 (0)