ydb-embedded-ui 1.8.7 → 1.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 +56 -0
- package/dist/components/BasicNodeViewer/BasicNodeViewer.scss +43 -0
- package/dist/components/BasicNodeViewer/BasicNodeViewer.tsx +53 -0
- package/dist/components/BasicNodeViewer/index.ts +1 -0
- package/dist/components/EntityStatus/EntityStatus.js +15 -3
- package/dist/components/FullNodeViewer/FullNodeViewer.js +29 -48
- package/dist/components/FullNodeViewer/FullNodeViewer.scss +0 -45
- package/dist/components/IndexInfoViewer/IndexInfoViewer.tsx +52 -0
- package/dist/components/InfoViewer/index.ts +4 -0
- package/dist/components/InfoViewer/utils.ts +32 -0
- package/dist/components/ProgressViewer/ProgressViewer.js +1 -1
- package/dist/components/TabletsOverall/TabletsOverall.tsx +1 -1
- package/dist/containers/Node/Node.scss +5 -1
- package/dist/containers/Node/Node.tsx +7 -1
- package/dist/containers/Node/NodeOverview/NodeOverview.tsx +1 -3
- package/dist/containers/Node/NodeStructure/NodeStructure.scss +30 -1
- package/dist/containers/Node/NodeStructure/PDiskTitleBadge.tsx +25 -0
- package/dist/containers/Node/NodeStructure/Pdisk.tsx +24 -2
- package/dist/containers/Nodes/Nodes.js +1 -0
- package/dist/containers/ReduxTooltip/ReduxTooltip.js +1 -1
- package/dist/containers/Storage/Pdisk/Pdisk.tsx +25 -33
- package/dist/containers/Storage/Vdisk/Vdisk.js +2 -0
- package/dist/containers/Tablet/Tablet.js +2 -2
- package/dist/containers/Tablets/Tablets.js +1 -1
- package/dist/containers/Tablets/Tablets.scss +0 -6
- package/dist/containers/TabletsFilters/TabletsFilters.scss +0 -7
- package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.scss +6 -2
- package/dist/containers/Tenant/Diagnostics/DiagnosticsPages.ts +24 -14
- package/dist/containers/Tenant/Diagnostics/Healthcheck/Healthcheck.js +6 -2
- package/dist/containers/Tenant/Diagnostics/Healthcheck/Healthcheck.scss +6 -2
- package/dist/containers/Tenant/Diagnostics/HotKeys/HotKeys.js +3 -3
- package/dist/containers/Tenant/Diagnostics/Overview/Overview.tsx +24 -3
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +15 -13
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.scss +22 -6
- package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.js +80 -10
- package/dist/containers/Tenant/Schema/SchemaInfoViewer/SchemaInfoViewer.js +20 -16
- package/dist/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx +1 -0
- package/dist/containers/Tenant/utils/schema.ts +73 -28
- package/dist/containers/Tenant/utils/schemaActions.ts +42 -32
- package/dist/services/api.js +13 -8
- package/dist/store/reducers/executeQuery.js +1 -1
- package/dist/store/reducers/executeTopQueries.js +1 -1
- package/dist/store/reducers/olapStats.js +5 -1
- package/dist/store/reducers/preview.js +1 -1
- package/dist/store/reducers/shardsWorkload.js +32 -4
- package/dist/types/api/schema.ts +43 -1
- package/dist/types/api/storage.ts +54 -0
- package/dist/utils/getNodesColumns.js +2 -0
- package/dist/utils/pdisk.ts +74 -0
- package/dist/utils/tooltip.js +27 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,61 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [1.10.0](https://github.com/ydb-platform/ydb-embedded-ui/compare/v1.9.0...v1.10.0) (2022-08-10)
|
4
|
+
|
5
|
+
|
6
|
+
### Features
|
7
|
+
|
8
|
+
* **TopShards:** add DataSize column ([cbcd047](https://github.com/ydb-platform/ydb-embedded-ui/commit/cbcd047d277f699a67bc002a5542f3b9f6a0c942))
|
9
|
+
* **TopShards:** sort table data on backend ([dc28c5c](https://github.com/ydb-platform/ydb-embedded-ui/commit/dc28c5c75b0036480bf804d49f82fc54eac98c8e))
|
10
|
+
|
11
|
+
|
12
|
+
### Bug Fixes
|
13
|
+
|
14
|
+
* add concurrentId for sendQuery request ([dc6b32a](https://github.com/ydb-platform/ydb-embedded-ui/commit/dc6b32a8fd51064ddeca2fc60a0f08a725216334))
|
15
|
+
* **Storage:** display pdisk type in tooltip ([2b03a35](https://github.com/ydb-platform/ydb-embedded-ui/commit/2b03a35fc11ddeae3bdd30a0690b324ae917f5c3))
|
16
|
+
* **Tablet:** change Kill to Restart ([dd585b1](https://github.com/ydb-platform/ydb-embedded-ui/commit/dd585b1d1a6a5ddb484a702523773b169900f582))
|
17
|
+
* **Tenant:** add missing schema node types ([62a0ecb](https://github.com/ydb-platform/ydb-embedded-ui/commit/62a0ecb848dbcee53e18535cbf7c03a731d0cfeb))
|
18
|
+
* **Tenant:** ensure correct behavior for new schema node types ([f80c381](https://github.com/ydb-platform/ydb-embedded-ui/commit/f80c38152656e8bbbe51ec38b29fc0d954c361cc))
|
19
|
+
* **Tenant:** use new schema icons ([389a921](https://github.com/ydb-platform/ydb-embedded-ui/commit/389a9214c64b1adb183fa0c6caa6f2ec536dbef3))
|
20
|
+
* **TopShards:** disable virtualization for table ([006d3d9](https://github.com/ydb-platform/ydb-embedded-ui/commit/006d3d9fb9a4744b8bb4ad03e53693199213f80e))
|
21
|
+
* **TopShards:** format DataSize value ([c51ce66](https://github.com/ydb-platform/ydb-embedded-ui/commit/c51ce66286f6454f7252d1194628ee5a50aafba2))
|
22
|
+
* **TopShards:** only allow DESC sort ([6aa326f](https://github.com/ydb-platform/ydb-embedded-ui/commit/6aa326fc4b8165f00f8b3ecf5becdb0943ed57af))
|
23
|
+
* **TopShards:** substring tenant name out of shards path ([9e57672](https://github.com/ydb-platform/ydb-embedded-ui/commit/9e5767222c7dac7734c68abd08067cea507b1e15))
|
24
|
+
|
25
|
+
## [1.9.0](https://github.com/ydb-platform/ydb-embedded-ui/compare/v1.8.8...v1.9.0) (2022-07-29)
|
26
|
+
|
27
|
+
|
28
|
+
### Features
|
29
|
+
|
30
|
+
* **Node:** display endpoints in overview ([89e9e47](https://github.com/ydb-platform/ydb-embedded-ui/commit/89e9e470499b6f458e8949211d97293c0b7d9b97))
|
31
|
+
* **Node:** display node basic info above tabs ([aafb15b](https://github.com/ydb-platform/ydb-embedded-ui/commit/aafb15b399bf116026eff36f3c4ac817e2c40e18))
|
32
|
+
* **Node:** more informative pdisks panels ([342712b](https://github.com/ydb-platform/ydb-embedded-ui/commit/342712bcaa793971e1ca354da57fb962639ef90c))
|
33
|
+
* **Nodes:** show node endpoints in tooltip ([34be559](https://github.com/ydb-platform/ydb-embedded-ui/commit/34be55957e02f947ede30b43f22fde82d21df308))
|
34
|
+
* **Tenant:** table index overview ([2aed714](https://github.com/ydb-platform/ydb-embedded-ui/commit/2aed71488cde1175e6569c236ab609bb126f9cf3))
|
35
|
+
* **Tenant:** virtualized tree in schema ([815f558](https://github.com/ydb-platform/ydb-embedded-ui/commit/815f5588e5fed6fb86f69653c4937e975465372f))
|
36
|
+
* utils for parsing bitfields in pdisk data ([da22b4a](https://github.com/ydb-platform/ydb-embedded-ui/commit/da22b4afde9efe4d9605cefb69ddd51aed989722))
|
37
|
+
|
38
|
+
|
39
|
+
### Bug Fixes
|
40
|
+
|
41
|
+
* **Node:** fix pdisk title items width ([ca5fec6](https://github.com/ydb-platform/ydb-embedded-ui/commit/ca5fec6388364b7d1d6362f1bda36431d9c29749))
|
42
|
+
* **Nodes:** hide tooltip on unmount ([54e4fdc](https://github.com/ydb-platform/ydb-embedded-ui/commit/54e4fdc8045c555338e79d89a93faf58e888fa0e))
|
43
|
+
* **ProgressViewer:** apply provided custom class name ([aa60e9d](https://github.com/ydb-platform/ydb-embedded-ui/commit/aa60e9d1b9c0752853f4323d3bcfd220bedd272d))
|
44
|
+
* **Tenant:** display all table props in overview ([d70e311](https://github.com/ydb-platform/ydb-embedded-ui/commit/d70e311296f6a4d1781f6e72929c70e0db7c3226))
|
45
|
+
* **Tenant:** display PartCount first in table overview ([8c09746](https://github.com/ydb-platform/ydb-embedded-ui/commit/8c09746b026a23a36fe31be94057cc92535aceaa))
|
46
|
+
|
47
|
+
## [1.8.8](https://github.com/ydb-platform/ydb-embedded-ui/compare/v1.8.7...v1.8.8) (2022-07-21)
|
48
|
+
|
49
|
+
|
50
|
+
### Bug Fixes
|
51
|
+
|
52
|
+
* **TabletsFilters:** display tablets grid full-height ([0dde809](https://github.com/ydb-platform/ydb-embedded-ui/commit/0dde8097fe026248aade97f034fa35c56b28e903))
|
53
|
+
* **TabletsOverall:** properly hide tooltip on mouseleave ([df36eba](https://github.com/ydb-platform/ydb-embedded-ui/commit/df36ebaf44d8966bc419f3720d51390dfd767a87))
|
54
|
+
* **Tablets:** properly display tablets in grid ([f3b64fa](https://github.com/ydb-platform/ydb-embedded-ui/commit/f3b64fae3a1e1a46ababd2d2f04ddff488698676))
|
55
|
+
* **Tenant:** align info in overview ([acb39fa](https://github.com/ydb-platform/ydb-embedded-ui/commit/acb39fab70b7b4e0e78124fd887b2f1b76815221))
|
56
|
+
* **Tenant:** display tenant name in single line ([301e391](https://github.com/ydb-platform/ydb-embedded-ui/commit/301e3911330024f80ebfda6d1a16823b64d94b36))
|
57
|
+
* **Tenant:** move tablets under tenant name ([b7e4b8f](https://github.com/ydb-platform/ydb-embedded-ui/commit/b7e4b8f7027f1481a7c1baff77bf8ad5e2ed467c))
|
58
|
+
|
3
59
|
## [1.8.7](https://github.com/ydb-platform/ydb-embedded-ui/compare/v1.8.6...v1.8.7) (2022-07-18)
|
4
60
|
|
5
61
|
|
@@ -0,0 +1,43 @@
|
|
1
|
+
@import '../../styles/mixins.scss';
|
2
|
+
|
3
|
+
.basic-node-viewer {
|
4
|
+
font-size: var(--yc-text-body-2-font-size);
|
5
|
+
line-height: var(--yc-text-body-2-line-height);
|
6
|
+
|
7
|
+
display: flex;
|
8
|
+
align-items: center;
|
9
|
+
|
10
|
+
margin: 15px 0;
|
11
|
+
|
12
|
+
&__title {
|
13
|
+
margin: 0 20px 0 0;
|
14
|
+
|
15
|
+
font-size: var(--yc-text-body-2-font-size);
|
16
|
+
font-weight: 600;
|
17
|
+
line-height: var(--yc-text-body-2-line-height);
|
18
|
+
text-transform: uppercase;
|
19
|
+
}
|
20
|
+
|
21
|
+
&__id {
|
22
|
+
margin: 0 15px 0 24px;
|
23
|
+
}
|
24
|
+
|
25
|
+
&__label {
|
26
|
+
margin-right: 10px;
|
27
|
+
|
28
|
+
font-size: var(--yc-text-body-2-font-size);
|
29
|
+
line-height: 18px;
|
30
|
+
white-space: nowrap;
|
31
|
+
|
32
|
+
color: var(--yc-color-text-hint);
|
33
|
+
|
34
|
+
.yc-root_theme_dark & {
|
35
|
+
color: var(--yc-color-text-hint);
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
&__link {
|
40
|
+
margin-left: 5px;
|
41
|
+
@extend .link;
|
42
|
+
}
|
43
|
+
}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
import cn from 'bem-cn-lite';
|
2
|
+
|
3
|
+
import EntityStatus from '../EntityStatus/EntityStatus';
|
4
|
+
import Tags from '../Tags/Tags';
|
5
|
+
import Icon from '../Icon/Icon';
|
6
|
+
|
7
|
+
import './BasicNodeViewer.scss';
|
8
|
+
|
9
|
+
const b = cn('basic-node-viewer');
|
10
|
+
|
11
|
+
interface BasicNodeViewerProps {
|
12
|
+
node: any;
|
13
|
+
additionalNodesInfo?: any;
|
14
|
+
className?: string;
|
15
|
+
}
|
16
|
+
|
17
|
+
export const BasicNodeViewer = ({node, additionalNodesInfo, className}: BasicNodeViewerProps) => {
|
18
|
+
const nodeHref = additionalNodesInfo?.getNodeRef
|
19
|
+
? additionalNodesInfo.getNodeRef(node) + 'internal'
|
20
|
+
: undefined;
|
21
|
+
|
22
|
+
return (
|
23
|
+
<div className={b(null, className)}>
|
24
|
+
{node ? (
|
25
|
+
<>
|
26
|
+
<div className={b('title')}>Node</div>
|
27
|
+
<EntityStatus status={node.SystemState} name={node.Host} />
|
28
|
+
{nodeHref && (
|
29
|
+
<a
|
30
|
+
rel="noopener noreferrer"
|
31
|
+
className={b('link', {external: true})}
|
32
|
+
href={nodeHref}
|
33
|
+
target="_blank"
|
34
|
+
>
|
35
|
+
<Icon name="external" />
|
36
|
+
</a>
|
37
|
+
)}
|
38
|
+
|
39
|
+
<div className={b('id')}>
|
40
|
+
<label className={b('label')}>NodeID</label>
|
41
|
+
<label>{node.NodeId}</label>
|
42
|
+
</div>
|
43
|
+
|
44
|
+
<Tags tags={[node.DataCenter]} />
|
45
|
+
<Tags tags={node.Roles} tagsType="blue" />
|
46
|
+
</>
|
47
|
+
) : (
|
48
|
+
<div className="error">no data</div>
|
49
|
+
)}
|
50
|
+
|
51
|
+
</div>
|
52
|
+
);
|
53
|
+
};
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './BasicNodeViewer';
|
@@ -12,6 +12,8 @@ class EntityStatus extends React.Component {
|
|
12
12
|
static propTypes = {
|
13
13
|
status: PropTypes.string,
|
14
14
|
name: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
15
|
+
onNameMouseEnter: PropTypes.func,
|
16
|
+
onNameMouseLeave: PropTypes.func,
|
15
17
|
path: PropTypes.string,
|
16
18
|
size: PropTypes.string,
|
17
19
|
label: PropTypes.string,
|
@@ -49,19 +51,29 @@ class EntityStatus extends React.Component {
|
|
49
51
|
);
|
50
52
|
}
|
51
53
|
renderLink() {
|
52
|
-
const {externalLink, name, path} = this.props;
|
54
|
+
const {externalLink, name, path, onNameMouseEnter, onNameMouseLeave} = this.props;
|
53
55
|
|
54
56
|
if (externalLink) {
|
55
57
|
return <ExternalLink href={path}>{name}</ExternalLink>;
|
56
58
|
}
|
57
59
|
|
58
60
|
return path ? (
|
59
|
-
<Link
|
61
|
+
<Link
|
62
|
+
title={name}
|
63
|
+
to={path}
|
64
|
+
onMouseEnter={onNameMouseEnter}
|
65
|
+
onMouseLeave={onNameMouseLeave}
|
66
|
+
>
|
60
67
|
{name}
|
61
68
|
</Link>
|
62
69
|
) : (
|
63
70
|
name && (
|
64
|
-
<span
|
71
|
+
<span
|
72
|
+
className={b('name')}
|
73
|
+
title={name}
|
74
|
+
onMouseEnter={onNameMouseEnter}
|
75
|
+
onMouseLeave={onNameMouseLeave}
|
76
|
+
>
|
65
77
|
{name}
|
66
78
|
</span>
|
67
79
|
)
|
@@ -3,11 +3,8 @@ import cn from 'bem-cn-lite';
|
|
3
3
|
import PropTypes from 'prop-types';
|
4
4
|
|
5
5
|
import InfoViewer from '../InfoViewer/InfoViewer';
|
6
|
-
import EntityStatus from '../EntityStatus/EntityStatus';
|
7
6
|
import ProgressViewer from '../ProgressViewer/ProgressViewer';
|
8
7
|
import PoolUsage from '../PoolUsage/PoolUsage';
|
9
|
-
import Tags from '../Tags/Tags';
|
10
|
-
import Icon from '../Icon/Icon';
|
11
8
|
|
12
9
|
import {LOAD_AVERAGE_TIME_INTERVALS} from '../../utils/constants';
|
13
10
|
import {calcUptime} from '../../utils';
|
@@ -22,7 +19,6 @@ class FullNodeViewer extends React.Component {
|
|
22
19
|
node: PropTypes.object.isRequired,
|
23
20
|
backend: PropTypes.string,
|
24
21
|
singleClusterMode: PropTypes.bool,
|
25
|
-
additionalNodesInfo: PropTypes.object,
|
26
22
|
};
|
27
23
|
|
28
24
|
static defaultProps = {
|
@@ -30,10 +26,12 @@ class FullNodeViewer extends React.Component {
|
|
30
26
|
};
|
31
27
|
|
32
28
|
render() {
|
33
|
-
const {node, className
|
34
|
-
|
35
|
-
|
36
|
-
:
|
29
|
+
const {node, className} = this.props;
|
30
|
+
|
31
|
+
const endpointsInfo = node.Endpoints?.map(({Name, Address}) => ({
|
32
|
+
label: Name,
|
33
|
+
value: Address,
|
34
|
+
}));
|
37
35
|
|
38
36
|
const commonInfo = [
|
39
37
|
{label: 'Version', value: node.Version},
|
@@ -50,52 +48,35 @@ class FullNodeViewer extends React.Component {
|
|
50
48
|
return (
|
51
49
|
<div className={`${b()} ${className}`}>
|
52
50
|
{node ? (
|
53
|
-
<div>
|
54
|
-
<div
|
55
|
-
<div className={b('title')}>
|
56
|
-
<
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
className={b('link', {external: true})}
|
61
|
-
href={nodeHref}
|
62
|
-
target="_blank"
|
63
|
-
>
|
64
|
-
<Icon name="external" />
|
65
|
-
</a>
|
66
|
-
)}
|
67
|
-
|
68
|
-
<div className={b('row', {id: true})}>
|
69
|
-
<label className={b('label', {id: true})}>NodeID</label>
|
70
|
-
<label>{node.NodeId}</label>
|
51
|
+
<div className={b('common-info')}>
|
52
|
+
<div>
|
53
|
+
<div className={b('section-title')}>Pools</div>
|
54
|
+
<div className={b('section', {pools: true})}>
|
55
|
+
{node.PoolStats.map((pool, poolIndex) => (
|
56
|
+
<PoolUsage key={poolIndex} data={pool} />
|
57
|
+
))}
|
71
58
|
</div>
|
72
|
-
|
73
|
-
<Tags tags={[node.DataCenter]} />
|
74
|
-
<Tags tags={node.Roles} tagsType="blue" />
|
75
59
|
</div>
|
76
60
|
|
77
|
-
|
78
|
-
<div>
|
79
|
-
<div className={b('section-title')}>Pools</div>
|
80
|
-
<div className={b('section', {pools: true})}>
|
81
|
-
{node.PoolStats.map((pool, poolIndex) => (
|
82
|
-
<PoolUsage key={poolIndex} data={pool} />
|
83
|
-
))}
|
84
|
-
</div>
|
85
|
-
</div>
|
86
|
-
|
61
|
+
{endpointsInfo && endpointsInfo.length && (
|
87
62
|
<InfoViewer
|
88
|
-
title="
|
63
|
+
title="Endpoints"
|
89
64
|
className={b('section')}
|
90
|
-
info={
|
65
|
+
info={endpointsInfo}
|
91
66
|
/>
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
67
|
+
)}
|
68
|
+
|
69
|
+
<InfoViewer
|
70
|
+
title="Common info"
|
71
|
+
className={b('section')}
|
72
|
+
info={commonInfo}
|
73
|
+
/>
|
74
|
+
|
75
|
+
<InfoViewer
|
76
|
+
title="Load average"
|
77
|
+
className={b('section', {average: true})}
|
78
|
+
info={averageInfo}
|
79
|
+
/>
|
99
80
|
</div>
|
100
81
|
) : (
|
101
82
|
<div className="error">no data</div>
|
@@ -4,26 +4,6 @@
|
|
4
4
|
font-size: var(--yc-text-body-2-font-size);
|
5
5
|
line-height: var(--yc-text-body-2-line-height);
|
6
6
|
|
7
|
-
&__title {
|
8
|
-
margin: 0 20px 0 0;
|
9
|
-
|
10
|
-
font-size: var(--yc-text-body-2-font-size);
|
11
|
-
font-weight: 600;
|
12
|
-
line-height: var(--yc-text-body-2-line-height);
|
13
|
-
text-transform: uppercase;
|
14
|
-
}
|
15
|
-
|
16
|
-
&__row {
|
17
|
-
display: flex;
|
18
|
-
align-items: center;
|
19
|
-
|
20
|
-
margin: 15px 0;
|
21
|
-
|
22
|
-
&_id {
|
23
|
-
margin: 0 15px 0 24px;
|
24
|
-
}
|
25
|
-
}
|
26
|
-
|
27
7
|
&__common-info {
|
28
8
|
display: flex;
|
29
9
|
flex-direction: column;
|
@@ -46,26 +26,6 @@
|
|
46
26
|
min-width: 60px;
|
47
27
|
}
|
48
28
|
|
49
|
-
&__label {
|
50
|
-
min-width: 100px;
|
51
|
-
margin-right: 25px;
|
52
|
-
|
53
|
-
font-size: var(--yc-text-body-2-font-size);
|
54
|
-
line-height: 18px;
|
55
|
-
white-space: nowrap;
|
56
|
-
|
57
|
-
color: var(--yc-color-text-hint);
|
58
|
-
|
59
|
-
.yc-root_theme_dark & {
|
60
|
-
color: var(--yc-color-text-hint);
|
61
|
-
}
|
62
|
-
|
63
|
-
&_id {
|
64
|
-
min-width: auto;
|
65
|
-
margin-right: 10px;
|
66
|
-
}
|
67
|
-
}
|
68
|
-
|
69
29
|
&__section-title {
|
70
30
|
margin: 15px 0 10px;
|
71
31
|
|
@@ -73,9 +33,4 @@
|
|
73
33
|
font-weight: 600;
|
74
34
|
line-height: var(--yc-text-body-2-line-height);
|
75
35
|
}
|
76
|
-
|
77
|
-
&__link {
|
78
|
-
margin-left: 5px;
|
79
|
-
@extend .link;
|
80
|
-
}
|
81
36
|
}
|
@@ -0,0 +1,52 @@
|
|
1
|
+
import type {TEvDescribeSchemeResult, TIndexDescription} from '../../types/api/schema';
|
2
|
+
import {InfoViewer, createInfoFormatter} from '../InfoViewer';
|
3
|
+
|
4
|
+
const DISPLAYED_FIELDS: Set<keyof TIndexDescription> = new Set([
|
5
|
+
'Type',
|
6
|
+
'State',
|
7
|
+
'DataSize',
|
8
|
+
'KeyColumnNames',
|
9
|
+
'DataColumnNames',
|
10
|
+
]);
|
11
|
+
|
12
|
+
const formatItem = createInfoFormatter<TIndexDescription>({
|
13
|
+
Type: (value) => value?.substring(10), // trims EIndexType prefix
|
14
|
+
State: (value) => value?.substring(11), // trims EIndexState prefix
|
15
|
+
KeyColumnNames: (value) => value?.join(', '),
|
16
|
+
DataColumnNames: (value) => value?.join(', '),
|
17
|
+
}, {
|
18
|
+
KeyColumnNames: 'Columns',
|
19
|
+
DataColumnNames: 'Includes',
|
20
|
+
});
|
21
|
+
|
22
|
+
interface IndexInfoViewerProps {
|
23
|
+
data?: TEvDescribeSchemeResult;
|
24
|
+
}
|
25
|
+
|
26
|
+
export const IndexInfoViewer = ({data}: IndexInfoViewerProps) => {
|
27
|
+
if (!data) {
|
28
|
+
return (
|
29
|
+
<div className="error">no index data</div>
|
30
|
+
);
|
31
|
+
}
|
32
|
+
|
33
|
+
const TableIndex = data.PathDescription?.TableIndex;
|
34
|
+
const info: Array<{label?: string, value?: unknown}> = [];
|
35
|
+
|
36
|
+
let key: keyof TIndexDescription;
|
37
|
+
for (key in TableIndex) {
|
38
|
+
if (DISPLAYED_FIELDS.has(key)) {
|
39
|
+
info.push(formatItem(key, TableIndex?.[key]));
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
return (
|
44
|
+
<>
|
45
|
+
{info.length ? (
|
46
|
+
<InfoViewer info={info}></InfoViewer>
|
47
|
+
) : (
|
48
|
+
<>Empty</>
|
49
|
+
)}
|
50
|
+
</>
|
51
|
+
);
|
52
|
+
};
|
@@ -0,0 +1,32 @@
|
|
1
|
+
type LabelMap<T> = {
|
2
|
+
[label in keyof T]?: string;
|
3
|
+
}
|
4
|
+
|
5
|
+
type FieldMappers<T> = {
|
6
|
+
[label in keyof T]?: (value: T[label]) => string | undefined;
|
7
|
+
}
|
8
|
+
|
9
|
+
function formatLabel<Shape>(label: keyof Shape, map: LabelMap<Shape>) {
|
10
|
+
return map[label] ?? label;
|
11
|
+
}
|
12
|
+
|
13
|
+
function formatValue<Shape, Key extends keyof Shape>(
|
14
|
+
label: Key,
|
15
|
+
value: Shape[Key],
|
16
|
+
mappers: FieldMappers<Shape>,
|
17
|
+
) {
|
18
|
+
const mapper = mappers[label];
|
19
|
+
const mappedValue = mapper ? mapper(value) : value;
|
20
|
+
|
21
|
+
return String(mappedValue ?? '');
|
22
|
+
}
|
23
|
+
|
24
|
+
export function createInfoFormatter<Shape extends Record<string, any>>(
|
25
|
+
fieldMappers?: FieldMappers<Shape>,
|
26
|
+
labelMap?: LabelMap<Shape>,
|
27
|
+
) {
|
28
|
+
return <Key extends keyof Shape>(label: Key, value: Shape[Key]) => ({
|
29
|
+
label: formatLabel(label, labelMap || {}),
|
30
|
+
value: formatValue(label, value, fieldMappers || {}),
|
31
|
+
});
|
32
|
+
}
|
@@ -76,7 +76,7 @@ export class ProgressViewer extends React.Component {
|
|
76
76
|
|
77
77
|
if (!isNaN(fillWidth)) {
|
78
78
|
return (
|
79
|
-
<div className={b({size})}>
|
79
|
+
<div className={b({size}, className)}>
|
80
80
|
<div className={b('line', {bg})} style={lineStyle}></div>
|
81
81
|
<span className={b('text', {text})}>
|
82
82
|
{`${valueText} ${divider} ${capacityText}`}
|
@@ -93,7 +93,7 @@ function TabletsOverall({tablets}: TabletsOverallProps) {
|
|
93
93
|
<div className={b('row', {overall: true})}>
|
94
94
|
<span className={b('label', {overall: true})}>Overall:</span>
|
95
95
|
<div
|
96
|
-
onMouseLeave={dispatch(hideTooltip)}
|
96
|
+
onMouseLeave={() => dispatch(hideTooltip())}
|
97
97
|
onMouseEnter={(e) => dispatch(showTooltip(e.target, tooltipData, 'tabletsOverall'))}
|
98
98
|
>
|
99
99
|
<Progress value={memoryProgress} stack={stack} />
|
@@ -13,6 +13,7 @@ import Storage from '../Storage/Storage';
|
|
13
13
|
import NodeOverview from './NodeOverview/NodeOverview';
|
14
14
|
import NodeStructure from './NodeStructure/NodeStructure';
|
15
15
|
import Loader from '../../components/Loader/Loader';
|
16
|
+
import {BasicNodeViewer} from '../../components/BasicNodeViewer';
|
16
17
|
|
17
18
|
import {getNodeInfo, resetNode} from '../../store/reducers/node';
|
18
19
|
import routes, {CLUSTER_PAGES, createHref} from '../../routes';
|
@@ -133,7 +134,6 @@ function Node(props: NodeProps) {
|
|
133
134
|
case OVERVIEW: {
|
134
135
|
return (
|
135
136
|
<NodeOverview
|
136
|
-
additionalNodesInfo={additionalNodesInfo}
|
137
137
|
node={node}
|
138
138
|
className={b('overview-wrapper')}
|
139
139
|
/>
|
@@ -162,6 +162,12 @@ function Node(props: NodeProps) {
|
|
162
162
|
if (node) {
|
163
163
|
return (
|
164
164
|
<div className={b(null, props.className)}>
|
165
|
+
<BasicNodeViewer
|
166
|
+
node={node}
|
167
|
+
additionalNodesInfo={props.additionalNodesInfo}
|
168
|
+
className={b('header')}
|
169
|
+
/>
|
170
|
+
|
165
171
|
{renderTabs()}
|
166
172
|
|
167
173
|
<div className={b('content')}>{renderTabContent()}</div>
|
@@ -5,16 +5,14 @@ import {backend} from '../../../store';
|
|
5
5
|
|
6
6
|
interface NodeOverviewProps {
|
7
7
|
node: any;
|
8
|
-
additionalNodesInfo: any;
|
9
8
|
className?: string;
|
10
9
|
}
|
11
10
|
|
12
|
-
function NodeOverview({node,
|
11
|
+
function NodeOverview({node, className}: NodeOverviewProps) {
|
13
12
|
return (
|
14
13
|
<FullNodeViewer
|
15
14
|
node={node}
|
16
15
|
backend={backend}
|
17
|
-
additionalNodesInfo={additionalNodesInfo}
|
18
16
|
className={className}
|
19
17
|
/>
|
20
18
|
);
|
@@ -44,9 +44,38 @@
|
|
44
44
|
&__pdisk-title-wrapper {
|
45
45
|
display: flex;
|
46
46
|
align-items: center;
|
47
|
-
gap:
|
47
|
+
gap: 16px;
|
48
48
|
|
49
49
|
font-weight: 600;
|
50
|
+
|
51
|
+
.entity-status__status-icon {
|
52
|
+
margin-right: 0;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
&__pdisk-title-item {
|
57
|
+
display: flex;
|
58
|
+
gap: 4px;
|
59
|
+
|
60
|
+
&-label {
|
61
|
+
font-weight: 400;
|
62
|
+
|
63
|
+
color: var(--yc-color-text-secondary);
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
&__pdisk-title-id {
|
68
|
+
min-width: 110px;
|
69
|
+
}
|
70
|
+
|
71
|
+
&__pdisk-title-type {
|
72
|
+
justify-content: flex-end;
|
73
|
+
|
74
|
+
min-width: 50px;
|
75
|
+
}
|
76
|
+
|
77
|
+
&__pdisk-title-size {
|
78
|
+
min-width: 150px;
|
50
79
|
}
|
51
80
|
|
52
81
|
&__pdisk-details {
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import {ReactNode} from 'react';
|
2
|
+
import cn from 'bem-cn-lite';
|
3
|
+
|
4
|
+
const b = cn('kv-node-structure');
|
5
|
+
|
6
|
+
interface PDiskTitleBadgeProps {
|
7
|
+
label?: string;
|
8
|
+
value: ReactNode;
|
9
|
+
className?: string;
|
10
|
+
}
|
11
|
+
|
12
|
+
export function PDiskTitleBadge({label, value, className}: PDiskTitleBadgeProps) {
|
13
|
+
return (
|
14
|
+
<span className={b('pdisk-title-item', className)}>
|
15
|
+
{label && (
|
16
|
+
<span className={b('pdisk-title-item-label')}>
|
17
|
+
{label}:
|
18
|
+
</span>
|
19
|
+
)}
|
20
|
+
<span className={b('pdisk-title-item-value')}>
|
21
|
+
{value}
|
22
|
+
</span>
|
23
|
+
</span>
|
24
|
+
);
|
25
|
+
}
|