diff --git a/src/designer/elsa-workflows-designer/src/components.d.ts b/src/designer/elsa-workflows-designer/src/components.d.ts index 70289fa53..c49c7b2f6 100644 --- a/src/designer/elsa-workflows-designer/src/components.d.ts +++ b/src/designer/elsa-workflows-designer/src/components.d.ts @@ -5,7 +5,7 @@ * It contains typing information for all components that exist in this project. */ import { HTMLStencilElement, JSXBase } from "@stencil/core/internal"; -import { ActionDefinition, ActionInvokedArgs, Activity, ActivitySelectedArgs, ContainerSelectedArgs, CreateChildActivityArgs, GraphUpdatedArgs, IntellisenseContext, SelectListItem, TabChangedArgs, TabDefinition, Variable, WorkflowDefinition, WorkflowDefinitionSummary, WorkflowInstance, WorkflowInstanceSummary } from "./models"; +import { ActionDefinition, ActionInvokedArgs, Activity, ActivitySelectedArgs, ContainerSelectedArgs, CreateChildActivityArgs, EditChildActivityArgs, GraphUpdatedArgs, IntellisenseContext, SelectListItem, TabChangedArgs, TabDefinition, Variable, WorkflowDefinition, WorkflowDefinitionSummary, WorkflowInstance, WorkflowInstanceSummary } from "./models"; import { ActivityUpdatedArgs, DeleteActivityRequestedArgs } from "./components/designer/workflow-definition-editor/activity-properties-editor"; import { Button } from "./components/shared/button-group/models"; import { ContainerActivityComponent } from "./components/activities/container-activity-component"; @@ -68,7 +68,6 @@ export namespace Components { "value": string; } interface ElsaDefaultActivityTemplate { - "activity": Activity; "activityJson": string; "activityType": string; "displayType": string; @@ -86,9 +85,9 @@ export namespace Components { interface ElsaFlowchart { "addActivity": (args: AddActivityArgs) => Promise; "clear": () => Promise; - "exportRoot": () => Promise; + "export": () => Promise; "getGraph": () => Promise; - "importRoot": (root: Activity) => Promise; + "import": (root: Activity) => Promise; "interactiveMode": boolean; "root"?: Activity; "updateLayout": () => Promise; @@ -665,11 +664,11 @@ declare namespace LocalJSX { "value"?: string; } interface ElsaDefaultActivityTemplate { - "activity"?: Activity; "activityJson"?: string; "activityType"?: string; "displayType"?: string; "onCreateChildActivity"?: (event: CustomEvent) => void; + "onEditChildActivity"?: (event: CustomEvent) => void; "selected"?: boolean; } interface ElsaDropdownButton { @@ -856,6 +855,7 @@ declare namespace LocalJSX { } interface ElsaWorkflowNavigator { "items"?: Array; + "onNavigate"?: (event: CustomEvent) => void; } interface ElsaWorkflowPublishButton { "onExportClicked"?: (event: CustomEvent) => void; diff --git a/src/designer/elsa-workflows-designer/src/components/activities/container-activity-component.tsx b/src/designer/elsa-workflows-designer/src/components/activities/container-activity-component.tsx index 4bc59afe7..2454a23a9 100644 --- a/src/designer/elsa-workflows-designer/src/components/activities/container-activity-component.tsx +++ b/src/designer/elsa-workflows-designer/src/components/activities/container-activity-component.tsx @@ -4,8 +4,8 @@ import {Activity} from '../../models'; export interface ContainerActivityComponent { updateLayout(): Promise; addActivity(args: AddActivityArgs): Promise; - exportRoot(): Promise - importRoot(root: Activity): Promise; + export(): Promise + import(root: Activity): Promise; zoomToFit(): Promise; clear(): Promise; } 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 4b163c0f6..a262e4b2f 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 @@ -2,8 +2,7 @@ import 'reflect-metadata'; import {Node} from "@antv/x6"; import {Container, Service} from "typedi" import {ActivityNodeHandler, CreateUINodeContext} from "./activity-node-handler"; -import {PortProviderRegistry} from "./port-provider-registry"; -import {PortProviderContext} from "./port-provider"; +import {PortProviderContext, PortProviderRegistry} from "../../../services"; @Service() export class DefaultNodeHandler implements ActivityNodeHandler { diff --git a/src/designer/elsa-workflows-designer/src/components/activities/flowchart/flowchart.tsx b/src/designer/elsa-workflows-designer/src/components/activities/flowchart/flowchart.tsx index 630656425..28c14ac82 100644 --- a/src/designer/elsa-workflows-designer/src/components/activities/flowchart/flowchart.tsx +++ b/src/designer/elsa-workflows-designer/src/components/activities/flowchart/flowchart.tsx @@ -108,13 +108,13 @@ export class FlowchartComponent implements ContainerActivityComponent { } @Method() - async exportRoot(): Promise { - return this.exportRootInternal(); + async export(): Promise { + return this.exportInternal(); } @Method() - async importRoot(root: Activity): Promise { - return this.importRootInternal(root); + async import(root: Activity): Promise { + return this.importInternal(root); } async componentDidLoad() { @@ -184,7 +184,7 @@ export class FlowchartComponent implements ContainerActivityComponent { await this.updateLayout(); } - private exportRootInternal = (): Activity => { + private exportInternal = (): Activity => { const graph = this.graph; const graphModel = graph.toJSON(); const activities = graphModel.cells.filter(x => x.shape == 'activity').map(x => x.data as Activity); @@ -209,7 +209,7 @@ export class FlowchartComponent implements ContainerActivityComponent { } as Flowchart; } - private importRootInternal = async (root: Activity) => { + private importInternal = async (root: Activity) => { this.rootId = root.id; const descriptors = descriptorsStore.activityDescriptors; const flowchart = root as Flowchart; @@ -280,7 +280,7 @@ export class FlowchartComponent implements ContainerActivityComponent { @Watch('root') async onRootChange(value: Activity) { - await this.importRootInternal(value); + await this.importInternal(value); } @Watch('interactiveMode') @@ -413,7 +413,7 @@ export class FlowchartComponent implements ContainerActivityComponent { onGraphChanged = async () => { if (this.silent) return; - this.graphUpdated.emit({exportGraph: this.exportRootInternal}); + this.graphUpdated.emit({exportGraph: this.exportInternal}); } onToggleCanStartWorkflowClicked = (node: ActivityNodeShape) => { diff --git a/src/designer/elsa-workflows-designer/src/components/designer/activity-templates/default-activity-template.tsx b/src/designer/elsa-workflows-designer/src/components/designer/activity-templates/default-activity-template.tsx index 88e87beeb..9840704dc 100644 --- a/src/designer/elsa-workflows-designer/src/components/designer/activity-templates/default-activity-template.tsx +++ b/src/designer/elsa-workflows-designer/src/components/designer/activity-templates/default-activity-template.tsx @@ -2,7 +2,7 @@ import {Component, h, Prop, State, Event, EventEmitter, Listen, Element} from "@ import {camelCase} from 'lodash'; import {ActivityIcon, ActivityIconRegistry} from "../../../services"; import {Container} from "typedi"; -import {Activity, ActivityDescriptor, ActivityKind, CreateChildActivityArgs, Port} from "../../../models"; +import {Activity, ActivityDescriptor, ActivityKind, CreateChildActivityArgs, EditChildActivityArgs, Port} from "../../../models"; import descriptorsStore from "../../../data/descriptors-store"; import {isNullOrWhitespace} from "../../../utils"; @@ -25,24 +25,18 @@ export class DefaultActivityTemplate { @Prop({attribute: 'display-type'}) displayType: string; @Prop({attribute: 'activity'}) activityJson: string; @Prop() selected: boolean; - @Prop() activity: Activity; @Event() createChildActivity: EventEmitter; + @Event() editChildActivity: EventEmitter; @State() private selectedPortName: string; componentWillLoad() { const iconRegistry = this.iconRegistry; - if (!!this.activity) { - { - this.parsedActivity = this.activity; - } - } else { - const encodedActivityJson = this.activityJson; + const encodedActivityJson = this.activityJson; - if (!isNullOrWhitespace(encodedActivityJson)) { - const decodedActivityJson = decodeURI(encodedActivityJson); - this.parsedActivity = JSON.parse(decodedActivityJson); - } + if (!isNullOrWhitespace(encodedActivityJson)) { + const decodedActivityJson = decodeURI(encodedActivityJson); + this.parsedActivity = JSON.parse(decodedActivityJson); } this.activityDescriptor = descriptorsStore.activityDescriptors.find(x => x.activityType == this.activityType); @@ -150,7 +144,11 @@ export class DefaultActivityTemplate { {childActivityDisplayText}
- + this.onEditChildActivityClick(e, activity, port)} + onMouseDown={e => e.stopPropagation()} + href="#" + class="text-gray-500 hover:text-yellow-700"> @@ -163,7 +161,7 @@ export class DefaultActivityTemplate { ) : (
this.onAddChildActivityClick(e, activity, port)} + onClick={e => this.onEditChildActivityClick(e, activity, port)} onMouseDown={e => e.stopPropagation()} class="text-gray-400 hover:text-gray-600"> @@ -197,6 +195,11 @@ export class DefaultActivityTemplate { private onAddChildActivityClick = (e: MouseEvent, parentActivity: Activity, port: Port) => { e.preventDefault(); - this.createChildActivity.emit({parent: parentActivity, port: port}); + this.createChildActivity.emit({parentActivityId: parentActivity.id, port: port}); + }; + + private onEditChildActivityClick = (e: MouseEvent, parentActivity: Activity, port: Port) => { + e.preventDefault(); + this.editChildActivity.emit({parentActivityId: parentActivity.id, port: port}); }; } diff --git a/src/designer/elsa-workflows-designer/src/components/designer/canvas/canvas.tsx b/src/designer/elsa-workflows-designer/src/components/designer/canvas/canvas.tsx index c019e1159..542442073 100644 --- a/src/designer/elsa-workflows-designer/src/components/designer/canvas/canvas.tsx +++ b/src/designer/elsa-workflows-designer/src/components/designer/canvas/canvas.tsx @@ -36,7 +36,7 @@ export class Canvas { @Method() public async exportGraph(): Promise { - return await this.root.exportRoot(); + return await this.root.export(); } @Method() @@ -46,7 +46,7 @@ export class Canvas { @Method() public async importGraph(root: Activity): Promise { - return await this.root.importRoot(root); + return await this.root.import(root); } @Method() diff --git a/src/designer/elsa-workflows-designer/src/components/designer/workflow-definition-editor/workflow-definition-editor.tsx b/src/designer/elsa-workflows-designer/src/components/designer/workflow-definition-editor/workflow-definition-editor.tsx index 3577a2c39..bb772bb35 100644 --- a/src/designer/elsa-workflows-designer/src/components/designer/workflow-definition-editor/workflow-definition-editor.tsx +++ b/src/designer/elsa-workflows-designer/src/components/designer/workflow-definition-editor/workflow-definition-editor.tsx @@ -1,13 +1,12 @@ import {Component, h, Listen, Prop, State, Event, EventEmitter, Method, Watch, Element} from '@stencil/core'; -import {debounce} from 'lodash'; -import {v4 as uuid} from 'uuid'; +import {debounce, camelCase} from 'lodash'; import {Container} from "typedi"; import {PanelPosition, PanelStateChangedArgs} from '../panel/models'; import { Activity, ActivityDescriptor, ActivitySelectedArgs, - ContainerSelectedArgs, CreateChildActivityArgs, + ContainerSelectedArgs, CreateChildActivityArgs, EditChildActivityArgs, GraphUpdatedArgs, StorageDriverDescriptor, WorkflowDefinition } from '../../../models'; @@ -16,10 +15,9 @@ import { ActivityUpdatedArgs, DeleteActivityRequestedArgs } from './activity-properties-editor'; -import {PluginRegistry, ActivityNameFormatter, ActivityDriverRegistry, EventBus} from '../../../services'; +import {PluginRegistry, ActivityNameFormatter, ActivityDriverRegistry, EventBus, findActivity, walkActivities, flattenList} from '../../../services'; import {MonacoEditorSettings} from "../../../services/monaco-editor-settings"; import {Flowchart} from "../../activities/flowchart/models"; -import {flattenList, walkActivities} from "../../activities/flowchart/activity-walker"; import {ActivityPropertyChangedEventArgs, WorkflowDefinitionPropsUpdatedArgs, WorkflowDefinitionUpdatedArgs, WorkflowEditorEventTypes} from "./models"; import descriptorsStore from "../../../data/descriptors-store"; import {WorkflowNavigationItem} from "../workflow-navigator/models"; @@ -51,12 +49,11 @@ export class WorkflowDefinitionEditor { } @Prop() workflowDefinition?: WorkflowDefinition; - @Prop({attribute: 'monaco-lib-path'}) public monacoLibPath: string; + @Prop({attribute: 'monaco-lib-path'}) monacoLibPath: string; @Event() workflowUpdated: EventEmitter @State() private workflowDefinitionState: WorkflowDefinition; @State() private selectedActivity?: Activity; - @State() private currentActivityPath: Array = []; - @State() private currentRootActivity: Activity; + @State() private currentWorkflowPath: Array = []; @Watch('monacoLibPath') private handleMonacoLibPath(value: string) { @@ -96,52 +93,60 @@ export class WorkflowDefinitionEditor { this.saveChangesDebounced(); } - @Listen('createChildActivity') - private async handleCreateChildActivity(e: CustomEvent) { + @Listen('editChildActivity') + private async editChildActivity(e: CustomEvent) { + const activity = findActivity(this.workflowDefinitionState.root, x => x.id == e.detail.parentActivityId); const item: WorkflowNavigationItem = { - activity: e.detail.parent, + activity: activity, port: e.detail.port, }; - this.currentActivityPath = [...this.currentActivityPath, item]; + this.currentWorkflowPath = [...this.currentWorkflowPath, item]; + const portName = camelCase(e.detail.port.name); + const childActivity = activity[portName] as Activity; - await this.canvas.clear(); + if (!childActivity) { + await this.canvas.clear(); + } else { + await this.canvas.importGraph(childActivity); + } } @Method() - public async getCanvas(): Promise { + async getCanvas(): Promise { return this.canvas; } @Method() - public async registerActivityDrivers(register: (registry: ActivityDriverRegistry) => void): Promise { + async registerActivityDrivers(register: (registry: ActivityDriverRegistry) => void): Promise { const registry = Container.get(ActivityDriverRegistry); register(registry); } @Method() - public getWorkflowDefinition(): Promise { + getWorkflowDefinition(): Promise { return this.getWorkflowDefinitionInternal(); } @Method() - public async importWorkflow(workflowDefinition: WorkflowDefinition): Promise { - this.workflowDefinitionState = workflowDefinition; - this.currentActivityPath = [{activity: workflowDefinition.root}]; - this.currentRootActivity = workflowDefinition.root; + async importWorkflow(workflowDefinition: WorkflowDefinition): Promise { + await this.updateWorkflowDefinition(workflowDefinition); await this.canvas.importGraph(workflowDefinition.root); await this.eventBus.emit(WorkflowEditorEventTypes.WorkflowDefinition.Imported, this, {workflowDefinition}); } // Updates the workflow definition without importing it into the designer. @Method() - public async updateWorkflowDefinition(workflowDefinition: WorkflowDefinition): Promise { + async updateWorkflowDefinition(workflowDefinition: WorkflowDefinition): Promise { this.workflowDefinitionState = workflowDefinition; + + if (this.currentWorkflowPath.length == 0 || this.currentWorkflowPath.length == 1) + this.currentWorkflowPath = [{activity: workflowDefinition.root, port: null}]; } @Method() - public async newWorkflow() { + async newWorkflow() { const flowchartDescriptor = descriptorsStore.activityDescriptors.find(x => x.activityType == 'Elsa.Flowchart'); const newName = await this.generateUniqueActivityName(flowchartDescriptor); @@ -167,15 +172,14 @@ export class WorkflowDefinitionEditor { materializerName: 'Json' } - await this.importWorkflow(workflowDefinition); } - public async componentWillLoad() { - this.workflowDefinitionState = this.workflowDefinition; + async componentWillLoad() { + await this.updateWorkflowDefinition(this.workflowDefinition); } - public async componentDidLoad() { + async componentDidLoad() { if (!this.workflowDefinitionState) await this.newWorkflow(); else @@ -184,7 +188,7 @@ export class WorkflowDefinitionEditor { await this.eventBus.emit(WorkflowEditorEventTypes.WorkflowEditor.Ready, this, {workflowEditor: this}); } - public render() { + render() { const tunnelState: WorkflowDesignerState = { workflowDefinition: this.workflowDefinitionState, }; @@ -193,7 +197,7 @@ export class WorkflowDefinitionEditor {
this.container = el}> - + => { - const root = await this.canvas.exportGraph(); + const activity: Activity = await this.canvas.exportGraph(); const workflowDefinition = this.workflowDefinitionState; - workflowDefinition.root = root; + const currentWorkflowPath = this.currentWorkflowPath; + const currentWorkflowNavigationItem = currentWorkflowPath[currentWorkflowPath.length - 1]; + let currentActivity = currentWorkflowNavigationItem.activity; + const currentPort = currentWorkflowNavigationItem.port; + + if (!!currentPort) { + const portName = camelCase(currentPort.name); + const flowchart = activity as Flowchart; + const activities = flowchart.activities; + const root = activities.length == 0 ? null : activities.length == 1 ? activities[0] : flowchart; + currentActivity[portName] = root; + currentWorkflowPath[currentWorkflowPath.length - 1] = {activity: currentActivity, port: currentPort}; + + } else { + workflowDefinition.root = activity; + currentWorkflowPath[0] = {activity: activity, port: null}; + } + return workflowDefinition; }; @@ -246,6 +267,7 @@ export class WorkflowDefinitionEditor { private saveChanges = async (): Promise => { const workflowDefinition = await this.getWorkflowDefinitionInternal(); + this.workflowDefinitionState = workflowDefinition; this.workflowUpdated.emit({workflowDefinition}); }; @@ -267,8 +289,7 @@ export class WorkflowDefinitionEditor { const activityType = activityDescriptor.activityType; const workflowDefinition = await this.getWorkflowDefinitionInternal(); const root = workflowDefinition.root; - const activityDescriptors = descriptorsStore.activityDescriptors; - const graph = walkActivities(root, activityDescriptors); + const graph = walkActivities(root); const activityNodes = flattenList(graph.children); const activityCount = activityNodes.filter(x => x.activity.typeName == activityType).length; let counter = activityCount + 1; @@ -315,4 +336,13 @@ export class WorkflowDefinitionEditor { this.deleteActivity(e.detail.activity); this.selectedActivity = null; }; + + private onNavigateHierarchy = async (e: CustomEvent) => { + const item = e.detail; + const path = this.currentWorkflowPath; + const index = path.indexOf(item); + + this.currentWorkflowPath = path.slice(0, index + 1); + await this.canvas.importGraph(item.activity); + } } diff --git a/src/designer/elsa-workflows-designer/src/components/designer/workflow-instance-viewer/workflow-journal.tsx b/src/designer/elsa-workflows-designer/src/components/designer/workflow-instance-viewer/workflow-journal.tsx index b41002c8e..0ef90577d 100644 --- a/src/designer/elsa-workflows-designer/src/components/designer/workflow-instance-viewer/workflow-journal.tsx +++ b/src/designer/elsa-workflows-designer/src/components/designer/workflow-instance-viewer/workflow-journal.tsx @@ -1,12 +1,10 @@ import {Component, h, Prop, State, Watch} from "@stencil/core"; import {ActionDefinition, ActionType, ActivityDescriptor, ActivityMetadata, WorkflowDefinition, WorkflowExecutionLogRecord, WorkflowInstance} from "../../../models"; import {Container} from "typedi"; -import {ElsaApiClientProvider} from "../../../services"; +import {ActivityNode, ElsaApiClientProvider, flatten, walkActivities} from "../../../services"; import {durationToString, formatTime, formatTimestamp, getDuration, isNullOrWhitespace} from "../../../utils"; -import {ActivityNode, flatten, walkActivities} from "../../activities/flowchart/activity-walker"; import descriptorsStore from '../../../data/descriptors-store'; import {ActivityExecutionEventBlock} from "./models"; -import {start} from "@stencil/core/dev-server"; const PAGE_SIZE: number = 20; @@ -118,8 +116,7 @@ export class WorkflowJournal { if (!this.workflowInstance || !this.workflowDefinition) return; - const activityDescriptors = descriptorsStore.activityDescriptors; - const rootNode = walkActivities(this.workflowDefinition.root, activityDescriptors); + const rootNode = walkActivities(this.workflowDefinition.root); const nodes = flatten(rootNode); this.activityNodes = nodes; }; diff --git a/src/designer/elsa-workflows-designer/src/components/designer/workflow-navigator/models.ts b/src/designer/elsa-workflows-designer/src/components/designer/workflow-navigator/models.ts index ed2d74f72..865daebae 100644 --- a/src/designer/elsa-workflows-designer/src/components/designer/workflow-navigator/models.ts +++ b/src/designer/elsa-workflows-designer/src/components/designer/workflow-navigator/models.ts @@ -1,6 +1,6 @@ import {Activity, Port} from "../../../models"; export interface WorkflowNavigationItem { - activity?: Activity; + activity: Activity; port?: Port; } diff --git a/src/designer/elsa-workflows-designer/src/components/designer/workflow-navigator/workflow-navigator.tsx b/src/designer/elsa-workflows-designer/src/components/designer/workflow-navigator/workflow-navigator.tsx index 4f308cbad..9736eb4a7 100644 --- a/src/designer/elsa-workflows-designer/src/components/designer/workflow-navigator/workflow-navigator.tsx +++ b/src/designer/elsa-workflows-designer/src/components/designer/workflow-navigator/workflow-navigator.tsx @@ -1,7 +1,4 @@ -import {Component, FunctionalComponent, h, Prop} from "@stencil/core"; -import {FlowchartIcon, IfIcon} from "../../icons/activities"; -import {Activity} from "../../../models"; -import descriptorsStore from "../../../data/descriptors-store"; +import {Component, FunctionalComponent, h, Prop, Event, EventEmitter} from "@stencil/core"; import {Container} from "typedi"; import {ActivityIconRegistry} from "../../../services"; import {WorkflowNavigationItem} from "./models"; @@ -13,6 +10,7 @@ import {WorkflowNavigationItem} from "./models"; export class WorkflowNavigator { @Prop() items: Array = []; + @Event() navigate: EventEmitter; render() { @@ -24,29 +22,38 @@ export class WorkflowNavigator { return
} + + private onItemClick = (item: WorkflowNavigationItem) => this.navigate.emit(item); } interface ActivityPathItemProps { item: WorkflowNavigationItem; + onClick: (item: WorkflowNavigationItem) => void; } -const ActivityPathItem: FunctionalComponent = ({item}) => { +const ActivityPathItem: FunctionalComponent = ({item, onClick}) => { const iconRegistry = Container.get(ActivityIconRegistry); const activity = item.activity; const icon = iconRegistry.get(activity.typeName)(); const activityId = activity.id; - const listElements = []; + const onItemClick = (e: MouseEvent, item: WorkflowNavigationItem) => { + e.preventDefault(); + onClick(item); + } + listElements.push(
  • - + onItemClick(e, item)} + href="#" + class="block flex items-center text-gray-400 hover:text-gray-500">
    {icon}
    diff --git a/src/designer/elsa-workflows-designer/src/models/event-args.ts b/src/designer/elsa-workflows-designer/src/models/event-args.ts index 42e9a52a2..49dde4492 100644 --- a/src/designer/elsa-workflows-designer/src/models/event-args.ts +++ b/src/designer/elsa-workflows-designer/src/models/event-args.ts @@ -14,6 +14,11 @@ export interface GraphUpdatedArgs { } export interface CreateChildActivityArgs { - parent: Activity; + parentActivityId: string; + port: Port; +} + +export interface EditChildActivityArgs { + parentActivityId: string; port: Port; } 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 4a57d306e..339817173 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,9 +1,8 @@ import 'reflect-metadata'; import {FunctionalComponent, h} from '@stencil/core'; import {Container, Service} from "typedi"; -import {ActivityIconRegistry, InputControlRegistry} from "../../services"; +import {ActivityIconRegistry, InputControlRegistry, PortProviderRegistry} from "../../services"; import {Plugin} from "../../models"; -import {PortProviderRegistry} from "../../components/activities/flowchart/port-provider-registry"; import {SwitchPortProvider} from "./switch-port-provider"; @Service() 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 index d71b50187..61a6a4e9e 100644 --- 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 @@ -1,8 +1,8 @@ import 'reflect-metadata'; import {Service} from "typedi"; -import {PortProvider, PortProviderContext} from "../../components/activities/flowchart/port-provider"; import {Port} from "../../models"; import {SwitchActivity} from "./models"; +import {PortProvider, PortProviderContext} from "../../services"; @Service() export class SwitchPortProvider implements PortProvider { diff --git a/src/designer/elsa-workflows-designer/src/services/activity-name-formatter.ts b/src/designer/elsa-workflows-designer/src/services/activity-name-formatter.ts index 29d92364e..61b9b2fb3 100644 --- a/src/designer/elsa-workflows-designer/src/services/activity-name-formatter.ts +++ b/src/designer/elsa-workflows-designer/src/services/activity-name-formatter.ts @@ -1,8 +1,8 @@ import {Service} from 'typedi'; import {camelCase, startCase, snakeCase, kebabCase} from 'lodash'; import {ActivityDescriptor} from "../models"; -import {ActivityNode} from "../components/activities/flowchart/activity-walker"; import {stripActivityNameSpace} from "../utils"; +import {ActivityNode} from "./activity-walker"; export type ActivityNameStrategy = (context: ActivityNameFormatterContext) => string; diff --git a/src/designer/elsa-workflows-designer/src/components/activities/flowchart/activity-walker.ts b/src/designer/elsa-workflows-designer/src/services/activity-walker.ts similarity index 85% rename from src/designer/elsa-workflows-designer/src/components/activities/flowchart/activity-walker.ts rename to src/designer/elsa-workflows-designer/src/services/activity-walker.ts index 9aa0af2ec..f11ffeb84 100644 --- a/src/designer/elsa-workflows-designer/src/components/activities/flowchart/activity-walker.ts +++ b/src/designer/elsa-workflows-designer/src/services/activity-walker.ts @@ -1,8 +1,9 @@ import 'reflect-metadata'; import {camelCase} from 'lodash'; import {Container} from "typedi" -import {Activity, ActivityDescriptor} from "../../../models"; +import {Activity, ActivityDescriptor} from "../models"; import {PortProviderRegistry} from "./port-provider-registry"; +import descriptorsStore from '../data/descriptors-store'; export interface ActivityNode { activity: Activity; @@ -16,7 +17,8 @@ export interface ActivityPort { port: string; } -export function walkActivities(root: Activity, descriptors: Array): ActivityNode { +export function walkActivities(root: Activity): ActivityNode { + const descriptors = descriptorsStore.activityDescriptors; const collectedActivities = new Set([root]); const graph: ActivityNode = {activity: root, parents: [], children: []}; const collectedNodes = new Set([graph]); @@ -39,6 +41,12 @@ export function flattenList(activities: Array): Array boolean): Activity { + const graph = walkActivities(root); + const nodes = flatten(graph); + return nodes.find(node => predicate(node.activity))?.activity; +} + function walkRecursive(node: ActivityNode, activity: Activity, collectedActivities: Set, collectedNodes: Set, descriptors: Array) { const ports = getPorts(node, activity, descriptors); diff --git a/src/designer/elsa-workflows-designer/src/components/activities/flowchart/default-port-provider.ts b/src/designer/elsa-workflows-designer/src/services/default-port-provider.ts similarity index 92% rename from src/designer/elsa-workflows-designer/src/components/activities/flowchart/default-port-provider.ts rename to src/designer/elsa-workflows-designer/src/services/default-port-provider.ts index c1fc784c9..8a0b0b267 100644 --- a/src/designer/elsa-workflows-designer/src/components/activities/flowchart/default-port-provider.ts +++ b/src/designer/elsa-workflows-designer/src/services/default-port-provider.ts @@ -1,7 +1,7 @@ import 'reflect-metadata'; import {Service} from "typedi" -import {Port} from "../../../models"; import {PortProvider, PortProviderContext} from "./port-provider"; +import {Port} from "../models"; @Service() export class DefaultPortProvider implements PortProvider { diff --git a/src/designer/elsa-workflows-designer/src/services/index.ts b/src/designer/elsa-workflows-designer/src/services/index.ts index a4b749f89..a096da6d9 100644 --- a/src/designer/elsa-workflows-designer/src/services/index.ts +++ b/src/designer/elsa-workflows-designer/src/services/index.ts @@ -9,3 +9,7 @@ export * from './input-driver-registry'; export * from './server-settings'; export * from './activity-name-formatter'; export * from './plugin-registry'; +export * from './activity-walker'; +export * from './default-port-provider'; +export * from './port-provider'; +export * from './port-provider-registry'; diff --git a/src/designer/elsa-workflows-designer/src/components/activities/flowchart/port-provider-registry.ts b/src/designer/elsa-workflows-designer/src/services/port-provider-registry.ts similarity index 100% rename from src/designer/elsa-workflows-designer/src/components/activities/flowchart/port-provider-registry.ts rename to src/designer/elsa-workflows-designer/src/services/port-provider-registry.ts diff --git a/src/designer/elsa-workflows-designer/src/components/activities/flowchart/port-provider.ts b/src/designer/elsa-workflows-designer/src/services/port-provider.ts similarity index 79% rename from src/designer/elsa-workflows-designer/src/components/activities/flowchart/port-provider.ts rename to src/designer/elsa-workflows-designer/src/services/port-provider.ts index 33c2b164e..0ec84cd25 100644 --- a/src/designer/elsa-workflows-designer/src/components/activities/flowchart/port-provider.ts +++ b/src/designer/elsa-workflows-designer/src/services/port-provider.ts @@ -1,4 +1,4 @@ -import {Activity, ActivityDescriptor, Port} from "../../../models"; +import {Activity, ActivityDescriptor, Port} from "../models"; export interface PortProvider { getInboundPorts(context: PortProviderContext): Array;