Skip to content

Commit

Permalink
feat: Indication that some of the connectors mandatory properties are…
Browse files Browse the repository at this point in the history
… not yet configured

Fixes: #126
  • Loading branch information
igarashitm committed Jan 17, 2024
1 parent 1d2998c commit e1c404a
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ export class CanvasService {
width: CanvasDefaults.DEFAULT_NODE_DIAMETER,
height: CanvasDefaults.DEFAULT_NODE_DIAMETER,
shape: CanvasDefaults.DEFAULT_NODE_SHAPE,
status: options.data?.vizNode?.getStatus(),
};
}

Expand Down
11 changes: 10 additions & 1 deletion packages/ui/src/components/Visualization/Custom/CustomNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,18 @@ interface CustomNodeProps extends WithSelectionProps {
const CustomNode: FunctionComponent<CustomNodeProps> = ({ element, ...rest }) => {
const vizNode = element.getData()?.vizNode;
const label = vizNode?.getNodeLabel();
const statusDecoratorTooltip = vizNode?.getStatusDecoratorTooltip();

return (
<DefaultNode element={element} label={label} truncateLength={15} {...rest} showStatusDecorator>
<DefaultNode
element={element}
label={label}
truncateLength={15}
{...rest}
showStatusDecorator
statusDecoratorTooltip={statusDecoratorTooltip}
onStatusDecoratorClick={() => {}}
>
<g data-testid={`custom-node__${vizNode?.id}`} data-nodelabel={label}>
<foreignObject
x="0"
Expand Down
9 changes: 9 additions & 0 deletions packages/ui/src/models/visualization/base-visual-entity.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { JSONSchemaType } from 'ajv';
import { DefinedComponent } from '../camel-catalog-index';
import { BaseCamelEntity, EntityType } from '../camel/entities';
import { NodeStatus } from '@patternfly/react-topology';

/**
* BaseVisualCamelEntity
Expand Down Expand Up @@ -94,6 +95,14 @@ export interface IVisualizationNode<T extends IVisualizationNodeData = IVisualiz
removeChild(): void;

populateLeafNodesIds(ids: string[]): void;

getStatus(): NodeStatus | undefined;

setStatus(status: NodeStatus): void;

getStatusDecoratorTooltip(): string | undefined;

setStatusDecoratorTooltip(tooltip: string): void;
}

export interface IVisualizationNodeData {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,22 @@ import {
ICamelElementLookupResult,
} from './support/camel-component-types';
import { EntityType } from '../../camel/entities';
import Ajv from 'ajv';
import { NodeStatus } from '@patternfly/react-topology';

export abstract class AbstractCamelVisualEntity implements BaseVisualCamelEntity {
constructor(public route: RouteDefinition) {}
constructor(public route: RouteDefinition) {
this.ajv = new Ajv({
allErrors: true,
useDefaults: true,
});
}

abstract id: string;
abstract type: EntityType;
abstract setId(id: string): void;
protected abstract getRootUri(): string | undefined;
protected ajv: Ajv;

getId(): string {
return this.id;
Expand Down Expand Up @@ -240,9 +248,34 @@ export abstract class AbstractCamelVisualEntity implements BaseVisualCamelEntity
childrenVizNodes.forEach((childVizNode) => vizNode.addChild(childVizNode));
});

this.setNodeStatus(path, vizNode);
return vizNode;
}

private setNodeStatus(path: string, vizNode: IVisualizationNode) {
const schema = this.getComponentSchema(path);
if (schema?.schema) {
const validator = this.ajv.compile(schema?.schema);
validator(get(this.route, path));
const missingProperties = validator.errors?.reduce((acc, error) => {
if (error.keyword === 'required' && error.params?.missingProperty) {
acc.push(error.params.missingProperty);
}
return acc;
}, [] as string[]);
if (missingProperties && missingProperties.length > 0) {
const message =
missingProperties.length > 1
? `${missingProperties.length} required properties are not yet configured: [ ${missingProperties} ]`
: `1 required property is not yet configured: [ ${missingProperties} ]`;
vizNode.setStatus(NodeStatus.warning);
vizNode.setStatusDecoratorTooltip(message);
} else {
vizNode.setStatus(NodeStatus.success);
}
}
}

private getVizNodesFromChildren(path: string, stepsProperty: CamelProcessorStepsProperties): IVisualizationNode[] {
let singlePath: string;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ spec:
template:
from:
id: ${getCamelRandomId('from')}
uri: "timer:user"
uri: "timer"
parameters:
timerName: user
period: "{{period}}"
steps:
- to: https://random-data-api.com/api/v2/users
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ export const routeTemplate = () => {
id: ${getCamelRandomId('route')}
from:
id: ${getCamelRandomId('from')}
uri: timer:template
uri: timer
parameters:
timerName: template
period: "1000"
steps:
- log:
Expand Down
19 changes: 19 additions & 0 deletions packages/ui/src/models/visualization/visualization-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
NodeInteraction,
VisualComponentSchema,
} from './base-visual-entity';
import { NodeStatus } from '@patternfly/react-topology';

export const createVisualizationNode = <T extends IVisualizationNodeData = IVisualizationNodeData>(
id: string,
Expand All @@ -24,6 +25,8 @@ class VisualizationNode<T extends IVisualizationNodeData = IVisualizationNodeDat
private previousNode: IVisualizationNode | undefined = undefined;
private nextNode: IVisualizationNode | undefined = undefined;
private children: IVisualizationNode[] | undefined;
private status: NodeStatus | undefined = undefined;
private statusDecoratorTooltip: string | undefined = undefined;

constructor(
public readonly id: string,
Expand Down Expand Up @@ -128,4 +131,20 @@ class VisualizationNode<T extends IVisualizationNodeData = IVisualizationNodeDat
/** If this node has children, populate the leaf nodes ids of each child */
this.children?.forEach((child) => child.populateLeafNodesIds(ids));
}

getStatus(): NodeStatus | undefined {
return this.status;
}

setStatus(status: NodeStatus) {
this.status = status;
}

getStatusDecoratorTooltip(): string | undefined {
return this.statusDecoratorTooltip;
}

setStatusDecoratorTooltip(tooltip: string) {
this.statusDecoratorTooltip = tooltip;
}
}

0 comments on commit e1c404a

Please sign in to comment.