Skip to content

Commit e08ba61

Browse files
committed
refactor: use React 19 use hook in IconResolver
1 parent d4807e7 commit e08ba61

7 files changed

Lines changed: 81 additions & 69 deletions

File tree

packages/ui/src/components/Catalog/DataListItem.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
GridItem,
1010
LabelGroup,
1111
} from '@patternfly/react-core';
12-
import { FunctionComponent } from 'react';
12+
import { FunctionComponent, Suspense } from 'react';
1313

1414
import { CatalogKind } from '../../models/catalog-kind';
1515
import { IconResolver } from '../IconResolver';
@@ -55,11 +55,13 @@ export const CatalogDataListItem: FunctionComponent<ICatalogDataListItemProps> =
5555
<Grid>
5656
<GridItem sm={12} md={6} order={titleElementOrder}>
5757
<div className="catalog-data-list-item__title-div-left">
58-
<IconResolver
59-
className="catalog-data-list-item__title-div-left__icon"
60-
catalogKind={props.tile.type as CatalogKind}
61-
name={props.tile.name}
62-
/>
58+
<Suspense fallback={null}>
59+
<IconResolver
60+
className="catalog-data-list-item__title-div-left__icon"
61+
catalogKind={props.tile.type as CatalogKind}
62+
name={props.tile.name}
63+
/>
64+
</Suspense>
6365
<span id="clickable-action-item1" className="catalog-data-list-item__title-div-left__title">
6466
{props.tile.title}
6567
</span>

packages/ui/src/components/Catalog/Tile.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import './Tile.scss';
22

33
import { Card, CardBody, CardFooter, CardHeader, CardTitle, LabelGroup } from '@patternfly/react-core';
4-
import { FunctionComponent, PropsWithChildren, useCallback } from 'react';
4+
import { FunctionComponent, PropsWithChildren, Suspense, useCallback } from 'react';
55

66
import { CatalogKind } from '../../models/catalog-kind';
77
import { IconResolver } from '../IconResolver';
@@ -35,7 +35,9 @@ export const Tile: FunctionComponent<PropsWithChildren<TileProps>> = (props) =>
3535
onClick={onTileClick}
3636
>
3737
<div className="tile__header">
38-
<IconResolver className="tile__icon" catalogKind={props.tile.type as CatalogKind} name={props.tile.name} />
38+
<Suspense fallback={null}>
39+
<IconResolver className="tile__icon" catalogKind={props.tile.type as CatalogKind} name={props.tile.name} />
40+
</Suspense>
3941
<LabelGroup isCompact aria-label="tile-headers-tags">
4042
{props.tile.headerTags?.map((tag, index) => (
4143
<CatalogTag key={`${props.tile.name}-${tag}-${index}`} tag={tag} />
Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { FunctionComponent, PropsWithChildren, useEffect, useState } from 'react';
1+
import { FunctionComponent, PropsWithChildren, use, useMemo } from 'react';
22

33
import { CatalogKind } from '../../models/catalog-kind';
44
import { NodeIconResolver } from './node-icon-resolver';
@@ -10,54 +10,54 @@ interface IconResolverProps {
1010
alt?: string;
1111
}
1212

13+
function getIconRequest(catalogKind: CatalogKind, name: string, altProps?: string) {
14+
switch (catalogKind) {
15+
case CatalogKind.Entity:
16+
return {
17+
iconPromise: NodeIconResolver.getIcon(name, catalogKind),
18+
alt: altProps ?? 'Entity icon',
19+
};
20+
case CatalogKind.Kamelet:
21+
return {
22+
iconPromise: NodeIconResolver.getIcon(`kamelet:${name}`, catalogKind),
23+
alt: altProps ?? 'Kamelet icon',
24+
};
25+
case CatalogKind.TestAction:
26+
case CatalogKind.TestActionGroup:
27+
case CatalogKind.TestContainer:
28+
case CatalogKind.TestEndpoint:
29+
case CatalogKind.TestFunction:
30+
case CatalogKind.TestValidationMatcher:
31+
return {
32+
iconPromise: NodeIconResolver.getIcon(name, catalogKind),
33+
alt: altProps ?? `Test ${catalogKind.substring('test'.length)} icon`,
34+
};
35+
case CatalogKind.Processor:
36+
case CatalogKind.Pattern:
37+
case CatalogKind.Component:
38+
return {
39+
iconPromise: NodeIconResolver.getIcon(name, catalogKind),
40+
alt: altProps ?? `${catalogKind} icon`,
41+
};
42+
default:
43+
return {
44+
iconPromise: Promise.resolve(NodeIconResolver.getDefaultCamelIcon()),
45+
alt: altProps ?? 'Default icon',
46+
};
47+
}
48+
}
49+
1350
export const IconResolver: FunctionComponent<PropsWithChildren<IconResolverProps>> = ({
1451
catalogKind,
1552
name,
1653
className,
1754
alt: altProps,
1855
}) => {
19-
const [icon, setIcon] = useState<string | undefined>(undefined);
20-
const [altText, setAltText] = useState<string | undefined>(altProps);
21-
22-
useEffect(() => {
23-
let iconName: string;
24-
let alt: string;
25-
26-
switch (catalogKind) {
27-
case CatalogKind.Entity:
28-
iconName = name;
29-
alt = altProps ?? 'Entity icon';
30-
break;
31-
case CatalogKind.Kamelet:
32-
iconName = `kamelet:${name}`;
33-
alt = altProps ?? 'Kamelet icon';
34-
break;
35-
case CatalogKind.TestAction:
36-
case CatalogKind.TestActionGroup:
37-
case CatalogKind.TestContainer:
38-
case CatalogKind.TestEndpoint:
39-
case CatalogKind.TestFunction:
40-
case CatalogKind.TestValidationMatcher:
41-
iconName = name;
42-
alt = altProps ?? `Test ${catalogKind.substring('test'.length)} icon`;
43-
break;
44-
case CatalogKind.Processor:
45-
case CatalogKind.Pattern:
46-
case CatalogKind.Component:
47-
iconName = name;
48-
alt = altProps ?? `${catalogKind} icon`;
49-
break;
50-
default:
51-
setIcon(NodeIconResolver.getDefaultCamelIcon());
52-
return;
53-
}
54-
55-
NodeIconResolver.getIcon(iconName, catalogKind).then((icon) => {
56-
setIcon(icon);
57-
setAltText(alt);
58-
});
59-
}, [altProps, catalogKind, name]);
56+
const { iconPromise, alt } = useMemo(
57+
() => getIconRequest(catalogKind, name, altProps),
58+
[catalogKind, name, altProps],
59+
);
60+
const icon = use(iconPromise);
6061

61-
if (!icon) return null;
62-
return <img className={className} src={icon} alt={altText} />;
62+
return <img className={className} src={icon} alt={alt} />;
6363
};

packages/ui/src/components/PropertiesModal/PropertiesModal.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import './PropertiesModal.scss';
22

33
import { Modal, ModalBody, ModalHeader, Tab, Tabs } from '@patternfly/react-core';
4-
import { FunctionComponent, ReactElement, useContext, useEffect, useState } from 'react';
4+
import { FunctionComponent, ReactElement, Suspense, useContext, useEffect, useState } from 'react';
55

66
import { CatalogContext } from '../../dynamic-catalog/catalog.provider';
77
import { CatalogKind } from '../../models/catalog-kind';
@@ -97,12 +97,14 @@ export const PropertiesModal: FunctionComponent<IPropertiesModalProps> = (props)
9797

9898
const title: ReactElement = (
9999
<div className="properties-modal__title-div">
100-
<IconResolver
101-
alt={`${props.tile.type} icon`}
102-
className={'properties-modal__title-image'}
103-
catalogKind={props.tile.type as CatalogKind}
104-
name={props.tile.name}
105-
/>
100+
<Suspense fallback={null}>
101+
<IconResolver
102+
alt={`${props.tile.type} icon`}
103+
className={'properties-modal__title-image'}
104+
catalogKind={props.tile.type as CatalogKind}
105+
name={props.tile.name}
106+
/>
107+
</Suspense>
106108
<h1 className="properties-modal__title">{props.tile.title}</h1>
107109
</div>
108110
);

packages/ui/src/components/Visualization/Canvas/Form/CanvasFormHeader.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import './CanvasFormHeader.scss';
33
import { CanvasFormTabsContext, FilteredFieldContext, FormTabsModes } from '@kaoto/forms';
44
import { Button, Grid, GridItem, SearchInput, Title, ToggleGroup, ToggleGroupItem } from '@patternfly/react-core';
55
import { TimesIcon } from '@patternfly/react-icons';
6-
import { FunctionComponent, useContext } from 'react';
6+
import { FunctionComponent, Suspense, useContext } from 'react';
77

88
import { CatalogKind } from '../../../../models';
99
import { IconResolver } from '../../../IconResolver';
@@ -30,7 +30,9 @@ export const CanvasFormHeader: FunctionComponent<CanvasFormHeaderProps> = ({
3030
<>
3131
<Grid hasGutter>
3232
<GridItem className="form-header" span={11}>
33-
<IconResolver className={`form-header__icon-${nodeId}`} catalogKind={catalogKind} name={name} />
33+
<Suspense fallback={null}>
34+
<IconResolver className={`form-header__icon-${nodeId}`} catalogKind={catalogKind} name={name} />
35+
</Suspense>
3436

3537
<Title className="form-header__title" headingLevel="h2">
3638
{title}

packages/ui/src/components/Visualization/Custom/Group/CustomGroupExpanded.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
useHover,
2626
} from '@patternfly/react-topology';
2727
import clsx from 'clsx';
28-
import { FunctionComponent, useContext, useMemo, useRef } from 'react';
28+
import { FunctionComponent, Suspense, useContext, useMemo, useRef } from 'react';
2929

3030
import { CatalogModalContext } from '../../../../dynamic-catalog/catalog-modal.provider';
3131
import { useProcessorIcon } from '../../../../hooks/processor-icon.hook';
@@ -221,11 +221,13 @@ export const CustomGroupExpandedInner: FunctionComponent<CustomGroupProps> = obs
221221
{doesHaveWarnings ? (
222222
<div className="custom-group__container__icon-placeholder" />
223223
) : (
224-
<IconResolver
225-
alt={tooltipContent}
226-
catalogKind={groupVizNode.data.catalogKind}
227-
name={groupVizNode.data.name}
228-
/>
224+
<Suspense fallback={null}>
225+
<IconResolver
226+
alt={tooltipContent}
227+
catalogKind={groupVizNode.data.catalogKind}
228+
name={groupVizNode.data.name}
229+
/>
230+
</Suspense>
229231
)}
230232
<span title={label}>{label}</span>
231233

packages/ui/src/components/Visualization/Custom/Node/CustomNodeContainer.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Icon } from '@patternfly/react-core';
22
import { BanIcon } from '@patternfly/react-icons';
33
import clsx from 'clsx';
4-
import { ElementType, FunctionComponent, Ref } from 'react';
4+
import { ElementType, FunctionComponent, Ref, Suspense } from 'react';
55

66
import { IVisualizationNode } from '../../../../models';
77
import { IconResolver } from '../../../IconResolver';
@@ -47,7 +47,9 @@ export const CustomNodeContainer: FunctionComponent<CustomNodeContainerProps> =
4747
>
4848
<div data-testid={dataTestId} className={clsx('custom-node__container', containerClassNames)}>
4949
<div title={tooltipContent} className="custom-node__container__image">
50-
<IconResolver alt={tooltipContent} catalogKind={vizNode.data.catalogKind} name={vizNode.data.name} />
50+
<Suspense fallback={null}>
51+
<IconResolver alt={tooltipContent} catalogKind={vizNode.data.catalogKind} name={vizNode.data.name} />
52+
</Suspense>
5153

5254
{childCount > 0 && (
5355
<FloatingCircle className="step-icon step-icon__processor">

0 commit comments

Comments
 (0)