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,4 +1,5 @@
|
|
1
1
|
import type {ClusterTab} from '../../../containers/Cluster/utils';
|
2
|
+
import type {EType} from '../../../types/api/tablet';
|
2
3
|
|
3
4
|
import {setHeaderBreadcrumbs} from './header';
|
4
5
|
|
@@ -23,6 +24,7 @@ export interface TabletsBreadcrumbsOptions extends TenantBreadcrumbsOptions {
|
|
23
24
|
|
24
25
|
export interface TabletBreadcrumbsOptions extends TabletsBreadcrumbsOptions {
|
25
26
|
tabletId?: string;
|
27
|
+
tabletType?: EType;
|
26
28
|
}
|
27
29
|
|
28
30
|
export type BreadcrumbsOptions =
|
@@ -30,7 +30,7 @@ import healthcheckInfo from './healthcheckInfo';
|
|
30
30
|
import shardsWorkload from './shardsWorkload';
|
31
31
|
import hotKeys from './hotKeys';
|
32
32
|
import olapStats from './olapStats';
|
33
|
-
import authentication from './authentication';
|
33
|
+
import authentication from './authentication/authentication';
|
34
34
|
import header from './header/header';
|
35
35
|
import saveQuery from './saveQuery';
|
36
36
|
import fullscreen from './fullscreen';
|
@@ -10,6 +10,7 @@ import type {
|
|
10
10
|
ComputeApiRequestParams,
|
11
11
|
NodesAction,
|
12
12
|
NodesApiRequestParams,
|
13
|
+
NodesSortParams,
|
13
14
|
NodesState,
|
14
15
|
} from './types';
|
15
16
|
import {prepareComputeNodesData, prepareNodesData} from './utils';
|
@@ -20,6 +21,7 @@ const RESET_NODES_STATE = 'nodes/RESET_NODES_STATE';
|
|
20
21
|
const SET_NODES_UPTIME_FILTER = 'nodes/SET_NODES_UPTIME_FILTER';
|
21
22
|
const SET_DATA_WAS_NOT_LOADED = 'nodes/SET_DATA_WAS_NOT_LOADED';
|
22
23
|
const SET_SEARCH_VALUE = 'nodes/SET_SEARCH_VALUE';
|
24
|
+
const SET_SORT = 'nodes/SET_SORT';
|
23
25
|
|
24
26
|
const initialState = {
|
25
27
|
loading: false,
|
@@ -47,6 +49,10 @@ const nodes: Reducer<NodesState, NodesAction> = (state = initialState, action) =
|
|
47
49
|
};
|
48
50
|
}
|
49
51
|
case FETCH_NODES.FAILURE: {
|
52
|
+
if (action.error?.isCancelled) {
|
53
|
+
return state;
|
54
|
+
}
|
55
|
+
|
50
56
|
return {
|
51
57
|
...state,
|
52
58
|
error: action.error,
|
@@ -74,7 +80,13 @@ const nodes: Reducer<NodesState, NodesAction> = (state = initialState, action) =
|
|
74
80
|
searchValue: action.data,
|
75
81
|
};
|
76
82
|
}
|
77
|
-
|
83
|
+
case SET_SORT: {
|
84
|
+
return {
|
85
|
+
...state,
|
86
|
+
sortValue: action.data.sortValue,
|
87
|
+
sortOrder: action.data.sortOrder,
|
88
|
+
};
|
89
|
+
}
|
78
90
|
case SET_DATA_WAS_NOT_LOADED: {
|
79
91
|
return {
|
80
92
|
...state,
|
@@ -85,13 +97,11 @@ const nodes: Reducer<NodesState, NodesAction> = (state = initialState, action) =
|
|
85
97
|
return state;
|
86
98
|
}
|
87
99
|
};
|
100
|
+
const concurrentId = 'getNodes';
|
88
101
|
|
89
102
|
export function getNodes({type = 'any', ...params}: NodesApiRequestParams) {
|
90
103
|
return createApiRequest({
|
91
|
-
request: window.api.getNodes({
|
92
|
-
type,
|
93
|
-
...params,
|
94
|
-
}),
|
104
|
+
request: window.api.getNodes({type, ...params}, {concurrentId}),
|
95
105
|
actions: FETCH_NODES,
|
96
106
|
dataHandler: prepareNodesData,
|
97
107
|
});
|
@@ -99,7 +109,7 @@ export function getNodes({type = 'any', ...params}: NodesApiRequestParams) {
|
|
99
109
|
|
100
110
|
export function getComputeNodes({version = EVersion.v2, ...params}: ComputeApiRequestParams) {
|
101
111
|
return createApiRequest({
|
102
|
-
request: window.api.getCompute({version, ...params}),
|
112
|
+
request: window.api.getCompute({version, ...params}, {concurrentId}),
|
103
113
|
actions: FETCH_NODES,
|
104
114
|
dataHandler: prepareComputeNodesData,
|
105
115
|
});
|
@@ -130,4 +140,11 @@ export const setSearchValue = (value: string) => {
|
|
130
140
|
} as const;
|
131
141
|
};
|
132
142
|
|
143
|
+
export const setSort = (sortParams: NodesSortParams) => {
|
144
|
+
return {
|
145
|
+
type: SET_SORT,
|
146
|
+
data: sortParams,
|
147
|
+
} as const;
|
148
|
+
};
|
149
|
+
|
133
150
|
export default nodes;
|
@@ -1,10 +1,10 @@
|
|
1
1
|
import {Selector, createSelector} from 'reselect';
|
2
|
-
import {escapeRegExp} from 'lodash';
|
3
2
|
|
4
3
|
import {EFlag} from '../../../types/api/enums';
|
5
4
|
import {calcUptimeInSeconds} from '../../../utils';
|
6
5
|
import {HOUR_IN_SECONDS} from '../../../utils/constants';
|
7
6
|
import {NodesUptimeFilterValues} from '../../../utils/nodes';
|
7
|
+
import {prepareSearchValue} from '../../../utils/filters';
|
8
8
|
|
9
9
|
import type {ProblemFilterValue} from '../settings/types';
|
10
10
|
import type {NodesPreparedEntity, NodesStateSlice} from './types';
|
@@ -41,7 +41,7 @@ const filterNodesBySearchValue = (nodesList: NodesPreparedEntity[] = [], searchV
|
|
41
41
|
if (!searchValue) {
|
42
42
|
return nodesList;
|
43
43
|
}
|
44
|
-
const re =
|
44
|
+
const re = prepareSearchValue(searchValue);
|
45
45
|
|
46
46
|
return nodesList.filter((node) => {
|
47
47
|
return node.Host ? re.test(node.Host) || re.test(String(node.NodeId)) : true;
|
@@ -1,3 +1,5 @@
|
|
1
|
+
import type {OrderType} from '@gravity-ui/react-data-table';
|
2
|
+
|
1
3
|
import type {IResponseError} from '../../../types/api/error';
|
2
4
|
import type {TEndpoint, TPoolStats} from '../../../types/api/nodes';
|
3
5
|
import type {
|
@@ -9,13 +11,14 @@ import type {EFlag} from '../../../types/api/enums';
|
|
9
11
|
import type {ApiRequestAction} from '../../utils';
|
10
12
|
import type {VisibleEntities} from '../storage/types';
|
11
13
|
|
12
|
-
import {NodesUptimeFilterValues} from '../../../utils/nodes';
|
14
|
+
import type {NodesSortValue, NodesUptimeFilterValues} from '../../../utils/nodes';
|
13
15
|
import {
|
14
16
|
FETCH_NODES,
|
15
17
|
resetNodesState,
|
16
18
|
setDataWasNotLoaded,
|
17
19
|
setNodesUptimeFilter,
|
18
20
|
setSearchValue,
|
21
|
+
setSort,
|
19
22
|
} from './nodes';
|
20
23
|
|
21
24
|
// Since nodes from different endpoints can have different types,
|
@@ -42,6 +45,8 @@ export interface NodesState {
|
|
42
45
|
wasLoaded: boolean;
|
43
46
|
nodesUptimeFilter: NodesUptimeFilterValues;
|
44
47
|
searchValue: string;
|
48
|
+
sortValue?: NodesSortValue;
|
49
|
+
sortOrder?: OrderType;
|
45
50
|
data?: NodesPreparedEntity[];
|
46
51
|
totalNodes?: number;
|
47
52
|
error?: IResponseError;
|
@@ -49,17 +54,21 @@ export interface NodesState {
|
|
49
54
|
|
50
55
|
export type NodeType = 'static' | 'dynamic' | 'any';
|
51
56
|
|
52
|
-
interface
|
57
|
+
export interface NodesSortParams {
|
58
|
+
sortOrder?: OrderType;
|
59
|
+
sortValue?: NodesSortValue;
|
60
|
+
}
|
61
|
+
|
62
|
+
export interface NodesGeneralRequestParams extends NodesSortParams {
|
53
63
|
filter?: string; // NodeId or Host
|
54
64
|
uptime?: number; // return nodes with less uptime in seconds
|
55
65
|
problems_only?: boolean; // return nodes with SystemState !== EFlag.Green
|
56
|
-
sort?: string; // Sort by one of ESort params (may differ for /nodes and /compute)
|
57
66
|
|
58
67
|
offser?: number;
|
59
68
|
limit?: number;
|
60
69
|
}
|
61
70
|
|
62
|
-
export interface NodesApiRequestParams extends
|
71
|
+
export interface NodesApiRequestParams extends NodesGeneralRequestParams {
|
63
72
|
tenant?: string;
|
64
73
|
type?: NodeType;
|
65
74
|
visibleEntities?: VisibleEntities; // "with" param
|
@@ -67,7 +76,7 @@ export interface NodesApiRequestParams extends RequestParams {
|
|
67
76
|
tablets?: boolean;
|
68
77
|
}
|
69
78
|
|
70
|
-
export interface ComputeApiRequestParams extends
|
79
|
+
export interface ComputeApiRequestParams extends NodesGeneralRequestParams {
|
71
80
|
path: string;
|
72
81
|
version?: EVersion; // only v2 works with filters
|
73
82
|
}
|
@@ -90,6 +99,7 @@ export type NodesAction =
|
|
90
99
|
| ReturnType<typeof setDataWasNotLoaded>
|
91
100
|
| ReturnType<typeof setNodesUptimeFilter>
|
92
101
|
| ReturnType<typeof setSearchValue>
|
102
|
+
| ReturnType<typeof setSort>
|
93
103
|
| ReturnType<typeof resetNodesState>
|
94
104
|
);
|
95
105
|
|
@@ -13,6 +13,7 @@ import {
|
|
13
13
|
ENABLE_ADDITIONAL_QUERY_MODES,
|
14
14
|
CLUSTER_INFO_HIDDEN_KEY,
|
15
15
|
LAST_USED_QUERY_ACTION_KEY,
|
16
|
+
USE_BACKEND_PARAMS_FOR_TABLES_KEY,
|
16
17
|
} from '../../../utils/constants';
|
17
18
|
import '../../../services/api';
|
18
19
|
import {getValueFromLS, parseJson} from '../../../utils/utils';
|
@@ -76,6 +77,10 @@ export const initialState = {
|
|
76
77
|
[ASIDE_HEADER_COMPACT_KEY]: readSavedSettingsValue(ASIDE_HEADER_COMPACT_KEY, 'true'),
|
77
78
|
[PARTITIONS_HIDDEN_COLUMNS_KEY]: readSavedSettingsValue(PARTITIONS_HIDDEN_COLUMNS_KEY),
|
78
79
|
[CLUSTER_INFO_HIDDEN_KEY]: readSavedSettingsValue(CLUSTER_INFO_HIDDEN_KEY, 'true'),
|
80
|
+
[USE_BACKEND_PARAMS_FOR_TABLES_KEY]: readSavedSettingsValue(
|
81
|
+
USE_BACKEND_PARAMS_FOR_TABLES_KEY,
|
82
|
+
'false',
|
83
|
+
),
|
79
84
|
},
|
80
85
|
systemSettings,
|
81
86
|
};
|
@@ -1,128 +1,20 @@
|
|
1
1
|
import {Selector, createSelector} from 'reselect';
|
2
|
-
import {getUsage} from '../../../utils/storage';
|
3
2
|
|
4
|
-
import type {
|
5
|
-
import {
|
6
|
-
import {EVDiskState, TVDiskStateInfo} from '../../../types/api/vdisk';
|
7
|
-
import {EFlag} from '../../../types/api/enums';
|
8
|
-
import {getPDiskType} from '../../../utils/pdisk';
|
9
|
-
import {calcUptime} from '../../../utils';
|
3
|
+
import type {OrderType} from '@gravity-ui/react-data-table';
|
4
|
+
import {ASCENDING, DESCENDING} from '@gravity-ui/react-data-table/build/esm/lib/constants';
|
10
5
|
|
6
|
+
import type {TVDiskStateInfo} from '../../../types/api/vdisk';
|
7
|
+
import {NODES_SORT_VALUES, type NodesSortValue} from '../../../utils/nodes';
|
8
|
+
import {STORAGE_SORT_VALUES, type StorageSortValue, getUsage} from '../../../utils/storage';
|
9
|
+
|
10
|
+
import {filterNodesByUptime} from '../nodes/selectors';
|
11
11
|
import type {
|
12
12
|
PreparedStorageGroup,
|
13
13
|
PreparedStorageNode,
|
14
|
-
RawStorageGroup,
|
15
14
|
StorageStateSlice,
|
16
15
|
UsageFilter,
|
17
16
|
} from './types';
|
18
|
-
import {
|
19
|
-
|
20
|
-
// ==== Prepare data ====
|
21
|
-
const FLAGS_POINTS = {
|
22
|
-
[EFlag.Green]: 1,
|
23
|
-
[EFlag.Yellow]: 100,
|
24
|
-
[EFlag.Orange]: 10_000,
|
25
|
-
[EFlag.Red]: 1_000_000,
|
26
|
-
};
|
27
|
-
|
28
|
-
const prepareStorageGroupData = (
|
29
|
-
group: RawStorageGroup,
|
30
|
-
poolName?: string,
|
31
|
-
): PreparedStorageGroup => {
|
32
|
-
let missing = 0;
|
33
|
-
let usedSpaceFlag = 0;
|
34
|
-
let usedSpaceBytes = 0;
|
35
|
-
let limitSizeBytes = 0;
|
36
|
-
let readSpeedBytesPerSec = 0;
|
37
|
-
let writeSpeedBytesPerSec = 0;
|
38
|
-
let mediaType = '';
|
39
|
-
|
40
|
-
if (group.VDisks) {
|
41
|
-
for (const vDisk of group.VDisks) {
|
42
|
-
const {
|
43
|
-
Replicated,
|
44
|
-
VDiskState,
|
45
|
-
AvailableSize,
|
46
|
-
AllocatedSize,
|
47
|
-
PDisk,
|
48
|
-
DiskSpace,
|
49
|
-
ReadThroughput,
|
50
|
-
WriteThroughput,
|
51
|
-
} = vDisk;
|
52
|
-
|
53
|
-
if (
|
54
|
-
!Replicated ||
|
55
|
-
PDisk?.State !== TPDiskState.Normal ||
|
56
|
-
VDiskState !== EVDiskState.OK
|
57
|
-
) {
|
58
|
-
missing += 1;
|
59
|
-
}
|
60
|
-
|
61
|
-
if (DiskSpace && DiskSpace !== EFlag.Grey) {
|
62
|
-
usedSpaceFlag += FLAGS_POINTS[DiskSpace];
|
63
|
-
}
|
64
|
-
|
65
|
-
const available = Number(AvailableSize ?? PDisk?.AvailableSize) || 0;
|
66
|
-
const allocated = Number(AllocatedSize) || 0;
|
67
|
-
|
68
|
-
usedSpaceBytes += allocated;
|
69
|
-
limitSizeBytes += available + allocated;
|
70
|
-
|
71
|
-
readSpeedBytesPerSec += Number(ReadThroughput) || 0;
|
72
|
-
writeSpeedBytesPerSec += Number(WriteThroughput) || 0;
|
73
|
-
|
74
|
-
const currentType = getPDiskType(PDisk || {});
|
75
|
-
mediaType =
|
76
|
-
currentType && (currentType === mediaType || mediaType === '')
|
77
|
-
? currentType
|
78
|
-
: 'Mixed';
|
79
|
-
}
|
80
|
-
}
|
81
|
-
|
82
|
-
// VDisk doesn't have its own StoragePoolName when located inside StoragePool data
|
83
|
-
const vDisks = group.VDisks?.map((vdisk) => ({
|
84
|
-
...vdisk,
|
85
|
-
StoragePoolName: poolName,
|
86
|
-
Donors: vdisk.Donors?.map((donor) => ({
|
87
|
-
...donor,
|
88
|
-
StoragePoolName: poolName,
|
89
|
-
})),
|
90
|
-
}));
|
91
|
-
|
92
|
-
return {
|
93
|
-
...group,
|
94
|
-
VDisks: vDisks,
|
95
|
-
Read: readSpeedBytesPerSec,
|
96
|
-
Write: writeSpeedBytesPerSec,
|
97
|
-
PoolName: poolName,
|
98
|
-
Used: usedSpaceBytes,
|
99
|
-
Limit: limitSizeBytes,
|
100
|
-
Missing: missing,
|
101
|
-
UsedSpaceFlag: usedSpaceFlag,
|
102
|
-
Type: mediaType || null,
|
103
|
-
};
|
104
|
-
};
|
105
|
-
|
106
|
-
const prepareStorageNodeData = (node: TNodeInfo): PreparedStorageNode => {
|
107
|
-
const systemState = node.SystemState ?? {};
|
108
|
-
const missing =
|
109
|
-
node.PDisks?.filter((pDisk) => {
|
110
|
-
return pDisk.State !== TPDiskState.Normal;
|
111
|
-
}).length || 0;
|
112
|
-
|
113
|
-
return {
|
114
|
-
NodeId: node.NodeId,
|
115
|
-
SystemState: systemState.SystemState,
|
116
|
-
DataCenter: systemState.DataCenter,
|
117
|
-
Rack: systemState.Rack,
|
118
|
-
Host: systemState.Host,
|
119
|
-
Endpoints: systemState.Endpoints,
|
120
|
-
Uptime: calcUptime(systemState.StartTime),
|
121
|
-
StartTime: systemState.StartTime,
|
122
|
-
PDisks: node.PDisks,
|
123
|
-
Missing: missing,
|
124
|
-
};
|
125
|
-
};
|
17
|
+
import {VISIBLE_ENTITIES} from './constants';
|
126
18
|
|
127
19
|
// ==== Filters ====
|
128
20
|
|
@@ -163,24 +55,21 @@ const filterGroupsByUsage = (entities: PreparedStorageGroup[], usage?: string[])
|
|
163
55
|
}
|
164
56
|
|
165
57
|
return entities.filter((entity) => {
|
166
|
-
const entityUsage =
|
58
|
+
const entityUsage = entity.Usage;
|
167
59
|
return usage.some((val) => Number(val) <= entityUsage && entityUsage < Number(val) + 5);
|
168
60
|
});
|
169
61
|
};
|
170
62
|
|
171
63
|
// ==== Simple selectors ====
|
172
64
|
|
173
|
-
export const
|
174
|
-
|
175
|
-
|
176
|
-
found: state.storage.groups?.FoundGroups || 0,
|
177
|
-
});
|
178
|
-
export const selectStorageNodes = (state: StorageStateSlice) => state.storage.nodes?.Nodes;
|
179
|
-
export const selectStorageNodesCount = (state: StorageStateSlice) => ({
|
180
|
-
total: state.storage.nodes?.TotalNodes || 0,
|
181
|
-
found: state.storage.nodes?.FoundNodes || 0,
|
65
|
+
export const selectEntitiesCount = (state: StorageStateSlice) => ({
|
66
|
+
total: state.storage.total,
|
67
|
+
found: state.storage.found,
|
182
68
|
});
|
183
69
|
|
70
|
+
export const selectStorageGroups = (state: StorageStateSlice) => state.storage.groups;
|
71
|
+
export const selectStorageNodes = (state: StorageStateSlice) => state.storage.nodes;
|
72
|
+
|
184
73
|
export const selectStorageFilter = (state: StorageStateSlice) => state.storage.filter;
|
185
74
|
export const selectUsageFilter = (state: StorageStateSlice) => state.storage.usageFilter;
|
186
75
|
export const selectVisibleEntities = (state: StorageStateSlice) => state.storage.visible;
|
@@ -188,29 +77,39 @@ export const selectNodesUptimeFilter = (state: StorageStateSlice) =>
|
|
188
77
|
state.storage.nodesUptimeFilter;
|
189
78
|
export const selectStorageType = (state: StorageStateSlice) => state.storage.type;
|
190
79
|
|
191
|
-
// ====
|
80
|
+
// ==== Sort params selectors ====
|
81
|
+
export const selectNodesSortParams = (state: StorageStateSlice) => {
|
82
|
+
const defaultSortValue: NodesSortValue = NODES_SORT_VALUES.NodeId;
|
83
|
+
const defaultSortOrder: OrderType = ASCENDING;
|
84
|
+
|
85
|
+
return {
|
86
|
+
sortValue: state.storage.nodesSortValue || defaultSortValue,
|
87
|
+
sortOrder: state.storage.nodesSortOrder || defaultSortOrder,
|
88
|
+
};
|
89
|
+
};
|
192
90
|
|
193
|
-
const
|
194
|
-
|
195
|
-
if (!storageNodes) {
|
196
|
-
return [];
|
197
|
-
}
|
91
|
+
export const selectGroupsSortParams = (state: StorageStateSlice) => {
|
92
|
+
const visibleEntities = state.storage.visible;
|
198
93
|
|
199
|
-
|
200
|
-
|
94
|
+
let defaultSortValue: StorageSortValue = STORAGE_SORT_VALUES.PoolName;
|
95
|
+
let defaultSortOrder: OrderType = ASCENDING;
|
201
96
|
|
202
|
-
|
203
|
-
|
204
|
-
|
97
|
+
if (visibleEntities === VISIBLE_ENTITIES.missing) {
|
98
|
+
defaultSortValue = STORAGE_SORT_VALUES.Degraded;
|
99
|
+
defaultSortOrder = DESCENDING;
|
100
|
+
}
|
205
101
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
});
|
102
|
+
if (visibleEntities === VISIBLE_ENTITIES.space) {
|
103
|
+
defaultSortValue = STORAGE_SORT_VALUES.Usage;
|
104
|
+
defaultSortOrder = DESCENDING;
|
105
|
+
}
|
211
106
|
|
212
|
-
|
213
|
-
|
107
|
+
return {
|
108
|
+
sortValue: state.storage.groupsSortValue || defaultSortValue,
|
109
|
+
sortOrder: state.storage.groupsSortOrder || defaultSortOrder,
|
110
|
+
};
|
111
|
+
};
|
112
|
+
// ==== Complex selectors ====
|
214
113
|
|
215
114
|
export const selectVDisksForPDisk: Selector<
|
216
115
|
StorageStateSlice,
|
@@ -232,11 +131,12 @@ export const selectVDisksForPDisk: Selector<
|
|
232
131
|
);
|
233
132
|
|
234
133
|
export const selectUsageFilterOptions: Selector<StorageStateSlice, UsageFilter[]> = createSelector(
|
235
|
-
|
134
|
+
selectStorageGroups,
|
236
135
|
(groups) => {
|
237
136
|
const items: Record<number, number> = {};
|
238
137
|
|
239
|
-
groups
|
138
|
+
groups?.forEach((group) => {
|
139
|
+
// Get groups usage with step 5
|
240
140
|
const usage = getUsage(group, 5);
|
241
141
|
|
242
142
|
if (!Object.prototype.hasOwnProperty.call(items, usage)) {
|
@@ -256,9 +156,9 @@ export const selectUsageFilterOptions: Selector<StorageStateSlice, UsageFilter[]
|
|
256
156
|
|
257
157
|
export const selectFilteredNodes: Selector<StorageStateSlice, PreparedStorageNode[]> =
|
258
158
|
createSelector(
|
259
|
-
[
|
159
|
+
[selectStorageNodes, selectStorageFilter, selectNodesUptimeFilter],
|
260
160
|
(storageNodes, textFilter, uptimeFilter) => {
|
261
|
-
let result = storageNodes;
|
161
|
+
let result = storageNodes || [];
|
262
162
|
result = filterNodesByText(result, textFilter);
|
263
163
|
result = filterNodesByUptime(result, uptimeFilter);
|
264
164
|
|
@@ -268,9 +168,9 @@ export const selectFilteredNodes: Selector<StorageStateSlice, PreparedStorageNod
|
|
268
168
|
|
269
169
|
export const selectFilteredGroups: Selector<StorageStateSlice, PreparedStorageGroup[]> =
|
270
170
|
createSelector(
|
271
|
-
[
|
171
|
+
[selectStorageGroups, selectStorageFilter, selectUsageFilter],
|
272
172
|
(storageGroups, textFilter, usageFilter) => {
|
273
|
-
let result = storageGroups;
|
173
|
+
let result = storageGroups || [];
|
274
174
|
result = filterGroupsByText(result, textFilter);
|
275
175
|
result = filterGroupsByUsage(result, usageFilter);
|
276
176
|
|
@@ -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;
|