Skip to content

Commit

Permalink
[GEN-2176]: fix "ResizeObserver loop" error in UI (#2215)
Browse files Browse the repository at this point in the history
This pull request includes several changes to the frontend web
application, focusing on refactoring the data flow components and
updating GraphQL queries. The changes involve removing redundant code,
updating imports, and modifying the way data is fetched and processed.

### Refactoring Data Flow Components:

*
[`frontend/webapp/components/overview/add-entity/index.tsx`](diffhunk://#diff-c2573243562745e61986b398f50211fc364b6391e2a2d792f518a72a86b44ea2R6-R8):
Removed the `useComputePlatform` hook and the `FadeLoader` component,
simplifying the `AddEntity` component.
[[1]](diffhunk://#diff-c2573243562745e61986b398f50211fc364b6391e2a2d792f518a72a86b44ea2R6-R8)
[[2]](diffhunk://#diff-c2573243562745e61986b398f50211fc364b6391e2a2d792f518a72a86b44ea2L75)
[[3]](diffhunk://#diff-c2573243562745e61986b398f50211fc364b6391e2a2d792f518a72a86b44ea2L95-R94)
*
[`frontend/webapp/containers/main/overview/overview-data-flow/build-action-nodes.ts`](diffhunk://#diff-2a2957e6035bd001e3c0c52f29f01f4473b6b99a8ce4381a08e9de504916c3b1L3-R11):
Updated the `Params` interface and the `buildActionNodes` function to
use `ActionDataParsed` and a single `unfilteredCount` instead of
`ComputePlatformMapped` and `EntityCounts`.
[[1]](diffhunk://#diff-2a2957e6035bd001e3c0c52f29f01f4473b6b99a8ce4381a08e9de504916c3b1L3-R11)
[[2]](diffhunk://#diff-2a2957e6035bd001e3c0c52f29f01f4473b6b99a8ce4381a08e9de504916c3b1L32-L35)
[[3]](diffhunk://#diff-2a2957e6035bd001e3c0c52f29f01f4473b6b99a8ce4381a08e9de504916c3b1L48-R46)
*
[`frontend/webapp/containers/main/overview/overview-data-flow/build-destination-nodes.ts`](diffhunk://#diff-aa30a6b7893a9d1393f196b9846b1fdc19956c7c07f4099570cb25ff2f77fa43L3-R11):
Similar updates as `build-action-nodes.ts`, using `ActualDestination`
and `unfilteredCount`.
[[1]](diffhunk://#diff-aa30a6b7893a9d1393f196b9846b1fdc19956c7c07f4099570cb25ff2f77fa43L3-R11)
[[2]](diffhunk://#diff-aa30a6b7893a9d1393f196b9846b1fdc19956c7c07f4099570cb25ff2f77fa43L31-L34)
[[3]](diffhunk://#diff-aa30a6b7893a9d1393f196b9846b1fdc19956c7c07f4099570cb25ff2f77fa43L47-R45)
*
[`frontend/webapp/containers/main/overview/overview-data-flow/build-rule-nodes.ts`](diffhunk://#diff-a37edc5ed2e31d0b06f407f3d1d5b155d499c689f95609db388f0e8246a1800bL3-R11):
Updated to use `InstrumentationRuleSpecMapped` and `unfilteredCount`.
[[1]](diffhunk://#diff-a37edc5ed2e31d0b06f407f3d1d5b155d499c689f95609db388f0e8246a1800bL3-R11)
[[2]](diffhunk://#diff-a37edc5ed2e31d0b06f407f3d1d5b155d499c689f95609db388f0e8246a1800bL31-L34)
[[3]](diffhunk://#diff-a37edc5ed2e31d0b06f407f3d1d5b155d499c689f95609db388f0e8246a1800bL47-R45)
*
[`frontend/webapp/containers/main/overview/overview-data-flow/build-source-nodes.ts`](diffhunk://#diff-278da68d858c88d202c10e2011bc1263fe6c0b543dc9d0fc4995a0f0675d3db1L3):
Updated to use `K8sActualSource` and `unfilteredCount`.
[[1]](diffhunk://#diff-278da68d858c88d202c10e2011bc1263fe6c0b543dc9d0fc4995a0f0675d3db1L3)
[[2]](diffhunk://#diff-278da68d858c88d202c10e2011bc1263fe6c0b543dc9d0fc4995a0f0675d3db1L13-R12)
[[3]](diffhunk://#diff-278da68d858c88d202c10e2011bc1263fe6c0b543dc9d0fc4995a0f0675d3db1L39-L42)

### Removing Redundant Code:

*
[`frontend/webapp/containers/main/overview/overview-data-flow/get-entity-counts.ts`](diffhunk://#diff-9180e7735f3b0a44ca96a2b3211d3f6adf63d412713f4f6e6b8cfe4566eb0e86L1-L21):
Removed the `get-entity-counts.ts` file as it is no longer needed.
*
[`frontend/webapp/containers/main/overview/overview-data-flow/index.tsx`](diffhunk://#diff-ee7b35d91186596456e449c5e4d64517a4c905dc8735b0211d51a8b500d11e55L9-L20):
Refactored to use CRUD hooks instead of `useComputePlatform`, and
removed references to `getEntityCounts`.
[[1]](diffhunk://#diff-ee7b35d91186596456e449c5e4d64517a4c905dc8735b0211d51a8b500d11e55L9-L20)
[[2]](diffhunk://#diff-ee7b35d91186596456e449c5e4d64517a4c905dc8735b0211d51a8b500d11e55L38-R81)
[[3]](diffhunk://#diff-ee7b35d91186596456e449c5e4d64517a4c905dc8735b0211d51a8b500d11e55L125-R120)

### Updating GraphQL Queries:

*
[`frontend/webapp/graphql/queries/compute-platform.ts`](diffhunk://#diff-31f9118ffb7e3400a45302bd5f30d621f58adaf33d086beb183bd302b980c521R6):
Added new queries `GET_NAMESPACE`, `GET_SOURCES`, `GET_DESTINATIONS`,
`GET_ACTIONS`, and `GET_INSTRUMENTATION_RULES`, and removed redundant
parts of `GET_COMPUTE_PLATFORM`.
[[1]](diffhunk://#diff-31f9118ffb7e3400a45302bd5f30d621f58adaf33d086beb183bd302b980c521R6)
[[2]](diffhunk://#diff-31f9118ffb7e3400a45302bd5f30d621f58adaf33d086beb183bd302b980c521R17-R70)
[[3]](diffhunk://#diff-31f9118ffb7e3400a45302bd5f30d621f58adaf33d086beb183bd302b980c521R102-R108)
[[4]](diffhunk://#diff-31f9118ffb7e3400a45302bd5f30d621f58adaf33d086beb183bd302b980c521R121-R127)
[[5]](diffhunk://#diff-31f9118ffb7e3400a45302bd5f30d621f58adaf33d086beb183bd302b980c521L90-L136)
  • Loading branch information
BenElferink authored Jan 14, 2025
1 parent cef91ec commit 9e10aff
Show file tree
Hide file tree
Showing 17 changed files with 271 additions and 286 deletions.
7 changes: 3 additions & 4 deletions frontend/webapp/components/overview/add-entity/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import theme from '@/styles/theme';
import { PlusIcon } from '@/assets';
import { useModalStore } from '@/store';
import { getEntityIcon } from '@/utils';
import { useOnClickOutside } from '@/hooks';
import styled, { css } from 'styled-components';
import { useComputePlatform, useOnClickOutside } from '@/hooks';
import { Button, FadeLoader, Text } from '@/reuseable-components';
import { Button, Text } from '@/reuseable-components';
import { type DropdownOption, OVERVIEW_ENTITY_TYPES } from '@/types';

// Styled components for the dropdown UI
Expand Down Expand Up @@ -72,7 +72,6 @@ interface Props {
}

export const AddEntity: React.FC<Props> = ({ options = DEFAULT_OPTIONS, placeholder = 'ADD...' }) => {
const { loading } = useComputePlatform();
const { currentModal, setCurrentModal } = useModalStore();

const [isDropdownOpen, setIsDropdownOpen] = useState(false);
Expand All @@ -92,7 +91,7 @@ export const AddEntity: React.FC<Props> = ({ options = DEFAULT_OPTIONS, placehol
return (
<Container ref={dropdownRef}>
<StyledButton data-id='add-entity' onClick={handleToggle}>
{loading ? <FadeLoader color={theme.colors.primary} /> : <PlusIcon fill={theme.colors.primary} />}
<PlusIcon fill={theme.colors.primary} />
<ButtonText size={14}>{placeholder}</ButtonText>
</StyledButton>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { type Node } from '@xyflow/react';
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 { NODE_TYPES, OVERVIEW_ENTITY_TYPES, OVERVIEW_NODE_TYPES, STATUSES, type ComputePlatformMapped } from '@/types';
import { type ActionDataParsed, NODE_TYPES, OVERVIEW_ENTITY_TYPES, OVERVIEW_NODE_TYPES, STATUSES } from '@/types';

interface Params {
loading: boolean;
entities: ComputePlatformMapped['computePlatform']['actions'];
entities: ActionDataParsed[];
positions: NodePositions;
unfilteredCounts: EntityCounts;
unfilteredCount: number;
}

const { nodeWidth, nodeHeight, framePadding } = nodeConfig;
Expand All @@ -29,10 +28,9 @@ const mapToNodeData = (entity: Params['entities'][0]) => {
};
};

export const buildActionNodes = ({ loading, entities, positions, unfilteredCounts }: Params) => {
export const buildActionNodes = ({ loading, entities, positions, unfilteredCount }: Params) => {
const nodes: Node[] = [];
const position = positions[OVERVIEW_ENTITY_TYPES.ACTION];
const unfilteredCount = unfilteredCounts[OVERVIEW_ENTITY_TYPES.ACTION];

nodes.push({
id: 'action-header',
Expand All @@ -45,7 +43,7 @@ export const buildActionNodes = ({ loading, entities, positions, unfilteredCount
nodeWidth,
title: 'Actions',
icon: getEntityIcon(OVERVIEW_ENTITY_TYPES.ACTION),
tagValue: unfilteredCounts[OVERVIEW_ENTITY_TYPES.ACTION],
tagValue: unfilteredCount,
},
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { type Node } from '@xyflow/react';
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 { NODE_TYPES, OVERVIEW_ENTITY_TYPES, OVERVIEW_NODE_TYPES, STATUSES, type ComputePlatformMapped } from '@/types';
import { type ActualDestination, NODE_TYPES, OVERVIEW_ENTITY_TYPES, OVERVIEW_NODE_TYPES, STATUSES } from '@/types';

interface Params {
loading: boolean;
entities: ComputePlatformMapped['computePlatform']['destinations'];
entities: ActualDestination[];
positions: NodePositions;
unfilteredCounts: EntityCounts;
unfilteredCount: number;
}

const { nodeWidth } = nodeConfig;
Expand All @@ -28,10 +27,9 @@ const mapToNodeData = (entity: Params['entities'][0]) => {
};
};

export const buildDestinationNodes = ({ loading, entities, positions, unfilteredCounts }: Params) => {
export const buildDestinationNodes = ({ loading, entities, positions, unfilteredCount }: Params) => {
const nodes: Node[] = [];
const position = positions[OVERVIEW_ENTITY_TYPES.DESTINATION];
const unfilteredCount = unfilteredCounts[OVERVIEW_ENTITY_TYPES.DESTINATION];

nodes.push({
id: 'destination-header',
Expand All @@ -44,7 +42,7 @@ export const buildDestinationNodes = ({ loading, entities, positions, unfiltered
nodeWidth,
title: 'Destinations',
icon: getEntityIcon(OVERVIEW_ENTITY_TYPES.DESTINATION),
tagValue: unfilteredCounts[OVERVIEW_ENTITY_TYPES.DESTINATION],
tagValue: unfilteredCount,
},
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { type Node } from '@xyflow/react';
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 { NODE_TYPES, OVERVIEW_ENTITY_TYPES, OVERVIEW_NODE_TYPES, STATUSES, type ComputePlatformMapped } from '@/types';
import { type InstrumentationRuleSpecMapped, NODE_TYPES, OVERVIEW_ENTITY_TYPES, OVERVIEW_NODE_TYPES, STATUSES } from '@/types';

interface Params {
loading: boolean;
entities: ComputePlatformMapped['computePlatform']['instrumentationRules'];
entities: InstrumentationRuleSpecMapped[];
positions: NodePositions;
unfilteredCounts: EntityCounts;
unfilteredCount: number;
}

const { nodeWidth } = nodeConfig;
Expand All @@ -28,10 +27,9 @@ const mapToNodeData = (entity: Params['entities'][0]) => {
};
};

export const buildRuleNodes = ({ loading, entities, positions, unfilteredCounts }: Params) => {
export const buildRuleNodes = ({ loading, entities, positions, unfilteredCount }: Params) => {
const nodes: Node[] = [];
const position = positions[OVERVIEW_ENTITY_TYPES.RULE];
const unfilteredCount = unfilteredCounts[OVERVIEW_ENTITY_TYPES.RULE];

nodes.push({
id: 'rule-header',
Expand All @@ -44,7 +42,7 @@ export const buildRuleNodes = ({ loading, entities, positions, unfilteredCounts
nodeWidth,
title: 'Instrumentation Rules',
icon: getEntityIcon(OVERVIEW_ENTITY_TYPES.RULE),
tagValue: unfilteredCounts[OVERVIEW_ENTITY_TYPES.RULE],
tagValue: unfilteredCount,
},
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { type Node } from '@xyflow/react';
import nodeConfig from './node-config.json';
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';
Expand All @@ -10,7 +9,7 @@ interface Params {
loading: boolean;
entities: K8sActualSource[];
positions: NodePositions;
unfilteredCounts: EntityCounts;
unfilteredCount: number;
containerHeight: number;
onScroll: (params: { clientHeight: number; scrollHeight: number; scrollTop: number }) => void;
}
Expand All @@ -36,10 +35,9 @@ const mapToNodeData = (entity: Params['entities'][0]) => {
};
};

export const buildSourceNodes = ({ loading, entities, positions, unfilteredCounts, containerHeight, onScroll }: Params) => {
export const buildSourceNodes = ({ loading, entities, positions, unfilteredCount, containerHeight, onScroll }: Params) => {
const nodes: Node[] = [];
const position = positions[OVERVIEW_ENTITY_TYPES.SOURCE];
const unfilteredCount = unfilteredCounts[OVERVIEW_ENTITY_TYPES.SOURCE];

nodes.push({
id: 'source-header',
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,16 @@ import { NodeDataFlow } from '@/reuseable-components';
import { MultiSourceControl } from '../multi-source-control';
import { OverviewActionsMenu } from '../overview-actions-menu';
import { type Edge, useEdgesState, useNodesState, type Node, applyNodeChanges } from '@xyflow/react';
import { useComputePlatform, useContainerSize, useMetrics, useNodeDataFlowHandlers, useSourceCRUD } from '@/hooks';
import { useActionCRUD, useContainerSize, useDestinationCRUD, useInstrumentationRuleCRUD, useMetrics, useNodeDataFlowHandlers, useSourceCRUD } from '@/hooks';

import { buildEdges } from './build-edges';
import { getEntityCounts } from './get-entity-counts';
import { getNodePositions } from './get-node-positions';
import { buildRuleNodes } from './build-rule-nodes';
import { buildActionNodes } from './build-action-nodes';
import { buildDestinationNodes } from './build-destination-nodes';
import { buildSourceNodes } from './build-source-nodes';
import nodeConfig from './node-config.json';

export * from './get-entity-counts';
export * from './get-node-positions';
export { nodeConfig };

Expand All @@ -35,61 +33,52 @@ export default function OverviewDataFlowContainer() {
const positions = useMemo(() => getNodePositions({ containerWidth }), [containerWidth]);

const { metrics } = useMetrics();
const { sources, filteredSources } = useSourceCRUD();
const { data, filteredData, loading } = useComputePlatform(); // TODO: remove this in favor of CRUD hooks

const unfilteredCounts = useMemo(
() =>
getEntityCounts({
sources,
destinations: data?.computePlatform.destinations,
actions: data?.computePlatform.actions,
instrumentationRules: data?.computePlatform.instrumentationRules,
}),
[sources, data],
);
const { actions, filteredActions, loading: actLoad } = useActionCRUD();
const { sources, filteredSources, loading: srcLoad } = useSourceCRUD();
const { destinations, filteredDestinations, loading: destLoad } = useDestinationCRUD();
const { instrumentationRules, filteredInstrumentationRules, loading: ruleLoad } = useInstrumentationRuleCRUD();

const ruleNodes = useMemo(
() =>
buildRuleNodes({
loading,
entities: filteredData?.computePlatform.instrumentationRules || [],
loading: ruleLoad,
entities: filteredInstrumentationRules,
unfilteredCount: instrumentationRules.length,
positions,
unfilteredCounts,
}),
[loading, filteredData?.computePlatform.instrumentationRules, positions, unfilteredCounts.rule],
[ruleLoad, instrumentationRules, filteredInstrumentationRules, positions],
);
const actionNodes = useMemo(
() =>
buildActionNodes({
loading,
entities: filteredData?.computePlatform.actions || [],
loading: actLoad,
entities: filteredActions,
unfilteredCount: actions.length,
positions,
unfilteredCounts,
}),
[loading, filteredData?.computePlatform.actions, positions, unfilteredCounts.action],
[actLoad, actions, filteredActions, positions],
);
const destinationNodes = useMemo(
() =>
buildDestinationNodes({
loading,
entities: filteredData?.computePlatform.destinations || [],
loading: destLoad,
entities: filteredDestinations,
unfilteredCount: destinations.length,
positions,
unfilteredCounts,
}),
[loading, filteredData?.computePlatform.destinations, positions, unfilteredCounts.destination],
[destLoad, destinations, filteredDestinations, positions],
);
const sourceNodes = useMemo(
() =>
buildSourceNodes({
loading,
loading: srcLoad,
entities: filteredSources,
unfilteredCount: sources.length,
positions,
unfilteredCounts,
containerHeight,
onScroll: ({ scrollTop }) => setScrollYOffset(scrollTop),
}),
[loading, filteredSources, positions, unfilteredCounts.source, containerHeight],
[srcLoad, sources, filteredSources, positions, containerHeight],
);

const [nodes, setNodes, onNodesChange] = useNodesState(([] as Node[]).concat(actionNodes, ruleNodes, sourceNodes, destinationNodes));
Expand Down Expand Up @@ -122,7 +111,13 @@ export default function OverviewDataFlowContainer() {
<Container ref={containerRef}>
<OverviewActionsMenu />
<MultiSourceControl />
<NodeDataFlow nodes={nodes} edges={edges} onNodeClick={handleNodeClick} onNodesChange={onNodesChange} onEdgesChange={onEdgesChange} />
<NodeDataFlow
nodes={nodes}
edges={edges}
onNodeClick={handleNodeClick}
onNodesChange={(changes) => setTimeout(() => onNodesChange(changes))} // Timeout is needed to fix this error: "ResizeObserver loop completed with undelivered notifications."
onEdgesChange={(changes) => setTimeout(() => onEdgesChange(changes))} // Timeout is needed to fix this error: "ResizeObserver loop completed with undelivered notifications."
/>
</Container>
);
}
Loading

0 comments on commit 9e10aff

Please sign in to comment.