Skip to content

Commit b12dceb

Browse files
authored
fix: fix top queries table row height (#565)
1 parent db5d922 commit b12dceb

File tree

9 files changed

+85
-10
lines changed

9 files changed

+85
-10
lines changed

package-lock.json

Lines changed: 5 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
@@ -18,6 +18,7 @@
1818
"axios": "0.19.2",
1919
"bem-cn-lite": "4.0.0",
2020
"copy-to-clipboard": "^3.3.3",
21+
"crc-32": "^1.2.2",
2122
"history": "4.10.1",
2223
"js-cookie": "2.2.1",
2324
"lodash": "4.17.11",

src/components/TruncatedQuery/TruncatedQuery.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,12 @@
1414
}
1515
}
1616
}
17+
18+
&__popover-content {
19+
overflow: hidden;
20+
21+
max-width: 600px;
22+
23+
white-space: pre;
24+
}
1725
}

src/components/TruncatedQuery/TruncatedQuery.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import cn from 'bem-cn-lite';
22

3+
import {CellWithPopover} from '../CellWithPopover/CellWithPopover';
4+
35
import './TruncatedQuery.scss';
46

57
const b = cn('kv-truncated-query');
68

79
interface TruncatedQueryProps {
8-
value: string | undefined;
10+
value?: string;
911
maxQueryHeight?: number;
1012
}
1113

@@ -26,3 +28,15 @@ export const TruncatedQuery = ({value = '', maxQueryHeight = 6}: TruncatedQueryP
2628
}
2729
return <>{value}</>;
2830
};
31+
32+
interface OneLineQueryWithPopoverProps {
33+
value?: string;
34+
}
35+
36+
export const OneLineQueryWithPopover = ({value = ''}: OneLineQueryWithPopoverProps) => {
37+
return (
38+
<CellWithPopover contentClassName={b('popover-content')} content={value}>
39+
{value}
40+
</CellWithPopover>
41+
);
42+
};

src/containers/Tenant/Diagnostics/TenantOverview/TenantCpu/TopQueries.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import qs from 'qs';
21
import {useDispatch} from 'react-redux';
32
import {useHistory, useLocation} from 'react-router';
43
import {useCallback} from 'react';
@@ -14,6 +13,7 @@ import {
1413
} from '../../../../../store/reducers/tenantOverview/topQueries/tenantOverviewTopQueries';
1514
import {changeUserInput} from '../../../../../store/reducers/executeQuery';
1615
import {useAutofetcher, useTypedSelector} from '../../../../../utils/hooks';
16+
import {parseQuery} from '../../../../../routes';
1717
import {TenantTabsGroups, getTenantPath} from '../../../TenantPages';
1818
import {getTenantOverviewTopQueriesColumns} from '../../TopQueries/getTopQueriesColumns';
1919
import {TenantOverviewTableLayout} from '../TenantOverviewTableLayout';
@@ -55,9 +55,7 @@ export function TopQueries({path}: TopQueriesProps) {
5555

5656
dispatch(changeUserInput({input}));
5757

58-
const queryParams = qs.parse(location.search, {
59-
ignoreQueryPrefix: true,
60-
});
58+
const queryParams = parseQuery(location);
6159

6260
const queryPath = getTenantPath({
6361
...queryParams,

src/containers/Tenant/Diagnostics/TopQueries/TopQueries.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {useAutofetcher, useTypedSelector} from '../../../../utils/hooks';
3030
import {prepareQueryError} from '../../../../utils/query';
3131
import {parseQuery} from '../../../../routes';
3232
import {QUERY_TABLE_SETTINGS} from '../../utils/constants';
33+
import {isSortableTopQueriesProperty} from '../../../../utils/diagnostics';
3334
import {isColumnEntityType} from '../../utils/schema';
3435
import {TenantTabsGroups, getTenantPath} from '../../TenantPages';
3536
import {getTopQueriesColumns} from './getTopQueriesColumns';
@@ -58,7 +59,7 @@ export const TopQueries = ({path, type}: TopQueriesProps) => {
5859
data: {result: data = undefined} = {},
5960
filters: storeFilters,
6061
} = useTypedSelector((state) => state.executeTopQueries);
61-
const columns = getTopQueriesColumns();
62+
const rawColumns = getTopQueriesColumns();
6263

6364
const preventFetch = useRef(false);
6465

@@ -71,6 +72,11 @@ export const TopQueries = ({path, type}: TopQueriesProps) => {
7172
dispatch(setTopQueriesFilters(filters));
7273
}, [dispatch, filters]);
7374

75+
const columns = rawColumns.map((column) => ({
76+
...column,
77+
sortable: isSortableTopQueriesProperty(column.name),
78+
}));
79+
7480
const setDefaultFiltersFromResponse = (responseData?: IQueryResult) => {
7581
const intervalEnd = responseData?.result?.[0]?.IntervalEnd;
7682

src/containers/Tenant/Diagnostics/TopQueries/getTopQueriesColumns.tsx

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ import DataTable, {type Column} from '@gravity-ui/react-data-table';
44

55
import type {KeyValueRow} from '../../../../types/api/query';
66
import {formatDateTime, formatNumber} from '../../../../utils/dataFormatters/dataFormatters';
7-
import {TruncatedQuery} from '../../../../components/TruncatedQuery/TruncatedQuery';
7+
import {generateHash} from '../../../../utils/generateHash';
8+
import {
9+
TruncatedQuery,
10+
OneLineQueryWithPopover,
11+
} from '../../../../components/TruncatedQuery/TruncatedQuery';
812
import {MAX_QUERY_HEIGHT} from '../../utils/constants';
913

1014
import './TopQueries.scss';
@@ -18,6 +22,8 @@ const TOP_QUERIES_COLUMNS_IDS = {
1822
ReadRows: 'ReadRows',
1923
ReadBytes: 'ReadBytes',
2024
UserSID: 'UserSID',
25+
OneLineQueryText: 'OneLineQueryText',
26+
QueryHash: 'QueryHash',
2127
};
2228

2329
const cpuTimeUsColumn: Column<KeyValueRow> = {
@@ -66,6 +72,20 @@ const userSIDColumn: Column<KeyValueRow> = {
6672
align: DataTable.LEFT,
6773
};
6874

75+
const oneLineQueryTextColumn: Column<KeyValueRow> = {
76+
name: TOP_QUERIES_COLUMNS_IDS.OneLineQueryText,
77+
header: 'QueryText',
78+
render: ({row}) => <OneLineQueryWithPopover value={row.QueryText?.toString()} />,
79+
sortable: false,
80+
};
81+
82+
const queryHashColumn: Column<KeyValueRow> = {
83+
name: TOP_QUERIES_COLUMNS_IDS.QueryHash,
84+
render: ({row}) => generateHash(String(row.QueryText)),
85+
width: 130,
86+
sortable: false,
87+
};
88+
6989
export const getTopQueriesColumns = (): Column<KeyValueRow>[] => {
7090
return [
7191
cpuTimeUsColumn,
@@ -78,5 +98,5 @@ export const getTopQueriesColumns = (): Column<KeyValueRow>[] => {
7898
};
7999

80100
export const getTenantOverviewTopQueriesColumns = (): Column<KeyValueRow>[] => {
81-
return [queryTextColumn, cpuTimeUsColumn];
101+
return [queryHashColumn, oneLineQueryTextColumn, cpuTimeUsColumn];
82102
};

src/utils/diagnostics.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
11
import {ValueOf} from '../types/common';
22

3-
export const TOP_SHARDS_SORT_VALUES = {
3+
const TOP_SHARDS_SORT_VALUES = {
44
CPUCores: 'CPUCores',
55
DataSize: 'DataSize',
66
} as const;
77

8-
export type TopShardsSortValue = ValueOf<typeof TOP_SHARDS_SORT_VALUES>;
8+
const TOP_QUERIES_SORT_VALUES = {
9+
CPUTimeUs: 'CPUTimeUs',
10+
EndTime: 'EndTime',
11+
ReadRows: 'ReadRows',
12+
ReadBytes: 'ReadBytes',
13+
UserSID: 'UserSID',
14+
} as const;
15+
16+
type TopShardsSortValue = ValueOf<typeof TOP_SHARDS_SORT_VALUES>;
17+
type TopQueriesSortValue = ValueOf<typeof TOP_QUERIES_SORT_VALUES>;
918

1019
export const isSortableTopShardsProperty = (value: string): value is TopShardsSortValue =>
1120
Object.values(TOP_SHARDS_SORT_VALUES).includes(value as TopShardsSortValue);
21+
22+
export const isSortableTopQueriesProperty = (value: string): value is TopQueriesSortValue =>
23+
Object.values(TOP_QUERIES_SORT_VALUES).includes(value as TopQueriesSortValue);

src/utils/generateHash.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import crc32 from 'crc-32';
2+
3+
export const generateHash = (value: string) => {
4+
// 1. crc32.str(value) - generate crc32 hash
5+
// 2. (>>>) - use unsigned right shift operator (>>>) to avoid negative values
6+
// 3. toString(16) - convert hash to hex format
7+
// 4. toUpperCase() - convert hash to uppercase
8+
// 5. padStart(8, '0') - fill hash with leading zeros if hash length < 8
9+
// eslint-disable-next-line no-bitwise
10+
return (crc32.str(value) >>> 0).toString(16).toUpperCase().padStart(8, '0');
11+
};

0 commit comments

Comments
 (0)