ydb-embedded-ui 3.4.0 → 3.4.2
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 +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});
|