ydb-embedded-ui 3.2.3 → 3.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/components/InfoViewer/InfoViewer.scss +10 -0
  3. package/dist/components/InfoViewer/InfoViewer.tsx +12 -2
  4. package/dist/components/InfoViewer/formatters/cdcStream.ts +10 -0
  5. package/dist/components/InfoViewer/formatters/index.ts +3 -0
  6. package/dist/components/InfoViewer/formatters/pqGroup.ts +51 -0
  7. package/dist/components/InfoViewer/formatters/schema.ts +1 -29
  8. package/dist/components/InfoViewer/formatters/topicStats.tsx +50 -0
  9. package/dist/components/InfoViewer/schemaInfo/index.ts +0 -2
  10. package/dist/components/InfoViewer/utils.ts +15 -0
  11. package/dist/components/InternalLink/InternalLink.tsx +17 -0
  12. package/dist/components/InternalLink/index.ts +1 -0
  13. package/dist/components/Tablet/Tablet.js +1 -1
  14. package/dist/components/TabletsStatistic/TabletsStatistic.tsx +1 -1
  15. package/dist/components/VerticalBars/VerticalBars.scss +15 -0
  16. package/dist/components/VerticalBars/VerticalBars.tsx +38 -0
  17. package/dist/components/VerticalBars/index.ts +1 -0
  18. package/dist/containers/App/App.js +0 -11
  19. package/dist/containers/App/App.scss +0 -1
  20. package/dist/containers/Cluster/Cluster.tsx +2 -2
  21. package/dist/containers/Nodes/Nodes.scss +5 -1
  22. package/dist/containers/Nodes/Nodes.tsx +196 -0
  23. package/dist/containers/{App → Nodes}/NodesTable.scss +2 -2
  24. package/dist/{utils/getNodesColumns.js → containers/Nodes/getNodesColumns.tsx} +60 -35
  25. package/dist/containers/Nodes/i18n/en.json +3 -0
  26. package/dist/containers/Nodes/i18n/index.ts +11 -0
  27. package/dist/containers/Nodes/i18n/ru.json +3 -0
  28. package/dist/containers/Nodes/index.ts +1 -0
  29. package/dist/containers/Storage/DiskStateProgressBar/DiskStateProgressBar.scss +14 -20
  30. package/dist/containers/Storage/DiskStateProgressBar/DiskStateProgressBar.tsx +32 -16
  31. package/dist/containers/Storage/DiskStateProgressBar/index.ts +1 -0
  32. package/dist/containers/Storage/{Pdisk/Pdisk.scss → PDisk/PDisk.scss} +15 -4
  33. package/dist/containers/Storage/PDisk/PDisk.tsx +145 -0
  34. package/dist/containers/Storage/PDisk/__tests__/colors.tsx +37 -0
  35. package/dist/containers/Storage/PDisk/index.ts +1 -0
  36. package/dist/containers/Storage/PDiskPopup/PDiskPopup.scss +3 -0
  37. package/dist/containers/Storage/PDiskPopup/PDiskPopup.tsx +82 -0
  38. package/dist/containers/Storage/PDiskPopup/index.ts +1 -0
  39. package/dist/containers/Storage/Storage.js +1 -1
  40. package/dist/containers/Storage/StorageGroups/StorageGroups.tsx +10 -10
  41. package/dist/containers/Storage/StorageNodes/StorageNodes.scss +1 -0
  42. package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +7 -4
  43. package/dist/containers/Storage/VDisk/VDisk.scss +7 -0
  44. package/dist/containers/Storage/VDisk/VDisk.tsx +148 -0
  45. package/dist/containers/Storage/VDisk/__tests__/colors.tsx +209 -0
  46. package/dist/containers/Storage/VDisk/index.ts +1 -0
  47. package/dist/containers/Storage/VDiskPopup/VDiskPopup.scss +14 -0
  48. package/dist/containers/Storage/VDiskPopup/VDiskPopup.tsx +134 -0
  49. package/dist/containers/Storage/VDiskPopup/index.ts +1 -0
  50. package/dist/containers/Storage/utils/constants.ts +2 -9
  51. package/dist/containers/TabletsFilters/TabletsFilters.js +10 -6
  52. package/dist/containers/Tenant/Diagnostics/Diagnostics.scss +2 -2
  53. package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +3 -4
  54. package/dist/containers/Tenant/Diagnostics/OverloadedShards/OverloadedShards.tsx +1 -1
  55. package/dist/containers/Tenant/Diagnostics/Overview/ChangefeedInfo/ChangefeedInfo.tsx +69 -0
  56. package/dist/containers/Tenant/Diagnostics/Overview/ChangefeedInfo/index.ts +1 -0
  57. package/dist/containers/Tenant/Diagnostics/Overview/Overview.tsx +18 -16
  58. package/dist/containers/Tenant/Diagnostics/Overview/TopicInfo/TopicInfo.tsx +37 -0
  59. package/dist/containers/Tenant/Diagnostics/Overview/TopicInfo/index.ts +1 -0
  60. package/dist/containers/Tenant/Diagnostics/Overview/TopicStats/TopicStats.scss +30 -0
  61. package/dist/containers/Tenant/Diagnostics/Overview/TopicStats/TopicStats.tsx +94 -0
  62. package/dist/containers/Tenant/Diagnostics/Overview/TopicStats/i18n/en.json +3 -0
  63. package/dist/containers/Tenant/Diagnostics/Overview/TopicStats/i18n/index.ts +11 -0
  64. package/dist/containers/Tenant/Diagnostics/Overview/TopicStats/i18n/ru.json +3 -0
  65. package/dist/containers/Tenant/Diagnostics/Overview/TopicStats/index.ts +1 -0
  66. package/dist/containers/Tenant/Diagnostics/Overview/utils/index.ts +1 -0
  67. package/dist/containers/Tenant/Diagnostics/Overview/utils/prepareTopicSchemaInfo.ts +42 -0
  68. package/dist/containers/Tenant/utils/schema.ts +19 -0
  69. package/dist/containers/UserSettings/UserSettings.scss +9 -0
  70. package/dist/containers/UserSettings/UserSettings.tsx +41 -11
  71. package/dist/services/api.d.ts +8 -1
  72. package/dist/services/api.js +27 -8
  73. package/dist/store/reducers/index.ts +3 -1
  74. package/dist/store/reducers/nodes.ts +148 -14
  75. package/dist/store/reducers/{clusterNodes.js → nodesList.js} +0 -41
  76. package/dist/store/reducers/settings.js +10 -4
  77. package/dist/store/reducers/storage.js +24 -13
  78. package/dist/store/reducers/tenant.js +5 -4
  79. package/dist/store/reducers/tooltip.ts +1 -1
  80. package/dist/store/reducers/topic.ts +52 -0
  81. package/dist/styles/mixins.scss +19 -11
  82. package/dist/types/api/common.ts +5 -0
  83. package/dist/types/api/compute.ts +1 -1
  84. package/dist/types/api/consumer.ts +12 -10
  85. package/dist/types/api/nodes.ts +2 -0
  86. package/dist/types/api/pdisk.ts +1 -0
  87. package/dist/types/api/schema.ts +3 -3
  88. package/dist/types/api/topic.ts +5 -4
  89. package/dist/types/api/vdisk.ts +2 -1
  90. package/dist/types/store/nodes.ts +56 -6
  91. package/dist/types/store/tooltip.ts +1 -1
  92. package/dist/types/store/topic.ts +21 -0
  93. package/dist/utils/constants.ts +5 -1
  94. package/dist/utils/i18n/i18n.ts +10 -2
  95. package/dist/utils/index.js +1 -1
  96. package/dist/utils/timeParsers/__test__/formatDuration.test.ts +50 -0
  97. package/dist/utils/timeParsers/__test__/protobuf.test.ts +74 -0
  98. package/dist/utils/timeParsers/formatDuration.ts +46 -0
  99. package/dist/utils/timeParsers/i18n/en.json +7 -0
  100. package/dist/utils/timeParsers/i18n/index.ts +11 -0
  101. package/dist/utils/timeParsers/i18n/ru.json +7 -0
  102. package/dist/utils/timeParsers/index.ts +2 -0
  103. package/dist/utils/timeParsers/protobuf.ts +36 -0
  104. package/package.json +1 -1
  105. package/dist/components/InfoViewer/schemaInfo/CDCStreamInfo.tsx +0 -48
  106. package/dist/components/InfoViewer/schemaInfo/PersQueueGroupInfo.tsx +0 -30
  107. package/dist/components/InternalLink/InternalLink.js +0 -23
  108. package/dist/containers/Nodes/Nodes.js +0 -214
  109. package/dist/containers/NodesViewer/NodesViewer.js +0 -163
  110. package/dist/containers/NodesViewer/NodesViewer.scss +0 -66
  111. package/dist/containers/Storage/Pdisk/Pdisk.tsx +0 -153
  112. package/dist/containers/Storage/Pdisk/__tests__/colors.tsx +0 -41
  113. package/dist/containers/Storage/Vdisk/Vdisk.js +0 -275
  114. package/dist/containers/Storage/Vdisk/Vdisk.scss +0 -22
  115. package/dist/containers/Storage/Vdisk/__tests__/colors.tsx +0 -163
  116. package/dist/containers/Tenant/Diagnostics/Compute/Compute.js +0 -139
  117. package/dist/containers/Tenant/Diagnostics/Compute/Compute.scss +0 -14
@@ -1,275 +0,0 @@
1
- import React, {useEffect, useState, useRef, useMemo} from 'react';
2
- import PropTypes from 'prop-types';
3
- import cn from 'bem-cn-lite';
4
-
5
- import {Label, Popup} from '@gravity-ui/uikit';
6
-
7
- import InternalLink from '../../../components/InternalLink/InternalLink';
8
- import {InfoViewer} from '../../../components/InfoViewer';
9
-
10
- import routes, {createHref} from '../../../routes';
11
- import {stringifyVdiskId, getPDiskId} from '../../../utils';
12
- import {getPDiskType} from '../../../utils/pdisk';
13
- import {bytesToGB, bytesToSpeed} from '../../../utils/utils';
14
-
15
- import {STRUCTURE} from '../../Node/NodePages';
16
-
17
- import DiskStateProgressBar, {
18
- diskProgressColors,
19
- } from '../DiskStateProgressBar/DiskStateProgressBar';
20
-
21
- import {colorSeverity, NOT_AVAILABLE_SEVERITY} from '../utils';
22
-
23
- import './Vdisk.scss';
24
-
25
- const b = cn('vdisk-storage');
26
-
27
- const propTypes = {
28
- SatisfactionRank: PropTypes.object,
29
- VDiskState: PropTypes.string,
30
- DiskSpace: PropTypes.string,
31
- FrontQueues: PropTypes.string,
32
- Replicated: PropTypes.bool,
33
- PoolName: PropTypes.string,
34
- VDiskId: PropTypes.object,
35
- DonorMode: PropTypes.bool,
36
- nodes: PropTypes.object,
37
- };
38
-
39
- const stateSeverity = {
40
- Initial: 3,
41
- LocalRecoveryError: 5,
42
- SyncGuidRecoveryError: 5,
43
- SyncGuidRecovery: 3,
44
- PDiskError: 5,
45
- OK: 1,
46
- };
47
-
48
- const getStateSeverity = (vDiskState) => {
49
- return stateSeverity[vDiskState] ?? NOT_AVAILABLE_SEVERITY;
50
- };
51
-
52
- const getColorSeverity = (color) => {
53
- return colorSeverity[color] ?? colorSeverity.Grey;
54
- };
55
-
56
- function Vdisk(props) {
57
- const [severity, setSeverity] = useState(getStateSeverity(props.VDiskState));
58
- const [isPopupVisible, setIsPopupVisible] = useState(false);
59
-
60
- const anchor = useRef();
61
-
62
- // determine disk status severity
63
- useEffect(() => {
64
- const {DiskSpace, VDiskState, FrontQueues, Replicated, DonorMode} = props;
65
-
66
- // if the disk is not available, this determines its status severity regardless of other features
67
- if (!VDiskState) {
68
- setSeverity(NOT_AVAILABLE_SEVERITY);
69
- return;
70
- }
71
-
72
- const DiskSpaceSeverity = getColorSeverity(DiskSpace);
73
- const VDiskSpaceSeverity = getStateSeverity(VDiskState);
74
- const FrontQueuesSeverity = Math.min(colorSeverity.Orange, getColorSeverity(FrontQueues));
75
-
76
- let newSeverity = Math.max(DiskSpaceSeverity, VDiskSpaceSeverity, FrontQueuesSeverity);
77
-
78
- // donors are always in the not replicated state since they are leftovers
79
- // painting them blue is useless
80
- if (!Replicated && !DonorMode && newSeverity === colorSeverity.Green) {
81
- newSeverity = colorSeverity.Blue;
82
- }
83
-
84
- setSeverity(newSeverity);
85
- }, [props.VDiskState, props.DiskSpace, props.FrontQueues, props.Replicated]);
86
-
87
- const showPopup = () => {
88
- setIsPopupVisible(true);
89
- };
90
-
91
- const hidePopup = () => {
92
- setIsPopupVisible(false);
93
- };
94
- /* eslint-disable */
95
- const prepareVdiskData = () => {
96
- const {
97
- VDiskId,
98
- VDiskState,
99
- PoolName,
100
- SatisfactionRank,
101
- DiskSpace,
102
- FrontQueues,
103
- Replicated,
104
- UnsyncedVDisks,
105
- AllocatedSize,
106
- ReadThroughput,
107
- WriteThroughput,
108
- } = props;
109
- const vdiskData = [{label: 'VDisk', value: stringifyVdiskId(VDiskId)}];
110
- vdiskData.push({label: 'State', value: VDiskState ?? 'not available'});
111
- PoolName && vdiskData.push({label: 'StoragePool', value: PoolName});
112
-
113
- SatisfactionRank &&
114
- SatisfactionRank.FreshRank?.Flag !== diskProgressColors[colorSeverity.Green] &&
115
- vdiskData.push({
116
- label: 'Fresh',
117
- value: SatisfactionRank.FreshRank.Flag,
118
- });
119
-
120
- SatisfactionRank &&
121
- SatisfactionRank.LevelRank?.Flag !== diskProgressColors[colorSeverity.Green] &&
122
- vdiskData.push({
123
- label: 'Level',
124
- value: SatisfactionRank.LevelRank.Flag,
125
- });
126
-
127
- SatisfactionRank &&
128
- SatisfactionRank.FreshRank?.RankPercent &&
129
- vdiskData.push({
130
- label: 'Fresh',
131
- value: SatisfactionRank.FreshRank.RankPercent,
132
- });
133
-
134
- SatisfactionRank &&
135
- SatisfactionRank.LevelRank?.RankPercent &&
136
- vdiskData.push({
137
- label: 'Level',
138
- value: SatisfactionRank.LevelRank.RankPercent,
139
- });
140
-
141
- DiskSpace &&
142
- DiskSpace !== diskProgressColors[colorSeverity.Green] &&
143
- vdiskData.push({label: 'Space', value: DiskSpace});
144
-
145
- FrontQueues &&
146
- FrontQueues !== diskProgressColors[colorSeverity.Green] &&
147
- vdiskData.push({label: 'FrontQueues', value: FrontQueues});
148
-
149
- !Replicated && vdiskData.push({label: 'Replicated', value: 'NO'});
150
-
151
- UnsyncedVDisks && vdiskData.push({label: 'UnsyncVDisks', value: UnsyncedVDisks});
152
-
153
- Boolean(Number(AllocatedSize)) &&
154
- vdiskData.push({
155
- label: 'Allocated',
156
- value: bytesToGB(AllocatedSize),
157
- });
158
-
159
- Boolean(Number(ReadThroughput)) &&
160
- vdiskData.push({label: 'Read', value: bytesToSpeed(ReadThroughput)});
161
-
162
- Boolean(Number(WriteThroughput)) &&
163
- vdiskData.push({
164
- label: 'Write',
165
- value: bytesToSpeed(WriteThroughput),
166
- });
167
-
168
- return vdiskData;
169
- };
170
-
171
- const preparePdiskData = () => {
172
- const {PDisk, nodes} = props;
173
- const errorColors = [
174
- diskProgressColors[colorSeverity.Orange],
175
- diskProgressColors[colorSeverity.Red],
176
- diskProgressColors[colorSeverity.Yellow],
177
- ];
178
- if (PDisk && nodes) {
179
- const pdiskData = [{label: 'PDisk', value: getPDiskId(PDisk)}];
180
- pdiskData.push({
181
- label: 'State',
182
- value: PDisk.State || 'not available',
183
- });
184
- pdiskData.push({label: 'Type', value: getPDiskType(PDisk) || 'unknown'});
185
- PDisk.NodeId && pdiskData.push({label: 'Node Id', value: PDisk.NodeId});
186
- PDisk.NodeId &&
187
- nodes[PDisk.NodeId] &&
188
- pdiskData.push({label: 'Host', value: nodes[PDisk.NodeId]});
189
- PDisk.Path && pdiskData.push({label: 'Path', value: PDisk.Path});
190
- pdiskData.push({
191
- label: 'Available',
192
- value: `${bytesToGB(PDisk.AvailableSize)} of ${bytesToGB(PDisk.TotalSize)}`,
193
- });
194
- errorColors.includes(PDisk.Realtime) &&
195
- pdiskData.push({label: 'Realtime', value: PDisk.Realtime});
196
- errorColors.includes(PDisk.Device) &&
197
- pdiskData.push({label: 'Device', value: PDisk.Device});
198
- return pdiskData;
199
- }
200
- return null;
201
- };
202
- /* eslint-enable */
203
-
204
- const renderPopup = () => (
205
- <Popup
206
- className={b('popup-wrapper')}
207
- anchorRef={anchor}
208
- open={isPopupVisible}
209
- placement={['top', 'bottom']}
210
- // bigger offset for easier switching to neighbour nodes
211
- // matches the default offset for popup with arrow out of a sense of beauty
212
- offset={[0, 12]}
213
- >
214
- {props.DonorMode && <Label className={b('donor-label')}>Donor</Label>}
215
- <InfoViewer
216
- title="VDisk"
217
- info={prepareVdiskData()}
218
- size="s"
219
- />
220
- <InfoViewer
221
- title="PDisk"
222
- info={preparePdiskData()}
223
- size="s"
224
- />
225
- </Popup>
226
- );
227
-
228
- const vdiskAllocatedPercent = useMemo(() => {
229
- const {AvailableSize, AllocatedSize, PDisk} = props;
230
- const available = AvailableSize ? AvailableSize : PDisk?.AvailableSize;
231
-
232
- if (!available) {
233
- return undefined;
234
- }
235
-
236
- return isNaN(Number(AllocatedSize))
237
- ? undefined
238
- : (Number(AllocatedSize) * 100) / (Number(available) + Number(AllocatedSize));
239
- }, [props.AllocatedSize, props.AvailableSize, props.PDisk?.AvailableSize]);
240
-
241
- return (
242
- <React.Fragment>
243
- {renderPopup()}
244
- <div className={b()} ref={anchor} onMouseEnter={showPopup} onMouseLeave={hidePopup}>
245
- {props.NodeId ? (
246
- <InternalLink
247
- to={createHref(
248
- routes.node,
249
- {id: props.NodeId, activeTab: STRUCTURE},
250
- {
251
- pdiskId: props.PDisk?.PDiskId,
252
- vdiskId: stringifyVdiskId(props.VDiskId),
253
- },
254
- )}
255
- className={b('content')}
256
- >
257
- <DiskStateProgressBar
258
- diskAllocatedPercent={vdiskAllocatedPercent}
259
- severity={severity}
260
- />
261
- </InternalLink>
262
- ) : (
263
- <DiskStateProgressBar
264
- diskAllocatedPercent={vdiskAllocatedPercent}
265
- severity={severity}
266
- />
267
- )}
268
- </div>
269
- </React.Fragment>
270
- );
271
- }
272
-
273
- Vdisk.propTypes = propTypes;
274
-
275
- export default Vdisk;
@@ -1,22 +0,0 @@
1
- .vdisk-storage {
2
- border-radius: 4px; // to match interactive area with disk shape
3
-
4
- &__content {
5
- border-radius: 4px; // to match interactive area with disk shape
6
- }
7
-
8
- &__popup-wrapper {
9
- padding: 12px;
10
-
11
- .info-viewer + .info-viewer {
12
- margin-top: 8px;
13
- padding-top: 8px;
14
-
15
- border-top: 1px solid var(--yc-color-line-generic);
16
- }
17
- }
18
-
19
- &__donor-label {
20
- margin-bottom: 8px;
21
- }
22
- }
@@ -1,163 +0,0 @@
1
- import {renderWithStore} from '../../../../utils/tests/providers';
2
-
3
- import VDisk from '../Vdisk'
4
-
5
- describe('VDisk state', () => {
6
- it('Should determine severity based on the highest value among VDiskState, DiskSpace and FrontQueues', () => {
7
- const {getAllByRole} = renderWithStore(
8
- <>
9
- <VDisk
10
- VDiskId={{Domain: 1}}
11
- VDiskState="OK" // severity 1, green
12
- DiskSpace="Yellow" // severity 3, yellow
13
- FrontQueues="Green" // severity 1, green
14
- />
15
- <VDisk
16
- VDiskId={{Domain: 2}}
17
- VDiskState="PDiskError" // severity 5, red
18
- DiskSpace="Yellow" // severity 3, yellow
19
- FrontQueues="Green" // severity 1, green
20
- />
21
- <VDisk
22
- VDiskId={{Domain: 3}}
23
- VDiskState="OK" // severity 1, green
24
- DiskSpace="Yellow" // severity 3, yellow
25
- FrontQueues="Orange" // severity 4, orange
26
- />
27
- </>
28
- );
29
-
30
- const [disk1, disk2, disk3] = getAllByRole('meter');
31
-
32
- expect(disk1.className).toMatch(/_yellow\b/i);
33
- expect(disk2.className).toMatch(/_red\b/i);
34
- expect(disk3.className).toMatch(/_orange\b/i);
35
- });
36
-
37
- it('Should not pick the highest severity based on FrontQueues value', () => {
38
- const {getAllByRole} = renderWithStore(
39
- <>
40
- <VDisk
41
- VDiskId={{Domain: 1}}
42
- VDiskState="OK" // severity 1, green
43
- DiskSpace="Green" // severity 1, green
44
- FrontQueues="Red" // severity 5, red
45
- />
46
- <VDisk
47
- VDiskId={{Domain: 2}}
48
- VDiskState="OK" // severity 1, green
49
- DiskSpace="Red" // severity 5, red
50
- FrontQueues="Red" // severity 5, red
51
- />
52
- </>
53
- );
54
-
55
- const [disk1, disk2] = getAllByRole('meter');
56
-
57
- expect(disk1.className).not.toMatch(/_red\b/i);
58
- expect(disk2.className).toMatch(/_red\b/i);
59
- });
60
-
61
- it('Should display as unavailable when no VDiskState is provided', () => {
62
- const {getAllByRole} = renderWithStore(
63
- <>
64
- <VDisk VDiskId={{Domain: 1}} />
65
- <VDisk VDiskId={{Domain: 2}} VDiskState="OK" />
66
- <VDisk VDiskId={{Domain: 3}} DiskSpace="Green" />
67
- <VDisk VDiskId={{Domain: 4}} FrontQueues="Green" />
68
- <VDisk VDiskId={{Domain: 5}} VDiskState="OK" DiskSpace="Green" />
69
- <VDisk VDiskId={{Domain: 6}} VDiskState="OK" FrontQueues="Green" />
70
- <VDisk VDiskId={{Domain: 7}} DiskSpace="Green" FrontQueues="Green" />
71
- <VDisk VDiskId={{Domain: 8}} VDiskState="OK" DiskSpace="Green" FrontQueues="Green" />
72
- </>
73
- );
74
-
75
- const [disk1, disk2, disk3, disk4, disk5, disk6, disk7, disk8] = getAllByRole('meter');
76
-
77
- // unavailable disks display with the highest severity
78
- expect(disk1.className).toMatch(/_red\b/i);
79
- expect(disk2.className).not.toMatch(/_red\b/i);
80
- expect(disk3.className).toMatch(/_red\b/i);
81
- expect(disk4.className).toMatch(/_red\b/i);
82
- expect(disk5.className).not.toMatch(/_red\b/i);
83
- expect(disk6.className).not.toMatch(/_red\b/i);
84
- expect(disk7.className).toMatch(/_red\b/i);
85
- expect(disk8.className).not.toMatch(/_red\b/i);
86
- });
87
-
88
- it('Should display replicating VDisks in OK state with a distinct color', () => {
89
- const {getAllByRole} = renderWithStore(
90
- <>
91
- <VDisk
92
- VDiskId={{Domain: 1}}
93
- VDiskState="OK" // severity 1, green
94
- Replicated={false}
95
- />
96
- <VDisk
97
- VDiskId={{Domain: 2}}
98
- VDiskState="OK" // severity 1, green
99
- Replicated={true}
100
- />
101
- </>
102
- );
103
-
104
- const [disk1, disk2] = getAllByRole('meter');
105
-
106
- expect(disk1.className).toMatch(/_blue\b/i);
107
- expect(disk2.className).not.toMatch(/_blue\b/i);
108
- });
109
-
110
- it('Should display replicating VDisks in a not-OK state with a regular color', () => {
111
- const {getAllByRole} = renderWithStore(
112
- <>
113
- <VDisk
114
- VDiskId={{Domain: 1}}
115
- VDiskState="Initial" // severity 3, yellow
116
- Replicated={false}
117
- />
118
- <VDisk
119
- VDiskId={{Domain: 2}}
120
- VDiskState="PDiskError" // severity 5, red
121
- Replicated={false}
122
- />
123
- </>
124
- );
125
-
126
- const [disk1, disk2] = getAllByRole('meter');
127
-
128
- expect(disk1.className).toMatch(/_yellow\b/i);
129
- expect(disk2.className).toMatch(/_red\b/i);
130
- });
131
-
132
- it('Should always display donor VDisks with a regular color', () => {
133
- const {getAllByRole} = renderWithStore(
134
- <>
135
- <VDisk
136
- VDiskId={{Domain: 1}}
137
- VDiskState="OK" // severity 1, green
138
- Replicated={false} // donors are always in the not replicated state since they are leftovers
139
- DonorMode
140
- />
141
- <VDisk
142
- VDiskId={{Domain: 2}}
143
- VDiskState="Initial" // severity 3, yellow
144
- Replicated={false}
145
- DonorMode
146
- />
147
- <VDisk
148
- VDiskId={{Domain: 3}}
149
- VDiskState="PDiskError" // severity 5, red
150
- Replicated={false}
151
- DonorMode
152
- />
153
- </>
154
- );
155
-
156
- const [disk1, disk2, disk3] = getAllByRole('meter');
157
-
158
- expect(disk1.className).not.toMatch(/_blue\b/i);
159
- expect(disk1.className).toMatch(/_green\b/i);
160
- expect(disk2.className).toMatch(/_yellow\b/i);
161
- expect(disk3.className).toMatch(/_red\b/i);
162
- });
163
- });
@@ -1,139 +0,0 @@
1
- import React from 'react';
2
- import cn from 'bem-cn-lite';
3
- import PropTypes from 'prop-types';
4
- import {connect} from 'react-redux';
5
-
6
- import {Loader} from '@gravity-ui/uikit';
7
-
8
- import NodesViewer from '../../../NodesViewer/NodesViewer';
9
-
10
- import {backend} from '../../../../store';
11
- import {hideTooltip, showTooltip} from '../../../../store/reducers/tooltip';
12
- import {getNodes, clearNodes, setDataWasNotLoaded} from '../../../../store/reducers/nodes';
13
-
14
- import './Compute.scss';
15
- import {AutoFetcher} from '../../../../utils/autofetcher';
16
-
17
- const b = cn('compute');
18
-
19
- class Compute extends React.Component {
20
- static propTypes = {
21
- className: PropTypes.string,
22
- clearNodes: PropTypes.func,
23
- tenantName: PropTypes.string,
24
- nodes: PropTypes.object,
25
- loading: PropTypes.bool,
26
- autorefresh: PropTypes.bool,
27
- error: PropTypes.object,
28
- wasLoaded: PropTypes.bool,
29
- setDataWasNotLoaded: PropTypes.func,
30
- getNodes: PropTypes.func,
31
- hideTooltip: PropTypes.func,
32
- showTooltip: PropTypes.func,
33
- };
34
-
35
- autofetcher;
36
-
37
- componentDidMount() {
38
- const {getNodes, tenantName, autorefresh} = this.props;
39
-
40
- this.autofetcher = new AutoFetcher();
41
-
42
- if (tenantName) {
43
- getNodes(tenantName);
44
- if (autorefresh) {
45
- this.autofetcher.start();
46
- this.autofetcher.fetch(() => getNodes(tenantName));
47
- }
48
- }
49
- }
50
-
51
- componentDidUpdate(prevProps) {
52
- const {autorefresh, getNodes, setDataWasNotLoaded, tenantName} = this.props;
53
-
54
- const restartAutorefresh = () => {
55
- this.autofetcher.stop();
56
- this.autofetcher.start();
57
- this.autofetcher.fetch(() => getNodes(tenantName));
58
- };
59
-
60
- if (tenantName !== prevProps.tenantName) {
61
- setDataWasNotLoaded();
62
- getNodes(tenantName);
63
- if (autorefresh) {
64
- restartAutorefresh();
65
- }
66
- }
67
-
68
- if (autorefresh && !prevProps.autorefresh) {
69
- getNodes(tenantName);
70
- restartAutorefresh();
71
- }
72
- if (!autorefresh && prevProps.autorefresh) {
73
- this.autofetcher.stop();
74
- }
75
- }
76
-
77
- componentWillUnmount() {
78
- this.props.clearNodes();
79
- this.autofetcher.stop();
80
- }
81
-
82
- renderLoader() {
83
- return (
84
- <div className={b('loader')}>
85
- <Loader size="m" />
86
- </div>
87
- );
88
- }
89
-
90
- render() {
91
- const {nodes, error, tenantName, wasLoaded, loading} = this.props;
92
- if (!tenantName) {
93
- return <div className="error">no tenant name in the query string</div>;
94
- } else if (loading && !wasLoaded) {
95
- return this.renderLoader();
96
- } else if (error) {
97
- return <div>{error.statusText}</div>;
98
- } else {
99
- return (
100
- <div className={b()}>
101
- <NodesViewer
102
- backend={backend}
103
- nodes={nodes}
104
- path={tenantName}
105
- hideTooltip={this.props.hideTooltip}
106
- showTooltip={this.props.showTooltip}
107
- additionalNodesInfo={this.props.additionalNodesInfo}
108
- />
109
- </div>
110
- );
111
- }
112
- }
113
- }
114
-
115
- function mapStateToProps(state, ownProps) {
116
- const {data, loading, wasLoaded, error} = state.nodes;
117
- const {autorefresh} = state.schema;
118
- const nodes = (data && data.Tenants && data.Tenants[0] && data.Tenants[0].Nodes) || [];
119
- return {
120
- ...ownProps,
121
- nodes,
122
- loading,
123
- wasLoaded,
124
- error,
125
- autorefresh,
126
- };
127
- }
128
-
129
- const mapDispatchToProps = {
130
- getNodes,
131
- clearNodes,
132
- hideTooltip,
133
- showTooltip,
134
- setDataWasNotLoaded,
135
- };
136
-
137
- const ConnectedCompute = connect(mapStateToProps, mapDispatchToProps)(Compute);
138
-
139
- export default ConnectedCompute;
@@ -1,14 +0,0 @@
1
- @import '../../../../styles/mixins.scss';
2
-
3
- .compute {
4
- overflow: auto;
5
-
6
- height: 100%;
7
- max-height: 100%;
8
- @include flex-container();
9
-
10
- &__loader {
11
- display: flex;
12
- justify-content: center;
13
- }
14
- }