Skip to content

Commit 9ac8cfc

Browse files
authored
feat: redesign query (#1974)
1 parent 519f587 commit 9ac8cfc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+697
-546
lines changed

package-lock.json

Lines changed: 16 additions & 12 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 & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@
130130
"@gravity-ui/prettier-config": "^1.1.0",
131131
"@gravity-ui/stylelint-config": "^4.0.1",
132132
"@gravity-ui/tsconfig": "^1.0.0",
133-
"@playwright/test": "^1.49.1",
133+
"@playwright/test": "^1.50.1",
134134
"@testing-library/jest-dom": "^6.6.3",
135135
"@testing-library/react": "^16.1.0",
136136
"@testing-library/user-event": "^14.5.2",

playwright.config.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@ const config: PlaywrightTestConfig = {
1818
? undefined
1919
: {
2020
command: 'npm run dev',
21+
env: {
22+
REACT_APP_DISABLE_CHECKS: 'true',
23+
},
2124
port: 3000,
22-
reuseExistingServer: true,
25+
reuseExistingServer: !process.env.CI,
2326
},
2427
use: {
2528
baseURL: baseUrl || 'http://localhost:3000/',

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: 63 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
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 {duration} from '@gravity-ui/date-utils';
4+
import {CircleCheckFill, CircleQuestionFill, CircleStop, CircleXmark} from '@gravity-ui/icons';
5+
import type {LabelProps, TextProps} from '@gravity-ui/uikit';
6+
import {Icon, Label, Spin, Text} from '@gravity-ui/uikit';
117

12-
import i18n from '../../containers/Tenant/Query/i18n';
138
import {isQueryCancelledError} from '../../containers/Tenant/Query/utils/isQueryCancelledError';
9+
import {selectQueryDuration} from '../../store/reducers/query/query';
1410
import {cn} from '../../utils/cn';
15-
import {useChangedQuerySettings} from '../../utils/hooks/useChangedQuerySettings';
11+
import {HOUR_IN_SECONDS, SECOND_IN_MS} from '../../utils/constants';
12+
import {useTypedSelector} from '../../utils/hooks';
1613
import {isAxiosError} from '../../utils/response';
17-
import QuerySettingsDescription from '../QuerySettingsDescription/QuerySettingsDescription';
1814

1915
import './QueryExecutionStatus.scss';
2016

@@ -26,57 +22,83 @@ interface QueryExecutionStatusProps {
2622
loading?: boolean;
2723
}
2824

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-
5125
export const QueryExecutionStatus = ({className, error, loading}: QueryExecutionStatusProps) => {
5226
let icon: React.ReactNode;
5327
let label: string;
28+
let theme: LabelProps['theme'];
29+
let textColor: TextProps['color'];
30+
const {startTime, endTime} = useTypedSelector(selectQueryDuration);
31+
32+
const [queryDuration, setQueryDuration] = React.useState<number>(
33+
startTime ? (endTime || Date.now()) - startTime : 0,
34+
);
35+
36+
const isCancelled = isQueryCancelledError(error);
37+
38+
const setDuration = React.useCallback(() => {
39+
if (startTime) {
40+
const actualEndTime = endTime || Date.now();
41+
setQueryDuration(actualEndTime - startTime);
42+
}
43+
}, [endTime, startTime]);
44+
45+
React.useEffect(() => {
46+
let timerId: ReturnType<typeof setInterval> | undefined;
47+
setDuration();
48+
49+
if (loading) {
50+
timerId = setInterval(setDuration, SECOND_IN_MS);
51+
} else {
52+
clearInterval(timerId);
53+
}
54+
return () => {
55+
clearInterval(timerId);
56+
};
57+
}, [loading, setDuration]);
58+
59+
const formattedQueryDuration = React.useMemo(() => {
60+
return queryDuration > HOUR_IN_SECONDS * SECOND_IN_MS
61+
? duration(queryDuration).format('hh:mm:ss')
62+
: duration(queryDuration).format('mm:ss');
63+
}, [queryDuration]);
5464

5565
if (loading) {
66+
theme = 'info';
67+
textColor = 'info-heavy';
5668
icon = <Spin size="xs" />;
5769
label = 'Running';
5870
} else if (isAxiosError(error) && error.code === 'ECONNABORTED') {
71+
theme = 'danger';
72+
textColor = 'danger-heavy';
5973
icon = <Icon data={CircleQuestionFill} />;
6074
label = 'Connection aborted';
61-
} else if (isQueryCancelledError(error)) {
62-
icon = <Icon data={CircleStop} />;
75+
} else if (isCancelled) {
76+
theme = 'warning';
77+
textColor = 'warning-heavy';
78+
icon = <Icon data={CircleStop} className={b('result-status-icon', {error: true})} />;
6379
label = 'Stopped';
6480
} else {
6581
const hasError = Boolean(error);
82+
theme = hasError ? 'danger' : 'success';
83+
textColor = hasError ? 'danger-heavy' : 'positive-heavy';
6684
icon = (
6785
<Icon
68-
data={hasError ? CircleXmark : CircleCheck}
86+
data={hasError ? CircleXmark : CircleCheckFill}
6987
className={b('result-status-icon', {error: hasError})}
7088
/>
7189
);
7290
label = hasError ? 'Failed' : 'Completed';
7391
}
7492

7593
return (
76-
<div className={b(null, className)}>
77-
{icon}
78-
{label}
79-
{isQueryCancelledError(error) || loading ? null : <QuerySettingsIndicator />}
80-
</div>
94+
<Label
95+
theme={theme}
96+
size="m"
97+
className={b(null, className)}
98+
icon={icon}
99+
value={formattedQueryDuration}
100+
>
101+
<Text color={textColor}>{label}</Text>
102+
</Label>
81103
);
82104
};

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.

0 commit comments

Comments
 (0)