Add activity selection
This commit is contained in:
parent
6b411bb518
commit
4a5df3c816
|
|
@ -1,50 +0,0 @@
|
|||
// using System;
|
||||
// using System.Collections.Generic;
|
||||
// using System.Threading;
|
||||
// using System.Threading.Tasks;
|
||||
// using Elsa.Models;
|
||||
// using Elsa.Triggers;
|
||||
//
|
||||
// namespace Elsa.Services
|
||||
// {
|
||||
// public interface IWorkflowScheduler
|
||||
// {
|
||||
// /// <summary>
|
||||
// /// Schedules new and existing instances matching the specified trigger.
|
||||
// /// </summary>
|
||||
// Task TriggerWorkflowsAsync<TTrigger>(Func<TTrigger, bool> predicate, object? input = default, string? correlationId = default, string? contextId = default, CancellationToken cancellationToken = default) where TTrigger : ITrigger;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Schedules the specified workflow instance for execution.
|
||||
// /// </summary>
|
||||
// Task ScheduleWorkflowInstanceAsync(string instanceId, string? activityId = default, object? input = default, CancellationToken cancellationToken = default);
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Creates new workflow instances of the specified workflow definition for each start activity and schedules it for execution.
|
||||
// /// </summary>
|
||||
// Task<IEnumerable<WorkflowInstance>> ScheduleWorkflowDefinitionAsync(
|
||||
// string definitionId,
|
||||
// string? tenantId,
|
||||
// object? input = default,
|
||||
// string? correlationId = default,
|
||||
// string? contextId = default,
|
||||
// CancellationToken cancellationToken = default);
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Creates a new workflow instances of the specified workflow definition for the specified start activity and schedules it for execution.
|
||||
// /// </summary>
|
||||
// Task<IEnumerable<WorkflowInstance>> ScheduleWorkflowDefinitionAsync(
|
||||
// string definitionId,
|
||||
// string activityId,
|
||||
// string? tenantId,
|
||||
// object? input = default,
|
||||
// string? correlationId = default,
|
||||
// string? contextId = default,
|
||||
// CancellationToken cancellationToken = default);
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Schedules new workflows that start with the specified activity type or are blocked on the specified activity type.
|
||||
// /// </summary>
|
||||
// Task TriggerWorkflowsAsync(string activityType, object? input = default, string? correlationId = default, string? contextId = default, CancellationToken cancellationToken = default);
|
||||
// }
|
||||
// }
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
* It contains typing information for all components that exist in this project.
|
||||
*/
|
||||
import { HTMLStencilElement, JSXBase } from "@stencil/core/internal";
|
||||
import { ActivityDefinitionProperty, ActivityDescriptor, ActivityPropertyDescriptor, VersionOptions, WorkflowBlueprint, WorkflowDefinition, WorkflowExecutionLogRecord, WorkflowModel } from "./models";
|
||||
import { ActivityDefinitionProperty, ActivityDescriptor, ActivityModel, ActivityPropertyDescriptor, VersionOptions, WorkflowBlueprint, WorkflowDefinition, WorkflowExecutionLogRecord, WorkflowModel } from "./models";
|
||||
import { LocationSegments, MatchResults, RouterHistory } from "@stencil/router";
|
||||
import { MenuItem } from "./components/controls/elsa-context-menu/models";
|
||||
import { DropdownButtonItem, DropdownButtonOrigin } from "./components/controls/elsa-dropdown-button/models";
|
||||
|
|
@ -35,6 +35,7 @@ export namespace Components {
|
|||
}
|
||||
interface ElsaDesignerTree {
|
||||
"model": WorkflowModel;
|
||||
"selectedActivityIds": Array<string>;
|
||||
}
|
||||
interface ElsaDropdownButton {
|
||||
"icon"?: any;
|
||||
|
|
@ -487,7 +488,10 @@ declare namespace LocalJSX {
|
|||
}
|
||||
interface ElsaDesignerTree {
|
||||
"model"?: WorkflowModel;
|
||||
"onActivityDeselected"?: (event: CustomEvent<ActivityModel>) => void;
|
||||
"onActivitySelected"?: (event: CustomEvent<ActivityModel>) => void;
|
||||
"onWorkflow-changed"?: (event: CustomEvent<WorkflowModel>) => void;
|
||||
"selectedActivityIds"?: Array<string>;
|
||||
}
|
||||
interface ElsaDropdownButton {
|
||||
"icon"?: any;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ import {registerClickOutside} from 'stencil-click-outside';
|
|||
import state from '../../../../utils/store';
|
||||
import uuid = jsPlumb.jsPlumbUtil.uuid;
|
||||
import {ActivityIcon} from '../../../icons/activity-icon';
|
||||
import {languages} from "monaco-editor";
|
||||
import css = languages.css;
|
||||
|
||||
@Component({
|
||||
tag: 'elsa-designer-tree',
|
||||
|
|
@ -27,7 +29,10 @@ import {ActivityIcon} from '../../../icons/activity-icon';
|
|||
})
|
||||
export class ElsaWorkflowDesigner {
|
||||
@Prop() model: WorkflowModel = {activities: [], connections: [], persistenceBehavior: WorkflowPersistenceBehavior.WorkflowBurst};
|
||||
@Prop() selectedActivityIds: Array<string> = [];
|
||||
@Event({eventName: 'workflow-changed', bubbles: true, composed: true, cancelable: true}) workflowChanged: EventEmitter<WorkflowModel>;
|
||||
@Event() activitySelected: EventEmitter<ActivityModel>;
|
||||
@Event() activityDeselected: EventEmitter<ActivityModel>;
|
||||
@State() workflowModel: WorkflowModel;
|
||||
|
||||
el: HTMLElement;
|
||||
|
|
@ -43,6 +48,7 @@ export class ElsaWorkflowDesigner {
|
|||
parentActivityId?: string;
|
||||
parentActivityOutcome?: string;
|
||||
activityDisplayContexts: Map<ActivityDesignDisplayContext> = {};
|
||||
selectedActivities: Map<ActivityModel> = {};
|
||||
|
||||
@State() contextMenu: {
|
||||
shown: boolean;
|
||||
|
|
@ -70,6 +76,20 @@ export class ElsaWorkflowDesigner {
|
|||
this.workflowModel = newValue;
|
||||
}
|
||||
|
||||
@Watch('selectedActivityIds')
|
||||
handleSelectedActivityIdsChanged(newValue: Array<string>) {
|
||||
debugger;
|
||||
const ids = newValue || [];
|
||||
const selectedActivities = this.workflowModel.activities.filter(x => ids.includes(x.activityId));
|
||||
const map: Map<ActivityModel> = {};
|
||||
|
||||
for (const activity of selectedActivities)
|
||||
map[activity.activityId] = activity;
|
||||
|
||||
this.selectedActivities = map;
|
||||
this.rerenderTree();
|
||||
}
|
||||
|
||||
handleEditActivity(activity: ActivityModel) {
|
||||
this.showActivityEditor(activity, true);
|
||||
}
|
||||
|
|
@ -197,7 +217,7 @@ export class ElsaWorkflowDesigner {
|
|||
this.innerD3Selected = d3.select(this.inner);
|
||||
setTimeout(() => {
|
||||
this.rerenderTree()
|
||||
}, 400)
|
||||
}, 600)
|
||||
}
|
||||
|
||||
componentWillRender() {
|
||||
|
|
@ -222,7 +242,7 @@ export class ElsaWorkflowDesigner {
|
|||
eventBus.emit(EventTypes.ActivityDesignDisplaying, this, displayContext);
|
||||
displayContexts[model.activityId] = displayContext;
|
||||
}
|
||||
|
||||
|
||||
this.activityDisplayContexts = displayContexts;
|
||||
}
|
||||
|
||||
|
|
@ -355,9 +375,27 @@ export class ElsaWorkflowDesigner {
|
|||
|
||||
d3.selectAll('.node.activity').each((n: any) => {
|
||||
const node = this.graph.node(n) as any;
|
||||
const activity = node.activity;
|
||||
const activityId = activity.activityId;
|
||||
|
||||
d3.select(node.elem).on('click', () => {
|
||||
// If a parent activity was selected to connect to:
|
||||
if (this.parentActivityId && this.parentActivityOutcome) {
|
||||
this.addConnection(this.parentActivityId, node.activity.activityId, this.parentActivityOutcome);
|
||||
this.addConnection(this.parentActivityId, activityId, this.parentActivityOutcome);
|
||||
} else {
|
||||
// When clicking an activity:
|
||||
if (!!this.selectedActivities[activityId])
|
||||
delete this.selectedActivities[activityId];
|
||||
else {
|
||||
for (const key in this.selectedActivities) {
|
||||
this.activityDeselected.emit(this.selectedActivities[key]);
|
||||
}
|
||||
this.selectedActivities = {};
|
||||
this.selectedActivities[activityId] = activity;
|
||||
this.activitySelected.emit(activity);
|
||||
}
|
||||
|
||||
this.rerenderTree();
|
||||
}
|
||||
});
|
||||
d3.select(node.elem)
|
||||
|
|
@ -399,8 +437,9 @@ export class ElsaWorkflowDesigner {
|
|||
|
||||
renderActivity(activity: ActivityModel) {
|
||||
const displayContext = this.activityDisplayContexts[activity.activityId] || undefined;
|
||||
const cssClass = !!this.selectedActivities[activity.activityId] ? 'border-blue-600' : 'border-white hover:border-blue-600'
|
||||
return `<div id=${`activity-${activity.activityId}`}
|
||||
class="activity border-2 border-solid border-white rounded bg-white text-left text-black text-lg hover:border-blue-600 select-none max-w-md shadow-sm relative">
|
||||
class="activity border-2 border-solid rounded bg-white text-left text-black text-lg select-none max-w-md shadow-sm relative ${cssClass}">
|
||||
<div class="p-5">
|
||||
<div class="flex justify-between space-x-8">
|
||||
<div class="flex-shrink-0">
|
||||
|
|
@ -429,9 +468,11 @@ export class ElsaWorkflowDesigner {
|
|||
|
||||
renderActivityBody(description: string | null) {
|
||||
if (!description) return '';
|
||||
return `<div class="p-6 text-gray-400 text-sm border-t border-t-solid">
|
||||
${description}
|
||||
</div>`;
|
||||
return (
|
||||
`<div class="p-6 text-gray-400 text-sm border-t border-t-solid">
|
||||
${description}
|
||||
</div>`
|
||||
);
|
||||
}
|
||||
|
||||
// private onActivitySelected(e: CustomEvent<ActivityModel>) {
|
||||
|
|
@ -445,8 +486,8 @@ export class ElsaWorkflowDesigner {
|
|||
render() {
|
||||
return (
|
||||
<Host class="workflow-canvas flex-1 flex" ref={el => (this.el = el)}>
|
||||
<svg ref={el => (this.svg = el)} id="svg" style={{ height: 'calc(100vh - 64px)', width: '100%', pointerEvents: this.contextMenu.shown ? 'none' : '' }}>
|
||||
<g ref={el => (this.inner = el)} />
|
||||
<svg ref={el => (this.svg = el)} id="svg" style={{height: 'calc(100vh - 64px)', width: '100%', pointerEvents: this.contextMenu.shown ? 'none' : ''}}>
|
||||
<g ref={el => (this.inner = el)}/>
|
||||
</svg>
|
||||
<div
|
||||
data-transition-enter="transition ease-out duration-100"
|
||||
|
|
@ -456,7 +497,7 @@ export class ElsaWorkflowDesigner {
|
|||
data-transition-leave-start="transform opacity-100 scale-100"
|
||||
data-transition-leave-end="transform opacity-0 scale-95"
|
||||
class={`${this.contextMenu.shown ? '' : 'hidden'} context-menu z-10 mx-3 w-48 mt-1 rounded-md shadow-lg`}
|
||||
style={{ position: 'absolute', left: `${this.contextMenu.x}px`, top: `${this.contextMenu.y - 64}px` }}
|
||||
style={{position: 'absolute', left: `${this.contextMenu.x}px`, top: `${this.contextMenu.y - 64}px`}}
|
||||
ref={el =>
|
||||
registerClickOutside(this, el, () => {
|
||||
this.handleContextMenuChange(0, 0, false, null);
|
||||
|
|
@ -487,7 +528,6 @@ export class ElsaWorkflowDesigner {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <div innerHTML={<ActivityIcon />} /> */}
|
||||
</Host>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ export class ElsaWorkflowInstanceViewerScreen {
|
|||
}
|
||||
|
||||
onActivityDeselected(e: CustomEvent<ActivityModel>) {
|
||||
if(this.selectedActivityId == e.detail.activityId)
|
||||
if (this.selectedActivityId == e.detail.activityId)
|
||||
this.selectedActivityId = null;
|
||||
|
||||
this.journal.selectActivityRecord(this.selectedActivityId);
|
||||
|
|
@ -180,7 +180,7 @@ export class ElsaWorkflowInstanceViewerScreen {
|
|||
return (
|
||||
<Host class="flex flex-col w-full relative" ref={el => this.el = el}>
|
||||
{this.renderCanvas()}
|
||||
<elsa-workflow-instance-journal ref={el => this.journal = el}
|
||||
<elsa-workflow-instance-journal ref={el => this.journal = el}
|
||||
workflowInstanceId={this.workflowInstanceId}
|
||||
serverUrl={this.serverUrl}
|
||||
activityDescriptors={descriptors}
|
||||
|
|
@ -196,9 +196,9 @@ export class ElsaWorkflowInstanceViewerScreen {
|
|||
<div class="flex-1 flex">
|
||||
<elsa-designer-tree model={this.workflowModel}
|
||||
class="flex-1" ref={el => this.designer = el}
|
||||
// selectedActivityId={this.selectedActivityId}
|
||||
// onActivitySelected={e => this.onActivitySelected(e)}
|
||||
// onActivityDeselected={e => this.onActivityDeselected(e)}
|
||||
selectedActivityIds={[this.selectedActivityId]}
|
||||
onActivitySelected={e => this.onActivitySelected(e)}
|
||||
onActivityDeselected={e => this.onActivityDeselected(e)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue