ydb-embedded-ui 3.1.0 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
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);