ydb-embedded-ui 4.19.3 → 4.20.1
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +27 -0
- package/dist/components/CellWithPopover/CellWithPopover.scss +13 -0
- package/dist/components/CellWithPopover/CellWithPopover.tsx +26 -0
- package/dist/components/LinkToSchemaObject/LinkToSchemaObject.tsx +20 -0
- package/dist/components/NodeHostWrapper/NodeHostWrapper.scss +0 -2
- package/dist/components/NodeHostWrapper/NodeHostWrapper.tsx +28 -29
- package/dist/components/QueryExecutionStatus/QueryExecutionStatus.tsx +3 -2
- package/dist/components/TruncatedQuery/TruncatedQuery.scss +8 -0
- package/dist/components/TruncatedQuery/TruncatedQuery.tsx +15 -1
- package/dist/components/UsageLabel/UsageLabel.scss +6 -0
- package/dist/components/UsageLabel/UsageLabel.tsx +22 -0
- package/dist/containers/AsideNavigation/AsideNavigation.tsx +13 -8
- package/dist/containers/AsideNavigation/i18n/en.json +13 -0
- package/dist/containers/AsideNavigation/i18n/index.ts +11 -0
- package/dist/containers/AsideNavigation/i18n/ru.json +13 -0
- package/dist/containers/Node/NodeStructure/Pdisk.tsx +74 -68
- package/dist/containers/Node/NodeStructure/Vdisk.tsx +9 -33
- package/dist/containers/Nodes/Nodes.tsx +10 -2
- package/dist/containers/Nodes/getNodesColumns.tsx +207 -123
- package/dist/containers/Storage/Storage.tsx +9 -2
- package/dist/containers/Storage/StorageGroups/StorageGroups.scss +0 -11
- package/dist/containers/Storage/StorageGroups/getStorageGroupsColumns.tsx +11 -11
- package/dist/containers/Storage/utils/index.ts +1 -22
- package/dist/containers/Tenant/Diagnostics/Describe/Describe.tsx +2 -3
- package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.scss +0 -1
- package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.tsx +4 -2
- package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +1 -0
- package/dist/containers/Tenant/Diagnostics/TenantOverview/Healthcheck/HealthcheckDetails.tsx +8 -1
- package/dist/containers/Tenant/Diagnostics/TenantOverview/Healthcheck/HealthcheckPreview.tsx +11 -1
- package/dist/containers/Tenant/Diagnostics/TenantOverview/Healthcheck/IssuesViewer/IssueTree.tsx +0 -1
- package/dist/containers/Tenant/Diagnostics/TenantOverview/MetricsCards/MetricsCards.tsx +3 -0
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantCpu/TenantCpu.tsx +21 -0
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantCpu/TopNodesByCpu.tsx +53 -0
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantCpu/TopNodesByLoad.tsx +53 -0
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantCpu/TopQueries.tsx +83 -0
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantCpu/TopShards.tsx +53 -0
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantMemory/TenantMemory.tsx +9 -0
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantMemory/TopNodesByMemory.tsx +55 -0
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.scss +44 -0
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.tsx +35 -19
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverviewTableLayout.tsx +53 -0
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/TenantStorage.tsx +4 -2
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/TopGroups.tsx +9 -36
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/TopTables.tsx +22 -41
- package/dist/containers/Tenant/Diagnostics/TenantOverview/i18n/en.json +3 -3
- package/dist/containers/Tenant/Diagnostics/TenantOverview/i18n/ru.json +3 -3
- package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.scss +0 -2
- package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.tsx +19 -61
- package/dist/containers/Tenant/Diagnostics/TopQueries/getTopQueriesColumns.tsx +102 -0
- package/dist/containers/Tenant/Diagnostics/TopShards/Filters/Filters.tsx +2 -2
- package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.tsx +18 -97
- package/dist/containers/Tenant/Diagnostics/TopShards/getTopShardsColumns.tsx +138 -0
- package/dist/containers/Tenant/Info/ExternalTable/ExternalTable.tsx +2 -4
- package/dist/containers/Tenant/Query/ExecuteResult/{ExecuteResult.js → ExecuteResult.tsx} +51 -31
- package/dist/containers/Tenant/Query/Issues/Issues.tsx +4 -6
- package/dist/containers/Tenant/Query/QueryDuration/QueryDuration.tsx +1 -1
- package/dist/containers/Tenant/utils/paneVisibilityToggleHelpers.tsx +1 -1
- package/dist/routes.ts +26 -1
- package/dist/store/reducers/{executeTopQueries.ts → executeTopQueries/executeTopQueries.ts} +23 -75
- package/dist/{types/store/executeTopQueries.ts → store/reducers/executeTopQueries/types.ts} +3 -7
- package/dist/store/reducers/executeTopQueries/utils.ts +36 -0
- package/dist/store/reducers/index.ts +12 -2
- package/dist/store/reducers/nodes/types.ts +1 -0
- package/dist/store/reducers/nodes/utils.ts +16 -6
- package/dist/store/reducers/{shardsWorkload.ts → shardsWorkload/shardsWorkload.ts} +5 -11
- package/dist/{types/store/shardsWorkload.ts → store/reducers/shardsWorkload/types.ts} +3 -7
- package/dist/store/reducers/tenantOverview/topNodesByCpu/topNodesByCpu.ts +87 -0
- package/dist/store/reducers/tenantOverview/topNodesByCpu/types.ts +29 -0
- package/dist/store/reducers/tenantOverview/topNodesByLoad/topNodesByLoad.ts +87 -0
- package/dist/store/reducers/tenantOverview/topNodesByLoad/types.ts +29 -0
- package/dist/store/reducers/tenantOverview/topNodesByMemory/topNodesByMemory.ts +87 -0
- package/dist/store/reducers/tenantOverview/topNodesByMemory/types.ts +29 -0
- package/dist/store/reducers/tenantOverview/topQueries/tenantOverviewTopQueries.ts +93 -0
- package/dist/store/reducers/tenantOverview/topQueries/types.ts +14 -0
- package/dist/store/reducers/tenantOverview/topShards/tenantOverviewTopShards.ts +103 -0
- package/dist/store/reducers/tenantOverview/topShards/types.ts +14 -0
- package/dist/store/reducers/tenantOverview/topShards/utils.ts +3 -0
- package/dist/styles/mixins.scss +4 -0
- package/dist/types/additionalProps.ts +3 -1
- package/dist/types/api/compute.ts +1 -1
- package/dist/types/react-json-inspector.d.ts +21 -0
- package/dist/utils/diagnostics.ts +23 -0
- package/dist/utils/generateEvaluator.ts +21 -0
- package/dist/utils/generateHash.ts +11 -0
- package/package.json +3 -2
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/TenantStorage.scss +0 -41
@@ -1,26 +1,20 @@
|
|
1
1
|
import {useDispatch} from 'react-redux';
|
2
|
-
import
|
2
|
+
import {useLocation} from 'react-router';
|
3
3
|
|
4
4
|
import DataTable, {Column} from '@gravity-ui/react-data-table';
|
5
|
-
import {Popover} from '@gravity-ui/uikit';
|
6
5
|
|
7
6
|
import {useAutofetcher, useTypedSelector} from '../../../../../utils/hooks';
|
8
7
|
import {
|
9
8
|
fetchTopTables,
|
10
9
|
setDataWasNotLoaded,
|
11
10
|
} from '../../../../../store/reducers/tenantOverview/executeTopTables/executeTopTables';
|
12
|
-
import {
|
13
|
-
TENANT_OVERVIEW_TABLES_LIMIT,
|
14
|
-
TENANT_OVERVIEW_TABLES_SETTINGS,
|
15
|
-
} from '../../../../../utils/constants';
|
16
11
|
import type {KeyValueRow} from '../../../../../types/api/query';
|
17
12
|
import {formatBytes, getSizeWithSignificantDigits} from '../../../../../utils/bytesParsers';
|
18
|
-
import {
|
19
|
-
import {
|
20
|
-
|
21
|
-
import './TenantStorage.scss';
|
13
|
+
import {LinkToSchemaObject} from '../../../../../components/LinkToSchemaObject/LinkToSchemaObject';
|
14
|
+
import {CellWithPopover} from '../../../../../components/CellWithPopover/CellWithPopover';
|
15
|
+
import {TenantOverviewTableLayout} from '../TenantOverviewTableLayout';
|
22
16
|
|
23
|
-
|
17
|
+
import '../TenantOverview.scss';
|
24
18
|
|
25
19
|
interface TopTablesProps {
|
26
20
|
path: string;
|
@@ -28,6 +22,7 @@ interface TopTablesProps {
|
|
28
22
|
|
29
23
|
export function TopTables({path}: TopTablesProps) {
|
30
24
|
const dispatch = useDispatch();
|
25
|
+
const location = useLocation();
|
31
26
|
|
32
27
|
const {autorefresh} = useTypedSelector((state) => state.schema);
|
33
28
|
|
@@ -67,39 +62,25 @@ export function TopTables({path}: TopTablesProps) {
|
|
67
62
|
{
|
68
63
|
name: 'Path',
|
69
64
|
sortable: false,
|
70
|
-
render: ({row}) =>
|
71
|
-
|
72
|
-
<
|
73
|
-
{row.Path}
|
74
|
-
|
75
|
-
|
76
|
-
|
65
|
+
render: ({row}) =>
|
66
|
+
row.Path ? (
|
67
|
+
<CellWithPopover content={row.Path}>
|
68
|
+
<LinkToSchemaObject path={String(row.Path)} location={location}>
|
69
|
+
{row.Path}
|
70
|
+
</LinkToSchemaObject>
|
71
|
+
</CellWithPopover>
|
72
|
+
) : null,
|
77
73
|
},
|
78
74
|
];
|
79
75
|
|
80
|
-
const renderContent = () => {
|
81
|
-
if (error) {
|
82
|
-
return <ResponseError error={error} />;
|
83
|
-
}
|
84
|
-
|
85
|
-
if (loading && !wasLoaded) {
|
86
|
-
return <TableSkeleton rows={TENANT_OVERVIEW_TABLES_LIMIT} />;
|
87
|
-
}
|
88
|
-
|
89
|
-
return (
|
90
|
-
<DataTable
|
91
|
-
theme="yandex-cloud"
|
92
|
-
columns={columns}
|
93
|
-
settings={TENANT_OVERVIEW_TABLES_SETTINGS}
|
94
|
-
data={data || []}
|
95
|
-
/>
|
96
|
-
);
|
97
|
-
};
|
98
|
-
|
99
76
|
return (
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
77
|
+
<TenantOverviewTableLayout
|
78
|
+
data={data || []}
|
79
|
+
columns={columns}
|
80
|
+
title="Top tables by size"
|
81
|
+
loading={loading}
|
82
|
+
wasLoaded={wasLoaded}
|
83
|
+
error={error}
|
84
|
+
/>
|
104
85
|
);
|
105
86
|
}
|
@@ -2,10 +2,10 @@
|
|
2
2
|
"no-data": "No data",
|
3
3
|
"no-pools-data": "No pools data",
|
4
4
|
|
5
|
+
"top-nodes.empty-data": "No such nodes",
|
6
|
+
|
5
7
|
"title.pools": "Pools",
|
6
8
|
"title.metrics": "Metrics",
|
7
9
|
|
8
|
-
"top-groups.empty-data": "No such groups"
|
9
|
-
|
10
|
-
"label.under-development": "This section is under development"
|
10
|
+
"top-groups.empty-data": "No such groups"
|
11
11
|
}
|
@@ -2,10 +2,10 @@
|
|
2
2
|
"no-data": "Нет данных",
|
3
3
|
"no-pools-data": "Нет данных о пулах",
|
4
4
|
|
5
|
+
"top-nodes.empty-data": "Нет узлов",
|
6
|
+
|
5
7
|
"title.pools": "Пулы",
|
6
8
|
"title.metrics": "Метрики",
|
7
9
|
|
8
|
-
"top-groups.empty-data": "Нет групп"
|
9
|
-
|
10
|
-
"label.under-development": "Этот раздел находится в разработке"
|
10
|
+
"top-groups.empty-data": "Нет групп"
|
11
11
|
}
|
@@ -1,91 +1,45 @@
|
|
1
1
|
import {useCallback, useEffect, useRef, useState} from 'react';
|
2
2
|
import {useDispatch} from 'react-redux';
|
3
3
|
import {useHistory, useLocation} from 'react-router';
|
4
|
-
import qs from 'qs';
|
5
4
|
import cn from 'bem-cn-lite';
|
6
5
|
|
7
|
-
import DataTable
|
6
|
+
import DataTable from '@gravity-ui/react-data-table';
|
8
7
|
import {Loader} from '@gravity-ui/uikit';
|
9
8
|
|
10
9
|
import {DateRange, DateRangeValues} from '../../../../components/DateRange';
|
11
10
|
import {Search} from '../../../../components/Search';
|
12
|
-
import {TruncatedQuery} from '../../../../components/TruncatedQuery/TruncatedQuery';
|
13
11
|
|
14
12
|
import {changeUserInput} from '../../../../store/reducers/executeQuery';
|
15
|
-
import {
|
16
|
-
fetchTopQueries,
|
17
|
-
setTopQueriesFilters,
|
18
|
-
setTopQueriesState,
|
19
|
-
} from '../../../../store/reducers/executeTopQueries';
|
20
13
|
|
21
|
-
import type {KeyValueRow} from '../../../../types/api/query';
|
22
14
|
import type {EPathType} from '../../../../types/api/schema';
|
23
|
-
import type {ITopQueriesFilters} from '../../../../types/store/executeTopQueries';
|
24
15
|
import type {IQueryResult} from '../../../../types/store/query';
|
16
|
+
import type {ITopQueriesFilters} from '../../../../store/reducers/executeTopQueries/types';
|
25
17
|
|
26
18
|
import {
|
27
19
|
TENANT_PAGE,
|
28
20
|
TENANT_PAGES_IDS,
|
29
21
|
TENANT_QUERY_TABS_ID,
|
30
22
|
} from '../../../../store/reducers/tenant/constants';
|
31
|
-
import {
|
23
|
+
import {
|
24
|
+
setTopQueriesFilters,
|
25
|
+
setTopQueriesState,
|
26
|
+
fetchTopQueries,
|
27
|
+
} from '../../../../store/reducers/executeTopQueries/executeTopQueries';
|
32
28
|
import {HOUR_IN_SECONDS} from '../../../../utils/constants';
|
33
29
|
import {useAutofetcher, useTypedSelector} from '../../../../utils/hooks';
|
34
30
|
import {prepareQueryError} from '../../../../utils/query';
|
35
|
-
|
36
|
-
import {
|
31
|
+
import {parseQuery} from '../../../../routes';
|
32
|
+
import {QUERY_TABLE_SETTINGS} from '../../utils/constants';
|
33
|
+
import {isSortableTopQueriesProperty} from '../../../../utils/diagnostics';
|
37
34
|
import {isColumnEntityType} from '../../utils/schema';
|
38
35
|
import {TenantTabsGroups, getTenantPath} from '../../TenantPages';
|
36
|
+
import {getTopQueriesColumns} from './getTopQueriesColumns';
|
39
37
|
|
40
38
|
import i18n from './i18n';
|
41
39
|
import './TopQueries.scss';
|
42
40
|
|
43
41
|
const b = cn('kv-top-queries');
|
44
42
|
|
45
|
-
const COLUMNS: Column<KeyValueRow>[] = [
|
46
|
-
{
|
47
|
-
name: 'CPUTimeUs',
|
48
|
-
sortAccessor: (row) => Number(row.CPUTimeUs),
|
49
|
-
align: DataTable.RIGHT,
|
50
|
-
},
|
51
|
-
{
|
52
|
-
name: 'QueryText',
|
53
|
-
width: 500,
|
54
|
-
sortable: false,
|
55
|
-
render: ({row}) => (
|
56
|
-
<div className={b('query')}>
|
57
|
-
<TruncatedQuery
|
58
|
-
value={row.QueryText?.toString()}
|
59
|
-
maxQueryHeight={MAX_QUERY_HEIGHT}
|
60
|
-
/>
|
61
|
-
</div>
|
62
|
-
),
|
63
|
-
},
|
64
|
-
{
|
65
|
-
name: 'EndTime',
|
66
|
-
render: ({row}) => formatDateTime(new Date(row.EndTime as string).getTime()),
|
67
|
-
align: DataTable.RIGHT,
|
68
|
-
},
|
69
|
-
{
|
70
|
-
name: 'ReadRows',
|
71
|
-
render: ({row}) => formatNumber(row.ReadRows),
|
72
|
-
sortAccessor: (row) => Number(row.ReadRows),
|
73
|
-
align: DataTable.RIGHT,
|
74
|
-
},
|
75
|
-
{
|
76
|
-
name: 'ReadBytes',
|
77
|
-
render: ({row}) => formatNumber(row.ReadBytes),
|
78
|
-
sortAccessor: (row) => Number(row.ReadBytes),
|
79
|
-
align: DataTable.RIGHT,
|
80
|
-
},
|
81
|
-
{
|
82
|
-
name: 'UserSID',
|
83
|
-
render: ({row}) => <div className={b('user-sid')}>{row.UserSID || '–'}</div>,
|
84
|
-
sortAccessor: (row) => String(row.UserSID),
|
85
|
-
align: DataTable.LEFT,
|
86
|
-
},
|
87
|
-
];
|
88
|
-
|
89
43
|
interface TopQueriesProps {
|
90
44
|
path: string;
|
91
45
|
type?: EPathType;
|
@@ -105,6 +59,7 @@ export const TopQueries = ({path, type}: TopQueriesProps) => {
|
|
105
59
|
data: {result: data = undefined} = {},
|
106
60
|
filters: storeFilters,
|
107
61
|
} = useTypedSelector((state) => state.executeTopQueries);
|
62
|
+
const rawColumns = getTopQueriesColumns();
|
108
63
|
|
109
64
|
const preventFetch = useRef(false);
|
110
65
|
|
@@ -117,6 +72,11 @@ export const TopQueries = ({path, type}: TopQueriesProps) => {
|
|
117
72
|
dispatch(setTopQueriesFilters(filters));
|
118
73
|
}, [dispatch, filters]);
|
119
74
|
|
75
|
+
const columns = rawColumns.map((column) => ({
|
76
|
+
...column,
|
77
|
+
sortable: isSortableTopQueriesProperty(column.name),
|
78
|
+
}));
|
79
|
+
|
120
80
|
const setDefaultFiltersFromResponse = (responseData?: IQueryResult) => {
|
121
81
|
const intervalEnd = responseData?.result?.[0]?.IntervalEnd;
|
122
82
|
|
@@ -173,9 +133,7 @@ export const TopQueries = ({path, type}: TopQueriesProps) => {
|
|
173
133
|
|
174
134
|
dispatch(changeUserInput({input}));
|
175
135
|
|
176
|
-
const queryParams =
|
177
|
-
ignoreQueryPrefix: true,
|
178
|
-
});
|
136
|
+
const queryParams = parseQuery(location);
|
179
137
|
|
180
138
|
const queryPath = getTenantPath({
|
181
139
|
...queryParams,
|
@@ -220,7 +178,7 @@ export const TopQueries = ({path, type}: TopQueriesProps) => {
|
|
220
178
|
return (
|
221
179
|
<div className={b('table')}>
|
222
180
|
<DataTable
|
223
|
-
columns={
|
181
|
+
columns={columns}
|
224
182
|
data={data}
|
225
183
|
settings={QUERY_TABLE_SETTINGS}
|
226
184
|
onRowClick={handleRowClick}
|
@@ -0,0 +1,102 @@
|
|
1
|
+
import cn from 'bem-cn-lite';
|
2
|
+
|
3
|
+
import DataTable, {type Column} from '@gravity-ui/react-data-table';
|
4
|
+
|
5
|
+
import type {KeyValueRow} from '../../../../types/api/query';
|
6
|
+
import {formatDateTime, formatNumber} from '../../../../utils/dataFormatters/dataFormatters';
|
7
|
+
import {generateHash} from '../../../../utils/generateHash';
|
8
|
+
import {
|
9
|
+
TruncatedQuery,
|
10
|
+
OneLineQueryWithPopover,
|
11
|
+
} from '../../../../components/TruncatedQuery/TruncatedQuery';
|
12
|
+
import {MAX_QUERY_HEIGHT} from '../../utils/constants';
|
13
|
+
|
14
|
+
import './TopQueries.scss';
|
15
|
+
|
16
|
+
const b = cn('kv-top-queries');
|
17
|
+
|
18
|
+
const TOP_QUERIES_COLUMNS_IDS = {
|
19
|
+
CPUTimeUs: 'CPUTimeUs',
|
20
|
+
QueryText: 'QueryText',
|
21
|
+
EndTime: 'EndTime',
|
22
|
+
ReadRows: 'ReadRows',
|
23
|
+
ReadBytes: 'ReadBytes',
|
24
|
+
UserSID: 'UserSID',
|
25
|
+
OneLineQueryText: 'OneLineQueryText',
|
26
|
+
QueryHash: 'QueryHash',
|
27
|
+
};
|
28
|
+
|
29
|
+
const cpuTimeUsColumn: Column<KeyValueRow> = {
|
30
|
+
name: TOP_QUERIES_COLUMNS_IDS.CPUTimeUs,
|
31
|
+
sortAccessor: (row) => Number(row.CPUTimeUs),
|
32
|
+
width: 120,
|
33
|
+
align: DataTable.RIGHT,
|
34
|
+
sortable: false,
|
35
|
+
};
|
36
|
+
|
37
|
+
const queryTextColumn: Column<KeyValueRow> = {
|
38
|
+
name: TOP_QUERIES_COLUMNS_IDS.QueryText,
|
39
|
+
sortAccessor: (row) => Number(row.CPUTimeUs),
|
40
|
+
render: ({row}) => (
|
41
|
+
<div className={b('query')}>
|
42
|
+
<TruncatedQuery value={row.QueryText?.toString()} maxQueryHeight={MAX_QUERY_HEIGHT} />
|
43
|
+
</div>
|
44
|
+
),
|
45
|
+
sortable: false,
|
46
|
+
};
|
47
|
+
|
48
|
+
const endTimeColumn: Column<KeyValueRow> = {
|
49
|
+
name: TOP_QUERIES_COLUMNS_IDS.EndTime,
|
50
|
+
render: ({row}) => formatDateTime(new Date(row.EndTime as string).getTime()),
|
51
|
+
align: DataTable.RIGHT,
|
52
|
+
};
|
53
|
+
|
54
|
+
const readRowsColumn: Column<KeyValueRow> = {
|
55
|
+
name: TOP_QUERIES_COLUMNS_IDS.ReadRows,
|
56
|
+
render: ({row}) => formatNumber(row.ReadRows),
|
57
|
+
sortAccessor: (row) => Number(row.ReadRows),
|
58
|
+
align: DataTable.RIGHT,
|
59
|
+
};
|
60
|
+
|
61
|
+
const readBytesColumn: Column<KeyValueRow> = {
|
62
|
+
name: TOP_QUERIES_COLUMNS_IDS.ReadBytes,
|
63
|
+
render: ({row}) => formatNumber(row.ReadBytes),
|
64
|
+
sortAccessor: (row) => Number(row.ReadBytes),
|
65
|
+
align: DataTable.RIGHT,
|
66
|
+
};
|
67
|
+
|
68
|
+
const userSIDColumn: Column<KeyValueRow> = {
|
69
|
+
name: TOP_QUERIES_COLUMNS_IDS.UserSID,
|
70
|
+
render: ({row}) => <div className={b('user-sid')}>{row.UserSID || '–'}</div>,
|
71
|
+
sortAccessor: (row) => String(row.UserSID),
|
72
|
+
align: DataTable.LEFT,
|
73
|
+
};
|
74
|
+
|
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
|
+
|
89
|
+
export const getTopQueriesColumns = (): Column<KeyValueRow>[] => {
|
90
|
+
return [
|
91
|
+
cpuTimeUsColumn,
|
92
|
+
queryTextColumn,
|
93
|
+
endTimeColumn,
|
94
|
+
readRowsColumn,
|
95
|
+
readBytesColumn,
|
96
|
+
userSIDColumn,
|
97
|
+
];
|
98
|
+
};
|
99
|
+
|
100
|
+
export const getTenantOverviewTopQueriesColumns = (): Column<KeyValueRow>[] => {
|
101
|
+
return [queryHashColumn, oneLineQueryTextColumn, cpuTimeUsColumn];
|
102
|
+
};
|
@@ -4,8 +4,8 @@ import {DateRange, DateRangeValues} from '../../../../../components/DateRange';
|
|
4
4
|
|
5
5
|
import {
|
6
6
|
EShardsWorkloadMode,
|
7
|
-
IShardsWorkloadFilters,
|
8
|
-
} from '../../../../../
|
7
|
+
type IShardsWorkloadFilters,
|
8
|
+
} from '../../../../../store/reducers/shardsWorkload/types';
|
9
9
|
|
10
10
|
import {isEnumMember} from '../../../../../utils/typecheckers';
|
11
11
|
|
@@ -1,43 +1,38 @@
|
|
1
|
-
import {useState,
|
1
|
+
import {useState, useEffect, useMemo} from 'react';
|
2
2
|
import {useDispatch} from 'react-redux';
|
3
3
|
import cn from 'bem-cn-lite';
|
4
|
+
import {useLocation} from 'react-router';
|
4
5
|
|
5
6
|
import DataTable, {Column, Settings, SortOrder} from '@gravity-ui/react-data-table';
|
6
7
|
import {Loader} from '@gravity-ui/uikit';
|
7
8
|
|
8
|
-
import {InternalLink} from '../../../../components/InternalLink';
|
9
|
-
|
10
|
-
import HistoryContext from '../../../../contexts/HistoryContext';
|
11
|
-
|
12
|
-
import routes, {createHref} from '../../../../routes';
|
13
|
-
|
14
9
|
import {
|
15
10
|
sendShardQuery,
|
16
11
|
setShardsState,
|
17
12
|
setShardsQueryFilters,
|
18
|
-
} from '../../../../store/reducers/shardsWorkload';
|
19
|
-
import {
|
20
|
-
|
13
|
+
} from '../../../../store/reducers/shardsWorkload/shardsWorkload';
|
14
|
+
import {
|
15
|
+
EShardsWorkloadMode,
|
16
|
+
type IShardsWorkloadFilters,
|
17
|
+
} from '../../../../store/reducers/shardsWorkload/types';
|
21
18
|
|
22
19
|
import type {EPathType} from '../../../../types/api/schema';
|
23
20
|
import type {CellValue, KeyValueRow} from '../../../../types/api/query';
|
24
21
|
|
25
|
-
import {formatDateTime
|
22
|
+
import {formatDateTime} from '../../../../utils/dataFormatters/dataFormatters';
|
26
23
|
import {DEFAULT_TABLE_SETTINGS, HOUR_IN_SECONDS} from '../../../../utils/constants';
|
27
24
|
import {useAutofetcher, useTypedSelector} from '../../../../utils/hooks';
|
28
25
|
import {prepareQueryError} from '../../../../utils/query';
|
29
|
-
|
30
|
-
import {getDefaultNodePath} from '../../../Node/NodePages';
|
31
|
-
|
26
|
+
import {isSortableTopShardsProperty} from '../../../../utils/diagnostics';
|
32
27
|
import {isColumnEntityType} from '../../utils/schema';
|
33
28
|
|
34
29
|
import {Filters} from './Filters';
|
30
|
+
import {getShardsWorkloadColumns} from './getTopShardsColumns';
|
35
31
|
|
36
32
|
import i18n from './i18n';
|
37
33
|
import './TopShards.scss';
|
38
34
|
|
39
35
|
export const b = cn('top-shards');
|
40
|
-
const bLink = cn('yc-link');
|
41
36
|
|
42
37
|
const TABLE_SETTINGS: Settings = {
|
43
38
|
...DEFAULT_TABLE_SETTINGS,
|
@@ -58,10 +53,6 @@ const tableColumnsNames = {
|
|
58
53
|
IntervalEnd: 'IntervalEnd',
|
59
54
|
};
|
60
55
|
|
61
|
-
function prepareCPUWorkloadValue(value: string | number) {
|
62
|
-
return `${(Number(value) * 100).toFixed(2)}%`;
|
63
|
-
}
|
64
|
-
|
65
56
|
function prepareDateTimeValue(value: CellValue) {
|
66
57
|
if (!value) {
|
67
58
|
return '–';
|
@@ -105,6 +96,7 @@ interface TopShardsProps {
|
|
105
96
|
|
106
97
|
export const TopShards = ({tenantPath, type}: TopShardsProps) => {
|
107
98
|
const dispatch = useDispatch();
|
99
|
+
const location = useLocation();
|
108
100
|
|
109
101
|
const {autorefresh, currentSchemaPath} = useTypedSelector((state) => state.schema);
|
110
102
|
|
@@ -159,8 +151,6 @@ export const TopShards = ({tenantPath, type}: TopShardsProps) => {
|
|
159
151
|
);
|
160
152
|
}, [dispatch, currentSchemaPath, tenantPath, filters]);
|
161
153
|
|
162
|
-
const history = useContext(HistoryContext);
|
163
|
-
|
164
154
|
const onSort = (newSortOrder?: SortOrder | SortOrder[]) => {
|
165
155
|
// omit information about sort order to disable ASC order, only DESC makes sense for top shards
|
166
156
|
// use a string (and not the DataTable default format) to prevent reference change,
|
@@ -190,81 +180,12 @@ export const TopShards = ({tenantPath, type}: TopShardsProps) => {
|
|
190
180
|
};
|
191
181
|
|
192
182
|
const tableColumns = useMemo(() => {
|
193
|
-
const
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
};
|
200
|
-
|
201
|
-
const columns: Column<KeyValueRow>[] = [
|
202
|
-
{
|
203
|
-
name: tableColumnsNames.Path,
|
204
|
-
render: ({row}) => {
|
205
|
-
// row.Path - relative schema path
|
206
|
-
return (
|
207
|
-
<span
|
208
|
-
onClick={onSchemaClick(tenantPath + row.Path)}
|
209
|
-
className={bLink({view: 'normal'})}
|
210
|
-
>
|
211
|
-
{row.Path}
|
212
|
-
</span>
|
213
|
-
);
|
214
|
-
},
|
215
|
-
sortable: false,
|
216
|
-
},
|
217
|
-
{
|
218
|
-
name: tableColumnsNames.CPUCores,
|
219
|
-
render: ({row}) => {
|
220
|
-
return prepareCPUWorkloadValue(row.CPUCores || 0);
|
221
|
-
},
|
222
|
-
align: DataTable.RIGHT,
|
223
|
-
},
|
224
|
-
{
|
225
|
-
name: tableColumnsNames.DataSize,
|
226
|
-
header: 'DataSize (B)',
|
227
|
-
render: ({row}) => {
|
228
|
-
return formatNumber(row.DataSize);
|
229
|
-
},
|
230
|
-
align: DataTable.RIGHT,
|
231
|
-
},
|
232
|
-
{
|
233
|
-
name: tableColumnsNames.TabletId,
|
234
|
-
render: ({row}) => {
|
235
|
-
if (!row.TabletId) {
|
236
|
-
return '–';
|
237
|
-
}
|
238
|
-
return (
|
239
|
-
<InternalLink to={createHref(routes.tablet, {id: row.TabletId})}>
|
240
|
-
{row.TabletId}
|
241
|
-
</InternalLink>
|
242
|
-
);
|
243
|
-
},
|
244
|
-
sortable: false,
|
245
|
-
},
|
246
|
-
{
|
247
|
-
name: tableColumnsNames.NodeId,
|
248
|
-
render: ({row}) => {
|
249
|
-
if (!row.NodeId) {
|
250
|
-
return '–';
|
251
|
-
}
|
252
|
-
return (
|
253
|
-
<InternalLink to={getDefaultNodePath(row.NodeId)}>
|
254
|
-
{row.NodeId}
|
255
|
-
</InternalLink>
|
256
|
-
);
|
257
|
-
},
|
258
|
-
align: DataTable.RIGHT,
|
259
|
-
sortable: false,
|
260
|
-
},
|
261
|
-
{
|
262
|
-
name: tableColumnsNames.InFlightTxCount,
|
263
|
-
render: ({row}) => formatNumber(row.InFlightTxCount),
|
264
|
-
align: DataTable.RIGHT,
|
265
|
-
sortable: false,
|
266
|
-
},
|
267
|
-
];
|
183
|
+
const rawColumns: Column<KeyValueRow>[] = getShardsWorkloadColumns(tenantPath, location);
|
184
|
+
|
185
|
+
const columns: Column<KeyValueRow>[] = rawColumns.map((column) => ({
|
186
|
+
...column,
|
187
|
+
sortable: isSortableTopShardsProperty(column.name),
|
188
|
+
}));
|
268
189
|
|
269
190
|
if (filters.mode === EShardsWorkloadMode.History) {
|
270
191
|
// after NodeId
|
@@ -284,7 +205,7 @@ export const TopShards = ({tenantPath, type}: TopShardsProps) => {
|
|
284
205
|
}
|
285
206
|
|
286
207
|
return columns;
|
287
|
-
}, [
|
208
|
+
}, [filters.mode, tenantPath, location]);
|
288
209
|
|
289
210
|
const renderLoader = () => {
|
290
211
|
return (
|