Skip to content

Commit ad96cb8

Browse files
authored
fix(ui): overlapping UI elements and add resource units to tooltips (#24717)
Signed-off-by: choejwoo <[email protected]>
1 parent 541a154 commit ad96cb8

File tree

4 files changed

+97
-23
lines changed

4 files changed

+97
-23
lines changed

ui/src/app/applications/components/application-pod-view/pod-tooltip.tsx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import * as React from 'react';
22
import Moment from 'react-moment';
33
import {Pod, ResourceName} from '../../../shared/models';
4-
import {isYoungerThanXMinutes} from '../utils';
5-
import {formatMetric} from './pod-view';
4+
import {isYoungerThanXMinutes, formatResourceInfo} from '../utils';
65

76
export const PodTooltip = (props: {pod: Pod}) => {
87
const pod = props.pod;
@@ -23,10 +22,20 @@ export const PodTooltip = (props: {pod: Pod}) => {
2322
})
2423
.map(i => {
2524
const isPodRequests = i.name === ResourceName.ResourceCPU || i.name === ResourceName.ResourceMemory;
26-
const formattedValue = isPodRequests ? formatMetric(i.name as ResourceName, parseInt(i.value, 10)) : i.value;
25+
let formattedValue = i.value;
26+
let label = `${i.name}:`;
2727

28-
//this is just to show cpu and mem info with "Requests" as prefix
29-
const label = i.name === ResourceName.ResourceCPU ? 'Requests CPU:' : i.name === ResourceName.ResourceMemory ? 'Requests MEM:' : `${i.name}:`;
28+
if (isPodRequests) {
29+
if (i.name === ResourceName.ResourceCPU) {
30+
const {displayValue} = formatResourceInfo('cpu', i.value);
31+
formattedValue = displayValue;
32+
label = 'Requests CPU:';
33+
} else if (i.name === ResourceName.ResourceMemory) {
34+
const {displayValue} = formatResourceInfo('memory', i.value);
35+
formattedValue = displayValue;
36+
label = 'Requests MEM:';
37+
}
38+
}
3039

3140
return (
3241
<div className='row' key={i.name}>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
position: absolute;
2121
color: #A3A3A3;
2222
font-size: 10px;
23-
top: -10px;
23+
top: -9px;
2424
transform: rotate(180deg);
2525
}
2626
}

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

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ import {
2424
PodHealthIcon,
2525
getUsrMsgKeyToDisplay,
2626
getApplicationLinkURLFromNode,
27-
getManagedByURLFromNode
27+
getManagedByURLFromNode,
28+
formatResourceInfo
2829
} from '../utils';
2930
import {NodeUpdateAnimation} from './node-update-animation';
3031
import {PodGroup} from '../application-pod-view/pod-view';
@@ -543,11 +544,19 @@ function renderPodGroup(props: ApplicationResourceTreeProps, id: string, node: R
543544
<Tooltip
544545
content={
545546
<>
546-
{(node.info || []).map(i => (
547-
<div key={i.name}>
548-
{i.name}: {i.value}
549-
</div>
550-
))}
547+
{(node.info || []).map(i => {
548+
// Use common formatting function for CPU and Memory
549+
if (i.name === 'cpu' || i.name === 'memory') {
550+
const {tooltipValue} = formatResourceInfo(i.name, `${i.value}`);
551+
return <div key={i.name}>{tooltipValue}</div>;
552+
} else {
553+
return (
554+
<div key={i.name}>
555+
{i.name}: {i.value}
556+
</div>
557+
);
558+
}
559+
})}
551560
</>
552561
}
553562
key={node.uid}>
@@ -675,9 +684,9 @@ function expandCollapse(node: ResourceTreeNode, props: ApplicationResourceTreePr
675684

676685
function NodeInfoDetails({tag: tag, kind: kind}: {tag: models.InfoItem; kind: string}) {
677686
if (kind === 'Pod') {
678-
const val = `${tag.name}`;
687+
const val = tag.name;
679688
if (val === 'Status Reason') {
680-
if (`${tag.value}` !== 'ImagePullBackOff')
689+
if (String(tag.value) !== 'ImagePullBackOff')
681690
return (
682691
<span className='application-resource-tree__node-label' title={`Status: ${tag.value}`}>
683692
{tag.value}
@@ -693,10 +702,10 @@ function NodeInfoDetails({tag: tag, kind: kind}: {tag: models.InfoItem; kind: st
693702
);
694703
}
695704
} else if (val === 'Containers') {
696-
const arr = `${tag.value}`.split('/');
705+
const arr = String(tag.value).split('/');
697706
const title = `Number of containers in total: ${arr[1]} \nNumber of ready containers: ${arr[0]}`;
698707
return (
699-
<span className='application-resource-tree__node-label' title={`${title}`}>
708+
<span className='application-resource-tree__node-label' title={title}>
700709
{tag.value}
701710
</span>
702711
);
@@ -712,6 +721,14 @@ function NodeInfoDetails({tag: tag, kind: kind}: {tag: models.InfoItem; kind: st
712721
{tag.value}
713722
</span>
714723
);
724+
} else if (val === 'cpu' || val === 'memory') {
725+
// Use common formatting function for CPU and Memory
726+
const {displayValue, tooltipValue} = formatResourceInfo(val, String(tag.value));
727+
return (
728+
<span className='application-resource-tree__node-label' title={tooltipValue}>
729+
{displayValue}
730+
</span>
731+
);
715732
} else {
716733
return (
717734
<span className='application-resource-tree__node-label' title={`${tag.name}: ${tag.value}`}>
@@ -825,19 +842,27 @@ function renderResourceNode(props: ApplicationResourceTreeProps, id: string, nod
825842
) : null}
826843
{(node.info || [])
827844
.filter(tag => !tag.name.includes('Node') && tag.name !== 'managed-by-url')
828-
.slice(0, 4)
845+
.slice(0, 2)
829846
.map((tag, i) => {
830847
return <NodeInfoDetails tag={tag} kind={node.kind} key={i} />;
831848
})}
832-
{(node.info || []).length > 4 && (
849+
{(node.info || []).length > 3 && (
833850
<Tooltip
834851
content={
835852
<>
836-
{(node.info || []).map(i => (
837-
<div key={i.name}>
838-
{i.name}: {i.value}
839-
</div>
840-
))}
853+
{(node.info || []).map(i => {
854+
// Use common formatting function for CPU and Memory
855+
if (i.name === 'cpu' || i.name === 'memory') {
856+
const {tooltipValue} = formatResourceInfo(i.name, `${i.value}`);
857+
return <div key={i.name}>{tooltipValue}</div>;
858+
} else {
859+
return (
860+
<div key={i.name}>
861+
{i.name}: {i.value}
862+
</div>
863+
);
864+
}
865+
})}
841866
</>
842867
}
843868
key={node.uid}>

ui/src/app/applications/components/utils.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1859,3 +1859,43 @@ export function getApplicationLinkURLFromNode(node: any, baseHref: string): {url
18591859
}
18601860
return {url, isExternal};
18611861
}
1862+
1863+
export function formatResourceInfo(name: string, value: string): {displayValue: string; tooltipValue: string} {
1864+
const numValue = parseInt(value, 10);
1865+
1866+
const formatCPUValue = (milliCpu: number): string => {
1867+
return milliCpu >= 1000 ? `${(milliCpu / 1000).toFixed(1)}` : `${milliCpu}m`;
1868+
};
1869+
1870+
const formatMemoryValue = (milliBytes: number): string => {
1871+
const mib = Math.round(milliBytes / (1024 * 1024 * 1000));
1872+
return `${mib}Mi`;
1873+
};
1874+
1875+
const formatCPUTooltip = (milliCpu: number): string => {
1876+
const displayValue = milliCpu >= 1000 ? `${(milliCpu / 1000).toFixed(1)} cores` : `${milliCpu}m`;
1877+
return `CPU Request: ${displayValue}`;
1878+
};
1879+
1880+
const formatMemoryTooltip = (milliBytes: number): string => {
1881+
const mib = Math.round(milliBytes / (1024 * 1024 * 1000));
1882+
return `Memory Request: ${mib}Mi`;
1883+
};
1884+
1885+
if (name === 'cpu') {
1886+
return {
1887+
displayValue: formatCPUValue(numValue),
1888+
tooltipValue: formatCPUTooltip(numValue)
1889+
};
1890+
} else if (name === 'memory') {
1891+
return {
1892+
displayValue: formatMemoryValue(numValue),
1893+
tooltipValue: formatMemoryTooltip(numValue)
1894+
};
1895+
}
1896+
1897+
return {
1898+
displayValue: value,
1899+
tooltipValue: `${name}: ${value}`
1900+
};
1901+
}

0 commit comments

Comments
 (0)