Skip to content

Commit 5247dec

Browse files
authored
Merge pull request #3527 from sniok/map-updates
frontend: Map: Various small fixes
2 parents 635d8fa + 6482f91 commit 5247dec

File tree

11 files changed

+107
-555
lines changed

11 files changed

+107
-555
lines changed

frontend/src/components/App/Layout.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,9 +269,9 @@ export default function Layout({}: LayoutProps) {
269269
<ClusterNotFoundPopup key={clusterName} cluster={clusterName} />
270270
))}
271271
<AlertNotification />
272-
<Box>
272+
<Box sx={{ height: '100%' }}>
273273
<Div />
274-
<Container {...containerProps}>
274+
<Container {...containerProps} sx={{ height: '100%' }}>
275275
<NavigationTabs />
276276
{arePluginsLoaded && (
277277
<RouteSwitcher

frontend/src/components/resourceMap/GraphRenderer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export function GraphRenderer({
100100
maxZoom={maxZoom}
101101
connectionMode={ConnectionMode.Loose}
102102
>
103-
<Background variant={BackgroundVariant.Dots} style={{ color: theme.palette.divider }} />
103+
<Background variant={BackgroundVariant.Dots} color={theme.palette.divider} size={2} />
104104
<Controls showInteractive={false} showFitView={false} showZoom={false}>
105105
<GraphControls>{controlActions}</GraphControls>
106106
</Controls>

frontend/src/components/resourceMap/GraphView.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
:root {
2-
--graph-animation-duration: 0.2s;
3-
--graph-animation-delay: calc(var(--graph-animation-duration) * 0.5);
2+
--graph-animation-duration: 0.15s;
3+
--graph-animation-delay: calc(var(--graph-animation-duration) * 0.8);
44
--graph-animation-appear: calc(var(--graph-animation-duration) * 0.4);
55
}
66

frontend/src/components/resourceMap/GraphView.tsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -208,14 +208,21 @@ function GraphViewContent({
208208
const viewport = useGraphViewport();
209209

210210
useEffect(() => {
211+
let isCurrent = true;
211212
applyGraphLayout(visibleGraph, viewport.aspectRatio).then(layout => {
213+
if (!isCurrent) return;
214+
212215
setLayoutedGraph(layout);
213216

214217
// Only fit bounds when user hasn't moved viewport manually
215218
if (!viewportMovedRef.current) {
216219
viewport.updateViewport({ nodes: layout.nodes });
217220
}
218221
});
222+
223+
return () => {
224+
isCurrent = false;
225+
};
219226
}, [visibleGraph, viewport]);
220227

221228
// Reset after view change
@@ -378,14 +385,12 @@ function GraphViewContent({
378385
</div>
379386
</Box>
380387
</CustomThemeProvider>
381-
{maybeSelectedNode && (
382-
<GraphNodeDetails
383-
node={maybeSelectedNode}
384-
close={() => {
385-
setSelectedNodeId(selectedGroup?.id ?? defaultNodeSelection);
386-
}}
387-
/>
388-
)}
388+
<GraphNodeDetails
389+
node={maybeSelectedNode}
390+
close={() => {
391+
setSelectedNodeId(selectedGroup?.id ?? defaultNodeSelection);
392+
}}
393+
/>
389394
</Box>
390395
</FullGraphContext.Provider>
391396
</GraphViewContext.Provider>

frontend/src/components/resourceMap/SelectionBreadcrumbs.tsx

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,20 +95,35 @@ export function SelectionBreadcrumbs({
9595

9696
const subtitle = it.subtitle ?? it?.kubeObject?.kind;
9797
const subtitleElement = subtitle ? <Box sx={{ opacity: 0.7 }}>{subtitle}</Box> : null;
98+
const label = getLabel(it);
99+
98100
return i === path.length - 1 ? (
99101
<Box
100102
key={it.id}
103+
title={label}
101104
sx={{
102105
display: 'flex',
103106
gap: 0.5,
107+
maxWidth: '200px',
108+
whiteSpace: 'nowrap',
109+
overflow: 'hidden',
104110
}}
105111
>
106-
{icon} {subtitleElement} {getLabel(it)}
112+
{icon} {subtitleElement}{' '}
113+
<Box
114+
sx={{
115+
overflow: 'hidden',
116+
textOverflow: 'ellipsis',
117+
}}
118+
>
119+
{label}
120+
</Box>
107121
</Box>
108122
) : (
109123
<Link
110124
key={it.id}
111125
onClick={() => onNodeClick(it.id)}
126+
title={label}
112127
sx={{
113128
display: 'flex',
114129
gap: 0.5,
@@ -120,7 +135,15 @@ export function SelectionBreadcrumbs({
120135
cursor: 'pointer',
121136
}}
122137
>
123-
{icon} {subtitleElement} {getLabel(it)}
138+
{icon} {subtitleElement}{' '}
139+
<Box
140+
sx={{
141+
overflow: 'hidden',
142+
textOverflow: 'ellipsis',
143+
}}
144+
>
145+
{label}
146+
</Box>
124147
</Link>
125148
);
126149
})}

frontend/src/components/resourceMap/__snapshots__/GraphView.BasicExample.stories.storyshot

Lines changed: 13 additions & 514 deletions
Large diffs are not rendered by default.

frontend/src/components/resourceMap/details/GraphNodeDetails.tsx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import Box from '@mui/material/Box';
1818
import Card from '@mui/material/Card';
19+
import { useDeferredValue } from 'react';
1920
import { useTranslation } from 'react-i18next';
2021
import ActionButton from '../../common/ActionButton';
2122
import { GraphNode } from '../graph/graphModel';
@@ -33,10 +34,10 @@ export interface GraphNodeDetailsProps {
3334
*/
3435
export function GraphNodeDetails({ node, close }: GraphNodeDetailsProps) {
3536
const { t } = useTranslation();
37+
const deferredNode = useDeferredValue(node);
3638

37-
if (!node) return null;
39+
const hasContent = node && (node.detailsComponent || node.kubeObject);
3840

39-
const hasContent = node.detailsComponent || node.kubeObject;
4041
if (!hasContent) return null;
4142

4243
return (
@@ -70,13 +71,24 @@ export function GraphNodeDetails({ node, close }: GraphNodeDetailsProps) {
7071
/>
7172
</Box>
7273

74+
<NodeDetailsRenderer node={deferredNode} />
75+
</Card>
76+
);
77+
}
78+
79+
function NodeDetailsRenderer({ node }: { node?: GraphNode }) {
80+
const hasContent = node && (node.detailsComponent || node.kubeObject);
81+
if (!hasContent) return null;
82+
83+
return (
84+
<>
7385
{node.detailsComponent && <node.detailsComponent node={node} />}
7486
{node.kubeObject && (
7587
<KubeObjectDetails
7688
resource={node.kubeObject}
7789
customResourceDefinition={node.customResourceDefinition}
7890
/>
7991
)}
80-
</Card>
92+
</>
8193
);
8294
}

frontend/src/components/resourceMap/graph/graphLayout.tsx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616

1717
import { Edge, EdgeMarker, Node } from '@xyflow/react';
1818
import { ElkExtendedEdge, ElkNode } from 'elkjs';
19-
import ELK from 'elkjs';
19+
import ELK, { type ELK as ELKInterface } from 'elkjs/lib/elk-api';
20+
import elkWorker from 'elkjs/lib/elk-worker.min.js?url';
2021
import { forEachNode, getNodeWeight, GraphNode } from './graphModel';
2122

2223
type ElkNodeWithData = Omit<ElkNode, 'edges'> & {
@@ -30,9 +31,15 @@ type ElkEdgeWithData = ElkExtendedEdge & {
3031
data: any;
3132
};
3233

33-
const elk = new ELK({
34-
defaultLayoutOptions: {},
35-
});
34+
let elk: ELKInterface | undefined;
35+
try {
36+
elk = new ELK({
37+
defaultLayoutOptions: {},
38+
workerUrl: elkWorker,
39+
});
40+
} catch (e) {
41+
console.error('Failed to create ELK instance', e);
42+
}
3643

3744
const layoutOptions = {
3845
nodeSize: {
@@ -124,7 +131,7 @@ function convertToElkNode(node: GraphNode, aspectRatio: number): ElkNodeWithData
124131
'elk.rectpacking.packing.compaction.rowHeightReevaluation': 'true',
125132
'elk.edgeRouting': 'SPLINES',
126133
'elk.spacing.nodeNode': '20',
127-
'elk.padding': '[left=24, top=24, right=24, bottom=24]',
134+
'elk.padding': '[left=24, top=48, right=24, bottom=24]',
128135
};
129136
elkNode.edges = convertedEdges;
130137
elkNode.children =
@@ -227,6 +234,8 @@ function convertToReactFlowGraph(elkGraph: ElkNodeWithData) {
227234
export const applyGraphLayout = (graph: GraphNode, aspectRatio: number) => {
228235
const elkGraph = convertToElkNode(graph, aspectRatio);
229236

237+
if (!elk) return Promise.resolve({ nodes: [], edges: [] });
238+
230239
return elk
231240
.layout(elkGraph, {
232241
layoutOptions: {

frontend/src/components/resourceMap/nodes/GroupNode.tsx

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,20 @@ const Container = styled('div')(({ theme }) => ({
3030
borderRadius: theme.spacing(1.5),
3131
}));
3232

33-
const Label = styled('div')(({ theme }) => ({
33+
const Label = styled('div')(() => ({
3434
display: 'flex',
3535
alignItems: 'center',
3636
position: 'absolute',
3737
gap: '4px',
3838
fontSize: '16px',
39-
top: '-16px',
40-
background: theme.palette.background.paper,
41-
left: '22px',
42-
padding: '8px',
39+
top: 0,
40+
left: 0,
41+
padding: '8px 12px',
4342
whiteSpace: 'nowrap',
4443
overflow: 'hidden',
4544
textOverflow: 'ellipsis',
46-
maxWidth: 'calc(100% - 52px)',
47-
color: alpha(theme.palette.text.primary, 0.6),
48-
borderRadius: 2,
45+
width: '100%',
46+
borderRadius: 4,
4947
}));
5048

5149
export const GroupNodeComponent = memo(({ id }: { id: string }) => {
@@ -67,15 +65,17 @@ export const GroupNodeComponent = memo(({ id }: { id: string }) => {
6765
}
6866
}}
6967
>
70-
<Label title={node?.label}>
71-
{node?.kubeObject ? (
72-
<KubeIcon kind={node.kubeObject.kind} width="24px" height="24px" />
73-
) : (
74-
node?.icon ?? null
75-
)}
76-
<Box sx={{ opacity: 0.7 }}>{node?.subtitle}</Box>
77-
<Box>{node?.label}</Box>
78-
</Label>
68+
{(node?.label || node?.subtitle) && (
69+
<Label title={node?.label}>
70+
{node?.kubeObject ? (
71+
<KubeIcon kind={node.kubeObject.kind} width="24px" height="24px" />
72+
) : (
73+
node?.icon ?? null
74+
)}
75+
<Box sx={{ opacity: 0.8 }}>{node?.subtitle}</Box>
76+
<Box sx={{ overflow: 'hidden', textOverflow: 'ellipsis' }}>{node?.label}</Box>
77+
</Label>
78+
)}
7979
</Container>
8080
);
8181
});

frontend/src/lib/router.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -922,7 +922,7 @@ const defaultRoutes: {
922922
name: 'Map',
923923
sidebar: 'map',
924924
isFullWidth: true,
925-
component: () => <LazyGraphView height="calc(100vh - 64px)" />,
925+
component: () => <LazyGraphView height="100%" />,
926926
},
927927
};
928928

0 commit comments

Comments
 (0)