Skip to content

Commit

Permalink
chore(Canvas): Add routeConfiguration branches
Browse files Browse the repository at this point in the history
  • Loading branch information
lordrip committed Feb 10, 2025
1 parent f9f4347 commit b8a8dfa
Show file tree
Hide file tree
Showing 21 changed files with 96 additions and 44 deletions.
21 changes: 20 additions & 1 deletion packages/ui/src/camel-utils/camel-to-tile.adapter.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CatalogKind, ICamelComponentDefinition, ICamelProcessorDefinition, IKameletDefinition } from '../models';
import { camelComponentToTile, camelProcessorToTile, kameletToTile } from './camel-to-tile.adapter';
import { camelComponentToTile, camelEntityToTile, camelProcessorToTile, kameletToTile } from './camel-to-tile.adapter';

describe('camelComponentToTile', () => {
it('should return a tile with the correct type', () => {
Expand Down Expand Up @@ -114,6 +114,25 @@ describe('camelProcessorToTile', () => {
});
});

describe('camelEntityToTile', () => {
it('should return a tile with the correct type', () => {
const processorDef = {
model: {
name: 'my-entity',
title: 'My Entity',
description: 'My Entity Description',
label: 'label1,label2',
},
} as ICamelProcessorDefinition;

const tile = camelEntityToTile(processorDef);

expect(tile.type).toEqual(CatalogKind.Entity);
expect(tile.name).toEqual('my-entity');
expect(tile.description).toEqual('My Entity Description');
});
});

describe('kameletToTile', () => {
it('should return a tile with the correct type', () => {
const kameletDef = {
Expand Down
8 changes: 8 additions & 0 deletions packages/ui/src/camel-utils/camel-to-tile.adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ export const camelProcessorToTile = (processorDef: ICamelProcessorDefinition): I
};
};

export const camelEntityToTile = (processorDef: ICamelProcessorDefinition): ITile => {
const entityTile = camelProcessorToTile(processorDef);
entityTile.type = CatalogKind.Entity;
entityTile.headerTags = ['Entity'];

return entityTile;
};

export const kameletToTile = (kameletDef: IKameletDefinition): ITile => {
const headerTags: string[] = ['Kamelet'];
if (kameletDef.metadata.annotations['camel.apache.org/kamelet.support.level']) {
Expand Down
19 changes: 12 additions & 7 deletions packages/ui/src/components/PropertiesModal/PropertiesModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,22 @@ export const PropertiesModal: FunctionComponent<IPropertiesModalProps> = (props)
const catalogService = useContext(CatalogContext);
const tabs = useMemo(() => {
switch (props.tile.type) {
case CatalogKind.Component: {
case CatalogKind.Component:
return transformCamelComponentIntoTab(catalogService.getComponent(CatalogKind.Component, props.tile.name));
}
case CatalogKind.Processor: {

case CatalogKind.Processor:
return transformCamelProcessorComponentIntoTab(
catalogService.getComponent(CatalogKind.Processor, props.tile.name),
);
}
case CatalogKind.Kamelet: {

case CatalogKind.Entity:
return transformCamelProcessorComponentIntoTab(
catalogService.getComponent(CatalogKind.Entity, props.tile.name),
);

case CatalogKind.Kamelet:
return transformKameletComponentIntoTab(catalogService.getComponent(CatalogKind.Kamelet, props.tile.name));
}

default:
throw Error('Unknown CatalogKind during rendering modal: ' + props.tile.type);
}
Expand All @@ -52,7 +57,7 @@ export const PropertiesModal: FunctionComponent<IPropertiesModalProps> = (props)
setActiveTab(tabs[tabIndex as number]);
setActiveTabKey(tabIndex as number);
};
const nodeIconType = capitalize(props.tile.type === 'processor' ? 'EIP' : props.tile.type);
const nodeIconType = capitalize(props.tile.type === 'processor' ? NodeIconType.EIP : props.tile.type);
const iconName = nodeIconType === NodeIconType.Kamelet ? `kamelet:${props.tile.name}` : props.tile.name;

const title: ReactElement = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const PropertiesField: FunctionComponent<FieldProps> = ({ propName, requi
{schema.title} <Badge title={`${items.length} properties`}>{items.length}</Badge>
</>
}
type="boolean"
type="object"
description={schema.description}
defaultValue={schema.default?.toString()}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ export abstract class AbstractCamelVisualEntity<T extends object> implements Bas
path: this.getRootPath(),
entity: this,
isGroup: true,
icon: NodeIconResolver.getIcon(this.type, NodeIconType.VisualEntity),
icon: NodeIconResolver.getIcon(this.type, NodeIconType.Entity),
processorName: 'route',
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ export class CamelErrorHandlerVisualEntity implements BaseVisualCamelEntity {
);
errorHandlerGroupNode.data.entity = this;
errorHandlerGroupNode.data.isGroup = true;
errorHandlerGroupNode.data.icon = NodeIconResolver.getIcon(this.type, NodeIconType.VisualEntity);
errorHandlerGroupNode.data.icon = NodeIconResolver.getIcon(this.type, NodeIconType.Entity);

return errorHandlerGroupNode;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export class CamelInterceptFromVisualEntity
);
interceptFromGroupNode.data.entity = this;
interceptFromGroupNode.data.isGroup = true;
interceptFromGroupNode.data.icon = NodeIconResolver.getIcon(this.type, NodeIconType.VisualEntity);
interceptFromGroupNode.data.icon = NodeIconResolver.getIcon(this.type, NodeIconType.Entity);

return interceptFromGroupNode;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export class CamelInterceptSendToEndpointVisualEntity
);
interceptSendToEndpointGroupNode.data.entity = this;
interceptSendToEndpointGroupNode.data.isGroup = true;
interceptSendToEndpointGroupNode.data.icon = NodeIconResolver.getIcon(this.type, NodeIconType.VisualEntity);
interceptSendToEndpointGroupNode.data.icon = NodeIconResolver.getIcon(this.type, NodeIconType.Entity);

return interceptSendToEndpointGroupNode;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export class CamelInterceptVisualEntity
);
interceptGroupNode.data.entity = this;
interceptGroupNode.data.isGroup = true;
interceptGroupNode.data.icon = NodeIconResolver.getIcon(this.type, NodeIconType.VisualEntity);
interceptGroupNode.data.icon = NodeIconResolver.getIcon(this.type, NodeIconType.Entity);

return interceptGroupNode;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export class CamelOnCompletionVisualEntity
);
onCompletionGroupNode.data.entity = this;
onCompletionGroupNode.data.isGroup = true;
onCompletionGroupNode.data.icon = NodeIconResolver.getIcon(this.type, NodeIconType.VisualEntity);
onCompletionGroupNode.data.icon = NodeIconResolver.getIcon(this.type, NodeIconType.Entity);

return onCompletionGroupNode;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export class CamelOnExceptionVisualEntity
);
onExceptionGroupNode.data.entity = this;
onExceptionGroupNode.data.isGroup = true;
onExceptionGroupNode.data.icon = NodeIconResolver.getIcon(this.type, NodeIconType.VisualEntity);
onExceptionGroupNode.data.icon = NodeIconResolver.getIcon(this.type, NodeIconType.Entity);

return onExceptionGroupNode;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export class CamelRestConfigurationVisualEntity implements BaseVisualCamelEntity
);
restConfigurationGroupNode.data.entity = this;
restConfigurationGroupNode.data.isGroup = true;
restConfigurationGroupNode.data.icon = NodeIconResolver.getIcon(this.type, NodeIconType.VisualEntity);
restConfigurationGroupNode.data.icon = NodeIconResolver.getIcon(this.type, NodeIconType.Entity);

return restConfigurationGroupNode;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export class CamelRestVisualEntity extends AbstractCamelVisualEntity<{ rest: Res
);
restGroupNode.data.entity = this;
restGroupNode.data.isGroup = true;
restGroupNode.data.icon = NodeIconResolver.getIcon(this.type, NodeIconType.VisualEntity);
restGroupNode.data.icon = NodeIconResolver.getIcon(this.type, NodeIconType.Entity);

return restGroupNode;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ export class CamelRouteConfigurationVisualEntity
path: this.getRootPath(),
entity: this,
isGroup: true,
icon: NodeIconResolver.getIcon(this.type, NodeIconType.VisualEntity),
icon: NodeIconResolver.getIcon(this.type, NodeIconType.Entity),
processorName: this.getRootPath(),
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ export class PipeVisualEntity implements BaseVisualCamelEntity {
path: this.getRootPath(),
entity: this,
isGroup: true,
icon: NodeIconResolver.getIcon(this.type, NodeIconType.VisualEntity),
icon: NodeIconResolver.getIcon(this.type, NodeIconType.Entity),
});

const sourceNode = this.getVizNodeFromStep(this.pipe.spec!.source, 'source', true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,4 +149,13 @@ describe('CamelComponentDefaultService', () => {
expect(removeHeadersDefault.removeHeaders.pattern).toEqual('*');
});
});

it('should return the default value for a intercept entity', () => {
const interceptDefault = CamelComponentDefaultService.getDefaultNodeDefinitionValue({
type: 'entity',
name: 'intercept',
} as DefinedComponent) as any;
expect(interceptDefault.intercept).toBeDefined();
expect(interceptDefault.intercept.id as string).toMatch(/^intercept-/);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export class CamelComponentDefaultService {
case CatalogKind.Kamelet:
return this.getDefaultValueFromKamelet(definedComponent.name);
case CatalogKind.Processor:
case CatalogKind.Entity:
return this.getDefaultValueFromProcessor(definedComponent.name as keyof ProcessorDefinition);
default:
return {};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { CamelRouteVisualEntityData } from './camel-component-types';

export class CamelComponentFilterService {
static readonly REST_DSL_METHODS = ['delete', 'get', 'head', 'patch', 'post', 'put'];
private static SPECIAL_CHILDREN = [
private static SPECIAL_PROCESSORS = [
'when',
'otherwise',
'doCatch',
Expand All @@ -17,6 +17,15 @@ export class CamelComponentFilterService {
'onCompletion',
...this.REST_DSL_METHODS,
];
/**
* specialChildren is a map of processor names and their special children.
*/
static readonly SPECIAL_PROCESSORS_PARENTS_MAP = {
choice: ['when', 'otherwise'],
doTry: ['doCatch', 'doFinally'],
routeConfiguration: ['intercept', 'interceptFrom', 'interceptSendToEndpoint', 'onException', 'onCompletion'],
rest: this.REST_DSL_METHODS,
};

static getCamelCompatibleComponents(
mode: AddStepMode,
Expand All @@ -41,35 +50,28 @@ export class CamelComponentFilterService {
}

if (mode === AddStepMode.InsertSpecialChildStep) {
/**
* specialChildren is a map of processor names and their special children.
*/
const specialChildren: Record<string, string[]> = {
choice: ['when'],
doTry: ['doCatch'],
routeConfiguration: ['intercept', 'interceptFrom', 'interceptSendToEndpoint', 'onException', 'onCompletion'],
rest: this.REST_DSL_METHODS,
};
const { processorName } = visualEntityData;
if (!(processorName in this.SPECIAL_PROCESSORS_PARENTS_MAP)) {
return () => false;
}

let childrenLookup: string[] =
this.SPECIAL_PROCESSORS_PARENTS_MAP[processorName as keyof typeof this.SPECIAL_PROCESSORS_PARENTS_MAP];
/** If an `otherwise` or a `doFinally` already exists, we shouldn't offer it in the catalog */
const definitionKeys = Object.keys(definition ?? {});
if (!definitionKeys.includes('otherwise')) {
specialChildren.choice.push('otherwise');
if (processorName === 'choice' && definitionKeys.includes('otherwise')) {
childrenLookup = childrenLookup.filter((child) => child !== 'otherwise');
}
if (!definitionKeys.includes('doFinally')) {
specialChildren.doTry.push('doFinally');
if (processorName === 'doTry' && definitionKeys.includes('doFinally')) {
childrenLookup = childrenLookup.filter((child) => child !== 'doFinally');
}

/**
* For special child steps, we need to check which type of processor it is, in order to determine
* what kind of components we want to show.
*/
return (item: ITile) => {
if (item.type !== CatalogKind.Processor || specialChildren[visualEntityData.processorName] === undefined) {
return false;
}

return specialChildren[visualEntityData.processorName].includes(item.name);
return childrenLookup.includes(item.name);
};
}

Expand All @@ -79,7 +81,7 @@ export class CamelComponentFilterService {
*/
return (item: ITile) => {
return (
(item.type === CatalogKind.Processor && !this.SPECIAL_CHILDREN.includes(item.name)) ||
(item.type === CatalogKind.Processor && !this.SPECIAL_PROCESSORS.includes(item.name)) ||
(item.type === CatalogKind.Component && !item.tags.includes('consumerOnly')) ||
(item.type === CatalogKind.Kamelet && !item.tags.includes('source') && item.name !== 'sink')
);
Expand Down
3 changes: 2 additions & 1 deletion packages/ui/src/providers/catalog-tiles.provider.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,10 @@ describe('CatalogTilesProvider', () => {
);
});

expect(getCatalogByKeySpy).toHaveBeenCalledTimes(3);
expect(getCatalogByKeySpy).toHaveBeenCalledTimes(4);
expect(getCatalogByKeySpy).toHaveBeenCalledWith(CatalogKind.Component);
expect(getCatalogByKeySpy).toHaveBeenCalledWith(CatalogKind.Pattern);
expect(getCatalogByKeySpy).toHaveBeenCalledWith(CatalogKind.Entity);
expect(getCatalogByKeySpy).toHaveBeenCalledWith(CatalogKind.Kamelet);
});

Expand Down
9 changes: 8 additions & 1 deletion packages/ui/src/providers/catalog-tiles.provider.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { FunctionComponent, PropsWithChildren, createContext, useContext, useMemo } from 'react';
import { camelComponentToTile, camelProcessorToTile, kameletToTile } from '../camel-utils';
import { camelComponentToTile, camelEntityToTile, camelProcessorToTile, kameletToTile } from '../camel-utils';
import { ITile } from '../components/Catalog';
import { CatalogKind } from '../models';
import { CatalogContext } from './catalog.provider';
import { isDefined } from '../utils';

export const CatalogTilesContext = createContext<ITile[]>([]);

Expand All @@ -28,6 +29,12 @@ export const CatalogTilesProvider: FunctionComponent<PropsWithChildren> = (props
Object.values(catalogService.getCatalogByKey(CatalogKind.Pattern) ?? {}).forEach((processor) => {
combinedTiles.push(camelProcessorToTile(processor));
});
Object.values(catalogService.getCatalogByKey(CatalogKind.Entity) ?? {}).forEach((entity) => {
/** KameletConfiguration and PipeConfiguration schemas are stored inside the entity catalog without model or properties */
if (isDefined(entity.model)) {
combinedTiles.push(camelEntityToTile(entity));
}
});
Object.values(catalogService.getCatalogByKey(CatalogKind.Kamelet) ?? {}).forEach((kamelet) => {
combinedTiles.push(kameletToTile(kamelet));
});
Expand Down
4 changes: 2 additions & 2 deletions packages/ui/src/utils/node-icon-resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ export const enum NodeIconType {
Component = 'Component',
EIP = 'EIP',
Kamelet = 'Kamelet',
VisualEntity = 'VisualEntity',
Entity = 'Entity',
}

export class NodeIconResolver {
Expand All @@ -257,7 +257,7 @@ export class NodeIconResolver {
return this.getComponentIcon(elementName) ?? this.getDefaultCamelIcon();
case NodeIconType.EIP:
return this.getEIPIcon(elementName) ?? this.getDefaultCamelIcon();
case NodeIconType.VisualEntity:
case NodeIconType.Entity:
return this.getVisualEntityIcon(elementName) ?? this.getDefaultCamelIcon();
}
}
Expand Down

0 comments on commit b8a8dfa

Please sign in to comment.