Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit bd9e652

Browse files
committed
Merge branch '470-improve-configuration-form' into 'master'
fix(ui): Improve configuration form (#470) Closes #470 See merge request postgres-ai/database-lab!698
2 parents e09a7af + fbdbdac commit bd9e652

File tree

4 files changed

+127
-53
lines changed

4 files changed

+127
-53
lines changed

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

Lines changed: 65 additions & 28 deletions
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-
<divclassName={styles.chipContainer}>
123-
{value&&
124-
uniqueChipValue(value)
148+
{value&&(
149+
<divclassName={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‎

Lines changed: 51 additions & 23 deletions
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‎

Lines changed: 5 additions & 1 deletion
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‎

Lines changed: 6 additions & 1 deletion
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)

AltStyle によって変換されたページ (->オリジナル) /