Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
38 changes: 16 additions & 22 deletions frontend/src/components/treeView/TreeViewNodes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Position, MarkerType } from 'reactflow';
import { NodeLabel } from '../wds_topology/NodeLabel';
import useTheme from '../../stores/themeStore';
import useLabelHighlightStore from '../../stores/labelHighlightStore';
import useZoomStore from '../../stores/zoomStore';
import useEdgeTypeStore from '../../stores/edgeTypeStore';
import { CustomNode, ResourceItem, CustomEdge } from './types';
import ConfigMap from '../../assets/k8s_resources_logo/cm.svg';
Expand Down Expand Up @@ -49,7 +48,17 @@ interface TreeViewNodesProps {
isExpanded: boolean;
}

// Node styling is now handled dynamically through the zoom store
// TreeView node dimensions
export const TREE_VIEW_NODE_WIDTH = 146;
export const TREE_VIEW_NODE_HEIGHT = 30;

// Fixed node style - shared across all node creation and updates
const FIXED_NODE_STYLE = {
padding: '2px 12px',
fontSize: '12px',
width: `${TREE_VIEW_NODE_WIDTH}px`,
height: `${TREE_VIEW_NODE_HEIGHT}px`,
} as const;

const iconMap: Record<string, string> = {
ConfigMap: ConfigMap,
Expand Down Expand Up @@ -253,7 +262,6 @@ const getTimeAgo = (timestamp: string | undefined, t: (key: string) => string):
export const useTreeViewNodes = ({ onNodeSelect, onMenuOpen, isExpanded }: TreeViewNodesProps) => {
const theme = useTheme(state => state.theme);
const highlightedLabels = useLabelHighlightStore(state => state.highlightedLabels);
const { currentZoom, getScaledNodeStyle } = useZoomStore();
const nodeCache = useRef<Map<string, CustomNode>>(new Map());
const edgeIdCounter = useRef<number>(0);
const { edgeType } = useEdgeTypeStore();
Expand Down Expand Up @@ -285,9 +293,6 @@ export const useTreeViewNodes = ({ onNodeSelect, onMenuOpen, isExpanded }: TreeV
resourceData?.metadata?.labels &&
resourceData.metadata.labels[highlightedLabels.key] === highlightedLabels.value;

// Get dynamically scaled node style
const scaledNodeStyle = getScaledNodeStyle(currentZoom);

const node =
cachedNode ||
({
Expand Down Expand Up @@ -331,7 +336,7 @@ export const useTreeViewNodes = ({ onNodeSelect, onMenuOpen, isExpanded }: TreeV
},
position: { x: 0, y: 0 },
style: {
...scaledNodeStyle,
...FIXED_NODE_STYLE,
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
Expand Down Expand Up @@ -366,7 +371,7 @@ export const useTreeViewNodes = ({ onNodeSelect, onMenuOpen, isExpanded }: TreeV
// If the node is already cached but highlighting changed, update style
if (cachedNode) {
node.style = {
...scaledNodeStyle,
...FIXED_NODE_STYLE,
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
Expand Down Expand Up @@ -451,16 +456,7 @@ export const useTreeViewNodes = ({ onNodeSelect, onMenuOpen, isExpanded }: TreeV
newEdges.push(edge);
}
},
[
theme,
isExpanded,
highlightedLabels,
onNodeSelect,
onMenuOpen,
currentZoom,
getScaledNodeStyle,
edgeType,
]
[theme, isExpanded, highlightedLabels, onNodeSelect, onMenuOpen, edgeType]
);

const clearNodeCache = useCallback(() => {
Expand All @@ -478,10 +474,8 @@ export const useTreeViewNodes = ({ onNodeSelect, onMenuOpen, isExpanded }: TreeV
highlightedLabels &&
resourceData.metadata.labels[highlightedLabels.key] === highlightedLabels.value;

const scaledNodeStyle = getScaledNodeStyle(currentZoom);

const newStyle = {
...scaledNodeStyle,
...FIXED_NODE_STYLE,
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
Expand Down Expand Up @@ -518,7 +512,7 @@ export const useTreeViewNodes = ({ onNodeSelect, onMenuOpen, isExpanded }: TreeV
};
});
},
[theme, highlightedLabels, currentZoom, getScaledNodeStyle]
[theme, highlightedLabels]
);

return {
Expand Down
20 changes: 9 additions & 11 deletions frontend/src/components/treeView/hooks/useTreeViewData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@ import { useLocation } from 'react-router-dom';
import * as dagre from 'dagre';
import { isEqual } from 'lodash';
import useTheme from '../../../stores/themeStore';
import useZoomStore from '../../../stores/zoomStore';
import {
NamespaceResource,
CustomNode,
CustomEdge,
ResourceItem,
ResourceDataChangeEvent,
} from '../types';
import { useTreeViewNodes } from '../TreeViewNodes';
import { useTreeViewNodes, TREE_VIEW_NODE_WIDTH, TREE_VIEW_NODE_HEIGHT } from '../TreeViewNodes';
import { useTreeViewEdges } from '../TreeViewEdges';

interface UseTreeViewDataProps {
Expand Down Expand Up @@ -124,15 +123,15 @@ export const useTreeViewData = ({

const getLayoutedElements = useCallback(
(nodes: CustomNode[], edges: CustomEdge[], direction = 'LR') => {
const { currentZoom } = useZoomStore.getState();
const scaleFactor = Math.max(0.5, Math.min(2.0, currentZoom));
const NODE_WIDTH = TREE_VIEW_NODE_WIDTH;
const NODE_HEIGHT = TREE_VIEW_NODE_HEIGHT;

const dagreGraph = new dagre.graphlib.Graph();
dagreGraph.setDefaultEdgeLabel(() => ({}));
dagreGraph.setGraph({
rankdir: direction,
nodesep: 50 * scaleFactor, // Increased from 30
ranksep: 130 * scaleFactor, // Increased from 60
nodesep: 50,
ranksep: 130,
});

const nodeMap = new Map<string, CustomNode>();
Expand All @@ -147,8 +146,8 @@ export const useTreeViewData = ({
const cachedNode = nodeMap.get(node.id);
if (!cachedNode || !isEqual(cachedNode, node) || shouldRecalculate) {
dagreGraph.setNode(node.id, {
width: 146 * scaleFactor,
height: 30 * scaleFactor, // Match the actual node height from zoom store
width: NODE_WIDTH,
height: NODE_HEIGHT,
});
newNodes.push(node);
} else {
Expand All @@ -168,16 +167,15 @@ export const useTreeViewData = ({
? {
...node,
position: {
x: dagreNode.x - 73 * scaleFactor + 50 * scaleFactor,
y: dagreNode.y - 15 * scaleFactor + 50 * scaleFactor, // This is correct: 30/2 = 15
x: dagreNode.x - NODE_WIDTH / 2 + 50,
y: dagreNode.y - NODE_HEIGHT / 2 + 50,
},
}
: node;
});

return { nodes: layoutedNodes, edges };
},
// Include dependencies for useZoomStore.getState() and any other external values
[prevNodes]
);

Expand Down
29 changes: 10 additions & 19 deletions frontend/src/components/wds_topology/NodeLabel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,10 @@ export const NodeLabel = memo<NodeLabelProps>(
margin: '-12px -16px',
padding: '12px 16px',
borderRadius: '16px',
minWidth: `${Math.max(200, iconSize + 150)}px`, // Minimum width based on zoom
maxWidth: `${Math.max(320, iconSize + 250)}px`, // Maximum width to prevent excessive stretching
minWidth: '200px',
maxWidth: '320px',
width: 'calc(100% + 32px)',
minHeight: `${Math.max(48, iconSize + 24)}px`, // Minimum height for consistency
minHeight: '48px',
background:
theme === 'dark'
? hasHighlightedLabel
Expand Down Expand Up @@ -217,16 +217,7 @@ export const NodeLabel = memo<NodeLabelProps>(
overflow: 'hidden', // Prevent any content from escaping
overflowWrap: 'break-word' as const, // Handle any edge cases
}),
[
theme,
hasHighlightedLabel,
hasLabels,
statusStyle,
isHovered,
status,
prefersReducedMotion,
iconSize,
]
[theme, hasHighlightedLabel, hasLabels, statusStyle, isHovered, status, prefersReducedMotion]
);

const labelTooltipContent = hasLabels ? (
Expand Down Expand Up @@ -418,8 +409,8 @@ export const NodeLabel = memo<NodeLabelProps>(
{/* Icon section with status indicator - improved responsiveness */}
<div
style={{
width: `${Math.max(70, Math.min(90, iconSize + 50))}px`,
minWidth: `${Math.max(70, Math.min(90, iconSize + 50))}px`,
width: '80px',
minWidth: '80px',
display: 'flex',
alignItems: 'center',
gap: '6px',
Expand Down Expand Up @@ -480,8 +471,8 @@ export const NodeLabel = memo<NodeLabelProps>(
: 'none',
backgroundSize: '200% 200%',
flex: 1,
minWidth: 0, // Allow shrinking
maxWidth: `${Math.max(30, 60 - iconSize / 2)}px`, // Dynamic max width
minWidth: 0,
maxWidth: '40px',
}}
>
{dynamicText}
Expand All @@ -496,8 +487,8 @@ export const NodeLabel = memo<NodeLabelProps>(
justifyContent: 'center',
gap: '2px',
flex: 1,
minWidth: 0, // Allows flex child to shrink below content size
maxWidth: `${Math.max(120, 200 - iconSize)}px`, // Responsive max width
minWidth: 0,
maxWidth: '140px',
}}
>
<Tooltip
Expand Down
Loading