ydb-embedded-ui 3.4.5 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +41 -0
- package/dist/components/InfoViewer/formatters/table.ts +6 -0
- package/dist/components/TruncatedQuery/TruncatedQuery.js +1 -1
- package/dist/components/TruncatedQuery/TruncatedQuery.scss +7 -3
- package/dist/containers/Node/{NodePages.js → NodePages.ts} +1 -1
- package/dist/containers/Tablet/TabletControls/TabletControls.tsx +2 -2
- package/dist/containers/Tenant/Diagnostics/Overview/Overview.tsx +11 -43
- package/dist/containers/Tenant/Diagnostics/Overview/TableInfo/TableInfo.tsx +19 -17
- package/dist/containers/Tenant/Diagnostics/Overview/TableInfo/prepareTableInfo.ts +192 -37
- package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.scss +20 -14
- package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.tsx +49 -12
- package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.tsx +37 -18
- package/dist/containers/Tenant/QueryEditor/QueriesHistory/QueriesHistory.tsx +3 -3
- package/dist/containers/Tenant/QueryEditor/QueryDuration/QueryDuration.scss +8 -0
- package/dist/containers/Tenant/QueryEditor/QueryDuration/QueryDuration.tsx +21 -0
- package/dist/containers/Tenant/QueryEditor/QueryEditor.js +58 -82
- package/dist/containers/Tenant/QueryEditor/QueryEditor.scss +0 -33
- package/dist/containers/Tenant/QueryEditor/QueryEditorControls/OldQueryEditorControls.tsx +83 -0
- package/dist/containers/Tenant/QueryEditor/QueryEditorControls/QueryEditorControls.scss +57 -0
- package/dist/containers/Tenant/QueryEditor/QueryEditorControls/QueryEditorControls.tsx +84 -0
- package/dist/containers/Tenant/QueryEditor/QueryEditorControls/shared.ts +23 -0
- package/dist/containers/Tenant/QueryEditor/QueryExplain/QueryExplain.js +12 -23
- package/dist/containers/Tenant/QueryEditor/QueryResult/QueryResult.js +4 -6
- package/dist/containers/Tenant/QueryEditor/i18n/en.json +3 -0
- package/dist/containers/Tenant/QueryEditor/i18n/index.ts +11 -0
- package/dist/containers/Tenant/QueryEditor/i18n/ru.json +3 -0
- package/dist/containers/UserSettings/UserSettings.tsx +30 -1
- package/dist/routes.ts +1 -1
- package/dist/services/api.d.ts +4 -3
- package/dist/services/api.js +5 -5
- package/dist/store/reducers/{executeQuery.js → executeQuery.ts} +48 -43
- package/dist/store/reducers/executeTopQueries.ts +5 -1
- package/dist/store/reducers/{explainQuery.js → explainQuery.ts} +44 -59
- package/dist/store/reducers/{olapStats.js → olapStats.ts} +8 -18
- package/dist/store/reducers/settings.js +19 -4
- package/dist/store/reducers/storage.js +5 -7
- package/dist/types/api/error.ts +14 -0
- package/dist/types/api/query.ts +227 -115
- package/dist/types/api/schema.ts +523 -3
- package/dist/types/common.ts +1 -0
- package/dist/types/store/executeQuery.ts +38 -0
- package/dist/types/store/explainQuery.ts +38 -0
- package/dist/types/store/olapStats.ts +14 -0
- package/dist/types/store/query.ts +23 -3
- package/dist/utils/constants.ts +2 -1
- package/dist/utils/error.ts +25 -0
- package/dist/utils/index.js +0 -49
- package/dist/utils/prepareQueryExplain.ts +7 -24
- package/dist/utils/query.test.ts +148 -213
- package/dist/utils/query.ts +68 -90
- package/dist/utils/timeParsers/formatDuration.ts +30 -12
- package/dist/utils/timeParsers/i18n/en.json +9 -5
- package/dist/utils/timeParsers/i18n/ru.json +9 -5
- package/dist/utils/timeParsers/parsers.ts +9 -0
- package/dist/utils/utils.js +1 -2
- package/package.json +1 -1
@@ -1,35 +1,40 @@
|
|
1
|
-
import {
|
2
|
-
|
1
|
+
import type {Reducer} from 'redux';
|
2
|
+
|
3
|
+
import type {ExecuteActions} from '../../types/api/query';
|
4
|
+
import type {
|
5
|
+
ExecuteQueryAction,
|
6
|
+
ExecuteQueryState,
|
7
|
+
MonacoHotKeyAction,
|
8
|
+
} from '../../types/store/executeQuery';
|
9
|
+
import type {QueryRequestParams, QueryModes} from '../../types/store/query';
|
3
10
|
import {getValueFromLS, parseJson} from '../../utils/utils';
|
4
|
-
import {QUERIES_HISTORY_KEY
|
11
|
+
import {QUERIES_HISTORY_KEY} from '../../utils/constants';
|
5
12
|
import {parseQueryAPIExecuteResponse} from '../../utils/query';
|
6
|
-
import {
|
13
|
+
import {parseQueryError} from '../../utils/error';
|
14
|
+
import '../../services/api';
|
15
|
+
|
16
|
+
import {createRequestActionTypes, createApiRequest} from '../utils';
|
7
17
|
|
8
18
|
const MAXIMUM_QUERIES_IN_HISTORY = 20;
|
9
19
|
|
10
|
-
const SEND_QUERY = createRequestActionTypes('query', 'SEND_QUERY');
|
20
|
+
export const SEND_QUERY = createRequestActionTypes('query', 'SEND_QUERY');
|
21
|
+
|
11
22
|
const CHANGE_USER_INPUT = 'query/CHANGE_USER_INPUT';
|
12
23
|
const SAVE_QUERY_TO_HISTORY = 'query/SAVE_QUERY_TO_HISTORY';
|
13
24
|
const GO_TO_PREVIOUS_QUERY = 'query/GO_TO_PREVIOUS_QUERY';
|
14
25
|
const GO_TO_NEXT_QUERY = 'query/GO_TO_NEXT_QUERY';
|
15
|
-
const SELECT_RUN_ACTION = 'query/SELECT_RUN_ACTION';
|
16
26
|
const MONACO_HOT_KEY = 'query/MONACO_HOT_KEY';
|
17
27
|
|
18
|
-
const queriesHistoryInitial = parseJson(getValueFromLS(QUERIES_HISTORY_KEY, '[]'));
|
28
|
+
const queriesHistoryInitial: string[] = parseJson(getValueFromLS(QUERIES_HISTORY_KEY, '[]'));
|
19
29
|
|
20
30
|
const sliceLimit = queriesHistoryInitial.length - MAXIMUM_QUERIES_IN_HISTORY;
|
21
31
|
|
22
|
-
export const RUN_ACTIONS_VALUES = {
|
23
|
-
script: 'execute-script',
|
24
|
-
scan: 'execute-scan',
|
25
|
-
};
|
26
|
-
|
27
32
|
export const MONACO_HOT_KEY_ACTIONS = {
|
28
33
|
sendQuery: 'sendQuery',
|
29
34
|
goPrev: 'goPrev',
|
30
35
|
goNext: 'goNext',
|
31
36
|
getExplain: 'getExplain',
|
32
|
-
};
|
37
|
+
} as const;
|
33
38
|
|
34
39
|
const initialState = {
|
35
40
|
loading: false,
|
@@ -41,11 +46,13 @@ const initialState = {
|
|
41
46
|
? MAXIMUM_QUERIES_IN_HISTORY - 1
|
42
47
|
: queriesHistoryInitial.length - 1,
|
43
48
|
},
|
44
|
-
runAction: readSavedSettingsValue(QUERY_INITIAL_RUN_ACTION_KEY, RUN_ACTIONS_VALUES.script),
|
45
49
|
monacoHotKey: null,
|
46
50
|
};
|
47
51
|
|
48
|
-
const executeQuery
|
52
|
+
const executeQuery: Reducer<ExecuteQueryState, ExecuteQueryAction> = (
|
53
|
+
state = initialState,
|
54
|
+
action,
|
55
|
+
) => {
|
49
56
|
switch (action.type) {
|
50
57
|
case SEND_QUERY.REQUEST: {
|
51
58
|
return {
|
@@ -64,22 +71,14 @@ const executeQuery = (state = initialState, action) => {
|
|
64
71
|
error: undefined,
|
65
72
|
};
|
66
73
|
}
|
67
|
-
// 401 Unauthorized error is handled by GenericAPI
|
68
74
|
case SEND_QUERY.FAILURE: {
|
69
75
|
return {
|
70
76
|
...state,
|
71
|
-
error: action.error
|
77
|
+
error: parseQueryError(action.error),
|
72
78
|
loading: false,
|
73
79
|
};
|
74
80
|
}
|
75
81
|
|
76
|
-
case SELECT_RUN_ACTION: {
|
77
|
-
return {
|
78
|
-
...state,
|
79
|
-
runAction: action.data,
|
80
|
-
};
|
81
|
-
}
|
82
|
-
|
83
82
|
case CHANGE_USER_INPUT: {
|
84
83
|
return {
|
85
84
|
...state,
|
@@ -141,51 +140,57 @@ const executeQuery = (state = initialState, action) => {
|
|
141
140
|
}
|
142
141
|
};
|
143
142
|
|
144
|
-
|
143
|
+
interface SendQueryParams extends QueryRequestParams {
|
144
|
+
mode?: QueryModes;
|
145
|
+
}
|
146
|
+
|
147
|
+
export const sendExecuteQuery = ({query, database, mode}: SendQueryParams) => {
|
148
|
+
const action: ExecuteActions = mode ? `execute-${mode}` : 'execute';
|
149
|
+
|
145
150
|
return createApiRequest({
|
146
|
-
request: window.api.sendQuery({
|
151
|
+
request: window.api.sendQuery({
|
152
|
+
schema: 'modern',
|
153
|
+
query,
|
154
|
+
database,
|
155
|
+
action,
|
156
|
+
stats: 'profile',
|
157
|
+
}),
|
147
158
|
actions: SEND_QUERY,
|
148
159
|
dataHandler: parseQueryAPIExecuteResponse,
|
149
160
|
});
|
150
161
|
};
|
151
162
|
|
152
|
-
export const saveQueryToHistory = (query) => {
|
163
|
+
export const saveQueryToHistory = (query: string) => {
|
153
164
|
return {
|
154
165
|
type: SAVE_QUERY_TO_HISTORY,
|
155
166
|
data: query,
|
156
|
-
};
|
157
|
-
};
|
158
|
-
|
159
|
-
export const selectRunAction = (value) => {
|
160
|
-
return {
|
161
|
-
type: SELECT_RUN_ACTION,
|
162
|
-
data: value,
|
163
|
-
};
|
167
|
+
} as const;
|
164
168
|
};
|
165
169
|
|
166
170
|
export const goToPreviousQuery = () => {
|
167
171
|
return {
|
168
172
|
type: GO_TO_PREVIOUS_QUERY,
|
169
|
-
};
|
173
|
+
} as const;
|
170
174
|
};
|
171
175
|
|
172
176
|
export const goToNextQuery = () => {
|
173
177
|
return {
|
174
178
|
type: GO_TO_NEXT_QUERY,
|
175
|
-
};
|
179
|
+
} as const;
|
176
180
|
};
|
177
181
|
|
178
|
-
export const changeUserInput = ({input}) => {
|
179
|
-
return
|
180
|
-
|
181
|
-
|
182
|
+
export const changeUserInput = ({input}: {input: string}) => {
|
183
|
+
return {
|
184
|
+
type: CHANGE_USER_INPUT,
|
185
|
+
data: {input},
|
186
|
+
} as const;
|
182
187
|
};
|
183
188
|
|
184
|
-
export const setMonacoHotKey = (value) => {
|
189
|
+
export const setMonacoHotKey = (value: MonacoHotKeyAction) => {
|
185
190
|
return {
|
186
191
|
type: MONACO_HOT_KEY,
|
187
192
|
data: value,
|
188
|
-
};
|
193
|
+
} as const;
|
189
194
|
};
|
190
195
|
|
191
196
|
export default executeQuery;
|
@@ -66,7 +66,11 @@ const getQueryText = (path: string, filters?: ITopQueriesFilters) => {
|
|
66
66
|
SELECT
|
67
67
|
CPUTime as CPUTimeUs,
|
68
68
|
QueryText,
|
69
|
-
IntervalEnd
|
69
|
+
IntervalEnd,
|
70
|
+
EndTime,
|
71
|
+
ReadRows,
|
72
|
+
ReadBytes,
|
73
|
+
UserSID
|
70
74
|
FROM \`${path}/.sys/top_queries_by_cpu_time_one_hour\`
|
71
75
|
WHERE ${filterConditions || 'true'}
|
72
76
|
`;
|
@@ -1,21 +1,33 @@
|
|
1
|
+
import type {Reducer} from 'redux';
|
2
|
+
import type {ExplainPlanNodeData, GraphNode, Link} from '@gravity-ui/paranoid';
|
1
3
|
import _ from 'lodash';
|
2
4
|
|
3
5
|
import '../../services/api';
|
6
|
+
import type {ExplainActions} from '../../types/api/query';
|
7
|
+
import type {
|
8
|
+
ExplainQueryAction,
|
9
|
+
ExplainQueryState,
|
10
|
+
PreparedExplainResponse,
|
11
|
+
} from '../../types/store/explainQuery';
|
12
|
+
import type {QueryRequestParams, QueryModes} from '../../types/store/query';
|
4
13
|
|
5
|
-
import {getExplainNodeId, getMetaForExplainNode} from '../../utils';
|
6
14
|
import {preparePlan} from '../../utils/prepareQueryExplain';
|
7
|
-
import {parseQueryAPIExplainResponse} from '../../utils/query';
|
15
|
+
import {parseQueryAPIExplainResponse, parseQueryExplainPlan} from '../../utils/query';
|
16
|
+
import {parseQueryError} from '../../utils/error';
|
8
17
|
|
9
18
|
import {createRequestActionTypes, createApiRequest} from '../utils';
|
10
19
|
|
11
|
-
const GET_EXPLAIN_QUERY = createRequestActionTypes('query', 'GET_EXPLAIN_QUERY');
|
12
|
-
const GET_EXPLAIN_QUERY_AST = createRequestActionTypes('query', 'GET_EXPLAIN_QUERY_AST');
|
20
|
+
export const GET_EXPLAIN_QUERY = createRequestActionTypes('query', 'GET_EXPLAIN_QUERY');
|
21
|
+
export const GET_EXPLAIN_QUERY_AST = createRequestActionTypes('query', 'GET_EXPLAIN_QUERY_AST');
|
13
22
|
|
14
23
|
const initialState = {
|
15
24
|
loading: false,
|
16
25
|
};
|
17
26
|
|
18
|
-
const explainQuery
|
27
|
+
const explainQuery: Reducer<ExplainQueryState, ExplainQueryAction> = (
|
28
|
+
state = initialState,
|
29
|
+
action,
|
30
|
+
) => {
|
19
31
|
switch (action.type) {
|
20
32
|
case GET_EXPLAIN_QUERY.REQUEST: {
|
21
33
|
return {
|
@@ -36,11 +48,10 @@ const explainQuery = (state = initialState, action) => {
|
|
36
48
|
error: undefined,
|
37
49
|
};
|
38
50
|
}
|
39
|
-
// 401 Unauthorized error is handled by GenericAPI
|
40
51
|
case GET_EXPLAIN_QUERY.FAILURE: {
|
41
52
|
return {
|
42
53
|
...state,
|
43
|
-
error: action.error
|
54
|
+
error: parseQueryError(action.error),
|
44
55
|
loading: false,
|
45
56
|
};
|
46
57
|
}
|
@@ -63,7 +74,7 @@ const explainQuery = (state = initialState, action) => {
|
|
63
74
|
case GET_EXPLAIN_QUERY_AST.FAILURE: {
|
64
75
|
return {
|
65
76
|
...state,
|
66
|
-
errorAst: action.error
|
77
|
+
errorAst: parseQueryError(action.error),
|
67
78
|
loadingAst: false,
|
68
79
|
};
|
69
80
|
}
|
@@ -73,7 +84,7 @@ const explainQuery = (state = initialState, action) => {
|
|
73
84
|
}
|
74
85
|
};
|
75
86
|
|
76
|
-
export const getExplainQueryAst = ({query, database}) => {
|
87
|
+
export const getExplainQueryAst = ({query, database}: QueryRequestParams) => {
|
77
88
|
return createApiRequest({
|
78
89
|
request: window.api.getExplainQueryAst(query, database),
|
79
90
|
actions: GET_EXPLAIN_QUERY_AST,
|
@@ -82,74 +93,48 @@ export const getExplainQueryAst = ({query, database}) => {
|
|
82
93
|
};
|
83
94
|
|
84
95
|
export const explainVersions = {
|
85
|
-
v1: '0.1',
|
86
96
|
v2: '0.2',
|
87
97
|
};
|
88
98
|
|
89
99
|
const supportedExplainQueryVersions = Object.values(explainVersions);
|
90
100
|
|
91
|
-
|
101
|
+
interface ExplainQueryParams extends QueryRequestParams {
|
102
|
+
mode?: QueryModes;
|
103
|
+
}
|
104
|
+
|
105
|
+
export const getExplainQuery = ({query, database, mode}: ExplainQueryParams) => {
|
106
|
+
const action: ExplainActions = mode ? `explain-${mode}` : 'explain';
|
107
|
+
|
92
108
|
return createApiRequest({
|
93
|
-
request: window.api.getExplainQuery(query, database),
|
109
|
+
request: window.api.getExplainQuery(query, database, action),
|
94
110
|
actions: GET_EXPLAIN_QUERY,
|
95
|
-
dataHandler: (response) => {
|
96
|
-
const {plan:
|
111
|
+
dataHandler: (response): PreparedExplainResponse => {
|
112
|
+
const {plan: rawPlan, ast} = parseQueryAPIExplainResponse(response);
|
97
113
|
|
98
|
-
if (!
|
114
|
+
if (!rawPlan) {
|
99
115
|
return {ast};
|
100
116
|
}
|
101
117
|
|
102
|
-
|
103
|
-
let nodes = [];
|
104
|
-
const {tables, meta, Plan} = result;
|
118
|
+
const {tables, meta, Plan} = parseQueryExplainPlan(rawPlan);
|
105
119
|
|
106
120
|
if (supportedExplainQueryVersions.indexOf(meta.version) === -1) {
|
121
|
+
// Do not prepare plan for not supported versions
|
107
122
|
return {
|
108
|
-
|
109
|
-
|
123
|
+
plan: {
|
124
|
+
pristine: rawPlan,
|
125
|
+
version: meta.version,
|
126
|
+
},
|
127
|
+
ast,
|
110
128
|
};
|
111
129
|
}
|
112
|
-
|
130
|
+
|
131
|
+
let links: Link[] = [];
|
132
|
+
let nodes: GraphNode<ExplainPlanNodeData>[] = [];
|
133
|
+
|
134
|
+
if (Plan) {
|
113
135
|
const preparedPlan = preparePlan(Plan);
|
114
136
|
links = preparedPlan.links;
|
115
137
|
nodes = preparedPlan.nodes;
|
116
|
-
} else {
|
117
|
-
_.forEach(tables, (table) => {
|
118
|
-
nodes.push({
|
119
|
-
name: table.name,
|
120
|
-
});
|
121
|
-
|
122
|
-
const tableTypes = {};
|
123
|
-
|
124
|
-
const {reads = [], writes = []} = table;
|
125
|
-
let prevNodeId = table.name;
|
126
|
-
|
127
|
-
_.forEach([...reads, ...writes], (node) => {
|
128
|
-
if (tableTypes[node.type]) {
|
129
|
-
tableTypes[node.type] = tableTypes[node.type] + 1;
|
130
|
-
} else {
|
131
|
-
tableTypes[node.type] = 1;
|
132
|
-
}
|
133
|
-
|
134
|
-
const nodeId = getExplainNodeId(
|
135
|
-
table.name,
|
136
|
-
node.type,
|
137
|
-
tableTypes[node.type],
|
138
|
-
);
|
139
|
-
|
140
|
-
links.push({
|
141
|
-
from: prevNodeId,
|
142
|
-
to: nodeId,
|
143
|
-
});
|
144
|
-
nodes.push({
|
145
|
-
name: nodeId,
|
146
|
-
meta: getMetaForExplainNode(node),
|
147
|
-
id: nodeId,
|
148
|
-
});
|
149
|
-
|
150
|
-
prevNodeId = nodeId;
|
151
|
-
});
|
152
|
-
});
|
153
138
|
}
|
154
139
|
|
155
140
|
return {
|
@@ -158,7 +143,7 @@ export const getExplainQuery = ({query, database}) => {
|
|
158
143
|
nodes,
|
159
144
|
tables,
|
160
145
|
version: meta.version,
|
161
|
-
pristine:
|
146
|
+
pristine: rawPlan,
|
162
147
|
},
|
163
148
|
ast,
|
164
149
|
};
|
@@ -1,11 +1,13 @@
|
|
1
|
-
import '
|
1
|
+
import type {Reducer} from 'redux';
|
2
|
+
|
3
|
+
import type {OlapStatsAction, OlapStatsState} from '../../types/store/olapStats';
|
2
4
|
|
5
|
+
import '../../services/api';
|
3
6
|
import {parseQueryAPIExecuteResponse} from '../../utils/query';
|
4
7
|
|
5
8
|
import {createRequestActionTypes, createApiRequest} from '../utils';
|
6
9
|
|
7
|
-
const FETCH_OLAP_STATS = createRequestActionTypes('query', 'SEND_OLAP_STATS_QUERY');
|
8
|
-
const SET_OLAP_STATS_OPTIONS = createRequestActionTypes('query', 'SET_OLAP_STATS_OPTIONS');
|
10
|
+
export const FETCH_OLAP_STATS = createRequestActionTypes('query', 'SEND_OLAP_STATS_QUERY');
|
9
11
|
const RESET_LOADING_STATE = 'olapStats/RESET_LOADING_STATE';
|
10
12
|
|
11
13
|
const initialState = {
|
@@ -13,13 +15,13 @@ const initialState = {
|
|
13
15
|
wasLoaded: false,
|
14
16
|
};
|
15
17
|
|
16
|
-
function createOlatStatsQuery(path) {
|
18
|
+
function createOlatStatsQuery(path: string) {
|
17
19
|
return `SELECT * FROM \`${path}/.sys/primary_index_stats\``;
|
18
20
|
}
|
19
21
|
|
20
22
|
const queryAction = 'execute-scan';
|
21
23
|
|
22
|
-
const olapStats = (state = initialState, action) => {
|
24
|
+
const olapStats: Reducer<OlapStatsState, OlapStatsAction> = (state = initialState, action) => {
|
23
25
|
switch (action.type) {
|
24
26
|
case FETCH_OLAP_STATS.REQUEST: {
|
25
27
|
return {
|
@@ -44,11 +46,6 @@ const olapStats = (state = initialState, action) => {
|
|
44
46
|
loading: false,
|
45
47
|
};
|
46
48
|
}
|
47
|
-
case SET_OLAP_STATS_OPTIONS:
|
48
|
-
return {
|
49
|
-
...state,
|
50
|
-
...action.data,
|
51
|
-
};
|
52
49
|
case RESET_LOADING_STATE: {
|
53
50
|
return {
|
54
51
|
...state,
|
@@ -73,17 +70,10 @@ export const getOlapStats = ({path = ''}) => {
|
|
73
70
|
});
|
74
71
|
};
|
75
72
|
|
76
|
-
export function setOlapStatsOptions(options) {
|
77
|
-
return {
|
78
|
-
type: SET_OLAP_STATS_OPTIONS,
|
79
|
-
data: options,
|
80
|
-
};
|
81
|
-
}
|
82
|
-
|
83
73
|
export function resetLoadingState() {
|
84
74
|
return {
|
85
75
|
type: RESET_LOADING_STATE,
|
86
|
-
};
|
76
|
+
} as const;
|
87
77
|
}
|
88
78
|
|
89
79
|
export default olapStats;
|
@@ -3,14 +3,16 @@ import {
|
|
3
3
|
SAVED_QUERIES_KEY,
|
4
4
|
THEME_KEY,
|
5
5
|
TENANT_INITIAL_TAB_KEY,
|
6
|
-
QUERY_INITIAL_RUN_ACTION_KEY,
|
7
6
|
INVERTED_DISKS_KEY,
|
8
7
|
ASIDE_HEADER_COMPACT_KEY,
|
9
8
|
USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY,
|
10
9
|
PARTITIONS_SELECTED_COLUMNS_KEY,
|
10
|
+
QUERY_INITIAL_MODE_KEY,
|
11
|
+
ENABLE_QUERY_MODES_FOR_EXPLAIN,
|
11
12
|
} from '../../utils/constants';
|
12
13
|
import '../../services/api';
|
13
|
-
import {getValueFromLS} from '../../utils/utils';
|
14
|
+
import {getValueFromLS, parseJson} from '../../utils/utils';
|
15
|
+
import {QueryModes} from '../../types/store/query';
|
14
16
|
|
15
17
|
const CHANGE_PROBLEM_FILTER = 'settings/CHANGE_PROBLEM_FILTER';
|
16
18
|
const SET_SETTING_VALUE = 'settings/SET_VALUE';
|
@@ -38,15 +40,19 @@ export const initialState = {
|
|
38
40
|
problemFilter: ALL,
|
39
41
|
userSettings: {
|
40
42
|
...userSettings,
|
41
|
-
[THEME_KEY]: readSavedSettingsValue(THEME_KEY, '
|
43
|
+
[THEME_KEY]: readSavedSettingsValue(THEME_KEY, 'system'),
|
42
44
|
[INVERTED_DISKS_KEY]: readSavedSettingsValue(INVERTED_DISKS_KEY, 'false'),
|
43
45
|
[USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY]: readSavedSettingsValue(
|
44
46
|
USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY,
|
45
47
|
'false',
|
46
48
|
),
|
49
|
+
[ENABLE_QUERY_MODES_FOR_EXPLAIN]: readSavedSettingsValue(
|
50
|
+
ENABLE_QUERY_MODES_FOR_EXPLAIN,
|
51
|
+
'false',
|
52
|
+
),
|
47
53
|
[SAVED_QUERIES_KEY]: readSavedSettingsValue(SAVED_QUERIES_KEY, '[]'),
|
48
54
|
[TENANT_INITIAL_TAB_KEY]: readSavedSettingsValue(TENANT_INITIAL_TAB_KEY),
|
49
|
-
[
|
55
|
+
[QUERY_INITIAL_MODE_KEY]: readSavedSettingsValue(QUERY_INITIAL_MODE_KEY, QueryModes.script),
|
50
56
|
[ASIDE_HEADER_COMPACT_KEY]: readSavedSettingsValue(
|
51
57
|
ASIDE_HEADER_COMPACT_KEY,
|
52
58
|
legacyAsideNavCompactState || 'true',
|
@@ -97,6 +103,15 @@ export const getSettingValue = (state, name) => {
|
|
97
103
|
return state.settings.userSettings[name];
|
98
104
|
};
|
99
105
|
|
106
|
+
/**
|
107
|
+
* Returns parsed settings value.
|
108
|
+
* If value cannot be parsed, returns initially stored string
|
109
|
+
*/
|
110
|
+
export const getParsedSettingValue = (state, name) => {
|
111
|
+
const value = state.settings.userSettings[name];
|
112
|
+
return parseJson(value);
|
113
|
+
};
|
114
|
+
|
100
115
|
export const changeFilter = (filter) => {
|
101
116
|
return {
|
102
117
|
type: CHANGE_PROBLEM_FILTER,
|
@@ -243,13 +243,11 @@ export const getFlatListStorageGroups = createSelector([getStoragePools], (stora
|
|
243
243
|
const limitSizeBytes = _.reduce(
|
244
244
|
group.VDisks,
|
245
245
|
(acc, vDisk) => {
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
(Number(vDisk.AllocatedSize) || 0)
|
252
|
-
);
|
246
|
+
const {AvailableSize, AllocatedSize, PDisk} = vDisk;
|
247
|
+
const available = (AvailableSize ?? PDisk?.AvailableSize) || 0;
|
248
|
+
const allocated = AllocatedSize || 0;
|
249
|
+
|
250
|
+
return acc + Number(available) + Number(allocated);
|
253
251
|
},
|
254
252
|
0,
|
255
253
|
);
|
package/dist/types/api/error.ts
CHANGED
@@ -4,3 +4,17 @@ export interface IResponseError {
|
|
4
4
|
statusText?: string;
|
5
5
|
isCancelled?: boolean;
|
6
6
|
}
|
7
|
+
|
8
|
+
// Error on offline backend or requests blocked by CORS
|
9
|
+
export interface NetworkError {
|
10
|
+
code?: unknown;
|
11
|
+
columnNumber?: unknown;
|
12
|
+
config?: Record<string, unknown>;
|
13
|
+
description?: unknown;
|
14
|
+
fileName?: unknown;
|
15
|
+
lineNumber?: unknown;
|
16
|
+
message?: 'Network Error';
|
17
|
+
name?: string;
|
18
|
+
number?: unknown;
|
19
|
+
stack?: string;
|
20
|
+
}
|