ydb-embedded-ui 4.14.0 → 4.15.1
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 +16 -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 +113 -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);
|