ydb-embedded-ui 4.8.2 → 4.9.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 +15 -0
- package/dist/components/NodeHostWrapper/NodeHostWrapper.tsx +2 -2
- package/dist/containers/Nodes/Nodes.tsx +1 -1
- package/dist/containers/Nodes/getNodesColumns.tsx +2 -2
- package/dist/containers/Storage/PDisk/PDisk.tsx +1 -1
- package/dist/containers/Storage/Storage.js +26 -48
- package/dist/containers/Storage/StorageGroups/StorageGroups.tsx +16 -19
- package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +12 -10
- package/dist/containers/Storage/StorageTypeFilter/StorageTypeFilter.tsx +27 -0
- package/dist/containers/Storage/StorageVisibleEntityFilter/StorageVisibleEntityFilter.tsx +31 -0
- package/dist/containers/Tenant/Query/QueryEditor/QueryEditor.js +17 -43
- package/dist/containers/Tenant/Query/QueryEditorControls/QueryEditorControls.scss +20 -15
- package/dist/containers/Tenant/Query/QueryEditorControls/QueryEditorControls.tsx +74 -27
- package/dist/containers/Tenant/Query/i18n/en.json +1 -1
- package/dist/containers/Tenant/Query/i18n/ru.json +1 -1
- package/dist/containers/UserSettings/i18n/en.json +1 -1
- package/dist/containers/UserSettings/i18n/ru.json +1 -1
- package/dist/services/api.ts +6 -13
- package/dist/store/reducers/executeQuery.ts +2 -3
- package/dist/store/reducers/explainQuery.ts +2 -2
- package/dist/store/reducers/index.ts +2 -2
- package/dist/store/reducers/{nodes.ts → nodes/nodes.ts} +31 -30
- package/dist/{types/store/nodes.ts → store/reducers/nodes/types.ts} +24 -27
- package/dist/store/reducers/settings/settings.ts +10 -2
- package/dist/store/reducers/storage/constants.ts +10 -0
- package/dist/store/reducers/{storage.js → storage/storage.js} +19 -53
- package/dist/store/reducers/storage/types.ts +12 -0
- package/dist/types/store/query.ts +5 -6
- package/dist/utils/constants.ts +1 -0
- package/dist/utils/nodes.ts +2 -2
- package/dist/utils/query.ts +12 -0
- package/package.json +1 -1
- package/dist/containers/Tenant/Query/QueryEditorControls/OldQueryEditorControls.tsx +0 -90
- package/dist/containers/Tenant/Query/QueryEditorControls/shared.ts +0 -18
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,20 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [4.9.0](https://github.com/ydb-platform/ydb-embedded-ui/compare/v4.8.2...v4.9.0) (2023-06-30)
|
4
|
+
|
5
|
+
|
6
|
+
### Features
|
7
|
+
|
8
|
+
* **QueryEditor:** remove old controls, update setting ([#445](https://github.com/ydb-platform/ydb-embedded-ui/issues/445)) ([75efd44](https://github.com/ydb-platform/ydb-embedded-ui/commit/75efd444c8b8ba5213117ec9c33f6b9664855a2c))
|
9
|
+
|
10
|
+
|
11
|
+
### Bug Fixes
|
12
|
+
|
13
|
+
* **QueryEditor:** color last used query action, run on command ([#436](https://github.com/ydb-platform/ydb-embedded-ui/issues/436)) ([c4d3bb8](https://github.com/ydb-platform/ydb-embedded-ui/commit/c4d3bb81bc1cea8ec3fe2e5e7e18c997d94f5714))
|
14
|
+
* **QueryEditor:** rename query modes ([#449](https://github.com/ydb-platform/ydb-embedded-ui/issues/449)) ([c93c9c1](https://github.com/ydb-platform/ydb-embedded-ui/commit/c93c9c17ba26e01c596009657cac02ecc9cc9ab0))
|
15
|
+
* **StorageNodes:** sort by uptime ([#447](https://github.com/ydb-platform/ydb-embedded-ui/issues/447)) ([283cb81](https://github.com/ydb-platform/ydb-embedded-ui/commit/283cb81b3f4711ddc2bb991615729a9bda7e893c))
|
16
|
+
* **Storage:** remove visible entities filter ([#448](https://github.com/ydb-platform/ydb-embedded-ui/issues/448)) ([b4d9489](https://github.com/ydb-platform/ydb-embedded-ui/commit/b4d948965cd349a54fe833a6b81ea3b087782735))
|
17
|
+
|
3
18
|
## [4.8.2](https://github.com/ydb-platform/ydb-embedded-ui/compare/v4.8.1...v4.8.2) (2023-06-27)
|
4
19
|
|
5
20
|
|
@@ -2,7 +2,7 @@ import block from 'bem-cn-lite';
|
|
2
2
|
|
3
3
|
import {Button, Popover, PopoverBehavior} from '@gravity-ui/uikit';
|
4
4
|
|
5
|
-
import type {
|
5
|
+
import type {NodesPreparedEntity} from '../../store/reducers/nodes/types';
|
6
6
|
import {getDefaultNodePath} from '../../containers/Node/NodePages';
|
7
7
|
import {isUnavailableNode, NodeAddress} from '../../utils/nodes';
|
8
8
|
|
@@ -15,7 +15,7 @@ import './NodeHostWrapper.scss';
|
|
15
15
|
const b = block('ydb-node-host-wrapper');
|
16
16
|
|
17
17
|
interface NodeHostWrapperProps {
|
18
|
-
node:
|
18
|
+
node: NodesPreparedEntity;
|
19
19
|
getNodeRef?: (node?: NodeAddress) => string | null;
|
20
20
|
}
|
21
21
|
|
@@ -26,7 +26,7 @@ import {
|
|
26
26
|
setSearchValue,
|
27
27
|
resetNodesState,
|
28
28
|
getComputeNodes,
|
29
|
-
} from '../../store/reducers/nodes';
|
29
|
+
} from '../../store/reducers/nodes/nodes';
|
30
30
|
import {changeFilter, ProblemFilterValues} from '../../store/reducers/settings/settings';
|
31
31
|
|
32
32
|
import {isDatabaseEntityType} from '../Tenant/utils/schema';
|
@@ -9,7 +9,7 @@ import {NodeHostWrapper} from '../../components/NodeHostWrapper/NodeHostWrapper'
|
|
9
9
|
import type {NodeAddress} from '../../utils/nodes';
|
10
10
|
import {formatBytesToGigabyte} from '../../utils/index';
|
11
11
|
|
12
|
-
import type {
|
12
|
+
import type {NodesPreparedEntity} from '../../store/reducers/nodes/types';
|
13
13
|
|
14
14
|
interface GetNodesColumnsProps {
|
15
15
|
tabletsPath?: string;
|
@@ -17,7 +17,7 @@ interface GetNodesColumnsProps {
|
|
17
17
|
}
|
18
18
|
|
19
19
|
export function getNodesColumns({tabletsPath, getNodeRef}: GetNodesColumnsProps) {
|
20
|
-
const columns: Column<
|
20
|
+
const columns: Column<NodesPreparedEntity>[] = [
|
21
21
|
{
|
22
22
|
name: 'NodeId',
|
23
23
|
header: '#',
|
@@ -5,7 +5,7 @@ import {InternalLink} from '../../../components/InternalLink';
|
|
5
5
|
import {Stack} from '../../../components/Stack/Stack';
|
6
6
|
|
7
7
|
import routes, {createHref} from '../../../routes';
|
8
|
-
import {getVDisksForPDisk} from '../../../store/reducers/storage';
|
8
|
+
import {getVDisksForPDisk} from '../../../store/reducers/storage/storage';
|
9
9
|
import {TPDiskStateInfo, TPDiskState} from '../../../types/api/pdisk';
|
10
10
|
import {TVDiskStateInfo} from '../../../types/api/vdisk';
|
11
11
|
import {stringifyVdiskId} from '../../../utils';
|
@@ -3,7 +3,6 @@ import PropTypes from 'prop-types';
|
|
3
3
|
import {connect} from 'react-redux';
|
4
4
|
import cn from 'bem-cn-lite';
|
5
5
|
import DataTable from '@gravity-ui/react-data-table';
|
6
|
-
import {RadioButton} from '@gravity-ui/uikit';
|
7
6
|
|
8
7
|
import {Search} from '../../components/Search';
|
9
8
|
import {UsageFilter} from './UsageFilter';
|
@@ -18,33 +17,29 @@ import {
|
|
18
17
|
getStorageInfo,
|
19
18
|
setInitialState,
|
20
19
|
getFilteredEntities,
|
21
|
-
VisibleEntities,
|
22
20
|
setVisibleEntities,
|
23
21
|
setStorageFilter,
|
24
22
|
setUsageFilter,
|
25
|
-
StorageTypes,
|
26
23
|
setStorageType,
|
27
24
|
setNodesUptimeFilter,
|
28
25
|
setDataWasNotLoaded,
|
29
|
-
VisibleEntitiesTitles,
|
30
26
|
getStoragePoolsGroupsCount,
|
31
27
|
getStorageNodesCount,
|
32
28
|
getUsageFilterOptions,
|
33
|
-
} from '../../store/reducers/storage';
|
29
|
+
} from '../../store/reducers/storage/storage';
|
30
|
+
import {VISIBLE_ENTITIES, STORAGE_TYPES} from '../../store/reducers/storage/constants';
|
34
31
|
import {getNodesList, selectNodesMap} from '../../store/reducers/nodesList';
|
35
32
|
import StorageGroups from './StorageGroups/StorageGroups';
|
36
33
|
import StorageNodes from './StorageNodes/StorageNodes';
|
37
34
|
import {DEFAULT_TABLE_SETTINGS} from '../../utils/constants';
|
38
35
|
|
36
|
+
import {StorageTypeFilter} from './StorageTypeFilter/StorageTypeFilter';
|
37
|
+
import {StorageVisibleEntityFilter} from './StorageVisibleEntityFilter/StorageVisibleEntityFilter';
|
38
|
+
|
39
39
|
import './Storage.scss';
|
40
40
|
|
41
41
|
const b = cn('global-storage');
|
42
42
|
|
43
|
-
const FILTER_OPTIONS = {
|
44
|
-
Missing: 'missing',
|
45
|
-
Space: 'space',
|
46
|
-
};
|
47
|
-
|
48
43
|
const tableSettings = {
|
49
44
|
...DEFAULT_TABLE_SETTINGS,
|
50
45
|
defaultOrder: DataTable.DESCENDING,
|
@@ -74,25 +69,23 @@ class Storage extends React.Component {
|
|
74
69
|
};
|
75
70
|
|
76
71
|
componentDidMount() {
|
77
|
-
const {tenant, nodeId, setVisibleEntities, storageType, getNodesList} =
|
78
|
-
this.props;
|
72
|
+
const {tenant, nodeId, setVisibleEntities, storageType, getNodesList} = this.props;
|
79
73
|
|
80
74
|
this.autofetcher = new AutoFetcher();
|
81
75
|
getNodesList();
|
82
76
|
if (tenant || nodeId) {
|
83
|
-
setVisibleEntities(
|
77
|
+
setVisibleEntities(VISIBLE_ENTITIES.all);
|
84
78
|
this.getStorageInfo({
|
85
|
-
filter: FILTER_OPTIONS.All,
|
86
79
|
type: storageType,
|
87
80
|
});
|
88
81
|
} else {
|
89
82
|
this.getStorageInfo({
|
90
|
-
|
83
|
+
visibleEntities: VISIBLE_ENTITIES.missing,
|
91
84
|
type: storageType,
|
92
85
|
});
|
93
86
|
this.autofetcher.fetch(() =>
|
94
87
|
this.getStorageInfo({
|
95
|
-
|
88
|
+
visibleEntities: VISIBLE_ENTITIES.missing,
|
96
89
|
type: storageType,
|
97
90
|
}),
|
98
91
|
);
|
@@ -105,7 +98,7 @@ class Storage extends React.Component {
|
|
105
98
|
|
106
99
|
const startFetch = () => {
|
107
100
|
this.getStorageInfo({
|
108
|
-
|
101
|
+
visibleEntities,
|
109
102
|
type: storageType,
|
110
103
|
});
|
111
104
|
};
|
@@ -115,7 +108,7 @@ class Storage extends React.Component {
|
|
115
108
|
this.autofetcher.start();
|
116
109
|
this.autofetcher.fetch(() =>
|
117
110
|
this.getStorageInfo({
|
118
|
-
|
111
|
+
visibleEntities,
|
119
112
|
type: storageType,
|
120
113
|
}),
|
121
114
|
);
|
@@ -183,16 +176,16 @@ class Storage extends React.Component {
|
|
183
176
|
|
184
177
|
return (
|
185
178
|
<div className={b('table-wrapper')}>
|
186
|
-
{storageType ===
|
179
|
+
{storageType === STORAGE_TYPES.groups && (
|
187
180
|
<StorageGroups
|
188
181
|
visibleEntities={visibleEntities}
|
189
182
|
data={flatListStorageEntities}
|
190
183
|
tableSettings={tableSettings}
|
191
184
|
nodes={nodes}
|
192
|
-
onShowAll={() => this.onGroupVisibilityChange(
|
185
|
+
onShowAll={() => this.onGroupVisibilityChange(VISIBLE_ENTITIES.all)}
|
193
186
|
/>
|
194
187
|
)}
|
195
|
-
{storageType ===
|
188
|
+
{storageType === STORAGE_TYPES.nodes && (
|
196
189
|
<StorageNodes
|
197
190
|
visibleEntities={visibleEntities}
|
198
191
|
nodesUptimeFilter={nodesUptimeFilter}
|
@@ -221,7 +214,7 @@ class Storage extends React.Component {
|
|
221
214
|
};
|
222
215
|
|
223
216
|
onShowAllNodes = () => {
|
224
|
-
this.onGroupVisibilityChange(
|
217
|
+
this.onGroupVisibilityChange(VISIBLE_ENTITIES.all);
|
225
218
|
this.onUptimeFilterChange(NodesUptimeFilterValues.All);
|
226
219
|
};
|
227
220
|
|
@@ -229,8 +222,8 @@ class Storage extends React.Component {
|
|
229
222
|
const {storageType, groupsCount, nodesCount, flatListStorageEntities, loading, wasLoaded} =
|
230
223
|
this.props;
|
231
224
|
|
232
|
-
const entityName = storageType ===
|
233
|
-
const count = storageType ===
|
225
|
+
const entityName = storageType === STORAGE_TYPES.groups ? 'Groups' : 'Nodes';
|
226
|
+
const count = storageType === STORAGE_TYPES.groups ? groupsCount : nodesCount;
|
234
227
|
|
235
228
|
return (
|
236
229
|
<EntitiesCount
|
@@ -259,7 +252,7 @@ class Storage extends React.Component {
|
|
259
252
|
<div className={b('search')}>
|
260
253
|
<Search
|
261
254
|
placeholder={
|
262
|
-
storageType ===
|
255
|
+
storageType === STORAGE_TYPES.groups
|
263
256
|
? 'Group ID, Pool name'
|
264
257
|
: 'Node ID, FQDN'
|
265
258
|
}
|
@@ -268,32 +261,17 @@ class Storage extends React.Component {
|
|
268
261
|
/>
|
269
262
|
</div>
|
270
263
|
|
271
|
-
<
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
</RadioButton>
|
279
|
-
|
280
|
-
<RadioButton value={visibleEntities} onUpdate={this.onGroupVisibilityChange}>
|
281
|
-
<RadioButton.Option value={VisibleEntities.Missing}>
|
282
|
-
{VisibleEntitiesTitles[VisibleEntities.Missing]}
|
283
|
-
</RadioButton.Option>
|
284
|
-
<RadioButton.Option value={VisibleEntities.Space}>
|
285
|
-
{VisibleEntitiesTitles[VisibleEntities.Space]}
|
286
|
-
</RadioButton.Option>
|
287
|
-
<RadioButton.Option value={VisibleEntities.All}>
|
288
|
-
{VisibleEntitiesTitles[VisibleEntities.All]}
|
289
|
-
</RadioButton.Option>
|
290
|
-
</RadioButton>
|
291
|
-
|
292
|
-
{storageType === StorageTypes.nodes && (
|
264
|
+
<StorageTypeFilter value={storageType} onChange={this.onStorageTypeChange} />
|
265
|
+
<StorageVisibleEntityFilter
|
266
|
+
value={visibleEntities}
|
267
|
+
onChange={this.onGroupVisibilityChange}
|
268
|
+
/>
|
269
|
+
|
270
|
+
{storageType === STORAGE_TYPES.nodes && (
|
293
271
|
<UptimeFilter value={nodesUptimeFilter} onChange={this.onUptimeFilterChange} />
|
294
272
|
)}
|
295
273
|
|
296
|
-
{storageType ===
|
274
|
+
{storageType === STORAGE_TYPES.groups && (
|
297
275
|
<UsageFilter
|
298
276
|
value={usageFilter}
|
299
277
|
onChange={setUsageFilter}
|
@@ -1,25 +1,22 @@
|
|
1
1
|
import _ from 'lodash';
|
2
2
|
import cn from 'bem-cn-lite';
|
3
|
+
|
3
4
|
import DataTable, {Column, Settings, SortOrder} from '@gravity-ui/react-data-table';
|
4
5
|
import {Icon, Label, Popover, PopoverBehavior} from '@gravity-ui/uikit';
|
5
6
|
|
6
7
|
import type {NodesMap} from '../../../types/store/nodesList';
|
8
|
+
import type {TVDiskStateInfo} from '../../../types/api/vdisk';
|
9
|
+
import type {VisibleEntities} from '../../../store/reducers/storage/types';
|
7
10
|
|
8
|
-
import
|
9
|
-
|
10
|
-
import {Stack} from '../../../components/Stack/Stack';
|
11
|
-
//@ts-ignore
|
12
|
-
import EntityStatus from '../../../components/EntityStatus/EntityStatus';
|
13
|
-
|
14
|
-
import {TVDiskStateInfo} from '../../../types/api/vdisk';
|
15
|
-
//@ts-ignore
|
16
|
-
import {VisibleEntities} from '../../../store/reducers/storage';
|
17
|
-
//@ts-ignore
|
11
|
+
import {VISIBLE_ENTITIES} from '../../../store/reducers/storage/constants';
|
18
12
|
import {bytesToGB, bytesToSpeed} from '../../../utils/utils';
|
19
|
-
//@ts-ignore
|
20
13
|
import {stringifyVdiskId} from '../../../utils';
|
21
14
|
import {getUsage, isFullVDiskData} from '../../../utils/storage';
|
22
15
|
|
16
|
+
import shieldIcon from '../../../assets/icons/shield.svg';
|
17
|
+
import {Stack} from '../../../components/Stack/Stack';
|
18
|
+
import EntityStatus from '../../../components/EntityStatus/EntityStatus';
|
19
|
+
|
23
20
|
import {EmptyFilter} from '../EmptyFilter/EmptyFilter';
|
24
21
|
import {VDisk} from '../VDisk';
|
25
22
|
import {getDegradedSeverity, getUsageSeverityForStorageGroup} from '../utils';
|
@@ -49,7 +46,7 @@ interface StorageGroupsProps {
|
|
49
46
|
data: any;
|
50
47
|
nodes: NodesMap;
|
51
48
|
tableSettings: Settings;
|
52
|
-
visibleEntities:
|
49
|
+
visibleEntities: VisibleEntities;
|
53
50
|
onShowAll?: VoidFunction;
|
54
51
|
}
|
55
52
|
|
@@ -70,21 +67,21 @@ const tableColumnsNames: Record<TableColumnsIdsValues, string> = {
|
|
70
67
|
|
71
68
|
const b = cn('global-storage-groups');
|
72
69
|
|
73
|
-
function setSortOrder(visibleEntities:
|
70
|
+
function setSortOrder(visibleEntities: VisibleEntities): SortOrder | undefined {
|
74
71
|
switch (visibleEntities) {
|
75
|
-
case
|
72
|
+
case VISIBLE_ENTITIES.all: {
|
76
73
|
return {
|
77
74
|
columnId: TableColumnsIds.PoolName,
|
78
75
|
order: DataTable.ASCENDING,
|
79
76
|
};
|
80
77
|
}
|
81
|
-
case
|
78
|
+
case VISIBLE_ENTITIES.missing: {
|
82
79
|
return {
|
83
80
|
columnId: TableColumnsIds.Missing,
|
84
81
|
order: DataTable.DESCENDING,
|
85
82
|
};
|
86
83
|
}
|
87
|
-
case
|
84
|
+
case VISIBLE_ENTITIES.space: {
|
88
85
|
return {
|
89
86
|
columnId: TableColumnsIds.UsedSpaceFlag,
|
90
87
|
order: DataTable.DESCENDING,
|
@@ -295,7 +292,7 @@ function StorageGroups({
|
|
295
292
|
|
296
293
|
let columns = allColumns;
|
297
294
|
|
298
|
-
if (visibleEntities ===
|
295
|
+
if (visibleEntities === VISIBLE_ENTITIES.all) {
|
299
296
|
columns = allColumns.filter((col) => {
|
300
297
|
return (
|
301
298
|
col.name !== TableColumnsIds.Missing && col.name !== TableColumnsIds.UsedSpaceFlag
|
@@ -303,7 +300,7 @@ function StorageGroups({
|
|
303
300
|
});
|
304
301
|
}
|
305
302
|
|
306
|
-
if (visibleEntities ===
|
303
|
+
if (visibleEntities === VISIBLE_ENTITIES.space) {
|
307
304
|
columns = allColumns.filter((col) => col.name !== TableColumnsIds.Missing);
|
308
305
|
|
309
306
|
if (!data.length) {
|
@@ -317,7 +314,7 @@ function StorageGroups({
|
|
317
314
|
}
|
318
315
|
}
|
319
316
|
|
320
|
-
if (visibleEntities ===
|
317
|
+
if (visibleEntities === VISIBLE_ENTITIES.missing) {
|
321
318
|
columns = allColumns.filter((col) => col.name !== TableColumnsIds.UsedSpaceFlag);
|
322
319
|
|
323
320
|
if (!data.length) {
|
@@ -3,7 +3,9 @@ import cn from 'bem-cn-lite';
|
|
3
3
|
|
4
4
|
import DataTable, {Column, Settings, SortOrder} from '@gravity-ui/react-data-table';
|
5
5
|
|
6
|
-
import {VisibleEntities} from '../../../store/reducers/storage';
|
6
|
+
import type {VisibleEntities} from '../../../store/reducers/storage/types';
|
7
|
+
|
8
|
+
import {VISIBLE_ENTITIES} from '../../../store/reducers/storage/constants';
|
7
9
|
import {
|
8
10
|
AdditionalNodesInfo,
|
9
11
|
isUnavailableNode,
|
@@ -35,7 +37,7 @@ interface StorageNodesProps {
|
|
35
37
|
data: any;
|
36
38
|
nodes: any;
|
37
39
|
tableSettings: Settings;
|
38
|
-
visibleEntities:
|
40
|
+
visibleEntities: VisibleEntities;
|
39
41
|
nodesUptimeFilter: keyof typeof NodesUptimeFilterValues;
|
40
42
|
onShowAll?: VoidFunction;
|
41
43
|
additionalNodesInfo?: AdditionalNodesInfo;
|
@@ -53,15 +55,15 @@ const tableColumnsNames: Record<TableColumnsIdsValues, string> = {
|
|
53
55
|
|
54
56
|
const b = cn('global-storage-nodes');
|
55
57
|
|
56
|
-
function setSortOrder(visibleEntities:
|
58
|
+
function setSortOrder(visibleEntities: VisibleEntities): SortOrder | undefined {
|
57
59
|
switch (visibleEntities) {
|
58
|
-
case
|
60
|
+
case VISIBLE_ENTITIES.all: {
|
59
61
|
return {
|
60
62
|
columnId: TableColumnsIds.NodeId,
|
61
63
|
order: DataTable.ASCENDING,
|
62
64
|
};
|
63
65
|
}
|
64
|
-
case
|
66
|
+
case VISIBLE_ENTITIES.missing: {
|
65
67
|
return {
|
66
68
|
columnId: TableColumnsIds.Missing,
|
67
69
|
order: DataTable.DESCENDING,
|
@@ -115,7 +117,7 @@ function StorageNodes({
|
|
115
117
|
name: TableColumnsIds.uptime,
|
116
118
|
header: tableColumnsNames[TableColumnsIds.uptime],
|
117
119
|
width: 130,
|
118
|
-
sortAccessor: ({StartTime}) => -StartTime,
|
120
|
+
sortAccessor: ({StartTime}) => (StartTime ? -StartTime : 0),
|
119
121
|
align: DataTable.RIGHT,
|
120
122
|
},
|
121
123
|
{
|
@@ -146,18 +148,18 @@ function StorageNodes({
|
|
146
148
|
|
147
149
|
let columns = allColumns;
|
148
150
|
|
149
|
-
if (visibleEntities ===
|
151
|
+
if (visibleEntities === VISIBLE_ENTITIES.space) {
|
150
152
|
columns = allColumns.filter((col) => col.name !== TableColumnsIds.Missing);
|
151
153
|
}
|
152
154
|
|
153
155
|
if (!data.length) {
|
154
156
|
let message;
|
155
157
|
|
156
|
-
if (visibleEntities ===
|
158
|
+
if (visibleEntities === VISIBLE_ENTITIES.space) {
|
157
159
|
message = i18n('empty.out_of_space');
|
158
160
|
}
|
159
161
|
|
160
|
-
if (visibleEntities ===
|
162
|
+
if (visibleEntities === VISIBLE_ENTITIES.missing) {
|
161
163
|
message = i18n('empty.degraded');
|
162
164
|
}
|
163
165
|
|
@@ -166,7 +168,7 @@ function StorageNodes({
|
|
166
168
|
}
|
167
169
|
|
168
170
|
if (
|
169
|
-
visibleEntities !==
|
171
|
+
visibleEntities !== VISIBLE_ENTITIES.all &&
|
170
172
|
nodesUptimeFilter !== NodesUptimeFilterValues.All
|
171
173
|
) {
|
172
174
|
message = i18n('empty.several_filters');
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import {RadioButton} from '@gravity-ui/uikit';
|
2
|
+
|
3
|
+
import type {StorageType} from '../../../store/reducers/storage/types';
|
4
|
+
import {STORAGE_TYPES} from '../../../store/reducers/storage/constants';
|
5
|
+
|
6
|
+
const StorageTypesTitles = {
|
7
|
+
[STORAGE_TYPES.groups]: 'Groups',
|
8
|
+
[STORAGE_TYPES.nodes]: 'Nodes',
|
9
|
+
};
|
10
|
+
|
11
|
+
interface StorageTypeFilterProps {
|
12
|
+
value: StorageType;
|
13
|
+
onChange: (value: string) => void;
|
14
|
+
}
|
15
|
+
|
16
|
+
export const StorageTypeFilter = ({value, onChange}: StorageTypeFilterProps) => {
|
17
|
+
return (
|
18
|
+
<RadioButton value={value} onUpdate={onChange}>
|
19
|
+
<RadioButton.Option value={STORAGE_TYPES.groups}>
|
20
|
+
{StorageTypesTitles[STORAGE_TYPES.groups]}
|
21
|
+
</RadioButton.Option>
|
22
|
+
<RadioButton.Option value={STORAGE_TYPES.nodes}>
|
23
|
+
{StorageTypesTitles[STORAGE_TYPES.nodes]}
|
24
|
+
</RadioButton.Option>
|
25
|
+
</RadioButton>
|
26
|
+
);
|
27
|
+
};
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import {RadioButton} from '@gravity-ui/uikit';
|
2
|
+
|
3
|
+
import type {VisibleEntities} from '../../../store/reducers/storage/types';
|
4
|
+
import {VISIBLE_ENTITIES} from '../../../store/reducers/storage/constants';
|
5
|
+
|
6
|
+
export const VisibleEntitiesTitles = {
|
7
|
+
[VISIBLE_ENTITIES.all]: 'All',
|
8
|
+
[VISIBLE_ENTITIES.missing]: 'Degraded',
|
9
|
+
[VISIBLE_ENTITIES.space]: 'Out of Space',
|
10
|
+
};
|
11
|
+
|
12
|
+
interface StorageProblemFilterProps {
|
13
|
+
value: VisibleEntities;
|
14
|
+
onChange: (value: string) => void;
|
15
|
+
}
|
16
|
+
|
17
|
+
export const StorageVisibleEntityFilter = ({value, onChange}: StorageProblemFilterProps) => {
|
18
|
+
return (
|
19
|
+
<RadioButton value={value} onUpdate={onChange}>
|
20
|
+
<RadioButton.Option value={VISIBLE_ENTITIES.missing}>
|
21
|
+
{VisibleEntitiesTitles[VISIBLE_ENTITIES.missing]}
|
22
|
+
</RadioButton.Option>
|
23
|
+
<RadioButton.Option value={VISIBLE_ENTITIES.space}>
|
24
|
+
{VisibleEntitiesTitles[VISIBLE_ENTITIES.space]}
|
25
|
+
</RadioButton.Option>
|
26
|
+
<RadioButton.Option value={VISIBLE_ENTITIES.all}>
|
27
|
+
{VisibleEntitiesTitles[VISIBLE_ENTITIES.all]}
|
28
|
+
</RadioButton.Option>
|
29
|
+
</RadioButton>
|
30
|
+
);
|
31
|
+
};
|
@@ -26,9 +26,10 @@ import {
|
|
26
26
|
SAVED_QUERIES_KEY,
|
27
27
|
QUERY_INITIAL_MODE_KEY,
|
28
28
|
ENABLE_ADDITIONAL_QUERY_MODES,
|
29
|
+
LAST_USED_QUERY_ACTION_KEY,
|
29
30
|
} from '../../../../utils/constants';
|
30
31
|
import {useSetting} from '../../../../utils/hooks';
|
31
|
-
import {
|
32
|
+
import {QUERY_ACTIONS, QUERY_MODES} from '../../../../utils/query';
|
32
33
|
|
33
34
|
import {
|
34
35
|
PaneVisibilityActionTypes,
|
@@ -39,7 +40,6 @@ import Preview from '../../Preview/Preview';
|
|
39
40
|
import {ExecuteResult} from '../ExecuteResult/ExecuteResult';
|
40
41
|
import {ExplainResult} from '../ExplainResult/ExplainResult';
|
41
42
|
import {QueryEditorControls} from '../QueryEditorControls/QueryEditorControls';
|
42
|
-
import {OldQueryEditorControls} from '../QueryEditorControls/OldQueryEditorControls';
|
43
43
|
|
44
44
|
import {getPreparedResult} from '../utils/getPreparedResult';
|
45
45
|
|
@@ -93,11 +93,12 @@ function QueryEditor(props) {
|
|
93
93
|
const [isResultLoaded, setIsResultLoaded] = useState(false);
|
94
94
|
const [queryMode, setQueryMode] = useSetting(QUERY_INITIAL_MODE_KEY);
|
95
95
|
const [enableAdditionalQueryModes] = useSetting(ENABLE_ADDITIONAL_QUERY_MODES);
|
96
|
+
const [lastUsedQueryAction, setLastUsedQueryAction] = useSetting(LAST_USED_QUERY_ACTION_KEY);
|
96
97
|
|
97
98
|
useEffect(() => {
|
98
|
-
const isNewQueryMode = queryMode !==
|
99
|
+
const isNewQueryMode = queryMode !== QUERY_MODES.script && queryMode !== QUERY_MODES.scan;
|
99
100
|
if (!enableAdditionalQueryModes && isNewQueryMode) {
|
100
|
-
setQueryMode(
|
101
|
+
setQueryMode(QUERY_MODES.script);
|
101
102
|
}
|
102
103
|
}, [enableAdditionalQueryModes, queryMode, setQueryMode]);
|
103
104
|
|
@@ -170,7 +171,11 @@ function QueryEditor(props) {
|
|
170
171
|
setMonacoHotKey(null);
|
171
172
|
switch (monacoHotKey) {
|
172
173
|
case MONACO_HOT_KEY_ACTIONS.sendQuery: {
|
173
|
-
|
174
|
+
if (lastUsedQueryAction === QUERY_ACTIONS.explain) {
|
175
|
+
return handleGetExplainQueryClick(queryMode);
|
176
|
+
} else {
|
177
|
+
return handleSendExecuteClick(queryMode);
|
178
|
+
}
|
174
179
|
}
|
175
180
|
case MONACO_HOT_KEY_ACTIONS.goPrev: {
|
176
181
|
return handlePreviousHistoryClick();
|
@@ -178,9 +183,6 @@ function QueryEditor(props) {
|
|
178
183
|
case MONACO_HOT_KEY_ACTIONS.goNext: {
|
179
184
|
return handleNextHistoryClick();
|
180
185
|
}
|
181
|
-
case MONACO_HOT_KEY_ACTIONS.getExplain: {
|
182
|
-
return handleGetExplainQueryClick();
|
183
|
-
}
|
184
186
|
default: {
|
185
187
|
return;
|
186
188
|
}
|
@@ -201,8 +203,8 @@ function QueryEditor(props) {
|
|
201
203
|
editorRef.current = editor;
|
202
204
|
editor.focus();
|
203
205
|
editor.addAction({
|
204
|
-
id: '
|
205
|
-
label: '
|
206
|
+
id: 'sendQuery',
|
207
|
+
label: 'Send query',
|
206
208
|
keybindings: [
|
207
209
|
// eslint-disable-next-line no-bitwise
|
208
210
|
monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter,
|
@@ -240,22 +242,6 @@ function QueryEditor(props) {
|
|
240
242
|
contextMenuOrder: 3,
|
241
243
|
run: handleKeyBinding(MONACO_HOT_KEY_ACTIONS.goNext),
|
242
244
|
});
|
243
|
-
|
244
|
-
editor.addAction({
|
245
|
-
id: 'explain',
|
246
|
-
label: 'Explain',
|
247
|
-
keybindings: [
|
248
|
-
// eslint-disable-next-line no-bitwise
|
249
|
-
monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_E,
|
250
|
-
],
|
251
|
-
// A precondition for this action.
|
252
|
-
precondition: null,
|
253
|
-
// A rule to evaluate on top of the precondition in order to dispatch the keybindings.
|
254
|
-
keybindingContext: null,
|
255
|
-
contextMenuGroupId: CONTEXT_MENU_GROUP_ID,
|
256
|
-
contextMenuOrder: 4,
|
257
|
-
run: handleKeyBinding(MONACO_HOT_KEY_ACTIONS.getExplain),
|
258
|
-
});
|
259
245
|
};
|
260
246
|
const onChange = (newValue) => {
|
261
247
|
props.changeUserInput({input: newValue});
|
@@ -270,6 +256,7 @@ function QueryEditor(props) {
|
|
270
256
|
setShowPreview,
|
271
257
|
} = props;
|
272
258
|
|
259
|
+
setLastUsedQueryAction(QUERY_ACTIONS.execute);
|
273
260
|
setResultType(RESULT_TYPES.EXECUTE);
|
274
261
|
sendExecuteQuery({query: input, database: path, mode});
|
275
262
|
setIsResultLoaded(true);
|
@@ -290,6 +277,7 @@ function QueryEditor(props) {
|
|
290
277
|
setShowPreview,
|
291
278
|
} = props;
|
292
279
|
|
280
|
+
setLastUsedQueryAction(QUERY_ACTIONS.explain);
|
293
281
|
setResultType(RESULT_TYPES.EXPLAIN);
|
294
282
|
getExplainQuery({
|
295
283
|
query: input,
|
@@ -488,24 +476,8 @@ function QueryEditor(props) {
|
|
488
476
|
const renderControls = () => {
|
489
477
|
const {executeQuery, explainQuery, savedQueries} = props;
|
490
478
|
|
491
|
-
if (enableAdditionalQueryModes) {
|
492
|
-
return (
|
493
|
-
<QueryEditorControls
|
494
|
-
onRunButtonClick={handleSendExecuteClick}
|
495
|
-
runIsLoading={executeQuery.loading}
|
496
|
-
onExplainButtonClick={handleGetExplainQueryClick}
|
497
|
-
explainIsLoading={explainQuery.loading}
|
498
|
-
onSaveQueryClick={onSaveQueryHandler}
|
499
|
-
savedQueries={savedQueries}
|
500
|
-
disabled={!executeQuery.input}
|
501
|
-
onUpdateQueryMode={setQueryMode}
|
502
|
-
queryMode={queryMode}
|
503
|
-
/>
|
504
|
-
);
|
505
|
-
}
|
506
|
-
|
507
479
|
return (
|
508
|
-
<
|
480
|
+
<QueryEditorControls
|
509
481
|
onRunButtonClick={handleSendExecuteClick}
|
510
482
|
runIsLoading={executeQuery.loading}
|
511
483
|
onExplainButtonClick={handleGetExplainQueryClick}
|
@@ -515,6 +487,8 @@ function QueryEditor(props) {
|
|
515
487
|
disabled={!executeQuery.input}
|
516
488
|
onUpdateQueryMode={setQueryMode}
|
517
489
|
queryMode={queryMode}
|
490
|
+
enableAdditionalQueryModes={enableAdditionalQueryModes}
|
491
|
+
highlitedAction={lastUsedQueryAction}
|
518
492
|
/>
|
519
493
|
);
|
520
494
|
};
|