ydb-embedded-ui 3.4.5 → 3.5.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 +19 -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/QueryEditor.js +1 -0
- package/dist/routes.ts +1 -1
- package/dist/services/api.js +3 -3
- package/dist/store/reducers/{executeQuery.js → executeQuery.ts} +51 -21
- package/dist/store/reducers/executeTopQueries.ts +5 -1
- package/dist/store/reducers/{olapStats.js → olapStats.ts} +8 -18
- package/dist/store/reducers/settings.js +1 -1
- package/dist/store/reducers/storage.js +5 -7
- package/dist/types/api/query.ts +4 -1
- package/dist/types/api/schema.ts +523 -3
- package/dist/types/common.ts +1 -0
- package/dist/types/store/executeQuery.ts +42 -0
- package/dist/types/store/olapStats.ts +14 -0
- package/dist/utils/query.test.ts +42 -29
- package/dist/utils/query.ts +34 -22
- package/dist/utils/timeParsers/formatDuration.ts +30 -12
- package/dist/utils/timeParsers/i18n/en.json +4 -0
- package/dist/utils/timeParsers/i18n/ru.json +4 -0
- package/package.json +1 -1
@@ -1,5 +1,7 @@
|
|
1
1
|
import {useCallback, useEffect, useRef, useState} from 'react';
|
2
2
|
import {useDispatch} from 'react-redux';
|
3
|
+
import {useHistory, useLocation} from 'react-router';
|
4
|
+
import qs from 'qs';
|
3
5
|
import cn from 'bem-cn-lite';
|
4
6
|
|
5
7
|
import DataTable, {Column, Settings} from '@gravity-ui/react-data-table';
|
@@ -21,13 +23,14 @@ import type {EPathType} from '../../../../types/api/schema';
|
|
21
23
|
import type {ITopQueriesFilters} from '../../../../types/store/executeTopQueries';
|
22
24
|
import type {IQueryResult} from '../../../../types/store/query';
|
23
25
|
|
24
|
-
import {formatDateTime} from '../../../../utils';
|
26
|
+
import {formatDateTime, formatNumber} from '../../../../utils';
|
25
27
|
import {DEFAULT_TABLE_SETTINGS, HOUR_IN_SECONDS} from '../../../../utils/constants';
|
26
28
|
import {useAutofetcher, useTypedSelector} from '../../../../utils/hooks';
|
27
29
|
import {prepareQueryError} from '../../../../utils/query';
|
30
|
+
import routes, {createHref} from '../../../../routes';
|
28
31
|
|
29
32
|
import {isColumnEntityType} from '../../utils/schema';
|
30
|
-
import {TenantGeneralTabsIds} from '../../TenantPages';
|
33
|
+
import {TenantGeneralTabsIds, TenantTabsGroups} from '../../TenantPages';
|
31
34
|
|
32
35
|
import i18n from './i18n';
|
33
36
|
import './TopQueries.scss';
|
@@ -43,19 +46,41 @@ const MAX_QUERY_HEIGHT = 10;
|
|
43
46
|
const COLUMNS: Column<KeyValueRow>[] = [
|
44
47
|
{
|
45
48
|
name: 'CPUTimeUs',
|
46
|
-
|
47
|
-
|
49
|
+
sortAccessor: (row) => Number(row.CPUTimeUs),
|
50
|
+
align: DataTable.RIGHT,
|
48
51
|
},
|
49
52
|
{
|
50
53
|
name: 'QueryText',
|
51
54
|
width: 500,
|
52
55
|
sortable: false,
|
53
|
-
render: ({
|
56
|
+
render: ({row}) => (
|
57
|
+
<div className={b('query')}>
|
58
|
+
<TruncatedQuery value={row.QueryText} maxQueryHeight={MAX_QUERY_HEIGHT} />
|
59
|
+
</div>
|
60
|
+
),
|
61
|
+
},
|
62
|
+
{
|
63
|
+
name: 'EndTime',
|
64
|
+
render: ({row}) => formatDateTime(new Date(row.EndTime as string).getTime()),
|
65
|
+
align: DataTable.RIGHT,
|
66
|
+
},
|
67
|
+
{
|
68
|
+
name: 'ReadRows',
|
69
|
+
render: ({row}) => formatNumber(row.ReadRows),
|
70
|
+
sortAccessor: (row) => Number(row.ReadRows),
|
71
|
+
align: DataTable.RIGHT,
|
72
|
+
},
|
73
|
+
{
|
74
|
+
name: 'ReadBytes',
|
75
|
+
render: ({row}) => formatNumber(row.ReadBytes),
|
76
|
+
sortAccessor: (row) => Number(row.ReadBytes),
|
77
|
+
align: DataTable.RIGHT,
|
54
78
|
},
|
55
79
|
{
|
56
|
-
name: '
|
57
|
-
|
58
|
-
|
80
|
+
name: 'UserSID',
|
81
|
+
render: ({row}) => <div className={b('user-sid')}>{row.UserSID || '–'}</div>,
|
82
|
+
sortAccessor: (row) => String(row.UserSID),
|
83
|
+
align: DataTable.LEFT,
|
59
84
|
},
|
60
85
|
];
|
61
86
|
|
@@ -65,8 +90,10 @@ interface TopQueriesProps {
|
|
65
90
|
type?: EPathType;
|
66
91
|
}
|
67
92
|
|
68
|
-
export const TopQueries = ({path, type
|
93
|
+
export const TopQueries = ({path, type}: TopQueriesProps) => {
|
69
94
|
const dispatch = useDispatch();
|
95
|
+
const location = useLocation();
|
96
|
+
const history = useHistory();
|
70
97
|
|
71
98
|
const {autorefresh} = useTypedSelector((state) => state.schema);
|
72
99
|
|
@@ -144,9 +171,19 @@ export const TopQueries = ({path, type, changeSchemaTab}: TopQueriesProps) => {
|
|
144
171
|
const {QueryText: input} = row;
|
145
172
|
|
146
173
|
dispatch(changeUserInput({input}));
|
147
|
-
|
174
|
+
|
175
|
+
const queryParams = qs.parse(location.search, {
|
176
|
+
ignoreQueryPrefix: true,
|
177
|
+
});
|
178
|
+
|
179
|
+
const queryPath = createHref(routes.tenant, undefined, {
|
180
|
+
...queryParams,
|
181
|
+
[TenantTabsGroups.general]: TenantGeneralTabsIds.query,
|
182
|
+
});
|
183
|
+
|
184
|
+
history.push(queryPath);
|
148
185
|
},
|
149
|
-
[
|
186
|
+
[dispatch, history, location],
|
150
187
|
);
|
151
188
|
|
152
189
|
const handleTextSearchUpdate = (text: string) => {
|
@@ -179,7 +216,7 @@ export const TopQueries = ({path, type, changeSchemaTab}: TopQueriesProps) => {
|
|
179
216
|
}
|
180
217
|
|
181
218
|
return (
|
182
|
-
<div className={b('
|
219
|
+
<div className={b('table')}>
|
183
220
|
<DataTable
|
184
221
|
columns={COLUMNS}
|
185
222
|
data={data}
|
@@ -20,6 +20,7 @@ import {setCurrentSchemaPath, getSchema} from '../../../../store/reducers/schema
|
|
20
20
|
import {EShardsWorkloadMode, IShardsWorkloadFilters} from '../../../../types/store/shardsWorkload';
|
21
21
|
|
22
22
|
import type {EPathType} from '../../../../types/api/schema';
|
23
|
+
import type {CellValue, KeyValueRow} from '../../../../types/api/query';
|
23
24
|
|
24
25
|
import {formatDateTime, formatNumber} from '../../../../utils';
|
25
26
|
import {DEFAULT_TABLE_SETTINGS, HOUR_IN_SECONDS} from '../../../../utils/constants';
|
@@ -57,10 +58,17 @@ const tableColumnsNames = {
|
|
57
58
|
IntervalEnd: 'IntervalEnd',
|
58
59
|
};
|
59
60
|
|
60
|
-
function prepareCPUWorkloadValue(value: string) {
|
61
|
+
function prepareCPUWorkloadValue(value: string | number) {
|
61
62
|
return `${(Number(value) * 100).toFixed(2)}%`;
|
62
63
|
}
|
63
64
|
|
65
|
+
function prepareDateTimeValue(value: CellValue) {
|
66
|
+
if (!value) {
|
67
|
+
return '–';
|
68
|
+
}
|
69
|
+
return formatDateTime(new Date(value).getTime());
|
70
|
+
}
|
71
|
+
|
64
72
|
function stringToDataTableSortOrder(value: string): SortOrder[] | undefined {
|
65
73
|
return value
|
66
74
|
? value.split(',').map((columnId) => ({
|
@@ -190,16 +198,17 @@ export const TopShards = ({tenantPath, type}: TopShardsProps) => {
|
|
190
198
|
};
|
191
199
|
};
|
192
200
|
|
193
|
-
const columns: Column<
|
201
|
+
const columns: Column<KeyValueRow>[] = [
|
194
202
|
{
|
195
203
|
name: tableColumnsNames.Path,
|
196
|
-
render: ({
|
204
|
+
render: ({row}) => {
|
205
|
+
// row.Path - relative schema path
|
197
206
|
return (
|
198
207
|
<span
|
199
|
-
onClick={onSchemaClick(tenantPath +
|
208
|
+
onClick={onSchemaClick(tenantPath + row.Path)}
|
200
209
|
className={bLink({view: 'normal'})}
|
201
210
|
>
|
202
|
-
{
|
211
|
+
{row.Path}
|
203
212
|
</span>
|
204
213
|
);
|
205
214
|
},
|
@@ -207,25 +216,28 @@ export const TopShards = ({tenantPath, type}: TopShardsProps) => {
|
|
207
216
|
},
|
208
217
|
{
|
209
218
|
name: tableColumnsNames.CPUCores,
|
210
|
-
render: ({
|
211
|
-
return prepareCPUWorkloadValue(
|
219
|
+
render: ({row}) => {
|
220
|
+
return prepareCPUWorkloadValue(row.CPUCores || 0);
|
212
221
|
},
|
213
222
|
align: DataTable.RIGHT,
|
214
223
|
},
|
215
224
|
{
|
216
225
|
name: tableColumnsNames.DataSize,
|
217
226
|
header: 'DataSize (B)',
|
218
|
-
render: ({
|
219
|
-
return formatNumber(
|
227
|
+
render: ({row}) => {
|
228
|
+
return formatNumber(row.DataSize);
|
220
229
|
},
|
221
230
|
align: DataTable.RIGHT,
|
222
231
|
},
|
223
232
|
{
|
224
233
|
name: tableColumnsNames.TabletId,
|
225
|
-
render: ({
|
234
|
+
render: ({row}) => {
|
235
|
+
if (!row.TabletId) {
|
236
|
+
return '–';
|
237
|
+
}
|
226
238
|
return (
|
227
|
-
<InternalLink to={createHref(routes.tablet, {id:
|
228
|
-
{
|
239
|
+
<InternalLink to={createHref(routes.tablet, {id: row.TabletId})}>
|
240
|
+
{row.TabletId}
|
229
241
|
</InternalLink>
|
230
242
|
);
|
231
243
|
},
|
@@ -233,10 +245,13 @@ export const TopShards = ({tenantPath, type}: TopShardsProps) => {
|
|
233
245
|
},
|
234
246
|
{
|
235
247
|
name: tableColumnsNames.NodeId,
|
236
|
-
render: ({
|
248
|
+
render: ({row}) => {
|
249
|
+
if (!row.NodeId) {
|
250
|
+
return '–';
|
251
|
+
}
|
237
252
|
return (
|
238
|
-
<InternalLink to={getDefaultNodePath(
|
239
|
-
{
|
253
|
+
<InternalLink to={getDefaultNodePath(row.NodeId)}>
|
254
|
+
{row.NodeId}
|
240
255
|
</InternalLink>
|
241
256
|
);
|
242
257
|
},
|
@@ -245,7 +260,7 @@ export const TopShards = ({tenantPath, type}: TopShardsProps) => {
|
|
245
260
|
},
|
246
261
|
{
|
247
262
|
name: tableColumnsNames.InFlightTxCount,
|
248
|
-
render: ({
|
263
|
+
render: ({row}) => formatNumber(row.InFlightTxCount),
|
249
264
|
align: DataTable.RIGHT,
|
250
265
|
sortable: false,
|
251
266
|
},
|
@@ -255,12 +270,16 @@ export const TopShards = ({tenantPath, type}: TopShardsProps) => {
|
|
255
270
|
// after NodeId
|
256
271
|
columns.splice(5, 0, {
|
257
272
|
name: tableColumnsNames.PeakTime,
|
258
|
-
render: ({
|
273
|
+
render: ({row}) => {
|
274
|
+
return prepareDateTimeValue(row.PeakTime);
|
275
|
+
},
|
259
276
|
sortable: false,
|
260
277
|
});
|
261
278
|
columns.push({
|
262
279
|
name: tableColumnsNames.IntervalEnd,
|
263
|
-
render: ({
|
280
|
+
render: ({row}) => {
|
281
|
+
return prepareDateTimeValue(row.IntervalEnd);
|
282
|
+
},
|
264
283
|
});
|
265
284
|
}
|
266
285
|
|
package/dist/routes.ts
CHANGED
@@ -28,7 +28,7 @@ export const CLUSTER_PAGES = {
|
|
28
28
|
|
29
29
|
export function createHref(
|
30
30
|
route: string,
|
31
|
-
params?:
|
31
|
+
params?: Record<string, string | number>,
|
32
32
|
query: Record<string | number, string | number | string[] | number[] | undefined> = {},
|
33
33
|
) {
|
34
34
|
let extendedQuery = query;
|
package/dist/services/api.js
CHANGED
@@ -96,9 +96,9 @@ export class YdbEmbeddedAPI extends AxiosWrapper {
|
|
96
96
|
enums: true,
|
97
97
|
backup: false,
|
98
98
|
private: true,
|
99
|
-
partition_config:
|
100
|
-
partition_stats:
|
101
|
-
partitioning_info:
|
99
|
+
partition_config: true,
|
100
|
+
partition_stats: true,
|
101
|
+
partitioning_info: true,
|
102
102
|
subs: 1,
|
103
103
|
},
|
104
104
|
{concurrentId: concurrentId || `getSchema|${path}`},
|
@@ -1,13 +1,25 @@
|
|
1
|
-
import {
|
2
|
-
|
1
|
+
import type {Reducer} from 'redux';
|
2
|
+
|
3
|
+
import type {Actions} from '../../types/api/query';
|
4
|
+
import type {
|
5
|
+
ExecuteQueryAction,
|
6
|
+
ExecuteQueryState,
|
7
|
+
MonacoHotKeyAction,
|
8
|
+
RunAction,
|
9
|
+
} from '../../types/store/executeQuery';
|
3
10
|
import {getValueFromLS, parseJson} from '../../utils/utils';
|
4
11
|
import {QUERIES_HISTORY_KEY, QUERY_INITIAL_RUN_ACTION_KEY} from '../../utils/constants';
|
5
12
|
import {parseQueryAPIExecuteResponse} from '../../utils/query';
|
13
|
+
import '../../services/api';
|
14
|
+
|
15
|
+
import {createRequestActionTypes, createApiRequest} from '../utils';
|
16
|
+
|
6
17
|
import {readSavedSettingsValue} from './settings';
|
7
18
|
|
8
19
|
const MAXIMUM_QUERIES_IN_HISTORY = 20;
|
9
20
|
|
10
|
-
const SEND_QUERY = createRequestActionTypes('query', 'SEND_QUERY');
|
21
|
+
export const SEND_QUERY = createRequestActionTypes('query', 'SEND_QUERY');
|
22
|
+
|
11
23
|
const CHANGE_USER_INPUT = 'query/CHANGE_USER_INPUT';
|
12
24
|
const SAVE_QUERY_TO_HISTORY = 'query/SAVE_QUERY_TO_HISTORY';
|
13
25
|
const GO_TO_PREVIOUS_QUERY = 'query/GO_TO_PREVIOUS_QUERY';
|
@@ -15,21 +27,21 @@ const GO_TO_NEXT_QUERY = 'query/GO_TO_NEXT_QUERY';
|
|
15
27
|
const SELECT_RUN_ACTION = 'query/SELECT_RUN_ACTION';
|
16
28
|
const MONACO_HOT_KEY = 'query/MONACO_HOT_KEY';
|
17
29
|
|
18
|
-
const queriesHistoryInitial = parseJson(getValueFromLS(QUERIES_HISTORY_KEY, '[]'));
|
30
|
+
const queriesHistoryInitial: string[] = parseJson(getValueFromLS(QUERIES_HISTORY_KEY, '[]'));
|
19
31
|
|
20
32
|
const sliceLimit = queriesHistoryInitial.length - MAXIMUM_QUERIES_IN_HISTORY;
|
21
33
|
|
22
34
|
export const RUN_ACTIONS_VALUES = {
|
23
35
|
script: 'execute-script',
|
24
36
|
scan: 'execute-scan',
|
25
|
-
};
|
37
|
+
} as const;
|
26
38
|
|
27
39
|
export const MONACO_HOT_KEY_ACTIONS = {
|
28
40
|
sendQuery: 'sendQuery',
|
29
41
|
goPrev: 'goPrev',
|
30
42
|
goNext: 'goNext',
|
31
43
|
getExplain: 'getExplain',
|
32
|
-
};
|
44
|
+
} as const;
|
33
45
|
|
34
46
|
const initialState = {
|
35
47
|
loading: false,
|
@@ -45,7 +57,10 @@ const initialState = {
|
|
45
57
|
monacoHotKey: null,
|
46
58
|
};
|
47
59
|
|
48
|
-
const executeQuery
|
60
|
+
const executeQuery: Reducer<ExecuteQueryState, ExecuteQueryAction> = (
|
61
|
+
state = initialState,
|
62
|
+
action,
|
63
|
+
) => {
|
49
64
|
switch (action.type) {
|
50
65
|
case SEND_QUERY.REQUEST: {
|
51
66
|
return {
|
@@ -141,51 +156,66 @@ const executeQuery = (state = initialState, action) => {
|
|
141
156
|
}
|
142
157
|
};
|
143
158
|
|
144
|
-
export const sendQuery = ({
|
159
|
+
export const sendQuery = ({
|
160
|
+
query,
|
161
|
+
database,
|
162
|
+
action,
|
163
|
+
}: {
|
164
|
+
query: string;
|
165
|
+
database: string;
|
166
|
+
action: Actions;
|
167
|
+
}) => {
|
145
168
|
return createApiRequest({
|
146
|
-
request: window.api.sendQuery({
|
169
|
+
request: window.api.sendQuery({
|
170
|
+
schema: 'modern',
|
171
|
+
query,
|
172
|
+
database,
|
173
|
+
action,
|
174
|
+
stats: 'profile',
|
175
|
+
}),
|
147
176
|
actions: SEND_QUERY,
|
148
177
|
dataHandler: parseQueryAPIExecuteResponse,
|
149
178
|
});
|
150
179
|
};
|
151
180
|
|
152
|
-
export const saveQueryToHistory = (query) => {
|
181
|
+
export const saveQueryToHistory = (query: string) => {
|
153
182
|
return {
|
154
183
|
type: SAVE_QUERY_TO_HISTORY,
|
155
184
|
data: query,
|
156
|
-
};
|
185
|
+
} as const;
|
157
186
|
};
|
158
187
|
|
159
|
-
export const selectRunAction = (value) => {
|
188
|
+
export const selectRunAction = (value: RunAction) => {
|
160
189
|
return {
|
161
190
|
type: SELECT_RUN_ACTION,
|
162
191
|
data: value,
|
163
|
-
};
|
192
|
+
} as const;
|
164
193
|
};
|
165
194
|
|
166
195
|
export const goToPreviousQuery = () => {
|
167
196
|
return {
|
168
197
|
type: GO_TO_PREVIOUS_QUERY,
|
169
|
-
};
|
198
|
+
} as const;
|
170
199
|
};
|
171
200
|
|
172
201
|
export const goToNextQuery = () => {
|
173
202
|
return {
|
174
203
|
type: GO_TO_NEXT_QUERY,
|
175
|
-
};
|
204
|
+
} as const;
|
176
205
|
};
|
177
206
|
|
178
|
-
export const changeUserInput = ({input}) => {
|
179
|
-
return
|
180
|
-
|
181
|
-
|
207
|
+
export const changeUserInput = ({input}: {input: string}) => {
|
208
|
+
return {
|
209
|
+
type: CHANGE_USER_INPUT,
|
210
|
+
data: {input},
|
211
|
+
} as const;
|
182
212
|
};
|
183
213
|
|
184
|
-
export const setMonacoHotKey = (value) => {
|
214
|
+
export const setMonacoHotKey = (value: MonacoHotKeyAction) => {
|
185
215
|
return {
|
186
216
|
type: MONACO_HOT_KEY,
|
187
217
|
data: value,
|
188
|
-
};
|
218
|
+
} as const;
|
189
219
|
};
|
190
220
|
|
191
221
|
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,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;
|
@@ -38,7 +38,7 @@ export const initialState = {
|
|
38
38
|
problemFilter: ALL,
|
39
39
|
userSettings: {
|
40
40
|
...userSettings,
|
41
|
-
[THEME_KEY]: readSavedSettingsValue(THEME_KEY, '
|
41
|
+
[THEME_KEY]: readSavedSettingsValue(THEME_KEY, 'system'),
|
42
42
|
[INVERTED_DISKS_KEY]: readSavedSettingsValue(INVERTED_DISKS_KEY, 'false'),
|
43
43
|
[USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY]: readSavedSettingsValue(
|
44
44
|
USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY,
|
@@ -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/query.ts
CHANGED
@@ -30,7 +30,7 @@ export type Schemas = 'classic' | 'modern' | 'ydb' | undefined;
|
|
30
30
|
|
31
31
|
// common types
|
32
32
|
|
33
|
-
type CellValue = string | number | null | undefined;
|
33
|
+
export type CellValue = string | number | null | undefined;
|
34
34
|
|
35
35
|
export type KeyValueRow<T = CellValue> = {
|
36
36
|
[key: string]: T;
|
@@ -63,6 +63,7 @@ export type ExecuteYdbResponse = {
|
|
63
63
|
result: KeyValueRow[];
|
64
64
|
} & CommonFields;
|
65
65
|
|
66
|
+
// prettier-ignore
|
66
67
|
type ExecuteResponse<Schema extends Schemas> =
|
67
68
|
| CommonFields // result can be undefined for queries like `insert into`
|
68
69
|
| (Schema extends 'modern'
|
@@ -102,6 +103,7 @@ type ExplainResponse = CommonFields;
|
|
102
103
|
|
103
104
|
// deprecated response from older versions, backward compatibility
|
104
105
|
|
106
|
+
// prettier-ignore
|
105
107
|
type DeprecatedExplainResponse<Action extends ExplainActions> =
|
106
108
|
Action extends 'explain-ast'
|
107
109
|
? ({result: {ast: AST}} & Required<DeprecatedCommonFields>) | {ast: AST}
|
@@ -121,6 +123,7 @@ export type QueryAPIExplainResponse<Action extends ExplainActions> =
|
|
121
123
|
| DeprecatedExplainResponse<Action>
|
122
124
|
| null;
|
123
125
|
|
126
|
+
// prettier-ignore
|
124
127
|
export type QueryAPIResponse<Action extends Actions, Schema extends Schemas = undefined> =
|
125
128
|
Action extends ExecuteActions
|
126
129
|
? QueryAPIExecuteResponse<Schema>
|