ydb-embedded-ui 4.8.2 → 4.10.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 +27 -0
- package/dist/components/BasicNodeViewer/BasicNodeViewer.tsx +7 -4
- package/dist/components/EntityStatus/EntityStatus.js +3 -1
- package/dist/components/FormattedBytes/FormattedBytes.tsx +10 -0
- package/dist/components/FormattedBytes/utils.tsx +13 -0
- package/dist/components/FullNodeViewer/FullNodeViewer.tsx +73 -0
- package/dist/components/InfoViewer/formatters/table.ts +6 -5
- package/dist/components/NodeHostWrapper/NodeHostWrapper.tsx +2 -2
- package/dist/components/ProblemFilter/ProblemFilter.tsx +2 -2
- package/dist/components/SpeedMultiMeter/SpeedMultiMeter.tsx +4 -4
- package/dist/components/TruncatedQuery/{TruncatedQuery.js → TruncatedQuery.tsx} +10 -8
- package/dist/containers/AsideNavigation/AsideNavigation.tsx +6 -6
- package/dist/containers/Cluster/Cluster.tsx +10 -6
- package/dist/containers/Node/Node.tsx +3 -3
- package/dist/containers/Nodes/Nodes.tsx +3 -3
- package/dist/containers/Nodes/getNodesColumns.tsx +2 -2
- package/dist/containers/Storage/PDisk/PDisk.tsx +2 -7
- package/dist/containers/Storage/Storage.tsx +240 -0
- package/dist/containers/Storage/StorageGroups/StorageGroups.tsx +59 -57
- package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +23 -25
- package/dist/containers/Storage/StorageTypeFilter/StorageTypeFilter.tsx +27 -0
- package/dist/containers/Storage/StorageVisibleEntityFilter/StorageVisibleEntityFilter.tsx +31 -0
- package/dist/containers/Storage/UsageFilter/UsageFilter.scss +1 -0
- package/dist/containers/Storage/UsageFilter/UsageFilter.tsx +17 -17
- package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +3 -3
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +7 -4
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.scss +0 -15
- package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.tsx +10 -3
- package/dist/containers/Tenant/{Preview → Query/Preview}/Preview.scss +1 -1
- package/dist/containers/Tenant/Query/Preview/Preview.tsx +121 -0
- package/dist/containers/Tenant/Query/QueriesHistory/QueriesHistory.tsx +1 -1
- package/dist/containers/Tenant/Query/QueryEditor/QueryEditor.js +23 -51
- 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/SavedQueries/SavedQueries.tsx +1 -1
- package/dist/containers/Tenant/Query/i18n/en.json +9 -2
- package/dist/containers/Tenant/Query/i18n/ru.json +9 -2
- package/dist/containers/Tenants/Tenants.tsx +269 -0
- package/dist/containers/UserSettings/i18n/en.json +1 -1
- package/dist/containers/UserSettings/i18n/ru.json +1 -1
- package/dist/services/api.ts +14 -16
- 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} +33 -32
- package/dist/{types/store/nodes.ts → store/reducers/nodes/types.ts} +24 -27
- package/dist/store/reducers/partitions/types.ts +3 -3
- package/dist/store/reducers/settings/settings.ts +14 -4
- package/dist/store/reducers/settings/types.ts +3 -1
- package/dist/store/reducers/storage/constants.ts +10 -0
- package/dist/store/reducers/storage/selectors.ts +279 -0
- package/dist/store/reducers/storage/storage.ts +191 -0
- package/dist/store/reducers/storage/types.ts +92 -0
- package/dist/store/reducers/tenants/selectors.ts +46 -0
- package/dist/store/reducers/tenants/tenants.ts +21 -14
- package/dist/store/reducers/tenants/types.ts +20 -5
- package/dist/store/reducers/tenants/utils.ts +68 -0
- package/dist/types/additionalProps.ts +8 -0
- package/dist/types/api/storage.ts +1 -1
- package/dist/types/store/query.ts +5 -6
- package/dist/types/store/topic.ts +3 -3
- package/dist/utils/bytesParsers/__test__/formatBytes.test.ts +38 -0
- package/dist/utils/bytesParsers/convertBytesObjectToSpeed.ts +2 -2
- package/dist/utils/bytesParsers/formatBytes.ts +132 -0
- package/dist/utils/bytesParsers/i18n/en.json +1 -0
- package/dist/utils/bytesParsers/i18n/ru.json +1 -0
- package/dist/utils/bytesParsers/index.ts +1 -1
- package/dist/utils/constants.ts +1 -0
- package/dist/utils/index.js +5 -10
- package/dist/utils/nodes.ts +2 -2
- package/dist/utils/numeral.ts +8 -0
- package/dist/utils/query.ts +12 -0
- package/package.json +1 -1
- package/dist/components/FullNodeViewer/FullNodeViewer.js +0 -89
- package/dist/containers/Node/NodeOverview/NodeOverview.scss +0 -0
- package/dist/containers/Node/NodeOverview/NodeOverview.tsx +0 -21
- package/dist/containers/Storage/Storage.js +0 -372
- package/dist/containers/Tenant/Preview/Preview.js +0 -168
- package/dist/containers/Tenant/Query/QueryEditorControls/OldQueryEditorControls.tsx +0 -90
- package/dist/containers/Tenant/Query/QueryEditorControls/shared.ts +0 -18
- package/dist/containers/Tenants/Tenants.js +0 -363
- package/dist/store/reducers/storage.js +0 -438
- package/dist/utils/bytesParsers/formatBytesCustom.ts +0 -57
@@ -0,0 +1,240 @@
|
|
1
|
+
import {useCallback, useEffect} from 'react';
|
2
|
+
import {useDispatch} from 'react-redux';
|
3
|
+
import cn from 'bem-cn-lite';
|
4
|
+
|
5
|
+
import DataTable, {Settings} from '@gravity-ui/react-data-table';
|
6
|
+
|
7
|
+
import {Search} from '../../components/Search';
|
8
|
+
import {TableSkeleton} from '../../components/TableSkeleton/TableSkeleton';
|
9
|
+
import {UptimeFilter} from '../../components/UptimeFIlter';
|
10
|
+
import {AccessDenied} from '../../components/Errors/403';
|
11
|
+
import {EntitiesCount} from '../../components/EntitiesCount';
|
12
|
+
|
13
|
+
import type {StorageType, VisibleEntities} from '../../store/reducers/storage/types';
|
14
|
+
import {
|
15
|
+
getStorageInfo,
|
16
|
+
setInitialState,
|
17
|
+
setVisibleEntities,
|
18
|
+
setStorageTextFilter,
|
19
|
+
setUsageFilter,
|
20
|
+
setStorageType,
|
21
|
+
setNodesUptimeFilter,
|
22
|
+
setDataWasNotLoaded,
|
23
|
+
} from '../../store/reducers/storage/storage';
|
24
|
+
import {
|
25
|
+
selectFilteredGroups,
|
26
|
+
selectFilteredNodes,
|
27
|
+
selectStorageNodesCount,
|
28
|
+
selectStorageGroupsCount,
|
29
|
+
selectUsageFilterOptions,
|
30
|
+
} from '../../store/reducers/storage/selectors';
|
31
|
+
import {VISIBLE_ENTITIES, STORAGE_TYPES} from '../../store/reducers/storage/constants';
|
32
|
+
import {getNodesList, selectNodesMap} from '../../store/reducers/nodesList';
|
33
|
+
import {useAutofetcher, useTypedSelector} from '../../utils/hooks';
|
34
|
+
import {AdditionalNodesInfo, NodesUptimeFilterValues} from '../../utils/nodes';
|
35
|
+
import {DEFAULT_TABLE_SETTINGS} from '../../utils/constants';
|
36
|
+
|
37
|
+
import {StorageGroups} from './StorageGroups/StorageGroups';
|
38
|
+
import {StorageNodes} from './StorageNodes/StorageNodes';
|
39
|
+
import {StorageTypeFilter} from './StorageTypeFilter/StorageTypeFilter';
|
40
|
+
import {StorageVisibleEntityFilter} from './StorageVisibleEntityFilter/StorageVisibleEntityFilter';
|
41
|
+
import {UsageFilter} from './UsageFilter';
|
42
|
+
|
43
|
+
import './Storage.scss';
|
44
|
+
|
45
|
+
const b = cn('global-storage');
|
46
|
+
|
47
|
+
const tableSettings: Settings = {
|
48
|
+
...DEFAULT_TABLE_SETTINGS,
|
49
|
+
defaultOrder: DataTable.DESCENDING,
|
50
|
+
};
|
51
|
+
|
52
|
+
interface StorageProps {
|
53
|
+
additionalNodesInfo?: AdditionalNodesInfo;
|
54
|
+
tenant?: string;
|
55
|
+
nodeId?: string;
|
56
|
+
}
|
57
|
+
|
58
|
+
export const Storage = ({additionalNodesInfo, tenant, nodeId}: StorageProps) => {
|
59
|
+
const dispatch = useDispatch();
|
60
|
+
|
61
|
+
const {autorefresh} = useTypedSelector((state) => state.schema);
|
62
|
+
const {
|
63
|
+
loading,
|
64
|
+
wasLoaded,
|
65
|
+
error,
|
66
|
+
type: storageType,
|
67
|
+
visible: visibleEntities,
|
68
|
+
filter,
|
69
|
+
usageFilter,
|
70
|
+
nodesUptimeFilter,
|
71
|
+
} = useTypedSelector((state) => state.storage);
|
72
|
+
const storageNodes = useTypedSelector(selectFilteredNodes);
|
73
|
+
const storageGroups = useTypedSelector(selectFilteredGroups);
|
74
|
+
const nodesCount = useTypedSelector(selectStorageNodesCount);
|
75
|
+
const groupsCount = useTypedSelector(selectStorageGroupsCount);
|
76
|
+
const nodesMap = useTypedSelector(selectNodesMap);
|
77
|
+
const usageFilterOptions = useTypedSelector(selectUsageFilterOptions);
|
78
|
+
|
79
|
+
useEffect(() => {
|
80
|
+
dispatch(getNodesList());
|
81
|
+
|
82
|
+
return () => {
|
83
|
+
// Clean data on component unmount
|
84
|
+
dispatch(setInitialState());
|
85
|
+
};
|
86
|
+
}, [dispatch]);
|
87
|
+
|
88
|
+
const fetchData = useCallback(
|
89
|
+
(isBackground: boolean) => {
|
90
|
+
if (!isBackground) {
|
91
|
+
dispatch(setDataWasNotLoaded());
|
92
|
+
}
|
93
|
+
|
94
|
+
dispatch(
|
95
|
+
getStorageInfo(
|
96
|
+
{
|
97
|
+
tenant,
|
98
|
+
nodeId,
|
99
|
+
visibleEntities,
|
100
|
+
type: storageType,
|
101
|
+
},
|
102
|
+
{
|
103
|
+
concurrentId: 'getStorageInfo',
|
104
|
+
},
|
105
|
+
),
|
106
|
+
);
|
107
|
+
},
|
108
|
+
[dispatch, tenant, nodeId, visibleEntities, storageType],
|
109
|
+
);
|
110
|
+
|
111
|
+
const autorefreshEnabled = tenant ? autorefresh : true;
|
112
|
+
|
113
|
+
useAutofetcher(fetchData, [fetchData], autorefreshEnabled);
|
114
|
+
|
115
|
+
const handleUsageFilterChange = (value: string[]) => {
|
116
|
+
dispatch(setUsageFilter(value));
|
117
|
+
};
|
118
|
+
|
119
|
+
const handleTextFilterChange = (value: string) => {
|
120
|
+
dispatch(setStorageTextFilter(value));
|
121
|
+
};
|
122
|
+
|
123
|
+
const handleGroupVisibilityChange = (value: string) => {
|
124
|
+
dispatch(setVisibleEntities(value as VisibleEntities));
|
125
|
+
};
|
126
|
+
|
127
|
+
const handleStorageTypeChange = (value: string) => {
|
128
|
+
dispatch(setStorageType(value as StorageType));
|
129
|
+
};
|
130
|
+
|
131
|
+
const handleUptimeFilterChange = (value: string) => {
|
132
|
+
dispatch(setNodesUptimeFilter(value as NodesUptimeFilterValues));
|
133
|
+
};
|
134
|
+
|
135
|
+
const handleShowAllNodes = () => {
|
136
|
+
handleGroupVisibilityChange(VISIBLE_ENTITIES.all);
|
137
|
+
handleUptimeFilterChange(NodesUptimeFilterValues.All);
|
138
|
+
};
|
139
|
+
|
140
|
+
const renderLoader = () => {
|
141
|
+
return <TableSkeleton className={b('loader')} />;
|
142
|
+
};
|
143
|
+
|
144
|
+
const renderDataTable = () => {
|
145
|
+
return (
|
146
|
+
<div className={b('table-wrapper')}>
|
147
|
+
{storageType === STORAGE_TYPES.groups && (
|
148
|
+
<StorageGroups
|
149
|
+
visibleEntities={visibleEntities}
|
150
|
+
data={storageGroups}
|
151
|
+
tableSettings={tableSettings}
|
152
|
+
nodes={nodesMap}
|
153
|
+
onShowAll={() => handleGroupVisibilityChange(VISIBLE_ENTITIES.all)}
|
154
|
+
/>
|
155
|
+
)}
|
156
|
+
{storageType === STORAGE_TYPES.nodes && (
|
157
|
+
<StorageNodes
|
158
|
+
visibleEntities={visibleEntities}
|
159
|
+
nodesUptimeFilter={nodesUptimeFilter}
|
160
|
+
data={storageNodes}
|
161
|
+
tableSettings={tableSettings}
|
162
|
+
onShowAll={handleShowAllNodes}
|
163
|
+
additionalNodesInfo={additionalNodesInfo}
|
164
|
+
/>
|
165
|
+
)}
|
166
|
+
</div>
|
167
|
+
);
|
168
|
+
};
|
169
|
+
|
170
|
+
const renderEntitiesCount = () => {
|
171
|
+
const entityName = storageType === STORAGE_TYPES.groups ? 'Groups' : 'Nodes';
|
172
|
+
const count = storageType === STORAGE_TYPES.groups ? groupsCount : nodesCount;
|
173
|
+
const current =
|
174
|
+
storageType === STORAGE_TYPES.groups ? storageGroups.length : storageNodes.length;
|
175
|
+
|
176
|
+
return (
|
177
|
+
<EntitiesCount
|
178
|
+
label={entityName}
|
179
|
+
loading={loading && !wasLoaded}
|
180
|
+
total={count.total}
|
181
|
+
current={current}
|
182
|
+
/>
|
183
|
+
);
|
184
|
+
};
|
185
|
+
|
186
|
+
const renderControls = () => {
|
187
|
+
return (
|
188
|
+
<div className={b('controls')}>
|
189
|
+
<div className={b('search')}>
|
190
|
+
<Search
|
191
|
+
placeholder={
|
192
|
+
storageType === STORAGE_TYPES.groups
|
193
|
+
? 'Group ID, Pool name'
|
194
|
+
: 'Node ID, FQDN'
|
195
|
+
}
|
196
|
+
onChange={handleTextFilterChange}
|
197
|
+
value={filter}
|
198
|
+
/>
|
199
|
+
</div>
|
200
|
+
|
201
|
+
<StorageTypeFilter value={storageType} onChange={handleStorageTypeChange} />
|
202
|
+
<StorageVisibleEntityFilter
|
203
|
+
value={visibleEntities}
|
204
|
+
onChange={handleGroupVisibilityChange}
|
205
|
+
/>
|
206
|
+
|
207
|
+
{storageType === STORAGE_TYPES.nodes && (
|
208
|
+
<UptimeFilter value={nodesUptimeFilter} onChange={handleUptimeFilterChange} />
|
209
|
+
)}
|
210
|
+
|
211
|
+
{storageType === STORAGE_TYPES.groups && (
|
212
|
+
<UsageFilter
|
213
|
+
value={usageFilter}
|
214
|
+
onChange={handleUsageFilterChange}
|
215
|
+
groups={usageFilterOptions}
|
216
|
+
disabled={usageFilterOptions.length === 0}
|
217
|
+
/>
|
218
|
+
)}
|
219
|
+
{renderEntitiesCount()}
|
220
|
+
</div>
|
221
|
+
);
|
222
|
+
};
|
223
|
+
|
224
|
+
const showLoader = loading && !wasLoaded;
|
225
|
+
|
226
|
+
if (error) {
|
227
|
+
if (error.status === 403) {
|
228
|
+
return <AccessDenied />;
|
229
|
+
}
|
230
|
+
|
231
|
+
return <div className={b()}>{error.statusText}</div>;
|
232
|
+
}
|
233
|
+
|
234
|
+
return (
|
235
|
+
<div className={b()}>
|
236
|
+
{renderControls()}
|
237
|
+
{showLoader ? renderLoader() : renderDataTable()}
|
238
|
+
</div>
|
239
|
+
);
|
240
|
+
};
|
@@ -1,25 +1,20 @@
|
|
1
|
-
import _ from 'lodash';
|
2
1
|
import cn from 'bem-cn-lite';
|
2
|
+
|
3
3
|
import DataTable, {Column, Settings, SortOrder} from '@gravity-ui/react-data-table';
|
4
4
|
import {Icon, Label, Popover, PopoverBehavior} from '@gravity-ui/uikit';
|
5
5
|
|
6
6
|
import type {NodesMap} from '../../../types/store/nodesList';
|
7
|
+
import type {PreparedStorageGroup, VisibleEntities} from '../../../store/reducers/storage/types';
|
7
8
|
|
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
|
9
|
+
import {VISIBLE_ENTITIES} from '../../../store/reducers/storage/constants';
|
18
10
|
import {bytesToGB, bytesToSpeed} from '../../../utils/utils';
|
19
|
-
//@ts-ignore
|
20
11
|
import {stringifyVdiskId} from '../../../utils';
|
21
12
|
import {getUsage, isFullVDiskData} from '../../../utils/storage';
|
22
13
|
|
14
|
+
import shieldIcon from '../../../assets/icons/shield.svg';
|
15
|
+
import {Stack} from '../../../components/Stack/Stack';
|
16
|
+
import EntityStatus from '../../../components/EntityStatus/EntityStatus';
|
17
|
+
|
23
18
|
import {EmptyFilter} from '../EmptyFilter/EmptyFilter';
|
24
19
|
import {VDisk} from '../VDisk';
|
25
20
|
import {getDegradedSeverity, getUsageSeverityForStorageGroup} from '../utils';
|
@@ -46,10 +41,10 @@ type TableColumnsIdsKeys = keyof typeof TableColumnsIds;
|
|
46
41
|
type TableColumnsIdsValues = typeof TableColumnsIds[TableColumnsIdsKeys];
|
47
42
|
|
48
43
|
interface StorageGroupsProps {
|
49
|
-
data:
|
50
|
-
nodes
|
44
|
+
data: PreparedStorageGroup[];
|
45
|
+
nodes?: NodesMap;
|
51
46
|
tableSettings: Settings;
|
52
|
-
visibleEntities:
|
47
|
+
visibleEntities: VisibleEntities;
|
53
48
|
onShowAll?: VoidFunction;
|
54
49
|
}
|
55
50
|
|
@@ -70,21 +65,21 @@ const tableColumnsNames: Record<TableColumnsIdsValues, string> = {
|
|
70
65
|
|
71
66
|
const b = cn('global-storage-groups');
|
72
67
|
|
73
|
-
function setSortOrder(visibleEntities:
|
68
|
+
function setSortOrder(visibleEntities: VisibleEntities): SortOrder | undefined {
|
74
69
|
switch (visibleEntities) {
|
75
|
-
case
|
70
|
+
case VISIBLE_ENTITIES.all: {
|
76
71
|
return {
|
77
72
|
columnId: TableColumnsIds.PoolName,
|
78
73
|
order: DataTable.ASCENDING,
|
79
74
|
};
|
80
75
|
}
|
81
|
-
case
|
76
|
+
case VISIBLE_ENTITIES.missing: {
|
82
77
|
return {
|
83
78
|
columnId: TableColumnsIds.Missing,
|
84
79
|
order: DataTable.DESCENDING,
|
85
80
|
};
|
86
81
|
}
|
87
|
-
case
|
82
|
+
case VISIBLE_ENTITIES.space: {
|
88
83
|
return {
|
89
84
|
columnId: TableColumnsIds.UsedSpaceFlag,
|
90
85
|
order: DataTable.DESCENDING,
|
@@ -96,25 +91,25 @@ function setSortOrder(visibleEntities: keyof typeof VisibleEntities): SortOrder
|
|
96
91
|
}
|
97
92
|
}
|
98
93
|
|
99
|
-
function StorageGroups({
|
94
|
+
export function StorageGroups({
|
100
95
|
data,
|
101
96
|
tableSettings,
|
102
97
|
visibleEntities,
|
103
98
|
nodes,
|
104
99
|
onShowAll,
|
105
100
|
}: StorageGroupsProps) {
|
106
|
-
const allColumns: Column<
|
101
|
+
const allColumns: Column<PreparedStorageGroup>[] = [
|
107
102
|
{
|
108
103
|
name: TableColumnsIds.PoolName,
|
109
104
|
header: tableColumnsNames[TableColumnsIds.PoolName],
|
110
105
|
width: 250,
|
111
|
-
render: ({
|
112
|
-
const splitted =
|
106
|
+
render: ({row}) => {
|
107
|
+
const splitted = row.PoolName?.split('/');
|
113
108
|
return (
|
114
109
|
<div className={b('pool-name-wrapper')}>
|
115
110
|
{splitted && (
|
116
111
|
<Popover
|
117
|
-
content={
|
112
|
+
content={row.PoolName}
|
118
113
|
placement={['right']}
|
119
114
|
behavior={PopoverBehavior.Immediate}
|
120
115
|
>
|
@@ -132,9 +127,9 @@ function StorageGroups({
|
|
132
127
|
name: TableColumnsIds.Type,
|
133
128
|
header: tableColumnsNames[TableColumnsIds.Type],
|
134
129
|
// prettier-ignore
|
135
|
-
render: ({
|
130
|
+
render: ({row}) => (
|
136
131
|
<>
|
137
|
-
<Label>{
|
132
|
+
<Label>{row.Type || '—'}</Label>
|
138
133
|
{' '}
|
139
134
|
{row.Encryption && (
|
140
135
|
<Popover
|
@@ -160,8 +155,12 @@ function StorageGroups({
|
|
160
155
|
name: TableColumnsIds.Missing,
|
161
156
|
header: tableColumnsNames[TableColumnsIds.Missing],
|
162
157
|
width: 100,
|
163
|
-
render: ({
|
164
|
-
|
158
|
+
render: ({row}) =>
|
159
|
+
row.Missing ? (
|
160
|
+
<Label theme={getDegradedSeverity(row)}>Degraded: {row.Missing}</Label>
|
161
|
+
) : (
|
162
|
+
'-'
|
163
|
+
),
|
165
164
|
align: DataTable.LEFT,
|
166
165
|
defaultOrder: DataTable.DESCENDING,
|
167
166
|
},
|
@@ -192,8 +191,8 @@ function StorageGroups({
|
|
192
191
|
name: TableColumnsIds.GroupID,
|
193
192
|
header: tableColumnsNames[TableColumnsIds.GroupID],
|
194
193
|
width: 130,
|
195
|
-
render: ({
|
196
|
-
return <span className={b('group-id')}>{
|
194
|
+
render: ({row}) => {
|
195
|
+
return <span className={b('group-id')}>{row.GroupID}</span>;
|
197
196
|
},
|
198
197
|
align: DataTable.RIGHT,
|
199
198
|
},
|
@@ -201,8 +200,8 @@ function StorageGroups({
|
|
201
200
|
name: TableColumnsIds.Used,
|
202
201
|
header: tableColumnsNames[TableColumnsIds.Used],
|
203
202
|
width: 100,
|
204
|
-
render: ({
|
205
|
-
return bytesToGB(
|
203
|
+
render: ({row}) => {
|
204
|
+
return bytesToGB(row.Used, true);
|
206
205
|
},
|
207
206
|
align: DataTable.RIGHT,
|
208
207
|
},
|
@@ -210,8 +209,8 @@ function StorageGroups({
|
|
210
209
|
name: TableColumnsIds.Limit,
|
211
210
|
header: tableColumnsNames[TableColumnsIds.Limit],
|
212
211
|
width: 100,
|
213
|
-
render: ({
|
214
|
-
return bytesToGB(
|
212
|
+
render: ({row}) => {
|
213
|
+
return bytesToGB(row.Limit);
|
215
214
|
},
|
216
215
|
align: DataTable.RIGHT,
|
217
216
|
},
|
@@ -219,15 +218,17 @@ function StorageGroups({
|
|
219
218
|
name: TableColumnsIds.UsedSpaceFlag,
|
220
219
|
header: tableColumnsNames[TableColumnsIds.UsedSpaceFlag],
|
221
220
|
width: 110,
|
222
|
-
render: ({
|
223
|
-
const
|
221
|
+
render: ({row}) => {
|
222
|
+
const value = row.UsedSpaceFlag;
|
223
|
+
|
224
224
|
let color = 'Red';
|
225
|
-
|
225
|
+
|
226
|
+
if (value < 100) {
|
226
227
|
color = 'Green';
|
227
|
-
} else if (
|
228
|
+
} else if (value < 10000) {
|
228
229
|
color = 'Yellow';
|
229
|
-
} else if (
|
230
|
-
|
230
|
+
} else if (value < 1000000) {
|
231
|
+
color = 'Orange';
|
231
232
|
}
|
232
233
|
return <EntityStatus status={color} />;
|
233
234
|
},
|
@@ -238,8 +239,8 @@ function StorageGroups({
|
|
238
239
|
name: TableColumnsIds.Read,
|
239
240
|
header: tableColumnsNames[TableColumnsIds.Read],
|
240
241
|
width: 100,
|
241
|
-
render: ({
|
242
|
-
return
|
242
|
+
render: ({row}) => {
|
243
|
+
return row.Read ? bytesToSpeed(row.Read) : '-';
|
243
244
|
},
|
244
245
|
align: DataTable.RIGHT,
|
245
246
|
},
|
@@ -247,8 +248,8 @@ function StorageGroups({
|
|
247
248
|
name: TableColumnsIds.Write,
|
248
249
|
header: tableColumnsNames[TableColumnsIds.Write],
|
249
250
|
width: 100,
|
250
|
-
render: ({
|
251
|
-
return
|
251
|
+
render: ({row}) => {
|
252
|
+
return row.Write ? bytesToSpeed(row.Write) : '-';
|
252
253
|
},
|
253
254
|
align: DataTable.RIGHT,
|
254
255
|
},
|
@@ -256,14 +257,17 @@ function StorageGroups({
|
|
256
257
|
name: TableColumnsIds.VDisks,
|
257
258
|
className: b('vdisks-column'),
|
258
259
|
header: tableColumnsNames[TableColumnsIds.VDisks],
|
259
|
-
render: ({
|
260
|
+
render: ({row}) => (
|
260
261
|
<div className={b('vdisks-wrapper')}>
|
261
|
-
{
|
262
|
-
const donors =
|
262
|
+
{row.VDisks?.map((vDisk) => {
|
263
|
+
const donors = vDisk.Donors;
|
263
264
|
|
264
265
|
return donors && donors.length > 0 ? (
|
265
|
-
<Stack
|
266
|
-
|
266
|
+
<Stack
|
267
|
+
className={b('vdisks-item')}
|
268
|
+
key={stringifyVdiskId(vDisk.VDiskId)}
|
269
|
+
>
|
270
|
+
<VDisk data={vDisk} nodes={nodes} />
|
267
271
|
{donors.map((donor) => {
|
268
272
|
const isFullData = isFullVDiskData(donor);
|
269
273
|
|
@@ -280,8 +284,8 @@ function StorageGroups({
|
|
280
284
|
})}
|
281
285
|
</Stack>
|
282
286
|
) : (
|
283
|
-
<div className={b('vdisks-item')} key={stringifyVdiskId(
|
284
|
-
<VDisk data={
|
287
|
+
<div className={b('vdisks-item')} key={stringifyVdiskId(vDisk.VDiskId)}>
|
288
|
+
<VDisk data={vDisk} nodes={nodes} />
|
285
289
|
</div>
|
286
290
|
);
|
287
291
|
})}
|
@@ -295,7 +299,7 @@ function StorageGroups({
|
|
295
299
|
|
296
300
|
let columns = allColumns;
|
297
301
|
|
298
|
-
if (visibleEntities ===
|
302
|
+
if (visibleEntities === VISIBLE_ENTITIES.all) {
|
299
303
|
columns = allColumns.filter((col) => {
|
300
304
|
return (
|
301
305
|
col.name !== TableColumnsIds.Missing && col.name !== TableColumnsIds.UsedSpaceFlag
|
@@ -303,7 +307,7 @@ function StorageGroups({
|
|
303
307
|
});
|
304
308
|
}
|
305
309
|
|
306
|
-
if (visibleEntities ===
|
310
|
+
if (visibleEntities === VISIBLE_ENTITIES.space) {
|
307
311
|
columns = allColumns.filter((col) => col.name !== TableColumnsIds.Missing);
|
308
312
|
|
309
313
|
if (!data.length) {
|
@@ -317,7 +321,7 @@ function StorageGroups({
|
|
317
321
|
}
|
318
322
|
}
|
319
323
|
|
320
|
-
if (visibleEntities ===
|
324
|
+
if (visibleEntities === VISIBLE_ENTITIES.missing) {
|
321
325
|
columns = allColumns.filter((col) => col.name !== TableColumnsIds.UsedSpaceFlag);
|
322
326
|
|
323
327
|
if (!data.length) {
|
@@ -333,7 +337,7 @@ function StorageGroups({
|
|
333
337
|
|
334
338
|
return data ? (
|
335
339
|
<DataTable
|
336
|
-
key={visibleEntities
|
340
|
+
key={visibleEntities}
|
337
341
|
theme="yandex-cloud"
|
338
342
|
data={data}
|
339
343
|
columns={columns}
|
@@ -343,5 +347,3 @@ function StorageGroups({
|
|
343
347
|
/>
|
344
348
|
) : null;
|
345
349
|
}
|
346
|
-
|
347
|
-
export default StorageGroups;
|
@@ -1,9 +1,10 @@
|
|
1
|
-
import _ from 'lodash';
|
2
1
|
import cn from 'bem-cn-lite';
|
3
2
|
|
4
3
|
import DataTable, {Column, Settings, SortOrder} from '@gravity-ui/react-data-table';
|
5
4
|
|
6
|
-
import {VisibleEntities} from '../../../store/reducers/storage';
|
5
|
+
import type {PreparedStorageNode, VisibleEntities} from '../../../store/reducers/storage/types';
|
6
|
+
|
7
|
+
import {VISIBLE_ENTITIES} from '../../../store/reducers/storage/constants';
|
7
8
|
import {
|
8
9
|
AdditionalNodesInfo,
|
9
10
|
isUnavailableNode,
|
@@ -23,7 +24,7 @@ enum TableColumnsIds {
|
|
23
24
|
FQDN = 'FQDN',
|
24
25
|
DataCenter = 'DataCenter',
|
25
26
|
Rack = 'Rack',
|
26
|
-
|
27
|
+
Uptime = 'Uptime',
|
27
28
|
PDisks = 'PDisks',
|
28
29
|
Missing = 'Missing',
|
29
30
|
}
|
@@ -32,10 +33,9 @@ type TableColumnsIdsKeys = keyof typeof TableColumnsIds;
|
|
32
33
|
type TableColumnsIdsValues = typeof TableColumnsIds[TableColumnsIdsKeys];
|
33
34
|
|
34
35
|
interface StorageNodesProps {
|
35
|
-
data:
|
36
|
-
nodes: any;
|
36
|
+
data: PreparedStorageNode[];
|
37
37
|
tableSettings: Settings;
|
38
|
-
visibleEntities:
|
38
|
+
visibleEntities: VisibleEntities;
|
39
39
|
nodesUptimeFilter: keyof typeof NodesUptimeFilterValues;
|
40
40
|
onShowAll?: VoidFunction;
|
41
41
|
additionalNodesInfo?: AdditionalNodesInfo;
|
@@ -46,22 +46,22 @@ const tableColumnsNames: Record<TableColumnsIdsValues, string> = {
|
|
46
46
|
FQDN: 'FQDN',
|
47
47
|
DataCenter: 'DC',
|
48
48
|
Rack: 'Rack',
|
49
|
-
|
49
|
+
Uptime: 'Uptime',
|
50
50
|
PDisks: 'PDisks',
|
51
51
|
Missing: 'Missing',
|
52
52
|
};
|
53
53
|
|
54
54
|
const b = cn('global-storage-nodes');
|
55
55
|
|
56
|
-
function setSortOrder(visibleEntities:
|
56
|
+
function setSortOrder(visibleEntities: VisibleEntities): SortOrder | undefined {
|
57
57
|
switch (visibleEntities) {
|
58
|
-
case
|
58
|
+
case VISIBLE_ENTITIES.all: {
|
59
59
|
return {
|
60
60
|
columnId: TableColumnsIds.NodeId,
|
61
61
|
order: DataTable.ASCENDING,
|
62
62
|
};
|
63
63
|
}
|
64
|
-
case
|
64
|
+
case VISIBLE_ENTITIES.missing: {
|
65
65
|
return {
|
66
66
|
columnId: TableColumnsIds.Missing,
|
67
67
|
order: DataTable.DESCENDING,
|
@@ -73,7 +73,7 @@ function setSortOrder(visibleEntities: keyof typeof VisibleEntities): SortOrder
|
|
73
73
|
}
|
74
74
|
}
|
75
75
|
|
76
|
-
function StorageNodes({
|
76
|
+
export function StorageNodes({
|
77
77
|
data,
|
78
78
|
tableSettings,
|
79
79
|
visibleEntities,
|
@@ -83,7 +83,7 @@ function StorageNodes({
|
|
83
83
|
}: StorageNodesProps) {
|
84
84
|
const getNodeRef = additionalNodesInfo?.getNodeRef;
|
85
85
|
|
86
|
-
const allColumns: Column<
|
86
|
+
const allColumns: Column<PreparedStorageNode>[] = [
|
87
87
|
{
|
88
88
|
name: TableColumnsIds.NodeId,
|
89
89
|
header: tableColumnsNames[TableColumnsIds.NodeId],
|
@@ -112,10 +112,10 @@ function StorageNodes({
|
|
112
112
|
align: DataTable.LEFT,
|
113
113
|
},
|
114
114
|
{
|
115
|
-
name: TableColumnsIds.
|
116
|
-
header: tableColumnsNames[TableColumnsIds.
|
115
|
+
name: TableColumnsIds.Uptime,
|
116
|
+
header: tableColumnsNames[TableColumnsIds.Uptime],
|
117
117
|
width: 130,
|
118
|
-
sortAccessor: ({StartTime}) => -StartTime,
|
118
|
+
sortAccessor: ({StartTime}) => (StartTime ? -StartTime : 0),
|
119
119
|
align: DataTable.RIGHT,
|
120
120
|
},
|
121
121
|
{
|
@@ -129,11 +129,11 @@ function StorageNodes({
|
|
129
129
|
name: TableColumnsIds.PDisks,
|
130
130
|
className: b('pdisks-column'),
|
131
131
|
header: tableColumnsNames[TableColumnsIds.PDisks],
|
132
|
-
render: ({
|
132
|
+
render: ({row}) => (
|
133
133
|
<div className={b('pdisks-wrapper')}>
|
134
|
-
{
|
135
|
-
<div className={b('pdisks-item')} key={
|
136
|
-
<PDisk data={
|
134
|
+
{row.PDisks?.map((pDisk) => (
|
135
|
+
<div className={b('pdisks-item')} key={pDisk.PDiskId}>
|
136
|
+
<PDisk data={pDisk} nodeId={row.NodeId} />
|
137
137
|
</div>
|
138
138
|
))}
|
139
139
|
</div>
|
@@ -146,18 +146,18 @@ function StorageNodes({
|
|
146
146
|
|
147
147
|
let columns = allColumns;
|
148
148
|
|
149
|
-
if (visibleEntities ===
|
149
|
+
if (visibleEntities === VISIBLE_ENTITIES.space) {
|
150
150
|
columns = allColumns.filter((col) => col.name !== TableColumnsIds.Missing);
|
151
151
|
}
|
152
152
|
|
153
153
|
if (!data.length) {
|
154
154
|
let message;
|
155
155
|
|
156
|
-
if (visibleEntities ===
|
156
|
+
if (visibleEntities === VISIBLE_ENTITIES.space) {
|
157
157
|
message = i18n('empty.out_of_space');
|
158
158
|
}
|
159
159
|
|
160
|
-
if (visibleEntities ===
|
160
|
+
if (visibleEntities === VISIBLE_ENTITIES.missing) {
|
161
161
|
message = i18n('empty.degraded');
|
162
162
|
}
|
163
163
|
|
@@ -166,7 +166,7 @@ function StorageNodes({
|
|
166
166
|
}
|
167
167
|
|
168
168
|
if (
|
169
|
-
visibleEntities !==
|
169
|
+
visibleEntities !== VISIBLE_ENTITIES.all &&
|
170
170
|
nodesUptimeFilter !== NodesUptimeFilterValues.All
|
171
171
|
) {
|
172
172
|
message = i18n('empty.several_filters');
|
@@ -193,5 +193,3 @@ function StorageNodes({
|
|
193
193
|
/>
|
194
194
|
) : null;
|
195
195
|
}
|
196
|
-
|
197
|
-
export default StorageNodes;
|