ydb-embedded-ui 4.14.0 → 4.15.0
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +9 -0
- package/dist/containers/App/App.js +1 -1
- package/dist/containers/AsideNavigation/AsideNavigation.tsx +1 -1
- package/dist/containers/Authentication/Authentication.tsx +1 -1
- package/dist/containers/Storage/Storage.tsx +64 -32
- package/dist/containers/Storage/StorageGroups/StorageGroups.tsx +56 -73
- package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +33 -43
- package/dist/containers/Storage/utils/index.ts +3 -3
- package/dist/containers/Tenant/i18n/en.json +3 -0
- package/dist/containers/Tenant/i18n/ru.json +3 -0
- package/dist/containers/Tenant/utils/queryTemplates.ts +89 -0
- package/dist/containers/Tenant/utils/schema.ts +1 -1
- package/dist/containers/Tenant/utils/schemaActions.ts +27 -44
- package/dist/containers/UserSettings/i18n/en.json +1 -1
- package/dist/containers/UserSettings/i18n/ru.json +1 -1
- package/dist/{reportWebVitals.js → reportWebVitals.ts} +3 -1
- package/dist/services/api.ts +6 -4
- package/dist/store/reducers/{authentication.js → authentication/authentication.ts} +14 -7
- package/dist/store/reducers/authentication/types.ts +15 -0
- package/dist/store/reducers/describe.ts +1 -16
- package/dist/store/reducers/index.ts +1 -1
- package/dist/store/reducers/storage/selectors.ts +50 -150
- package/dist/store/reducers/storage/storage.ts +73 -25
- package/dist/store/reducers/storage/types.ts +49 -17
- package/dist/store/reducers/storage/utils.ts +207 -0
- package/dist/store/utils.ts +1 -1
- package/dist/types/api/error.ts +4 -0
- package/dist/types/api/storage.ts +32 -4
- package/dist/types/window.d.ts +1 -0
- package/dist/utils/hooks/index.ts +1 -0
- package/dist/utils/hooks/useStorageRequestParams.ts +28 -0
- package/dist/utils/hooks/useTableSort.ts +1 -1
- package/dist/utils/storage.ts +31 -3
- package/package.json +1 -5
- package/dist/HOCS/WithSearch/WithSearch.js +0 -26
- package/dist/HOCS/index.js +0 -1
- package/dist/components/Hotkey/Hotkey.js +0 -102
- package/dist/components/Pagination/Pagination.js +0 -63
- package/dist/components/Pagination/Pagination.scss +0 -28
- package/dist/types/store/storage.ts +0 -12
- /package/dist/{index.js → index.tsx} +0 -0
- /package/dist/utils/{monaco.js → monaco.ts} +0 -0
@@ -1,13 +1,23 @@
|
|
1
1
|
import type {Reducer} from 'redux';
|
2
2
|
import _ from 'lodash';
|
3
3
|
|
4
|
+
import {EVersion} from '../../../types/api/storage';
|
4
5
|
import {NodesUptimeFilterValues} from '../../../utils/nodes';
|
5
6
|
import '../../../services/api';
|
6
7
|
|
7
8
|
import {createRequestActionTypes, createApiRequest} from '../../utils';
|
8
9
|
|
9
|
-
import type {
|
10
|
+
import type {NodesApiRequestParams, NodesSortParams} from '../nodes/types';
|
11
|
+
import type {
|
12
|
+
StorageAction,
|
13
|
+
StorageApiRequestParams,
|
14
|
+
StorageSortParams,
|
15
|
+
StorageState,
|
16
|
+
StorageType,
|
17
|
+
VisibleEntities,
|
18
|
+
} from './types';
|
10
19
|
import {VISIBLE_ENTITIES, STORAGE_TYPES} from './constants';
|
20
|
+
import {prepareStorageGroupsResponse, prepareStorageNodesResponse} from './utils';
|
11
21
|
|
12
22
|
export const FETCH_STORAGE = createRequestActionTypes('storage', 'FETCH_STORAGE');
|
13
23
|
|
@@ -18,6 +28,8 @@ const SET_VISIBLE_GROUPS = 'storage/SET_VISIBLE_GROUPS';
|
|
18
28
|
const SET_STORAGE_TYPE = 'storage/SET_STORAGE_TYPE';
|
19
29
|
const SET_NODES_UPTIME_FILTER = 'storage/SET_NODES_UPTIME_FILTER';
|
20
30
|
const SET_DATA_WAS_NOT_LOADED = 'storage/SET_DATA_WAS_NOT_LOADED';
|
31
|
+
const SET_NODES_SORT_PARAMS = 'storage/SET_NODES_SORT_PARAMS';
|
32
|
+
const SET_GROUPS_SORT_PARAMS = 'storage/SET_GROUPS_SORT_PARAMS';
|
21
33
|
|
22
34
|
const initialState = {
|
23
35
|
loading: true,
|
@@ -42,6 +54,8 @@ const storage: Reducer<StorageState, StorageAction> = (state = initialState, act
|
|
42
54
|
...state,
|
43
55
|
nodes: action.data.nodes,
|
44
56
|
groups: action.data.groups,
|
57
|
+
total: action.data.total,
|
58
|
+
found: action.data.found,
|
45
59
|
loading: false,
|
46
60
|
wasLoaded: true,
|
47
61
|
error: undefined,
|
@@ -80,6 +94,7 @@ const storage: Reducer<StorageState, StorageAction> = (state = initialState, act
|
|
80
94
|
return {
|
81
95
|
...state,
|
82
96
|
visible: action.data,
|
97
|
+
usageFilter: [],
|
83
98
|
wasLoaded: false,
|
84
99
|
error: undefined,
|
85
100
|
};
|
@@ -107,39 +122,58 @@ const storage: Reducer<StorageState, StorageAction> = (state = initialState, act
|
|
107
122
|
wasLoaded: false,
|
108
123
|
};
|
109
124
|
}
|
125
|
+
case SET_NODES_SORT_PARAMS: {
|
126
|
+
return {
|
127
|
+
...state,
|
128
|
+
nodesSortValue: action.data.sortValue,
|
129
|
+
nodesSortOrder: action.data.sortOrder,
|
130
|
+
};
|
131
|
+
}
|
132
|
+
case SET_GROUPS_SORT_PARAMS: {
|
133
|
+
return {
|
134
|
+
...state,
|
135
|
+
groupsSortValue: action.data.sortValue,
|
136
|
+
groupsSortOrder: action.data.sortOrder,
|
137
|
+
};
|
138
|
+
}
|
110
139
|
default:
|
111
140
|
return state;
|
112
141
|
}
|
113
142
|
};
|
114
143
|
|
115
|
-
|
116
|
-
{
|
117
|
-
tenant,
|
118
|
-
visibleEntities,
|
119
|
-
nodeId,
|
120
|
-
type,
|
121
|
-
}: {
|
122
|
-
tenant?: string;
|
123
|
-
visibleEntities?: VisibleEntities;
|
124
|
-
nodeId?: string;
|
125
|
-
type?: StorageType;
|
126
|
-
},
|
127
|
-
{concurrentId}: {concurrentId?: string} = {},
|
128
|
-
) {
|
129
|
-
if (type === STORAGE_TYPES.nodes) {
|
130
|
-
return createApiRequest({
|
131
|
-
request: window.api.getNodes({tenant, visibleEntities, type: 'static'}, {concurrentId}),
|
132
|
-
actions: FETCH_STORAGE,
|
133
|
-
dataHandler: (data) => ({nodes: data}),
|
134
|
-
});
|
135
|
-
}
|
144
|
+
const concurrentId = 'getStorageInfo';
|
136
145
|
|
146
|
+
export const getStorageNodesInfo = ({
|
147
|
+
tenant,
|
148
|
+
visibleEntities,
|
149
|
+
...params
|
150
|
+
}: Omit<NodesApiRequestParams, 'type'>) => {
|
137
151
|
return createApiRequest({
|
138
|
-
request: window.api.
|
152
|
+
request: window.api.getNodes(
|
153
|
+
{tenant, visibleEntities, type: 'static', ...params},
|
154
|
+
{concurrentId},
|
155
|
+
),
|
139
156
|
actions: FETCH_STORAGE,
|
140
|
-
dataHandler:
|
157
|
+
dataHandler: prepareStorageNodesResponse,
|
141
158
|
});
|
142
|
-
}
|
159
|
+
};
|
160
|
+
|
161
|
+
export const getStorageGroupsInfo = ({
|
162
|
+
tenant,
|
163
|
+
visibleEntities,
|
164
|
+
nodeId,
|
165
|
+
version = EVersion.v1,
|
166
|
+
...params
|
167
|
+
}: StorageApiRequestParams) => {
|
168
|
+
return createApiRequest({
|
169
|
+
request: window.api.getStorageInfo(
|
170
|
+
{tenant, visibleEntities, nodeId, version, ...params},
|
171
|
+
{concurrentId},
|
172
|
+
),
|
173
|
+
actions: FETCH_STORAGE,
|
174
|
+
dataHandler: prepareStorageGroupsResponse,
|
175
|
+
});
|
176
|
+
};
|
143
177
|
|
144
178
|
export function setInitialState() {
|
145
179
|
return {
|
@@ -188,4 +222,18 @@ export const setDataWasNotLoaded = () => {
|
|
188
222
|
} as const;
|
189
223
|
};
|
190
224
|
|
225
|
+
export const setNodesSortParams = (sortParams: NodesSortParams) => {
|
226
|
+
return {
|
227
|
+
type: SET_NODES_SORT_PARAMS,
|
228
|
+
data: sortParams,
|
229
|
+
} as const;
|
230
|
+
};
|
231
|
+
|
232
|
+
export const setGroupsSortParams = (sortParams: StorageSortParams) => {
|
233
|
+
return {
|
234
|
+
type: SET_GROUPS_SORT_PARAMS,
|
235
|
+
data: sortParams,
|
236
|
+
} as const;
|
237
|
+
};
|
238
|
+
|
191
239
|
export default storage;
|
@@ -1,20 +1,22 @@
|
|
1
|
+
import type {OrderType} from '@gravity-ui/react-data-table';
|
2
|
+
|
1
3
|
import type {IResponseError} from '../../../types/api/error';
|
2
|
-
import type {
|
4
|
+
import type {TSystemStateInfo} from '../../../types/api/nodes';
|
3
5
|
import type {TPDiskStateInfo} from '../../../types/api/pdisk';
|
4
|
-
import type {
|
5
|
-
|
6
|
-
THiveStorageGroupStats,
|
7
|
-
TStorageInfo,
|
8
|
-
} from '../../../types/api/storage';
|
6
|
+
import type {EVersion, TStorageGroupInfo} from '../../../types/api/storage';
|
7
|
+
import type {TVDiskStateInfo} from '../../../types/api/vdisk';
|
9
8
|
import type {ValueOf} from '../../../types/common';
|
10
|
-
import type {NodesUptimeFilterValues} from '../../../utils/nodes';
|
9
|
+
import type {NodesSortValue, NodesUptimeFilterValues} from '../../../utils/nodes';
|
10
|
+
import type {StorageSortValue} from '../../../utils/storage';
|
11
11
|
import type {ApiRequestAction} from '../../utils';
|
12
12
|
|
13
13
|
import {STORAGE_TYPES, VISIBLE_ENTITIES} from './constants';
|
14
14
|
import {
|
15
15
|
FETCH_STORAGE,
|
16
16
|
setDataWasNotLoaded,
|
17
|
+
setGroupsSortParams,
|
17
18
|
setInitialState,
|
19
|
+
setNodesSortParams,
|
18
20
|
setNodesUptimeFilter,
|
19
21
|
setStorageTextFilter,
|
20
22
|
setStorageType,
|
@@ -28,23 +30,24 @@ export type StorageType = ValueOf<typeof STORAGE_TYPES>;
|
|
28
30
|
export interface PreparedStorageNode extends TSystemStateInfo {
|
29
31
|
NodeId: number;
|
30
32
|
PDisks: TPDiskStateInfo[] | undefined;
|
33
|
+
VDisks: TVDiskStateInfo[] | undefined;
|
31
34
|
|
32
35
|
Missing: number;
|
33
36
|
Uptime: string;
|
34
37
|
}
|
35
38
|
|
36
|
-
export
|
37
|
-
|
38
|
-
export interface PreparedStorageGroup extends RawStorageGroup {
|
39
|
+
export interface PreparedStorageGroup extends TStorageGroupInfo {
|
39
40
|
PoolName: string | undefined;
|
40
41
|
|
42
|
+
Usage: number;
|
41
43
|
Read: number;
|
42
44
|
Write: number;
|
43
45
|
Used: number;
|
44
46
|
Limit: number;
|
45
|
-
|
47
|
+
Degraded: number;
|
48
|
+
Kind: string | undefined;
|
49
|
+
|
46
50
|
UsedSpaceFlag: number;
|
47
|
-
Type: string | null;
|
48
51
|
}
|
49
52
|
|
50
53
|
export interface UsageFilter {
|
@@ -52,10 +55,24 @@ export interface UsageFilter {
|
|
52
55
|
count: number;
|
53
56
|
}
|
54
57
|
|
55
|
-
export interface
|
58
|
+
export interface StorageSortParams {
|
59
|
+
sortOrder?: OrderType;
|
60
|
+
sortValue?: StorageSortValue;
|
61
|
+
}
|
62
|
+
|
63
|
+
export interface StorageSortAndFilterParams extends StorageSortParams {
|
64
|
+
filter?: string; // PoolName or GroupId
|
65
|
+
|
66
|
+
offser?: number;
|
67
|
+
limit?: number;
|
68
|
+
}
|
69
|
+
|
70
|
+
export interface StorageApiRequestParams extends StorageSortAndFilterParams {
|
56
71
|
tenant?: string;
|
57
72
|
nodeId?: string;
|
58
73
|
visibleEntities?: VisibleEntities;
|
74
|
+
|
75
|
+
version?: EVersion;
|
59
76
|
}
|
60
77
|
|
61
78
|
export interface StorageState {
|
@@ -65,15 +82,28 @@ export interface StorageState {
|
|
65
82
|
usageFilter: string[];
|
66
83
|
visible: VisibleEntities;
|
67
84
|
nodesUptimeFilter: NodesUptimeFilterValues;
|
85
|
+
groupsSortValue?: StorageSortValue;
|
86
|
+
groupsSortOrder?: OrderType;
|
87
|
+
nodesSortValue?: NodesSortValue;
|
88
|
+
nodesSortOrder?: OrderType;
|
68
89
|
type: StorageType;
|
69
|
-
nodes?:
|
70
|
-
groups?:
|
90
|
+
nodes?: PreparedStorageNode[];
|
91
|
+
groups?: PreparedStorageGroup[];
|
92
|
+
found?: number;
|
93
|
+
total?: number;
|
71
94
|
error?: IResponseError;
|
72
95
|
}
|
73
96
|
|
97
|
+
export interface PreparedStorageResponse {
|
98
|
+
nodes?: PreparedStorageNode[];
|
99
|
+
groups?: PreparedStorageGroup[];
|
100
|
+
found: number | undefined;
|
101
|
+
total: number | undefined;
|
102
|
+
}
|
103
|
+
|
74
104
|
type GetStorageInfoApiRequestAction = ApiRequestAction<
|
75
105
|
typeof FETCH_STORAGE,
|
76
|
-
|
106
|
+
PreparedStorageResponse,
|
77
107
|
IResponseError
|
78
108
|
>;
|
79
109
|
|
@@ -85,7 +115,9 @@ export type StorageAction =
|
|
85
115
|
| ReturnType<typeof setUsageFilter>
|
86
116
|
| ReturnType<typeof setVisibleEntities>
|
87
117
|
| ReturnType<typeof setNodesUptimeFilter>
|
88
|
-
| ReturnType<typeof setDataWasNotLoaded
|
118
|
+
| ReturnType<typeof setDataWasNotLoaded>
|
119
|
+
| ReturnType<typeof setNodesSortParams>
|
120
|
+
| ReturnType<typeof setGroupsSortParams>;
|
89
121
|
|
90
122
|
export interface StorageStateSlice {
|
91
123
|
storage: StorageState;
|
@@ -0,0 +1,207 @@
|
|
1
|
+
import type {TNodeInfo, TNodesInfo} from '../../../types/api/nodes';
|
2
|
+
import type {
|
3
|
+
TStorageGroupInfo,
|
4
|
+
TStorageGroupInfoV2,
|
5
|
+
TStorageInfo,
|
6
|
+
} from '../../../types/api/storage';
|
7
|
+
import {EVDiskState, type TVDiskStateInfo} from '../../../types/api/vdisk';
|
8
|
+
import {TPDiskState} from '../../../types/api/pdisk';
|
9
|
+
import {EFlag} from '../../../types/api/enums';
|
10
|
+
import {getPDiskType} from '../../../utils/pdisk';
|
11
|
+
import {getUsage} from '../../../utils/storage';
|
12
|
+
import {calcUptime} from '../../../utils';
|
13
|
+
|
14
|
+
import type {PreparedStorageGroup, PreparedStorageNode, PreparedStorageResponse} from './types';
|
15
|
+
|
16
|
+
// ==== Constants ====
|
17
|
+
|
18
|
+
const FLAGS_POINTS = {
|
19
|
+
[EFlag.Green]: 1,
|
20
|
+
[EFlag.Yellow]: 100,
|
21
|
+
[EFlag.Orange]: 10_000,
|
22
|
+
[EFlag.Red]: 1_000_000,
|
23
|
+
};
|
24
|
+
|
25
|
+
// ==== Prepare groups ====
|
26
|
+
|
27
|
+
const prepareVDisk = (vDisk: TVDiskStateInfo, poolName: string | undefined) => {
|
28
|
+
// VDisk doesn't have its own StoragePoolName when located inside StoragePool data
|
29
|
+
return {
|
30
|
+
...vDisk,
|
31
|
+
StoragePoolName: poolName,
|
32
|
+
Donors: vDisk.Donors?.map((donor) => ({
|
33
|
+
...donor,
|
34
|
+
StoragePoolName: poolName,
|
35
|
+
})),
|
36
|
+
};
|
37
|
+
};
|
38
|
+
|
39
|
+
const prepareStorageGroupData = (
|
40
|
+
group: TStorageGroupInfo,
|
41
|
+
poolName?: string,
|
42
|
+
): PreparedStorageGroup => {
|
43
|
+
let missing = 0;
|
44
|
+
let usedSpaceFlag = 0;
|
45
|
+
let usedSpaceBytes = 0;
|
46
|
+
let limitSizeBytes = 0;
|
47
|
+
let readSpeedBytesPerSec = 0;
|
48
|
+
let writeSpeedBytesPerSec = 0;
|
49
|
+
let mediaType = '';
|
50
|
+
|
51
|
+
if (group.VDisks) {
|
52
|
+
for (const vDisk of group.VDisks) {
|
53
|
+
const {
|
54
|
+
Replicated,
|
55
|
+
VDiskState,
|
56
|
+
AvailableSize,
|
57
|
+
AllocatedSize,
|
58
|
+
PDisk,
|
59
|
+
DiskSpace,
|
60
|
+
ReadThroughput,
|
61
|
+
WriteThroughput,
|
62
|
+
} = vDisk;
|
63
|
+
|
64
|
+
if (
|
65
|
+
!Replicated ||
|
66
|
+
PDisk?.State !== TPDiskState.Normal ||
|
67
|
+
VDiskState !== EVDiskState.OK
|
68
|
+
) {
|
69
|
+
missing += 1;
|
70
|
+
}
|
71
|
+
|
72
|
+
if (DiskSpace && DiskSpace !== EFlag.Grey) {
|
73
|
+
usedSpaceFlag += FLAGS_POINTS[DiskSpace];
|
74
|
+
}
|
75
|
+
|
76
|
+
const available = Number(AvailableSize ?? PDisk?.AvailableSize) || 0;
|
77
|
+
const allocated = Number(AllocatedSize) || 0;
|
78
|
+
|
79
|
+
usedSpaceBytes += allocated;
|
80
|
+
limitSizeBytes += available + allocated;
|
81
|
+
|
82
|
+
readSpeedBytesPerSec += Number(ReadThroughput) || 0;
|
83
|
+
writeSpeedBytesPerSec += Number(WriteThroughput) || 0;
|
84
|
+
|
85
|
+
const currentType = getPDiskType(PDisk || {});
|
86
|
+
mediaType =
|
87
|
+
currentType && (currentType === mediaType || mediaType === '')
|
88
|
+
? currentType
|
89
|
+
: 'Mixed';
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
const vDisks = group.VDisks?.map((vdisk) => prepareVDisk(vdisk, poolName));
|
94
|
+
const usage = getUsage({Used: usedSpaceBytes, Limit: limitSizeBytes}, 5);
|
95
|
+
|
96
|
+
return {
|
97
|
+
...group,
|
98
|
+
VDisks: vDisks,
|
99
|
+
Usage: usage,
|
100
|
+
Read: readSpeedBytesPerSec,
|
101
|
+
Write: writeSpeedBytesPerSec,
|
102
|
+
PoolName: poolName,
|
103
|
+
Used: usedSpaceBytes,
|
104
|
+
Limit: limitSizeBytes,
|
105
|
+
Degraded: missing,
|
106
|
+
UsedSpaceFlag: usedSpaceFlag,
|
107
|
+
Kind: mediaType || undefined,
|
108
|
+
};
|
109
|
+
};
|
110
|
+
|
111
|
+
const prepareStorageGroupDataV2 = (group: TStorageGroupInfoV2): PreparedStorageGroup => {
|
112
|
+
const {
|
113
|
+
VDisks = [],
|
114
|
+
PoolName,
|
115
|
+
Usage = 0,
|
116
|
+
Read = 0,
|
117
|
+
Write = 0,
|
118
|
+
Used = 0,
|
119
|
+
Limit = 0,
|
120
|
+
Degraded = 0,
|
121
|
+
Kind,
|
122
|
+
} = group;
|
123
|
+
|
124
|
+
const UsedSpaceFlag = VDisks.reduce((acc, {DiskSpace}) => {
|
125
|
+
if (DiskSpace && DiskSpace !== EFlag.Grey) {
|
126
|
+
return acc + FLAGS_POINTS[DiskSpace];
|
127
|
+
}
|
128
|
+
return acc;
|
129
|
+
}, 0);
|
130
|
+
|
131
|
+
const vDisks = VDisks.map((vdisk) => prepareVDisk(vdisk, PoolName));
|
132
|
+
const usage = Math.floor(Number(Usage) * 100);
|
133
|
+
|
134
|
+
return {
|
135
|
+
...group,
|
136
|
+
UsedSpaceFlag,
|
137
|
+
PoolName,
|
138
|
+
Kind,
|
139
|
+
VDisks: vDisks,
|
140
|
+
Usage: usage,
|
141
|
+
Read: Number(Read),
|
142
|
+
Write: Number(Write),
|
143
|
+
Used: Number(Used),
|
144
|
+
Limit: Number(Limit),
|
145
|
+
Degraded: Number(Degraded),
|
146
|
+
};
|
147
|
+
};
|
148
|
+
|
149
|
+
// ==== Prepare nodes ====
|
150
|
+
|
151
|
+
const prepareStorageNodeData = (node: TNodeInfo): PreparedStorageNode => {
|
152
|
+
const systemState = node.SystemState ?? {};
|
153
|
+
const missing =
|
154
|
+
node.PDisks?.filter((pDisk) => {
|
155
|
+
return pDisk.State !== TPDiskState.Normal;
|
156
|
+
}).length || 0;
|
157
|
+
|
158
|
+
return {
|
159
|
+
NodeId: node.NodeId,
|
160
|
+
SystemState: systemState.SystemState,
|
161
|
+
DataCenter: systemState.DataCenter,
|
162
|
+
Rack: systemState.Rack,
|
163
|
+
Host: systemState.Host,
|
164
|
+
Endpoints: systemState.Endpoints,
|
165
|
+
Uptime: calcUptime(systemState.StartTime),
|
166
|
+
StartTime: systemState.StartTime,
|
167
|
+
PDisks: node.PDisks,
|
168
|
+
VDisks: node.VDisks,
|
169
|
+
Missing: missing,
|
170
|
+
};
|
171
|
+
};
|
172
|
+
|
173
|
+
// ==== Prepare responses ====
|
174
|
+
|
175
|
+
export const prepareStorageNodesResponse = (data: TNodesInfo): PreparedStorageResponse => {
|
176
|
+
const {Nodes, TotalNodes, FoundNodes} = data;
|
177
|
+
|
178
|
+
const preparedNodes = Nodes?.map(prepareStorageNodeData);
|
179
|
+
|
180
|
+
return {
|
181
|
+
nodes: preparedNodes,
|
182
|
+
total: Number(TotalNodes) || preparedNodes?.length,
|
183
|
+
found: Number(FoundNodes),
|
184
|
+
};
|
185
|
+
};
|
186
|
+
|
187
|
+
export const prepareStorageGroupsResponse = (data: TStorageInfo): PreparedStorageResponse => {
|
188
|
+
const {StoragePools, StorageGroups, TotalGroups, FoundGroups} = data;
|
189
|
+
|
190
|
+
let preparedGroups: PreparedStorageGroup[] = [];
|
191
|
+
|
192
|
+
if (StorageGroups) {
|
193
|
+
preparedGroups = StorageGroups.map(prepareStorageGroupDataV2);
|
194
|
+
} else {
|
195
|
+
StoragePools?.forEach((pool) => {
|
196
|
+
pool.Groups?.forEach((group) => {
|
197
|
+
preparedGroups.push(prepareStorageGroupData(group, pool.Name));
|
198
|
+
});
|
199
|
+
});
|
200
|
+
}
|
201
|
+
|
202
|
+
return {
|
203
|
+
groups: preparedGroups,
|
204
|
+
total: Number(TotalGroups) || preparedGroups.length,
|
205
|
+
found: Number(FoundGroups),
|
206
|
+
};
|
207
|
+
};
|
package/dist/store/utils.ts
CHANGED
@@ -3,7 +3,7 @@ import {AxiosResponse} from 'axios';
|
|
3
3
|
|
4
4
|
import createToast from '../utils/createToast';
|
5
5
|
|
6
|
-
import {SET_UNAUTHENTICATED} from './reducers/authentication';
|
6
|
+
import {SET_UNAUTHENTICATED} from './reducers/authentication/authentication';
|
7
7
|
import type {GetState} from './reducers';
|
8
8
|
|
9
9
|
export const nop = (result: any) => result;
|
package/dist/types/api/error.ts
CHANGED
@@ -8,7 +8,8 @@ import {TVDiskStateInfo} from './vdisk';
|
|
8
8
|
*/
|
9
9
|
export interface TStorageInfo {
|
10
10
|
Overall?: EFlag;
|
11
|
-
StoragePools?: TStoragePoolInfo[];
|
11
|
+
StoragePools?: TStoragePoolInfo[]; // v1
|
12
|
+
StorageGroups?: TStorageGroupInfoV2[]; // v2
|
12
13
|
/** uint64 */
|
13
14
|
TotalGroups?: string;
|
14
15
|
/** uint64 */
|
@@ -19,7 +20,7 @@ interface TStoragePoolInfo {
|
|
19
20
|
Overall?: EFlag;
|
20
21
|
Name?: string;
|
21
22
|
Kind?: string;
|
22
|
-
Groups?:
|
23
|
+
Groups?: TStorageGroupInfo[];
|
23
24
|
/** uint64 */
|
24
25
|
AcquiredUnits?: string;
|
25
26
|
AcquiredIOPS?: number;
|
@@ -34,7 +35,29 @@ interface TStoragePoolInfo {
|
|
34
35
|
MaximumSize?: string;
|
35
36
|
}
|
36
37
|
|
37
|
-
export interface
|
38
|
+
export interface TStorageGroupInfoV2 extends TStorageGroupInfo {
|
39
|
+
PoolName?: string;
|
40
|
+
Kind?: string;
|
41
|
+
|
42
|
+
/** uint64 */
|
43
|
+
Degraded?: string;
|
44
|
+
|
45
|
+
/** uint64 */
|
46
|
+
Used: string;
|
47
|
+
/** uint64 */
|
48
|
+
Limit: string;
|
49
|
+
/** uint64 */
|
50
|
+
Read: string;
|
51
|
+
/** uint64 */
|
52
|
+
Write: string;
|
53
|
+
|
54
|
+
/** uint64 */
|
55
|
+
Usage?: string;
|
56
|
+
}
|
57
|
+
|
58
|
+
export type TStorageGroupInfo = TBSGroupStateInfo & THiveStorageGroupStats;
|
59
|
+
|
60
|
+
interface TBSGroupStateInfo {
|
38
61
|
GroupID?: number;
|
39
62
|
ErasureSpecies?: string;
|
40
63
|
VDisks?: TVDiskStateInfo[];
|
@@ -57,7 +80,7 @@ export interface TBSGroupStateInfo {
|
|
57
80
|
Encryption?: boolean;
|
58
81
|
}
|
59
82
|
|
60
|
-
|
83
|
+
interface THiveStorageGroupStats {
|
61
84
|
GroupID?: number;
|
62
85
|
/** uint64 */
|
63
86
|
AcquiredUnits?: string;
|
@@ -76,3 +99,8 @@ export interface THiveStorageGroupStats {
|
|
76
99
|
/** uint64 */
|
77
100
|
AvailableSize?: string;
|
78
101
|
}
|
102
|
+
|
103
|
+
export enum EVersion {
|
104
|
+
v1 = 'v1',
|
105
|
+
v2 = 'v2', // only this versions works with sorting
|
106
|
+
}
|
package/dist/types/window.d.ts
CHANGED
@@ -37,6 +37,7 @@ interface Window {
|
|
37
37
|
custom_backend?: string;
|
38
38
|
|
39
39
|
__REDUX_DEVTOOLS_EXTENSION_COMPOSE__?: typeof import('redux').compose;
|
40
|
+
store?: import('redux').Store;
|
40
41
|
|
41
42
|
userSettings?: Record<string, string | undefined>;
|
42
43
|
systemSettings?: Record<string, string | undefined>;
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import {useMemo} from 'react';
|
2
|
+
|
3
|
+
import type {StorageSortAndFilterParams} from '../../store/reducers/storage/types';
|
4
|
+
import {EVersion} from '../../types/api/storage';
|
5
|
+
import {USE_BACKEND_PARAMS_FOR_TABLES_KEY} from '../constants';
|
6
|
+
import {useSetting} from './useSetting';
|
7
|
+
|
8
|
+
export const useStorageRequestParams = ({
|
9
|
+
filter,
|
10
|
+
sortOrder,
|
11
|
+
sortValue,
|
12
|
+
}: StorageSortAndFilterParams) => {
|
13
|
+
const [useBackendParamsForTables] = useSetting<boolean>(USE_BACKEND_PARAMS_FOR_TABLES_KEY);
|
14
|
+
|
15
|
+
// If backend params are enabled, update params value to use them in fetch request
|
16
|
+
// Otherwise no params will be updated, no hooks that depend on requestParams will be triggered
|
17
|
+
return useMemo(() => {
|
18
|
+
if (useBackendParamsForTables) {
|
19
|
+
return {
|
20
|
+
version: EVersion.v2,
|
21
|
+
filter,
|
22
|
+
sortOrder,
|
23
|
+
sortValue,
|
24
|
+
};
|
25
|
+
}
|
26
|
+
return undefined;
|
27
|
+
}, [useBackendParamsForTables, filter, sortOrder, sortValue]);
|
28
|
+
};
|
@@ -8,7 +8,7 @@ interface SortParams {
|
|
8
8
|
sortOrder: OrderType | undefined;
|
9
9
|
}
|
10
10
|
|
11
|
-
type HandleSort = (rawValue: SortOrder | SortOrder[] | undefined) => void;
|
11
|
+
export type HandleSort = (rawValue: SortOrder | SortOrder[] | undefined) => void;
|
12
12
|
|
13
13
|
export const useTableSort = (
|
14
14
|
{sortValue, sortOrder = DESCENDING}: SortParams,
|
package/dist/utils/storage.ts
CHANGED
@@ -1,12 +1,40 @@
|
|
1
1
|
import type {TVSlotId, TVDiskStateInfo} from '../types/api/vdisk';
|
2
|
-
import type {
|
2
|
+
import type {ValueOf} from '../types/common';
|
3
3
|
|
4
4
|
export const isFullVDiskData = (disk: TVDiskStateInfo | TVSlotId): disk is TVDiskStateInfo =>
|
5
5
|
'VDiskId' in disk;
|
6
6
|
|
7
|
-
|
7
|
+
interface EntityWithUsage {
|
8
|
+
Used: number;
|
9
|
+
Limit: number;
|
10
|
+
}
|
11
|
+
|
12
|
+
export const getUsage = <T extends EntityWithUsage>(data: T, step = 1) => {
|
8
13
|
// if limit is 0, display 0
|
9
|
-
const usage =
|
14
|
+
const usage = data.Limit ? (data.Used * 100) / data.Limit : 0;
|
10
15
|
|
11
16
|
return Math.floor(usage / step) * step;
|
12
17
|
};
|
18
|
+
|
19
|
+
/**
|
20
|
+
* Values to sort /storage v2 response
|
21
|
+
*
|
22
|
+
* Source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/viewer/json_storage.h
|
23
|
+
*/
|
24
|
+
export const STORAGE_SORT_VALUES = {
|
25
|
+
PoolName: 'PoolName',
|
26
|
+
Kind: 'Kind',
|
27
|
+
Erasure: 'Erasure',
|
28
|
+
Degraded: 'Degraded',
|
29
|
+
Usage: 'Usage',
|
30
|
+
GroupId: 'GroupId',
|
31
|
+
Used: 'Used',
|
32
|
+
Limit: 'Limit',
|
33
|
+
Read: 'Read',
|
34
|
+
Write: 'Write',
|
35
|
+
} as const;
|
36
|
+
|
37
|
+
export type StorageSortValue = ValueOf<typeof STORAGE_SORT_VALUES>;
|
38
|
+
|
39
|
+
export const isSortableStorageProperty = (value: string): value is StorageSortValue =>
|
40
|
+
Object.values(STORAGE_SORT_VALUES).includes(value as StorageSortValue);
|