ydb-embedded-ui 3.2.2 → 3.3.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.
Files changed (118) 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/Consumers/Consumers.tsx +2 -1
  53. package/dist/containers/Tenant/Diagnostics/Diagnostics.scss +2 -2
  54. package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +3 -4
  55. package/dist/containers/Tenant/Diagnostics/OverloadedShards/OverloadedShards.tsx +1 -1
  56. package/dist/containers/Tenant/Diagnostics/Overview/ChangefeedInfo/ChangefeedInfo.tsx +69 -0
  57. package/dist/containers/Tenant/Diagnostics/Overview/ChangefeedInfo/index.ts +1 -0
  58. package/dist/containers/Tenant/Diagnostics/Overview/Overview.tsx +18 -16
  59. package/dist/containers/Tenant/Diagnostics/Overview/TopicInfo/TopicInfo.tsx +37 -0
  60. package/dist/containers/Tenant/Diagnostics/Overview/TopicInfo/index.ts +1 -0
  61. package/dist/containers/Tenant/Diagnostics/Overview/TopicStats/TopicStats.scss +30 -0
  62. package/dist/containers/Tenant/Diagnostics/Overview/TopicStats/TopicStats.tsx +94 -0
  63. package/dist/containers/Tenant/Diagnostics/Overview/TopicStats/i18n/en.json +3 -0
  64. package/dist/containers/Tenant/Diagnostics/Overview/TopicStats/i18n/index.ts +11 -0
  65. package/dist/containers/Tenant/Diagnostics/Overview/TopicStats/i18n/ru.json +3 -0
  66. package/dist/containers/Tenant/Diagnostics/Overview/TopicStats/index.ts +1 -0
  67. package/dist/containers/Tenant/Diagnostics/Overview/utils/index.ts +1 -0
  68. package/dist/containers/Tenant/Diagnostics/Overview/utils/prepareTopicSchemaInfo.ts +42 -0
  69. package/dist/containers/Tenant/utils/schema.ts +19 -0
  70. package/dist/containers/Tenants/Tenants.js +2 -1
  71. package/dist/containers/UserSettings/UserSettings.tsx +18 -10
  72. package/dist/services/api.d.ts +8 -1
  73. package/dist/services/api.js +27 -8
  74. package/dist/store/reducers/index.ts +3 -1
  75. package/dist/store/reducers/nodes.ts +148 -14
  76. package/dist/store/reducers/{clusterNodes.js → nodesList.js} +0 -41
  77. package/dist/store/reducers/settings.js +10 -4
  78. package/dist/store/reducers/storage.js +24 -13
  79. package/dist/store/reducers/tenant.js +5 -4
  80. package/dist/store/reducers/tooltip.ts +1 -1
  81. package/dist/store/reducers/topic.ts +52 -0
  82. package/dist/styles/mixins.scss +19 -11
  83. package/dist/types/api/common.ts +5 -0
  84. package/dist/types/api/compute.ts +1 -1
  85. package/dist/types/api/consumer.ts +12 -10
  86. package/dist/types/api/nodes.ts +2 -0
  87. package/dist/types/api/pdisk.ts +1 -0
  88. package/dist/types/api/schema.ts +3 -3
  89. package/dist/types/api/topic.ts +5 -4
  90. package/dist/types/api/vdisk.ts +2 -1
  91. package/dist/types/store/nodes.ts +56 -6
  92. package/dist/types/store/tooltip.ts +1 -1
  93. package/dist/types/store/topic.ts +21 -0
  94. package/dist/utils/constants.ts +5 -1
  95. package/dist/utils/i18n/i18n.ts +10 -2
  96. package/dist/utils/index.js +1 -1
  97. package/dist/utils/timeParsers/__test__/formatDuration.test.ts +50 -0
  98. package/dist/utils/timeParsers/__test__/protobuf.test.ts +74 -0
  99. package/dist/utils/timeParsers/formatDuration.ts +46 -0
  100. package/dist/utils/timeParsers/i18n/en.json +7 -0
  101. package/dist/utils/timeParsers/i18n/index.ts +11 -0
  102. package/dist/utils/timeParsers/i18n/ru.json +7 -0
  103. package/dist/utils/timeParsers/index.ts +2 -0
  104. package/dist/utils/timeParsers/protobuf.ts +36 -0
  105. package/package.json +1 -1
  106. package/dist/components/InfoViewer/schemaInfo/CDCStreamInfo.tsx +0 -48
  107. package/dist/components/InfoViewer/schemaInfo/PersQueueGroupInfo.tsx +0 -30
  108. package/dist/components/InternalLink/InternalLink.js +0 -23
  109. package/dist/containers/Nodes/Nodes.js +0 -213
  110. package/dist/containers/NodesViewer/NodesViewer.js +0 -163
  111. package/dist/containers/NodesViewer/NodesViewer.scss +0 -66
  112. package/dist/containers/Storage/Pdisk/Pdisk.tsx +0 -153
  113. package/dist/containers/Storage/Pdisk/__tests__/colors.tsx +0 -41
  114. package/dist/containers/Storage/Vdisk/Vdisk.js +0 -275
  115. package/dist/containers/Storage/Vdisk/Vdisk.scss +0 -22
  116. package/dist/containers/Storage/Vdisk/__tests__/colors.tsx +0 -163
  117. package/dist/containers/Tenant/Diagnostics/Compute/Compute.js +0 -139
  118. 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
- }