Skip to content

Commit 385d7fd

Browse files
authored
Merge 633909d into 689120c
2 parents 689120c + 633909d commit 385d7fd

36 files changed

+461
-509
lines changed

src/components/ElapsedTime/ElapsedTime.scss

Lines changed: 0 additions & 3 deletions
This file was deleted.

src/components/ElapsedTime/ElapsedTime.tsx

Lines changed: 0 additions & 35 deletions
This file was deleted.

src/components/QueryExecutionStatus/QueryExecutionStatus.scss

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,4 @@
22
display: flex;
33
align-items: center;
44
gap: 4px;
5-
6-
color: var(--g-color-text-complementary);
7-
&__result-status-icon {
8-
color: var(--g-color-text-positive);
9-
&_error {
10-
color: var(--g-color-text-danger);
11-
}
12-
}
13-
14-
&__query-settings-icon {
15-
color: var(--g-color-text-hint);
16-
}
175
}
Lines changed: 30 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
11
import React from 'react';
22

3-
import {
4-
CircleCheck,
5-
CircleInfo,
6-
CircleQuestionFill,
7-
CircleStop,
8-
CircleXmark,
9-
} from '@gravity-ui/icons';
10-
import {Icon, Spin, Tooltip} from '@gravity-ui/uikit';
3+
import {CircleCheckFill, CircleQuestionFill, CircleStop, CircleXmark} from '@gravity-ui/icons';
4+
import type {LabelProps, TextProps} from '@gravity-ui/uikit';
5+
import {Icon, Label, Spin, Text} from '@gravity-ui/uikit';
116

12-
import i18n from '../../containers/Tenant/Query/i18n';
137
import {isQueryCancelledError} from '../../containers/Tenant/Query/utils/isQueryCancelledError';
148
import {cn} from '../../utils/cn';
15-
import {useChangedQuerySettings} from '../../utils/hooks/useChangedQuerySettings';
169
import {isAxiosError} from '../../utils/response';
17-
import QuerySettingsDescription from '../QuerySettingsDescription/QuerySettingsDescription';
10+
11+
import {useElapsedTime} from './useElapsedTime';
1812

1913
import './QueryExecutionStatus.scss';
2014

@@ -26,57 +20,52 @@ interface QueryExecutionStatusProps {
2620
loading?: boolean;
2721
}
2822

29-
const QuerySettingsIndicator = () => {
30-
const {isIndicatorShown, changedLastExecutionSettingsDescriptions} = useChangedQuerySettings();
31-
32-
if (!isIndicatorShown) {
33-
return null;
34-
}
35-
36-
return (
37-
<Tooltip
38-
openDelay={0}
39-
content={
40-
<QuerySettingsDescription
41-
prefix={i18n('banner.query-settings.message')}
42-
querySettings={changedLastExecutionSettingsDescriptions}
43-
/>
44-
}
45-
>
46-
<Icon data={CircleInfo} className={b('query-settings-icon')} />
47-
</Tooltip>
48-
);
49-
};
50-
5123
export const QueryExecutionStatus = ({className, error, loading}: QueryExecutionStatusProps) => {
5224
let icon: React.ReactNode;
5325
let label: string;
26+
let theme: LabelProps['theme'];
27+
let textColor: TextProps['color'];
28+
29+
const elapsedTime = useElapsedTime(loading);
30+
const isCancelled = isQueryCancelledError(error);
5431

5532
if (loading) {
33+
theme = 'info';
34+
textColor = 'info-heavy';
5635
icon = <Spin size="xs" />;
5736
label = 'Running';
5837
} else if (isAxiosError(error) && error.code === 'ECONNABORTED') {
38+
theme = 'danger';
39+
textColor = 'danger-heavy';
5940
icon = <Icon data={CircleQuestionFill} />;
6041
label = 'Connection aborted';
61-
} else if (isQueryCancelledError(error)) {
62-
icon = <Icon data={CircleStop} />;
42+
} else if (isCancelled) {
43+
theme = 'warning';
44+
textColor = 'warning-heavy';
45+
icon = <Icon data={CircleStop} className={b('result-status-icon', {error: true})} />;
6346
label = 'Stopped';
6447
} else {
6548
const hasError = Boolean(error);
49+
theme = hasError ? 'danger' : 'success';
50+
textColor = hasError ? 'danger-heavy' : 'positive-heavy';
6651
icon = (
6752
<Icon
68-
data={hasError ? CircleXmark : CircleCheck}
53+
data={hasError ? CircleXmark : CircleCheckFill}
6954
className={b('result-status-icon', {error: hasError})}
7055
/>
7156
);
7257
label = hasError ? 'Failed' : 'Completed';
7358
}
7459

7560
return (
76-
<div className={b(null, className)}>
77-
{icon}
78-
{label}
79-
{isQueryCancelledError(error) || loading ? null : <QuerySettingsIndicator />}
80-
</div>
61+
<Label
62+
theme={theme}
63+
size="m"
64+
className={b(null, className)}
65+
icon={icon}
66+
value={elapsedTime}
67+
>
68+
<Text color={textColor}>{label}</Text>
69+
</Label>
8170
);
8271
};
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import React from 'react';
2+
3+
import {duration} from '@gravity-ui/date-utils';
4+
5+
import {HOUR_IN_SECONDS, SECOND_IN_MS} from '../../utils/constants';
6+
7+
export function useElapsedTime(loading?: boolean) {
8+
const [startTime, setStartTime] = React.useState(Date.now());
9+
const [elapsedTime, setElapsedTime] = React.useState(0);
10+
11+
React.useEffect(() => {
12+
let timerId: ReturnType<typeof setInterval> | undefined;
13+
14+
if (loading) {
15+
setElapsedTime(0);
16+
setStartTime(Date.now());
17+
timerId = setInterval(() => {
18+
setElapsedTime(Date.now() - startTime);
19+
}, SECOND_IN_MS);
20+
} else {
21+
clearInterval(timerId);
22+
}
23+
return () => {
24+
clearInterval(timerId);
25+
};
26+
}, [loading, startTime]);
27+
28+
return elapsedTime > HOUR_IN_SECONDS * SECOND_IN_MS
29+
? duration(elapsedTime).format('hh:mm:ss')
30+
: duration(elapsedTime).format('mm:ss');
31+
}

src/containers/Tenant/Query/CancelQueryButton/CancelQueryButton.tsx

Lines changed: 0 additions & 28 deletions
This file was deleted.

src/containers/Tenant/Query/QueryDuration/QueryDuration.scss

Lines changed: 0 additions & 27 deletions
This file was deleted.

src/containers/Tenant/Query/QueryDuration/QueryDuration.tsx

Lines changed: 0 additions & 33 deletions
This file was deleted.

src/containers/Tenant/Query/QueryEditor/QueryEditor.tsx

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {isEqual} from 'lodash';
55
import {v4 as uuidv4} from 'uuid';
66

77
import SplitPane from '../../../../components/SplitPane';
8-
import {cancelQueryApi} from '../../../../store/reducers/cancelQuery';
98
import {
109
useStreamingAvailable,
1110
useTracingLevelOptionAvailable,
@@ -92,12 +91,11 @@ export default function QueryEditor(props: QueryEditorProps) {
9291
LAST_USED_QUERY_ACTION_KEY,
9392
);
9493
const [lastExecutedQueryText, setLastExecutedQueryText] = React.useState<string>('');
95-
const [isQueryStreamingEnabled] = useSetting(ENABLE_QUERY_STREAMING);
94+
const [isQueryStreamingEnabled] = useSetting<boolean>(ENABLE_QUERY_STREAMING);
9695
const isStreamingEnabled = useStreamingAvailable() && isQueryStreamingEnabled;
9796

9897
const [sendQuery] = queryApi.useUseSendQueryMutation();
9998
const [streamQuery] = queryApi.useUseStreamQueryMutation();
100-
const [sendCancelQuery, cancelQueryResponse] = cancelQueryApi.useCancelQueryMutation();
10199

102100
const runningQueryRef = React.useRef<{abort: VoidFunction} | null>(null);
103101

@@ -150,7 +148,6 @@ export default function QueryEditor(props: QueryEditorProps) {
150148
database: tenantName,
151149
querySettings,
152150
enableTracingLevel,
153-
queryId,
154151
});
155152
} else {
156153
runningQueryRef.current = sendQuery({
@@ -202,14 +199,6 @@ export default function QueryEditor(props: QueryEditorProps) {
202199
dispatchResultVisibilityState(PaneVisibilityActionTypes.triggerExpand);
203200
});
204201

205-
const handleCancelRunningQuery = React.useCallback(() => {
206-
if (isStreamingEnabled && runningQueryRef.current) {
207-
runningQueryRef.current.abort();
208-
} else if (result?.queryId) {
209-
sendCancelQuery({queryId: result?.queryId, database: tenantName});
210-
}
211-
}, [isStreamingEnabled, result?.queryId, sendCancelQuery, tenantName]);
212-
213202
const onCollapseResultHandler = () => {
214203
dispatchResultVisibilityState(PaneVisibilityActionTypes.triggerCollapse);
215204
};
@@ -229,6 +218,10 @@ export default function QueryEditor(props: QueryEditorProps) {
229218
isLoading={Boolean(result?.isLoading)}
230219
handleGetExplainQueryClick={handleGetExplainQueryClick}
231220
highlightedAction={lastUsedQueryAction}
221+
tenantName={tenantName}
222+
queryId={result?.queryId}
223+
isStreamingEnabled={isStreamingEnabled}
224+
runningQueryRef={runningQueryRef}
232225
/>
233226
);
234227
};
@@ -270,12 +263,10 @@ export default function QueryEditor(props: QueryEditorProps) {
270263
theme={theme}
271264
key={result?.queryId}
272265
result={result}
273-
cancelQueryResponse={cancelQueryResponse}
274266
tenantName={tenantName}
275267
path={path}
276268
showPreview={showPreview}
277269
queryText={lastExecutedQueryText}
278-
onCancelRunningQuery={handleCancelRunningQuery}
279270
tableSettings={tableSettings}
280271
/>
281272
</div>
@@ -292,17 +283,14 @@ interface ResultProps {
292283
type?: EPathType;
293284
theme: string;
294285
result?: QueryResult;
295-
cancelQueryResponse?: Pick<QueryResult, 'isLoading' | 'error'>;
296286
tenantName: string;
297287
path: string;
298288
showPreview?: boolean;
299289
queryText: string;
300290
tableSettings?: Partial<Settings>;
301-
onCancelRunningQuery: VoidFunction;
302291
}
303292
function Result({
304293
resultVisibilityState,
305-
cancelQueryResponse,
306294
onExpandResultHandler,
307295
onCollapseResultHandler,
308296
type,
@@ -313,7 +301,6 @@ function Result({
313301
showPreview,
314302
queryText,
315303
tableSettings,
316-
onCancelRunningQuery,
317304
}: ResultProps) {
318305
if (showPreview) {
319306
return <Preview database={tenantName} path={path} type={type} />;
@@ -327,13 +314,10 @@ function Result({
327314
theme={theme}
328315
tenantName={tenantName}
329316
isResultsCollapsed={resultVisibilityState.collapsed}
330-
isCancelError={Boolean(cancelQueryResponse?.error)}
331-
isCancelling={Boolean(cancelQueryResponse?.isLoading)}
332317
tableSettings={tableSettings}
333318
onExpandResults={onExpandResultHandler}
334319
onCollapseResults={onCollapseResultHandler}
335320
queryText={queryText}
336-
onCancelRunningQuery={onCancelRunningQuery}
337321
/>
338322
);
339323
}

0 commit comments

Comments
 (0)