Skip to content

Commit 990a9fa

Browse files
fix: disable link and popover for unavailable nodes
1 parent 07922fd commit 990a9fa

File tree

6 files changed

+76
-116
lines changed

6 files changed

+76
-116
lines changed

src/containers/Nodes/NodesTable.scss renamed to src/components/NodeHostWrapper/NodeHostWrapper.scss

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
.ydb-nodes-table {
2-
&__host-field-wrapper {
3-
display: flex;
4-
}
1+
.ydb-node-host-wrapper {
2+
display: flex;
53

64
&__host-wrapper {
75
display: flex;
86

9-
max-width: 330px;
7+
width: 330px;
108
}
119

1210
&__host {
@@ -21,7 +19,7 @@
2119
}
2220

2321
.data-table__row:hover {
24-
.ydb-nodes-table__external-button {
22+
.ydb-node-host-wrapper__external-button {
2523
display: inline-flex;
2624
}
2725
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import block from 'bem-cn-lite';
2+
3+
import {Button, Popover, PopoverBehavior} from '@gravity-ui/uikit';
4+
5+
import type {INodesPreparedEntity} from '../../types/store/nodes';
6+
import {getDefaultNodePath} from '../../containers/Node/NodePages';
7+
import {isUnavailableNode, NodeAddress} from '../../utils/nodes';
8+
9+
import EntityStatus from '../EntityStatus/EntityStatus';
10+
import {NodeEndpointsTooltip} from '../Tooltips/NodeEndpointsTooltip/NodeEndpointsTooltip';
11+
import {IconWrapper} from '../Icon';
12+
13+
import './NodeHostWrapper.scss';
14+
15+
const b = block('ydb-node-host-wrapper');
16+
17+
interface NodeHostWrapperProps {
18+
node: INodesPreparedEntity;
19+
getNodeRef?: (node?: NodeAddress) => string;
20+
}
21+
22+
export const NodeHostWrapper = ({node, getNodeRef}: NodeHostWrapperProps) => {
23+
if (!node.Host) {
24+
return <span></span>;
25+
}
26+
27+
const isNodeAvailable = !isUnavailableNode(node);
28+
const nodeRef = isNodeAvailable && getNodeRef ? getNodeRef(node) + 'internal' : undefined;
29+
30+
return (
31+
<div className={b()}>
32+
<Popover
33+
disabled={!isNodeAvailable}
34+
content={<NodeEndpointsTooltip data={node} />}
35+
placement={['top', 'bottom']}
36+
behavior={PopoverBehavior.Immediate}
37+
>
38+
<div className={b('host-wrapper')}>
39+
<EntityStatus
40+
name={node.Host}
41+
status={node.SystemState}
42+
path={isNodeAvailable ? getDefaultNodePath(node.NodeId) : undefined}
43+
hasClipboardButton
44+
className={b('host')}
45+
/>
46+
{nodeRef && (
47+
<Button
48+
size="s"
49+
href={nodeRef}
50+
className={b('external-button')}
51+
target="_blank"
52+
>
53+
<IconWrapper name="external" />
54+
</Button>
55+
)}
56+
</div>
57+
</Popover>
58+
</div>
59+
);
60+
};

src/containers/Nodes/getNodesColumns.tsx

Lines changed: 7 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,22 @@
1-
import cn from 'bem-cn-lite';
21
import DataTable, {Column} from '@gravity-ui/react-data-table';
3-
import {Button, Popover, PopoverBehavior} from '@gravity-ui/uikit';
2+
import {Popover} from '@gravity-ui/uikit';
43

5-
import {IconWrapper} from '../../components/Icon';
6-
import EntityStatus from '../../components/EntityStatus/EntityStatus';
74
import PoolsGraph from '../../components/PoolsGraph/PoolsGraph';
85
import ProgressViewer from '../../components/ProgressViewer/ProgressViewer';
96
import {TabletsStatistic} from '../../components/TabletsStatistic';
10-
import {NodeEndpointsTooltip} from '../../components/Tooltips/NodeEndpointsTooltip/NodeEndpointsTooltip';
7+
import {NodeHostWrapper} from '../../components/NodeHostWrapper/NodeHostWrapper';
118

9+
import type {NodeAddress} from '../../utils/nodes';
1210
import {formatBytesToGigabyte} from '../../utils/index';
13-
import {INodesPreparedEntity} from '../../types/store/nodes';
14-
import {showTooltip as externalShowTooltip} from '../../store/reducers/tooltip';
15-
16-
import {getDefaultNodePath} from '../Node/NodePages';
17-
18-
import './NodesTable.scss';
1911

20-
const b = cn('ydb-nodes-table');
12+
import type {INodesPreparedEntity} from '../../types/store/nodes';
13+
import {showTooltip as externalShowTooltip} from '../../store/reducers/tooltip';
2114

2215
interface GetNodesColumnsProps {
2316
showTooltip: (...args: Parameters<typeof externalShowTooltip>) => void;
2417
hideTooltip: VoidFunction;
2518
tabletsPath?: string;
26-
getNodeRef?: Function;
19+
getNodeRef?: (node?: NodeAddress) => string;
2720
}
2821

2922
export function getNodesColumns({
@@ -42,39 +35,7 @@ export function getNodesColumns({
4235
{
4336
name: 'Host',
4437
render: ({row}) => {
45-
const nodeRef = getNodeRef ? getNodeRef(row) + 'internal' : undefined;
46-
if (typeof row.Host === 'undefined') {
47-
return <span></span>;
48-
}
49-
return (
50-
<div className={b('host-field-wrapper')}>
51-
<Popover
52-
content={<NodeEndpointsTooltip data={row} />}
53-
placement={['top', 'bottom']}
54-
behavior={PopoverBehavior.Immediate}
55-
>
56-
<div className={b('host-wrapper')}>
57-
<EntityStatus
58-
name={row.Host}
59-
status={row.SystemState}
60-
path={getDefaultNodePath(row.NodeId)}
61-
hasClipboardButton
62-
className={b('host')}
63-
/>
64-
{nodeRef && (
65-
<Button
66-
size="s"
67-
href={nodeRef}
68-
className={b('external-button')}
69-
target="_blank"
70-
>
71-
<IconWrapper name="external" />
72-
</Button>
73-
)}
74-
</div>
75-
</Popover>
76-
</div>
77-
);
38+
return <NodeHostWrapper node={row} getNodeRef={getNodeRef} />;
7839
},
7940
width: '350px',
8041
align: DataTable.LEFT,

src/containers/Storage/StorageNodes/StorageNodes.scss

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,6 @@
2020
margin-right: 0px;
2121
}
2222
}
23-
&__fqdn-field-wrapper {
24-
width: 330px;
25-
}
26-
&__fqdn-wrapper {
27-
display: flex;
28-
align-items: center;
29-
30-
max-width: 330px;
31-
}
32-
&__fqdn {
33-
overflow: hidden;
34-
}
3523

3624
&__group-id {
3725
font-weight: 500;
@@ -40,16 +28,4 @@
4028
&__node_unavailable {
4129
opacity: 0.6;
4230
}
43-
44-
&__external-button {
45-
display: none;
46-
47-
margin-left: 4px;
48-
}
49-
}
50-
51-
.data-table__row:hover {
52-
.global-storage-nodes__external-button {
53-
display: inline-flex;
54-
}
5531
}

src/containers/Storage/StorageNodes/StorageNodes.tsx

Lines changed: 2 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@ import _ from 'lodash';
22
import cn from 'bem-cn-lite';
33

44
import DataTable, {Column, Settings, SortOrder} from '@gravity-ui/react-data-table';
5-
import {Button, Popover, PopoverBehavior} from '@gravity-ui/uikit';
6-
7-
import {NodeEndpointsTooltip} from '../../../components/Tooltips/NodeEndpointsTooltip/NodeEndpointsTooltip';
8-
import EntityStatus from '../../../components/EntityStatus/EntityStatus';
9-
import {IconWrapper} from '../../../components/Icon';
105

116
import {VisibleEntities} from '../../../store/reducers/storage';
127
import {
@@ -15,7 +10,7 @@ import {
1510
NodesUptimeFilterValues,
1611
} from '../../../utils/nodes';
1712

18-
import {getDefaultNodePath} from '../../Node/NodePages';
13+
import {NodeHostWrapper} from '../../../components/NodeHostWrapper/NodeHostWrapper';
1914

2015
import {EmptyFilter} from '../EmptyFilter/EmptyFilter';
2116
import {PDisk} from '../PDisk';
@@ -100,39 +95,7 @@ function StorageNodes({
10095
header: tableColumnsNames[TableColumnsIds.FQDN],
10196
width: 350,
10297
render: ({row}) => {
103-
const nodeRef = getNodeRef ? getNodeRef(row) + 'internal' : undefined;
104-
if (!row.Host) {
105-
return <span></span>;
106-
}
107-
return (
108-
<div className={b('fqdn-field-wrapper')}>
109-
<Popover
110-
content={<NodeEndpointsTooltip data={row} />}
111-
placement={['top', 'bottom']}
112-
behavior={PopoverBehavior.Immediate}
113-
>
114-
<div className={b('fqdn-wrapper')}>
115-
<EntityStatus
116-
name={row.Host}
117-
showStatus={false}
118-
path={getDefaultNodePath(row.NodeId)}
119-
hasClipboardButton
120-
className={b('fqdn')}
121-
/>
122-
{nodeRef && (
123-
<Button
124-
size="s"
125-
href={nodeRef}
126-
className={b('external-button')}
127-
target="_blank"
128-
>
129-
<IconWrapper name="external" />
130-
</Button>
131-
)}
132-
</div>
133-
</Popover>
134-
</div>
135-
);
98+
return <NodeHostWrapper node={row} getNodeRef={getNodeRef} />;
13699
},
137100
align: DataTable.LEFT,
138101
},

src/utils/nodes.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ export const NodesUptimeFilterTitles = {
1515
export const isUnavailableNode = (node: INodesPreparedEntity | TSystemStateInfo) =>
1616
!node.SystemState || node.SystemState === EFlag.Grey;
1717

18+
export type NodeAddress = Pick<TSystemStateInfo, 'Host' | 'Endpoints'>;
19+
1820
export interface AdditionalNodesInfo extends Record<string, unknown> {
19-
getNodeRef?: Function;
21+
getNodeRef?: (node?: NodeAddress) => string;
2022
}

0 commit comments

Comments
 (0)