ydb-embedded-ui 2.4.4 → 2.5.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.
- package/CHANGELOG.md +20 -0
- package/dist/components/InfoViewer/formatters/schema.ts +2 -1
- package/dist/components/InfoViewer/schemaInfo/CDCStreamInfo.tsx +3 -16
- package/dist/components/InfoViewer/schemaInfo/PersQueueGroupInfo.tsx +8 -13
- package/dist/components/InfoViewer/schemaInfo/TableIndexInfo.tsx +2 -12
- package/dist/components/InfoViewer/schemaOverview/CDCStreamOverview.tsx +3 -16
- package/dist/components/InfoViewer/schemaOverview/PersQueueGroupOverview.tsx +8 -13
- package/dist/components/InfoViewer/utils.ts +6 -6
- package/dist/components/Loader/Loader.scss +6 -3
- package/dist/components/Loader/Loader.tsx +7 -5
- package/dist/components/Loader/index.ts +1 -0
- package/dist/components/UptimeFIlter/UptimeFilter.tsx +21 -0
- package/dist/components/UptimeFIlter/index.ts +1 -0
- package/dist/containers/Node/Node.scss +1 -0
- package/dist/containers/Node/Node.tsx +3 -8
- package/dist/containers/Node/NodeStructure/NodeStructure.scss +0 -6
- package/dist/containers/Node/NodeStructure/NodeStructure.tsx +1 -1
- package/dist/containers/Nodes/Nodes.js +22 -10
- package/dist/{components → containers}/NodesViewer/NodesViewer.js +49 -62
- package/dist/{components → containers}/NodesViewer/NodesViewer.scss +0 -0
- package/dist/containers/Storage/Pdisk/Pdisk.scss +1 -1
- package/dist/containers/Storage/Storage.js +35 -10
- package/dist/containers/Storage/StorageNodes/StorageNodes.scss +2 -2
- package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +35 -17
- package/dist/containers/Storage/StorageNodes/i18n/en.json +6 -4
- package/dist/containers/Storage/StorageNodes/i18n/ru.json +6 -4
- package/dist/containers/Storage/UsageFilter/UsageFilter.scss +10 -5
- package/dist/containers/Tenant/Acl/Acl.js +1 -7
- package/dist/containers/Tenant/Diagnostics/Compute/Compute.js +1 -1
- package/dist/containers/Tenant/Diagnostics/Consumers/Consumers.tsx +34 -8
- package/dist/containers/Tenant/Diagnostics/Describe/Describe.scss +0 -8
- package/dist/containers/Tenant/Diagnostics/Describe/Describe.tsx +2 -6
- package/dist/containers/Tenant/Diagnostics/Diagnostics.scss +0 -7
- package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +5 -7
- package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.js +21 -13
- package/dist/containers/Tenant/ObjectGeneral/ObjectGeneral.tsx +1 -5
- package/dist/containers/Tenant/QueryEditor/QueryExplain/QueryExplain.js +4 -4
- package/dist/containers/Tenant/QueryEditor/SaveQuery/SaveQuery.js +1 -4
- package/dist/containers/Tenant/Schema/SchemaInfoViewer/SchemaInfoViewer.js +23 -28
- package/dist/containers/Tenant/TenantPages.tsx +1 -1
- package/dist/containers/Tenant/utils/schemaActions.ts +9 -20
- package/dist/store/reducers/clusterNodes.js +29 -10
- package/dist/store/reducers/nodes.js +24 -3
- package/dist/store/reducers/{schema.js → schema.ts} +22 -14
- package/dist/store/reducers/storage.js +46 -5
- package/dist/types/store/schema.ts +46 -0
- package/dist/utils/index.js +6 -2
- package/dist/utils/nodes.ts +9 -0
- package/package.json +1 -1
@@ -1,28 +1,46 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import cn from 'bem-cn-lite';
|
3
3
|
import PropTypes from 'prop-types';
|
4
|
-
import _ from 'lodash';
|
5
4
|
import {connect} from 'react-redux';
|
6
5
|
|
7
6
|
import {TextInput, Label} from '@gravity-ui/uikit';
|
8
7
|
import DataTable from '@yandex-cloud/react-data-table';
|
9
8
|
|
10
|
-
import ProblemFilter, {problemFilterType} from '
|
9
|
+
import ProblemFilter, {problemFilterType} from '../../components/ProblemFilter/ProblemFilter';
|
10
|
+
import {UptimeFilter} from '../../components/UptimeFIlter';
|
11
|
+
import {Illustration} from '../../components/Illustration';
|
11
12
|
|
12
13
|
import {withSearch} from '../../HOCS';
|
13
14
|
import {calcUptime} from '../../utils';
|
14
|
-
import {
|
15
|
+
import {DEFAULT_TABLE_SETTINGS} from '../../utils/constants';
|
15
16
|
import {changeFilter} from '../../store/reducers/settings';
|
17
|
+
import {filterNodesByStatusAndUptime} from '../../store/reducers/clusterNodes';
|
18
|
+
import {setNodesUptimeFilter} from '../../store/reducers/nodes';
|
16
19
|
import {hideTooltip, showTooltip} from '../../store/reducers/tooltip';
|
17
20
|
import {getNodesColumns} from '../../utils/getNodesColumns';
|
18
21
|
|
19
|
-
import {Illustration} from '../Illustration';
|
20
|
-
|
21
22
|
import './NodesViewer.scss';
|
22
23
|
|
23
24
|
const b = cn('nodes-viewer');
|
24
25
|
|
25
26
|
class NodesViewer extends React.PureComponent {
|
27
|
+
static selectNodesToShow(nodes, searchQuery) {
|
28
|
+
let preparedNodes = nodes;
|
29
|
+
if (nodes && Array.isArray(nodes)) {
|
30
|
+
preparedNodes = nodes
|
31
|
+
.map((node) => {
|
32
|
+
node.uptime = calcUptime(node.StartTime);
|
33
|
+
return node;
|
34
|
+
})
|
35
|
+
/* Filter by nodes with the Host field.
|
36
|
+
If a node does not have a Host field it is also
|
37
|
+
included in the filter and displayed with a dash in the corresponding column
|
38
|
+
*/
|
39
|
+
.filter((node) => (node.Host ? node.Host.includes(searchQuery) : true));
|
40
|
+
}
|
41
|
+
return preparedNodes;
|
42
|
+
}
|
43
|
+
|
26
44
|
static propTypes = {
|
27
45
|
nodes: PropTypes.array.isRequired,
|
28
46
|
className: PropTypes.string,
|
@@ -30,7 +48,9 @@ class NodesViewer extends React.PureComponent {
|
|
30
48
|
handleSearchQuery: PropTypes.func,
|
31
49
|
showTooltip: PropTypes.func,
|
32
50
|
hideTooltip: PropTypes.func,
|
33
|
-
|
51
|
+
problemFilter: problemFilterType,
|
52
|
+
nodesUptimeFilter: PropTypes.string,
|
53
|
+
setNodesUptimeFilter: PropTypes.func,
|
34
54
|
changeFilter: PropTypes.func,
|
35
55
|
showControls: PropTypes.bool,
|
36
56
|
additionalNodesInfo: PropTypes.object,
|
@@ -42,60 +62,18 @@ class NodesViewer extends React.PureComponent {
|
|
42
62
|
showControls: true,
|
43
63
|
};
|
44
64
|
|
45
|
-
|
46
|
-
|
47
|
-
nodesToShow: [],
|
65
|
+
handleProblemFilterChange = (value) => {
|
66
|
+
this.props.changeFilter(value);
|
48
67
|
};
|
49
68
|
|
50
|
-
|
51
|
-
|
52
|
-
if (!_.isEqual(nodes, state.nodes)) {
|
53
|
-
return {
|
54
|
-
nodes,
|
55
|
-
filteredNodes: NodesViewer.filterNodes(nodes, filter),
|
56
|
-
};
|
57
|
-
}
|
58
|
-
return null;
|
59
|
-
}
|
60
|
-
|
61
|
-
static filterNodes(nodes, filter) {
|
62
|
-
if (filter === ALL) {
|
63
|
-
return nodes;
|
64
|
-
}
|
65
|
-
|
66
|
-
return _.filter(nodes, (node) => {
|
67
|
-
return node.Overall && node.Overall !== 'Green';
|
68
|
-
});
|
69
|
-
}
|
70
|
-
|
71
|
-
static selectNodesToShow(nodes, searchQuery) {
|
72
|
-
let preparedNodes = nodes;
|
73
|
-
if (nodes && Array.isArray(nodes)) {
|
74
|
-
preparedNodes = nodes
|
75
|
-
.map((node) => {
|
76
|
-
node.uptime = calcUptime(node.StartTime);
|
77
|
-
return node;
|
78
|
-
})
|
79
|
-
/* Filter by nodes with the Host field.
|
80
|
-
If a node does not have a Host field it is also
|
81
|
-
included in the filter and displayed with a dash in the corresponding column
|
82
|
-
*/
|
83
|
-
.filter((node) => (node.Host ? node.Host.includes(searchQuery) : true));
|
84
|
-
}
|
85
|
-
return preparedNodes;
|
86
|
-
}
|
87
|
-
|
88
|
-
onChangeProblemFilter = (filter) => {
|
89
|
-
const {nodes, changeFilter} = this.props;
|
90
|
-
const filteredNodes = NodesViewer.filterNodes(nodes, filter);
|
91
|
-
|
92
|
-
changeFilter(filter);
|
93
|
-
this.setState({filteredNodes});
|
69
|
+
handleUptimeFilterChange = (value) => {
|
70
|
+
this.props.setNodesUptimeFilter(value);
|
94
71
|
};
|
95
72
|
|
96
73
|
renderControls() {
|
97
|
-
const {searchQuery, handleSearchQuery,
|
98
|
-
|
74
|
+
const {nodes, searchQuery, handleSearchQuery, nodesUptimeFilter, problemFilter} =
|
75
|
+
this.props;
|
76
|
+
const nodesToShow = NodesViewer.selectNodesToShow(nodes, searchQuery);
|
99
77
|
|
100
78
|
return (
|
101
79
|
<div className={b('controls')}>
|
@@ -108,7 +86,8 @@ class NodesViewer extends React.PureComponent {
|
|
108
86
|
hasClear
|
109
87
|
autoFocus
|
110
88
|
/>
|
111
|
-
<ProblemFilter value={
|
89
|
+
<ProblemFilter value={problemFilter} onChange={this.handleProblemFilterChange} />
|
90
|
+
<UptimeFilter value={nodesUptimeFilter} onChange={this.handleUptimeFilterChange} />
|
112
91
|
<Label theme="info" size="m">{`Nodes: ${nodesToShow.length}`}</Label>
|
113
92
|
</div>
|
114
93
|
);
|
@@ -119,13 +98,13 @@ class NodesViewer extends React.PureComponent {
|
|
119
98
|
className,
|
120
99
|
searchQuery,
|
121
100
|
path,
|
122
|
-
|
101
|
+
problemFilter,
|
123
102
|
showControls,
|
124
103
|
hideTooltip,
|
125
104
|
showTooltip,
|
126
105
|
additionalNodesInfo = {},
|
106
|
+
nodes,
|
127
107
|
} = this.props;
|
128
|
-
const {filteredNodes = []} = this.state;
|
129
108
|
|
130
109
|
const columns = getNodesColumns({
|
131
110
|
tabletsPath: path,
|
@@ -134,7 +113,7 @@ class NodesViewer extends React.PureComponent {
|
|
134
113
|
getNodeRef: additionalNodesInfo.getNodeRef,
|
135
114
|
});
|
136
115
|
|
137
|
-
const nodesToShow = NodesViewer.selectNodesToShow(
|
116
|
+
const nodesToShow = NodesViewer.selectNodesToShow(nodes, searchQuery);
|
138
117
|
|
139
118
|
return (
|
140
119
|
<div className={`${b()} ${className}`}>
|
@@ -146,7 +125,7 @@ class NodesViewer extends React.PureComponent {
|
|
146
125
|
<div className={b('table-content')}>
|
147
126
|
<DataTable
|
148
127
|
theme="yandex-cloud"
|
149
|
-
key={
|
128
|
+
key={problemFilter}
|
150
129
|
data={nodesToShow}
|
151
130
|
columns={columns}
|
152
131
|
settings={DEFAULT_TABLE_SETTINGS}
|
@@ -160,9 +139,16 @@ class NodesViewer extends React.PureComponent {
|
|
160
139
|
}
|
161
140
|
}
|
162
141
|
|
163
|
-
const mapStateToProps = (state) => {
|
142
|
+
const mapStateToProps = (state, ownProps) => {
|
143
|
+
const {nodesUptimeFilter} = state.nodes;
|
144
|
+
const {problemFilter} = state.settings;
|
145
|
+
|
146
|
+
const nodes = filterNodesByStatusAndUptime(ownProps.nodes, problemFilter, nodesUptimeFilter);
|
147
|
+
|
164
148
|
return {
|
165
|
-
|
149
|
+
problemFilter,
|
150
|
+
nodesUptimeFilter,
|
151
|
+
nodes,
|
166
152
|
};
|
167
153
|
};
|
168
154
|
|
@@ -170,6 +156,7 @@ const mapDispatchToProps = {
|
|
170
156
|
changeFilter,
|
171
157
|
hideTooltip,
|
172
158
|
showTooltip,
|
159
|
+
setNodesUptimeFilter,
|
173
160
|
};
|
174
161
|
|
175
162
|
const ConnectedNodesViewer = connect(mapStateToProps, mapDispatchToProps)(NodesViewer);
|
File without changes
|
@@ -8,7 +8,9 @@ import {RadioButton, Label} from '@gravity-ui/uikit';
|
|
8
8
|
import {Search} from '../../components/Search';
|
9
9
|
import {UsageFilter} from './UsageFilter';
|
10
10
|
import {AutoFetcher} from '../../utils/autofetcher';
|
11
|
+
import {NodesUptimeFilterValues} from '../../utils/nodes';
|
11
12
|
import {TableSkeleton} from '../../components/TableSkeleton/TableSkeleton';
|
13
|
+
import {UptimeFilter} from '../../components/UptimeFIlter';
|
12
14
|
import {AccessDenied} from '../../components/Errors/403';
|
13
15
|
|
14
16
|
import {
|
@@ -22,6 +24,7 @@ import {
|
|
22
24
|
getNodesObject,
|
23
25
|
StorageTypes,
|
24
26
|
setStorageType,
|
27
|
+
setNodesUptimeFilter,
|
25
28
|
VisibleEntitiesTitles,
|
26
29
|
getStoragePoolsGroupsCount,
|
27
30
|
getStorageNodesCount,
|
@@ -66,6 +69,8 @@ class Storage extends React.Component {
|
|
66
69
|
setHeader: PropTypes.func,
|
67
70
|
tenant: PropTypes.string,
|
68
71
|
nodeId: PropTypes.string,
|
72
|
+
nodesUptimeFilter: PropTypes.string,
|
73
|
+
setNodesUptimeFilter: PropTypes.func,
|
69
74
|
};
|
70
75
|
|
71
76
|
componentDidMount() {
|
@@ -166,7 +171,8 @@ class Storage extends React.Component {
|
|
166
171
|
}
|
167
172
|
|
168
173
|
renderDataTable() {
|
169
|
-
const {flatListStorageEntities, visibleEntities, nodes, storageType} =
|
174
|
+
const {flatListStorageEntities, visibleEntities, nodesUptimeFilter, nodes, storageType} =
|
175
|
+
this.props;
|
170
176
|
|
171
177
|
return (
|
172
178
|
<div className={b('table-wrapper')}>
|
@@ -182,9 +188,10 @@ class Storage extends React.Component {
|
|
182
188
|
{storageType === StorageTypes.nodes && (
|
183
189
|
<StorageNodes
|
184
190
|
visibleEntities={visibleEntities}
|
191
|
+
nodesUptimeFilter={nodesUptimeFilter}
|
185
192
|
data={flatListStorageEntities}
|
186
193
|
tableSettings={tableSettings}
|
187
|
-
onShowAll={
|
194
|
+
onShowAll={this.onShowAllNodes}
|
188
195
|
/>
|
189
196
|
)}
|
190
197
|
</div>
|
@@ -201,6 +208,15 @@ class Storage extends React.Component {
|
|
201
208
|
setStorageType(value);
|
202
209
|
};
|
203
210
|
|
211
|
+
onUptimeFilterChange = (value) => {
|
212
|
+
this.props.setNodesUptimeFilter(value);
|
213
|
+
};
|
214
|
+
|
215
|
+
onShowAllNodes = () => {
|
216
|
+
this.onGroupVisibilityChange(VisibleEntities.All);
|
217
|
+
this.onUptimeFilterChange(NodesUptimeFilterValues.All);
|
218
|
+
};
|
219
|
+
|
204
220
|
renderEntitiesCount() {
|
205
221
|
const {storageType, groupsCount, nodesCount, flatListStorageEntities, loading, wasLoaded} =
|
206
222
|
this.props;
|
@@ -230,6 +246,7 @@ class Storage extends React.Component {
|
|
230
246
|
visibleEntities,
|
231
247
|
storageType,
|
232
248
|
usageFilter,
|
249
|
+
nodesUptimeFilter,
|
233
250
|
setUsageFilter,
|
234
251
|
usageFilterOptions,
|
235
252
|
} = this.props;
|
@@ -247,6 +264,16 @@ class Storage extends React.Component {
|
|
247
264
|
value={filter}
|
248
265
|
/>
|
249
266
|
</div>
|
267
|
+
|
268
|
+
<RadioButton value={storageType} onUpdate={this.onStorageTypeChange}>
|
269
|
+
<RadioButton.Option value={StorageTypes.groups}>
|
270
|
+
{StorageTypes.groups}
|
271
|
+
</RadioButton.Option>
|
272
|
+
<RadioButton.Option value={StorageTypes.nodes}>
|
273
|
+
{StorageTypes.nodes}
|
274
|
+
</RadioButton.Option>
|
275
|
+
</RadioButton>
|
276
|
+
|
250
277
|
<RadioButton value={visibleEntities} onUpdate={this.onGroupVisibilityChange}>
|
251
278
|
<RadioButton.Option value={VisibleEntities.Missing}>
|
252
279
|
{VisibleEntitiesTitles[VisibleEntities.Missing]}
|
@@ -259,14 +286,9 @@ class Storage extends React.Component {
|
|
259
286
|
</RadioButton.Option>
|
260
287
|
</RadioButton>
|
261
288
|
|
262
|
-
|
263
|
-
<
|
264
|
-
|
265
|
-
</RadioButton.Option>
|
266
|
-
<RadioButton.Option value={StorageTypes.nodes}>
|
267
|
-
{StorageTypes.nodes}
|
268
|
-
</RadioButton.Option>
|
269
|
-
</RadioButton>
|
289
|
+
{storageType === StorageTypes.nodes && (
|
290
|
+
<UptimeFilter value={nodesUptimeFilter} onChange={this.onUptimeFilterChange} />
|
291
|
+
)}
|
270
292
|
|
271
293
|
{storageType === StorageTypes.groups && (
|
272
294
|
<UsageFilter
|
@@ -314,6 +336,7 @@ function mapStateToProps(state) {
|
|
314
336
|
type: storageType,
|
315
337
|
filter,
|
316
338
|
usageFilter,
|
339
|
+
nodesUptimeFilter,
|
317
340
|
} = state.storage;
|
318
341
|
|
319
342
|
return {
|
@@ -329,6 +352,7 @@ function mapStateToProps(state) {
|
|
329
352
|
storageType,
|
330
353
|
filter,
|
331
354
|
usageFilter,
|
355
|
+
nodesUptimeFilter,
|
332
356
|
usageFilterOptions: getUsageFilterOptions(state),
|
333
357
|
};
|
334
358
|
}
|
@@ -339,6 +363,7 @@ const mapDispatchToProps = {
|
|
339
363
|
setStorageFilter,
|
340
364
|
setUsageFilter,
|
341
365
|
setVisibleEntities: setVisibleEntities,
|
366
|
+
setNodesUptimeFilter,
|
342
367
|
getNodesList,
|
343
368
|
setStorageType,
|
344
369
|
setHeader,
|
@@ -5,6 +5,7 @@ import DataTable, {Column, Settings, SortOrder} from '@yandex-cloud/react-data-t
|
|
5
5
|
import {Popover, PopoverBehavior} from '@gravity-ui/uikit';
|
6
6
|
|
7
7
|
import {VisibleEntities} from '../../../store/reducers/storage';
|
8
|
+
import {NodesUptimeFilterValues} from '../../../utils/nodes';
|
8
9
|
|
9
10
|
import {EmptyFilter} from '../EmptyFilter/EmptyFilter';
|
10
11
|
import Pdisk from '../Pdisk/Pdisk';
|
@@ -28,6 +29,7 @@ interface StorageNodesProps {
|
|
28
29
|
nodes: any;
|
29
30
|
tableSettings: Settings;
|
30
31
|
visibleEntities: keyof typeof VisibleEntities;
|
32
|
+
nodesUptimeFilter: keyof typeof NodesUptimeFilterValues;
|
31
33
|
onShowAll?: VoidFunction;
|
32
34
|
}
|
33
35
|
|
@@ -61,7 +63,13 @@ function setSortOrder(visibleEntities: keyof typeof VisibleEntities): SortOrder
|
|
61
63
|
}
|
62
64
|
}
|
63
65
|
|
64
|
-
function StorageNodes({
|
66
|
+
function StorageNodes({
|
67
|
+
data,
|
68
|
+
tableSettings,
|
69
|
+
visibleEntities,
|
70
|
+
onShowAll,
|
71
|
+
nodesUptimeFilter,
|
72
|
+
}: StorageNodesProps) {
|
65
73
|
const allColumns: Column<any>[] = [
|
66
74
|
{
|
67
75
|
name: TableColumnsIds.NodeId,
|
@@ -124,23 +132,33 @@ function StorageNodes({data, tableSettings, visibleEntities, onShowAll}: Storage
|
|
124
132
|
|
125
133
|
if (visibleEntities === VisibleEntities.Space) {
|
126
134
|
columns = allColumns.filter((col) => col.name !== TableColumnsIds.Missing);
|
127
|
-
|
128
|
-
return (
|
129
|
-
<EmptyFilter
|
130
|
-
title={i18n('empty.out_of_space')}
|
131
|
-
showAll={i18n('show_all')}
|
132
|
-
onShowAll={onShowAll}
|
133
|
-
/>
|
134
|
-
);
|
135
135
|
}
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
136
|
+
|
137
|
+
if (!data.length) {
|
138
|
+
let message;
|
139
|
+
|
140
|
+
if (visibleEntities === VisibleEntities.Space) {
|
141
|
+
message = i18n('empty.out_of_space');
|
142
|
+
}
|
143
|
+
|
144
|
+
if (visibleEntities === VisibleEntities.Missing) {
|
145
|
+
message = i18n('empty.degraded');
|
146
|
+
}
|
147
|
+
|
148
|
+
if (nodesUptimeFilter === NodesUptimeFilterValues.SmallUptime) {
|
149
|
+
message = i18n('empty.small_uptime');
|
150
|
+
}
|
151
|
+
|
152
|
+
if (
|
153
|
+
visibleEntities !== VisibleEntities.All &&
|
154
|
+
nodesUptimeFilter !== NodesUptimeFilterValues.All
|
155
|
+
) {
|
156
|
+
message = i18n('empty.several_filters');
|
157
|
+
}
|
158
|
+
|
159
|
+
if (message) {
|
160
|
+
return <EmptyFilter title={message} showAll={i18n('show_all')} onShowAll={onShowAll} />;
|
161
|
+
}
|
144
162
|
}
|
145
163
|
|
146
164
|
return data ? (
|
@@ -1,6 +1,8 @@
|
|
1
1
|
{
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
"empty.default": "No such nodes",
|
3
|
+
"empty.out_of_space": "No nodes with out of space errors",
|
4
|
+
"empty.degraded": "No degraded nodes",
|
5
|
+
"empty.small_uptime": "No nodes with uptime < 1h",
|
6
|
+
"empty.several_filters": "No nodes match current filters combination",
|
7
|
+
"show_all": "Show all nodes"
|
6
8
|
}
|
@@ -1,6 +1,8 @@
|
|
1
1
|
{
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
"empty.default": "Нет узлов",
|
3
|
+
"empty.out_of_space": "Нет узлов, в которых кончается место",
|
4
|
+
"empty.degraded": "Нет деградировавших узлов",
|
5
|
+
"empty.small_uptime": "Нет узлов с uptime < 1h",
|
6
|
+
"empty.several_filters": "Нет узлов, подходящих под текущие фильтры",
|
7
|
+
"show_all": "Показать все узлы"
|
6
8
|
}
|
@@ -1,4 +1,6 @@
|
|
1
1
|
.usage-filter {
|
2
|
+
min-width: 100px;
|
3
|
+
|
2
4
|
&__option {
|
3
5
|
flex-grow: 1;
|
4
6
|
|
@@ -10,22 +12,25 @@
|
|
10
12
|
}
|
11
13
|
|
12
14
|
&-meta {
|
13
|
-
padding: 0 5px;
|
14
15
|
position: relative;
|
15
|
-
|
16
|
+
|
17
|
+
padding: 0 5px;
|
18
|
+
|
16
19
|
font-size: var(--yc-text-caption-2-font-size);
|
17
20
|
line-height: var(--yc-text-caption-2-line-height);
|
21
|
+
|
22
|
+
border-radius: 3px;
|
18
23
|
}
|
19
24
|
|
20
25
|
&-bar {
|
21
26
|
position: absolute;
|
22
|
-
|
27
|
+
z-index: -1;
|
23
28
|
top: 0;
|
24
29
|
bottom: 0;
|
25
|
-
|
30
|
+
left: 0;
|
26
31
|
|
27
|
-
background-color: var(--yc-color-infographics-info-medium);
|
28
32
|
border-radius: 3px;
|
33
|
+
background-color: var(--yc-color-infographics-info-medium);
|
29
34
|
}
|
30
35
|
}
|
31
36
|
}
|
@@ -83,13 +83,7 @@ class Acl extends React.Component {
|
|
83
83
|
return null;
|
84
84
|
}
|
85
85
|
|
86
|
-
return
|
87
|
-
<DataTable
|
88
|
-
columns={this.COLUMNS}
|
89
|
-
data={acl}
|
90
|
-
settings={TABLE_SETTINGS}
|
91
|
-
/>
|
92
|
-
);
|
86
|
+
return <DataTable columns={this.COLUMNS} data={acl} settings={TABLE_SETTINGS} />;
|
93
87
|
};
|
94
88
|
|
95
89
|
renderOwner = () => {
|
@@ -7,7 +7,7 @@ import qs from 'qs';
|
|
7
7
|
|
8
8
|
import {Loader} from '@gravity-ui/uikit';
|
9
9
|
|
10
|
-
import NodesViewer from '
|
10
|
+
import NodesViewer from '../../../NodesViewer/NodesViewer';
|
11
11
|
|
12
12
|
import {backend} from '../../../../store';
|
13
13
|
import {hideTooltip, showTooltip} from '../../../../store/reducers/tooltip';
|
@@ -1,13 +1,20 @@
|
|
1
|
-
import {useEffect, useState} from 'react';
|
1
|
+
import {useCallback, useEffect, useState} from 'react';
|
2
2
|
import {useDispatch} from 'react-redux';
|
3
3
|
import block from 'bem-cn-lite';
|
4
4
|
|
5
5
|
import DataTable, {Column} from '@yandex-cloud/react-data-table';
|
6
6
|
|
7
|
+
import { Loader } from '../../../../components/Loader';
|
8
|
+
import {prepareQueryError} from '../../../../utils/query';
|
7
9
|
import {DEFAULT_TABLE_SETTINGS} from '../../../../utils/constants';
|
8
10
|
import {useAutofetcher, useTypedSelector} from '../../../../utils/hooks';
|
9
11
|
import {Search} from '../../../../components/Search';
|
10
|
-
import {
|
12
|
+
import {
|
13
|
+
getDescribe,
|
14
|
+
selectConsumers,
|
15
|
+
setCurrentDescribePath,
|
16
|
+
setDataWasNotLoaded,
|
17
|
+
} from '../../../../store/reducers/describe';
|
11
18
|
|
12
19
|
import i18n from './i18n';
|
13
20
|
|
@@ -20,14 +27,25 @@ interface ConsumersProps {
|
|
20
27
|
}
|
21
28
|
|
22
29
|
export const Consumers = ({path}: ConsumersProps) => {
|
23
|
-
const
|
30
|
+
const dispatch = useDispatch();
|
31
|
+
|
32
|
+
const fetchData = useCallback(
|
33
|
+
(isBackground: boolean) => {
|
34
|
+
if (!isBackground) {
|
35
|
+
dispatch(setDataWasNotLoaded());
|
36
|
+
}
|
37
|
+
dispatch(setCurrentDescribePath(path));
|
38
|
+
dispatch(getDescribe({path}));
|
39
|
+
},
|
24
40
|
|
25
|
-
|
26
|
-
|
27
|
-
|
41
|
+
[path, dispatch],
|
42
|
+
);
|
43
|
+
|
44
|
+
const {autorefresh} = useTypedSelector((state) => state.schema);
|
28
45
|
|
29
|
-
useAutofetcher(fetchData, [
|
46
|
+
useAutofetcher(fetchData, [fetchData], autorefresh);
|
30
47
|
|
48
|
+
const {loading, wasLoaded, error} = useTypedSelector((state) => state.describe);
|
31
49
|
const consumers = useTypedSelector((state) => selectConsumers(state, path));
|
32
50
|
|
33
51
|
const [consumersToRender, setConsumersToRender] = useState(consumers);
|
@@ -59,8 +77,16 @@ export const Consumers = ({path}: ConsumersProps) => {
|
|
59
77
|
},
|
60
78
|
];
|
61
79
|
|
80
|
+
if (loading && !wasLoaded) {
|
81
|
+
return <Loader size="m" />;
|
82
|
+
}
|
83
|
+
|
84
|
+
if (!loading && error) {
|
85
|
+
return <div className={b('message', 'error')}>{prepareQueryError(error)}</div>;
|
86
|
+
}
|
87
|
+
|
62
88
|
if (consumers.length === 0) {
|
63
|
-
return <div>{i18n('noConsumersMessage')}</div>;
|
89
|
+
return <div className={b('message')}>{i18n('noConsumersMessage')}</div>;
|
64
90
|
}
|
65
91
|
|
66
92
|
return (
|
@@ -5,7 +5,7 @@ import cn from 'bem-cn-lite';
|
|
5
5
|
import JSONTree from 'react-json-inspector';
|
6
6
|
import 'react-json-inspector/json-inspector.css';
|
7
7
|
|
8
|
-
import {Loader} from '
|
8
|
+
import {Loader} from '../../../../components/Loader';
|
9
9
|
|
10
10
|
import {prepareQueryError} from '../../../../utils/query';
|
11
11
|
import {useAutofetcher, useTypedSelector} from '../../../../utils/hooks';
|
@@ -51,11 +51,7 @@ const Describe = ({tenant}: IDescribeProps) => {
|
|
51
51
|
useAutofetcher(fetchData, [fetchData], autorefresh);
|
52
52
|
|
53
53
|
if (loading && !wasLoaded) {
|
54
|
-
return
|
55
|
-
<div className={b('loader-container')}>
|
56
|
-
<Loader size="m" />
|
57
|
-
</div>
|
58
|
-
);
|
54
|
+
return <Loader size="m" />;
|
59
55
|
}
|
60
56
|
|
61
57
|
if (error) {
|