From 36c589c06290ddd92a42cc5f57e086ecb65cd9e4 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 18 Jun 2022 15:08:39 +0200 Subject: [PATCH] Incremental work on embedded activities --- .../src/components.d.ts | 13 ++++ .../activities/flowchart/flowchart.tsx | 6 +- .../flowchart/flowchart/assign-parent.ts | 36 --------- .../flowchart/flowchart/find-parent.ts | 17 ---- .../activities/flowchart/graph-factory.ts | 1 - .../components/activities/flowchart/shapes.ts | 19 ++--- .../default-activity-template.tsx | 78 +++++++------------ .../workflow-definition-editor/toolbar.tsx | 2 +- .../workflow-definition-editor.scss | 9 ++- .../workflow-definition-editor.tsx | 1 + .../workflow-navigator/workflow-navigator.tsx | 11 +++ 11 files changed, 70 insertions(+), 123 deletions(-) delete mode 100644 src/designer/elsa-workflows-designer/src/components/activities/flowchart/flowchart/assign-parent.ts delete mode 100644 src/designer/elsa-workflows-designer/src/components/activities/flowchart/flowchart/find-parent.ts create mode 100644 src/designer/elsa-workflows-designer/src/components/designer/workflow-navigator/workflow-navigator.tsx diff --git a/src/designer/elsa-workflows-designer/src/components.d.ts b/src/designer/elsa-workflows-designer/src/components.d.ts index f566de0ea..03811764a 100644 --- a/src/designer/elsa-workflows-designer/src/components.d.ts +++ b/src/designer/elsa-workflows-designer/src/components.d.ts @@ -264,6 +264,8 @@ export namespace Components { "workflowDefinition"?: WorkflowDefinition; "workflowInstance"?: WorkflowInstance; } + interface ElsaWorkflowNavigator { + } interface ElsaWorkflowPublishButton { "publishing": boolean; } @@ -549,6 +551,12 @@ declare global { prototype: HTMLElsaWorkflowManagerElement; new (): HTMLElsaWorkflowManagerElement; }; + interface HTMLElsaWorkflowNavigatorElement extends Components.ElsaWorkflowNavigator, HTMLStencilElement { + } + var HTMLElsaWorkflowNavigatorElement: { + prototype: HTMLElsaWorkflowNavigatorElement; + new (): HTMLElsaWorkflowNavigatorElement; + }; interface HTMLElsaWorkflowPublishButtonElement extends Components.ElsaWorkflowPublishButton, HTMLStencilElement { } var HTMLElsaWorkflowPublishButtonElement: { @@ -614,6 +622,7 @@ declare global { "elsa-workflow-instance-viewer": HTMLElsaWorkflowInstanceViewerElement; "elsa-workflow-journal": HTMLElsaWorkflowJournalElement; "elsa-workflow-manager": HTMLElsaWorkflowManagerElement; + "elsa-workflow-navigator": HTMLElsaWorkflowNavigatorElement; "elsa-workflow-publish-button": HTMLElsaWorkflowPublishButtonElement; "elsa-workflow-toolbar": HTMLElsaWorkflowToolbarElement; "elsa-workflow-toolbar-menu": HTMLElsaWorkflowToolbarMenuElement; @@ -840,6 +849,8 @@ declare namespace LocalJSX { "workflowDefinition"?: WorkflowDefinition; "workflowInstance"?: WorkflowInstance; } + interface ElsaWorkflowNavigator { + } interface ElsaWorkflowPublishButton { "onExportClicked"?: (event: CustomEvent) => void; "onImportClicked"?: (event: CustomEvent) => void; @@ -899,6 +910,7 @@ declare namespace LocalJSX { "elsa-workflow-instance-viewer": ElsaWorkflowInstanceViewer; "elsa-workflow-journal": ElsaWorkflowJournal; "elsa-workflow-manager": ElsaWorkflowManager; + "elsa-workflow-navigator": ElsaWorkflowNavigator; "elsa-workflow-publish-button": ElsaWorkflowPublishButton; "elsa-workflow-toolbar": ElsaWorkflowToolbar; "elsa-workflow-toolbar-menu": ElsaWorkflowToolbarMenu; @@ -954,6 +966,7 @@ declare module "@stencil/core" { "elsa-workflow-instance-viewer": LocalJSX.ElsaWorkflowInstanceViewer & JSXBase.HTMLAttributes; "elsa-workflow-journal": LocalJSX.ElsaWorkflowJournal & JSXBase.HTMLAttributes; "elsa-workflow-manager": LocalJSX.ElsaWorkflowManager & JSXBase.HTMLAttributes; + "elsa-workflow-navigator": LocalJSX.ElsaWorkflowNavigator & JSXBase.HTMLAttributes; "elsa-workflow-publish-button": LocalJSX.ElsaWorkflowPublishButton & JSXBase.HTMLAttributes; "elsa-workflow-toolbar": LocalJSX.ElsaWorkflowToolbar & JSXBase.HTMLAttributes; "elsa-workflow-toolbar-menu": LocalJSX.ElsaWorkflowToolbarMenu & JSXBase.HTMLAttributes; 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 df92a78dc..71ae867b0 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 @@ -20,7 +20,6 @@ import FromJSONData = Model.FromJSONData; import {ContextMenuAnchorPoint, MenuItem, MenuItemGroup} from "../../shared/context-menu/models"; import PointLike = Point.PointLike; import descriptorsStore from "../../../data/descriptors-store"; -import {assignParent} from "./flowchart/assign-parent"; @Component({ tag: 'elsa-flowchart', @@ -350,6 +349,9 @@ export class FlowchartComponent implements ContainerActivityComponent { } onNodeMoved = (e: PositionEventArgs) => { + + console.debug("Node moved..."); + const node = e.node as ActivityNodeShape; const activity = node.data as Activity; const nodePosition = node.position({relative: false}); @@ -364,8 +366,6 @@ export class FlowchartComponent implements ContainerActivityComponent { } } } - - assignParent(this.graph, node); } onEdgeConnected = async (e: { isNew: boolean, edge: Edge }) => { diff --git a/src/designer/elsa-workflows-designer/src/components/activities/flowchart/flowchart/assign-parent.ts b/src/designer/elsa-workflows-designer/src/components/activities/flowchart/flowchart/assign-parent.ts deleted file mode 100644 index 074e0ae11..000000000 --- a/src/designer/elsa-workflows-designer/src/components/activities/flowchart/flowchart/assign-parent.ts +++ /dev/null @@ -1,36 +0,0 @@ -import {Graph, Rectangle, Node} from "@antv/x6"; -import {camelCase} from 'lodash'; -import {Activity} from "../../../../models"; -import {ActivityNode as ActivityNodeShape} from "../shapes"; - -export function assignParent(graph: Graph, node: ActivityNodeShape) { - const underlyingNodes = graph.getNodesUnderNode(node); - - if (underlyingNodes.length > 0) { - const underlyingNode = underlyingNodes[0] as ActivityNodeShape; - const underlyingActivity = underlyingNode.data as Activity; - const underlyingView: any = graph.findView(underlyingNode); - const portElements: Array = underlyingView.selectors.foContent.getElementsByClassName('activity-port'); - - if (portElements.length == 0) - return; - - const movedNodeView = graph.findView(node); - const movedNodeViewRect = movedNodeView.getBBox(); - - for (const portElement of portElements) { - const portRect = Rectangle.create(portElement.getBoundingClientRect()); - const localPortRect = Rectangle.create(graph.pageToLocal(portRect)); - - if (movedNodeViewRect.intersectsWithRect(localPortRect)) { - const portName = camelCase(portElement.dataset.portName); - const childActivity = node.data as Activity; - underlyingActivity[portName] = childActivity; - underlyingNode.activity = {...underlyingActivity}; - graph.removeCell(node); - break; - } - } - - } -} diff --git a/src/designer/elsa-workflows-designer/src/components/activities/flowchart/flowchart/find-parent.ts b/src/designer/elsa-workflows-designer/src/components/activities/flowchart/flowchart/find-parent.ts deleted file mode 100644 index 72cb0f0e2..000000000 --- a/src/designer/elsa-workflows-designer/src/components/activities/flowchart/flowchart/find-parent.ts +++ /dev/null @@ -1,17 +0,0 @@ -// export function findParent(args: any): Array { -// const childNode = args.node; -// const bbox = childNode.getBBox(); -// -// return this.getNodes().filter((node) => { -// -// const data = node.getData(); -// -// if (data?.typeName == 'Elsa.If') { -// debugger; -// const targetBBox = node.getBBox(); -// return bbox.isIntersectWithRect(targetBBox); -// } -// -// return false; -// }) -// } diff --git a/src/designer/elsa-workflows-designer/src/components/activities/flowchart/graph-factory.ts b/src/designer/elsa-workflows-designer/src/components/activities/flowchart/graph-factory.ts index abcb639c2..e8724a73a 100644 --- a/src/designer/elsa-workflows-designer/src/components/activities/flowchart/graph-factory.ts +++ b/src/designer/elsa-workflows-designer/src/components/activities/flowchart/graph-factory.ts @@ -1,7 +1,6 @@ import {CellView, Graph, Node, Shape} from '@antv/x6'; import {v4 as uuid} from 'uuid'; import './ports'; -import {assignParent} from "./flowchart/assign-parent"; export function createGraph( container: HTMLElement, diff --git a/src/designer/elsa-workflows-designer/src/components/activities/flowchart/shapes.ts b/src/designer/elsa-workflows-designer/src/components/activities/flowchart/shapes.ts index e1c3c239c..cf1603d68 100644 --- a/src/designer/elsa-workflows-designer/src/components/activities/flowchart/shapes.ts +++ b/src/designer/elsa-workflows-designer/src/components/activities/flowchart/shapes.ts @@ -68,20 +68,15 @@ export class ActivityNode extends Shape.HTML { // Wait for activity element to be completely rendered. // When using custom elements, they are rendered after they are mounted. Before then, they have a 0 width and height. const tryUpdateSize = () => { - // TODO: Figure out if there's a way to select *any* custom element. - // Worst case, we need to look for a registered set if tags, or introduce a convention where custom elements need to specify a class name for example. - const activityElements: Array = Array.from(wrapper.getElementsByTagName('elsa-default-activity-template')); + const activityElement: Element = wrapper.getElementsByTagName('elsa-default-activity-template')[0]; + const activityElementRect = activityElement.getBoundingClientRect(); - for (const activityElement of activityElements) { - const activityElementRect = activityElement.getBoundingClientRect(); + // If the custom element has no width or height yet, it means it has not yet rendered. + if (activityElementRect.width == 0 || activityElementRect.height == 0) { - // If the custom element has no width or height yet, it means it has not yet rendered. - if (activityElementRect.width == 0 || activityElementRect.height == 0) { - - // Request an animation frame and call ourselves back immediately after. - window.requestAnimationFrame(tryUpdateSize); - return; - } + // Request an animation frame and call ourselves back immediately after. + window.requestAnimationFrame(tryUpdateSize); + return; } const rect = wrapper.firstElementChild.getBoundingClientRect(); 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 fddc0b2d2..50af98f45 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 @@ -131,7 +131,11 @@ export class DefaultActivityTemplate { const portName = camelCase(port.name); const activity = this.parsedActivity; const childActivity: Activity = activity ? activity[portName] : null; - const isSelected = port.name == this.selectedPortName; + const childActivityDescriptor: ActivityDescriptor = childActivity != null ? descriptorsStore.activityDescriptors.find(x => x.activityType == childActivity.typeName) : null; + let childActivityDisplayText = childActivity?.metadata?.displayText; + + if (isNullOrWhitespace(childActivityDisplayText)) + childActivityDisplayText = childActivityDescriptor?.displayName; return (
this.portElements.push(el)}> @@ -140,20 +144,29 @@ export class DefaultActivityTemplate {
{childActivity ? ( -
this.onPortMouseDown(e, port)} - onMouseUp={e => this.onPortMouseUp(e, port)} - > - - {/*{childActivity.typeName}*/} +
+
+
+ {childActivityDisplayText} +
+ +
) : ( -
- - - + )}
@@ -178,43 +191,4 @@ export class DefaultActivityTemplate { this.selectedPortName = null; } - - private onPortMouseDown = (e: MouseEvent, port: Port) => { - e.stopPropagation(); - }; - - private onPortMouseUp = (e: MouseEvent, port: Port) => { - e.stopPropagation(); - - if (this.selectedPortName != port.name) { - this.selectedPortName = port.name; - - const activity = this.parsedActivity; - const portName = camelCase(port.name); - const childActivity: Activity = activity ? activity[portName] : null; - - const args: ActivitySelectedArgs = { - activity: childActivity, - applyChanges: a => { - activity[portName] = a; - }, - deleteActivity: a => { - activity[portName] = null; - } - }; - - this.activitySelected.emit(args); - } - }; - - private onDragOverPort = (e: DragEvent) => { - console.debug("Dragging over!"); - e.stopPropagation(); - e.preventDefault(); - } - - private onDropOnPort = (e: DragEvent) => { - //debugger; - console.debug("Dropped!"); - } } diff --git a/src/designer/elsa-workflows-designer/src/components/designer/workflow-definition-editor/toolbar.tsx b/src/designer/elsa-workflows-designer/src/components/designer/workflow-definition-editor/toolbar.tsx index ace7b4279..536d341fa 100644 --- a/src/designer/elsa-workflows-designer/src/components/designer/workflow-definition-editor/toolbar.tsx +++ b/src/designer/elsa-workflows-designer/src/components/designer/workflow-definition-editor/toolbar.tsx @@ -9,7 +9,7 @@ export class Toolbar { render() { return ( -
+
Currently in development

}>