From b21d3c7dbcd3158ab8a7865277383de8bfa8eb5d Mon Sep 17 00:00:00 2001 From: Ben Elferink Date: Thu, 12 Dec 2024 19:47:12 +0200 Subject: [PATCH 1/2] feat: add edged node --- .../overview-data-flow/build-action-nodes.ts | 10 +-- .../build-destination-nodes.ts | 8 +-- .../overview-data-flow/build-edges.ts | 67 ++++++++----------- .../overview-data-flow/build-rule-nodes.ts | 8 +-- .../overview-data-flow/build-source-nodes.ts | 20 +++--- .../nodes-data-flow/edges/labeled-edge.tsx | 3 +- .../nodes-data-flow/index.tsx | 15 +++-- .../nodes-data-flow/nodes/add-node.tsx | 4 +- .../nodes-data-flow/nodes/base-node.tsx | 19 ++---- .../nodes-data-flow/nodes/edged-node.tsx | 34 ++++++++++ .../nodes-data-flow/nodes/frame-node.tsx | 3 +- .../nodes-data-flow/nodes/header-node.tsx | 3 +- .../nodes-data-flow/nodes/scroll-node.tsx | 27 ++++---- frontend/webapp/types/data-flow.ts | 12 ++++ frontend/webapp/types/index.ts | 8 +-- 15 files changed, 136 insertions(+), 105 deletions(-) create mode 100644 frontend/webapp/reuseable-components/nodes-data-flow/nodes/edged-node.tsx create mode 100644 frontend/webapp/types/data-flow.ts diff --git a/frontend/webapp/containers/main/overview/overview-data-flow/build-action-nodes.ts b/frontend/webapp/containers/main/overview/overview-data-flow/build-action-nodes.ts index 5cffcba92..116d8b481 100644 --- a/frontend/webapp/containers/main/overview/overview-data-flow/build-action-nodes.ts +++ b/frontend/webapp/containers/main/overview/overview-data-flow/build-action-nodes.ts @@ -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']; @@ -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, @@ -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'](), @@ -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, @@ -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: { diff --git a/frontend/webapp/containers/main/overview/overview-data-flow/build-destination-nodes.ts b/frontend/webapp/containers/main/overview/overview-data-flow/build-destination-nodes.ts index 357c5bd2a..8d7c6dfd6 100644 --- a/frontend/webapp/containers/main/overview/overview-data-flow/build-destination-nodes.ts +++ b/frontend/webapp/containers/main/overview/overview-data-flow/build-destination-nodes.ts @@ -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']; @@ -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, @@ -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'](), @@ -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), diff --git a/frontend/webapp/containers/main/overview/overview-data-flow/build-edges.ts b/frontend/webapp/containers/main/overview/overview-data-flow/build-edges.ts index 5b7d893ec..1632484d8 100644 --- a/frontend/webapp/containers/main/overview/overview-data-flow/build-edges.ts +++ b/frontend/webapp/containers/main/overview/overview-data-flow/build-edges.ts @@ -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 { @@ -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, @@ -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, + }), + ); } }); diff --git a/frontend/webapp/containers/main/overview/overview-data-flow/build-rule-nodes.ts b/frontend/webapp/containers/main/overview/overview-data-flow/build-rule-nodes.ts index 08bbda592..dd6f05c42 100644 --- a/frontend/webapp/containers/main/overview/overview-data-flow/build-rule-nodes.ts +++ b/frontend/webapp/containers/main/overview/overview-data-flow/build-rule-nodes.ts @@ -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']; @@ -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, @@ -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'](), @@ -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), diff --git a/frontend/webapp/containers/main/overview/overview-data-flow/build-source-nodes.ts b/frontend/webapp/containers/main/overview/overview-data-flow/build-source-nodes.ts index 70166f1f6..c4a3c67f7 100644 --- a/frontend/webapp/containers/main/overview/overview-data-flow/build-source-nodes.ts +++ b/frontend/webapp/containers/main/overview/overview-data-flow/build-source-nodes.ts @@ -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']; @@ -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, @@ -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, @@ -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'](), @@ -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, @@ -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, }, @@ -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), }); }); } diff --git a/frontend/webapp/reuseable-components/nodes-data-flow/edges/labeled-edge.tsx b/frontend/webapp/reuseable-components/nodes-data-flow/edges/labeled-edge.tsx index c6f2452f8..687064b90 100644 --- a/frontend/webapp/reuseable-components/nodes-data-flow/edges/labeled-edge.tsx +++ b/frontend/webapp/reuseable-components/nodes-data-flow/edges/labeled-edge.tsx @@ -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'; @@ -10,7 +11,7 @@ interface Props isMultiTarget?: boolean; isError?: boolean; }, - 'labeled' + EDGE_TYPES.LABELED > > {} diff --git a/frontend/webapp/reuseable-components/nodes-data-flow/index.tsx b/frontend/webapp/reuseable-components/nodes-data-flow/index.tsx index bae0649db..1a8edaa32 100644 --- a/frontend/webapp/reuseable-components/nodes-data-flow/index.tsx +++ b/frontend/webapp/reuseable-components/nodes-data-flow/index.tsx @@ -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 { @@ -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 = ({ nodes, edges, onNodeClick, onNodesChange, onEdgesChange }) => { diff --git a/frontend/webapp/reuseable-components/nodes-data-flow/nodes/add-node.tsx b/frontend/webapp/reuseable-components/nodes-data-flow/nodes/add-node.tsx index 10389bd8d..c9cd52278 100644 --- a/frontend/webapp/reuseable-components/nodes-data-flow/nodes/add-node.tsx +++ b/frontend/webapp/reuseable-components/nodes-data-flow/nodes/add-node.tsx @@ -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 @@ -16,7 +16,7 @@ interface Props title: string; subTitle: string; }, - 'add' + NODE_TYPES.ADD > > {} diff --git a/frontend/webapp/reuseable-components/nodes-data-flow/nodes/base-node.tsx b/frontend/webapp/reuseable-components/nodes-data-flow/nodes/base-node.tsx index fb3cb44b1..4414e19cc 100644 --- a/frontend/webapp/reuseable-components/nodes-data-flow/nodes/base-node.tsx +++ b/frontend/webapp/reuseable-components/nodes-data-flow/nodes/base-node.tsx @@ -5,7 +5,7 @@ import styled from 'styled-components'; import { getStatusIcon } from '@/utils'; import { Checkbox, DataTab } from '@/reuseable-components'; import { Handle, type Node, type NodeProps, Position } from '@xyflow/react'; -import { type ActionDataParsed, type ActualDestination, type InstrumentationRuleSpec, type K8sActualSource, OVERVIEW_ENTITY_TYPES, STATUSES, WorkloadId } from '@/types'; +import { type ActionDataParsed, type ActualDestination, type InstrumentationRuleSpec, type K8sActualSource, NODE_TYPES, OVERVIEW_ENTITY_TYPES, STATUSES, WorkloadId } from '@/types'; interface Props extends NodeProps< @@ -23,7 +23,7 @@ interface Props isActive?: boolean; raw: InstrumentationRuleSpec | K8sActualSource | ActionDataParsed | ActualDestination; }, - 'base' + NODE_TYPES.BASE > > {} @@ -72,23 +72,14 @@ const BaseNode: React.FC = ({ id: nodeId, data }) => { ); }; - const renderHandles = () => { - switch (type) { - case 'source': - return ; - case 'destination': - return ; - default: - return null; - } - }; - return ( {}}> {renderActions()} - {renderHandles()} + + + ); }; diff --git a/frontend/webapp/reuseable-components/nodes-data-flow/nodes/edged-node.tsx b/frontend/webapp/reuseable-components/nodes-data-flow/nodes/edged-node.tsx new file mode 100644 index 000000000..c90cfd27a --- /dev/null +++ b/frontend/webapp/reuseable-components/nodes-data-flow/nodes/edged-node.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { NODE_TYPES } from '@/types'; +import styled from 'styled-components'; +import { Handle, type Node, type NodeProps, Position } from '@xyflow/react'; + +interface Props + extends NodeProps< + Node< + { + nodeWidth: number; + nodeHeight: number; + }, + NODE_TYPES.EDGED + > + > {} + +const Container = styled.div<{ $nodeWidth: Props['data']['nodeWidth']; $nodeHeight: Props['data']['nodeHeight'] }>` + width: ${({ $nodeWidth }) => `${$nodeWidth}px`}; + height: ${({ $nodeHeight }) => `${$nodeHeight}px`}; + opacity: 0; +`; + +const EdgedNode: React.FC = ({ data }) => { + const { nodeWidth, nodeHeight } = data; + + return ( + + + + + ); +}; + +export default EdgedNode; diff --git a/frontend/webapp/reuseable-components/nodes-data-flow/nodes/frame-node.tsx b/frontend/webapp/reuseable-components/nodes-data-flow/nodes/frame-node.tsx index c93d20a18..6c06e6369 100644 --- a/frontend/webapp/reuseable-components/nodes-data-flow/nodes/frame-node.tsx +++ b/frontend/webapp/reuseable-components/nodes-data-flow/nodes/frame-node.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { NODE_TYPES } from '@/types'; import styled from 'styled-components'; import { Handle, type Node, type NodeProps, Position } from '@xyflow/react'; @@ -9,7 +10,7 @@ interface Props nodeWidth: number; nodeHeight: number; }, - 'frame' + NODE_TYPES.FRAME > > {} diff --git a/frontend/webapp/reuseable-components/nodes-data-flow/nodes/header-node.tsx b/frontend/webapp/reuseable-components/nodes-data-flow/nodes/header-node.tsx index 3261de9bc..9a2e9522b 100644 --- a/frontend/webapp/reuseable-components/nodes-data-flow/nodes/header-node.tsx +++ b/frontend/webapp/reuseable-components/nodes-data-flow/nodes/header-node.tsx @@ -1,5 +1,6 @@ import React, { useMemo } from 'react'; import Image from 'next/image'; +import { NODE_TYPES } from '@/types'; import { useAppStore } from '@/store'; import styled from 'styled-components'; import { useSourceCRUD } from '@/hooks'; @@ -16,7 +17,7 @@ interface Props title: string; tagValue: number; }, - 'header' + NODE_TYPES.HEADER > > {} diff --git a/frontend/webapp/reuseable-components/nodes-data-flow/nodes/scroll-node.tsx b/frontend/webapp/reuseable-components/nodes-data-flow/nodes/scroll-node.tsx index 3479fe43e..14a4f9695 100644 --- a/frontend/webapp/reuseable-components/nodes-data-flow/nodes/scroll-node.tsx +++ b/frontend/webapp/reuseable-components/nodes-data-flow/nodes/scroll-node.tsx @@ -1,9 +1,9 @@ import React, { useEffect, useRef } from 'react'; import BaseNode from './base-node'; import styled from 'styled-components'; -import { type Node, type NodeProps } from '@xyflow/react'; -import { type K8sActualSource, OVERVIEW_ENTITY_TYPES, STATUSES, type WorkloadId } from '@/types'; import { useDrawerStore } from '@/store'; +import { type Node, type NodeProps } from '@xyflow/react'; +import { type K8sActualSource, NODE_TYPES, OVERVIEW_ENTITY_TYPES, STATUSES, type WorkloadId } from '@/types'; interface Props extends NodeProps< @@ -24,12 +24,12 @@ interface Props imageUri: string; raw: K8sActualSource; }, - 'scroll-item' + NODE_TYPES.BASE > >[]; onScroll: (params: { clientHeight: number; scrollHeight: number; scrollTop: number }) => void; }, - 'scroll' + NODE_TYPES.SCROLL > > {} @@ -57,16 +57,17 @@ const ScrollNode: React.FC = ({ data, ...rest }) => { // @ts-ignore - these properties are available on the EventTarget, TS is not aware of it const { clientHeight, scrollHeight, scrollTop } = e.target || { clientHeight: 0, scrollHeight: 0, scrollTop: 0 }; - const isTop = scrollTop === 0; - const isBottom = scrollHeight - scrollTop <= clientHeight; - - if (isTop) { - console.log('Reached top of scroll-node'); - } else if (isBottom) { - console.log('Reached bottom of scroll-node'); - } if (!!onScroll) onScroll({ clientHeight, scrollHeight, scrollTop }); + + // TODO: Use the following once we have to handle paginated API requests: + // const isTop = scrollTop === 0; + // const isBottom = scrollHeight - scrollTop <= clientHeight; + // if (isTop) { + // console.log('Reached top of scroll-node'); + // } else if (isBottom) { + // console.log('Reached bottom of scroll-node'); + // } }; const { current } = containerRef; @@ -86,7 +87,7 @@ const ScrollNode: React.FC = ({ data, ...rest }) => { setSelectedItem({ id: item.data.id, type: item.data.type, item: item.data.raw }); }} > - + ))} diff --git a/frontend/webapp/types/data-flow.ts b/frontend/webapp/types/data-flow.ts new file mode 100644 index 000000000..a2892e241 --- /dev/null +++ b/frontend/webapp/types/data-flow.ts @@ -0,0 +1,12 @@ +export enum NODE_TYPES { + HEADER = 'header', + ADD = 'add', + BASE = 'base', + EDGED = 'edged', + FRAME = 'frame', + SCROLL = 'scroll', +} + +export enum EDGE_TYPES { + LABELED = 'labeled', +} diff --git a/frontend/webapp/types/index.ts b/frontend/webapp/types/index.ts index 514841421..1a5009a4f 100644 --- a/frontend/webapp/types/index.ts +++ b/frontend/webapp/types/index.ts @@ -1,9 +1,9 @@ -export * from './sources'; -export * from './destinations'; export * from './actions'; -export * from './sources'; export * from './common'; export * from './compute-platform'; -export * from './namespace'; +export * from './data-flow'; +export * from './destinations'; export * from './instrumentation-rules'; export * from './metrics'; +export * from './namespace'; +export * from './sources'; From 5a93abf1b987b4d0d768adea7ece05621ec87115 Mon Sep 17 00:00:00 2001 From: Ben Elferink Date: Thu, 12 Dec 2024 20:53:39 +0200 Subject: [PATCH 2/2] fix: remove log --- .../containers/main/overview/overview-data-flow/index.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/frontend/webapp/containers/main/overview/overview-data-flow/index.tsx b/frontend/webapp/containers/main/overview/overview-data-flow/index.tsx index be27b5f30..c834b2fb3 100644 --- a/frontend/webapp/containers/main/overview/overview-data-flow/index.tsx +++ b/frontend/webapp/containers/main/overview/overview-data-flow/index.tsx @@ -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], );