diff --git a/src/designer/elsa-workflows-studio/src/components/designers/tree/elsa-designer-tree/elsa-designer-tree.tsx b/src/designer/elsa-workflows-studio/src/components/designers/tree/elsa-designer-tree/elsa-designer-tree.tsx index 2199d4772..9b7ccc493 100644 --- a/src/designer/elsa-workflows-studio/src/components/designers/tree/elsa-designer-tree/elsa-designer-tree.tsx +++ b/src/designer/elsa-workflows-studio/src/components/designers/tree/elsa-designer-tree/elsa-designer-tree.tsx @@ -44,24 +44,35 @@ export class ElsaWorkflowDesigner { this.removeActivity(e.detail.activityId); } + connectedCallback() { + eventBus.on(EventTypes.ActivityPicked, this.onActivityPicked); + eventBus.on(EventTypes.UpdateActivity, this.onUpdateActivity); + } + + disconnectedCallback() { + eventBus.off(EventTypes.ActivityPicked, this.onActivityPicked); + eventBus.off(EventTypes.UpdateActivity, this.onUpdateActivity); + cleanup(); + } + componentWillLoad() { this.workflowModel = this.model; - - eventBus.on(EventTypes.ActivityPicked, async args => { - const activityDescriptor = (args as ActivityDescriptor); - const connectFromRoot = !this.parentActivityOutcome || this.parentActivityOutcome == ""; - const sourceId = connectFromRoot ? null : this.parentActivityId; - const targetId = connectFromRoot ? this.parentActivityId : null; - const activityModel = this.addActivity(activityDescriptor, sourceId, targetId, this.parentActivityOutcome); - - this.showActivityEditor(activityModel, false); - }); - - eventBus.on(EventTypes.UpdateActivity, async args => { - const activityModel = (args as ActivityModel); - this.updateActivity(activityModel); - }); } + + onActivityPicked = async (args) =>{ + const activityDescriptor = (args as ActivityDescriptor); + const connectFromRoot = !this.parentActivityOutcome || this.parentActivityOutcome == ""; + const sourceId = connectFromRoot ? null : this.parentActivityId; + const targetId = connectFromRoot ? this.parentActivityId : null; + const activityModel = this.addActivity(activityDescriptor, sourceId, targetId, this.parentActivityOutcome); + + this.showActivityEditor(activityModel, false); + }; + + onUpdateActivity = args => { + const activityModel = (args as ActivityModel); + this.updateActivity(activityModel); + }; componentWillRender() { destroy(); @@ -106,10 +117,6 @@ export class ElsaWorkflowDesigner { this.removeInvalidConnections(invalidConnections); } - disconnectedCallback() { - cleanup(); - } - showActivityPicker() { eventBus.emit(EventTypes.ShowActivityPicker); } diff --git a/src/designer/elsa-workflows-studio/src/components/screens/workflow-definition-editor/elsa-workflow-definition-editor-notifications/elsa-workflow-editor-notifications.tsx b/src/designer/elsa-workflows-studio/src/components/screens/workflow-definition-editor/elsa-workflow-definition-editor-notifications/elsa-workflow-editor-notifications.tsx index 95db21c79..0bec2faa1 100644 --- a/src/designer/elsa-workflows-studio/src/components/screens/workflow-definition-editor/elsa-workflow-definition-editor-notifications/elsa-workflow-editor-notifications.tsx +++ b/src/designer/elsa-workflows-studio/src/components/screens/workflow-definition-editor/elsa-workflow-definition-editor-notifications/elsa-workflow-editor-notifications.tsx @@ -3,33 +3,41 @@ import {eventBus} from '../../../../services/event-bus'; import {EventTypes, WorkflowDefinition} from "../../../../models"; @Component({ - tag: 'elsa-workflow-definition-editor-notifications', - shadow: false, + tag: 'elsa-workflow-definition-editor-notifications', + shadow: false, }) export class ElsaWorkflowEditorNotifications { - toastNotificationElement: HTMLElsaToastNotificationElement; + toastNotificationElement: HTMLElsaToastNotificationElement; - componentDidLoad() { - eventBus.on(EventTypes.WorkflowPublished, async (workflowDefinition: WorkflowDefinition) => { - await this.toastNotificationElement.show({autoCloseIn: 1500, title: 'Workflow Published', message: `Workflow successfully published at version ${workflowDefinition.version}.`}); + connectedCallback() { + eventBus.on(EventTypes.WorkflowPublished, this.onWorkflowPublished); + eventBus.on(EventTypes.WorkflowRetracted, this.onWorkflowRetracted); + eventBus.on(EventTypes.WorkflowImported, this.onWorkflowImported); + } + + disconnectedCallback() { + eventBus.off(EventTypes.WorkflowPublished, this.onWorkflowPublished); + eventBus.off(EventTypes.WorkflowRetracted, this.onWorkflowRetracted); + eventBus.off(EventTypes.WorkflowImported, this.onWorkflowImported); + } + + onWorkflowPublished = async (workflowDefinition: WorkflowDefinition) => await this.toastNotificationElement.show({autoCloseIn: 1500, title: 'Workflow Unpublished', message: `Workflow successfully retracted.`}); + + onWorkflowRetracted = async (workflowDefinition: WorkflowDefinition) => await this.toastNotificationElement.show({ + autoCloseIn: 1500, + title: 'Workflow Published', + message: `Workflow successfully published at version ${workflowDefinition.version}.` }); - eventBus.on(EventTypes.WorkflowRetracted, async (workflowDefinition: WorkflowDefinition) => { - await this.toastNotificationElement.show({autoCloseIn: 1500, title: 'Workflow Unpublished', message: `Workflow successfully retracted.`}); - }); + onWorkflowImported = async (workflowDefinition: WorkflowDefinition) => await this.toastNotificationElement.show({autoCloseIn: 1500, title: 'Workflow Imported', message: `Workflow successfully imported.`}); - eventBus.on(EventTypes.WorkflowImported, async (workflowDefinition: WorkflowDefinition) => { - await this.toastNotificationElement.show({autoCloseIn: 1500, title: 'Workflow Imported', message: `Workflow successfully imported.`}); - }); - } + render() { - render() { - - return ( - - this.toastNotificationElement = el}/> - - ); - } + return ( + + this.toastNotificationElement = el}/> + + ); + } } diff --git a/src/designer/elsa-workflows-studio/src/components/screens/workflow-definition-editor/elsa-workflow-definition-editor-screen/elsa-workflow-definition-editor-screen.tsx b/src/designer/elsa-workflows-studio/src/components/screens/workflow-definition-editor/elsa-workflow-definition-editor-screen/elsa-workflow-definition-editor-screen.tsx index ce18f4d35..6d811c0e8 100644 --- a/src/designer/elsa-workflows-studio/src/components/screens/workflow-definition-editor/elsa-workflow-definition-editor-screen/elsa-workflow-definition-editor-screen.tsx +++ b/src/designer/elsa-workflows-studio/src/components/screens/workflow-definition-editor/elsa-workflow-definition-editor-screen/elsa-workflow-definition-editor-screen.tsx @@ -8,406 +8,415 @@ import Tunnel, {WorkflowEditorState} from '../../../../data/workflow-editor'; import {downloadFromBlob} from "../../../../utils/download"; @Component({ - tag: 'elsa-workflow-definition-editor-screen', - styleUrl: 'elsa-workflow-definition-editor-screen.css', - shadow: false, + tag: 'elsa-workflow-definition-editor-screen', + styleUrl: 'elsa-workflow-definition-editor-screen.css', + shadow: false, }) export class ElsaWorkflowDefinitionEditorScreen { - constructor() { - pluginManager.initialize(); - } - - @Event() workflowSaved: EventEmitter; - @Prop({attribute: 'workflow-definition-id', reflect: true}) workflowDefinitionId: string; - @Prop({attribute: 'server-url', reflect: true}) serverUrl: string; - @Prop({attribute: 'monaco-lib-path', reflect: true}) monacoLibPath: string; - @State() workflowDefinition: WorkflowDefinition; - @State() workflowModel: WorkflowModel; - @State() publishing: boolean; - @State() unPublishing: boolean; - @State() unPublished: boolean; - @State() saving: boolean; - @State() saved: boolean; - @State() importing: boolean; - @State() imported: boolean; - @State() networkError: string; - el: HTMLElement; - designer: HTMLElsaDesignerTreeElement; - - @Method() - async getServerUrl(): Promise { - return this.serverUrl; - } - - @Method() - async getWorkflowDefinitionId(): Promise { - return this.workflowDefinition.definitionId; - } - - @Method() - async exportWorkflow() { - const client = createElsaClient(this.serverUrl); - const workflowDefinition = this.workflowDefinition; - const versionOptions: VersionOptions = {version: workflowDefinition.version}; - const response = await client.workflowDefinitionsApi.export(workflowDefinition.definitionId, versionOptions); - downloadFromBlob(response.data, {contentType: 'application/json', fileName: response.fileName}); - } - - @Method() - async importWorkflow(file: File) { - const client = createElsaClient(this.serverUrl); - - this.importing = true; - this.imported = false; - this.networkError = null; - - // A small hack to make sure JS Plumb is cleaned up before HTML elements get removed. - await this.designer.destroyJsPlumb(); - - try { - const workflowDefinition = await client.workflowDefinitionsApi.import(this.workflowDefinition.definitionId, file); - this.workflowDefinition = workflowDefinition; - this.workflowModel = this.mapWorkflowModel(workflowDefinition); - - this.importing = false; - this.imported = true; - setTimeout(() => this.imported = false, 500); - eventBus.emit(EventTypes.WorkflowImported, this, this.workflowDefinition); - } catch (e) { - console.error(e); - this.importing = false; - this.imported = false; - this.networkError = e.message; - setTimeout(() => this.networkError = null, 10000); - } - } - - @Watch('workflowDefinitionId') - async workflowDefinitionIdChangedHandler(newValue: string) { - const workflowDefinitionId = newValue; - let workflowDefinition: WorkflowDefinition = this.createWorkflowDefinition(); - const client = createElsaClient(this.serverUrl); - - if (workflowDefinitionId && workflowDefinitionId.length > 0) { - try { - workflowDefinition = await client.workflowDefinitionsApi.getByDefinitionAndVersion(workflowDefinitionId, {isLatest: true}); - } catch { - console.warn(`The specified workflow definition does not exist. Creating a new one.`) - } + constructor() { + pluginManager.initialize(); } - this.updateWorkflowDefinition(workflowDefinition); - } + @Event() workflowSaved: EventEmitter; + @Prop({attribute: 'workflow-definition-id', reflect: true}) workflowDefinitionId: string; + @Prop({attribute: 'server-url', reflect: true}) serverUrl: string; + @Prop({attribute: 'monaco-lib-path', reflect: true}) monacoLibPath: string; + @State() workflowDefinition: WorkflowDefinition; + @State() workflowModel: WorkflowModel; + @State() publishing: boolean; + @State() unPublishing: boolean; + @State() unPublished: boolean; + @State() saving: boolean; + @State() saved: boolean; + @State() importing: boolean; + @State() imported: boolean; + @State() networkError: string; + el: HTMLElement; + designer: HTMLElsaDesignerTreeElement; - @Watch("serverUrl") - async serverUrlChangedHandler(newValue: string) { - if (newValue && newValue.length > 0) - await this.loadActivityDescriptors(); - } - - @Watch("monacoLibPath") - async monacoLibPathChangedHandler(newValue: string) { - state.monacoLibPath = newValue; - } - - @Listen('workflow-changed') - async workflowChangedHandler(event: CustomEvent) { - const workflowModel = event.detail; - await this.saveWorkflowInternal(workflowModel); - } - - async componentWillLoad() { - await this.serverUrlChangedHandler(this.serverUrl); - await this.workflowDefinitionIdChangedHandler(this.workflowDefinitionId); - await this.monacoLibPathChangedHandler(this.monacoLibPath); - } - - componentDidLoad() { - if (!this.designer) { - this.designer = this.el.querySelector("elsa-designer-tree") as HTMLElsaDesignerTreeElement; - this.designer.model = this.workflowModel; + @Method() + async getServerUrl(): Promise { + return this.serverUrl; } - eventBus.on(EventTypes.UpdateWorkflowSettings, async (workflowDefinition: WorkflowDefinition) => { - this.updateWorkflowDefinition(workflowDefinition); - await this.saveWorkflowInternal(this.workflowModel); - }); - } - - async loadActivityDescriptors() { - const client = createElsaClient(this.serverUrl); - state.activityDescriptors = await client.activitiesApi.list(); - } - - updateWorkflowDefinition(value: WorkflowDefinition) { - this.workflowDefinition = value; - this.workflowModel = this.mapWorkflowModel(value); - } - - async publishWorkflow() { - this.publishing = true; - await this.saveWorkflow(true); - this.publishing = false; - eventBus.emit(EventTypes.WorkflowPublished, this, this.workflowDefinition); - } - - async unPublishWorkflow() { - this.unPublishing = true; - await this.unpublishWorkflow(); - this.unPublishing = false; - eventBus.emit(EventTypes.WorkflowRetracted, this, this.workflowDefinition); - } - - async saveWorkflow(publish?: boolean) { - await this.saveWorkflowInternal(null, publish); - } - - async saveWorkflowInternal(workflowModel?: WorkflowModel, publish?: boolean) { - if (!this.serverUrl || this.serverUrl.length == 0) - return; - - workflowModel = workflowModel || this.workflowModel; - - const client = createElsaClient(this.serverUrl); - let workflowDefinition = this.workflowDefinition; - - const request: SaveWorkflowDefinitionRequest = { - workflowDefinitionId: workflowDefinition.definitionId || this.workflowDefinitionId, - contextOptions: workflowDefinition.contextOptions, - deleteCompletedInstances: workflowDefinition.deleteCompletedInstances, - description: workflowDefinition.description, - displayName: workflowDefinition.displayName, - isSingleton: workflowDefinition.isSingleton, - name: workflowDefinition.name, - persistenceBehavior: workflowDefinition.persistenceBehavior, - publish: publish || false, - variables: workflowDefinition.variables, - activities: workflowModel.activities.map(x => ({ - activityId: x.activityId, - type: x.type, - name: x.name, - displayName: x.displayName, - description: x.description, - persistWorkflow: x.persistWorkflow, - loadWorkflowContext: x.loadWorkflowContext, - saveWorkflowContext: x.saveWorkflowContext, - persistOutput: x.persistOutput, - properties: x.properties - })), - connections: workflowModel.connections.map(x => ({ - sourceActivityId: x.sourceId, - targetActivityId: x.targetId, - outcome: x.outcome - })), - }; - - this.saving = !publish; - this.publishing = publish; - - try { - workflowDefinition = await client.workflowDefinitionsApi.save(request); - this.workflowDefinition = workflowDefinition; - this.workflowModel = this.mapWorkflowModel(workflowDefinition); - - this.saving = false; - this.saved = !publish; - this.publishing = false; - setTimeout(() => this.saved = false, 500); - this.workflowSaved.emit(workflowDefinition); - } catch (e) { - console.error(e); - this.saving = false; - this.saved = false; - this.networkError = e.message; - setTimeout(() => this.networkError = null, 10000); + @Method() + async getWorkflowDefinitionId(): Promise { + return this.workflowDefinition.definitionId; } - } - async unpublishWorkflow() { - const client = createElsaClient(this.serverUrl); - const workflowDefinitionId = this.workflowDefinition.definitionId; - this.unPublishing = true; - - try { - this.workflowDefinition = await client.workflowDefinitionsApi.retract(workflowDefinitionId); - this.unPublishing = false; - this.unPublished = true - setTimeout(() => this.unPublished = false, 500); - } catch (e) { - console.error(e); - this.unPublishing = false; - this.unPublished = false; - this.networkError = e.message; - setTimeout(() => this.networkError = null, 2000); + @Method() + async exportWorkflow() { + const client = createElsaClient(this.serverUrl); + const workflowDefinition = this.workflowDefinition; + const versionOptions: VersionOptions = {version: workflowDefinition.version}; + const response = await client.workflowDefinitionsApi.export(workflowDefinition.definitionId, versionOptions); + downloadFromBlob(response.data, {contentType: 'application/json', fileName: response.fileName}); } - } - mapWorkflowModel(workflowDefinition: WorkflowDefinition): WorkflowModel { - return { - activities: workflowDefinition.activities.map(this.mapActivityModel), - connections: workflowDefinition.connections.map(this.mapConnectionModel), - persistenceBehavior: workflowDefinition.persistenceBehavior, + @Method() + async importWorkflow(file: File) { + const client = createElsaClient(this.serverUrl); - }; - } + this.importing = true; + this.imported = false; + this.networkError = null; - mapActivityModel(source: ActivityDefinition): ActivityModel { - const descriptors: Array = state.activityDescriptors; - const descriptor = descriptors.find(x => x.type == source.type); + // A small hack to make sure JS Plumb is cleaned up before HTML elements get removed. + await this.designer.destroyJsPlumb(); - return { - activityId: source.activityId, - description: source.description, - displayName: source.displayName, - name: source.name, - type: source.type, - properties: source.properties, - outcomes: [...descriptor.outcomes], - persistOutput: source.persistOutput, - persistWorkflow: source.persistWorkflow, - saveWorkflowContext: source.saveWorkflowContext, - loadWorkflowContext: source.loadWorkflowContext + try { + const workflowDefinition = await client.workflowDefinitionsApi.import(this.workflowDefinition.definitionId, file); + this.workflowDefinition = workflowDefinition; + this.workflowModel = this.mapWorkflowModel(workflowDefinition); + + this.importing = false; + this.imported = true; + setTimeout(() => this.imported = false, 500); + eventBus.emit(EventTypes.WorkflowImported, this, this.workflowDefinition); + } catch (e) { + console.error(e); + this.importing = false; + this.imported = false; + this.networkError = e.message; + setTimeout(() => this.networkError = null, 10000); + } } - } - mapConnectionModel(source: ConnectionDefinition): ConnectionModel { - return { - sourceId: source.sourceActivityId, - targetId: source.targetActivityId, - outcome: source.outcome + @Watch('workflowDefinitionId') + async workflowDefinitionIdChangedHandler(newValue: string) { + const workflowDefinitionId = newValue; + let workflowDefinition: WorkflowDefinition = ElsaWorkflowDefinitionEditorScreen.createWorkflowDefinition(); + workflowDefinition.definitionId = workflowDefinitionId; + const client = createElsaClient(this.serverUrl); + + if (workflowDefinitionId && workflowDefinitionId.length > 0) { + try { + workflowDefinition = await client.workflowDefinitionsApi.getByDefinitionAndVersion(workflowDefinitionId, {isLatest: true}); + } catch { + console.warn(`The specified workflow definition does not exist. Creating a new one.`) + } + } + + this.updateWorkflowDefinition(workflowDefinition); } - } - onShowWorkflowSettingsClick() { - eventBus.emit(EventTypes.ShowWorkflowSettings); - } + @Watch("serverUrl") + async serverUrlChangedHandler(newValue: string) { + if (newValue && newValue.length > 0) + await this.loadActivityDescriptors(); + } - async onPublishClicked() { - await this.publishWorkflow(); - } + @Watch("monacoLibPath") + async monacoLibPathChangedHandler(newValue: string) { + state.monacoLibPath = newValue; + } - async onUnPublishClicked() { - await this.unPublishWorkflow(); - } + @Listen('workflow-changed') + async workflowChangedHandler(event: CustomEvent) { + const workflowModel = event.detail; + await this.saveWorkflowInternal(workflowModel); + } - async onExportClicked() { - await this.exportWorkflow(); - } + async componentWillLoad() { + await this.serverUrlChangedHandler(this.serverUrl); + await this.workflowDefinitionIdChangedHandler(this.workflowDefinitionId); + await this.monacoLibPathChangedHandler(this.monacoLibPath); + } - async onImportClicked(file: File) { - await this.importWorkflow(file); - } + connectedCallback() { + eventBus.on(EventTypes.UpdateWorkflowSettings, this.onUpdateWorkflowSettings); + } - render() { - const tunnelState: WorkflowEditorState = { - serverUrl: this.serverUrl, - workflowDefinitionId: this.workflowDefinition.definitionId - }; + disconnectedCallback() { + eventBus.detach(EventTypes.UpdateWorkflowSettings, this.onUpdateWorkflowSettings); + } - return ( - this.el = el}> - - {this.renderCanvas()} - {this.renderActivityPicker()} - {this.renderActivityEditor()} - - - ); - } + componentDidLoad() { + if (!this.designer) { + this.designer = this.el.querySelector("elsa-designer-tree") as HTMLElsaDesignerTreeElement; + this.designer.model = this.workflowModel; + } + } - renderCanvas() { - return ( - - this.designer = el}/> - {this.renderWorkflowSettingsButton()} - - - - - {this.renderSavingIndicator()} - {this.renderNetworkError()} - {this.renderPublishButton()} - - - - ); - } + async loadActivityDescriptors() { + const client = createElsaClient(this.serverUrl); + state.activityDescriptors = await client.activitiesApi.list(); + } - renderActivityPicker() { - return ; - } + updateWorkflowDefinition(value: WorkflowDefinition) { + this.workflowDefinition = value; + this.workflowModel = this.mapWorkflowModel(value); + } - renderActivityEditor() { - return ; - } + async publishWorkflow() { + this.publishing = true; + await this.saveWorkflow(true); + this.publishing = false; + eventBus.emit(EventTypes.WorkflowPublished, this, this.workflowDefinition); + } - renderWorkflowSettingsButton() { - return ( - this.onShowWorkflowSettingsClick()} type="button" - class="workflow-settings-button fixed top-20 right-12 inline-flex items-center p-2 rounded-full border border-transparent bg-white shadow text-gray-400 hover:text-blue-500 focus:text-blue-500 hover:ring-2 hover:ring-offset-2 hover:ring-blue-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"> - - - - - - ); - } + async unPublishWorkflow() { + this.unPublishing = true; + await this.unpublishWorkflow(); + this.unPublishing = false; + eventBus.emit(EventTypes.WorkflowRetracted, this, this.workflowDefinition); + } - renderWorkflowSettingsModal() { - return; - } + async saveWorkflow(publish?: boolean) { + await this.saveWorkflowInternal(null, publish); + } - renderSavingIndicator() { + async saveWorkflowInternal(workflowModel?: WorkflowModel, publish?: boolean) { + if (!this.serverUrl || this.serverUrl.length == 0) + return; - if (this.publishing) - return undefined; + workflowModel = workflowModel || this.workflowModel; - const message = - this.unPublishing ? 'Unpublishing...' : this.unPublished ? 'Unpublished' - : this.saving ? 'Saving...' : this.saved ? 'Saved' - : this.importing ? 'Importing...' : this.imported ? 'Imported' - : null; + const client = createElsaClient(this.serverUrl); + let workflowDefinition = this.workflowDefinition; - if (!message) - return undefined; + const request: SaveWorkflowDefinitionRequest = { + workflowDefinitionId: workflowDefinition.definitionId || this.workflowDefinitionId, + contextOptions: workflowDefinition.contextOptions, + deleteCompletedInstances: workflowDefinition.deleteCompletedInstances, + description: workflowDefinition.description, + displayName: workflowDefinition.displayName, + isSingleton: workflowDefinition.isSingleton, + name: workflowDefinition.name, + persistenceBehavior: workflowDefinition.persistenceBehavior, + publish: publish || false, + variables: workflowDefinition.variables, + activities: workflowModel.activities.map(x => ({ + activityId: x.activityId, + type: x.type, + name: x.name, + displayName: x.displayName, + description: x.description, + persistWorkflow: x.persistWorkflow, + loadWorkflowContext: x.loadWorkflowContext, + saveWorkflowContext: x.saveWorkflowContext, + persistOutput: x.persistOutput, + properties: x.properties + })), + connections: workflowModel.connections.map(x => ({ + sourceActivityId: x.sourceId, + targetActivityId: x.targetId, + outcome: x.outcome + })), + }; - return ( - - {message} - - ); - } + this.saving = !publish; + this.publishing = publish; - renderNetworkError() { - if (!this.networkError) - return undefined; + try { + workflowDefinition = await client.workflowDefinitionsApi.save(request); + this.workflowDefinition = workflowDefinition; + this.workflowModel = this.mapWorkflowModel(workflowDefinition); - return ( - - An error occurred: {this.networkError} - ); - } + this.saving = false; + this.saved = !publish; + this.publishing = false; + setTimeout(() => this.saved = false, 500); + this.workflowSaved.emit(workflowDefinition); + } catch (e) { + console.error(e); + this.saving = false; + this.saved = false; + this.networkError = e.message; + setTimeout(() => this.networkError = null, 10000); + } + } - renderPublishButton() { - return this.onPublishClicked()} - onUnPublishClicked={() => this.onUnPublishClicked()} - onExportClicked={() => this.onExportClicked()} - onImportClicked={e => this.onImportClicked(e.detail)} - />; - } + async unpublishWorkflow() { + const client = createElsaClient(this.serverUrl); + const workflowDefinitionId = this.workflowDefinition.definitionId; + this.unPublishing = true; - private createWorkflowDefinition(): WorkflowDefinition { - return { - definitionId: this.workflowDefinitionId, - version: 1, - activities: [], - connections: [], - persistenceBehavior: WorkflowPersistenceBehavior.WorkflowBurst, - }; - } + try { + this.workflowDefinition = await client.workflowDefinitionsApi.retract(workflowDefinitionId); + this.unPublishing = false; + this.unPublished = true + setTimeout(() => this.unPublished = false, 500); + } catch (e) { + console.error(e); + this.unPublishing = false; + this.unPublished = false; + this.networkError = e.message; + setTimeout(() => this.networkError = null, 2000); + } + } + + mapWorkflowModel(workflowDefinition: WorkflowDefinition): WorkflowModel { + return { + activities: workflowDefinition.activities.map(this.mapActivityModel), + connections: workflowDefinition.connections.map(this.mapConnectionModel), + persistenceBehavior: workflowDefinition.persistenceBehavior, + + }; + } + + mapActivityModel(source: ActivityDefinition): ActivityModel { + const descriptors: Array = state.activityDescriptors; + const descriptor = descriptors.find(x => x.type == source.type); + + return { + activityId: source.activityId, + description: source.description, + displayName: source.displayName, + name: source.name, + type: source.type, + properties: source.properties, + outcomes: [...descriptor.outcomes], + persistOutput: source.persistOutput, + persistWorkflow: source.persistWorkflow, + saveWorkflowContext: source.saveWorkflowContext, + loadWorkflowContext: source.loadWorkflowContext + } + } + + mapConnectionModel(source: ConnectionDefinition): ConnectionModel { + return { + sourceId: source.sourceActivityId, + targetId: source.targetActivityId, + outcome: source.outcome + } + } + + onShowWorkflowSettingsClick() { + eventBus.emit(EventTypes.ShowWorkflowSettings); + } + + private onUpdateWorkflowSettings = async (workflowDefinition: WorkflowDefinition) => { + this.updateWorkflowDefinition(workflowDefinition); + await this.saveWorkflowInternal(this.workflowModel); + } + + async onPublishClicked() { + await this.publishWorkflow(); + } + + async onUnPublishClicked() { + await this.unPublishWorkflow(); + } + + async onExportClicked() { + await this.exportWorkflow(); + } + + async onImportClicked(file: File) { + await this.importWorkflow(file); + } + + render() { + const tunnelState: WorkflowEditorState = { + serverUrl: this.serverUrl, + workflowDefinitionId: this.workflowDefinition.definitionId + }; + + return ( + this.el = el}> + + {this.renderCanvas()} + {this.renderActivityPicker()} + {this.renderActivityEditor()} + + + ); + } + + renderCanvas() { + return ( + + this.designer = el}/> + {this.renderWorkflowSettingsButton()} + + + + + {this.renderSavingIndicator()} + {this.renderNetworkError()} + {this.renderPublishButton()} + + + + ); + } + + renderActivityPicker() { + return ; + } + + renderActivityEditor() { + return ; + } + + renderWorkflowSettingsButton() { + return ( + this.onShowWorkflowSettingsClick()} type="button" + class="workflow-settings-button fixed top-20 right-12 inline-flex items-center p-2 rounded-full border border-transparent bg-white shadow text-gray-400 hover:text-blue-500 focus:text-blue-500 hover:ring-2 hover:ring-offset-2 hover:ring-blue-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"> + + + + + + ); + } + + renderWorkflowSettingsModal() { + return; + } + + renderSavingIndicator() { + + if (this.publishing) + return undefined; + + const message = + this.unPublishing ? 'Unpublishing...' : this.unPublished ? 'Unpublished' + : this.saving ? 'Saving...' : this.saved ? 'Saved' + : this.importing ? 'Importing...' : this.imported ? 'Imported' + : null; + + if (!message) + return undefined; + + return ( + + {message} + + ); + } + + renderNetworkError() { + if (!this.networkError) + return undefined; + + return ( + + An error occurred: {this.networkError} + ); + } + + renderPublishButton() { + return this.onPublishClicked()} + onUnPublishClicked={() => this.onUnPublishClicked()} + onExportClicked={() => this.onExportClicked()} + onImportClicked={e => this.onImportClicked(e.detail)} + />; + } + + private static createWorkflowDefinition(): WorkflowDefinition { + return { + definitionId: null, + version: 1, + activities: [], + connections: [], + persistenceBehavior: WorkflowPersistenceBehavior.WorkflowBurst, + }; + } }