ydb-embedded-ui 2.2.1 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +20 -0
- package/dist/assets/icons/shield.svg +3 -0
- package/dist/components/NodesViewer/NodesViewer.js +1 -1
- package/dist/containers/App/App.scss +5 -1
- package/dist/containers/Nodes/Nodes.js +1 -1
- package/dist/containers/Storage/DiskStateProgressBar/DiskStateProgressBar.scss +7 -5
- package/dist/containers/Storage/DiskStateProgressBar/DiskStateProgressBar.tsx +1 -11
- package/dist/containers/Storage/Pdisk/Pdisk.scss +15 -8
- package/dist/containers/Storage/Pdisk/Pdisk.tsx +22 -14
- package/dist/containers/Storage/Storage.js +29 -48
- package/dist/containers/Storage/StorageGroups/StorageGroups.scss +1 -4
- package/dist/containers/Storage/StorageGroups/StorageGroups.tsx +27 -2
- package/dist/containers/Storage/StorageGroups/i18n/en.json +2 -1
- package/dist/containers/Storage/StorageGroups/i18n/ru.json +2 -1
- package/dist/containers/Storage/StorageNodes/StorageNodes.scss +14 -12
- package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +7 -5
- package/dist/containers/Storage/Vdisk/Vdisk.js +36 -23
- package/dist/containers/Storage/Vdisk/Vdisk.scss +6 -0
- package/dist/containers/Tenant/Diagnostics/Diagnostics.scss +7 -0
- package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +25 -11
- package/dist/containers/Tenant/Diagnostics/Overview/Overview.tsx +34 -19
- package/dist/containers/Tenant/QueryEditor/SaveQuery/SaveQuery.js +1 -1
- package/dist/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx +27 -20
- package/dist/containers/Tenant/Tenant.tsx +12 -9
- package/dist/containers/Tenants/Tenants.js +1 -1
- package/dist/store/reducers/olapStats.js +13 -0
- package/dist/store/reducers/schema.js +42 -0
- package/dist/store/reducers/storage.js +26 -16
- package/dist/store/reducers/tenant.js +3 -1
- package/dist/styles/mixins.scss +1 -1
- package/dist/types/api/storage.ts +35 -10
- package/dist/types/store/storage.ts +1 -0
- package/dist/utils/hooks/useAutofetcher.ts +9 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,25 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [2.3.0](https://github.com/ydb-platform/ydb-embedded-ui/compare/v2.2.1...v2.3.0) (2022-10-24)
|
4
|
+
|
5
|
+
|
6
|
+
### Features
|
7
|
+
|
8
|
+
* **PDisk:** display type on disk progressbar ([00bcbf5](https://github.com/ydb-platform/ydb-embedded-ui/commit/00bcbf5d439ca3bb4834fd5f191c65f0ac62585f))
|
9
|
+
* **Storage:** display media type for groups ([cdff5e9](https://github.com/ydb-platform/ydb-embedded-ui/commit/cdff5e9882f3f1f8769a3aeaf3e53c05f3ce1c07))
|
10
|
+
* **Storage:** display shield icon for encrypted groups ([d0a4442](https://github.com/ydb-platform/ydb-embedded-ui/commit/d0a4442dc100c312dcc54afcf685057cc587211d))
|
11
|
+
|
12
|
+
|
13
|
+
### Bug Fixes
|
14
|
+
|
15
|
+
* **Diagnostics:** fix tabs reset on page reload ([68d2971](https://github.com/ydb-platform/ydb-embedded-ui/commit/68d297165aea1360d1081349d8133804004f8fe0))
|
16
|
+
* **Storage:** prevent loading reset on cancelled fetch ([625159a](https://github.com/ydb-platform/ydb-embedded-ui/commit/625159a396e1ab84fe9da94d047da67fdd03b30f))
|
17
|
+
* **Storage:** shrink tooltip active area on FQDN ([7c33d5a](https://github.com/ydb-platform/ydb-embedded-ui/commit/7c33d5afb561efa64f90ce5b93edd30f7d27c247))
|
18
|
+
* **Tenant:** prevent selected tab reset on tree navigation ([a4e633a](https://github.com/ydb-platform/ydb-embedded-ui/commit/a4e633aa45c803503fe69e52f0f2cfac4c6aae0d))
|
19
|
+
* **Tenant:** show loader when fetching overview data ([ae77495](https://github.com/ydb-platform/ydb-embedded-ui/commit/ae77495faa687652040a1f2965700184220778b4))
|
20
|
+
* use correct prop for textinputs value ([de97ba1](https://github.com/ydb-platform/ydb-embedded-ui/commit/de97ba17ba8da54a626509cf08f147f9fcc67004))
|
21
|
+
* **useAutofetcher:** pass argument to indicate background fetch ([4063cb1](https://github.com/ydb-platform/ydb-embedded-ui/commit/4063cb1411338d351b612fc46c06bcc708fe32f1))
|
22
|
+
|
3
23
|
## [2.2.1](https://github.com/ydb-platform/ydb-embedded-ui/compare/v2.2.0...v2.2.1) (2022-10-19)
|
4
24
|
|
5
25
|
|
@@ -0,0 +1,3 @@
|
|
1
|
+
<svg viewBox="0 0 18 18" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
2
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.69222 1.56606C8.88795 1.47798 9.11205 1.47798 9.30778 1.56606L15.3078 4.26613C15.5769 4.38725 15.75 4.65494 15.75 4.95007V7.24592C15.75 11.1569 13.413 14.6895 9.81353 16.2192L9.29335 16.4403C9.1059 16.5199 8.8941 16.5199 8.70665 16.4403L8.18647 16.2192C4.58703 14.6895 2.25 11.1569 2.25 7.24592V4.95007C2.25 4.65494 2.42309 4.38725 2.69222 4.26613L8.69222 1.56606ZM3.75 5.43501V7.24592C3.75 10.5552 5.72748 13.5443 8.77317 14.8387L9 14.9351L9.22683 14.8387C12.2725 13.5443 14.25 10.5552 14.25 7.24592V5.43501L9 3.07244L3.75 5.43501ZM9.75 8.79933C10.1984 8.53997 10.5 8.05521 10.5 7.5C10.5 6.67157 9.82843 6 9 6C8.17157 6 7.5 6.67157 7.5 7.5C7.5 8.05521 7.80165 8.53997 8.25 8.79933V11.25C8.25 11.6642 8.58579 12 9 12C9.41421 12 9.75 11.6642 9.75 11.25V8.79933Z"/>
|
3
|
+
</svg>
|
@@ -31,6 +31,10 @@ body,
|
|
31
31
|
--data-table-row-height: 40px;
|
32
32
|
}
|
33
33
|
|
34
|
+
.yc-root {
|
35
|
+
--ydb-data-table-color-hover: var(--yc-color-base-float-hover);
|
36
|
+
}
|
37
|
+
|
34
38
|
.yc-select__label {
|
35
39
|
font-weight: 600;
|
36
40
|
}
|
@@ -130,7 +134,7 @@ body,
|
|
130
134
|
}
|
131
135
|
|
132
136
|
.yc-root .data-table_highlight-rows .data-table__row:hover {
|
133
|
-
background: var(--
|
137
|
+
background: var(--ydb-data-table-color-hover);
|
134
138
|
}
|
135
139
|
|
136
140
|
.yc-table-column-setup__item {
|
@@ -1,18 +1,20 @@
|
|
1
1
|
.storage-disk-progress-bar {
|
2
|
+
$block: &;
|
3
|
+
|
2
4
|
$border-width: 2px;
|
3
5
|
$outer-border-radius: 4px;
|
4
6
|
$inner-border-radius: $outer-border-radius - $border-width;
|
5
7
|
|
6
|
-
$block: &;
|
7
8
|
position: relative;
|
8
9
|
|
9
|
-
display:
|
10
|
+
display: block;
|
10
11
|
|
11
|
-
width:
|
12
|
+
min-width: 50px;
|
12
13
|
height: var(--yc-text-body-2-line-height);
|
13
14
|
|
14
|
-
|
15
|
+
text-align: center;
|
15
16
|
|
17
|
+
color: var(--yc-color-text-primary);
|
16
18
|
border: $border-width solid var(--yc-color-infographics-misc-heavy);
|
17
19
|
border-radius: $outer-border-radius;
|
18
20
|
background-color: var(--yc-color-infographics-misc-light);
|
@@ -82,7 +84,7 @@
|
|
82
84
|
}
|
83
85
|
}
|
84
86
|
&__filled-title {
|
85
|
-
position:
|
87
|
+
position: relative;
|
86
88
|
z-index: 2;
|
87
89
|
|
88
90
|
font-size: var(--yc-text-body-1-font-size);
|
@@ -5,8 +5,6 @@ import cn from 'bem-cn-lite';
|
|
5
5
|
import {INVERTED_DISKS_KEY} from '../../../utils/constants';
|
6
6
|
import {getSettingValue} from '../../../store/reducers/settings';
|
7
7
|
|
8
|
-
import InternalLink from '../../../components/InternalLink/InternalLink';
|
9
|
-
|
10
8
|
import './DiskStateProgressBar.scss';
|
11
9
|
|
12
10
|
const b = cn('storage-disk-progress-bar');
|
@@ -23,13 +21,11 @@ export const diskProgressColors = {
|
|
23
21
|
interface DiskStateProgressBarProps {
|
24
22
|
diskAllocatedPercent?: number;
|
25
23
|
severity?: keyof typeof diskProgressColors;
|
26
|
-
href?: string;
|
27
24
|
}
|
28
25
|
|
29
26
|
function DiskStateProgressBar({
|
30
27
|
diskAllocatedPercent = -1,
|
31
28
|
severity,
|
32
|
-
href,
|
33
29
|
}: DiskStateProgressBarProps) {
|
34
30
|
const inverted = useSelector((state) => getSettingValue(state, INVERTED_DISKS_KEY));
|
35
31
|
|
@@ -63,13 +59,7 @@ function DiskStateProgressBar({
|
|
63
59
|
aria-valuemax={100}
|
64
60
|
aria-valuenow={diskAllocatedPercent}
|
65
61
|
>
|
66
|
-
{
|
67
|
-
<InternalLink to={href} className={b('link')}>
|
68
|
-
{renderAllocatedPercent()}
|
69
|
-
</InternalLink>
|
70
|
-
) : (
|
71
|
-
renderAllocatedPercent()
|
72
|
-
)}
|
62
|
+
{renderAllocatedPercent()}
|
73
63
|
</div>
|
74
64
|
);
|
75
65
|
}
|
@@ -1,18 +1,25 @@
|
|
1
1
|
.pdisk-storage {
|
2
|
-
|
3
|
-
flex-grow: 1;
|
4
|
-
align-items: center;
|
2
|
+
position: relative;
|
5
3
|
|
6
|
-
|
7
|
-
margin-right: 10px;
|
4
|
+
min-width: 120px;
|
8
5
|
|
9
|
-
|
6
|
+
border-radius: 4px; // to match interactive area with disk shape
|
10
7
|
|
11
|
-
|
12
|
-
|
8
|
+
&__content {
|
9
|
+
border-radius: 4px; // to match interactive area with disk shape
|
13
10
|
}
|
14
11
|
|
15
12
|
&__popup-wrapper {
|
16
13
|
padding: 12px;
|
17
14
|
}
|
15
|
+
|
16
|
+
&__media-type {
|
17
|
+
position: absolute;
|
18
|
+
top: 0;
|
19
|
+
right: 4px;
|
20
|
+
|
21
|
+
font-size: var(--yc-text-body-1-font-size);
|
22
|
+
|
23
|
+
color: var(--yc-color-text-secondary);
|
24
|
+
}
|
18
25
|
}
|
@@ -1,21 +1,23 @@
|
|
1
1
|
import React, {useEffect, useState, useRef, useMemo} from 'react';
|
2
2
|
import cn from 'bem-cn-lite';
|
3
|
+
|
3
4
|
import {Popup} from '@gravity-ui/uikit';
|
4
5
|
|
5
|
-
import
|
6
|
-
|
7
|
-
|
8
|
-
//@ts-ignore
|
6
|
+
import {InfoViewer} from '../../../components/InfoViewer';
|
7
|
+
import InternalLink from '../../../components/InternalLink/InternalLink';
|
8
|
+
|
9
9
|
import routes, {createHref} from '../../../routes';
|
10
|
-
|
10
|
+
import type {RequiredField} from '../../../types';
|
11
|
+
import {TPDiskStateInfo, TPDiskState} from '../../../types/api/storage';
|
11
12
|
import {getPDiskId} from '../../../utils';
|
12
13
|
import {getPDiskType} from '../../../utils/pdisk';
|
13
|
-
import {
|
14
|
-
|
14
|
+
import {bytesToGB} from '../../../utils/utils';
|
15
|
+
|
16
|
+
import {STRUCTURE} from '../../Node/NodePages';
|
17
|
+
|
15
18
|
import DiskStateProgressBar, {
|
16
19
|
diskProgressColors,
|
17
20
|
} from '../DiskStateProgressBar/DiskStateProgressBar';
|
18
|
-
import {STRUCTURE} from '../../Node/NodePages';
|
19
21
|
|
20
22
|
import {colorSeverity, NOT_AVAILABLE_SEVERITY} from '../utils';
|
21
23
|
|
@@ -123,8 +125,9 @@ function Pdisk(props: PDiskProps) {
|
|
123
125
|
const {AvailableSize, TotalSize} = props;
|
124
126
|
|
125
127
|
if (!AvailableSize || !TotalSize) {
|
126
|
-
return;
|
128
|
+
return undefined;
|
127
129
|
}
|
130
|
+
|
128
131
|
return !isNaN(Number(AvailableSize)) && !isNaN(Number(TotalSize))
|
129
132
|
? Math.round(((Number(TotalSize) - Number(AvailableSize)) * 100) / Number(TotalSize))
|
130
133
|
: undefined;
|
@@ -134,15 +137,20 @@ function Pdisk(props: PDiskProps) {
|
|
134
137
|
<React.Fragment>
|
135
138
|
{renderPopup()}
|
136
139
|
<div className={b()} ref={anchor} onMouseEnter={showPopup} onMouseLeave={hidePopup}>
|
137
|
-
<
|
138
|
-
|
139
|
-
severity={severity as keyof typeof diskProgressColors}
|
140
|
-
href={createHref(
|
140
|
+
<InternalLink
|
141
|
+
to={createHref(
|
141
142
|
routes.node,
|
142
143
|
{id: props.NodeId, activeTab: STRUCTURE},
|
143
144
|
{pdiskId: props.PDiskId || ''},
|
144
145
|
)}
|
145
|
-
|
146
|
+
className={b('content')}
|
147
|
+
>
|
148
|
+
<DiskStateProgressBar
|
149
|
+
diskAllocatedPercent={pdiskAllocatedPercent}
|
150
|
+
severity={severity as keyof typeof diskProgressColors}
|
151
|
+
/>
|
152
|
+
<div className={b('media-type')}>{getPDiskType(props)}</div>
|
153
|
+
</InternalLink>
|
146
154
|
</div>
|
147
155
|
</React.Fragment>
|
148
156
|
);
|
@@ -68,14 +68,8 @@ class Storage extends React.Component {
|
|
68
68
|
};
|
69
69
|
|
70
70
|
componentDidMount() {
|
71
|
-
const {
|
72
|
-
|
73
|
-
nodeId,
|
74
|
-
setVisibleEntities,
|
75
|
-
storageType,
|
76
|
-
setHeader,
|
77
|
-
getNodesList,
|
78
|
-
} = this.props;
|
71
|
+
const {tenant, nodeId, setVisibleEntities, storageType, setHeader, getNodesList} =
|
72
|
+
this.props;
|
79
73
|
|
80
74
|
this.autofetcher = new AutoFetcher();
|
81
75
|
getNodesList();
|
@@ -106,12 +100,7 @@ class Storage extends React.Component {
|
|
106
100
|
}
|
107
101
|
|
108
102
|
componentDidUpdate(prevProps) {
|
109
|
-
const {
|
110
|
-
visibleEntities,
|
111
|
-
storageType,
|
112
|
-
autorefresh,
|
113
|
-
database,
|
114
|
-
} = this.props;
|
103
|
+
const {visibleEntities, storageType, autorefresh, database} = this.props;
|
115
104
|
|
116
105
|
const startFetch = () => {
|
117
106
|
this.getStorageInfo({
|
@@ -139,7 +128,10 @@ class Storage extends React.Component {
|
|
139
128
|
restartAutorefresh();
|
140
129
|
}
|
141
130
|
|
142
|
-
if (
|
131
|
+
if (
|
132
|
+
storageType !== prevProps.storageType ||
|
133
|
+
visibleEntities !== prevProps.visibleEntities
|
134
|
+
) {
|
143
135
|
startFetch();
|
144
136
|
|
145
137
|
if (!database || (database && autorefresh)) {
|
@@ -154,25 +146,22 @@ class Storage extends React.Component {
|
|
154
146
|
}
|
155
147
|
|
156
148
|
getStorageInfo(data) {
|
157
|
-
const {
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
});
|
149
|
+
const {tenant, nodeId, getStorageInfo} = this.props;
|
150
|
+
|
151
|
+
getStorageInfo(
|
152
|
+
{
|
153
|
+
tenant,
|
154
|
+
nodeId,
|
155
|
+
...data,
|
156
|
+
},
|
157
|
+
{
|
158
|
+
concurrentId: 'getStorageInfo',
|
159
|
+
},
|
160
|
+
);
|
170
161
|
}
|
171
162
|
|
172
163
|
renderLoader() {
|
173
|
-
return (
|
174
|
-
<TableSkeleton className={b('loader')}/>
|
175
|
-
);
|
164
|
+
return <TableSkeleton className={b('loader')} />;
|
176
165
|
}
|
177
166
|
|
178
167
|
renderDataTable() {
|
@@ -212,14 +201,8 @@ class Storage extends React.Component {
|
|
212
201
|
};
|
213
202
|
|
214
203
|
renderEntitiesCount() {
|
215
|
-
const {
|
216
|
-
|
217
|
-
groupsCount,
|
218
|
-
nodesCount,
|
219
|
-
flatListStorageEntities,
|
220
|
-
loading,
|
221
|
-
wasLoaded,
|
222
|
-
} = this.props;
|
204
|
+
const {storageType, groupsCount, nodesCount, flatListStorageEntities, loading, wasLoaded} =
|
205
|
+
this.props;
|
223
206
|
|
224
207
|
let label = `${storageType === StorageTypes.groups ? 'Groups' : 'Nodes'}: `;
|
225
208
|
const count = storageType === StorageTypes.groups ? groupsCount : nodesCount;
|
@@ -254,7 +237,11 @@ class Storage extends React.Component {
|
|
254
237
|
<div className={b('controls')}>
|
255
238
|
<div className={b('search')}>
|
256
239
|
<StorageFilter
|
257
|
-
placeholder={
|
240
|
+
placeholder={
|
241
|
+
storageType === StorageTypes.groups
|
242
|
+
? 'Group ID, Pool name'
|
243
|
+
: 'Node ID, FQDN'
|
244
|
+
}
|
258
245
|
onChange={setStorageFilter}
|
259
246
|
value={filter}
|
260
247
|
/>
|
@@ -303,14 +290,8 @@ class Storage extends React.Component {
|
|
303
290
|
return (
|
304
291
|
<div className={b()}>
|
305
292
|
{this.renderControls()}
|
306
|
-
{error &&
|
307
|
-
|
308
|
-
)}
|
309
|
-
{showLoader ? (
|
310
|
-
this.renderLoader()
|
311
|
-
) : (
|
312
|
-
this.renderDataTable()
|
313
|
-
)}
|
293
|
+
{error && <div>{error.statusText}</div>}
|
294
|
+
{showLoader ? this.renderLoader() : this.renderDataTable()}
|
314
295
|
</div>
|
315
296
|
);
|
316
297
|
}
|
@@ -23,7 +23,7 @@
|
|
23
23
|
background: var(--yc-color-base-background);
|
24
24
|
|
25
25
|
.data-table__row:hover & {
|
26
|
-
background: var(--
|
26
|
+
background: var(--ydb-data-table-color-hover);
|
27
27
|
}
|
28
28
|
}
|
29
29
|
}
|
@@ -51,7 +51,4 @@
|
|
51
51
|
&__group-id {
|
52
52
|
font-weight: 500;
|
53
53
|
}
|
54
|
-
&__tooltip {
|
55
|
-
word-break: break-all;
|
56
|
-
}
|
57
54
|
}
|
@@ -1,7 +1,9 @@
|
|
1
1
|
import _ from 'lodash';
|
2
2
|
import cn from 'bem-cn-lite';
|
3
3
|
import DataTable, {Column, Settings, SortOrder} from '@yandex-cloud/react-data-table';
|
4
|
-
import {Label, Popover, PopoverBehavior} from '@gravity-ui/uikit';
|
4
|
+
import {Icon, Label, Popover, PopoverBehavior} from '@gravity-ui/uikit';
|
5
|
+
|
6
|
+
import shieldIcon from '../../../assets/icons/shield.svg';
|
5
7
|
|
6
8
|
import {Stack} from '../../../components/Stack/Stack';
|
7
9
|
//@ts-ignore
|
@@ -25,6 +27,7 @@ import './StorageGroups.scss';
|
|
25
27
|
|
26
28
|
enum TableColumnsIds {
|
27
29
|
PoolName = 'PoolName',
|
30
|
+
Type = 'Type',
|
28
31
|
GroupID = 'GroupID',
|
29
32
|
Used = 'Used',
|
30
33
|
Limit = 'Limit',
|
@@ -49,6 +52,7 @@ interface StorageGroupsProps {
|
|
49
52
|
|
50
53
|
const tableColumnsNames: Record<TableColumnsIdsValues, string> = {
|
51
54
|
PoolName: 'Pool Name',
|
55
|
+
Type: 'Type',
|
52
56
|
GroupID: 'Group ID',
|
53
57
|
Used: 'Used',
|
54
58
|
Limit: 'Limit',
|
@@ -100,7 +104,7 @@ function StorageGroups({data, tableSettings, visibleEntities, nodes, onShowAll}:
|
|
100
104
|
<div className={b('pool-name-wrapper')}>
|
101
105
|
{splitted && (
|
102
106
|
<Popover
|
103
|
-
content={
|
107
|
+
content={value as string}
|
104
108
|
placement={['right']}
|
105
109
|
behavior={PopoverBehavior.Immediate}
|
106
110
|
>
|
@@ -114,6 +118,27 @@ function StorageGroups({data, tableSettings, visibleEntities, nodes, onShowAll}:
|
|
114
118
|
},
|
115
119
|
align: DataTable.LEFT,
|
116
120
|
},
|
121
|
+
{
|
122
|
+
name: TableColumnsIds.Type,
|
123
|
+
header: tableColumnsNames[TableColumnsIds.Type],
|
124
|
+
render: ({value, row}) => (
|
125
|
+
<>
|
126
|
+
<Label>{value as string || '—'}</Label>
|
127
|
+
{' '}
|
128
|
+
{row.Encryption && (
|
129
|
+
<Popover
|
130
|
+
content={i18n('encrypted')}
|
131
|
+
placement="right"
|
132
|
+
behavior={PopoverBehavior.Immediate}
|
133
|
+
>
|
134
|
+
<Label>
|
135
|
+
<Icon data={shieldIcon} />
|
136
|
+
</Label>
|
137
|
+
</Popover>
|
138
|
+
)}
|
139
|
+
</>
|
140
|
+
),
|
141
|
+
},
|
117
142
|
{
|
118
143
|
name: TableColumnsIds.Missing,
|
119
144
|
header: tableColumnsNames[TableColumnsIds.Missing],
|
@@ -7,27 +7,29 @@
|
|
7
7
|
|
8
8
|
min-width: 500px;
|
9
9
|
}
|
10
|
-
&
|
11
|
-
|
12
|
-
|
10
|
+
&__pdisks-item {
|
11
|
+
flex-grow: 1;
|
12
|
+
|
13
|
+
max-width: 200px;
|
14
|
+
margin-right: 10px;
|
15
|
+
|
16
|
+
&:last-child {
|
17
|
+
margin-right: 0px;
|
18
|
+
}
|
19
|
+
}
|
20
|
+
&__fqdn-wrapper {
|
21
|
+
width: 330px;
|
13
22
|
}
|
14
|
-
&
|
23
|
+
&__fqdn {
|
15
24
|
display: inline-block;
|
16
25
|
overflow: hidden;
|
17
26
|
|
18
|
-
width: 330px;
|
19
27
|
max-width: 330px;
|
20
28
|
|
29
|
+
vertical-align: top;
|
21
30
|
text-overflow: ellipsis;
|
22
31
|
}
|
23
32
|
&__group-id {
|
24
33
|
font-weight: 500;
|
25
34
|
}
|
26
|
-
&__tooltip-wrapper {
|
27
|
-
display: flex;
|
28
|
-
align-items: center;
|
29
|
-
}
|
30
|
-
&__tooltip {
|
31
|
-
word-break: break-all;
|
32
|
-
}
|
33
35
|
}
|
@@ -1,9 +1,9 @@
|
|
1
1
|
import _ from 'lodash';
|
2
2
|
import cn from 'bem-cn-lite';
|
3
|
+
|
3
4
|
import DataTable, {Column, Settings, SortOrder} from '@yandex-cloud/react-data-table';
|
4
5
|
import {Popover, PopoverBehavior} from '@gravity-ui/uikit';
|
5
6
|
|
6
|
-
//@ts-ignore
|
7
7
|
import {VisibleEntities} from '../../../store/reducers/storage';
|
8
8
|
|
9
9
|
import {EmptyFilter} from '../EmptyFilter/EmptyFilter';
|
@@ -75,13 +75,13 @@ function StorageNodes({data, tableSettings, visibleEntities, onShowAll}: Storage
|
|
75
75
|
width: 350,
|
76
76
|
render: ({value}) => {
|
77
77
|
return (
|
78
|
-
<div className={b('
|
78
|
+
<div className={b('fqdn-wrapper')}>
|
79
79
|
<Popover
|
80
|
-
content={
|
80
|
+
content={value as string}
|
81
81
|
placement={['right']}
|
82
82
|
behavior={PopoverBehavior.Immediate}
|
83
83
|
>
|
84
|
-
<span className={b('
|
84
|
+
<span className={b('fqdn')}>{value as string}</span>
|
85
85
|
</Popover>
|
86
86
|
</div>
|
87
87
|
);
|
@@ -108,7 +108,9 @@ function StorageNodes({data, tableSettings, visibleEntities, onShowAll}: Storage
|
|
108
108
|
render: ({value, row}) => (
|
109
109
|
<div className={b('pdisks-wrapper')}>
|
110
110
|
{_.map(value as any, (el) => (
|
111
|
-
<
|
111
|
+
<div className={b('pdisks-item')}>
|
112
|
+
<Pdisk key={el.PDiskId} {...el} NodeId={row.NodeId} />
|
113
|
+
</div>
|
112
114
|
))}
|
113
115
|
</div>
|
114
116
|
),
|
@@ -1,17 +1,22 @@
|
|
1
1
|
import React, {useEffect, useState, useRef, useMemo} from 'react';
|
2
2
|
import PropTypes from 'prop-types';
|
3
3
|
import cn from 'bem-cn-lite';
|
4
|
+
|
4
5
|
import {Label, Popup} from '@gravity-ui/uikit';
|
5
6
|
|
6
|
-
import
|
7
|
+
import InternalLink from '../../../components/InternalLink/InternalLink';
|
8
|
+
import {InfoViewer} from '../../../components/InfoViewer';
|
9
|
+
|
7
10
|
import routes, {createHref} from '../../../routes';
|
8
11
|
import {stringifyVdiskId, getPDiskId} from '../../../utils';
|
9
12
|
import {getPDiskType} from '../../../utils/pdisk';
|
10
|
-
import {
|
13
|
+
import {bytesToGB, bytesToSpeed} from '../../../utils/utils';
|
14
|
+
|
15
|
+
import {STRUCTURE} from '../../Node/NodePages';
|
16
|
+
|
11
17
|
import DiskStateProgressBar, {
|
12
18
|
diskProgressColors,
|
13
19
|
} from '../DiskStateProgressBar/DiskStateProgressBar';
|
14
|
-
import {STRUCTURE} from '../../Node/NodePages';
|
15
20
|
|
16
21
|
import {colorSeverity, NOT_AVAILABLE_SEVERITY} from '../utils';
|
17
22
|
|
@@ -225,33 +230,41 @@ function Vdisk(props) {
|
|
225
230
|
const available = AvailableSize ? AvailableSize : PDisk?.AvailableSize;
|
226
231
|
|
227
232
|
if (!available) {
|
228
|
-
return;
|
233
|
+
return undefined;
|
229
234
|
}
|
230
|
-
|
231
|
-
|
232
|
-
|
235
|
+
|
236
|
+
return isNaN(Number(AllocatedSize))
|
237
|
+
? undefined
|
238
|
+
: (Number(AllocatedSize) * 100) / (Number(available) + Number(AllocatedSize));
|
233
239
|
}, [props.AllocatedSize, props.AvailableSize, props.PDisk?.AvailableSize]);
|
234
240
|
|
235
241
|
return (
|
236
242
|
<React.Fragment>
|
237
243
|
{renderPopup()}
|
238
244
|
<div className={b()} ref={anchor} onMouseEnter={showPopup} onMouseLeave={hidePopup}>
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
245
|
+
{props.NodeId ? (
|
246
|
+
<InternalLink
|
247
|
+
to={createHref(
|
248
|
+
routes.node,
|
249
|
+
{id: props.NodeId, activeTab: STRUCTURE},
|
250
|
+
{
|
251
|
+
pdiskId: props.PDisk?.PDiskId,
|
252
|
+
vdiskId: stringifyVdiskId(props.VDiskId),
|
253
|
+
},
|
254
|
+
)}
|
255
|
+
className={b('content')}
|
256
|
+
>
|
257
|
+
<DiskStateProgressBar
|
258
|
+
diskAllocatedPercent={vdiskAllocatedPercent}
|
259
|
+
severity={severity}
|
260
|
+
/>
|
261
|
+
</InternalLink>
|
262
|
+
) : (
|
263
|
+
<DiskStateProgressBar
|
264
|
+
diskAllocatedPercent={vdiskAllocatedPercent}
|
265
|
+
severity={severity}
|
266
|
+
/>
|
267
|
+
)}
|
255
268
|
</div>
|
256
269
|
</React.Fragment>
|
257
270
|
);
|