ydb-embedded-ui 2.4.4 → 2.6.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 +42 -0
- package/dist/components/InfoViewer/InfoViewer.scss +3 -3
- package/dist/components/InfoViewer/formatters/schema.ts +2 -1
- package/dist/components/InfoViewer/schemaInfo/CDCStreamInfo.tsx +23 -22
- package/dist/components/InfoViewer/schemaInfo/PersQueueGroupInfo.tsx +8 -13
- package/dist/components/InfoViewer/schemaInfo/TableIndexInfo.tsx +2 -12
- package/dist/components/InfoViewer/schemaOverview/CDCStreamOverview.tsx +3 -16
- package/dist/components/InfoViewer/schemaOverview/PersQueueGroupOverview.tsx +8 -13
- package/dist/components/InfoViewer/utils.ts +6 -6
- package/dist/components/Loader/Loader.scss +6 -3
- package/dist/components/Loader/Loader.tsx +7 -5
- package/dist/components/Loader/index.ts +1 -0
- package/dist/components/UptimeFIlter/UptimeFilter.tsx +21 -0
- package/dist/components/UptimeFIlter/index.ts +1 -0
- package/dist/containers/Node/Node.scss +1 -0
- package/dist/containers/Node/Node.tsx +3 -8
- package/dist/containers/Node/NodeStructure/NodeStructure.scss +0 -6
- package/dist/containers/Node/NodeStructure/NodeStructure.tsx +1 -1
- package/dist/containers/Nodes/Nodes.js +22 -10
- package/dist/{components → containers}/NodesViewer/NodesViewer.js +49 -62
- package/dist/{components → containers}/NodesViewer/NodesViewer.scss +0 -0
- package/dist/containers/Storage/Pdisk/Pdisk.scss +1 -1
- package/dist/containers/Storage/Pdisk/Pdisk.tsx +3 -9
- package/dist/containers/Storage/Pdisk/__tests__/colors.tsx +1 -1
- package/dist/containers/Storage/Storage.js +46 -11
- package/dist/containers/Storage/StorageGroups/StorageGroups.tsx +39 -32
- package/dist/containers/Storage/StorageNodes/StorageNodes.scss +2 -2
- package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +35 -17
- package/dist/containers/Storage/StorageNodes/i18n/en.json +6 -4
- package/dist/containers/Storage/StorageNodes/i18n/ru.json +6 -4
- package/dist/containers/Storage/UsageFilter/UsageFilter.scss +10 -5
- package/dist/containers/Tenant/Acl/Acl.js +1 -7
- package/dist/containers/Tenant/Diagnostics/Compute/Compute.js +22 -14
- package/dist/containers/Tenant/Diagnostics/Consumers/Consumers.tsx +52 -10
- package/dist/containers/Tenant/Diagnostics/Describe/Describe.scss +0 -8
- package/dist/containers/Tenant/Diagnostics/Describe/Describe.tsx +42 -15
- package/dist/containers/Tenant/Diagnostics/Diagnostics.scss +0 -7
- package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +19 -15
- package/dist/containers/Tenant/Diagnostics/DiagnosticsPages.ts +1 -1
- package/dist/containers/Tenant/Diagnostics/Healthcheck/Healthcheck.tsx +13 -5
- package/dist/containers/Tenant/Diagnostics/Network/Network.js +17 -4
- package/dist/containers/Tenant/Diagnostics/Overview/Overview.tsx +50 -16
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +16 -2
- package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.js +1 -0
- package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.js +21 -13
- package/dist/containers/Tenant/ObjectGeneral/ObjectGeneral.tsx +1 -5
- package/dist/containers/Tenant/QueryEditor/QueryExplain/QueryExplain.js +4 -4
- package/dist/containers/Tenant/QueryEditor/SaveQuery/SaveQuery.js +1 -4
- package/dist/containers/Tenant/Schema/SchemaInfoViewer/SchemaInfoViewer.js +23 -28
- package/dist/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx +2 -2
- package/dist/containers/Tenant/TenantPages.tsx +1 -1
- package/dist/containers/Tenant/utils/schema.ts +84 -0
- package/dist/containers/Tenant/utils/schemaActions.ts +9 -20
- package/dist/services/api.d.ts +17 -11
- package/dist/store/reducers/clusterNodes.js +29 -10
- package/dist/store/reducers/describe.ts +56 -14
- package/dist/store/reducers/healthcheckInfo.ts +23 -8
- package/dist/store/reducers/network.js +22 -1
- package/dist/store/reducers/nodes.js +37 -3
- package/dist/store/reducers/schema.ts +229 -0
- package/dist/store/reducers/storage.js +59 -5
- package/dist/types/api/enums.ts +10 -0
- package/dist/types/api/nodes.ts +96 -0
- package/dist/types/api/pdisk.ts +48 -0
- package/dist/types/api/schema.ts +148 -9
- package/dist/types/api/storage.ts +3 -173
- package/dist/types/api/tablet.ts +97 -0
- package/dist/types/api/vdisk.ts +120 -0
- package/dist/types/store/describe.ts +8 -2
- package/dist/types/store/healthcheck.ts +12 -0
- package/dist/types/store/schema.ts +52 -0
- package/dist/utils/index.js +6 -2
- package/dist/utils/nodes.ts +9 -0
- package/dist/utils/pdisk.ts +1 -1
- package/dist/utils/storage.ts +1 -1
- package/package.json +1 -1
- package/dist/store/reducers/schema.js +0 -148
@@ -3,7 +3,13 @@ import {Reducer} from 'redux';
|
|
3
3
|
|
4
4
|
import '../../services/api';
|
5
5
|
import {IConsumer} from '../../types/api/consumers';
|
6
|
-
import {
|
6
|
+
import {
|
7
|
+
IDescribeRootStateSlice,
|
8
|
+
IDescribeState,
|
9
|
+
IDescribeAction,
|
10
|
+
IDescribeHandledResponse,
|
11
|
+
IDescribeData,
|
12
|
+
} from '../../types/store/describe';
|
7
13
|
import {createRequestActionTypes, createApiRequest} from '../utils';
|
8
14
|
|
9
15
|
export const FETCH_DESCRIBE = createRequestActionTypes('describe', 'FETCH_DESCRIBE');
|
@@ -27,16 +33,8 @@ const describe: Reducer<IDescribeState, IDescribeAction> = (state = initialState
|
|
27
33
|
};
|
28
34
|
}
|
29
35
|
case FETCH_DESCRIBE.SUCCESS: {
|
30
|
-
const
|
31
|
-
|
32
|
-
const isCurrentDescribePath = data.Path === state.currentDescribePath;
|
33
|
-
|
34
|
-
let newData = state.data;
|
35
|
-
|
36
|
-
if (data.Path) {
|
37
|
-
newData = JSON.parse(JSON.stringify(state.data));
|
38
|
-
newData[data.Path] = data;
|
39
|
-
}
|
36
|
+
const isCurrentDescribePath = action.data.path === state.currentDescribePath;
|
37
|
+
const newData = {...state.data, ...action.data.data};
|
40
38
|
|
41
39
|
if (!isCurrentDescribePath) {
|
42
40
|
return {
|
@@ -48,7 +46,7 @@ const describe: Reducer<IDescribeState, IDescribeAction> = (state = initialState
|
|
48
46
|
return {
|
49
47
|
...state,
|
50
48
|
data: newData,
|
51
|
-
currentDescribe: data,
|
49
|
+
currentDescribe: action.data.currentDescribe,
|
52
50
|
loading: false,
|
53
51
|
wasLoaded: true,
|
54
52
|
error: undefined,
|
@@ -97,7 +95,7 @@ export const setDataWasNotLoaded = () => {
|
|
97
95
|
};
|
98
96
|
|
99
97
|
// Consumers selectors
|
100
|
-
const selectConsumersNames = (state: IDescribeRootStateSlice, path
|
98
|
+
const selectConsumersNames = (state: IDescribeRootStateSlice, path?: string) =>
|
101
99
|
path
|
102
100
|
? state.describe.data[path]?.PathDescription?.PersQueueGroup?.PQTabletConfig?.ReadRules
|
103
101
|
: undefined;
|
@@ -106,9 +104,53 @@ export const selectConsumers: Selector<IDescribeRootStateSlice, IConsumer[], [st
|
|
106
104
|
createSelector(selectConsumersNames, (names = []) => names.map((name) => ({name})));
|
107
105
|
|
108
106
|
export function getDescribe({path}: {path: string}) {
|
107
|
+
const request = window.api.getDescribe({path});
|
108
|
+
return createApiRequest({
|
109
|
+
request,
|
110
|
+
actions: FETCH_DESCRIBE,
|
111
|
+
dataHandler: (data): IDescribeHandledResponse => {
|
112
|
+
const dataPath = data.Path;
|
113
|
+
const currentDescribe: IDescribeData = {};
|
114
|
+
const newData: IDescribeData = {};
|
115
|
+
|
116
|
+
if (dataPath) {
|
117
|
+
currentDescribe[dataPath] = data;
|
118
|
+
newData[dataPath] = data;
|
119
|
+
}
|
120
|
+
|
121
|
+
return {
|
122
|
+
path: dataPath,
|
123
|
+
currentDescribe,
|
124
|
+
data: newData,
|
125
|
+
};
|
126
|
+
},
|
127
|
+
});
|
128
|
+
}
|
129
|
+
|
130
|
+
export function getDescribeBatched(paths: string[]) {
|
131
|
+
const requestsArray = paths.map((p) => window.api.getDescribe({path: p}));
|
132
|
+
|
133
|
+
const request = Promise.all(requestsArray);
|
109
134
|
return createApiRequest({
|
110
|
-
request
|
135
|
+
request,
|
111
136
|
actions: FETCH_DESCRIBE,
|
137
|
+
dataHandler: (data): IDescribeHandledResponse => {
|
138
|
+
const currentDescribe: IDescribeData = {};
|
139
|
+
const newData: IDescribeData = {};
|
140
|
+
|
141
|
+
data.forEach((dataItem) => {
|
142
|
+
if (dataItem.Path) {
|
143
|
+
newData[dataItem.Path] = dataItem;
|
144
|
+
currentDescribe[dataItem.Path] = dataItem;
|
145
|
+
}
|
146
|
+
});
|
147
|
+
|
148
|
+
return {
|
149
|
+
path: data[0].Path,
|
150
|
+
currentDescribe,
|
151
|
+
data: newData,
|
152
|
+
};
|
153
|
+
},
|
112
154
|
});
|
113
155
|
}
|
114
156
|
|
@@ -9,21 +9,23 @@ import {
|
|
9
9
|
IHealthcheckInfoState,
|
10
10
|
IHealthcheckInfoRootStateSlice,
|
11
11
|
IIssuesTree,
|
12
|
+
IHealthCheckInfoAction,
|
12
13
|
} from '../../types/store/healthcheck';
|
13
|
-
import {
|
14
|
-
import {IResponseError} from '../../types/api/error';
|
14
|
+
import {IssueLog, StatusFlag} from '../../types/api/healthcheck';
|
15
15
|
|
16
16
|
import '../../services/api';
|
17
|
-
import {createRequestActionTypes, createApiRequest
|
17
|
+
import {createRequestActionTypes, createApiRequest} from '../utils';
|
18
18
|
|
19
|
-
const FETCH_HEALTHCHECK = createRequestActionTypes('cluster', 'FETCH_HEALTHCHECK');
|
19
|
+
export const FETCH_HEALTHCHECK = createRequestActionTypes('cluster', 'FETCH_HEALTHCHECK');
|
20
|
+
|
21
|
+
const SET_DATA_WAS_NOT_LOADED = 'healthcheckInfo/SET_DATA_WAS_NOT_LOADED';
|
20
22
|
|
21
23
|
const initialState = {loading: false, wasLoaded: false};
|
22
24
|
|
23
|
-
const healthcheckInfo: Reducer<
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
const healthcheckInfo: Reducer<IHealthcheckInfoState, IHealthCheckInfoAction> = function (
|
26
|
+
state = initialState,
|
27
|
+
action,
|
28
|
+
) {
|
27
29
|
switch (action.type) {
|
28
30
|
case FETCH_HEALTHCHECK.REQUEST: {
|
29
31
|
return {
|
@@ -49,6 +51,13 @@ const healthcheckInfo: Reducer<
|
|
49
51
|
loading: false,
|
50
52
|
};
|
51
53
|
}
|
54
|
+
|
55
|
+
case SET_DATA_WAS_NOT_LOADED: {
|
56
|
+
return {
|
57
|
+
...state,
|
58
|
+
wasLoaded: false,
|
59
|
+
};
|
60
|
+
}
|
52
61
|
default:
|
53
62
|
return state;
|
54
63
|
}
|
@@ -127,4 +136,10 @@ export function getHealthcheckInfo(database: string) {
|
|
127
136
|
});
|
128
137
|
}
|
129
138
|
|
139
|
+
export const setDataWasNotLoaded = () => {
|
140
|
+
return {
|
141
|
+
type: SET_DATA_WAS_NOT_LOADED,
|
142
|
+
} as const;
|
143
|
+
};
|
144
|
+
|
130
145
|
export default healthcheckInfo;
|
@@ -6,7 +6,15 @@ const FETCH_ALL_NODES_NETWORK = createRequestActionTypes(
|
|
6
6
|
'FETCH_ALL_NODES_NETWORK',
|
7
7
|
);
|
8
8
|
|
9
|
-
const
|
9
|
+
const SET_DATA_WAS_NOT_LOADED = 'network/SET_DATA_WAS_NOT_LOADED';
|
10
|
+
|
11
|
+
const initialState = {
|
12
|
+
data: {},
|
13
|
+
loading: false,
|
14
|
+
wasLoaded: false,
|
15
|
+
};
|
16
|
+
|
17
|
+
const network = (state = initialState, action) => {
|
10
18
|
switch (action.type) {
|
11
19
|
case FETCH_ALL_NODES_NETWORK.REQUEST: {
|
12
20
|
return {
|
@@ -30,11 +38,24 @@ const network = (state = {data: {}, loading: true, wasLoaded: false}, action) =>
|
|
30
38
|
loading: false,
|
31
39
|
};
|
32
40
|
}
|
41
|
+
|
42
|
+
case SET_DATA_WAS_NOT_LOADED: {
|
43
|
+
return {
|
44
|
+
...state,
|
45
|
+
wasLoaded: false,
|
46
|
+
};
|
47
|
+
}
|
33
48
|
default:
|
34
49
|
return state;
|
35
50
|
}
|
36
51
|
};
|
37
52
|
|
53
|
+
export const setDataWasNotLoaded = () => {
|
54
|
+
return {
|
55
|
+
type: SET_DATA_WAS_NOT_LOADED,
|
56
|
+
};
|
57
|
+
};
|
58
|
+
|
38
59
|
export const getNetworkInfo = (tenant) => {
|
39
60
|
return createApiRequest({
|
40
61
|
request: window.api.getNetwork(tenant),
|
@@ -1,9 +1,20 @@
|
|
1
1
|
import {createRequestActionTypes, createApiRequest} from '../utils';
|
2
2
|
import '../../services/api';
|
3
|
+
import {NodesUptimeFilterValues} from '../../utils/nodes';
|
3
4
|
|
4
5
|
const FETCH_NODES = createRequestActionTypes('nodes', 'FETCH_NODES');
|
5
6
|
|
6
|
-
const
|
7
|
+
const CLEAR_NODES = 'nodes/CLEAR_NODES';
|
8
|
+
const SET_NODES_UPTIME_FILTER = 'nodes/SET_NODES_UPTIME_FILTER';
|
9
|
+
const SET_DATA_WAS_NOT_LOADED = 'nodes/SET_DATA_WAS_NOT_LOADED';
|
10
|
+
|
11
|
+
const initialState = {
|
12
|
+
loading: true,
|
13
|
+
wasLoaded: false,
|
14
|
+
nodesUptimeFilter: NodesUptimeFilterValues.All,
|
15
|
+
};
|
16
|
+
|
17
|
+
const nodes = (state = initialState, action) => {
|
7
18
|
switch (action.type) {
|
8
19
|
case FETCH_NODES.REQUEST: {
|
9
20
|
return {
|
@@ -28,7 +39,7 @@ const nodes = function z(state = {loading: true, wasLoaded: false}, action) {
|
|
28
39
|
loading: false,
|
29
40
|
};
|
30
41
|
}
|
31
|
-
case
|
42
|
+
case CLEAR_NODES: {
|
32
43
|
return {
|
33
44
|
...state,
|
34
45
|
loading: true,
|
@@ -38,6 +49,16 @@ const nodes = function z(state = {loading: true, wasLoaded: false}, action) {
|
|
38
49
|
error: undefined,
|
39
50
|
};
|
40
51
|
}
|
52
|
+
|
53
|
+
case SET_NODES_UPTIME_FILTER: {
|
54
|
+
return {...state, nodesUptimeFilter: action.data};
|
55
|
+
}
|
56
|
+
case SET_DATA_WAS_NOT_LOADED: {
|
57
|
+
return {
|
58
|
+
...state,
|
59
|
+
wasLoaded: false,
|
60
|
+
};
|
61
|
+
}
|
41
62
|
default:
|
42
63
|
return state;
|
43
64
|
}
|
@@ -50,6 +71,19 @@ export function getNodes(path) {
|
|
50
71
|
});
|
51
72
|
}
|
52
73
|
|
53
|
-
export const clearNodes = () => ({type:
|
74
|
+
export const clearNodes = () => ({type: CLEAR_NODES});
|
75
|
+
|
76
|
+
export const setNodesUptimeFilter = (value) => ({
|
77
|
+
type: SET_NODES_UPTIME_FILTER,
|
78
|
+
data: value,
|
79
|
+
});
|
80
|
+
|
81
|
+
export const setDataWasNotLoaded = () => {
|
82
|
+
return {
|
83
|
+
type: SET_DATA_WAS_NOT_LOADED,
|
84
|
+
};
|
85
|
+
};
|
86
|
+
|
87
|
+
export const getNodesUptimeFilter = (state) => state.nodes.nodesUptimeFilter;
|
54
88
|
|
55
89
|
export default nodes;
|
@@ -0,0 +1,229 @@
|
|
1
|
+
import {Reducer} from 'redux';
|
2
|
+
import {createSelector, Selector} from 'reselect';
|
3
|
+
|
4
|
+
import {
|
5
|
+
ISchemaAction,
|
6
|
+
ISchemaData,
|
7
|
+
ISchemaHandledResponse,
|
8
|
+
ISchemaRootStateSlice,
|
9
|
+
ISchemaState,
|
10
|
+
} from '../../types/store/schema';
|
11
|
+
import {EPathType} from '../../types/api/schema';
|
12
|
+
import '../../services/api';
|
13
|
+
import {isEntityWithMergedImplementation} from '../../containers/Tenant/utils/schema';
|
14
|
+
|
15
|
+
import {createRequestActionTypes, createApiRequest} from '../utils';
|
16
|
+
|
17
|
+
export const FETCH_SCHEMA = createRequestActionTypes('schema', 'FETCH_SCHEMA');
|
18
|
+
const PRELOAD_SCHEMAS = 'schema/PRELOAD_SCHEMAS';
|
19
|
+
const SET_SCHEMA = 'schema/SET_SCHEMA';
|
20
|
+
const SET_SHOW_PREVIEW = 'schema/SET_SHOW_PREVIEW';
|
21
|
+
const ENABLE_AUTOREFRESH = 'schema/ENABLE_AUTOREFRESH';
|
22
|
+
const DISABLE_AUTOREFRESH = 'schema/DISABLE_AUTOREFRESH';
|
23
|
+
const RESET_LOADING_STATE = 'schema/RESET_LOADING_STATE';
|
24
|
+
|
25
|
+
export const initialState = {
|
26
|
+
loading: true,
|
27
|
+
wasLoaded: false,
|
28
|
+
data: {},
|
29
|
+
currentSchemaPath: undefined,
|
30
|
+
autorefresh: false,
|
31
|
+
showPreview: false,
|
32
|
+
};
|
33
|
+
|
34
|
+
const schema: Reducer<ISchemaState, ISchemaAction> = (state = initialState, action) => {
|
35
|
+
switch (action.type) {
|
36
|
+
case FETCH_SCHEMA.REQUEST: {
|
37
|
+
return {
|
38
|
+
...state,
|
39
|
+
loading: true,
|
40
|
+
};
|
41
|
+
}
|
42
|
+
case FETCH_SCHEMA.SUCCESS: {
|
43
|
+
const isCurrentSchema =
|
44
|
+
!state.currentSchemaPath || state.currentSchemaPath === action.data.path;
|
45
|
+
|
46
|
+
const newData = {...state.data, ...action.data.data};
|
47
|
+
|
48
|
+
if (!isCurrentSchema) {
|
49
|
+
return {
|
50
|
+
...state,
|
51
|
+
data: newData,
|
52
|
+
};
|
53
|
+
}
|
54
|
+
|
55
|
+
return {
|
56
|
+
...state,
|
57
|
+
error: undefined,
|
58
|
+
data: newData,
|
59
|
+
currentSchema: action.data.currentSchema,
|
60
|
+
currentSchemaPath: action.data.path,
|
61
|
+
loading: false,
|
62
|
+
wasLoaded: true,
|
63
|
+
};
|
64
|
+
}
|
65
|
+
case FETCH_SCHEMA.FAILURE: {
|
66
|
+
if (action.error?.isCancelled) {
|
67
|
+
return state;
|
68
|
+
}
|
69
|
+
|
70
|
+
return {
|
71
|
+
...state,
|
72
|
+
error: action.error,
|
73
|
+
loading: false,
|
74
|
+
};
|
75
|
+
}
|
76
|
+
case PRELOAD_SCHEMAS: {
|
77
|
+
return {
|
78
|
+
...state,
|
79
|
+
data: {
|
80
|
+
// we don't want to overwrite existing paths
|
81
|
+
...action.data,
|
82
|
+
...state.data,
|
83
|
+
},
|
84
|
+
};
|
85
|
+
}
|
86
|
+
case SET_SCHEMA: {
|
87
|
+
return {
|
88
|
+
...state,
|
89
|
+
currentSchemaPath: action.data,
|
90
|
+
wasLoaded: false,
|
91
|
+
};
|
92
|
+
}
|
93
|
+
case ENABLE_AUTOREFRESH: {
|
94
|
+
return {
|
95
|
+
...state,
|
96
|
+
autorefresh: true,
|
97
|
+
};
|
98
|
+
}
|
99
|
+
case DISABLE_AUTOREFRESH: {
|
100
|
+
return {
|
101
|
+
...state,
|
102
|
+
autorefresh: false,
|
103
|
+
};
|
104
|
+
}
|
105
|
+
case SET_SHOW_PREVIEW: {
|
106
|
+
return {
|
107
|
+
...state,
|
108
|
+
showPreview: action.data,
|
109
|
+
};
|
110
|
+
}
|
111
|
+
case RESET_LOADING_STATE: {
|
112
|
+
return {
|
113
|
+
...state,
|
114
|
+
wasLoaded: initialState.wasLoaded,
|
115
|
+
};
|
116
|
+
}
|
117
|
+
default:
|
118
|
+
return state;
|
119
|
+
}
|
120
|
+
};
|
121
|
+
|
122
|
+
export function getSchema({path}: {path: string}) {
|
123
|
+
const request = window.api.getSchema({path});
|
124
|
+
return createApiRequest({
|
125
|
+
request,
|
126
|
+
actions: FETCH_SCHEMA,
|
127
|
+
dataHandler: (data): ISchemaHandledResponse => {
|
128
|
+
const newData: ISchemaData = {};
|
129
|
+
if (data.Path) {
|
130
|
+
newData[data.Path] = data;
|
131
|
+
}
|
132
|
+
return {
|
133
|
+
path: data.Path,
|
134
|
+
currentSchema: data,
|
135
|
+
data: newData,
|
136
|
+
};
|
137
|
+
},
|
138
|
+
});
|
139
|
+
}
|
140
|
+
|
141
|
+
export function getSchemaBatched(paths: string[]) {
|
142
|
+
const requestArray = paths.map((p) =>
|
143
|
+
window.api.getSchema({path: p}, {concurrentId: `getSchemaBatched|${p}`}),
|
144
|
+
);
|
145
|
+
const request = Promise.all(requestArray);
|
146
|
+
|
147
|
+
return createApiRequest({
|
148
|
+
request,
|
149
|
+
actions: FETCH_SCHEMA,
|
150
|
+
dataHandler: (data): ISchemaHandledResponse => {
|
151
|
+
const newData: ISchemaData = {};
|
152
|
+
|
153
|
+
data.forEach((dataItem) => {
|
154
|
+
if (dataItem.Path) {
|
155
|
+
newData[dataItem.Path] = dataItem;
|
156
|
+
}
|
157
|
+
});
|
158
|
+
|
159
|
+
return {
|
160
|
+
path: data[0].Path,
|
161
|
+
currentSchema: data[0],
|
162
|
+
data: newData,
|
163
|
+
};
|
164
|
+
},
|
165
|
+
});
|
166
|
+
}
|
167
|
+
|
168
|
+
export function setCurrentSchemaPath(currentSchemaPath: string) {
|
169
|
+
return {
|
170
|
+
type: SET_SCHEMA,
|
171
|
+
data: currentSchemaPath,
|
172
|
+
} as const;
|
173
|
+
}
|
174
|
+
export function enableAutorefresh() {
|
175
|
+
return {
|
176
|
+
type: ENABLE_AUTOREFRESH,
|
177
|
+
} as const;
|
178
|
+
}
|
179
|
+
export function disableAutorefresh() {
|
180
|
+
return {
|
181
|
+
type: DISABLE_AUTOREFRESH,
|
182
|
+
} as const;
|
183
|
+
}
|
184
|
+
export function setShowPreview(value: boolean) {
|
185
|
+
return {
|
186
|
+
type: SET_SHOW_PREVIEW,
|
187
|
+
data: value,
|
188
|
+
} as const;
|
189
|
+
}
|
190
|
+
|
191
|
+
// only stores data for paths that are not in the store yet
|
192
|
+
// existing paths are ignored
|
193
|
+
export function preloadSchemas(data: ISchemaData) {
|
194
|
+
return {
|
195
|
+
type: PRELOAD_SCHEMAS,
|
196
|
+
data,
|
197
|
+
} as const;
|
198
|
+
}
|
199
|
+
|
200
|
+
export function resetLoadingState() {
|
201
|
+
return {
|
202
|
+
type: RESET_LOADING_STATE,
|
203
|
+
} as const;
|
204
|
+
}
|
205
|
+
|
206
|
+
export const selectSchemaChildren = (state: ISchemaRootStateSlice, path?: string) =>
|
207
|
+
path ? state.schema.data[path]?.PathDescription?.Children : undefined;
|
208
|
+
|
209
|
+
export const selectSchemaData = (state: ISchemaRootStateSlice, path?: string) =>
|
210
|
+
path ? state.schema.data[path] : undefined;
|
211
|
+
|
212
|
+
export const selectSchemaMergedChildrenPaths: Selector<
|
213
|
+
ISchemaRootStateSlice,
|
214
|
+
string[] | undefined,
|
215
|
+
[string | undefined, EPathType | undefined]
|
216
|
+
> = createSelector(
|
217
|
+
[
|
218
|
+
(_, path?: string) => path,
|
219
|
+
(_, _path, type: EPathType | undefined) => type,
|
220
|
+
selectSchemaChildren,
|
221
|
+
],
|
222
|
+
(path, type, children) => {
|
223
|
+
return isEntityWithMergedImplementation(type)
|
224
|
+
? children?.map(({Name}) => path + '/' + Name)
|
225
|
+
: undefined;
|
226
|
+
},
|
227
|
+
);
|
228
|
+
|
229
|
+
export default schema;
|
@@ -1,10 +1,14 @@
|
|
1
|
-
import {createRequestActionTypes, createApiRequest} from '../utils';
|
2
|
-
import '../../services/api';
|
3
1
|
import _ from 'lodash';
|
4
2
|
import {createSelector} from 'reselect';
|
5
|
-
|
3
|
+
|
4
|
+
import {calcUptime, calcUptimeInSeconds} from '../../utils';
|
6
5
|
import {getUsage} from '../../utils/storage';
|
6
|
+
import {NodesUptimeFilterValues} from '../../utils/nodes';
|
7
7
|
import {getPDiskType} from '../../utils/pdisk';
|
8
|
+
import {HOUR_IN_SECONDS} from '../../utils/constants';
|
9
|
+
import '../../services/api';
|
10
|
+
|
11
|
+
import {createRequestActionTypes, createApiRequest} from '../utils';
|
8
12
|
|
9
13
|
export const VisibleEntities = {
|
10
14
|
All: 'All',
|
@@ -29,6 +33,8 @@ const SET_FILTER = 'storage/SET_FILTER';
|
|
29
33
|
const SET_USAGE_FILTER = 'storage/SET_USAGE_FILTER';
|
30
34
|
const SET_VISIBLE_GROUPS = 'storage/SET_VISIBLE_GROUPS';
|
31
35
|
const SET_STORAGE_TYPE = 'storage/SET_STORAGE_TYPE';
|
36
|
+
const SET_NODES_UPTIME_FILTER = 'storage/SET_NODES_UPTIME_FILTER';
|
37
|
+
const SET_DATA_WAS_NOT_LOADED = 'storage/SET_DATA_WAS_NOT_LOADED';
|
32
38
|
|
33
39
|
const initialState = {
|
34
40
|
loading: true,
|
@@ -36,6 +42,7 @@ const initialState = {
|
|
36
42
|
filter: '',
|
37
43
|
usageFilter: [],
|
38
44
|
visible: VisibleEntities.Missing,
|
45
|
+
nodesUptimeFilter: NodesUptimeFilterValues.All,
|
39
46
|
type: StorageTypes.groups,
|
40
47
|
};
|
41
48
|
|
@@ -93,6 +100,13 @@ const storage = (state = initialState, action) => {
|
|
93
100
|
error: undefined,
|
94
101
|
};
|
95
102
|
}
|
103
|
+
|
104
|
+
case SET_NODES_UPTIME_FILTER: {
|
105
|
+
return {
|
106
|
+
...state,
|
107
|
+
nodesUptimeFilter: action.data,
|
108
|
+
};
|
109
|
+
}
|
96
110
|
case SET_STORAGE_TYPE: {
|
97
111
|
return {
|
98
112
|
...state,
|
@@ -103,6 +117,12 @@ const storage = (state = initialState, action) => {
|
|
103
117
|
error: undefined,
|
104
118
|
};
|
105
119
|
}
|
120
|
+
case SET_DATA_WAS_NOT_LOADED: {
|
121
|
+
return {
|
122
|
+
...state,
|
123
|
+
wasLoaded: false,
|
124
|
+
};
|
125
|
+
}
|
106
126
|
default:
|
107
127
|
return state;
|
108
128
|
}
|
@@ -149,6 +169,19 @@ export function setVisibleEntities(value) {
|
|
149
169
|
};
|
150
170
|
}
|
151
171
|
|
172
|
+
export function setNodesUptimeFilter(value) {
|
173
|
+
return {
|
174
|
+
type: SET_NODES_UPTIME_FILTER,
|
175
|
+
data: value,
|
176
|
+
};
|
177
|
+
}
|
178
|
+
|
179
|
+
export const setDataWasNotLoaded = () => {
|
180
|
+
return {
|
181
|
+
type: SET_DATA_WAS_NOT_LOADED,
|
182
|
+
};
|
183
|
+
};
|
184
|
+
|
152
185
|
export const getStoragePools = (state) => state.storage.data?.StoragePools;
|
153
186
|
export const getStoragePoolsGroupsCount = (state) => ({
|
154
187
|
total: state.storage.data?.TotalGroups || 0,
|
@@ -162,6 +195,7 @@ export const getStorageNodesCount = (state) => ({
|
|
162
195
|
export const getStorageFilter = (state) => state.storage.filter;
|
163
196
|
export const getUsageFilter = (state) => state.storage.usageFilter;
|
164
197
|
export const getVisibleEntities = (state) => state.storage.visible;
|
198
|
+
export const getNodesUptimeFilter = (state) => state.storage.nodesUptimeFilter;
|
165
199
|
export const getStorageType = (state) => state.storage.type;
|
166
200
|
export const getNodesObject = (state) =>
|
167
201
|
_.reduce(
|
@@ -337,12 +371,32 @@ const filterByUsage = (entities, usage) => {
|
|
337
371
|
});
|
338
372
|
};
|
339
373
|
|
374
|
+
export const filterByUptime = (nodes = [], nodesUptimeFilter) => {
|
375
|
+
if (nodesUptimeFilter === NodesUptimeFilterValues.All) {
|
376
|
+
return nodes;
|
377
|
+
}
|
378
|
+
return nodes.filter(({StartTime}) => {
|
379
|
+
return !StartTime || calcUptimeInSeconds(StartTime) < HOUR_IN_SECONDS;
|
380
|
+
});
|
381
|
+
};
|
382
|
+
|
340
383
|
export const getFilteredEntities = createSelector(
|
341
|
-
[
|
342
|
-
|
384
|
+
[
|
385
|
+
getStorageFilter,
|
386
|
+
getUsageFilter,
|
387
|
+
getStorageType,
|
388
|
+
getNodesUptimeFilter,
|
389
|
+
getVisibleEntitiesList,
|
390
|
+
],
|
391
|
+
(textFilter, usageFilter, type, nodesUptimeFilter, entities) => {
|
343
392
|
let result = entities;
|
344
393
|
result = filterByText(result, type, textFilter);
|
345
394
|
result = filterByUsage(result, usageFilter);
|
395
|
+
|
396
|
+
if (type === StorageTypes.nodes) {
|
397
|
+
result = filterByUptime(result, nodesUptimeFilter);
|
398
|
+
}
|
399
|
+
|
346
400
|
return result;
|
347
401
|
},
|
348
402
|
);
|
@@ -0,0 +1,10 @@
|
|
1
|
+
// Shows system status
|
2
|
+
// Currently is used in response types of viewer/json/nodes and viewer/json/storage
|
3
|
+
// Probably will appear in /viewer/json/tenantinfo /viewer/json/cluster /viewer/json/tabletinfo /viewer/json/compute
|
4
|
+
export enum EFlag {
|
5
|
+
Grey = 'Grey',
|
6
|
+
Green = 'Green',
|
7
|
+
Yellow = 'Yellow',
|
8
|
+
Orange = 'Orange',
|
9
|
+
Red = 'Red',
|
10
|
+
}
|