ydb-embedded-ui 3.0.1 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +26 -0
- package/README.md +2 -0
- package/dist/components/DateRange/DateRange.scss +11 -0
- package/dist/components/DateRange/DateRange.tsx +75 -0
- package/dist/components/DateRange/index.ts +1 -0
- package/dist/components/Illustration/Illustration.tsx +4 -11
- package/dist/components/InfoViewer/InfoViewer.scss +2 -0
- package/dist/containers/Storage/DiskStateProgressBar/DiskStateProgressBar.tsx +1 -1
- package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +16 -0
- package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +4 -5
- package/dist/containers/Tenant/Diagnostics/DiagnosticsPages.ts +7 -7
- package/dist/containers/Tenant/Diagnostics/OverloadedShards/OverloadedShards.scss +27 -0
- package/dist/containers/Tenant/Diagnostics/{TopShards/TopShards.tsx → OverloadedShards/OverloadedShards.tsx} +75 -20
- package/dist/containers/Tenant/Diagnostics/OverloadedShards/i18n/en.json +4 -0
- package/dist/containers/Tenant/Diagnostics/OverloadedShards/i18n/index.ts +11 -0
- package/dist/containers/Tenant/Diagnostics/OverloadedShards/i18n/ru.json +4 -0
- package/dist/containers/Tenant/Diagnostics/OverloadedShards/index.ts +1 -0
- package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.scss +16 -19
- package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.tsx +202 -0
- package/dist/containers/Tenant/Diagnostics/TopQueries/i18n/en.json +4 -0
- package/dist/containers/Tenant/Diagnostics/TopQueries/i18n/index.ts +11 -0
- package/dist/containers/Tenant/Diagnostics/TopQueries/i18n/ru.json +4 -0
- package/dist/containers/Tenant/Diagnostics/TopQueries/index.ts +1 -0
- package/dist/containers/UserSettings/UserSettings.tsx +1 -1
- package/dist/services/api.d.ts +7 -0
- package/dist/store/reducers/describe.ts +4 -1
- package/dist/store/reducers/executeTopQueries.ts +170 -0
- package/dist/store/reducers/settings.js +1 -1
- package/dist/store/reducers/shardsWorkload.ts +91 -25
- package/dist/store/reducers/storage.js +2 -0
- package/dist/store/reducers/{tablets.js → tablets.ts} +30 -17
- package/dist/store/state-url-mapping.js +16 -0
- package/dist/types/api/compute.ts +52 -0
- package/dist/types/api/consumer.ts +257 -0
- package/dist/types/api/enums.ts +2 -2
- package/dist/types/api/nodes.ts +5 -2
- package/dist/types/api/pdisk.ts +3 -0
- package/dist/types/api/schema.ts +1 -0
- package/dist/types/api/storage.ts +31 -28
- package/dist/types/api/tablet.ts +18 -2
- package/dist/types/api/tenant.ts +4 -1
- package/dist/types/api/topic.ts +157 -0
- package/dist/types/api/vdisk.ts +3 -0
- package/dist/types/store/executeTopQueries.ts +29 -0
- package/dist/types/store/schema.ts +3 -3
- package/dist/types/store/shardsWorkload.ts +11 -2
- package/dist/types/store/tablets.ts +42 -0
- package/dist/utils/getNodesColumns.js +8 -1
- package/dist/utils/query.ts +1 -1
- package/package.json +3 -3
- package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.js +0 -188
- package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.scss +0 -7
- package/dist/containers/Tenant/Diagnostics/TopShards/index.ts +0 -1
- package/dist/store/reducers/executeTopQueries.js +0 -66
- package/dist/types/api/consumers.ts +0 -3
@@ -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
|
+
}
|
package/dist/types/api/vdisk.ts
CHANGED
@@ -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
|
29
|
-
currentSchema
|
30
|
-
data
|
28
|
+
path?: string;
|
29
|
+
currentSchema?: TEvDescribeSchemeResult;
|
30
|
+
data?: ISchemaData;
|
31
31
|
}
|
32
32
|
|
33
33
|
type ISchemaApiRequestAction = ApiRequestAction<
|
@@ -1,18 +1,27 @@
|
|
1
|
-
import {SEND_SHARD_QUERY,
|
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';
|
5
5
|
|
6
|
+
export interface IShardsWorkloadFilters {
|
7
|
+
/** ms from epoch */
|
8
|
+
from?: number;
|
9
|
+
/** ms from epoch */
|
10
|
+
to?: number;
|
11
|
+
}
|
12
|
+
|
6
13
|
export interface IShardsWorkloadState {
|
7
14
|
loading: boolean;
|
8
15
|
wasLoaded: boolean;
|
9
16
|
data?: IQueryResult;
|
10
17
|
error?: IResponseError;
|
18
|
+
filters: IShardsWorkloadFilters;
|
11
19
|
}
|
12
20
|
|
13
21
|
export type IShardsWorkloadAction =
|
14
22
|
| ApiRequestAction<typeof SEND_SHARD_QUERY, IQueryResult, IResponseError>
|
15
|
-
| ReturnType<typeof
|
23
|
+
| ReturnType<typeof setShardsState>
|
24
|
+
| ReturnType<typeof setShardsQueryFilters>;
|
16
25
|
|
17
26
|
export interface IShardsWorkloadRootStateSlice {
|
18
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/dist/utils/query.ts
CHANGED
@@ -186,5 +186,5 @@ export const prepareQueryResponse = (data?: KeyValueRow[]) => {
|
|
186
186
|
};
|
187
187
|
|
188
188
|
export function prepareQueryError(error: any) {
|
189
|
-
return error.data?.error?.message || error.data || error.statusText || JSON.stringify(error);
|
189
|
+
return error.data?.error?.message || error.message || error.data || error.statusText || JSON.stringify(error);
|
190
190
|
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "ydb-embedded-ui",
|
3
|
-
"version": "3.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
|
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.
|
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);
|
@@ -1 +0,0 @@
|
|
1
|
-
export * from './TopShards';
|
@@ -1,66 +0,0 @@
|
|
1
|
-
import '../../services/api';
|
2
|
-
|
3
|
-
import {parseQueryAPIExecuteResponse} from '../../utils/query';
|
4
|
-
|
5
|
-
import {createRequestActionTypes, createApiRequest} from '../utils';
|
6
|
-
|
7
|
-
const SEND_QUERY = createRequestActionTypes('top-queries', 'SEND_QUERY');
|
8
|
-
const SET_QUERY_OPTIONS = createRequestActionTypes('top-queries', 'SET_QUERY_OPTIONS');
|
9
|
-
|
10
|
-
const initialState = {
|
11
|
-
loading: false,
|
12
|
-
wasLoaded: false,
|
13
|
-
};
|
14
|
-
|
15
|
-
const executeTopQueries = (state = initialState, action) => {
|
16
|
-
switch (action.type) {
|
17
|
-
case SEND_QUERY.REQUEST: {
|
18
|
-
return {
|
19
|
-
...state,
|
20
|
-
loading: true,
|
21
|
-
error: undefined,
|
22
|
-
};
|
23
|
-
}
|
24
|
-
case SEND_QUERY.SUCCESS: {
|
25
|
-
return {
|
26
|
-
...state,
|
27
|
-
data: action.data,
|
28
|
-
loading: false,
|
29
|
-
error: undefined,
|
30
|
-
wasLoaded: true,
|
31
|
-
};
|
32
|
-
}
|
33
|
-
// 401 Unauthorized error is handled by GenericAPI
|
34
|
-
case SEND_QUERY.FAILURE: {
|
35
|
-
return {
|
36
|
-
...state,
|
37
|
-
error: action.error || 'Unauthorized',
|
38
|
-
loading: false,
|
39
|
-
};
|
40
|
-
}
|
41
|
-
case SET_QUERY_OPTIONS:
|
42
|
-
return {
|
43
|
-
...state,
|
44
|
-
...action.data,
|
45
|
-
};
|
46
|
-
default:
|
47
|
-
return state;
|
48
|
-
}
|
49
|
-
};
|
50
|
-
|
51
|
-
export const sendQuery = ({query, database, action}) => {
|
52
|
-
return createApiRequest({
|
53
|
-
request: window.api.sendQuery({schema: 'modern', query, database, action}),
|
54
|
-
actions: SEND_QUERY,
|
55
|
-
dataHandler: parseQueryAPIExecuteResponse,
|
56
|
-
});
|
57
|
-
};
|
58
|
-
|
59
|
-
export function setQueryOptions(options) {
|
60
|
-
return {
|
61
|
-
type: SET_QUERY_OPTIONS,
|
62
|
-
data: options,
|
63
|
-
};
|
64
|
-
}
|
65
|
-
|
66
|
-
export default executeTopQueries;
|