Skip to content

Commit bc5d59d

Browse files
authored
feat: turn streaming on by default (#2028)
1 parent cb5a755 commit bc5d59d

File tree

20 files changed

+404
-73
lines changed

20 files changed

+404
-73
lines changed

src/containers/Tenant/ObjectSummary/SchemaTree/SchemaTree.tsx

+1-4
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export function SchemaTree(props: SchemaTreeProps) {
4848
{currentData: actionsSchemaData, isFetching: isActionsDataFetching},
4949
] = tableSchemaDataApi.useLazyGetTableSchemaDataQuery();
5050

51-
const [querySettings, setQueryExecutionSettings] = useQueryExecutionSettings();
51+
const [querySettings] = useQueryExecutionSettings();
5252
const [createDirectoryOpen, setCreateDirectoryOpen] = React.useState(false);
5353
const [parentPath, setParentPath] = React.useState('');
5454
const setSchemaTreeKey = useDispatchTreeKey();
@@ -128,8 +128,6 @@ export function SchemaTree(props: SchemaTreeProps) {
128128
dispatch,
129129
{
130130
setActivePath: onActivePathUpdate,
131-
updateQueryExecutionSettings: (settings) =>
132-
setQueryExecutionSettings({...querySettings, ...settings}),
133131
showCreateDirectoryDialog: createDirectoryFeatureAvailable
134132
? handleOpenCreateDirectoryDialog
135133
: undefined,
@@ -149,7 +147,6 @@ export function SchemaTree(props: SchemaTreeProps) {
149147
onActivePathUpdate,
150148
querySettings,
151149
rootPath,
152-
setQueryExecutionSettings,
153150
]);
154151

155152
return (

src/containers/Tenant/Query/QuerySettingsDialog/QuerySettingsDialog.scss

+4-15
Original file line numberDiff line numberDiff line change
@@ -28,24 +28,13 @@
2828
flex: 6;
2929
}
3030

31-
&__limit-rows,
32-
&__timeout {
33-
width: 33.3%;
31+
&__limit-rows {
32+
width: 50%;
3433
margin-right: var(--g-spacing-2);
3534
}
3635

37-
&__timeout-suffix {
38-
display: flex;
39-
align-items: center;
40-
41-
color: var(--g-color-text-secondary);
42-
}
43-
44-
&__documentation-link {
45-
display: flex;
46-
align-items: center;
47-
48-
margin-left: var(--g-spacing-4);
36+
&__postfix {
37+
margin-right: var(--g-spacing-2);
4938

5039
color: var(--g-color-text-secondary);
5140
}

src/containers/Tenant/Query/QuerySettingsDialog/QuerySettingsDialog.tsx

+43-35
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
22

3-
import {Dialog, Link as ExternalLink, Flex, TextInput, Tooltip} from '@gravity-ui/uikit';
3+
import {Button, Dialog, Flex, TextInput, Tooltip} from '@gravity-ui/uikit';
44
import {zodResolver} from '@hookform/resolvers/zod';
55
import {Controller, useForm} from 'react-hook-form';
66

@@ -18,9 +18,10 @@ import {
1818
useTypedDispatch,
1919
useTypedSelector,
2020
} from '../../../../utils/hooks';
21-
import {querySettingsValidationSchema} from '../../../../utils/query';
21+
import {QUERY_MODES, querySettingsValidationSchema} from '../../../../utils/query';
2222

2323
import {QuerySettingsSelect} from './QuerySettingsSelect';
24+
import {QuerySettingsTimeout} from './QuerySettingsTimeout';
2425
import {QUERY_SETTINGS_FIELD_SETTINGS} from './constants';
2526
import i18n from './i18n';
2627

@@ -73,6 +74,8 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
7374
const {
7475
control,
7576
handleSubmit,
77+
setValue,
78+
watch,
7679
formState: {errors},
7780
} = useForm<QuerySettings>({
7881
defaultValues: initialValues,
@@ -82,6 +85,9 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
8285
const [useShowPlanToSvg] = useSetting<boolean>(USE_SHOW_PLAN_SVG_KEY);
8386
const enableTracingLevel = useTracingLevelOptionAvailable();
8487

88+
const timeout = watch('timeout');
89+
const queryMode = watch('queryMode');
90+
8591
return (
8692
<form onSubmit={handleSubmit(onSubmit)}>
8793
<Dialog.Body className={b('dialog-body')}>
@@ -97,42 +103,21 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
97103
<QuerySettingsSelect
98104
id="queryMode"
99105
setting={field.value}
100-
onUpdateSetting={field.onChange}
106+
onUpdateSetting={(mode) => {
107+
field.onChange(mode);
108+
109+
if (mode !== 'query' && timeout === null) {
110+
setValue('timeout', '');
111+
} else if (mode === 'query') {
112+
setValue('timeout', null);
113+
}
114+
}}
101115
settingOptions={QUERY_SETTINGS_FIELD_SETTINGS.queryMode.options}
102116
/>
103117
)}
104118
/>
105119
</div>
106120
</Flex>
107-
<Flex direction="row" alignItems="flex-start" className={b('dialog-row')}>
108-
<label htmlFor="timeout" className={b('field-title')}>
109-
{QUERY_SETTINGS_FIELD_SETTINGS.timeout.title}
110-
</label>
111-
<div className={b('control-wrapper')}>
112-
<Controller
113-
name="timeout"
114-
control={control}
115-
render={({field}) => (
116-
<React.Fragment>
117-
<TextInput
118-
id="timeout"
119-
type="number"
120-
{...field}
121-
value={field.value?.toString()}
122-
className={b('timeout')}
123-
placeholder="60"
124-
validationState={errors.timeout ? 'invalid' : undefined}
125-
errorMessage={errors.timeout?.message}
126-
errorPlacement="inside"
127-
/>
128-
<span className={b('timeout-suffix')}>
129-
{i18n('form.timeout.seconds')}
130-
</span>
131-
</React.Fragment>
132-
)}
133-
/>
134-
</div>
135-
</Flex>
136121
{enableTracingLevel && (
137122
<Flex direction="row" alignItems="flex-start" className={b('dialog-row')}>
138123
<label htmlFor="tracingLevel" className={b('field-title')}>
@@ -225,11 +210,33 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
225210
validationState={errors.limitRows ? 'invalid' : undefined}
226211
errorMessage={errors.limitRows?.message}
227212
errorPlacement="inside"
213+
endContent={
214+
<span className={b('postfix')}>
215+
{i18n('form.limit.rows')}
216+
</span>
217+
}
228218
/>
229219
)}
230220
/>
231221
</div>
232222
</Flex>
223+
<Flex direction="row" alignItems="flex-start" className={b('dialog-row')}>
224+
<Controller
225+
name="timeout"
226+
control={control}
227+
render={({field}) => (
228+
<QuerySettingsTimeout
229+
id="timeout"
230+
value={typeof field.value === 'string' ? undefined : field.value}
231+
onChange={field.onChange}
232+
onToggle={(enabled) => field.onChange(enabled ? '' : null)}
233+
validationState={errors.timeout ? 'invalid' : undefined}
234+
errorMessage={errors.timeout?.message}
235+
isDisabled={queryMode !== QUERY_MODES.query}
236+
/>
237+
)}
238+
/>
239+
</Flex>
233240
</Dialog.Body>
234241
<Dialog.Footer
235242
textButtonApply={i18n('button-done')}
@@ -240,13 +247,14 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
240247
}}
241248
renderButtons={(buttonApply, buttonCancel) => (
242249
<div className={b('buttons-container')}>
243-
<ExternalLink
250+
<Button
244251
href="https://ydb.tech/docs"
245252
target="_blank"
246-
className={b('documentation-link')}
253+
view="outlined"
254+
size="l"
247255
>
248256
{i18n('docs')}
249-
</ExternalLink>
257+
</Button>
250258
<div className={b('main-buttons')}>
251259
{buttonCancel}
252260
{buttonApply}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
.ydb-query-settings-timeout {
2+
&__control-wrapper {
3+
display: flex;
4+
flex: 6;
5+
align-items: center;
6+
}
7+
8+
&__input {
9+
width: 50%;
10+
}
11+
12+
&__postfix {
13+
margin-right: var(--g-spacing-2);
14+
15+
color: var(--g-color-text-secondary);
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import React from 'react';
2+
3+
import {TextInput} from '@gravity-ui/uikit';
4+
5+
import {cn} from '../../../../utils/cn';
6+
7+
import {TimeoutLabel} from './TimeoutLabel';
8+
import i18n from './i18n';
9+
10+
import './QuerySettingsTimeout.scss';
11+
12+
const b = cn('ydb-query-settings-timeout');
13+
14+
interface QuerySettingsTimeoutProps {
15+
id?: string;
16+
value: number | null | undefined;
17+
onChange: (value: number | undefined) => void;
18+
onToggle: (enabled: boolean) => void;
19+
validationState?: 'invalid';
20+
errorMessage?: string;
21+
isDisabled?: boolean;
22+
}
23+
24+
export function QuerySettingsTimeout({
25+
id,
26+
value,
27+
onChange,
28+
onToggle,
29+
validationState,
30+
errorMessage,
31+
isDisabled,
32+
}: QuerySettingsTimeoutProps) {
33+
const handleValueChange = React.useCallback(
34+
(event: React.ChangeEvent<HTMLInputElement>) => {
35+
const newValue = event.target.value ? Number(event.target.value) : undefined;
36+
onChange(newValue);
37+
},
38+
[onChange],
39+
);
40+
41+
const isChecked = value !== null;
42+
43+
return (
44+
<React.Fragment>
45+
<TimeoutLabel isDisabled={isDisabled} isChecked={isChecked} onToggle={onToggle} />
46+
{isChecked && (
47+
<div className={b('control-wrapper')}>
48+
<TextInput
49+
id={id}
50+
type="number"
51+
value={value?.toString() || ''}
52+
onChange={handleValueChange}
53+
className={b('input')}
54+
placeholder="60"
55+
validationState={validationState}
56+
errorMessage={errorMessage}
57+
errorPlacement="inside"
58+
endContent={
59+
<span className={b('postfix')}>{i18n('form.timeout.seconds')}</span>
60+
}
61+
/>
62+
</div>
63+
)}
64+
</React.Fragment>
65+
);
66+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
.ydb-timeout-label {
2+
&__switch {
3+
align-items: center;
4+
5+
height: var(--g-text-header-2-line-height);
6+
margin-right: var(--g-spacing-1);
7+
}
8+
9+
&__label-title,
10+
&__switch-title {
11+
flex: 4;
12+
align-items: center;
13+
14+
margin-right: var(--g-spacing-3);
15+
16+
font-weight: 500;
17+
white-space: nowrap;
18+
}
19+
20+
&__label-title {
21+
line-height: var(--g-text-header-2-line-height);
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import {HelpMark, Switch} from '@gravity-ui/uikit';
2+
3+
import {cn} from '../../../../utils/cn';
4+
import {ENABLE_QUERY_STREAMING} from '../../../../utils/constants';
5+
import {useSetting} from '../../../../utils/hooks';
6+
7+
import {QUERY_SETTINGS_FIELD_SETTINGS} from './constants';
8+
import i18n from './i18n';
9+
10+
import './TimeoutLabel.scss';
11+
12+
const b = cn('ydb-timeout-label');
13+
14+
interface TimeoutLabelProps {
15+
isDisabled?: boolean;
16+
isChecked: boolean;
17+
onToggle: (enabled: boolean) => void;
18+
}
19+
20+
export function TimeoutLabel({isDisabled, isChecked, onToggle}: TimeoutLabelProps) {
21+
const [isQueryStreamingEnabled] = useSetting<boolean>(ENABLE_QUERY_STREAMING);
22+
23+
if (isQueryStreamingEnabled) {
24+
return (
25+
<div className={b('switch-title')}>
26+
<Switch
27+
disabled={isDisabled}
28+
checked={isChecked}
29+
onUpdate={onToggle}
30+
className={b('switch')}
31+
content={QUERY_SETTINGS_FIELD_SETTINGS.timeout.title}
32+
/>
33+
{isDisabled && (
34+
<HelpMark className={b('question-icon')} placement="bottom-start">
35+
{i18n('form.timeout.disabled')}
36+
</HelpMark>
37+
)}
38+
</div>
39+
);
40+
}
41+
42+
return (
43+
<label htmlFor="timeout" className={b('label-title')}>
44+
{QUERY_SETTINGS_FIELD_SETTINGS.timeout.title}
45+
</label>
46+
);
47+
}

src/containers/Tenant/Query/QuerySettingsDialog/i18n/en.json

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
"tooltip_plan-to-svg-statistics": "Statistics option is set to \"Full\" due to the enabled \"Execution plan\" experiment.\n To disable it, go to the \"Experiments\" section in the user settings.",
1111
"button-cancel": "Cancel",
1212
"form.timeout.seconds": "sec",
13+
"form.limit.rows": "rows",
14+
"form.timeout.disabled": "Not available to turn off in this query type",
1315
"form.validation.timeout": "Must be positive",
1416
"form.validation.limitRows": "Must be between 1 and 100000",
1517
"description.default": " (default)",

src/containers/Tenant/Query/QuerySettingsDialog/i18n/ru.json

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
"button-done": "Готово",
1111
"button-cancel": "Отменить",
1212
"form.timeout.seconds": "сек",
13+
"form.limit.rows": "строк",
14+
"form.timeout.disabled": "Невозможно выключить для текущего типа запроса",
1315
"form.validation.timeout": "Таймаут должен быть положительным",
1416
"form.validation.limitRows": "Лимит строк должен быть между 1 и 100000",
1517
"description.default": " (default)",

src/containers/Tenant/utils/schemaActions.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import type {SnippetParams} from '../../../components/ConnectToDB/types';
77
import type {AppDispatch} from '../../../store';
88
import {TENANT_PAGES_IDS, TENANT_QUERY_TABS_ID} from '../../../store/reducers/tenant/constants';
99
import {setQueryTab, setTenantPage} from '../../../store/reducers/tenant/tenant';
10-
import type {QuerySettings} from '../../../types/store/query';
1110
import createToast from '../../../utils/createToast';
1211
import {insertSnippetToEditor} from '../../../utils/monaco/insertSnippet';
1312
import {transformPath} from '../ObjectSummary/transformPath';
@@ -42,7 +41,6 @@ import {
4241
} from './schemaQueryTemplates';
4342

4443
interface ActionsAdditionalParams {
45-
updateQueryExecutionSettings: (settings?: Partial<QuerySettings>) => void;
4644
setActivePath: (path: string) => void;
4745
showCreateDirectoryDialog?: (path: string) => void;
4846
getConfirmation?: () => Promise<boolean>;

0 commit comments

Comments
 (0)