1
1
import React from 'react' ;
2
2
3
3
import { Dialog , Link as ExternalLink , Flex , TextInput } from '@gravity-ui/uikit' ;
4
+ import { yupResolver } from '@hookform/resolvers/yup' ;
4
5
import { Controller , useForm } from 'react-hook-form' ;
6
+ import * as yup from 'yup' ;
5
7
6
8
import { useTracingLevelOptionAvailable } from '../../../../store/reducers/capabilities/hooks' ;
7
9
import {
8
10
selectQueryAction ,
9
11
setQueryAction ,
10
12
} from '../../../../store/reducers/queryActions/queryActions' ;
11
- import type { QuerySettings } from '../../../../types/store/query' ;
13
+ import type {
14
+ QueryMode ,
15
+ QuerySettings ,
16
+ StatisticsMode ,
17
+ TracingLevel ,
18
+ TransactionMode ,
19
+ } from '../../../../types/store/query' ;
12
20
import { cn } from '../../../../utils/cn' ;
13
21
import {
14
22
useQueryExecutionSettings ,
@@ -24,6 +32,27 @@ import './QuerySettingsDialog.scss';
24
32
25
33
const b = cn ( 'ydb-query-settings-dialog' ) ;
26
34
35
+ const validationSchema = yup . object ( ) . shape ( {
36
+ timeout : yup . string ( ) . test ( 'is-within-range' , i18n ( 'form.validation.timeout' ) , ( value ) => {
37
+ if ( ! value ) {
38
+ return true ;
39
+ }
40
+ const num = Number ( value ) ;
41
+ return ! isNaN ( num ) && num > 0 ;
42
+ } ) ,
43
+ limitRows : yup . string ( ) . test ( 'is-within-range' , i18n ( 'form.validation.limitRows' ) , ( value ) => {
44
+ if ( ! value ) {
45
+ return true ;
46
+ }
47
+ const num = Number ( value ) ;
48
+ return ! isNaN ( num ) && num > 0 && num <= 100000 ;
49
+ } ) ,
50
+ queryMode : yup . mixed < QueryMode > ( ) . required ( ) ,
51
+ transactionMode : yup . mixed < TransactionMode > ( ) . required ( ) ,
52
+ statisticsMode : yup . mixed < StatisticsMode > ( ) ,
53
+ tracingLevel : yup . mixed < TracingLevel > ( ) ,
54
+ } ) ;
55
+
27
56
export function QuerySettingsDialog ( ) {
28
57
const dispatch = useTypedDispatch ( ) ;
29
58
const queryAction = useTypedSelector ( selectQueryAction ) ;
@@ -66,8 +95,13 @@ interface QuerySettingsFormProps {
66
95
}
67
96
68
97
function QuerySettingsForm ( { initialValues, onSubmit, onClose} : QuerySettingsFormProps ) {
69
- const { control, handleSubmit} = useForm < QuerySettings > ( {
98
+ const {
99
+ control,
100
+ handleSubmit,
101
+ formState : { errors} ,
102
+ } = useForm < QuerySettings > ( {
70
103
defaultValues : initialValues ,
104
+ resolver : yupResolver < QuerySettings > ( validationSchema ) ,
71
105
} ) ;
72
106
73
107
const enableTracingLevel = useTracingLevelOptionAvailable ( ) ;
@@ -85,6 +119,7 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
85
119
control = { control }
86
120
render = { ( { field} ) => (
87
121
< QuerySettingsSelect
122
+ id = "queryMode"
88
123
setting = { field . value }
89
124
onUpdateSetting = { field . onChange }
90
125
settingOptions = { QUERY_SETTINGS_FIELD_SETTINGS . queryMode . options }
@@ -104,10 +139,14 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
104
139
render = { ( { field} ) => (
105
140
< React . Fragment >
106
141
< TextInput
142
+ id = "timeout"
107
143
type = "number"
108
144
{ ...field }
109
145
className = { b ( 'timeout' ) }
110
146
placeholder = "60"
147
+ validationState = { errors . timeout ? 'invalid' : undefined }
148
+ errorMessage = { errors . timeout ?. message }
149
+ errorPlacement = "inside"
111
150
/>
112
151
< span className = { b ( 'timeout-suffix' ) } >
113
152
{ i18n ( 'form.timeout.seconds' ) }
@@ -128,6 +167,7 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
128
167
control = { control }
129
168
render = { ( { field} ) => (
130
169
< QuerySettingsSelect
170
+ id = "tracingLevel"
131
171
setting = { field . value }
132
172
onUpdateSetting = { field . onChange }
133
173
settingOptions = {
@@ -149,6 +189,7 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
149
189
control = { control }
150
190
render = { ( { field} ) => (
151
191
< QuerySettingsSelect
192
+ id = "transactionMode"
152
193
setting = { field . value }
153
194
onUpdateSetting = { field . onChange }
154
195
settingOptions = {
@@ -169,6 +210,7 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
169
210
control = { control }
170
211
render = { ( { field} ) => (
171
212
< QuerySettingsSelect
213
+ id = "statisticsMode"
172
214
setting = { field . value }
173
215
onUpdateSetting = { field . onChange }
174
216
settingOptions = {
@@ -188,14 +230,16 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
188
230
name = "limitRows"
189
231
control = { control }
190
232
render = { ( { field} ) => (
191
- < React . Fragment >
192
- < TextInput
193
- type = "number"
194
- { ...field }
195
- className = { b ( 'limit-rows' ) }
196
- placeholder = "10000"
197
- />
198
- </ React . Fragment >
233
+ < TextInput
234
+ id = "limitRows"
235
+ type = "number"
236
+ { ...field }
237
+ className = { b ( 'limit-rows' ) }
238
+ placeholder = "10000"
239
+ validationState = { errors . limitRows ? 'invalid' : undefined }
240
+ errorMessage = { errors . limitRows ?. message }
241
+ errorPlacement = "inside"
242
+ />
199
243
) }
200
244
/>
201
245
</ div >
0 commit comments