ydb-embedded-ui 3.1.0 → 3.2.1
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +30 -0
- package/README.md +2 -0
- package/dist/components/DateRange/DateRange.scss +11 -0
- package/dist/{containers/Tenant/Diagnostics/TopShards → components}/DateRange/DateRange.tsx +7 -7
- package/dist/{containers/Tenant/Diagnostics/TopShards → components}/DateRange/index.ts +0 -0
- package/dist/components/EntitiesCount/EntitiesCount.tsx +34 -0
- package/dist/components/EntitiesCount/i18n/en.json +3 -0
- package/dist/components/{AsideNavigation/Settings → EntitiesCount}/i18n/index.ts +2 -2
- package/dist/components/EntitiesCount/i18n/ru.json +3 -0
- package/dist/components/EntitiesCount/index.ts +1 -0
- package/dist/components/Fullscreen/Fullscreen.scss +7 -5
- package/dist/components/Illustration/Illustration.tsx +4 -11
- package/dist/components/InfoViewer/InfoViewer.scss +2 -0
- package/dist/components/TabletsOverall/TabletsOverall.tsx +4 -4
- package/dist/components/TabletsStatistic/TabletsStatistic.tsx +56 -0
- package/dist/components/TabletsStatistic/index.ts +1 -0
- package/dist/containers/App/App.scss +4 -12
- package/dist/containers/AsideNavigation/AsideNavigation.scss +0 -18
- package/dist/containers/AsideNavigation/AsideNavigation.tsx +95 -33
- package/dist/containers/Heatmap/Heatmap.scss +0 -7
- package/dist/containers/Heatmap/Heatmap.tsx +203 -0
- package/dist/containers/Heatmap/HeatmapCanvas/HeatmapCanvas.js +2 -1
- package/dist/containers/Heatmap/index.ts +1 -0
- package/dist/containers/Node/Node.tsx +1 -1
- package/dist/containers/Storage/DiskStateProgressBar/DiskStateProgressBar.tsx +1 -1
- package/dist/containers/Storage/Storage.js +12 -19
- package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +16 -0
- package/dist/containers/Tablets/Tablets.scss +0 -5
- package/dist/containers/Tablets/Tablets.tsx +172 -0
- package/dist/containers/Tablets/i18n/en.json +6 -0
- package/dist/{components/AsideNavigation → containers/Tablets}/i18n/index.ts +1 -1
- package/dist/containers/Tablets/i18n/ru.json +6 -0
- package/dist/containers/Tablets/index.ts +1 -0
- package/dist/containers/TabletsFilters/TabletsFilters.js +4 -8
- package/dist/containers/TabletsFilters/TabletsFilters.scss +6 -2
- package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +8 -13
- package/dist/containers/Tenant/Diagnostics/DiagnosticsPages.ts +7 -7
- package/dist/containers/Tenant/Diagnostics/{TopShards/TopShards.scss → OverloadedShards/OverloadedShards.scss} +1 -1
- package/dist/containers/Tenant/Diagnostics/{TopShards/TopShards.tsx → OverloadedShards/OverloadedShards.tsx} +10 -11
- package/dist/containers/Tenant/Diagnostics/{TopShards → OverloadedShards}/i18n/en.json +0 -0
- package/dist/containers/Tenant/Diagnostics/OverloadedShards/i18n/index.ts +11 -0
- package/dist/containers/Tenant/Diagnostics/{TopShards → OverloadedShards}/i18n/ru.json +0 -0
- package/dist/containers/Tenant/Diagnostics/OverloadedShards/index.ts +1 -0
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +7 -7
- 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/{TopShards → TopQueries}/i18n/index.ts +1 -1
- package/dist/containers/Tenant/Diagnostics/TopQueries/i18n/ru.json +4 -0
- package/dist/containers/Tenant/Diagnostics/TopQueries/index.ts +1 -0
- package/dist/containers/Tenants/Tenants.js +1 -1
- package/dist/containers/UserSettings/UserSettings.tsx +5 -4
- package/dist/routes.ts +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/{heatmap.js → heatmap.ts} +33 -18
- package/dist/store/reducers/settings.js +13 -3
- package/dist/store/reducers/shardsWorkload.ts +9 -9
- 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 +10 -2
- 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 +17 -3
- 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/heatmap.ts +51 -0
- package/dist/types/store/schema.ts +3 -3
- package/dist/types/store/shardsWorkload.ts +3 -3
- package/dist/types/store/tablets.ts +42 -0
- package/dist/utils/constants.ts +1 -37
- package/dist/utils/getNodesColumns.js +14 -2
- package/dist/utils/tablet.ts +53 -0
- package/package.json +4 -3
- package/dist/components/AsideNavigation/AsideHeader.scss +0 -147
- package/dist/components/AsideNavigation/AsideHeader.tsx +0 -389
- package/dist/components/AsideNavigation/AsideHeaderFooterItem/AsideHeaderFooterItem.scss +0 -82
- package/dist/components/AsideNavigation/AsideHeaderFooterItem/AsideHeaderFooterItem.tsx +0 -138
- package/dist/components/AsideNavigation/AsideHeaderFooterSlot/AsideHeaderFooterSlot.tsx +0 -33
- package/dist/components/AsideNavigation/AsideHeaderFooterSlot/SlotsContext.tsx +0 -49
- package/dist/components/AsideNavigation/AsideHeaderTooltip/AsideHeaderTooltip.scss +0 -16
- package/dist/components/AsideNavigation/AsideHeaderTooltip/AsideHeaderTooltip.tsx +0 -37
- package/dist/components/AsideNavigation/CompositeBar/CompositeBar.scss +0 -108
- package/dist/components/AsideNavigation/CompositeBar/CompositeBar.tsx +0 -282
- package/dist/components/AsideNavigation/Content/Content.tsx +0 -35
- package/dist/components/AsideNavigation/Drawer/Drawer.scss +0 -76
- package/dist/components/AsideNavigation/Drawer/Drawer.tsx +0 -134
- package/dist/components/AsideNavigation/Drawer/index.ts +0 -1
- package/dist/components/AsideNavigation/Logo/Logo.scss +0 -43
- package/dist/components/AsideNavigation/Logo/Logo.tsx +0 -82
- package/dist/components/AsideNavigation/Settings/README.md +0 -92
- package/dist/components/AsideNavigation/Settings/Settings.scss +0 -128
- package/dist/components/AsideNavigation/Settings/Settings.tsx +0 -270
- package/dist/components/AsideNavigation/Settings/SettingsMenu/SettingsMenu.scss +0 -78
- package/dist/components/AsideNavigation/Settings/SettingsMenu/SettingsMenu.tsx +0 -141
- package/dist/components/AsideNavigation/Settings/SettingsSearch/SettingsSearch.tsx +0 -57
- package/dist/components/AsideNavigation/Settings/collect-settings.ts +0 -156
- package/dist/components/AsideNavigation/Settings/filter-settings.ts +0 -38
- package/dist/components/AsideNavigation/Settings/helpers.ts +0 -39
- package/dist/components/AsideNavigation/Settings/i18n/en.json +0 -5
- package/dist/components/AsideNavigation/Settings/i18n/ru.json +0 -5
- package/dist/components/AsideNavigation/Settings/index.ts +0 -1
- package/dist/components/AsideNavigation/constants.ts +0 -28
- package/dist/components/AsideNavigation/helpers.ts +0 -34
- package/dist/components/AsideNavigation/i18n/en.json +0 -4
- package/dist/components/AsideNavigation/i18n/ru.json +0 -4
- package/dist/components/AsideNavigation/icons.ts +0 -32
- package/dist/components/AsideNavigation/types.ts +0 -23
- package/dist/components/TabletsStatistic/TabletsStatistic.js +0 -58
- package/dist/containers/Heatmap/Heatmap.js +0 -244
- package/dist/containers/Tablets/Tablets.js +0 -228
- package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.js +0 -188
- package/dist/containers/Tenant/Diagnostics/TopShards/DateRange/DateRange.scss +0 -13
- 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
@@ -1,244 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import PropTypes from 'prop-types';
|
3
|
-
import {connect} from 'react-redux';
|
4
|
-
import cn from 'bem-cn-lite';
|
5
|
-
|
6
|
-
import {getTabletsInfo, setHeatmapOptions} from '../../store/reducers/heatmap';
|
7
|
-
import {showTooltip, hideTooltip} from '../../store/reducers/tooltip';
|
8
|
-
import {COLORS_RANGE_SIZE, getColorRange, getColorIndex, getCurrentMetricLimits} from './util';
|
9
|
-
import {formatNumber} from '../../utils';
|
10
|
-
|
11
|
-
import {Loader, Checkbox, Select} from '@gravity-ui/uikit';
|
12
|
-
import {HeatmapCanvas} from './HeatmapCanvas/HeatmapCanvas';
|
13
|
-
import {Histogram} from './Histogram/Histogram';
|
14
|
-
import {AutoFetcher} from '../../utils/autofetcher';
|
15
|
-
|
16
|
-
import './Heatmap.scss';
|
17
|
-
|
18
|
-
const b = cn('heatmap');
|
19
|
-
const COLORS_RANGE = getColorRange(COLORS_RANGE_SIZE);
|
20
|
-
|
21
|
-
const PageLoader = () => (
|
22
|
-
<div className={b('loader')}>
|
23
|
-
<Loader size="m" />
|
24
|
-
</div>
|
25
|
-
);
|
26
|
-
|
27
|
-
class Heatmap extends React.Component {
|
28
|
-
static propTypes = {
|
29
|
-
tablets: PropTypes.array,
|
30
|
-
error: PropTypes.bool,
|
31
|
-
wasLoaded: PropTypes.bool,
|
32
|
-
loading: PropTypes.bool,
|
33
|
-
showTooltip: PropTypes.func,
|
34
|
-
hideTooltip: PropTypes.func,
|
35
|
-
getTabletsInfo: PropTypes.func,
|
36
|
-
nodeId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
37
|
-
path: PropTypes.string,
|
38
|
-
clearWasLoadingFlag: PropTypes.func,
|
39
|
-
metrics: PropTypes.array,
|
40
|
-
sort: PropTypes.bool,
|
41
|
-
heatmap: PropTypes.bool,
|
42
|
-
currentMetric: PropTypes.string,
|
43
|
-
setHeatmapOptions: PropTypes.func,
|
44
|
-
};
|
45
|
-
autofetcher;
|
46
|
-
|
47
|
-
componentDidMount() {
|
48
|
-
this.getTablets();
|
49
|
-
this.autofetcher = new AutoFetcher();
|
50
|
-
this.setInitialMetric();
|
51
|
-
if (this.props.autorefresh) {
|
52
|
-
this.autofetcher.start();
|
53
|
-
this.autofetcher.fetch(() => this.getTablets());
|
54
|
-
}
|
55
|
-
}
|
56
|
-
componentDidUpdate(prevProps) {
|
57
|
-
const {path, autorefresh} = this.props;
|
58
|
-
|
59
|
-
if (path && prevProps.path !== path) {
|
60
|
-
this.props.setHeatmapOptions({
|
61
|
-
wasLoaded: false,
|
62
|
-
});
|
63
|
-
this.getTablets();
|
64
|
-
}
|
65
|
-
|
66
|
-
if (autorefresh && !prevProps.autorefresh) {
|
67
|
-
this.getTablets();
|
68
|
-
this.autofetcher.start();
|
69
|
-
this.autofetcher.fetch(() => this.getTablets());
|
70
|
-
}
|
71
|
-
if (!autorefresh && prevProps.autorefresh) {
|
72
|
-
this.autofetcher.stop();
|
73
|
-
}
|
74
|
-
|
75
|
-
this.setInitialMetric();
|
76
|
-
}
|
77
|
-
componentWillUnmount() {
|
78
|
-
this.autofetcher.stop();
|
79
|
-
}
|
80
|
-
|
81
|
-
itemsContainer = React.createRef();
|
82
|
-
|
83
|
-
setInitialMetric = () => {
|
84
|
-
const {metrics, currentMetric} = this.props;
|
85
|
-
|
86
|
-
if (!currentMetric && metrics && metrics.length) {
|
87
|
-
this.props.setHeatmapOptions({
|
88
|
-
currentMetric: metrics[0].value,
|
89
|
-
});
|
90
|
-
}
|
91
|
-
};
|
92
|
-
getTablets = () => {
|
93
|
-
const {path} = this.props;
|
94
|
-
|
95
|
-
this.props.getTabletsInfo({path});
|
96
|
-
};
|
97
|
-
_onMetricChange = (value) => {
|
98
|
-
this.props.setHeatmapOptions({
|
99
|
-
currentMetric: value,
|
100
|
-
});
|
101
|
-
};
|
102
|
-
_onCheckboxChange = () => {
|
103
|
-
this.props.setHeatmapOptions({
|
104
|
-
sort: !this.props.sort,
|
105
|
-
});
|
106
|
-
};
|
107
|
-
_onHeatmapChange = () => {
|
108
|
-
this.props.setHeatmapOptions({
|
109
|
-
heatmap: !this.props.heatmap,
|
110
|
-
});
|
111
|
-
};
|
112
|
-
renderHistogram() {
|
113
|
-
const {tablets, currentMetric} = this.props;
|
114
|
-
|
115
|
-
return (
|
116
|
-
<Histogram
|
117
|
-
tablets={tablets}
|
118
|
-
currentMetric={currentMetric}
|
119
|
-
showTooltip={this.props.showTooltip}
|
120
|
-
hideTooltip={this.props.hideTooltip}
|
121
|
-
/>
|
122
|
-
);
|
123
|
-
}
|
124
|
-
renderHeatmapCanvas() {
|
125
|
-
const {tablets, currentMetric, sort} = this.props;
|
126
|
-
|
127
|
-
const {min, max} = getCurrentMetricLimits(currentMetric, tablets);
|
128
|
-
|
129
|
-
const preparedTablets = tablets.map((tablet) => {
|
130
|
-
const value = currentMetric && Number(tablet.metrics[currentMetric]);
|
131
|
-
const colorIndex = getColorIndex(value, min, max);
|
132
|
-
const color = COLORS_RANGE[colorIndex];
|
133
|
-
|
134
|
-
return {
|
135
|
-
...tablet,
|
136
|
-
color,
|
137
|
-
value,
|
138
|
-
formattedValue: formatNumber(value),
|
139
|
-
currentMetric,
|
140
|
-
};
|
141
|
-
});
|
142
|
-
const sortedTablets = sort
|
143
|
-
? preparedTablets.sort((a, b) => b.value - a.value)
|
144
|
-
: preparedTablets;
|
145
|
-
|
146
|
-
return (
|
147
|
-
<div ref={this.itemsContainer} className={b('items')}>
|
148
|
-
<HeatmapCanvas
|
149
|
-
tablets={sortedTablets}
|
150
|
-
parentRef={this.itemsContainer}
|
151
|
-
showTooltip={this.props.showTooltip}
|
152
|
-
hideTooltip={this.props.hideTooltip}
|
153
|
-
currentMetric={currentMetric}
|
154
|
-
/>
|
155
|
-
</div>
|
156
|
-
);
|
157
|
-
}
|
158
|
-
renderContent() {
|
159
|
-
const {tablets, metrics, currentMetric, heatmap, sort} = this.props;
|
160
|
-
|
161
|
-
const {min, max} = getCurrentMetricLimits(currentMetric, tablets);
|
162
|
-
|
163
|
-
return (
|
164
|
-
<div className={b()}>
|
165
|
-
<div className={b('filters')}>
|
166
|
-
<Select
|
167
|
-
className={b('heatmap-select')}
|
168
|
-
value={currentMetric}
|
169
|
-
options={metrics}
|
170
|
-
onUpdate={this._onMetricChange}
|
171
|
-
width={200}
|
172
|
-
/>
|
173
|
-
<div className={b('sort-checkbox')}>
|
174
|
-
<Checkbox onUpdate={this._onCheckboxChange} checked={sort}>
|
175
|
-
Sort
|
176
|
-
</Checkbox>
|
177
|
-
</div>
|
178
|
-
<div className={b('histogram-checkbox')}>
|
179
|
-
<Checkbox onUpdate={this._onHeatmapChange} checked={heatmap}>
|
180
|
-
Heatmap
|
181
|
-
</Checkbox>
|
182
|
-
</div>
|
183
|
-
<div className={b('limits')}>
|
184
|
-
<div className={b('limits-block')}>
|
185
|
-
<div className={b('limits-title')}>min:</div>
|
186
|
-
<div className={b('limits-value')}>
|
187
|
-
{Number.isInteger(min) ? formatNumber(min) : '—'}
|
188
|
-
</div>
|
189
|
-
</div>
|
190
|
-
<div className={b('limits-block')}>
|
191
|
-
<div className={b('limits-title')}>max:</div>
|
192
|
-
<div className={b('limits-value')}>
|
193
|
-
{Number.isInteger(max) ? formatNumber(max) : '—'}
|
194
|
-
</div>
|
195
|
-
</div>
|
196
|
-
<div className={b('limits-block')}>
|
197
|
-
<div className={b('limits-title')}>count:</div>
|
198
|
-
<div className={b('limits-value')}>{formatNumber(tablets.length)}</div>
|
199
|
-
</div>
|
200
|
-
</div>
|
201
|
-
</div>
|
202
|
-
{heatmap ? this.renderHeatmapCanvas() : this.renderHistogram()}
|
203
|
-
</div>
|
204
|
-
);
|
205
|
-
}
|
206
|
-
render() {
|
207
|
-
const {loading, wasLoaded} = this.props;
|
208
|
-
|
209
|
-
return loading && !wasLoaded ? <PageLoader /> : this.renderContent();
|
210
|
-
}
|
211
|
-
}
|
212
|
-
|
213
|
-
const mapStateToProps = (state) => {
|
214
|
-
const {
|
215
|
-
loading,
|
216
|
-
data: tablets = [],
|
217
|
-
metrics,
|
218
|
-
sort,
|
219
|
-
heatmap,
|
220
|
-
currentMetric,
|
221
|
-
wasLoaded,
|
222
|
-
} = state.heatmap;
|
223
|
-
const {autorefresh} = state.schema;
|
224
|
-
|
225
|
-
return {
|
226
|
-
tablets,
|
227
|
-
loading,
|
228
|
-
metrics,
|
229
|
-
sort,
|
230
|
-
heatmap,
|
231
|
-
currentMetric,
|
232
|
-
wasLoaded,
|
233
|
-
autorefresh,
|
234
|
-
};
|
235
|
-
};
|
236
|
-
|
237
|
-
const mapDispatchToProps = {
|
238
|
-
getTabletsInfo,
|
239
|
-
hideTooltip,
|
240
|
-
showTooltip,
|
241
|
-
setHeatmapOptions,
|
242
|
-
};
|
243
|
-
|
244
|
-
export default connect(mapStateToProps, mapDispatchToProps)(Heatmap);
|
@@ -1,228 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import PropTypes from 'prop-types';
|
3
|
-
import {connect} from 'react-redux';
|
4
|
-
import cn from 'bem-cn-lite';
|
5
|
-
|
6
|
-
import {
|
7
|
-
getTabletsInfo,
|
8
|
-
clearWasLoadingFlag,
|
9
|
-
setStateFilter,
|
10
|
-
setTypeFilter,
|
11
|
-
} from '../../store/reducers/tablets';
|
12
|
-
import {showTooltip, hideTooltip} from '../../store/reducers/tooltip';
|
13
|
-
|
14
|
-
import Tablet from '../../components/Tablet/Tablet';
|
15
|
-
import {Loader, Select} from '@gravity-ui/uikit';
|
16
|
-
import ReactList from 'react-list';
|
17
|
-
import {AutoFetcher} from '../../utils/autofetcher';
|
18
|
-
|
19
|
-
import './Tablets.scss';
|
20
|
-
import TabletsOverall from '../../components/TabletsOverall/TabletsOverall';
|
21
|
-
|
22
|
-
const b = cn('tablets');
|
23
|
-
|
24
|
-
class Tablets extends React.Component {
|
25
|
-
static propTypes = {
|
26
|
-
tablets: PropTypes.array,
|
27
|
-
error: PropTypes.bool,
|
28
|
-
wasLoaded: PropTypes.bool,
|
29
|
-
loading: PropTypes.bool,
|
30
|
-
showTooltip: PropTypes.func,
|
31
|
-
hideTooltip: PropTypes.func,
|
32
|
-
getTabletsInfo: PropTypes.func,
|
33
|
-
nodeId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
34
|
-
path: PropTypes.string,
|
35
|
-
clearWasLoadingFlag: PropTypes.func,
|
36
|
-
className: PropTypes.string,
|
37
|
-
};
|
38
|
-
|
39
|
-
autofetcher;
|
40
|
-
|
41
|
-
state = {
|
42
|
-
filteredTablets: [],
|
43
|
-
};
|
44
|
-
|
45
|
-
componentDidMount() {
|
46
|
-
this.makeRequestIfPathOrNodeExist();
|
47
|
-
this.autofetcher = new AutoFetcher();
|
48
|
-
if (this.props.autorefresh) {
|
49
|
-
this.autofetcher.start();
|
50
|
-
this.autofetcher.fetch(() => this.makeRequestIfPathOrNodeExist());
|
51
|
-
}
|
52
|
-
}
|
53
|
-
|
54
|
-
componentDidUpdate(prevProps) {
|
55
|
-
const {autorefresh} = this.props;
|
56
|
-
|
57
|
-
if (!prevProps.path && this.props.path) {
|
58
|
-
this.makeRequestIfPathOrNodeExist();
|
59
|
-
}
|
60
|
-
|
61
|
-
if (prevProps.path && this.props.path && prevProps.path !== this.props.path) {
|
62
|
-
this.props.clearWasLoadingFlag();
|
63
|
-
this.makeRequestIfPathOrNodeExist();
|
64
|
-
}
|
65
|
-
|
66
|
-
if (autorefresh && !prevProps.autorefresh) {
|
67
|
-
this.makeRequestIfPathOrNodeExist();
|
68
|
-
this.autofetcher.stop();
|
69
|
-
this.autofetcher.start();
|
70
|
-
this.autofetcher.fetch(() => this.makeRequestIfPathOrNodeExist());
|
71
|
-
}
|
72
|
-
if (!autorefresh && prevProps.autorefresh) {
|
73
|
-
this.autofetcher.stop();
|
74
|
-
}
|
75
|
-
}
|
76
|
-
|
77
|
-
componentWillUnmount() {
|
78
|
-
this.autofetcher.stop();
|
79
|
-
}
|
80
|
-
|
81
|
-
renderLoader = () => {
|
82
|
-
return (
|
83
|
-
<div className={b('loader-wrapper')}>
|
84
|
-
<Loader size="m" />
|
85
|
-
</div>
|
86
|
-
);
|
87
|
-
};
|
88
|
-
|
89
|
-
makeRequestIfPathOrNodeExist = () => {
|
90
|
-
const {nodeId, path} = this.props;
|
91
|
-
if (typeof nodeId !== 'undefined') {
|
92
|
-
this.props.getTabletsInfo({nodes: [nodeId]}).then(this.updateFilteredTablets);
|
93
|
-
} else if (typeof path !== 'undefined') {
|
94
|
-
this.props.getTabletsInfo({path}).then(this.updateFilteredTablets);
|
95
|
-
}
|
96
|
-
};
|
97
|
-
|
98
|
-
handleStateFilterChange = (stateFilter) => {
|
99
|
-
this.props.setStateFilter(stateFilter);
|
100
|
-
this.updateFilteredTablets();
|
101
|
-
};
|
102
|
-
|
103
|
-
handleTypeFilterChange = (typeFilter) => {
|
104
|
-
this.props.setTypeFilter(typeFilter);
|
105
|
-
this.updateFilteredTablets();
|
106
|
-
};
|
107
|
-
|
108
|
-
renderTablet = (tablet, tabletIndex) => {
|
109
|
-
return (
|
110
|
-
<Tablet
|
111
|
-
onMouseLeave={this.props.hideTooltip}
|
112
|
-
onMouseEnter={this.props.showTooltip}
|
113
|
-
tablet={this.state.filteredTablets[parseInt(tabletIndex, 10)]}
|
114
|
-
key={tabletIndex}
|
115
|
-
size={this.props.size}
|
116
|
-
className={b('tablet')}
|
117
|
-
/>
|
118
|
-
);
|
119
|
-
};
|
120
|
-
|
121
|
-
updateFilteredTablets = () => {
|
122
|
-
const {stateFilter, typeFilter} = this.props;
|
123
|
-
const {tablets} = this.props;
|
124
|
-
|
125
|
-
let filteredTablets = tablets;
|
126
|
-
|
127
|
-
if (typeFilter.length > 0) {
|
128
|
-
filteredTablets = filteredTablets.filter((tblt) =>
|
129
|
-
typeFilter.some((filter) => tblt.Type === filter),
|
130
|
-
);
|
131
|
-
}
|
132
|
-
if (stateFilter.length > 0) {
|
133
|
-
filteredTablets = filteredTablets.filter((tblt) =>
|
134
|
-
stateFilter.some((filter) => tblt.State === filter),
|
135
|
-
);
|
136
|
-
}
|
137
|
-
this.setState({filteredTablets});
|
138
|
-
};
|
139
|
-
|
140
|
-
renderContent = (tablets) => {
|
141
|
-
const states = Array.from(new Set(...[tablets.map((tblt) => tblt.State)])).map((item) => ({
|
142
|
-
value: item,
|
143
|
-
content: item,
|
144
|
-
}));
|
145
|
-
const types = Array.from(new Set(...[tablets.map((tblt) => tblt.Type)])).map((item) => ({
|
146
|
-
value: item,
|
147
|
-
content: item,
|
148
|
-
}));
|
149
|
-
const {filteredTablets} = this.state;
|
150
|
-
const {stateFilter, typeFilter, className} = this.props;
|
151
|
-
|
152
|
-
return (
|
153
|
-
<div className={b(null, className)}>
|
154
|
-
<div className={b('header')}>
|
155
|
-
<Select
|
156
|
-
className={b('filter-control')}
|
157
|
-
multiple
|
158
|
-
placeholder="All items"
|
159
|
-
label="States:"
|
160
|
-
options={states}
|
161
|
-
value={stateFilter}
|
162
|
-
onUpdate={this.handleStateFilterChange}
|
163
|
-
width="100%"
|
164
|
-
/>
|
165
|
-
<Select
|
166
|
-
className={b('filter-control')}
|
167
|
-
multiple
|
168
|
-
placeholder="All items"
|
169
|
-
label="Types:"
|
170
|
-
options={types}
|
171
|
-
value={typeFilter}
|
172
|
-
onUpdate={this.handleTypeFilterChange}
|
173
|
-
width="100%"
|
174
|
-
/>
|
175
|
-
<TabletsOverall tablets={tablets} />
|
176
|
-
</div>
|
177
|
-
|
178
|
-
<div className={b('items')}>
|
179
|
-
<ReactList
|
180
|
-
itemRenderer={this.renderTablet}
|
181
|
-
length={filteredTablets.length}
|
182
|
-
type="uniform"
|
183
|
-
/>
|
184
|
-
</div>
|
185
|
-
</div>
|
186
|
-
);
|
187
|
-
};
|
188
|
-
|
189
|
-
render() {
|
190
|
-
const {loading, wasLoaded, error, tablets} = this.props;
|
191
|
-
if (loading && !wasLoaded) {
|
192
|
-
return this.renderLoader();
|
193
|
-
} else if (error) {
|
194
|
-
return <div>{error.statusText}</div>;
|
195
|
-
} else {
|
196
|
-
return tablets.length > 0 ? (
|
197
|
-
this.renderContent(tablets)
|
198
|
-
) : (
|
199
|
-
<div className="error">no tablets data</div>
|
200
|
-
);
|
201
|
-
}
|
202
|
-
}
|
203
|
-
}
|
204
|
-
|
205
|
-
const mapStateToProps = (state) => {
|
206
|
-
const {data = {}, wasLoaded, loading, stateFilter, typeFilter} = state.tablets;
|
207
|
-
const {autorefresh} = state.schema;
|
208
|
-
const {TabletStateInfo: tablets = []} = data;
|
209
|
-
return {
|
210
|
-
tablets,
|
211
|
-
wasLoaded,
|
212
|
-
loading,
|
213
|
-
stateFilter,
|
214
|
-
typeFilter,
|
215
|
-
autorefresh,
|
216
|
-
};
|
217
|
-
};
|
218
|
-
|
219
|
-
const mapDispatchToProps = {
|
220
|
-
getTabletsInfo,
|
221
|
-
hideTooltip,
|
222
|
-
showTooltip,
|
223
|
-
clearWasLoadingFlag,
|
224
|
-
setStateFilter,
|
225
|
-
setTypeFilter,
|
226
|
-
};
|
227
|
-
|
228
|
-
export default connect(mapStateToProps, mapDispatchToProps)(Tablets);
|
@@ -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,13 +0,0 @@
|
|
1
|
-
.top-shards {
|
2
|
-
&__date-range {
|
3
|
-
&-input {
|
4
|
-
min-width: 190px;
|
5
|
-
padding: 5px 8px;
|
6
|
-
|
7
|
-
color: var(--yc-color-text-primary);
|
8
|
-
border: 1px solid var(--yc-color-line-generic);
|
9
|
-
border-radius: var(--yc-border-radius-m);
|
10
|
-
background: transparent;
|
11
|
-
}
|
12
|
-
}
|
13
|
-
}
|
@@ -1 +0,0 @@
|
|
1
|
-
export * from './TopShards';
|