ydb-embedded-ui 4.13.0 → 4.15.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 +25 -0
- package/dist/components/Tablet/Tablet.scss +1 -16
- package/dist/components/Tablet/Tablet.tsx +5 -5
- package/dist/components/TabletIcon/TabletIcon.scss +17 -0
- package/dist/components/TabletIcon/TabletIcon.tsx +18 -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/Header/Header.scss +2 -0
- package/dist/containers/Header/Header.tsx +2 -7
- package/dist/containers/Header/{breadcrumbs.ts → breadcrumbs.tsx} +19 -8
- package/dist/containers/Nodes/Nodes.tsx +53 -16
- package/dist/containers/Nodes/getNodesColumns.tsx +31 -13
- 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/Tablet/Tablet.tsx +9 -3
- package/dist/containers/Tenant/Query/QueryDuration/QueryDuration.scss +8 -0
- package/dist/containers/Tenant/Query/QueryDuration/QueryDuration.tsx +13 -1
- package/dist/containers/Tenant/Query/QueryEditorControls/QueryEditorControls.scss +3 -1
- package/dist/containers/Tenant/Query/i18n/en.json +6 -4
- package/dist/containers/Tenant/Query/i18n/ru.json +6 -4
- package/dist/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx +4 -0
- 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 +30 -54
- package/dist/containers/Tenant/utils/schemaControls.tsx +69 -0
- package/dist/containers/UserSettings/i18n/en.json +3 -0
- package/dist/containers/UserSettings/i18n/ru.json +3 -0
- package/dist/containers/UserSettings/settings.ts +12 -1
- package/dist/{reportWebVitals.js → reportWebVitals.ts} +3 -1
- package/dist/services/api.ts +30 -16
- 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/header/types.ts +2 -0
- package/dist/store/reducers/index.ts +1 -1
- package/dist/store/reducers/nodes/nodes.ts +23 -6
- package/dist/store/reducers/nodes/selectors.ts +2 -2
- package/dist/store/reducers/nodes/types.ts +15 -5
- package/dist/store/reducers/settings/settings.ts +5 -0
- 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/compute.ts +0 -12
- package/dist/types/api/error.ts +4 -0
- package/dist/types/api/nodes.ts +0 -12
- package/dist/types/api/storage.ts +32 -4
- package/dist/types/window.d.ts +1 -0
- package/dist/utils/constants.ts +3 -0
- package/dist/utils/filters.ts +23 -0
- package/dist/utils/hooks/index.ts +4 -0
- package/dist/utils/hooks/useNodesRequestParams.ts +46 -0
- package/dist/utils/hooks/useStorageRequestParams.ts +28 -0
- package/dist/utils/hooks/useTableSort.ts +37 -0
- package/dist/utils/nodes.ts +25 -0
- package/dist/utils/storage.ts +31 -3
- package/package.json +2 -6
- 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,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;
|
@@ -65,15 +65,3 @@ export enum EVersion {
|
|
65
65
|
v1 = 'v1',
|
66
66
|
v2 = 'v2', // only this versions works with sorting
|
67
67
|
}
|
68
|
-
|
69
|
-
export enum ESort {
|
70
|
-
NodeId = 'NodeId',
|
71
|
-
Host = 'Host',
|
72
|
-
DC = 'DC',
|
73
|
-
Rack = 'Rack',
|
74
|
-
Version = 'Version',
|
75
|
-
Uptime = 'Uptime',
|
76
|
-
Memory = 'Memory',
|
77
|
-
CPU = 'CPU',
|
78
|
-
LoadAverage = 'LoadAverage',
|
79
|
-
}
|
package/dist/types/api/error.ts
CHANGED
package/dist/types/api/nodes.ts
CHANGED
@@ -101,15 +101,3 @@ enum EConfigState {
|
|
101
101
|
'Consistent' = 'Consistent',
|
102
102
|
'Outdated' = 'Outdated',
|
103
103
|
}
|
104
|
-
|
105
|
-
export enum ESort {
|
106
|
-
NodeId = 'NodeId',
|
107
|
-
Host = 'Host',
|
108
|
-
DC = 'DC',
|
109
|
-
Rack = 'Rack',
|
110
|
-
Version = 'Version',
|
111
|
-
Uptime = 'Uptime',
|
112
|
-
Memory = 'Memory',
|
113
|
-
CPU = 'CPU',
|
114
|
-
LoadAverage = 'LoadAverage',
|
115
|
-
}
|
@@ -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>;
|
package/dist/utils/constants.ts
CHANGED
@@ -119,3 +119,6 @@ export const CLUSTER_INFO_HIDDEN_KEY = 'clusterInfoHidden';
|
|
119
119
|
|
120
120
|
// Remain "tab" in key name for backward compatibility
|
121
121
|
export const TENANT_INITIAL_PAGE_KEY = 'saved_tenant_initial_tab';
|
122
|
+
|
123
|
+
// Send filters and sort params to backend for Nodes and Storage tables
|
124
|
+
export const USE_BACKEND_PARAMS_FOR_TABLES_KEY = 'useBackendParamsForTables';
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import {escapeRegExp} from 'lodash';
|
2
|
+
|
3
|
+
import type {OrderType} from '@gravity-ui/react-data-table';
|
4
|
+
import {DESCENDING} from '@gravity-ui/react-data-table/build/esm/lib/constants';
|
5
|
+
|
6
|
+
export const prepareSortValue = (
|
7
|
+
sortValue: string | undefined,
|
8
|
+
sortOrder: OrderType = DESCENDING,
|
9
|
+
) => {
|
10
|
+
if (!sortValue) {
|
11
|
+
return '';
|
12
|
+
}
|
13
|
+
|
14
|
+
if (sortOrder === DESCENDING) {
|
15
|
+
return '-' + sortValue;
|
16
|
+
}
|
17
|
+
|
18
|
+
return sortValue;
|
19
|
+
};
|
20
|
+
|
21
|
+
export const prepareSearchValue = (searchValue = '') => {
|
22
|
+
return new RegExp(escapeRegExp(searchValue), 'i');
|
23
|
+
};
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import {useMemo} from 'react';
|
2
|
+
|
3
|
+
import type {NodesGeneralRequestParams} from '../../store/reducers/nodes/types';
|
4
|
+
import type {ProblemFilterValue} from '../../store/reducers/settings/types';
|
5
|
+
import {ProblemFilterValues} from '../../store/reducers/settings/settings';
|
6
|
+
|
7
|
+
import {HOUR_IN_SECONDS, USE_BACKEND_PARAMS_FOR_TABLES_KEY} from '../constants';
|
8
|
+
import {NodesUptimeFilterValues} from '../nodes';
|
9
|
+
import {useSetting} from './useSetting';
|
10
|
+
|
11
|
+
interface NodesRawRequestParams
|
12
|
+
extends Omit<NodesGeneralRequestParams, 'problems_only' | 'uptime'> {
|
13
|
+
problemFilter?: ProblemFilterValue;
|
14
|
+
nodesUptimeFilter?: NodesUptimeFilterValues;
|
15
|
+
}
|
16
|
+
|
17
|
+
export const useNodesRequestParams = ({
|
18
|
+
filter,
|
19
|
+
problemFilter,
|
20
|
+
nodesUptimeFilter,
|
21
|
+
sortOrder,
|
22
|
+
sortValue,
|
23
|
+
}: NodesRawRequestParams) => {
|
24
|
+
const [useBackendParamsForTables] = useSetting<boolean>(USE_BACKEND_PARAMS_FOR_TABLES_KEY);
|
25
|
+
|
26
|
+
// If backend params are enabled, update params value to use them in fetch request
|
27
|
+
// Otherwise no params will be updated, no hooks that depend on requestParams will be triggered
|
28
|
+
return useMemo(() => {
|
29
|
+
if (useBackendParamsForTables) {
|
30
|
+
const problemsOnly = problemFilter === ProblemFilterValues.PROBLEMS;
|
31
|
+
const uptime =
|
32
|
+
nodesUptimeFilter === NodesUptimeFilterValues.SmallUptime
|
33
|
+
? HOUR_IN_SECONDS
|
34
|
+
: undefined;
|
35
|
+
|
36
|
+
return {
|
37
|
+
filter,
|
38
|
+
problems_only: problemsOnly,
|
39
|
+
uptime,
|
40
|
+
sortOrder,
|
41
|
+
sortValue,
|
42
|
+
};
|
43
|
+
}
|
44
|
+
return undefined;
|
45
|
+
}, [useBackendParamsForTables, filter, problemFilter, nodesUptimeFilter, sortOrder, sortValue]);
|
46
|
+
};
|
@@ -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
|
+
};
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import {useMemo} from 'react';
|
2
|
+
|
3
|
+
import {OrderType, SortOrder} from '@gravity-ui/react-data-table';
|
4
|
+
import {DESCENDING} from '@gravity-ui/react-data-table/build/esm/lib/constants';
|
5
|
+
|
6
|
+
interface SortParams {
|
7
|
+
sortValue: string | undefined;
|
8
|
+
sortOrder: OrderType | undefined;
|
9
|
+
}
|
10
|
+
|
11
|
+
export type HandleSort = (rawValue: SortOrder | SortOrder[] | undefined) => void;
|
12
|
+
|
13
|
+
export const useTableSort = (
|
14
|
+
{sortValue, sortOrder = DESCENDING}: SortParams,
|
15
|
+
onSort: (params: SortParams) => void,
|
16
|
+
): [SortOrder | undefined, HandleSort] => {
|
17
|
+
const sort: SortOrder | undefined = useMemo(() => {
|
18
|
+
if (!sortValue) {
|
19
|
+
return undefined;
|
20
|
+
}
|
21
|
+
|
22
|
+
return {
|
23
|
+
columnId: sortValue,
|
24
|
+
order: sortOrder,
|
25
|
+
};
|
26
|
+
}, [sortValue, sortOrder]);
|
27
|
+
|
28
|
+
const handleSort: HandleSort = (rawValue) => {
|
29
|
+
const value = Array.isArray(rawValue) ? rawValue[0] : rawValue;
|
30
|
+
onSort({
|
31
|
+
sortValue: value?.columnId,
|
32
|
+
sortOrder: value?.order,
|
33
|
+
});
|
34
|
+
};
|
35
|
+
|
36
|
+
return [sort, handleSort];
|
37
|
+
};
|
package/dist/utils/nodes.ts
CHANGED
@@ -2,6 +2,7 @@ import type {TSystemStateInfo} from '../types/api/nodes';
|
|
2
2
|
import type {TNodeInfo} from '../types/api/nodesList';
|
3
3
|
import type {NodesPreparedEntity} from '../store/reducers/nodes/types';
|
4
4
|
import type {NodesMap} from '../types/store/nodesList';
|
5
|
+
import type {ValueOf} from '../types/common';
|
5
6
|
import {EFlag} from '../types/api/enums';
|
6
7
|
|
7
8
|
export enum NodesUptimeFilterValues {
|
@@ -31,3 +32,27 @@ export const prepareNodesMap = (nodesList?: TNodeInfo[]) => {
|
|
31
32
|
return nodesMap;
|
32
33
|
}, new Map());
|
33
34
|
};
|
35
|
+
|
36
|
+
/**
|
37
|
+
* Values to sort /compute v2 and /nodes responses
|
38
|
+
*
|
39
|
+
* For actual values go to:\
|
40
|
+
* /nodes: https://github.com/ydb-platform/ydb/blob/main/ydb/core/viewer/json_nodes.h\
|
41
|
+
* /compute: https://github.com/ydb-platform/ydb/blob/main/ydb/core/viewer/json_compute.h
|
42
|
+
*/
|
43
|
+
export const NODES_SORT_VALUES = {
|
44
|
+
NodeId: 'NodeId',
|
45
|
+
Host: 'Host',
|
46
|
+
DC: 'DC',
|
47
|
+
Rack: 'Rack',
|
48
|
+
Version: 'Version',
|
49
|
+
Uptime: 'Uptime',
|
50
|
+
Memory: 'Memory',
|
51
|
+
CPU: 'CPU',
|
52
|
+
LoadAverage: 'LoadAverage',
|
53
|
+
} as const;
|
54
|
+
|
55
|
+
export type NodesSortValue = ValueOf<typeof NODES_SORT_VALUES>;
|
56
|
+
|
57
|
+
export const isSortableNodesProperty = (value: string): value is NodesSortValue =>
|
58
|
+
Object.values(NODES_SORT_VALUES).includes(value as NodesSortValue);
|