fix: resolve bugs in ServicesPage, NodesPage, and k8s helpers

- Add missing useEffect dependency array and useCallback for closePanel
- Fix invalid StatusLabel status="" to "info" for non-kube-vip services
- Add ARIA dialog attributes to service detail panel
- Use phaseToStatus() in NodesPage instead of hardcoded Running check
- Remove dead code in getNodeVipLabel (label keys never contain =)
- Simplify redundant lease lookup in OverviewPage
- Fix 46 ESLint indentation warnings
- Add CHANGELOG.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
DevContainer User
2026-03-04 12:43:23 +00:00
parent aa676e8300
commit f26d1414b2
8 changed files with 113 additions and 70 deletions
+17 -10
View File
@@ -13,7 +13,7 @@ import {
SimpleTable,
StatusLabel,
} from '@kinvolk/headlamp-plugin/lib/CommonComponents';
import React, { useEffect } from 'react';
import React, { useCallback, useEffect } from 'react';
import { useHistory, useLocation } from 'react-router-dom';
import {
formatAge,
@@ -38,7 +38,10 @@ export default function ServicesPage() {
? loadBalancerServices.find(s => `${s.metadata.namespace}/${s.metadata.name}` === selectedName)
: null;
const closePanel = () => history.push(location.pathname);
const closePanel = useCallback(
() => history.push(location.pathname),
[history, location.pathname]
);
useEffect(() => {
if (!selectedName) return;
@@ -47,7 +50,7 @@ export default function ServicesPage() {
};
window.addEventListener('keydown', handler);
return () => window.removeEventListener('keydown', handler);
});
}, [selectedName, closePanel]);
if (loading) {
return <Loader title="Loading services..." />;
@@ -111,7 +114,7 @@ export default function ServicesPage() {
{
label: 'kube-vip',
getter: s => (
<StatusLabel status={isKubeVipService(s) ? 'success' : ''}>
<StatusLabel status={isKubeVipService(s) ? 'success' : 'info'}>
{isKubeVipService(s) ? 'Yes' : '—'}
</StatusLabel>
),
@@ -130,8 +133,9 @@ export default function ServicesPage() {
{selectedService && (
<>
<div
role="presentation"
data-testid="panel-backdrop"
onClick={closePanel}
aria-label="Close panel backdrop"
style={{
position: 'fixed',
top: 0,
@@ -165,6 +169,9 @@ function ServiceDetailPanel({
return (
<div
role="dialog"
aria-modal="true"
aria-label="Service Details"
style={{
position: 'fixed',
top: 0,
@@ -221,11 +228,11 @@ function ServiceDetailPanel({
{ label: 'Protocol', getter: p => p.protocol ?? 'TCP' },
...(service.spec.ports?.some((p: { nodePort?: number }) => p.nodePort)
? [
{
label: 'NodePort',
getter: (p: { nodePort?: number }) => String(p.nodePort ?? '—'),
},
]
{
label: 'NodePort',
getter: (p: { nodePort?: number }) => String(p.nodePort ?? '—'),
},
]
: []),
]}
data={service.spec.ports}