Skip to content

Commit 1728e61

Browse files
authored
feat: add rows limit to query settings (#1291)
1 parent 61c3562 commit 1728e61

22 files changed

+162
-96
lines changed

package-lock.json

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"@gravity-ui/table": "^0.5.0",
2525
"@gravity-ui/uikit": "^6.20.1",
2626
"@gravity-ui/websql-autocomplete": "^9.1.0",
27+
"@hookform/resolvers": "^3.9.0",
2728
"@reduxjs/toolkit": "^2.2.3",
2829
"@tanstack/react-table": "^8.19.3",
2930
"axios": "^1.7.3",

src/containers/Tenant/Query/QueryEditorControls/utils/getChangedQueryExecutionSettings.test.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
11
import type {QuerySettings} from '../../../../../types/store/query';
22
import {
3+
DEFAULT_QUERY_SETTINGS,
34
QUERY_MODES,
45
STATISTICS_MODES,
56
TRACING_LEVELS,
67
TRANSACTION_MODES,
78
} from '../../../../../utils/query';
89

9-
const DEFAULT_QUERY_SETTINGS: QuerySettings = {
10-
queryMode: QUERY_MODES.query,
11-
transactionMode: TRANSACTION_MODES.implicit,
12-
timeout: '60',
13-
statisticsMode: STATISTICS_MODES.none,
14-
tracingLevel: TRACING_LEVELS.detailed,
15-
};
16-
1710
import getChangedQueryExecutionSettings from './getChangedQueryExecutionSettings';
1811

1912
describe('getChangedQueryExecutionSettings', () => {
@@ -27,7 +20,8 @@ describe('getChangedQueryExecutionSettings', () => {
2720
const currentSettings: QuerySettings = {
2821
...DEFAULT_QUERY_SETTINGS,
2922
queryMode: QUERY_MODES.data,
30-
timeout: '30',
23+
timeout: 30,
24+
limitRows: undefined,
3125
};
3226
const result = getChangedQueryExecutionSettings(currentSettings, DEFAULT_QUERY_SETTINGS);
3327
expect(result).toEqual(['queryMode', 'timeout']);
@@ -37,7 +31,8 @@ describe('getChangedQueryExecutionSettings', () => {
3731
const currentSettings: QuerySettings = {
3832
queryMode: QUERY_MODES.data,
3933
transactionMode: TRANSACTION_MODES.onlinero,
40-
timeout: '90',
34+
timeout: 90,
35+
limitRows: DEFAULT_QUERY_SETTINGS.limitRows,
4136
statisticsMode: STATISTICS_MODES.basic,
4237
tracingLevel: TRACING_LEVELS.basic,
4338
};

src/containers/Tenant/Query/QueryEditorControls/utils/getChangedQueryExecutionSettings.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ export default function getChangedQueryExecutionSettings(
88
const defaultMap = new Map(Object.entries(defaultSettings));
99

1010
return Array.from(currentMap.keys()).filter(
11-
(key) => currentMap.get(key) !== defaultMap.get(key),
11+
(key) =>
12+
currentMap.has(key) &&
13+
currentMap.get(key) !== undefined &&
14+
currentMap.get(key) !== defaultMap.get(key),
1215
) as (keyof QuerySettings)[];
1316
}

src/containers/Tenant/Query/QueryEditorControls/utils/getChangedQueryExecutionSettingsDescription.test.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type {QuerySettings} from '../../../../../types/store/query';
22
import {
3+
DEFAULT_QUERY_SETTINGS,
34
QUERY_MODES,
45
QUERY_MODES_TITLES,
56
STATISTICS_MODES,
@@ -13,14 +14,6 @@ import {QUERY_SETTINGS_FIELD_SETTINGS} from '../../QuerySettingsDialog/constants
1314

1415
import getChangedQueryExecutionSettingsDescription from './getChangedQueryExecutionSettingsDescription';
1516

16-
const DEFAULT_QUERY_SETTINGS: QuerySettings = {
17-
queryMode: QUERY_MODES.query,
18-
transactionMode: TRANSACTION_MODES.implicit,
19-
timeout: '60',
20-
statisticsMode: STATISTICS_MODES.none,
21-
tracingLevel: TRACING_LEVELS.detailed,
22-
};
23-
2417
describe('getChangedQueryExecutionSettingsDescription', () => {
2518
it('should return an empty object if no settings changed', () => {
2619
const currentSettings: QuerySettings = {...DEFAULT_QUERY_SETTINGS};
@@ -37,7 +30,8 @@ describe('getChangedQueryExecutionSettingsDescription', () => {
3730
const currentSettings: QuerySettings = {
3831
...DEFAULT_QUERY_SETTINGS,
3932
queryMode: QUERY_MODES.pg,
40-
timeout: '63',
33+
timeout: 63,
34+
limitRows: 100,
4135
};
4236

4337
const result = getChangedQueryExecutionSettingsDescription({
@@ -51,14 +45,16 @@ describe('getChangedQueryExecutionSettingsDescription', () => {
5145
(option) => option.value === QUERY_MODES.pg,
5246
)?.content,
5347
[QUERY_SETTINGS_FIELD_SETTINGS.timeout.title]: '63',
48+
[QUERY_SETTINGS_FIELD_SETTINGS.limitRows.title]: '100',
5449
});
5550
});
5651

5752
it('should return the correct description for all changed settings', () => {
5853
const currentSettings: QuerySettings = {
5954
queryMode: QUERY_MODES.data,
6055
transactionMode: TRANSACTION_MODES.snapshot,
61-
timeout: '120',
56+
timeout: 120,
57+
limitRows: DEFAULT_QUERY_SETTINGS.limitRows,
6258
statisticsMode: STATISTICS_MODES.profile,
6359
tracingLevel: TRACING_LEVELS.diagnostic,
6460
};

src/containers/Tenant/Query/QueryEditorControls/utils/getChangedQueryExecutionSettingsDescription.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,18 @@ export default function getChangedQueryExecutionSettingsDescription({
1515

1616
keys.forEach((key) => {
1717
const settings = QUERY_SETTINGS_FIELD_SETTINGS[key];
18-
const currentValue = currentSettings[key] as string;
18+
const currentValue = currentSettings[key];
1919

2020
if ('options' in settings) {
21-
const content = settings.options.find((option) => option.value === currentValue)
22-
?.content as string;
21+
const content = settings.options.find(
22+
(option) => option.value === currentValue,
23+
)?.content;
2324

24-
result[settings.title] = content;
25-
} else {
26-
result[settings.title] = currentValue;
25+
if (content) {
26+
result[settings.title] = content;
27+
}
28+
} else if (currentValue) {
29+
result[settings.title] = String(currentValue);
2730
}
2831
});
2932

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
flex: 6;
2929
}
3030

31+
&__limit-rows,
3132
&__timeout {
3233
width: 33.3%;
3334
margin-right: var(--g-spacing-2);

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

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from 'react';
22

33
import {Dialog, Link as ExternalLink, Flex, TextInput} from '@gravity-ui/uikit';
4+
import {zodResolver} from '@hookform/resolvers/zod';
45
import {Controller, useForm} from 'react-hook-form';
56

67
import {useTracingLevelOptionAvailable} from '../../../../store/reducers/capabilities/hooks';
@@ -15,6 +16,7 @@ import {
1516
useTypedDispatch,
1617
useTypedSelector,
1718
} from '../../../../utils/hooks';
19+
import {querySettingsValidationSchema} from '../../../../utils/query';
1820

1921
import {QuerySettingsSelect} from './QuerySettingsSelect';
2022
import {QUERY_SETTINGS_FIELD_SETTINGS} from './constants';
@@ -66,8 +68,13 @@ interface QuerySettingsFormProps {
6668
}
6769

6870
function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsFormProps) {
69-
const {control, handleSubmit} = useForm<QuerySettings>({
71+
const {
72+
control,
73+
handleSubmit,
74+
formState: {errors},
75+
} = useForm<QuerySettings>({
7076
defaultValues: initialValues,
77+
resolver: zodResolver(querySettingsValidationSchema),
7178
});
7279

7380
const enableTracingLevel = useTracingLevelOptionAvailable();
@@ -85,6 +92,7 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
8592
control={control}
8693
render={({field}) => (
8794
<QuerySettingsSelect
95+
id="queryMode"
8896
setting={field.value}
8997
onUpdateSetting={field.onChange}
9098
settingOptions={QUERY_SETTINGS_FIELD_SETTINGS.queryMode.options}
@@ -104,10 +112,15 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
104112
render={({field}) => (
105113
<React.Fragment>
106114
<TextInput
115+
id="timeout"
107116
type="number"
108117
{...field}
118+
value={field.value?.toString()}
109119
className={b('timeout')}
110120
placeholder="60"
121+
validationState={errors.timeout ? 'invalid' : undefined}
122+
errorMessage={errors.timeout?.message}
123+
errorPlacement="inside"
111124
/>
112125
<span className={b('timeout-suffix')}>
113126
{i18n('form.timeout.seconds')}
@@ -128,6 +141,7 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
128141
control={control}
129142
render={({field}) => (
130143
<QuerySettingsSelect
144+
id="tracingLevel"
131145
setting={field.value}
132146
onUpdateSetting={field.onChange}
133147
settingOptions={
@@ -149,6 +163,7 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
149163
control={control}
150164
render={({field}) => (
151165
<QuerySettingsSelect
166+
id="transactionMode"
152167
setting={field.value}
153168
onUpdateSetting={field.onChange}
154169
settingOptions={
@@ -169,6 +184,7 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
169184
control={control}
170185
render={({field}) => (
171186
<QuerySettingsSelect
187+
id="statisticsMode"
172188
setting={field.value}
173189
onUpdateSetting={field.onChange}
174190
settingOptions={
@@ -179,6 +195,30 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
179195
/>
180196
</div>
181197
</Flex>
198+
<Flex direction="row" alignItems="flex-start" className={b('dialog-row')}>
199+
<label htmlFor="limitRows" className={b('field-title')}>
200+
{QUERY_SETTINGS_FIELD_SETTINGS.limitRows.title}
201+
</label>
202+
<div className={b('control-wrapper')}>
203+
<Controller
204+
name="limitRows"
205+
control={control}
206+
render={({field}) => (
207+
<TextInput
208+
id="limitRows"
209+
type="number"
210+
{...field}
211+
value={field.value?.toString()}
212+
className={b('limit-rows')}
213+
placeholder="10000"
214+
validationState={errors.limitRows ? 'invalid' : undefined}
215+
errorMessage={errors.limitRows?.message}
216+
errorPlacement="inside"
217+
/>
218+
)}
219+
/>
220+
</div>
221+
</Flex>
182222
</Dialog.Body>
183223
<Dialog.Footer
184224
textButtonApply={i18n('button-done')}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ type SelectType = QueryMode | TransactionMode | StatisticsMode | TracingLevel;
2323
type QuerySettingSelectOption<T> = SelectOption<T> & {isDefault?: boolean};
2424

2525
interface QuerySettingsSelectProps<T extends SelectType> {
26+
id?: string;
2627
setting: T;
2728
settingOptions: QuerySettingSelectOption<T>[];
2829
onUpdateSetting: (mode: T) => void;
@@ -32,6 +33,7 @@ export function QuerySettingsSelect<T extends SelectType>(props: QuerySettingsSe
3233
return (
3334
<div className={b('selector')}>
3435
<Select<T>
36+
id={props.id}
3537
options={props.settingOptions}
3638
value={[props.setting]}
3739
onUpdate={(value) => {

src/containers/Tenant/Query/QuerySettingsDialog/constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,4 +148,7 @@ export const QUERY_SETTINGS_FIELD_SETTINGS = {
148148
timeout: {
149149
title: formI18n('form.timeout'),
150150
},
151+
limitRows: {
152+
title: formI18n('form.limit-rows'),
153+
},
151154
} as const;

0 commit comments

Comments
 (0)