ydb-embedded-ui 1.11.1 → 1.12.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 +8 -0
- package/dist/containers/Storage/StorageGroups/StorageGroups.scss +6 -0
- package/dist/containers/Storage/StorageGroups/StorageGroups.tsx +34 -25
- package/dist/containers/Storage/utils/index.ts +44 -0
- package/dist/services/api.d.ts +9 -0
- package/dist/types/api/storage.ts +46 -0
- package/dist/types/store/storage.ts +11 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [1.12.0](https://github.com/ydb-platform/ydb-embedded-ui/compare/v1.11.1...v1.12.0) (2022-08-26)
|
4
|
+
|
5
|
+
|
6
|
+
### Features
|
7
|
+
|
8
|
+
* **Storage:** show usage column ([73aed5f](https://github.com/ydb-platform/ydb-embedded-ui/commit/73aed5f9ed60b6d2bd77fd315ae514ee7443c489))
|
9
|
+
* **Storage:** vividly show degraded disks count ([7315a9c](https://github.com/ydb-platform/ydb-embedded-ui/commit/7315a9cfd98002a7fab85d721712aa82c6dbb552))
|
10
|
+
|
3
11
|
## [1.11.1](https://github.com/ydb-platform/ydb-embedded-ui/compare/v1.11.0...v1.11.1) (2022-08-26)
|
4
12
|
|
5
13
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import _ from 'lodash';
|
2
2
|
import cn from 'bem-cn-lite';
|
3
3
|
import DataTable, {Column, Settings, SortOrder} from '@yandex-cloud/react-data-table';
|
4
|
-
import {Popover, PopoverBehavior} from '@yandex-cloud/uikit';
|
4
|
+
import {Label, Popover, PopoverBehavior} from '@yandex-cloud/uikit';
|
5
5
|
|
6
6
|
import {Stack} from '../../../components/Stack/Stack';
|
7
7
|
//@ts-ignore
|
@@ -16,7 +16,7 @@ import {bytesToGB, bytesToSpeed} from '../../../utils/utils';
|
|
16
16
|
import {stringifyVdiskId} from '../../../utils';
|
17
17
|
|
18
18
|
import Vdisk from '../Vdisk/Vdisk';
|
19
|
-
import {isFullDonorData} from '../utils';
|
19
|
+
import {isFullDonorData, getDegradedSeverity, getUsageSeverity, getUsage} from '../utils';
|
20
20
|
|
21
21
|
import './StorageGroups.scss';
|
22
22
|
|
@@ -49,11 +49,11 @@ const tableColumnsNames: Record<TableColumnsIdsValues, string> = {
|
|
49
49
|
Used: 'Used',
|
50
50
|
Limit: 'Limit',
|
51
51
|
UsedSpaceFlag: 'Space',
|
52
|
-
UsedPercents: '
|
52
|
+
UsedPercents: 'Usage',
|
53
53
|
Read: 'Read',
|
54
54
|
Write: 'Write',
|
55
55
|
VDisks: 'VDisks',
|
56
|
-
Missing: '
|
56
|
+
Missing: 'Degraded',
|
57
57
|
};
|
58
58
|
|
59
59
|
const b = cn('global-storage-groups');
|
@@ -62,8 +62,8 @@ function setSortOrder(visibleEntities: keyof typeof VisibleEntities): SortOrder
|
|
62
62
|
switch (visibleEntities) {
|
63
63
|
case VisibleEntities.All: {
|
64
64
|
return {
|
65
|
-
columnId: TableColumnsIds.
|
66
|
-
order: DataTable.
|
65
|
+
columnId: TableColumnsIds.Missing,
|
66
|
+
order: DataTable.DESCENDING,
|
67
67
|
};
|
68
68
|
}
|
69
69
|
case VisibleEntities.Missing: {
|
@@ -110,6 +110,34 @@ function StorageGroups({data, tableSettings, visibleEntities, nodes}: StorageGro
|
|
110
110
|
},
|
111
111
|
align: DataTable.LEFT,
|
112
112
|
},
|
113
|
+
{
|
114
|
+
name: TableColumnsIds.Missing,
|
115
|
+
header: tableColumnsNames[TableColumnsIds.Missing],
|
116
|
+
width: 100,
|
117
|
+
render: ({value, row}) => value ? (
|
118
|
+
<Label theme={getDegradedSeverity(row)}>Degraded: {value}</Label>
|
119
|
+
) : '-',
|
120
|
+
align: DataTable.LEFT,
|
121
|
+
defaultOrder: DataTable.DESCENDING,
|
122
|
+
},
|
123
|
+
{
|
124
|
+
name: TableColumnsIds.UsedPercents,
|
125
|
+
header: tableColumnsNames[TableColumnsIds.UsedPercents],
|
126
|
+
width: 100,
|
127
|
+
render: ({row}) => {
|
128
|
+
const usage = getUsage(row, 5);
|
129
|
+
return (
|
130
|
+
<Label
|
131
|
+
theme={getUsageSeverity(usage)}
|
132
|
+
className={b('usage-label', {overload: usage >= 100})}
|
133
|
+
>
|
134
|
+
≥ {usage}%
|
135
|
+
</Label>
|
136
|
+
);
|
137
|
+
},
|
138
|
+
sortAccessor: getUsage,
|
139
|
+
align: DataTable.LEFT,
|
140
|
+
},
|
113
141
|
{
|
114
142
|
name: TableColumnsIds.GroupID,
|
115
143
|
header: tableColumnsNames[TableColumnsIds.GroupID],
|
@@ -137,18 +165,6 @@ function StorageGroups({data, tableSettings, visibleEntities, nodes}: StorageGro
|
|
137
165
|
},
|
138
166
|
align: DataTable.RIGHT,
|
139
167
|
},
|
140
|
-
// {
|
141
|
-
// name: tableColumnsIds.UsedPercents,
|
142
|
-
// header: tableColumnsNames[tableColumnsIds.UsedPercents],
|
143
|
-
// width: '100px',
|
144
|
-
// render: ({row}) => {
|
145
|
-
// return (
|
146
|
-
// Math.round((row[tableColumnsIds.Used] * 100) / row[tableColumnsIds.Limit]) +
|
147
|
-
// '%'
|
148
|
-
// );
|
149
|
-
// },
|
150
|
-
// align: DataTable.RIGHT,
|
151
|
-
// },
|
152
168
|
{
|
153
169
|
name: TableColumnsIds.UsedSpaceFlag,
|
154
170
|
header: tableColumnsNames[TableColumnsIds.UsedSpaceFlag],
|
@@ -186,13 +202,6 @@ function StorageGroups({data, tableSettings, visibleEntities, nodes}: StorageGro
|
|
186
202
|
},
|
187
203
|
align: DataTable.RIGHT,
|
188
204
|
},
|
189
|
-
{
|
190
|
-
name: TableColumnsIds.Missing,
|
191
|
-
header: tableColumnsNames[TableColumnsIds.Missing],
|
192
|
-
width: 100,
|
193
|
-
align: DataTable.CENTER,
|
194
|
-
defaultOrder: DataTable.DESCENDING,
|
195
|
-
},
|
196
205
|
{
|
197
206
|
name: TableColumnsIds.VDisks,
|
198
207
|
className: b('vdisks-column'),
|
@@ -1,6 +1,50 @@
|
|
1
1
|
import type {TVDiskStateInfo, TVSlotId} from '../../../types/api/storage';
|
2
|
+
import type {IStoragePoolGroup} from '../../../types/store/storage';
|
2
3
|
|
3
4
|
export * from './constants';
|
4
5
|
|
5
6
|
export const isFullDonorData = (donor: TVDiskStateInfo | TVSlotId): donor is TVDiskStateInfo =>
|
6
7
|
'VDiskId' in donor;
|
8
|
+
|
9
|
+
const generateEvaluator = (warn: number, crit: number) =>
|
10
|
+
(value: number) => {
|
11
|
+
if (0 <= value && value < warn) {
|
12
|
+
return 'success';
|
13
|
+
}
|
14
|
+
|
15
|
+
if (warn <= value && value < crit) {
|
16
|
+
return 'warning';
|
17
|
+
}
|
18
|
+
|
19
|
+
if (crit <= value) {
|
20
|
+
return 'danger';
|
21
|
+
}
|
22
|
+
|
23
|
+
return undefined;
|
24
|
+
};
|
25
|
+
|
26
|
+
const defaultDegradationEvaluator = generateEvaluator(1, 2);
|
27
|
+
|
28
|
+
const degradationEvaluators = {
|
29
|
+
'block-4-2': generateEvaluator(1, 2),
|
30
|
+
'mirror-3-dc': generateEvaluator(1, 3),
|
31
|
+
};
|
32
|
+
|
33
|
+
const canEvaluateErasureSpecies = (value?: string): value is keyof typeof degradationEvaluators =>
|
34
|
+
value !== undefined && value in degradationEvaluators;
|
35
|
+
|
36
|
+
export const getDegradedSeverity = (group: IStoragePoolGroup) => {
|
37
|
+
const evaluate = canEvaluateErasureSpecies(group.ErasureSpecies) ?
|
38
|
+
degradationEvaluators[group.ErasureSpecies] :
|
39
|
+
defaultDegradationEvaluator;
|
40
|
+
|
41
|
+
return evaluate(group.Missing);
|
42
|
+
};
|
43
|
+
|
44
|
+
export const getUsageSeverity = generateEvaluator(80, 85);
|
45
|
+
|
46
|
+
export const getUsage = (data: IStoragePoolGroup, step = 1) => {
|
47
|
+
const usage = Math.round((data.Used * 100) / data.Limit);
|
48
|
+
|
49
|
+
return Math.floor(usage / step) * step;
|
50
|
+
};
|
package/dist/services/api.d.ts
CHANGED
@@ -4,6 +4,15 @@ interface Window {
|
|
4
4
|
params: {path: string},
|
5
5
|
axiosOptions?: {concurrentId?: string},
|
6
6
|
) => Promise<import('../types/api/schema').TEvDescribeSchemeResult>;
|
7
|
+
getStorageInfo: (
|
8
|
+
params: {
|
9
|
+
tenant: string,
|
10
|
+
filter: string,
|
11
|
+
nodeId: string,
|
12
|
+
type: 'Groups' | 'Nodes',
|
13
|
+
},
|
14
|
+
axiosOptions?: {concurrentId?: string},
|
15
|
+
) => Promise<import('../types/api/storage').TStorageInfo>;
|
7
16
|
[method: string]: Function;
|
8
17
|
};
|
9
18
|
}
|
@@ -170,3 +170,49 @@ export interface TVDiskStateInfo {
|
|
170
170
|
*/
|
171
171
|
WriteThroughput?: string;
|
172
172
|
}
|
173
|
+
|
174
|
+
export interface TBSGroupStateInfo {
|
175
|
+
/** uint32 */
|
176
|
+
GroupID?: string;
|
177
|
+
ErasureSpecies?: string;
|
178
|
+
VDisks?: TVDiskStateInfo[];
|
179
|
+
/** uint64 */
|
180
|
+
ChangeTime?: string;
|
181
|
+
/** uint32 */
|
182
|
+
NodeId?: string; // filled during merge
|
183
|
+
/** uint32 */
|
184
|
+
GroupGeneration?: string;
|
185
|
+
Overall?: EFlag;
|
186
|
+
Latency?: EFlag;
|
187
|
+
/** uint32 */
|
188
|
+
Count?: string; // filled during group count
|
189
|
+
StoragePoolName?: string; // from BS_CONTROLLER
|
190
|
+
}
|
191
|
+
|
192
|
+
export interface TStoragePoolInfo {
|
193
|
+
Overall?: EFlag;
|
194
|
+
Name?: string;
|
195
|
+
Kind?: string;
|
196
|
+
Groups?: TBSGroupStateInfo[];
|
197
|
+
/** uint64 */
|
198
|
+
AcquiredUnits?: string;
|
199
|
+
AcquiredIOPS?: number;
|
200
|
+
/** uint64 */
|
201
|
+
AcquiredThroughput?: string;
|
202
|
+
/** uint64 */
|
203
|
+
AcquiredSize?: string;
|
204
|
+
MaximumIOPS?: number;
|
205
|
+
/** uint64 */
|
206
|
+
MaximumThroughput?: string;
|
207
|
+
/** uint64 */
|
208
|
+
MaximumSize?: string;
|
209
|
+
}
|
210
|
+
|
211
|
+
export interface TStorageInfo {
|
212
|
+
Overall?: EFlag;
|
213
|
+
StoragePools?: TStoragePoolInfo[];
|
214
|
+
/** uint64 */
|
215
|
+
TotalGroups?: string;
|
216
|
+
/** uint64 */
|
217
|
+
FoundGroups?: string;
|
218
|
+
}
|