ydb-embedded-ui 1.11.1 → 1.12.2
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 +23 -0
- package/dist/containers/Storage/StorageGroups/StorageGroups.scss +6 -0
- package/dist/containers/Storage/StorageGroups/StorageGroups.tsx +37 -25
- package/dist/containers/Storage/utils/index.ts +45 -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,28 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [1.12.2](https://github.com/ydb-platform/ydb-embedded-ui/compare/v1.12.1...v1.12.2) (2022-08-29)
|
4
|
+
|
5
|
+
|
6
|
+
### Bug Fixes
|
7
|
+
|
8
|
+
* **Storage:** bright red usage starting from 90% ([69b7ed2](https://github.com/ydb-platform/ydb-embedded-ui/commit/69b7ed248151f518ffc5fabbdccf5ea9bbcd9405))
|
9
|
+
* **Storage:** display usage without gte sign ([39630a2](https://github.com/ydb-platform/ydb-embedded-ui/commit/39630a2a06b574d53d0ef74c1b3e0dc96b9666a8))
|
10
|
+
|
11
|
+
## [1.12.1](https://github.com/ydb-platform/ydb-embedded-ui/compare/v1.12.0...v1.12.1) (2022-08-26)
|
12
|
+
|
13
|
+
|
14
|
+
### Bug Fixes
|
15
|
+
|
16
|
+
* **Storage:** properly display usage for 0 storage ([aee67f9](https://github.com/ydb-platform/ydb-embedded-ui/commit/aee67f9314341c995e2c9468f5eedc48fa0a3d35))
|
17
|
+
|
18
|
+
## [1.12.0](https://github.com/ydb-platform/ydb-embedded-ui/compare/v1.11.1...v1.12.0) (2022-08-26)
|
19
|
+
|
20
|
+
|
21
|
+
### Features
|
22
|
+
|
23
|
+
* **Storage:** show usage column ([73aed5f](https://github.com/ydb-platform/ydb-embedded-ui/commit/73aed5f9ed60b6d2bd77fd315ae514ee7443c489))
|
24
|
+
* **Storage:** vividly show degraded disks count ([7315a9c](https://github.com/ydb-platform/ydb-embedded-ui/commit/7315a9cfd98002a7fab85d721712aa82c6dbb552))
|
25
|
+
|
3
26
|
## [1.11.1](https://github.com/ydb-platform/ydb-embedded-ui/compare/v1.11.0...v1.11.1) (2022-08-26)
|
4
27
|
|
5
28
|
|
@@ -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,37 @@ 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
|
+
// without a limit the usage can be evaluated as 0,
|
130
|
+
// but the absence of a value is more clear
|
131
|
+
return row.Limit ? (
|
132
|
+
<Label
|
133
|
+
theme={getUsageSeverity(usage)}
|
134
|
+
className={b('usage-label', {overload: usage >= 90})}
|
135
|
+
>
|
136
|
+
{usage}%
|
137
|
+
</Label>
|
138
|
+
) : '-';
|
139
|
+
},
|
140
|
+
// without a limit exclude usage from sort to display at the bottom
|
141
|
+
sortAccessor: (row) => row.Limit ? getUsage(row) : null,
|
142
|
+
align: DataTable.LEFT,
|
143
|
+
},
|
113
144
|
{
|
114
145
|
name: TableColumnsIds.GroupID,
|
115
146
|
header: tableColumnsNames[TableColumnsIds.GroupID],
|
@@ -137,18 +168,6 @@ function StorageGroups({data, tableSettings, visibleEntities, nodes}: StorageGro
|
|
137
168
|
},
|
138
169
|
align: DataTable.RIGHT,
|
139
170
|
},
|
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
171
|
{
|
153
172
|
name: TableColumnsIds.UsedSpaceFlag,
|
154
173
|
header: tableColumnsNames[TableColumnsIds.UsedSpaceFlag],
|
@@ -186,13 +205,6 @@ function StorageGroups({data, tableSettings, visibleEntities, nodes}: StorageGro
|
|
186
205
|
},
|
187
206
|
align: DataTable.RIGHT,
|
188
207
|
},
|
189
|
-
{
|
190
|
-
name: TableColumnsIds.Missing,
|
191
|
-
header: tableColumnsNames[TableColumnsIds.Missing],
|
192
|
-
width: 100,
|
193
|
-
align: DataTable.CENTER,
|
194
|
-
defaultOrder: DataTable.DESCENDING,
|
195
|
-
},
|
196
208
|
{
|
197
209
|
name: TableColumnsIds.VDisks,
|
198
210
|
className: b('vdisks-column'),
|
@@ -1,6 +1,51 @@
|
|
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
|
+
// if limit is 0, display 0
|
48
|
+
const usage = Math.round((data.Used * 100) / data.Limit) || 0;
|
49
|
+
|
50
|
+
return Math.floor(usage / step) * step;
|
51
|
+
};
|
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
|
+
}
|