ydb-embedded-ui 3.4.0 → 3.4.2
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +18 -0
- package/dist/components/BasicNodeViewer/BasicNodeViewer.tsx +2 -3
- package/dist/components/ClusterInfo/ClusterInfo.tsx +14 -36
- package/dist/components/CopyToClipboard/CopyToClipboard.tsx +1 -2
- package/dist/components/CriticalActionDialog/CriticalActionDialog.js +1 -1
- package/dist/components/EmptyState/{EmptyState.js → EmptyState.tsx} +12 -15
- package/dist/components/EmptyState/index.ts +1 -0
- package/dist/components/EnableFullscreenButton/EnableFullscreenButton.tsx +7 -2
- package/dist/components/Errors/403/AccessDenied.tsx +1 -1
- package/dist/components/Fullscreen/Fullscreen.tsx +1 -1
- package/dist/components/Icon/Icon.tsx +33 -0
- package/dist/components/Icon/index.ts +1 -0
- package/dist/components/Pagination/Pagination.js +1 -1
- package/dist/components/QueryExecutionStatus/QueryExecutionStatus.tsx +1 -1
- package/dist/components/Tablet/Tablet.tsx +59 -0
- package/dist/components/Tablet/index.ts +1 -0
- package/dist/components/Tag/Tag.tsx +16 -0
- package/dist/components/Tag/index.ts +1 -0
- package/dist/components/Tags/Tags.tsx +22 -0
- package/dist/components/Tags/index.ts +1 -0
- package/dist/containers/Header/Header.tsx +2 -3
- package/dist/containers/Header/Host/Host.js +1 -1
- package/dist/containers/Node/NodeStructure/Pdisk.tsx +1 -1
- package/dist/containers/Nodes/getNodesColumns.tsx +1 -1
- package/dist/containers/Storage/EmptyFilter/EmptyFilter.tsx +8 -9
- package/dist/containers/Storage/PDisk/PDisk.scss +15 -0
- package/dist/containers/Storage/PDisk/PDisk.tsx +38 -13
- package/dist/containers/Storage/StorageNodes/StorageNodes.scss +4 -2
- package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +1 -0
- package/dist/containers/Tablet/Tablet.js +6 -6
- package/dist/containers/Tablets/Tablets.scss +0 -4
- package/dist/containers/Tablets/Tablets.tsx +1 -2
- package/dist/containers/TabletsFilters/TabletsFilters.js +1 -1
- package/dist/containers/Tenant/Diagnostics/Consumers/TopicStats/ConsumersTopicStats.scss +1 -1
- package/dist/containers/Tenant/Diagnostics/Consumers/columns/columns.tsx +27 -1
- package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.tsx +1 -2
- package/dist/containers/Tenant/Diagnostics/HotKeys/HotKeys.js +1 -1
- package/dist/containers/Tenant/Diagnostics/Network/Network.js +1 -1
- package/dist/containers/Tenant/Diagnostics/Partitions/Partitions.tsx +17 -13
- package/dist/containers/Tenant/Diagnostics/Partitions/PartitionsWrapper.tsx +2 -0
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +1 -1
- package/dist/containers/Tenant/ObjectSummary/ObjectSummary.tsx +1 -1
- package/dist/containers/Tenant/Preview/Preview.js +1 -1
- package/dist/containers/Tenant/QueryEditor/QueryEditor.js +1 -1
- package/dist/containers/Tenant/QueryEditor/SavedQueries/SavedQueries.js +1 -1
- package/dist/containers/Tenant/Schema/SchemaViewer/SchemaViewer.js +1 -1
- package/dist/containers/Tenant/TenantPages.tsx +1 -2
- package/dist/containers/Tenant/utils/paneVisibilityToggleHelpers.tsx +2 -2
- package/dist/services/api.d.ts +11 -0
- package/dist/services/api.js +3 -3
- package/dist/store/reducers/consumer.ts +14 -0
- package/dist/store/reducers/{host.js → host.ts} +9 -5
- package/dist/store/reducers/shardsWorkload.ts +4 -0
- package/dist/store/reducers/tablet.ts +111 -0
- package/dist/store/reducers/topic.ts +13 -0
- package/dist/store/state-url-mapping.js +3 -0
- package/dist/types/api/cluster.ts +34 -0
- package/dist/types/api/systemState.ts +13 -0
- package/dist/types/api/tablet.ts +12 -4
- package/dist/types/store/consumer.ts +10 -2
- package/dist/types/store/host.ts +23 -0
- package/dist/types/store/tablet.ts +50 -0
- package/dist/types/store/tooltip.ts +3 -1
- package/dist/types/store/topic.ts +3 -2
- package/package.json +7 -5
- package/dist/components/Icon/Icon.js +0 -28
- package/dist/components/Tablet/Tablet.js +0 -61
- package/dist/components/Tag/Tag.js +0 -14
- package/dist/components/Tags/Tags.js +0 -36
- package/dist/store/reducers/tablet.js +0 -94
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,23 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [3.4.2](https://github.com/ydb-platform/ydb-embedded-ui/compare/v3.4.1...v3.4.2) (2023-03-03)
|
4
|
+
|
5
|
+
|
6
|
+
### Bug Fixes
|
7
|
+
|
8
|
+
* **Partitions:** add search to consumers filter ([95e4462](https://github.com/ydb-platform/ydb-embedded-ui/commit/95e446295cb2b2729daf0d0ef719e37c7c8e0d3c))
|
9
|
+
* **Partitions:** fix error on wrong consumer in query string ([44269fa](https://github.com/ydb-platform/ydb-embedded-ui/commit/44269fa9240fe31c9ef69e061c20d58b2b55fae3))
|
10
|
+
* **PDisk:** display vdisks donors ([8b39b01](https://github.com/ydb-platform/ydb-embedded-ui/commit/8b39b01e8bf62624e9e12ac0a329fda5d03cc8df))
|
11
|
+
|
12
|
+
## [3.4.1](https://github.com/ydb-platform/ydb-embedded-ui/compare/v3.4.0...v3.4.1) (2023-03-01)
|
13
|
+
|
14
|
+
|
15
|
+
### Bug Fixes
|
16
|
+
|
17
|
+
* **Consumers:** enable navigation to Partitions tab ([fa79081](https://github.com/ydb-platform/ydb-embedded-ui/commit/fa7908124bc4392e272aa829fd4e5c1639fcf209))
|
18
|
+
* **Consumers:** update topic stats values align ([f2af851](https://github.com/ydb-platform/ydb-embedded-ui/commit/f2af851208a640ef9aa392fd7176eb579a2401db))
|
19
|
+
* **TopShards:** keep state on request cancel ([1bd4f65](https://github.com/ydb-platform/ydb-embedded-ui/commit/1bd4f65dd047b42f8edf9e4bb41c722f30220d77))
|
20
|
+
|
3
21
|
## [3.4.0](https://github.com/ydb-platform/ydb-embedded-ui/compare/v3.3.4...v3.4.0) (2023-02-17)
|
4
22
|
|
5
23
|
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import cn from 'bem-cn-lite';
|
2
2
|
|
3
3
|
import EntityStatus from '../EntityStatus/EntityStatus';
|
4
|
-
import Tags from '../Tags
|
5
|
-
import Icon from '../Icon
|
4
|
+
import {Tags} from '../Tags';
|
5
|
+
import {Icon} from '../Icon';
|
6
6
|
|
7
7
|
import './BasicNodeViewer.scss';
|
8
8
|
|
@@ -47,7 +47,6 @@ export const BasicNodeViewer = ({node, additionalNodesInfo, className}: BasicNod
|
|
47
47
|
) : (
|
48
48
|
<div className="error">no data</div>
|
49
49
|
)}
|
50
|
-
|
51
50
|
</div>
|
52
51
|
);
|
53
52
|
};
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import React, {ReactNode} from 'react';
|
2
2
|
import cn from 'bem-cn-lite';
|
3
3
|
import {connect} from 'react-redux';
|
4
|
+
import {Link, Loader} from '@gravity-ui/uikit';
|
4
5
|
|
5
6
|
//@ts-ignore
|
6
7
|
import EntityStatus from '../EntityStatus/EntityStatus';
|
@@ -8,10 +9,8 @@ import EntityStatus from '../EntityStatus/EntityStatus';
|
|
8
9
|
import ProgressViewer from '../ProgressViewer/ProgressViewer';
|
9
10
|
//@ts-ignore
|
10
11
|
import InfoViewer from '../InfoViewer/InfoViewer';
|
11
|
-
|
12
|
-
import
|
13
|
-
//@ts-ignore
|
14
|
-
import Tablet from '../Tablet/Tablet';
|
12
|
+
import {Tags} from '../Tags';
|
13
|
+
import {Tablet} from '../Tablet';
|
15
14
|
|
16
15
|
//@ts-ignore
|
17
16
|
import {hideTooltip, showTooltip} from '../../store/reducers/tooltip';
|
@@ -24,15 +23,16 @@ import {clusterName, backend, customBackend} from '../../store';
|
|
24
23
|
import {formatStorageValues} from '../../utils';
|
25
24
|
//@ts-ignore
|
26
25
|
import {TxAllocator} from '../../utils/constants';
|
27
|
-
|
28
|
-
import './ClusterInfo.scss';
|
29
26
|
import {AutoFetcher} from '../../utils/autofetcher';
|
30
|
-
import {
|
31
|
-
//@ts-ignore
|
32
|
-
import Icon from '../Icon/Icon';
|
27
|
+
import {Icon} from '../Icon';
|
33
28
|
import {setHeader} from '../../store/reducers/header';
|
34
29
|
import routes, {CLUSTER_PAGES, createHref} from '../../routes';
|
35
30
|
|
31
|
+
import type {TClusterInfo} from '../../types/api/cluster';
|
32
|
+
import type {TTabletStateInfo} from '../../types/api/tablet';
|
33
|
+
|
34
|
+
import './ClusterInfo.scss';
|
35
|
+
|
36
36
|
const b = cn('cluster-info');
|
37
37
|
|
38
38
|
export interface IClusterInfoItem {
|
@@ -40,25 +40,11 @@ export interface IClusterInfoItem {
|
|
40
40
|
value: ReactNode;
|
41
41
|
}
|
42
42
|
|
43
|
-
interface ICluster {
|
44
|
-
StorageTotal: string;
|
45
|
-
StorageUsed: string;
|
46
|
-
NodesAlive: number;
|
47
|
-
NodesTotal: number;
|
48
|
-
LoadAverage: number;
|
49
|
-
NumberOfCpus: number;
|
50
|
-
Versions: string[];
|
51
|
-
Name?: string;
|
52
|
-
Overall: string;
|
53
|
-
DataCenters?: string[];
|
54
|
-
SystemTablets?: ITablet[];
|
55
|
-
}
|
56
|
-
|
57
43
|
interface ClusterInfoProps {
|
58
44
|
className?: string;
|
59
|
-
cluster?:
|
45
|
+
cluster?: TClusterInfo;
|
60
46
|
hideTooltip: VoidFunction;
|
61
|
-
showTooltip:
|
47
|
+
showTooltip: (...args: Parameters<typeof showTooltip>) => void;
|
62
48
|
setHeader: any;
|
63
49
|
getClusterInfo: (clusterName: string) => void;
|
64
50
|
clusterTitle?: string;
|
@@ -69,12 +55,8 @@ interface ClusterInfoProps {
|
|
69
55
|
error?: {statusText: string};
|
70
56
|
}
|
71
57
|
|
72
|
-
interface ITablet {
|
73
|
-
Type: string;
|
74
|
-
}
|
75
|
-
|
76
58
|
class ClusterInfo extends React.Component<ClusterInfoProps> {
|
77
|
-
static compareTablets(tablet1:
|
59
|
+
static compareTablets(tablet1: TTabletStateInfo, tablet2: TTabletStateInfo) {
|
78
60
|
if (tablet1.Type === TxAllocator) {
|
79
61
|
return 1;
|
80
62
|
}
|
@@ -128,11 +110,7 @@ class ClusterInfo extends React.Component<ClusterInfoProps> {
|
|
128
110
|
private autofetcher: any;
|
129
111
|
|
130
112
|
private getInfo() {
|
131
|
-
const {
|
132
|
-
cluster = {} as ICluster,
|
133
|
-
additionalClusterInfo = [],
|
134
|
-
singleClusterMode,
|
135
|
-
} = this.props;
|
113
|
+
const {cluster = {}, additionalClusterInfo = [], singleClusterMode} = this.props;
|
136
114
|
const {StorageTotal, StorageUsed} = cluster;
|
137
115
|
|
138
116
|
let link = backend + '/internal';
|
@@ -193,7 +171,7 @@ class ClusterInfo extends React.Component<ClusterInfoProps> {
|
|
193
171
|
|
194
172
|
private renderContent = () => {
|
195
173
|
const {
|
196
|
-
cluster = {}
|
174
|
+
cluster = {},
|
197
175
|
showTooltip,
|
198
176
|
hideTooltip,
|
199
177
|
clusterTitle,
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import {Button, CopyToClipboard as CopyToClipboardUiKit} from '@gravity-ui/uikit';
|
2
2
|
import createToast from '../../utils/createToast';
|
3
|
-
|
4
|
-
import Icon from '../Icon/Icon';
|
3
|
+
import {Icon} from '../Icon';
|
5
4
|
|
6
5
|
interface CopyToClipboardProps {
|
7
6
|
text: string;
|
@@ -1,6 +1,7 @@
|
|
1
|
-
import
|
1
|
+
import {ReactNode} from 'react';
|
2
2
|
import cn from 'bem-cn-lite';
|
3
|
-
|
3
|
+
|
4
|
+
import {Icon} from '../Icon';
|
4
5
|
|
5
6
|
import './EmptyState.scss';
|
6
7
|
|
@@ -12,7 +13,15 @@ const sizes = {
|
|
12
13
|
l: 350,
|
13
14
|
};
|
14
15
|
|
15
|
-
|
16
|
+
interface EmptyStateProps {
|
17
|
+
title: string;
|
18
|
+
image?: ReactNode;
|
19
|
+
description?: ReactNode;
|
20
|
+
actions?: ReactNode[];
|
21
|
+
size?: keyof typeof sizes;
|
22
|
+
}
|
23
|
+
|
24
|
+
export const EmptyState = ({image, title, description, actions, size = 'm'}: EmptyStateProps) => {
|
16
25
|
return (
|
17
26
|
<div className={block({size})}>
|
18
27
|
<div className={block('wrapper', {size})}>
|
@@ -35,16 +44,4 @@ export default function EmptyState({image, title, description, actions, size}) {
|
|
35
44
|
</div>
|
36
45
|
</div>
|
37
46
|
);
|
38
|
-
}
|
39
|
-
|
40
|
-
EmptyState.propTypes = {
|
41
|
-
title: PropTypes.string.isRequired,
|
42
|
-
image: PropTypes.node,
|
43
|
-
description: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
44
|
-
actions: PropTypes.arrayOf(PropTypes.node),
|
45
|
-
size: PropTypes.string,
|
46
|
-
};
|
47
|
-
|
48
|
-
EmptyState.defaultProps = {
|
49
|
-
size: 'm',
|
50
47
|
};
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './EmptyState';
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import {Button} from '@gravity-ui/uikit';
|
2
2
|
import {useDispatch} from 'react-redux';
|
3
3
|
import {enableFullscreen} from '../../store/reducers/fullscreen';
|
4
|
-
import Icon from '../Icon
|
4
|
+
import {Icon} from '../Icon';
|
5
5
|
|
6
6
|
interface EnableFullscreenButtonProps {
|
7
7
|
disabled?: boolean;
|
@@ -13,7 +13,12 @@ function EnableFullscreenButton({disabled}: EnableFullscreenButtonProps) {
|
|
13
13
|
dispatch(enableFullscreen());
|
14
14
|
};
|
15
15
|
return (
|
16
|
-
<Button
|
16
|
+
<Button
|
17
|
+
onClick={onEnableFullscreen}
|
18
|
+
view="flat-secondary"
|
19
|
+
disabled={disabled}
|
20
|
+
title="Fullscreen"
|
21
|
+
>
|
17
22
|
<Icon name="enableFullscreen" viewBox={'0 0 16 16'} height={16} width={16} />
|
18
23
|
</Button>
|
19
24
|
);
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import {Icon as UiKitIcon} from '@gravity-ui/uikit';
|
2
|
+
|
3
|
+
interface IconProps {
|
4
|
+
name: string;
|
5
|
+
height?: number | string;
|
6
|
+
width?: number | string;
|
7
|
+
viewBox?: string;
|
8
|
+
className?: string;
|
9
|
+
onClick?: (event: React.MouseEvent<SVGElement, MouseEvent>) => void;
|
10
|
+
}
|
11
|
+
|
12
|
+
export const Icon = ({
|
13
|
+
name,
|
14
|
+
height = 16,
|
15
|
+
width = 16,
|
16
|
+
viewBox = '0 0 16 16',
|
17
|
+
className,
|
18
|
+
onClick,
|
19
|
+
}: IconProps) => {
|
20
|
+
return (
|
21
|
+
<UiKitIcon
|
22
|
+
// @ts-expect-error
|
23
|
+
// Both url and id strings are required in this uikit component.
|
24
|
+
// However, if no url provided, component uses id, which is what we need.
|
25
|
+
// If it is fixed in uikit it could be safely removed
|
26
|
+
data={{id: `icon.${name}`, viewBox}}
|
27
|
+
height={height}
|
28
|
+
width={width}
|
29
|
+
className={className}
|
30
|
+
onClick={onClick}
|
31
|
+
/>
|
32
|
+
);
|
33
|
+
};
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './Icon';
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
3
3
|
import cn from 'bem-cn-lite';
|
4
4
|
import {Button} from '@gravity-ui/uikit';
|
5
|
-
import Icon from '../Icon
|
5
|
+
import {Icon} from '../Icon';
|
6
6
|
import Hotkey from '../Hotkey/Hotkey';
|
7
7
|
|
8
8
|
import './Pagination.scss';
|
@@ -0,0 +1,59 @@
|
|
1
|
+
import {useRef} from 'react';
|
2
|
+
import cn from 'bem-cn-lite';
|
3
|
+
|
4
|
+
import type {TTabletStateInfo} from '../../types/api/tablet';
|
5
|
+
import type {ShowTooltipFunction} from '../../types/store/tooltip';
|
6
|
+
import {getTabletLabel} from '../../utils/constants';
|
7
|
+
import routes, {createHref} from '../../routes';
|
8
|
+
|
9
|
+
import {InternalLink} from '../InternalLink';
|
10
|
+
|
11
|
+
import './Tablet.scss';
|
12
|
+
|
13
|
+
const b = cn('tablet');
|
14
|
+
|
15
|
+
interface TabletProps {
|
16
|
+
tablet?: TTabletStateInfo;
|
17
|
+
onMouseEnter?: (...args: Parameters<ShowTooltipFunction>) => void;
|
18
|
+
onMouseLeave?: VoidFunction;
|
19
|
+
}
|
20
|
+
|
21
|
+
export const Tablet = ({
|
22
|
+
tablet = {},
|
23
|
+
onMouseEnter = () => {},
|
24
|
+
onMouseLeave = () => {},
|
25
|
+
}: TabletProps) => {
|
26
|
+
const ref = useRef(null);
|
27
|
+
|
28
|
+
const _onTabletMouseEnter = () => {
|
29
|
+
onMouseEnter(ref.current, tablet, 'tablet');
|
30
|
+
};
|
31
|
+
|
32
|
+
const _onTabletClick = () => {
|
33
|
+
const {TabletId: id} = tablet;
|
34
|
+
|
35
|
+
if (id) {
|
36
|
+
onMouseLeave();
|
37
|
+
}
|
38
|
+
};
|
39
|
+
|
40
|
+
const {TabletId: id} = tablet;
|
41
|
+
const status = tablet.Overall?.toLowerCase();
|
42
|
+
|
43
|
+
return (
|
44
|
+
<InternalLink
|
45
|
+
onClick={_onTabletClick}
|
46
|
+
to={id && createHref(routes.tablet, {id})}
|
47
|
+
className={b('wrapper')}
|
48
|
+
>
|
49
|
+
<div
|
50
|
+
ref={ref}
|
51
|
+
className={b({status})}
|
52
|
+
onMouseEnter={_onTabletMouseEnter}
|
53
|
+
onMouseLeave={onMouseLeave}
|
54
|
+
>
|
55
|
+
<div className={b('type')}>{[getTabletLabel(tablet.Type)]}</div>
|
56
|
+
</div>
|
57
|
+
</InternalLink>
|
58
|
+
);
|
59
|
+
};
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './Tablet';
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import cn from 'bem-cn-lite';
|
2
|
+
|
3
|
+
import './Tag.scss';
|
4
|
+
|
5
|
+
const b = cn('tag');
|
6
|
+
|
7
|
+
export type TagType = 'blue';
|
8
|
+
|
9
|
+
interface TagProps {
|
10
|
+
text: string;
|
11
|
+
type?: TagType;
|
12
|
+
}
|
13
|
+
|
14
|
+
export const Tag = ({text, type}: TagProps) => {
|
15
|
+
return <div className={b({type})}>{text}</div>;
|
16
|
+
};
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './Tag';
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import cn from 'bem-cn-lite';
|
2
|
+
|
3
|
+
import {Tag, TagType} from '../Tag';
|
4
|
+
|
5
|
+
import './Tags.scss';
|
6
|
+
|
7
|
+
const b = cn('tags');
|
8
|
+
|
9
|
+
interface TagsProps {
|
10
|
+
tags: string[];
|
11
|
+
tagsType?: TagType;
|
12
|
+
className?: string;
|
13
|
+
}
|
14
|
+
|
15
|
+
export const Tags = ({tags, tagsType, className = ''}: TagsProps) => {
|
16
|
+
return (
|
17
|
+
<div className={b(null, className)}>
|
18
|
+
{tags &&
|
19
|
+
tags.map((tag, tagIndex) => <Tag text={tag} key={tagIndex} type={tagsType}></Tag>)}
|
20
|
+
</div>
|
21
|
+
);
|
22
|
+
};
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './Tags';
|
@@ -5,8 +5,7 @@ import {useHistory, useLocation} from 'react-router';
|
|
5
5
|
import {Breadcrumbs, BreadcrumbsItem, Link} from '@gravity-ui/uikit';
|
6
6
|
|
7
7
|
import Divider from '../../components/Divider/Divider';
|
8
|
-
|
9
|
-
import Icon from '../../components/Icon/Icon';
|
8
|
+
import {Icon} from '../../components/Icon';
|
10
9
|
|
11
10
|
import {clusterName as clusterNameLocation, backend, customBackend} from '../../store';
|
12
11
|
import {getClusterInfo} from '../../store/reducers/cluster';
|
@@ -27,7 +26,7 @@ function ClusterName({name}: {name: string}) {
|
|
27
26
|
}
|
28
27
|
|
29
28
|
interface HeaderProps {
|
30
|
-
clusterName: string
|
29
|
+
clusterName: string;
|
31
30
|
}
|
32
31
|
|
33
32
|
function Header({clusterName}: HeaderProps) {
|
@@ -5,7 +5,7 @@ import cn from 'bem-cn-lite';
|
|
5
5
|
import {Link as ExternalLink} from '@gravity-ui/uikit';
|
6
6
|
|
7
7
|
import EntityStatus from '../../../components/EntityStatus/EntityStatus';
|
8
|
-
import {Tag} from '../../../components/Tag
|
8
|
+
import {Tag} from '../../../components/Tag';
|
9
9
|
|
10
10
|
import {calcUptime} from '../../../utils';
|
11
11
|
import {customBackend} from '../../../store';
|
@@ -9,7 +9,7 @@ import DataTable, {Column, Settings} from '@gravity-ui/react-data-table';
|
|
9
9
|
import EntityStatus from '../../../components/EntityStatus/EntityStatus';
|
10
10
|
import InfoViewer from '../../../components/InfoViewer/InfoViewer';
|
11
11
|
import ProgressViewer from '../../../components/ProgressViewer/ProgressViewer';
|
12
|
-
import Icon from '../../../components/Icon
|
12
|
+
import {Icon} from '../../../components/Icon';
|
13
13
|
import {Vdisk} from './Vdisk';
|
14
14
|
|
15
15
|
import {bytesToGB, pad9} from '../../../utils/utils';
|
@@ -2,7 +2,7 @@ import cn from 'bem-cn-lite';
|
|
2
2
|
import DataTable, {Column} from '@gravity-ui/react-data-table';
|
3
3
|
import {Button, Popover} from '@gravity-ui/uikit';
|
4
4
|
|
5
|
-
import Icon from '../../components/Icon
|
5
|
+
import {Icon} from '../../components/Icon';
|
6
6
|
import EntityStatus from '../../components/EntityStatus/EntityStatus';
|
7
7
|
import PoolsGraph from '../../components/PoolsGraph/PoolsGraph';
|
8
8
|
import ProgressViewer from '../../components/ProgressViewer/ProgressViewer';
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import {Button} from '@gravity-ui/uikit';
|
2
2
|
|
3
|
-
import EmptyState from '../../../components/EmptyState
|
3
|
+
import {EmptyState} from '../../../components/EmptyState';
|
4
4
|
import {Illustration} from '../../../components/Illustration';
|
5
5
|
|
6
6
|
import i18n from './i18n';
|
@@ -22,13 +22,12 @@ export const EmptyFilter = ({
|
|
22
22
|
image={<Illustration name="thumbsUp" />}
|
23
23
|
title={title}
|
24
24
|
description={message}
|
25
|
-
actions={
|
26
|
-
|
27
|
-
key="show-all"
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
]}
|
25
|
+
actions={
|
26
|
+
onShowAll && [
|
27
|
+
<Button key="show-all" onClick={onShowAll}>
|
28
|
+
{showAll}
|
29
|
+
</Button>,
|
30
|
+
]
|
31
|
+
}
|
33
32
|
/>
|
34
33
|
);
|
@@ -21,6 +21,21 @@
|
|
21
21
|
&__vdisks-item {
|
22
22
|
flex-basis: 5px;
|
23
23
|
flex-shrink: 0;
|
24
|
+
|
25
|
+
.stack__layer {
|
26
|
+
background: var(--yc-color-base-background);
|
27
|
+
|
28
|
+
.data-table__row:hover & {
|
29
|
+
background: var(--ydb-data-table-color-hover);
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
&__donors-stack {
|
35
|
+
--ydb-stack-offset-x: 0px;
|
36
|
+
--ydb-stack-offset-y: -2px;
|
37
|
+
--ydb-stack-offset-x-hover: 0px;
|
38
|
+
--ydb-stack-offset-y-hover: -7px;
|
24
39
|
}
|
25
40
|
|
26
41
|
&__media-type {
|
@@ -2,6 +2,7 @@ import React, {useEffect, useState, useRef, useMemo} from 'react';
|
|
2
2
|
import cn from 'bem-cn-lite';
|
3
3
|
|
4
4
|
import {InternalLink} from '../../../components/InternalLink';
|
5
|
+
import {Stack} from '../../../components/Stack/Stack';
|
5
6
|
|
6
7
|
import routes, {createHref} from '../../../routes';
|
7
8
|
import {getVDisksForPDisk} from '../../../store/reducers/storage';
|
@@ -10,6 +11,7 @@ import {TVDiskStateInfo} from '../../../types/api/vdisk';
|
|
10
11
|
import {stringifyVdiskId} from '../../../utils';
|
11
12
|
import {useTypedSelector} from '../../../utils/hooks';
|
12
13
|
import {getPDiskType} from '../../../utils/pdisk';
|
14
|
+
import {isFullVDiksData} from '../../../utils/storage';
|
13
15
|
|
14
16
|
import {STRUCTURE} from '../../Node/NodePages';
|
15
17
|
|
@@ -109,19 +111,42 @@ export const PDisk = ({nodeId, data: rawData = {}}: PDiskProps) => {
|
|
109
111
|
|
110
112
|
return (
|
111
113
|
<div className={b('vdisks')}>
|
112
|
-
{vdisks.map((vdisk) =>
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
114
|
+
{vdisks.map((vdisk) => {
|
115
|
+
const donors = vdisk.Donors;
|
116
|
+
|
117
|
+
return (
|
118
|
+
<div
|
119
|
+
key={stringifyVdiskId(vdisk.VDiskId)}
|
120
|
+
className={b('vdisks-item')}
|
121
|
+
style={{
|
122
|
+
// 1 is small enough for empty disks to be of the minimum width
|
123
|
+
// but if all of them are empty, `flex-grow: 1` would size them evenly
|
124
|
+
flexGrow: Number(vdisk.AllocatedSize) || 1,
|
125
|
+
}}
|
126
|
+
>
|
127
|
+
{donors && donors.length ? (
|
128
|
+
<Stack className={b('donors-stack')} key={stringifyVdiskId(vdisk.VDiskId)}>
|
129
|
+
<VDisk data={vdisk} compact />
|
130
|
+
{donors.map((donor) => {
|
131
|
+
const isFullData = isFullVDiksData(donor);
|
132
|
+
|
133
|
+
return (
|
134
|
+
<VDisk
|
135
|
+
compact
|
136
|
+
data={isFullData ? donor : {...donor, DonorMode: true}}
|
137
|
+
key={stringifyVdiskId(
|
138
|
+
isFullData ? donor.VDiskId : donor,
|
139
|
+
)}
|
140
|
+
/>
|
141
|
+
);
|
142
|
+
})}
|
143
|
+
</Stack>
|
144
|
+
) : (
|
145
|
+
<VDisk data={vdisk} compact />
|
146
|
+
)}
|
147
|
+
</div>
|
148
|
+
);
|
149
|
+
})}
|
125
150
|
</div>
|
126
151
|
);
|
127
152
|
};
|
@@ -12,9 +12,9 @@ import '../../services/api';
|
|
12
12
|
|
13
13
|
import InfoViewer from '../../components/InfoViewer/InfoViewer';
|
14
14
|
import EntityStatus from '../../components/EntityStatus/EntityStatus';
|
15
|
-
import {Tag} from '../../components/Tag
|
16
|
-
import Icon from '../../components/Icon
|
17
|
-
import EmptyState from '../../components/EmptyState
|
15
|
+
import {Tag} from '../../components/Tag';
|
16
|
+
import {Icon} from '../../components/Icon';
|
17
|
+
import {EmptyState} from '../../components/EmptyState';
|
18
18
|
import {Link as ExternalLink, Button, Loader} from '@gravity-ui/uikit';
|
19
19
|
import DataTable from '@gravity-ui/react-data-table';
|
20
20
|
import CriticalActionDialog from '../../components/CriticalActionDialog/CriticalActionDialog';
|
@@ -111,9 +111,9 @@ class Tablet extends React.Component {
|
|
111
111
|
const {isFirstFetchData} = this.state;
|
112
112
|
|
113
113
|
if (version && this.isValidVersion()) {
|
114
|
-
this.props.getTablet(id).then(({
|
115
|
-
if (isFirstFetchData &&
|
116
|
-
this.props.getTabletDescribe(
|
114
|
+
this.props.getTablet(id).then(({tabletData}) => {
|
115
|
+
if (isFirstFetchData && tabletData.TenantId) {
|
116
|
+
this.props.getTabletDescribe(tabletData.TenantId);
|
117
117
|
}
|
118
118
|
|
119
119
|
this.setState({isFirstFetchData: false});
|