From 50fd5f85edcd75414649b4bb1c4b3edc324a5a79 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Fri, 28 Jan 2022 21:25:01 +0100 Subject: [PATCH] Incremental work on dynamic ports --- .../flowchart/default-node-handler.ts | 28 +++++---- .../flowchart/default-port-provider.ts | 33 +++++++++++ .../flowchart/port-provider-registry.ts | 21 +++++++ .../activities/flowchart/port-provider.ts | 11 ++++ .../plugins/switch/switch-activity-driver.tsx | 28 +++++++++ .../src/plugins/switch/switch-node-handler.ts | 58 ------------------- .../src/plugins/switch/switch-plugin.tsx | 13 +++-- .../plugins/switch/switch-port-provider.ts | 13 +++++ 8 files changed, 126 insertions(+), 79 deletions(-) create mode 100644 src/designer/elsa-workflows-designer/src/components/activities/flowchart/default-port-provider.ts create mode 100644 src/designer/elsa-workflows-designer/src/components/activities/flowchart/port-provider-registry.ts create mode 100644 src/designer/elsa-workflows-designer/src/components/activities/flowchart/port-provider.ts create mode 100644 src/designer/elsa-workflows-designer/src/plugins/switch/switch-activity-driver.tsx delete mode 100644 src/designer/elsa-workflows-designer/src/plugins/switch/switch-node-handler.ts create mode 100644 src/designer/elsa-workflows-designer/src/plugins/switch/switch-port-provider.ts diff --git a/src/designer/elsa-workflows-designer/src/components/activities/flowchart/default-node-handler.ts b/src/designer/elsa-workflows-designer/src/components/activities/flowchart/default-node-handler.ts index 4a36043ab..6376437c5 100644 --- a/src/designer/elsa-workflows-designer/src/components/activities/flowchart/default-node-handler.ts +++ b/src/designer/elsa-workflows-designer/src/components/activities/flowchart/default-node-handler.ts @@ -1,26 +1,24 @@ import 'reflect-metadata'; import {Node} from "@antv/x6"; -import {Service} from "typedi" +import {Container, Service} from "typedi" import {ActivityNodeHandler, CreateUINodeContext} from "./activity-node-handler"; -import {Port} from "../../../models"; +import {PortProviderRegistry} from "./port-provider-registry"; +import {PortProviderContext} from "./port-provider"; @Service() export class DefaultNodeHandler implements ActivityNodeHandler { + private readonly portProviderRegistry: PortProviderRegistry; + + constructor() { + this.portProviderRegistry = Container.get(PortProviderRegistry); + } + createDesignerNode(context: CreateUINodeContext): Node.Metadata { const {activityDescriptor, activity, x, y} = context; - let inPorts: Array = [...activityDescriptor.inPorts]; - let outPorts: Array = [...activityDescriptor.outPorts]; - - if (inPorts.length == 0) - inPorts = [{name: 'In', displayName: 'In'}]; - - if (inPorts.length == 1) - inPorts[0].displayName = null; - - outPorts = [...outPorts, {name: 'Done', displayName: 'Done'}]; - - if (outPorts.length == 1) - outPorts[0].displayName = null; + const provider = this.portProviderRegistry.get(activityDescriptor.nodeType); + const providerContext: PortProviderContext = { activityDescriptor, activity }; + let inPorts = provider.getInboundPorts(providerContext); + let outPorts = provider.getOutboundPorts(providerContext); const inPortModels = inPorts.map(x => ({ id: x.name, diff --git a/src/designer/elsa-workflows-designer/src/components/activities/flowchart/default-port-provider.ts b/src/designer/elsa-workflows-designer/src/components/activities/flowchart/default-port-provider.ts new file mode 100644 index 000000000..1b1cf150a --- /dev/null +++ b/src/designer/elsa-workflows-designer/src/components/activities/flowchart/default-port-provider.ts @@ -0,0 +1,33 @@ +import 'reflect-metadata'; +import {Service} from "typedi" +import {Port} from "../../../models"; +import {PortProvider, PortProviderContext} from "./port-provider"; + +@Service() +export class DefaultPortProvider implements PortProvider { + getInboundPorts(context: PortProviderContext): Array { + const {activityDescriptor} = context; + let inPorts: Array = [...activityDescriptor.inPorts]; + + if (inPorts.length == 0) + inPorts = [{name: 'In', displayName: 'In'}]; + + if (inPorts.length == 1) + inPorts[0].displayName = null; + + return inPorts; + } + + getOutboundPorts(context: PortProviderContext): Array { + const {activityDescriptor} = context; + let outPorts: Array = [...activityDescriptor.outPorts]; + + outPorts = [...outPorts, {name: 'Done', displayName: 'Done'}]; + + if (outPorts.length == 1) + outPorts[0].displayName = null; + + return outPorts; + } + +} diff --git a/src/designer/elsa-workflows-designer/src/components/activities/flowchart/port-provider-registry.ts b/src/designer/elsa-workflows-designer/src/components/activities/flowchart/port-provider-registry.ts new file mode 100644 index 000000000..f3b169989 --- /dev/null +++ b/src/designer/elsa-workflows-designer/src/components/activities/flowchart/port-provider-registry.ts @@ -0,0 +1,21 @@ +import 'reflect-metadata'; +import {Container, Service} from "typedi"; +import {PortProvider} from "./port-provider"; +import {DefaultPortProvider} from "./default-port-provider"; + +export type PortProviderFactory = () => PortProvider; + +@Service() +export class PortProviderRegistry { + private map: Map = new Map(); + private defaultProviderFactory: PortProviderFactory = () => Container.get(DefaultPortProvider); + + public register(activityType: string, defaultProviderFactory: PortProviderFactory) { + this.map.set(activityType, defaultProviderFactory); + } + + public get(activityType: string): PortProvider { + const factory = this.map.get(activityType) ?? this.defaultProviderFactory; + return factory(); + } +} diff --git a/src/designer/elsa-workflows-designer/src/components/activities/flowchart/port-provider.ts b/src/designer/elsa-workflows-designer/src/components/activities/flowchart/port-provider.ts new file mode 100644 index 000000000..33c2b164e --- /dev/null +++ b/src/designer/elsa-workflows-designer/src/components/activities/flowchart/port-provider.ts @@ -0,0 +1,11 @@ +import {Activity, ActivityDescriptor, Port} from "../../../models"; + +export interface PortProvider { + getInboundPorts(context: PortProviderContext): Array; + getOutboundPorts(context: PortProviderContext): Array; +} + +export interface PortProviderContext { + activityDescriptor: ActivityDescriptor; + activity: Activity; +} diff --git a/src/designer/elsa-workflows-designer/src/plugins/switch/switch-activity-driver.tsx b/src/designer/elsa-workflows-designer/src/plugins/switch/switch-activity-driver.tsx new file mode 100644 index 000000000..27b6931db --- /dev/null +++ b/src/designer/elsa-workflows-designer/src/plugins/switch/switch-activity-driver.tsx @@ -0,0 +1,28 @@ +import 'reflect-metadata'; +import {h} from "@stencil/core"; +import {Container, Service} from "typedi"; +import {ActivityTraits} from '../../models'; +import {ActivityDisplayContext, ActivityDriver, ActivityIcon, ActivityIconRegistry} from '../../services'; + +@Service() +export class SwitchActivityDriver implements ActivityDriver { + + display(context: ActivityDisplayContext): any { + const activityDescriptor = context.activityDescriptor; + const text = activityDescriptor?.displayName; + + return (` +
+
+
+
+
+ ${text} +
+
+
+
+
+ `); + } +} diff --git a/src/designer/elsa-workflows-designer/src/plugins/switch/switch-node-handler.ts b/src/designer/elsa-workflows-designer/src/plugins/switch/switch-node-handler.ts deleted file mode 100644 index a6e3ee362..000000000 --- a/src/designer/elsa-workflows-designer/src/plugins/switch/switch-node-handler.ts +++ /dev/null @@ -1,58 +0,0 @@ -import 'reflect-metadata'; -import {Node} from '@antv/x6'; -import {Service} from 'typedi'; -import {ActivityNodeHandler} from "../../components/activities/flowchart/activity-node-handler"; -import {Port} from "../../models"; - -@Service() -export class SwitchNodeHandler implements ActivityNodeHandler { - createDesignerNode(context): Node.Metadata { - const {activityDescriptor, activity, x, y} = context; - let inPorts: Array = [...activityDescriptor.inPorts]; - let outPorts: Array = [...activityDescriptor.outPorts]; - - if (inPorts.length == 0) - inPorts = [{name: 'In', displayName: 'In'}]; - - if (inPorts.length == 1) - inPorts[0].displayName = null; - - outPorts = [...outPorts, {name: 'Done', displayName: 'Done'}]; - - if (outPorts.length == 1) - outPorts[0].displayName = null; - - const inPortModels = inPorts.map(x => ({ - id: x.name, - group: 'in', - attrs: !!x.displayName ? { - text: { - text: x.displayName - } - } : null - })); - - const outPortModels = outPorts.map(x => ({ - id: x.name, - group: 'out', - attrs: { - text: { - text: x.displayName - } - } - })); - - const portModels = [...inPortModels, ...outPortModels]; - - return { - id: activity.id, - shape: 'activity', - activity: activity, - activityDescriptor: activityDescriptor, - x: x, - y: y, - data: activity, - ports: portModels - } as Node.Metadata; - } -} diff --git a/src/designer/elsa-workflows-designer/src/plugins/switch/switch-plugin.tsx b/src/designer/elsa-workflows-designer/src/plugins/switch/switch-plugin.tsx index 6f965c211..5126cc515 100644 --- a/src/designer/elsa-workflows-designer/src/plugins/switch/switch-plugin.tsx +++ b/src/designer/elsa-workflows-designer/src/plugins/switch/switch-plugin.tsx @@ -1,20 +1,21 @@ import 'reflect-metadata'; import {h} from '@stencil/core'; import {Container, Service} from "typedi"; -import {InputControlRegistry} from "../../services"; +import {ActivityDriverRegistry, InputControlRegistry} from "../../services"; import {Plugin} from "../../models"; -import {NodeHandlerRegistry} from "../../components/activities/flowchart/node-handler-registry"; -import {SwitchNodeHandler} from "./switch-node-handler"; +import {SwitchActivityDriver} from "./switch-activity-driver"; @Service() export class SwitchPlugin implements Plugin { + private static readonly ActivityTypeName: string = 'ControlFlow.Switch'; constructor() { + const activityTypeName = SwitchPlugin.ActivityTypeName; + const driverRegistry = Container.get(ActivityDriverRegistry); const inputControlRegistry = Container.get(InputControlRegistry); - const nodeHandlerRegistry = Container.get(NodeHandlerRegistry); - inputControlRegistry.add('switch-editor', c => ) - nodeHandlerRegistry.add('ControlFlow.Switch', () => Container.get(SwitchNodeHandler)); + driverRegistry.add(activityTypeName, () => Container.get(SwitchActivityDriver)); + inputControlRegistry.add('switch-editor', c => ); } } diff --git a/src/designer/elsa-workflows-designer/src/plugins/switch/switch-port-provider.ts b/src/designer/elsa-workflows-designer/src/plugins/switch/switch-port-provider.ts new file mode 100644 index 000000000..44a9498e6 --- /dev/null +++ b/src/designer/elsa-workflows-designer/src/plugins/switch/switch-port-provider.ts @@ -0,0 +1,13 @@ +import {PortProvider, PortProviderContext} from "../../components/activities/flowchart/port-provider"; +import {Port} from "../../models"; + +export class SwitchPortProvider implements PortProvider { + getInboundPorts(context: PortProviderContext): Array { + return undefined; + } + + getOutboundPorts(context: PortProviderContext): Array { + return undefined; + } + +}