Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/components/NetworkTable/NetworkTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {Nodes} from '../../containers/Nodes/Nodes';
import type {NodesProps} from '../../containers/Nodes/Nodes';

import {getNetworkTableNodesColumns} from './columns';
import {
NETWORK_DEFAULT_NODES_COLUMNS,
NETWORK_NODES_GROUP_BY_PARAMS,
NETWORK_NODES_TABLE_SELECTED_COLUMNS_KEY,
NETWORK_REQUIRED_NODES_COLUMNS,
} from './constants';

type NetworkWrapperProps = Pick<
NodesProps,
'path' | 'scrollContainerRef' | 'additionalNodesProps' | 'database'
>;

export function NetworkTable({
database,
path,
scrollContainerRef,
additionalNodesProps,
}: NetworkWrapperProps) {
return (
<Nodes
path={path}
database={database}
scrollContainerRef={scrollContainerRef}
withPeerRoleFilter={Boolean(database)}
additionalNodesProps={additionalNodesProps}
columns={getNetworkTableNodesColumns({
database: database,
getNodeRef: additionalNodesProps?.getNodeRef,
})}
defaultColumnsIds={NETWORK_DEFAULT_NODES_COLUMNS}
requiredColumnsIds={NETWORK_REQUIRED_NODES_COLUMNS}
selectedColumnsKey={NETWORK_NODES_TABLE_SELECTED_COLUMNS_KEY}
groupByParams={NETWORK_NODES_GROUP_BY_PARAMS}
/>
);
}
41 changes: 41 additions & 0 deletions src/components/NetworkTable/columns.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type {NodesPreparedEntity} from '../../store/reducers/nodes/types';
import type {Column} from '../../utils/tableUtils/types';
import {
getClockSkewColumn,
getConnectionsColumn,
getCpuColumn,
getDataCenterColumn,
getHostColumn,
getNetworkUtilizationColumn,
getNodeIdColumn,
getPingTimeColumn,
getPoolsColumn,
getRackColumn,
getReceiveThroughputColumn,
getSendThroughputColumn,
getUptimeColumn,
} from '../nodesColumns/columns';
import {isSortableNodesColumn} from '../nodesColumns/constants';
import type {GetNodesColumnsParams} from '../nodesColumns/types';

export function getNetworkTableNodesColumns(params: GetNodesColumnsParams) {
const columns: Column<NodesPreparedEntity>[] = [
getNodeIdColumn(),
getHostColumn(params, {statusForIcon: 'ConnectStatus'}),
getDataCenterColumn(),
getRackColumn(),
getUptimeColumn(),
getCpuColumn(),
getPoolsColumn(),
getConnectionsColumn(),
getNetworkUtilizationColumn(),
getSendThroughputColumn(),
getReceiveThroughputColumn(),
getPingTimeColumn(),
getClockSkewColumn(),
];

return columns.map((column) => {
return {...column, sortable: isSortableNodesColumn(column.name)};
});
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {NodesColumnId} from '../../../../../components/nodesColumns/constants';
import type {NodesGroupByField} from '../../../../../types/api/nodes';
import type {NodesGroupByField} from '../../types/api/nodes';
import type {NodesColumnId} from '../nodesColumns/constants';

export const NETWORK_NODES_TABLE_SELECTED_COLUMNS_KEY = 'networkNodesTableSelectedColumns';

Expand Down
20 changes: 20 additions & 0 deletions src/components/NetworkTable/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {
useNodesHandlerHasWorkingClusterNetworkStats,
useViewerNodesHandlerHasNetworkStats,
} from '../../store/reducers/capabilities/hooks';
import {ENABLE_NETWORK_TABLE_KEY} from '../../utils/constants';
import {useSetting} from '../../utils/hooks';

export function useShouldShowDatabaseNetworkTable() {
const viewerNodesHasNetworkStats = useViewerNodesHandlerHasNetworkStats();
const [networkTableEnabled] = useSetting(ENABLE_NETWORK_TABLE_KEY);

return Boolean(viewerNodesHasNetworkStats && networkTableEnabled);
}

export function useShouldShowClusterNetworkTable() {
const nodesHasWorkingClusterNetworkStats = useNodesHandlerHasWorkingClusterNetworkStats();
const [networkTableEnabled] = useSetting(ENABLE_NETWORK_TABLE_KEY);

return Boolean(nodesHasWorkingClusterNetworkStats && networkTableEnabled);
}
39 changes: 35 additions & 4 deletions src/containers/Cluster/Cluster.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ import {AutoRefreshControl} from '../../components/AutoRefreshControl/AutoRefres
import {EntityStatus} from '../../components/EntityStatusNew/EntityStatus';
import {EFlagToDescription} from '../../components/EntityStatusNew/utils';
import {InternalLink} from '../../components/InternalLink';
import {NetworkTable} from '../../components/NetworkTable/NetworkTable';
import {useShouldShowClusterNetworkTable} from '../../components/NetworkTable/hooks';
import routes, {getLocationObjectFromHref} from '../../routes';
import {useClusterDashboardAvailable} from '../../store/reducers/capabilities/hooks';
import {
INITIAL_DEFAULT_CLUSTER_TAB,
clusterApi,
selectClusterTabletsWithFqdn,
selectClusterTitle,
Expand Down Expand Up @@ -55,6 +58,8 @@ export function Cluster({
const container = React.useRef<HTMLDivElement>(null);
const isClusterDashboardAvailable = useClusterDashboardAvailable();

const shouldShowNetworkTable = useShouldShowClusterNetworkTable();

const [autoRefreshInterval] = useAutoRefreshInterval();

const dispatch = useTypedDispatch();
Expand Down Expand Up @@ -92,6 +97,14 @@ export function Cluster({
dispatch(setHeaderBreadcrumbs('cluster', {}));
}, [dispatch]);

const actualClusterTabs = React.useMemo(() => {
if (shouldShowNetworkTable) {
return clusterTabs;
} else {
return clusterTabs.filter((tab) => tab.id !== clusterTabsIds.network);
}
}, [shouldShowNetworkTable]);

const getClusterTitle = () => {
if (infoLoading) {
return <Skeleton className={b('title-skeleton')} />;
Expand All @@ -110,8 +123,8 @@ export function Cluster({
};

const activeTab = React.useMemo(
() => clusterTabs.find(({id}) => id === activeTabId),
[activeTabId],
() => actualClusterTabs.find(({id}) => id === activeTabId),
[activeTabId, actualClusterTabs],
);

return (
Expand Down Expand Up @@ -142,7 +155,7 @@ export function Cluster({
size="l"
allowNotSelected={true}
activeTab={activeTabId}
items={clusterTabs}
items={actualClusterTabs}
wrapTo={({id}, node) => {
const path = getClusterPath(id as ClusterTab, {clusterName, backend});
return (
Expand Down Expand Up @@ -202,6 +215,19 @@ export function Cluster({
>
<PaginatedStorage scrollContainerRef={container} />
</Route>
{shouldShowNetworkTable && (
<Route
path={
getLocationObjectFromHref(getClusterPath(clusterTabsIds.network))
.pathname
}
>
<NetworkTable
scrollContainerRef={container}
additionalNodesProps={additionalNodesProps}
/>
</Route>
)}
<Route
path={
getLocationObjectFromHref(getClusterPath(clusterTabsIds.versions))
Expand All @@ -226,11 +252,16 @@ function useClusterTab() {

const defaultTab = useTypedSelector((state) => state.cluster.defaultClusterTab);

const shouldShowNetworkTable = useShouldShowClusterNetworkTable();

const match = useRouteMatch<{activeTab: string}>(routes.cluster);

const {activeTab: activeTabFromParams} = match?.params || {};
let activeTab: ClusterTab;
if (isClusterTab(activeTabFromParams)) {

if (!shouldShowNetworkTable && activeTabFromParams === clusterTabsIds.network) {
activeTab = INITIAL_DEFAULT_CLUSTER_TAB;
} else if (isClusterTab(activeTabFromParams)) {
activeTab = activeTabFromParams;
} else {
activeTab = defaultTab;
Expand Down
7 changes: 6 additions & 1 deletion src/containers/Cluster/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const clusterTabsIds = {
tenants: 'tenants',
nodes: 'nodes',
storage: 'storage',
network: 'network',
versions: 'versions',
tablets: 'tablets',
} as const;
Expand All @@ -25,6 +26,10 @@ const storage = {
id: clusterTabsIds.storage,
title: 'Storage',
};
const network = {
id: clusterTabsIds.network,
title: 'Network',
};
const versions = {
id: clusterTabsIds.versions,
title: 'Versions',
Expand All @@ -34,7 +39,7 @@ const tablets = {
title: 'Tablets',
};

export const clusterTabs = [tenants, nodes, storage, tablets, versions];
export const clusterTabs = [tenants, nodes, storage, network, tablets, versions];

export function isClusterTab(tab: any): tab is ClusterTab {
return Object.values(clusterTabsIds).includes(tab);
Expand Down

This file was deleted.

33 changes: 5 additions & 28 deletions src/containers/Tenant/Diagnostics/Network/NetworkWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,10 @@
import {LoaderWrapper} from '../../../../components/LoaderWrapper/LoaderWrapper';
import {
useCapabilitiesLoaded,
useViewerNodesHandlerHasNetworkStats,
} from '../../../../store/reducers/capabilities/hooks';
import {ENABLE_NETWORK_TABLE_KEY} from '../../../../utils/constants';
import {useSetting} from '../../../../utils/hooks';
import {NetworkTable} from '../../../../components/NetworkTable/NetworkTable';
import {useShouldShowDatabaseNetworkTable} from '../../../../components/NetworkTable/hooks';
import {useCapabilitiesLoaded} from '../../../../store/reducers/capabilities/hooks';
import type {NodesProps} from '../../../Nodes/Nodes';
import {Nodes} from '../../../Nodes/Nodes';

import {Network} from './Network';
import {getNetworkTableNodesColumns} from './NetworkTable/columns';
import {
NETWORK_DEFAULT_NODES_COLUMNS,
NETWORK_NODES_GROUP_BY_PARAMS,
NETWORK_NODES_TABLE_SELECTED_COLUMNS_KEY,
NETWORK_REQUIRED_NODES_COLUMNS,
} from './NetworkTable/constants';

interface NetworkWrapperProps
extends Pick<NodesProps, 'path' | 'scrollContainerRef' | 'additionalNodesProps'> {
Expand All @@ -29,28 +18,16 @@ export function NetworkWrapper({
additionalNodesProps,
}: NetworkWrapperProps) {
const capabilitiesLoaded = useCapabilitiesLoaded();
const viewerNodesHasNetworkStats = useViewerNodesHandlerHasNetworkStats();
const [networkTableEnabled] = useSetting(ENABLE_NETWORK_TABLE_KEY);

const shouldUseNetworkNodesTable = viewerNodesHasNetworkStats && networkTableEnabled;
const shouldUseNetworkNodesTable = useShouldShowDatabaseNetworkTable();

const renderContent = () => {
if (shouldUseNetworkNodesTable) {
return (
<Nodes
<NetworkTable
path={path}
database={database}
scrollContainerRef={scrollContainerRef}
withPeerRoleFilter
additionalNodesProps={additionalNodesProps}
columns={getNetworkTableNodesColumns({
database: database,
getNodeRef: additionalNodesProps?.getNodeRef,
})}
defaultColumnsIds={NETWORK_DEFAULT_NODES_COLUMNS}
requiredColumnsIds={NETWORK_REQUIRED_NODES_COLUMNS}
selectedColumnsKey={NETWORK_NODES_TABLE_SELECTED_COLUMNS_KEY}
groupByParams={NETWORK_NODES_GROUP_BY_PARAMS}
/>
);
}
Expand Down
7 changes: 7 additions & 0 deletions src/store/reducers/capabilities/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ export const useViewerNodesHandlerHasNetworkStats = () => {
return useGetFeatureVersion('/viewer/nodes') > 13;
};

// Before this version handler has very big response size if nodes quantity is more than 100
// Response size could be up to 20-30MB, it loads very long and freezes UI
// It is not very common for databases, but an ofter case for clusters
export const useNodesHandlerHasWorkingClusterNetworkStats = () => {
return useGetFeatureVersion('/viewer/nodes') >= 16;
};

export const useFeatureFlagsAvailable = () => {
return useGetFeatureVersion('/viewer/feature_flags') > 1;
};
Expand Down
4 changes: 3 additions & 1 deletion src/store/reducers/cluster/cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ import {
parseGroupsStatsQueryResponse,
} from './utils';

export const INITIAL_DEFAULT_CLUSTER_TAB = clusterTabsIds.tenants;

const defaultClusterTabLS = localStorage.getItem(DEFAULT_CLUSTER_TAB_KEY);

let defaultClusterTab: ClusterTab;
if (isClusterTab(defaultClusterTabLS)) {
defaultClusterTab = defaultClusterTabLS;
} else {
defaultClusterTab = clusterTabsIds.tenants;
defaultClusterTab = INITIAL_DEFAULT_CLUSTER_TAB;
}

const initialState: ClusterState = {
Expand Down
Loading