ydb-embedded-ui 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +2 -0
  3. package/dist/components/DateRange/DateRange.scss +11 -0
  4. package/dist/{containers/Tenant/Diagnostics/TopShards → components}/DateRange/DateRange.tsx +7 -7
  5. package/dist/{containers/Tenant/Diagnostics/TopShards → components}/DateRange/index.ts +0 -0
  6. package/dist/components/Illustration/Illustration.tsx +4 -11
  7. package/dist/components/InfoViewer/InfoViewer.scss +2 -0
  8. package/dist/containers/Storage/DiskStateProgressBar/DiskStateProgressBar.tsx +1 -1
  9. package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +16 -0
  10. package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +4 -5
  11. package/dist/containers/Tenant/Diagnostics/DiagnosticsPages.ts +7 -7
  12. package/dist/containers/Tenant/Diagnostics/{TopShards/TopShards.scss → OverloadedShards/OverloadedShards.scss} +1 -1
  13. package/dist/containers/Tenant/Diagnostics/{TopShards/TopShards.tsx → OverloadedShards/OverloadedShards.tsx} +10 -11
  14. package/dist/containers/Tenant/Diagnostics/{TopShards → OverloadedShards}/i18n/en.json +0 -0
  15. package/dist/containers/Tenant/Diagnostics/OverloadedShards/i18n/index.ts +11 -0
  16. package/dist/containers/Tenant/Diagnostics/{TopShards → OverloadedShards}/i18n/ru.json +0 -0
  17. package/dist/containers/Tenant/Diagnostics/OverloadedShards/index.ts +1 -0
  18. package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.scss +16 -19
  19. package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.tsx +202 -0
  20. package/dist/containers/Tenant/Diagnostics/TopQueries/i18n/en.json +4 -0
  21. package/dist/containers/Tenant/Diagnostics/{TopShards → TopQueries}/i18n/index.ts +1 -1
  22. package/dist/containers/Tenant/Diagnostics/TopQueries/i18n/ru.json +4 -0
  23. package/dist/containers/Tenant/Diagnostics/TopQueries/index.ts +1 -0
  24. package/dist/containers/UserSettings/UserSettings.tsx +1 -1
  25. package/dist/services/api.d.ts +7 -0
  26. package/dist/store/reducers/describe.ts +4 -1
  27. package/dist/store/reducers/executeTopQueries.ts +170 -0
  28. package/dist/store/reducers/settings.js +1 -1
  29. package/dist/store/reducers/shardsWorkload.ts +9 -9
  30. package/dist/store/reducers/storage.js +2 -0
  31. package/dist/store/reducers/{tablets.js → tablets.ts} +30 -17
  32. package/dist/store/state-url-mapping.js +10 -2
  33. package/dist/types/api/compute.ts +52 -0
  34. package/dist/types/api/consumer.ts +257 -0
  35. package/dist/types/api/enums.ts +2 -2
  36. package/dist/types/api/nodes.ts +5 -2
  37. package/dist/types/api/pdisk.ts +3 -0
  38. package/dist/types/api/schema.ts +1 -0
  39. package/dist/types/api/storage.ts +31 -28
  40. package/dist/types/api/tablet.ts +18 -2
  41. package/dist/types/api/tenant.ts +4 -1
  42. package/dist/types/api/topic.ts +157 -0
  43. package/dist/types/api/vdisk.ts +3 -0
  44. package/dist/types/store/executeTopQueries.ts +29 -0
  45. package/dist/types/store/schema.ts +3 -3
  46. package/dist/types/store/shardsWorkload.ts +3 -3
  47. package/dist/types/store/tablets.ts +42 -0
  48. package/dist/utils/getNodesColumns.js +8 -1
  49. package/package.json +3 -3
  50. package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.js +0 -188
  51. package/dist/containers/Tenant/Diagnostics/TopShards/DateRange/DateRange.scss +0 -13
  52. package/dist/containers/Tenant/Diagnostics/TopShards/index.ts +0 -1
  53. package/dist/store/reducers/executeTopQueries.js +0 -66
  54. package/dist/types/api/consumers.ts +0 -3
@@ -1,6 +1,6 @@
1
1
  // Shows system status
2
- // Currently is used in response types of viewer/json/nodes and viewer/json/storage
3
- // Probably will appear in /viewer/json/tenantinfo /viewer/json/cluster /viewer/json/tabletinfo /viewer/json/compute
2
+ // Currently is used in response types viewer/json/ storage, nodes, compute
3
+ // pdiskinfo, vdiskinfo, tabletinfo, tenantinfo
4
4
  export enum EFlag {
5
5
  Grey = 'Grey',
6
6
  Green = 'Green',
@@ -2,6 +2,9 @@ import {EFlag} from './enums';
2
2
  import {TPDiskStateInfo} from './pdisk';
3
3
  import {TTabletStateInfo} from './tablet';
4
4
 
5
+ // endpoint: /viewer/json/nodes
6
+ // source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/viewer/protos/viewer.proto
7
+
5
8
  export interface TNodesInfo {
6
9
  Overall: EFlag;
7
10
  Nodes?: TNodeInfo[];
@@ -64,12 +67,12 @@ export interface TPoolStats {
64
67
  Threads?: number;
65
68
  }
66
69
 
67
- interface TEndpoint {
70
+ export interface TEndpoint {
68
71
  Name?: string;
69
72
  Address?: string;
70
73
  }
71
74
 
72
- interface TLegacyNodeLocation {
75
+ export interface TLegacyNodeLocation {
73
76
  DataCenter?: number;
74
77
  Room?: number;
75
78
  Rack?: number;
@@ -1,5 +1,8 @@
1
1
  import {EFlag} from './enums';
2
2
 
3
+ // endpoint: /viewer/json/pdiskinfo
4
+ // source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/protos/node_whiteboard.proto
5
+
3
6
  export interface TPDiskStateInfo {
4
7
  PDiskId?: number;
5
8
  /** uint64 */
@@ -37,6 +37,7 @@ enum EStatus {
37
37
  StatusResourceExhausted = 'StatusResourceExhausted',
38
38
  }
39
39
 
40
+ // source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/protos/flat_scheme_op.proto
40
41
  // incomplete interface, only currently used fields are covered
41
42
  export interface TPathDescription {
42
43
  /** info about the path itself */
@@ -1,6 +1,37 @@
1
1
  import {EFlag} from './enums';
2
2
  import {TVDiskStateInfo} from './vdisk';
3
3
 
4
+ // endpoint: /viewer/json/storage
5
+ // source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/viewer/protos/viewer.proto
6
+
7
+ export interface TStorageInfo {
8
+ Overall?: EFlag;
9
+ StoragePools?: TStoragePoolInfo[];
10
+ /** uint64 */
11
+ TotalGroups?: string;
12
+ /** uint64 */
13
+ FoundGroups?: string;
14
+ }
15
+
16
+ interface TStoragePoolInfo {
17
+ Overall?: EFlag;
18
+ Name?: string;
19
+ Kind?: string;
20
+ Groups?: (TBSGroupStateInfo & THiveStorageGroupStats)[];
21
+ /** uint64 */
22
+ AcquiredUnits?: string;
23
+ AcquiredIOPS?: number;
24
+ /** uint64 */
25
+ AcquiredThroughput?: string;
26
+ /** uint64 */
27
+ AcquiredSize?: string;
28
+ MaximumIOPS?: number;
29
+ /** uint64 */
30
+ MaximumThroughput?: string;
31
+ /** uint64 */
32
+ MaximumSize?: string;
33
+ }
34
+
4
35
  export interface TBSGroupStateInfo {
5
36
  GroupID?: number;
6
37
  ErasureSpecies?: string;
@@ -43,31 +74,3 @@ interface THiveStorageGroupStats {
43
74
  /** uint64 */
44
75
  AvailableSize?: string;
45
76
  }
46
-
47
- interface TStoragePoolInfo {
48
- Overall?: EFlag;
49
- Name?: string;
50
- Kind?: string;
51
- Groups?: (TBSGroupStateInfo & THiveStorageGroupStats)[];
52
- /** uint64 */
53
- AcquiredUnits?: string;
54
- AcquiredIOPS?: number;
55
- /** uint64 */
56
- AcquiredThroughput?: string;
57
- /** uint64 */
58
- AcquiredSize?: string;
59
- MaximumIOPS?: number;
60
- /** uint64 */
61
- MaximumThroughput?: string;
62
- /** uint64 */
63
- MaximumSize?: string;
64
- }
65
-
66
- export interface TStorageInfo {
67
- Overall?: EFlag;
68
- StoragePools?: TStoragePoolInfo[];
69
- /** uint64 */
70
- TotalGroups?: string;
71
- /** uint64 */
72
- FoundGroups?: string;
73
- }
@@ -1,5 +1,21 @@
1
1
  import {EFlag} from './enums';
2
2
 
3
+ // endpoint: /viewer/json/tabletinfo
4
+ // source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/protos/sys_view.proto
5
+
6
+ export interface TEvTabletStateResponse {
7
+ TabletStateInfo?: TTabletStateInfo[];
8
+
9
+ /** uint64 */
10
+ ResponseTime?: string;
11
+ /** uint64 */
12
+ ResponseDuration?: string;
13
+ /** uint64 */
14
+ ProcessDuration?: string;
15
+
16
+ Packed5?: unknown;
17
+ }
18
+
3
19
  export interface TTabletStateInfo {
4
20
  /** uint64 */
5
21
  TabletId?: string;
@@ -37,7 +53,7 @@ interface TDomainKey {
37
53
  PathId?: string;
38
54
  }
39
55
 
40
- enum EType {
56
+ export enum EType {
41
57
  'Unknown' = 'Unknown',
42
58
  'OldSchemeShard' = 'OldSchemeShard',
43
59
  'OldDataShard' = 'OldDataShard',
@@ -79,7 +95,7 @@ enum EType {
79
95
  'TypeInvalid' = 'TypeInvalid',
80
96
  }
81
97
 
82
- enum ETabletState {
98
+ export enum ETabletState {
83
99
  'Created' = 'Created',
84
100
  'ResolveStateStorage' = 'ResolveStateStorage',
85
101
  'Candidate' = 'Candidate',
@@ -2,6 +2,9 @@ import {EFlag} from './enums';
2
2
  import {TPoolStats, TSystemStateInfo} from './nodes';
3
3
  import {TTabletStateInfo} from './tablet';
4
4
 
5
+ // endpoint: /viewer/json/tenantinfo
6
+ // source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/viewer/protos/viewer.proto
7
+
5
8
  export interface TTenants {
6
9
  Tenants?: TTenant[];
7
10
  }
@@ -51,7 +54,7 @@ interface THiveDomainStatsStateCount {
51
54
  Count?: number;
52
55
  }
53
56
 
54
- interface TMetrics {
57
+ export interface TMetrics {
55
58
  /** uint64 */
56
59
  CPU?: string;
57
60
  /** uint64 */
@@ -0,0 +1,157 @@
1
+ /* eslint-disable camelcase */
2
+
3
+ import {Consumer, Entry, MultipleWindowsStat, PartitionStats, SupportedCodecs} from './consumer';
4
+
5
+ /**
6
+ * endpoint: /json/describe_topic
7
+ *
8
+ * source: https://github.com/ydb-platform/ydb/blob/main/ydb/public/api/protos/ydb_topic.proto
9
+ *
10
+ * Original proto file doesn't specify optional fields, so every field is considered optional
11
+ */
12
+ export interface DescribeTopicResult {
13
+ /** Description of scheme object. */
14
+ self?: Entry;
15
+
16
+ /** Settings for partitioning */
17
+ partitioning_settings?: PartitioningSettings;
18
+
19
+ /** Partitions description. */
20
+ partitions?: PartitionInfo[];
21
+
22
+ // Retention settings.
23
+ // Currently, only one limit may be set, so other should not be set.
24
+
25
+ /**
26
+ * google.protobuf.Duration
27
+ *
28
+ * How long data in partition should be stored.
29
+ */
30
+ retention_period?: string;
31
+
32
+ /**
33
+ * int64
34
+ *
35
+ * How much data in partition should be stored.
36
+ * Zero value means infinite limit.
37
+ */
38
+ retention_storage_mb?: string;
39
+
40
+ /**
41
+ * List of allowed codecs for writers.
42
+ * Writes with codec not from this list are forbidden.
43
+ */
44
+ supported_codecs?: SupportedCodecs;
45
+
46
+ /**
47
+ * int64
48
+ *
49
+ * Partition write speed in bytes per second.
50
+ * Zero value means default limit: 1 MB per second.
51
+ */
52
+ partition_write_speed_bytes_per_second?: string;
53
+
54
+ /**
55
+ * int64
56
+ *
57
+ * Burst size for write in partition, in bytes.
58
+ * Zero value means default limit: 1 MB.
59
+ */
60
+ partition_write_burst_bytes?: string;
61
+
62
+ /** User and server attributes of topic. Server attributes starts from "_" and will be validated by server. */
63
+ attributes?: Record<string, string>;
64
+
65
+ /** List of consumers for this topic. */
66
+ consumers?: Consumer[];
67
+
68
+ /** Metering settings. */
69
+ metering_mode?: MeteringMode;
70
+
71
+ /** Statistics of topic. */
72
+ topic_stats?: TopicStats;
73
+ }
74
+
75
+ /** Partition info types differs for consumer and topic, although they are very similar */
76
+ interface PartitionInfo {
77
+ /** int64 */
78
+ partition_id?: string;
79
+
80
+ /** Is partition open for write. */
81
+ active?: boolean;
82
+
83
+ /**
84
+ * int64
85
+ *
86
+ * Ids of partitions which was formed when this partition was split or merged.
87
+ */
88
+ child_partition_ids?: string;
89
+
90
+ /**
91
+ * int64
92
+ *
93
+ * Ids of partitions from which this partition was formed by split or merge.
94
+ */
95
+ parent_partition_ids?: string;
96
+
97
+ /** Stats for partition, filled only when include_stats in request is true. */
98
+ partition_stats?: PartitionStats;
99
+ }
100
+
101
+ interface TopicStats {
102
+ /**
103
+ * int64
104
+ *
105
+ * Approximate size of topic.
106
+ */
107
+ store_size_bytes?: string;
108
+
109
+ /**
110
+ * google.protobuf.Timestamp
111
+ *
112
+ * Minimum of timestamps of last write among all partitions.
113
+ */
114
+ min_last_write_time?: string;
115
+
116
+ /**
117
+ * google.protobuf.Duration
118
+ *
119
+ * Maximum of differences between write timestamp and create timestamp for all messages, written during last minute.
120
+ */
121
+ max_write_time_lag?: string;
122
+
123
+ /** How much bytes were written statistics. */
124
+ bytes_written?: MultipleWindowsStat;
125
+ }
126
+
127
+ /** Partitioning settings for topic. */
128
+ interface PartitioningSettings {
129
+ /**
130
+ * int64
131
+ *
132
+ * Minimum partition count auto merge would stop working at.
133
+ *
134
+ * Zero value means default - 1.
135
+ */
136
+ min_active_partitions?: string;
137
+
138
+ /**
139
+ * int64
140
+ *
141
+ * Limit for total partition count, including active (open for write) and read-only partitions.
142
+ *
143
+ * Zero value means default - 100.
144
+ */
145
+ partition_count_limit?: string;
146
+ }
147
+
148
+ enum MeteringMode {
149
+ /** Use default */
150
+ METERING_MODE_UNSPECIFIED = 'METERING_MODE_UNSPECIFIED',
151
+
152
+ /** Metering based on resource reservation */
153
+ METERING_MODE_RESERVED_CAPACITY = 'METERING_MODE_RESERVED_CAPACITY',
154
+
155
+ /** Metering based on actual consumption. Default. */
156
+ METERING_MODE_REQUEST_UNITS = 'METERING_MODE_REQUEST_UNITS',
157
+ }
@@ -1,6 +1,9 @@
1
1
  import {EFlag} from './enums';
2
2
  import {TPDiskStateInfo} from './pdisk';
3
3
 
4
+ // endpoint: /viewer/json/vdiskinfo
5
+ // source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/protos/node_whiteboard.proto
6
+
4
7
  export interface TVDiskStateInfo {
5
8
  VDiskId?: TVDiskID;
6
9
  /** uint64 */
@@ -0,0 +1,29 @@
1
+ import {FETCH_TOP_QUERIES, setTopQueriesState, setTopQueriesFilters} from '../../store/reducers/executeTopQueries';
2
+ import type {ApiRequestAction} from '../../store/utils';
3
+ import type {IResponseError} from '../api/error';
4
+ import type {IQueryResult} from './query';
5
+
6
+ export interface ITopQueriesFilters {
7
+ /** ms from epoch */
8
+ from?: number;
9
+ /** ms from epoch */
10
+ to?: number;
11
+ text?: string;
12
+ }
13
+
14
+ export interface ITopQueriesState {
15
+ loading: boolean;
16
+ wasLoaded: boolean;
17
+ data?: IQueryResult;
18
+ error?: IResponseError;
19
+ filters: ITopQueriesFilters;
20
+ }
21
+
22
+ export type ITopQueriesAction =
23
+ | ApiRequestAction<typeof FETCH_TOP_QUERIES, IQueryResult, IResponseError>
24
+ | ReturnType<typeof setTopQueriesState>
25
+ | ReturnType<typeof setTopQueriesFilters>;
26
+
27
+ export interface ITopQueriesRootStateSlice {
28
+ executeTopQueries: ITopQueriesState;
29
+ }
@@ -25,9 +25,9 @@ export interface ISchemaState {
25
25
  }
26
26
 
27
27
  export interface ISchemaHandledResponse {
28
- path: string | undefined;
29
- currentSchema: TEvDescribeSchemeResult | undefined;
30
- data: ISchemaData | undefined;
28
+ path?: string;
29
+ currentSchema?: TEvDescribeSchemeResult;
30
+ data?: ISchemaData;
31
31
  }
32
32
 
33
33
  type ISchemaApiRequestAction = ApiRequestAction<
@@ -1,4 +1,4 @@
1
- import {SEND_SHARD_QUERY, setShardQueryOptions, setTopShardFilters} from '../../store/reducers/shardsWorkload';
1
+ import {SEND_SHARD_QUERY, setShardsState, setShardsQueryFilters} from '../../store/reducers/shardsWorkload';
2
2
  import type {ApiRequestAction} from '../../store/utils';
3
3
  import type {IResponseError} from '../api/error';
4
4
  import type {IQueryResult} from './query';
@@ -20,8 +20,8 @@ export interface IShardsWorkloadState {
20
20
 
21
21
  export type IShardsWorkloadAction =
22
22
  | ApiRequestAction<typeof SEND_SHARD_QUERY, IQueryResult, IResponseError>
23
- | ReturnType<typeof setShardQueryOptions>
24
- | ReturnType<typeof setTopShardFilters>;
23
+ | ReturnType<typeof setShardsState>
24
+ | ReturnType<typeof setShardsQueryFilters>;
25
25
 
26
26
  export interface IShardsWorkloadRootStateSlice {
27
27
  shardsWorkload: IShardsWorkloadState;
@@ -0,0 +1,42 @@
1
+ import type {ApiRequestAction} from '../../store/utils';
2
+ import {
3
+ clearWasLoadingFlag,
4
+ FETCH_TABLETS,
5
+ setStateFilter,
6
+ setTypeFilter,
7
+ } from '../../store/reducers/tablets';
8
+
9
+ import type {IResponseError} from '../api/error';
10
+ import type {TEvTabletStateResponse, EType, ETabletState} from '../api/tablet';
11
+
12
+ export interface ITabletsState {
13
+ loading: boolean;
14
+ wasLoaded: boolean;
15
+ stateFilter: ETabletState[];
16
+ typeFilter: EType[];
17
+ data?: TEvTabletStateResponse;
18
+ error?: IResponseError;
19
+ }
20
+
21
+ export interface ITabletsApiRequestParams {
22
+ nodes?: string[];
23
+ path?: string;
24
+ }
25
+
26
+ type ITabletsApiRequestAction = ApiRequestAction<
27
+ typeof FETCH_TABLETS,
28
+ TEvTabletStateResponse,
29
+ IResponseError
30
+ >;
31
+
32
+ export type ITabletsAction =
33
+ | ITabletsApiRequestAction
34
+ | (
35
+ | ReturnType<typeof clearWasLoadingFlag>
36
+ | ReturnType<typeof setStateFilter>
37
+ | ReturnType<typeof setTypeFilter>
38
+ );
39
+
40
+ export interface ITabletsRootStateSlice {
41
+ tablets: ITabletsState;
42
+ }
@@ -41,7 +41,7 @@ export function getNodesColumns({showTooltip, hideTooltip, tabletsPath, getNodeR
41
41
  className={b('host-name')}
42
42
  />
43
43
  {nodeRef && (
44
- <Button size="s" href={nodeRef} className={b('external-button')}>
44
+ <Button size="s" href={nodeRef} className={b('external-button')} target="_blank">
45
45
  <Icon name="external" />
46
46
  </Button>
47
47
  )}
@@ -58,6 +58,13 @@ export function getNodesColumns({showTooltip, hideTooltip, tabletsPath, getNodeR
58
58
  render: ({value}) => (value ? value : '—'),
59
59
  width: '60px',
60
60
  },
61
+ {
62
+ name: 'Rack',
63
+ header: 'Rack',
64
+ align: DataTable.LEFT,
65
+ render: ({value}) => (value ? value : '—'),
66
+ width: '80px',
67
+ },
61
68
  {
62
69
  name: 'Version',
63
70
  width: '200px',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ydb-embedded-ui",
3
- "version": "3.1.0",
3
+ "version": "3.2.0",
4
4
  "files": [
5
5
  "dist"
6
6
  ],
@@ -12,7 +12,7 @@
12
12
  "@gravity-ui/axios-wrapper": "^1.3.0",
13
13
  "@gravity-ui/i18n": "^1.0.0",
14
14
  "@yandex-cloud/paranoid": "^1.3.0",
15
- "@yandex-cloud/react-data-table": "0.2.1",
15
+ "@yandex-cloud/react-data-table": "^1.0.2",
16
16
  "axios": "0.19.2",
17
17
  "bem-cn-lite": "4.0.0",
18
18
  "history": "4.10.1",
@@ -37,7 +37,7 @@
37
37
  "reselect": "4.1.6",
38
38
  "sass": "1.32.8",
39
39
  "web-vitals": "1.1.2",
40
- "ydb-ui-components": "3.0.1"
40
+ "ydb-ui-components": "^3.0.2"
41
41
  },
42
42
  "scripts": {
43
43
  "start": "react-app-rewired start",
@@ -1,188 +0,0 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import cn from 'bem-cn-lite';
4
- import {connect} from 'react-redux';
5
- import DataTable from '@yandex-cloud/react-data-table';
6
- import {Loader} from '@gravity-ui/uikit';
7
-
8
- import {changeUserInput} from '../../../../store/reducers/executeQuery';
9
- import {sendQuery, setQueryOptions} from '../../../../store/reducers/executeTopQueries';
10
- import TruncatedQuery from '../../../../components/TruncatedQuery/TruncatedQuery';
11
- import {AutoFetcher} from '../../../../utils/autofetcher';
12
- import {isColumnEntityType} from '../../utils/schema';
13
-
14
- import {DEFAULT_TABLE_SETTINGS} from '../../../../utils/constants';
15
- import {TenantGeneralTabsIds} from '../../TenantPages';
16
- import {prepareQueryError} from '../../../../utils/query';
17
-
18
- import './TopQueries.scss';
19
-
20
- const b = cn('kv-top-queries');
21
-
22
- const MAX_QUERY_HEIGHT = 10;
23
- const COLUMNS = [
24
- {
25
- name: 'CPUTimeUs',
26
- width: 140,
27
- sortAccessor: (row) => Number(row['CPUTimeUs']),
28
- },
29
- {
30
- name: 'QueryText',
31
- width: 500,
32
- sortable: false,
33
- // eslint-disable-next-line
34
- render: ({value}) => <TruncatedQuery value={value} maxQueryHeight={MAX_QUERY_HEIGHT} />,
35
- },
36
- ];
37
- const getQueryText = (path) => `
38
- --!syntax_v1
39
- $last = (
40
- SELECT
41
- MAX(IntervalEnd)
42
- FROM \`${path}/.sys/top_queries_by_cpu_time_one_hour\`
43
- );
44
- SELECT
45
- CPUTime as CPUTimeUs,
46
- QueryText
47
- FROM \`${path}/.sys/top_queries_by_cpu_time_one_hour\`
48
- WHERE IntervalEnd IN $last
49
- `;
50
-
51
- class TopQueries extends React.Component {
52
- static propTypes = {
53
- error: PropTypes.string,
54
- sendQuery: PropTypes.func,
55
- path: PropTypes.string,
56
- data: PropTypes.array,
57
- loading: PropTypes.bool,
58
- wasLoaded: PropTypes.bool,
59
- changeSchemaTab: PropTypes.func,
60
- currentSchema: PropTypes.object,
61
- type: PropTypes.string,
62
- className: PropTypes.string,
63
- };
64
-
65
- autofetcher;
66
-
67
- componentDidMount() {
68
- this.autofetcher = new AutoFetcher();
69
- this.getTopQueries();
70
- if (this.props.autorefresh) {
71
- this.autofetcher.start();
72
- this.autofetcher.fetch(() => this.getTopQueries());
73
- }
74
- }
75
-
76
- componentDidUpdate(prevProps) {
77
- const {autorefresh, path, setQueryOptions} = this.props;
78
-
79
- if (autorefresh && !prevProps.autorefresh) {
80
- this.getTopQueries();
81
- this.autofetcher.start();
82
- this.autofetcher.fetch(() => this.getTopQueries());
83
- }
84
- if (!autorefresh && prevProps.autorefresh) {
85
- this.autofetcher.stop();
86
- }
87
-
88
- if (path !== prevProps.path) {
89
- setQueryOptions({
90
- wasLoaded: false,
91
- data: undefined,
92
- });
93
- this.getTopQueries();
94
- }
95
- }
96
-
97
- componentWillUnmount() {
98
- this.autofetcher.stop();
99
- }
100
-
101
- renderLoader = () => {
102
- return (
103
- <div className={b('loader')}>
104
- <Loader size="m" />
105
- </div>
106
- );
107
- };
108
-
109
- getTopQueries() {
110
- const {path} = this.props;
111
- const query = getQueryText(path);
112
- this.props.sendQuery({query, database: path, action: 'execute-scan'});
113
- }
114
-
115
- onRowClick = (row) => {
116
- const {QueryText: input} = row;
117
- const {changeUserInput, changeSchemaTab} = this.props;
118
-
119
- changeUserInput({input});
120
- changeSchemaTab(TenantGeneralTabsIds.query);
121
- };
122
-
123
- renderTable = () => {
124
- const {data} = this.props;
125
-
126
- if (!data) {
127
- return null;
128
- }
129
-
130
- return (
131
- <DataTable
132
- columns={COLUMNS}
133
- data={data}
134
- settings={DEFAULT_TABLE_SETTINGS}
135
- onRowClick={this.onRowClick}
136
- />
137
- );
138
- };
139
-
140
- renderResult = () => {
141
- return (
142
- <div className={b('table-wrapper')}>
143
- <div className={b('table-content')}>{this.renderTable()}</div>
144
- </div>
145
- );
146
- };
147
-
148
- render() {
149
- const {error, loading, data, type, className, wasLoaded} = this.props;
150
-
151
- let message;
152
-
153
- if (isColumnEntityType(type)) {
154
- message = 'No data';
155
- } else if (error && !error.isCancelled) {
156
- message = prepareQueryError(error).slice(0, 300);
157
- } else if (!loading && !data) {
158
- message = 'No data';
159
- }
160
-
161
- return loading && !wasLoaded ? (
162
- this.renderLoader()
163
- ) : (
164
- <div className={b()}>
165
- <div className={b('result', className)}>{message || this.renderResult()}</div>
166
- </div>
167
- );
168
- }
169
- }
170
- const mapStateToProps = (state) => {
171
- const {loading, data = {}, error, wasLoaded} = state.executeTopQueries;
172
- const {autorefresh} = state.schema;
173
- return {
174
- loading,
175
- data: data.result,
176
- error,
177
- wasLoaded,
178
- autorefresh,
179
- };
180
- };
181
-
182
- const mapDispatchToProps = {
183
- sendQuery,
184
- changeUserInput,
185
- setQueryOptions,
186
- };
187
-
188
- export default connect(mapStateToProps, mapDispatchToProps)(TopQueries);