Skip to content

Commit b6a715c

Browse files
authored
fix(ui): prevent wide gaps in grouped resource tree (#25747)
Signed-off-by: choejwoo <jaewoo45@gmail.com>
1 parent 4b69a7f commit b6a715c

2 files changed

Lines changed: 45 additions & 20 deletions

File tree

ui/src/app/applications/components/application-resource-tree/application-resource-tree.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959

6060
$pod-size: 25px;
6161
$gutter: 3px;
62+
// Keep in sync with `POD_GROUP_PODS_PER_ROW` in `application-resource-tree.tsx`.
6263
$pods-per-row: 8;
6364
$pods-per-column: 4;
6465
$max-rows: 5;

ui/src/app/applications/components/application-resource-tree/application-resource-tree.tsx

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ interface Line {
8888
const NODE_WIDTH = 282;
8989
const NODE_HEIGHT = 52;
9090
const POD_NODE_HEIGHT = 136;
91+
const POD_GROUP_ROW_HEIGHT = 20;
92+
// Keep in sync with `$pods-per-row` in `application-resource-tree.scss`.
93+
const POD_GROUP_PODS_PER_ROW = 8;
9194
const FILTERED_INDICATOR_NODE = '__filtered_indicator__';
9295
const EXTERNAL_TRAFFIC_NODE = '__external_traffic__';
9396
const INTERNAL_TRAFFIC_NODE = '__internal_traffic__';
@@ -400,11 +403,31 @@ function processPodGroup(targetPodGroup: ResourceTreeNode, child: ResourceTreeNo
400403
}
401404
}
402405

406+
function getPodGroupNumberOfRows(pods: models.Pod[], showPodGroupByStatus: boolean) {
407+
if (!pods || pods.length === 0) {
408+
return 0;
409+
}
410+
if (showPodGroupByStatus) {
411+
const statuses = new Set<string>();
412+
for (const pod of pods) {
413+
if (!pod) {
414+
continue;
415+
}
416+
const health = pod.health;
417+
if (health === 'Healthy' || health === 'Degraded' || health === 'Progressing') {
418+
statuses.add(health);
419+
}
420+
}
421+
return statuses.size;
422+
}
423+
return Math.ceil(pods.length / POD_GROUP_PODS_PER_ROW);
424+
}
425+
403426
function renderPodGroup(
404427
props: ApplicationResourceTreeProps,
405-
id: string,
406428
node: ResourceTreeNode & dagre.Node & {groupedNodeIds?: string[]},
407-
childMap: Map<string, ResourceTreeNode[]>
429+
childMap: Map<string, ResourceTreeNode[]>,
430+
showPodGroupByStatus: boolean
408431
) {
409432
const fullName = nodeKey(node);
410433
let comparisonStatus: models.SyncStatusCode = null;
@@ -424,8 +447,6 @@ function renderPodGroup(
424447
return acc;
425448
}, []);
426449
const childCount = nonPodChildren?.length;
427-
const margin = 8;
428-
let topExtra = 0;
429450
const podGroup = node.podGroup;
430451
const podGroupHealthy = [];
431452
const podGroupDegraded = [];
@@ -444,14 +465,10 @@ function renderPodGroup(
444465
}
445466
}
446467

447-
const showPodGroupByStatus = props.tree.nodes.filter((rNode: ResourceTreeNode) => rNode.kind === 'Pod').length >= props.podGroupCount;
448-
const numberOfRows = showPodGroupByStatus
449-
? [podGroupHealthy, podGroupDegraded, podGroupInProgress].reduce((total, podGroupByStatus) => total + (podGroupByStatus.filter(pod => pod).length > 0 ? 1 : 0), 0)
450-
: Math.ceil(podGroup?.pods.length / 8);
451-
452-
if (podGroup) {
453-
topExtra = margin + (POD_NODE_HEIGHT / 2 + 30 * numberOfRows) / 2;
454-
}
468+
// Use Dagre's measured height directly to avoid duplicating sizing logic in the render path.
469+
// Dagre assigns node.y as the node center; convert to DOM top-left for rendering.
470+
const podGroupHeight = node.height;
471+
const podGroupTop = node.y - podGroupHeight / 2;
455472

456473
return (
457474
<div
@@ -463,9 +480,9 @@ function renderPodGroup(
463480
title={describeNode(node)}
464481
style={{
465482
left: node.x,
466-
top: node.y - topExtra,
483+
top: podGroupTop,
467484
width: node.width,
468-
height: showPodGroupByStatus ? POD_NODE_HEIGHT + 20 * numberOfRows : node.height
485+
height: podGroupHeight
469486
}}>
470487
<NodeUpdateAnimation resourceVersion={node.resourceVersion} />
471488
<div onClick={() => props.onNodeClick && props.onNodeClick(fullName)} className={`application-resource-tree__node__top-part`}>
@@ -537,7 +554,7 @@ function renderPodGroup(
537554
<>
538555
<br />
539556
<div
540-
style={{top: node.height / 2 - 6}}
557+
style={{top: podGroupHeight / 2 - 6}}
541558
className='application-resource-tree__node--podgroup--expansion'
542559
onClick={event => {
543560
expandCollapse(node, props);
@@ -767,7 +784,7 @@ function NodeInfoDetails({tag: tag, kind: kind}: {tag: models.InfoItem; kind: st
767784
}
768785
}
769786

770-
function renderResourceNode(props: ApplicationResourceTreeProps, id: string, node: ResourceTreeNode & dagre.Node, nodesHavingChildren: Map<string, number>) {
787+
function renderResourceNode(props: ApplicationResourceTreeProps, node: ResourceTreeNode & dagre.Node, nodesHavingChildren: Map<string, number>) {
771788
const fullName = nodeKey(node);
772789
let comparisonStatus: models.SyncStatusCode = null;
773790
let healthState: models.HealthStatus = null;
@@ -1019,6 +1036,7 @@ export const ApplicationResourceTree = (props: ApplicationResourceTreeProps) =>
10191036
}, [props.filters]);
10201037
const {podGroupCount, userMsgs, updateUsrHelpTipMsgs, setShowCompactNodes} = props;
10211038
const podCount = nodes.filter(node => node.kind === 'Pod').length;
1039+
const showPodGroupByStatus = props.tree.nodes.filter((rNode: ResourceTreeNode) => rNode.kind === 'Pod').length >= props.podGroupCount;
10221040

10231041
React.useEffect(() => {
10241042
if (podCount > podGroupCount) {
@@ -1238,8 +1256,14 @@ export const ApplicationResourceTree = (props: ApplicationResourceTreeProps) =>
12381256
}
12391257

12401258
function setPodGroupNode(node: ResourceTreeNode, root: ResourceTreeNode) {
1241-
const numberOfRows = Math.ceil(node.podGroup.pods.length / 8);
1242-
graph.setNode(treeNodeKey(node), {...node, type: NODE_TYPES.podGroup, width: NODE_WIDTH, height: POD_NODE_HEIGHT + 30 * numberOfRows, root});
1259+
const numberOfRows = getPodGroupNumberOfRows(node.podGroup?.pods, showPodGroupByStatus);
1260+
graph.setNode(treeNodeKey(node), {
1261+
...node,
1262+
type: NODE_TYPES.podGroup,
1263+
width: NODE_WIDTH,
1264+
height: POD_NODE_HEIGHT + POD_GROUP_ROW_HEIGHT * numberOfRows,
1265+
root
1266+
});
12431267
}
12441268

12451269
function processNode(node: ResourceTreeNode, root: ResourceTreeNode, colors?: string[]) {
@@ -1410,9 +1434,9 @@ export const ApplicationResourceTree = (props: ApplicationResourceTreeProps) =>
14101434
case NODE_TYPES.groupedNodes:
14111435
return <React.Fragment key={key}>{renderGroupedNodes(props, node as any)}</React.Fragment>;
14121436
case NODE_TYPES.podGroup:
1413-
return <React.Fragment key={key}>{renderPodGroup(props, key, node as ResourceTreeNode & dagre.Node, childrenMap)}</React.Fragment>;
1437+
return <React.Fragment key={key}>{renderPodGroup(props, node as ResourceTreeNode & dagre.Node, childrenMap, showPodGroupByStatus)}</React.Fragment>;
14141438
default:
1415-
return <React.Fragment key={key}>{renderResourceNode(props, key, node as ResourceTreeNode & dagre.Node, nodesHavingChildren)}</React.Fragment>;
1439+
return <React.Fragment key={key}>{renderResourceNode(props, node as ResourceTreeNode & dagre.Node, nodesHavingChildren)}</React.Fragment>;
14161440
}
14171441
})}
14181442
{edges.map(edge => (

0 commit comments

Comments
 (0)