Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GEN-2006]: add edged node for hidden entities #1981

Merged
merged 4 commits into from
Dec 15, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import nodeConfig from './node-config.json';
import { type EntityCounts } from './get-entity-counts';
import { type NodePositions } from './get-node-positions';
import { getActionIcon, getEntityIcon, getEntityLabel } from '@/utils';
import { OVERVIEW_ENTITY_TYPES, OVERVIEW_NODE_TYPES, STATUSES, type ComputePlatformMapped } from '@/types';
import { NODE_TYPES, OVERVIEW_ENTITY_TYPES, OVERVIEW_NODE_TYPES, STATUSES, type ComputePlatformMapped } from '@/types';

interface Params {
entities: ComputePlatformMapped['computePlatform']['actions'];
Expand Down Expand Up @@ -35,7 +35,7 @@ export const buildActionNodes = ({ entities, positions, unfilteredCounts }: Para

nodes.push({
id: 'action-header',
type: 'header',
type: NODE_TYPES.HEADER,
position: {
x: positions[OVERVIEW_ENTITY_TYPES.ACTION]['x'],
y: 0,
Expand All @@ -51,7 +51,7 @@ export const buildActionNodes = ({ entities, positions, unfilteredCounts }: Para
if (!entities.length) {
nodes.push({
id: 'action-add',
type: 'add',
type: NODE_TYPES.ADD,
position: {
x: position['x'],
y: position['y'](),
Expand All @@ -67,7 +67,7 @@ export const buildActionNodes = ({ entities, positions, unfilteredCounts }: Para
} else {
nodes.push({
id: 'action-frame',
type: 'frame',
type: NODE_TYPES.FRAME,
position: {
x: position['x'] - framePadding,
y: position['y']() - framePadding,
Expand All @@ -81,7 +81,7 @@ export const buildActionNodes = ({ entities, positions, unfilteredCounts }: Para
entities.forEach((action, idx) => {
nodes.push({
id: `action-${idx}`,
type: 'base',
type: NODE_TYPES.BASE,
extent: 'parent',
parentId: 'action-frame',
position: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import nodeConfig from './node-config.json';
import { type EntityCounts } from './get-entity-counts';
import { type NodePositions } from './get-node-positions';
import { extractMonitors, getEntityIcon, getEntityLabel, getHealthStatus } from '@/utils';
import { OVERVIEW_ENTITY_TYPES, OVERVIEW_NODE_TYPES, STATUSES, type ComputePlatformMapped } from '@/types';
import { NODE_TYPES, OVERVIEW_ENTITY_TYPES, OVERVIEW_NODE_TYPES, STATUSES, type ComputePlatformMapped } from '@/types';

interface Params {
entities: ComputePlatformMapped['computePlatform']['destinations'];
Expand Down Expand Up @@ -34,7 +34,7 @@ export const buildDestinationNodes = ({ entities, positions, unfilteredCounts }:

nodes.push({
id: 'destination-header',
type: 'header',
type: NODE_TYPES.HEADER,
position: {
x: positions[OVERVIEW_ENTITY_TYPES.DESTINATION]['x'],
y: 0,
Expand All @@ -50,7 +50,7 @@ export const buildDestinationNodes = ({ entities, positions, unfilteredCounts }:
if (!entities.length) {
nodes.push({
id: 'destination-add',
type: 'add',
type: NODE_TYPES.ADD,
position: {
x: position['x'],
y: position['y'](),
Expand All @@ -67,7 +67,7 @@ export const buildDestinationNodes = ({ entities, positions, unfilteredCounts }:
entities.forEach((destination, idx) => {
nodes.push({
id: `destination-${idx}`,
type: 'base',
type: NODE_TYPES.BASE,
position: {
x: position['x'],
y: position['y'](idx),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import theme from '@/styles/theme';
import { formatBytes } from '@/utils';
import { type Edge, type Node } from '@xyflow/react';
import { OVERVIEW_ENTITY_TYPES, STATUSES, WorkloadId, type OverviewMetricsResponse } from '@/types';
import { EDGE_TYPES, NODE_TYPES, OVERVIEW_ENTITY_TYPES, STATUSES, WorkloadId, type OverviewMetricsResponse } from '@/types';
import nodeConfig from './node-config.json';

interface Params {
Expand All @@ -18,7 +18,7 @@ const createEdge = (edgeId: string, params?: { label?: string; isMultiTarget?: b

return {
id: edgeId,
type: !!label ? 'labeled' : 'default',
type: !!label ? EDGE_TYPES.LABELED : 'default',
source: sourceNodeId,
target: targetNodeId,
animated,
Expand All @@ -32,47 +32,36 @@ export const buildEdges = ({ nodes, metrics, containerHeight }: Params) => {
const actionNodeId = nodes.find(({ id: nodeId }) => ['action-frame', 'action-add'].includes(nodeId))?.id;

nodes.forEach(({ type: nodeType, id: nodeId, data: { type: entityType, id: entityId, status }, position }) => {
if (nodeType === 'base') {
switch (entityType) {
case OVERVIEW_ENTITY_TYPES.SOURCE: {
const { namespace, name, kind } = entityId as WorkloadId;
const metric = metrics?.getOverviewMetrics.sources.find((m) => m.kind === kind && m.name === name && m.namespace === namespace);
if (nodeType === NODE_TYPES.EDGED && entityType === OVERVIEW_ENTITY_TYPES.SOURCE) {
const { namespace, name, kind } = entityId as WorkloadId;
const metric = metrics?.getOverviewMetrics.sources.find((m) => m.kind === kind && m.name === name && m.namespace === namespace);

const topLimit = -nodeHeight / 2 + framePadding;
const bottomLimit = containerHeight - nodeHeight + framePadding * 2 + topLimit;
const topLimit = -nodeHeight / 2 + framePadding;
const bottomLimit = Math.floor(containerHeight / nodeHeight) * nodeHeight - (nodeHeight / 2 + framePadding);

if (position.y >= topLimit && position.y <= bottomLimit) {
edges.push(
createEdge(`${nodeId}-to-${actionNodeId}`, {
animated: false,
isMultiTarget: false,
label: formatBytes(metric?.throughput),
isError: status === STATUSES.UNHEALTHY,
}),
);
}

break;
}

case OVERVIEW_ENTITY_TYPES.DESTINATION: {
const metric = metrics?.getOverviewMetrics.destinations.find((m) => m.id === entityId);

edges.push(
createEdge(`${actionNodeId}-to-${nodeId}`, {
animated: false,
isMultiTarget: true,
label: formatBytes(metric?.throughput),
isError: status === STATUSES.UNHEALTHY,
}),
);
if (position.y >= topLimit && position.y <= bottomLimit) {
edges.push(
createEdge(`${nodeId}-to-${actionNodeId}`, {
animated: false,
isMultiTarget: false,
label: formatBytes(metric?.throughput),
isError: status === STATUSES.UNHEALTHY,
}),
);
}
}

break;
}
if (nodeType === NODE_TYPES.BASE && entityType === OVERVIEW_ENTITY_TYPES.DESTINATION) {
const metric = metrics?.getOverviewMetrics.destinations.find((m) => m.id === entityId);

default:
break;
}
edges.push(
createEdge(`${actionNodeId}-to-${nodeId}`, {
animated: false,
isMultiTarget: true,
label: formatBytes(metric?.throughput),
isError: status === STATUSES.UNHEALTHY,
}),
);
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import nodeConfig from './node-config.json';
import { type EntityCounts } from './get-entity-counts';
import { type NodePositions } from './get-node-positions';
import { getEntityIcon, getEntityLabel, getRuleIcon } from '@/utils';
import { OVERVIEW_ENTITY_TYPES, OVERVIEW_NODE_TYPES, STATUSES, type ComputePlatformMapped } from '@/types';
import { NODE_TYPES, OVERVIEW_ENTITY_TYPES, OVERVIEW_NODE_TYPES, STATUSES, type ComputePlatformMapped } from '@/types';

interface Params {
entities: ComputePlatformMapped['computePlatform']['instrumentationRules'];
Expand Down Expand Up @@ -34,7 +34,7 @@ export const buildRuleNodes = ({ entities, positions, unfilteredCounts }: Params

nodes.push({
id: 'rule-header',
type: 'header',
type: NODE_TYPES.HEADER,
position: {
x: positions[OVERVIEW_ENTITY_TYPES.RULE]['x'],
y: 0,
Expand All @@ -50,7 +50,7 @@ export const buildRuleNodes = ({ entities, positions, unfilteredCounts }: Params
if (!entities.length) {
nodes.push({
id: 'rule-add',
type: 'add',
type: NODE_TYPES.ADD,
position: {
x: position['x'],
y: position['y'](),
Expand All @@ -67,7 +67,7 @@ export const buildRuleNodes = ({ entities, positions, unfilteredCounts }: Params
entities.forEach((rule, idx) => {
nodes.push({
id: `rule-${idx}`,
type: 'base',
type: NODE_TYPES.BASE,
position: {
x: position['x'],
y: position['y'](idx),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { type EntityCounts } from './get-entity-counts';
import { type NodePositions } from './get-node-positions';
import { getMainContainerLanguage } from '@/utils/constants/programming-languages';
import { getEntityIcon, getEntityLabel, getHealthStatus, getProgrammingLanguageIcon } from '@/utils';
import { OVERVIEW_ENTITY_TYPES, OVERVIEW_NODE_TYPES, STATUSES, type ComputePlatformMapped } from '@/types';
import { NODE_TYPES, OVERVIEW_ENTITY_TYPES, OVERVIEW_NODE_TYPES, STATUSES, type ComputePlatformMapped } from '@/types';

interface Params {
entities: ComputePlatformMapped['computePlatform']['k8sActualSources'];
Expand All @@ -20,6 +20,8 @@ const { nodeWidth, nodeHeight, framePadding } = nodeConfig;
const mapToNodeData = (entity: Params['entities'][0]) => {
return {
nodeWidth,
nodeHeight,
framePadding,
id: {
namespace: entity.namespace,
name: entity.name,
Expand All @@ -41,7 +43,7 @@ export const buildSourceNodes = ({ entities, positions, unfilteredCounts, contai

nodes.push({
id: 'source-header',
type: 'header',
type: NODE_TYPES.HEADER,
position: {
x: positions[OVERVIEW_ENTITY_TYPES.SOURCE]['x'],
y: 0,
Expand All @@ -57,7 +59,7 @@ export const buildSourceNodes = ({ entities, positions, unfilteredCounts, contai
if (!entities.length) {
nodes.push({
id: 'source-add',
type: 'add',
type: NODE_TYPES.ADD,
position: {
x: position['x'],
y: position['y'](),
Expand All @@ -73,7 +75,7 @@ export const buildSourceNodes = ({ entities, positions, unfilteredCounts, contai
} else {
nodes.push({
id: 'source-scroll',
type: 'scroll',
type: NODE_TYPES.SCROLL,
position: {
x: position['x'],
y: position['y']() - framePadding,
Expand All @@ -83,10 +85,7 @@ export const buildSourceNodes = ({ entities, positions, unfilteredCounts, contai
nodeHeight: containerHeight - nodeHeight + framePadding * 2,
items: entities.map((source, idx) => ({
id: `source-${idx}`,
data: {
framePadding,
...mapToNodeData(source),
},
data: mapToNodeData(source),
})),
onScroll,
},
Expand All @@ -95,18 +94,17 @@ export const buildSourceNodes = ({ entities, positions, unfilteredCounts, contai
entities.forEach((source, idx) => {
nodes.push({
id: `source-${idx}-hidden`,
type: 'base',
type: NODE_TYPES.EDGED,
extent: 'parent',
parentId: 'source-scroll',
position: {
x: framePadding,
y: position['y'](idx) - (nodeHeight - framePadding),
},
data: mapToNodeData(source),
style: {
opacity: 0,
zIndex: -1,
},
data: mapToNodeData(source),
});
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,7 @@ export default function OverviewDataFlowContainer() {
positions,
unfilteredCounts,
containerHeight,
onScroll: ({ clientHeight, scrollHeight, scrollTop }) => {
console.log('Node scrolled', { clientHeight, scrollHeight, scrollTop });
setScrollYOffset(scrollTop);
},
onScroll: ({ scrollTop }) => setScrollYOffset(scrollTop),
}),
[filteredData?.computePlatform.k8sActualSources, positions, unfilteredCounts, containerHeight],
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
import { EDGE_TYPES } from '@/types';
import styled from 'styled-components';
import { EdgeLabelRenderer, BaseEdge, type EdgeProps, type Edge, getSmoothStepPath } from '@xyflow/react';

Expand All @@ -10,7 +11,7 @@ interface Props
isMultiTarget?: boolean;
isError?: boolean;
},
'labeled'
EDGE_TYPES.LABELED
>
> {}

Expand Down
15 changes: 9 additions & 6 deletions frontend/webapp/reuseable-components/nodes-data-flow/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import '@xyflow/react/dist/style.css';
import styled from 'styled-components';
import AddNode from './nodes/add-node';
import BaseNode from './nodes/base-node';
import EdgedNode from './nodes/edged-node';
import FrameNode from './nodes/frame-node';
import ScrollNode from './nodes/scroll-node';
import HeaderNode from './nodes/header-node';
import LabeledEdge from './edges/labeled-edge';
import { EDGE_TYPES, NODE_TYPES } from '@/types';
import { Controls, type Edge, type Node, type OnEdgesChange, type OnNodesChange, ReactFlow } from '@xyflow/react';

interface Props {
Expand Down Expand Up @@ -41,15 +43,16 @@ const ControllerWrapper = styled.div`
`;

const nodeTypes = {
header: HeaderNode,
add: AddNode,
base: BaseNode,
frame: FrameNode,
scroll: ScrollNode,
[NODE_TYPES.HEADER]: HeaderNode,
[NODE_TYPES.ADD]: AddNode,
[NODE_TYPES.BASE]: BaseNode,
[NODE_TYPES.EDGED]: EdgedNode,
[NODE_TYPES.FRAME]: FrameNode,
[NODE_TYPES.SCROLL]: ScrollNode,
};

const edgeTypes = {
labeled: LabeledEdge,
[EDGE_TYPES.LABELED]: LabeledEdge,
};

export const NodeDataFlow: React.FC<Props> = ({ nodes, edges, onNodeClick, onNodesChange, onEdgesChange }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import Image from 'next/image';
import styled from 'styled-components';
import { Text } from '@/reuseable-components';
import { OVERVIEW_NODE_TYPES, STATUSES } from '@/types';
import { NODE_TYPES, OVERVIEW_NODE_TYPES, STATUSES } from '@/types';
import { Handle, type Node, type NodeProps, Position } from '@xyflow/react';

interface Props
Expand All @@ -16,7 +16,7 @@ interface Props
title: string;
subTitle: string;
},
'add'
NODE_TYPES.ADD
>
> {}

Expand Down
Loading
Loading