Implemented version history
This commit is contained in:
parent
8fc3bac949
commit
d614a0dbe6
|
|
@ -257,6 +257,12 @@ export namespace Components {
|
|||
"hide": () => Promise<void>;
|
||||
"show": () => Promise<void>;
|
||||
"workflowDefinition"?: WorkflowDefinition;
|
||||
"workflowVersions": Array<WorkflowDefinition>;
|
||||
}
|
||||
interface ElsaWorkflowDefinitionVersionHistory {
|
||||
"selectedVersion": WorkflowDefinition;
|
||||
"serverUrl": string;
|
||||
"workflowVersions": Array<WorkflowDefinition>;
|
||||
}
|
||||
interface ElsaWorkflowInstanceBrowser {
|
||||
}
|
||||
|
|
@ -569,6 +575,12 @@ declare global {
|
|||
prototype: HTMLElsaWorkflowDefinitionPropertiesEditorElement;
|
||||
new (): HTMLElsaWorkflowDefinitionPropertiesEditorElement;
|
||||
};
|
||||
interface HTMLElsaWorkflowDefinitionVersionHistoryElement extends Components.ElsaWorkflowDefinitionVersionHistory, HTMLStencilElement {
|
||||
}
|
||||
var HTMLElsaWorkflowDefinitionVersionHistoryElement: {
|
||||
prototype: HTMLElsaWorkflowDefinitionVersionHistoryElement;
|
||||
new (): HTMLElsaWorkflowDefinitionVersionHistoryElement;
|
||||
};
|
||||
interface HTMLElsaWorkflowInstanceBrowserElement extends Components.ElsaWorkflowInstanceBrowser, HTMLStencilElement {
|
||||
}
|
||||
var HTMLElsaWorkflowInstanceBrowserElement: {
|
||||
|
|
@ -664,6 +676,7 @@ declare global {
|
|||
"elsa-workflow-definition-editor-toolbox": HTMLElsaWorkflowDefinitionEditorToolboxElement;
|
||||
"elsa-workflow-definition-editor-toolbox-activities": HTMLElsaWorkflowDefinitionEditorToolboxActivitiesElement;
|
||||
"elsa-workflow-definition-properties-editor": HTMLElsaWorkflowDefinitionPropertiesEditorElement;
|
||||
"elsa-workflow-definition-version-history": HTMLElsaWorkflowDefinitionVersionHistoryElement;
|
||||
"elsa-workflow-instance-browser": HTMLElsaWorkflowInstanceBrowserElement;
|
||||
"elsa-workflow-instance-properties": HTMLElsaWorkflowInstancePropertiesElement;
|
||||
"elsa-workflow-instance-viewer": HTMLElsaWorkflowInstanceViewerElement;
|
||||
|
|
@ -893,8 +906,20 @@ declare namespace LocalJSX {
|
|||
"graph"?: Graph;
|
||||
}
|
||||
interface ElsaWorkflowDefinitionPropertiesEditor {
|
||||
"onDeleteVersionClicked"?: (event: CustomEvent<WorkflowDefinition>) => void;
|
||||
"onRevertVersionClicked"?: (event: CustomEvent<WorkflowDefinition>) => void;
|
||||
"onVersionSelected"?: (event: CustomEvent<WorkflowDefinition>) => void;
|
||||
"onWorkflowPropsUpdated"?: (event: CustomEvent<WorkflowDefinitionPropsUpdatedArgs>) => void;
|
||||
"workflowDefinition"?: WorkflowDefinition;
|
||||
"workflowVersions"?: Array<WorkflowDefinition>;
|
||||
}
|
||||
interface ElsaWorkflowDefinitionVersionHistory {
|
||||
"onDeleteVersionClicked"?: (event: CustomEvent<WorkflowDefinition>) => void;
|
||||
"onRevertVersionClicked"?: (event: CustomEvent<WorkflowDefinition>) => void;
|
||||
"onVersionSelected"?: (event: CustomEvent<WorkflowDefinition>) => void;
|
||||
"selectedVersion"?: WorkflowDefinition;
|
||||
"serverUrl"?: string;
|
||||
"workflowVersions"?: Array<WorkflowDefinition>;
|
||||
}
|
||||
interface ElsaWorkflowInstanceBrowser {
|
||||
"onWorkflowInstanceSelected"?: (event: CustomEvent<WorkflowInstanceSummary>) => void;
|
||||
|
|
@ -976,6 +1001,7 @@ declare namespace LocalJSX {
|
|||
"elsa-workflow-definition-editor-toolbox": ElsaWorkflowDefinitionEditorToolbox;
|
||||
"elsa-workflow-definition-editor-toolbox-activities": ElsaWorkflowDefinitionEditorToolboxActivities;
|
||||
"elsa-workflow-definition-properties-editor": ElsaWorkflowDefinitionPropertiesEditor;
|
||||
"elsa-workflow-definition-version-history": ElsaWorkflowDefinitionVersionHistory;
|
||||
"elsa-workflow-instance-browser": ElsaWorkflowInstanceBrowser;
|
||||
"elsa-workflow-instance-properties": ElsaWorkflowInstanceProperties;
|
||||
"elsa-workflow-instance-viewer": ElsaWorkflowInstanceViewer;
|
||||
|
|
@ -1036,6 +1062,7 @@ declare module "@stencil/core" {
|
|||
"elsa-workflow-definition-editor-toolbox": LocalJSX.ElsaWorkflowDefinitionEditorToolbox & JSXBase.HTMLAttributes<HTMLElsaWorkflowDefinitionEditorToolboxElement>;
|
||||
"elsa-workflow-definition-editor-toolbox-activities": LocalJSX.ElsaWorkflowDefinitionEditorToolboxActivities & JSXBase.HTMLAttributes<HTMLElsaWorkflowDefinitionEditorToolboxActivitiesElement>;
|
||||
"elsa-workflow-definition-properties-editor": LocalJSX.ElsaWorkflowDefinitionPropertiesEditor & JSXBase.HTMLAttributes<HTMLElsaWorkflowDefinitionPropertiesEditorElement>;
|
||||
"elsa-workflow-definition-version-history": LocalJSX.ElsaWorkflowDefinitionVersionHistory & JSXBase.HTMLAttributes<HTMLElsaWorkflowDefinitionVersionHistoryElement>;
|
||||
"elsa-workflow-instance-browser": LocalJSX.ElsaWorkflowInstanceBrowser & JSXBase.HTMLAttributes<HTMLElsaWorkflowInstanceBrowserElement>;
|
||||
"elsa-workflow-instance-properties": LocalJSX.ElsaWorkflowInstanceProperties & JSXBase.HTMLAttributes<HTMLElsaWorkflowInstancePropertiesElement>;
|
||||
"elsa-workflow-instance-viewer": LocalJSX.ElsaWorkflowInstanceViewer & JSXBase.HTMLAttributes<HTMLElsaWorkflowInstanceViewerElement>;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
export {BulkActionsIcon} from "./bulk-actions";
|
||||
export {DeleteIcon} from "./delete";
|
||||
export {EditIcon} from "./edit";
|
||||
export {RevertIcon} from "./revert";
|
||||
export {PageSizeIcon} from "./page-size-icon";
|
||||
export {PublishIcon} from "./publish";
|
||||
export {PublishedIcon} from "./published";
|
||||
export {OrderByIcon} from "./order-by";
|
||||
export {UnPublishIcon} from "./un-publish";
|
||||
export {WorkflowIcon} from "./workflow";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
import {FunctionalComponent, h} from "@stencil/core";
|
||||
|
||||
export const PublishedIcon: FunctionalComponent = () =>
|
||||
<svg class="h-6 w-6 text-green-500" width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
||||
</svg>;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import {FunctionalComponent, h} from "@stencil/core";
|
||||
|
||||
export const RevertIcon: FunctionalComponent = () =>
|
||||
<svg class="h-6 w-6 text-gray-500" width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z"/>
|
||||
<path d="M9 11l-4 4l4 4m-4 -4h11a4 4 0 0 0 0 -8h-1"/>
|
||||
</svg>;
|
||||
|
|
@ -202,7 +202,7 @@ export class FlowchartComponent implements ContainerActivityComponent {
|
|||
|
||||
@Method()
|
||||
async import(root: Activity): Promise<void> {
|
||||
return this.importInternal(root);
|
||||
return await this.importInternal(root);
|
||||
}
|
||||
|
||||
@Method()
|
||||
|
|
|
|||
|
|
@ -9,13 +9,15 @@ import {
|
|||
ActivitySelectedArgs,
|
||||
ChildActivitySelectedArgs,
|
||||
ContainerSelectedArgs,
|
||||
GraphUpdatedArgs,
|
||||
GraphUpdatedArgs,
|
||||
VersionedEntity
|
||||
} from '../../../models';
|
||||
import {ActivityIdUpdatedArgs, ActivityUpdatedArgs} from './activity-properties-editor';
|
||||
import {ActivityDriverRegistry, ActivityNameFormatter, EventBus, PluginRegistry, PortProviderRegistry} from '../../../services';
|
||||
import {MonacoEditorSettings} from "../../../services/monaco-editor-settings";
|
||||
import {ActivityPropertyChangedEventArgs, WorkflowDefinitionPropsUpdatedArgs, WorkflowDefinitionUpdatedArgs, WorkflowEditorEventTypes} from "../models/ui";
|
||||
import {WorkflowDefinition} from "../models/entities";
|
||||
import {WorkflowDefinitionsApi} from "../../workflow-definitions/services/api";
|
||||
|
||||
@Component({
|
||||
tag: 'elsa-workflow-definition-editor',
|
||||
|
|
@ -34,6 +36,7 @@ export class WorkflowDefinitionEditor {
|
|||
private readonly emitActivityChangedDebounced: (e: ActivityPropertyChangedEventArgs) => void;
|
||||
private readonly updateModelDebounced: () => void;
|
||||
private readonly saveChangesDebounced: () => void;
|
||||
private readonly workflowDefinitionApi: WorkflowDefinitionsApi;
|
||||
|
||||
constructor() {
|
||||
this.eventBus = Container.get(EventBus);
|
||||
|
|
@ -43,6 +46,7 @@ export class WorkflowDefinitionEditor {
|
|||
this.emitActivityChangedDebounced = debounce(this.emitActivityChanged, 100);
|
||||
this.updateModelDebounced = debounce(this.updateModel, 10);
|
||||
this.saveChangesDebounced = debounce(this.saveChanges, 1000);
|
||||
this.workflowDefinitionApi = Container.get(WorkflowDefinitionsApi);
|
||||
}
|
||||
|
||||
@Prop() workflowDefinition?: WorkflowDefinition;
|
||||
|
|
@ -50,6 +54,7 @@ export class WorkflowDefinitionEditor {
|
|||
@Event() workflowUpdated: EventEmitter<WorkflowDefinitionUpdatedArgs>
|
||||
@State() private workflowDefinitionState: WorkflowDefinition;
|
||||
@State() private selectedActivity?: Activity;
|
||||
@State() workflowVersions: Array<WorkflowDefinition> = [];
|
||||
|
||||
@Watch('monacoLibPath')
|
||||
private handleMonacoLibPath(value: string) {
|
||||
|
|
@ -60,6 +65,7 @@ export class WorkflowDefinitionEditor {
|
|||
@Watch('workflowDefinition')
|
||||
async onWorkflowDefinitionChanged(value: WorkflowDefinition) {
|
||||
await this.importWorkflow(value);
|
||||
await this.loadWorkflowVersions();
|
||||
}
|
||||
|
||||
@Listen('resize', {target: 'window'})
|
||||
|
|
@ -116,6 +122,7 @@ export class WorkflowDefinitionEditor {
|
|||
@Method()
|
||||
async updateWorkflowDefinition(workflowDefinition: WorkflowDefinition): Promise<void> {
|
||||
this.workflowDefinitionState = workflowDefinition;
|
||||
await this.loadWorkflowVersions();
|
||||
}
|
||||
|
||||
@Method()
|
||||
|
|
@ -138,8 +145,19 @@ export class WorkflowDefinitionEditor {
|
|||
return workflowDefinition;
|
||||
}
|
||||
|
||||
loadWorkflowVersions = async () => {
|
||||
if(this.workflowDefinitionState.definitionId != null && this.workflowDefinitionState.definitionId.length > 0)
|
||||
{
|
||||
this.workflowVersions = await this.workflowDefinitionApi.getVersions(this.workflowDefinitionState.definitionId);
|
||||
}
|
||||
else {
|
||||
this.workflowVersions = [];
|
||||
}
|
||||
}
|
||||
|
||||
async componentWillLoad() {
|
||||
await this.updateWorkflowDefinition(this.workflowDefinition);
|
||||
await this.loadWorkflowVersions();
|
||||
}
|
||||
|
||||
async componentDidLoad() {
|
||||
|
|
@ -176,7 +194,8 @@ export class WorkflowDefinitionEditor {
|
|||
};
|
||||
|
||||
private saveChanges = async (): Promise<void> => {
|
||||
this.workflowUpdated.emit({workflowDefinition: this.workflowDefinitionState});
|
||||
const latestVersion = this.workflowVersions.find(v => v.isLatest);
|
||||
this.workflowUpdated.emit({workflowDefinition: this.workflowDefinitionState, latestVersionNumber: latestVersion?.version});
|
||||
};
|
||||
|
||||
private updateLayout = async () => {
|
||||
|
|
@ -231,6 +250,28 @@ export class WorkflowDefinitionEditor {
|
|||
this.saveChangesDebounced();
|
||||
}
|
||||
|
||||
onVersionSelected = async (e: CustomEvent<WorkflowDefinition>) => {
|
||||
const workflowToView = e.detail;
|
||||
const workflowDefinition = await this.workflowDefinitionApi.get({definitionId: workflowToView.definitionId, versionOptions: {version: workflowToView.version}});
|
||||
this.importWorkflow(workflowDefinition);
|
||||
};
|
||||
|
||||
onDeleteVersionClicked = async (e: CustomEvent<WorkflowDefinition>) => {
|
||||
const workflowToDelete = e.detail;
|
||||
await this.workflowDefinitionApi.deleteVersion({definitionId: workflowToDelete.definitionId, version: workflowToDelete.version});
|
||||
const latestWorkflowDefinition = await this.workflowDefinitionApi.get({definitionId: workflowToDelete.definitionId, versionOptions: {isLatest: true}});
|
||||
await this.loadWorkflowVersions();
|
||||
this.importWorkflow(latestWorkflowDefinition);
|
||||
};
|
||||
|
||||
onRevertVersionClicked = async (e: CustomEvent<WorkflowDefinition>) => {
|
||||
const workflowToRevert = e.detail;
|
||||
await this.workflowDefinitionApi.revertVersion({definitionId: workflowToRevert.definitionId, version: workflowToRevert.version});
|
||||
const workflowDefinition = await this.workflowDefinitionApi.get({definitionId: workflowToRevert.definitionId, versionOptions: {isLatest: true}});
|
||||
await this.loadWorkflowVersions();
|
||||
this.importWorkflow(workflowDefinition);
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
|
|
@ -254,7 +295,11 @@ export class WorkflowDefinitionEditor {
|
|||
<div class="object-editor-container">
|
||||
<elsa-workflow-definition-properties-editor
|
||||
workflowDefinition={this.workflowDefinitionState}
|
||||
workflowVersions={this.workflowVersions}
|
||||
onWorkflowPropsUpdated={e => this.onWorkflowPropsUpdated(e)}
|
||||
onVersionSelected={e => this.onVersionSelected(e)}
|
||||
onDeleteVersionClicked={e => this.onDeleteVersionClicked(e)}
|
||||
onRevertVersionClicked={e => this.onRevertVersionClicked(e)}
|
||||
/>
|
||||
</div>
|
||||
</elsa-panel>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ import {PropertiesTabModel, TabModel, WorkflowDefinitionPropsUpdatedArgs, Workfl
|
|||
import {FormEntry} from "../../../components/shared/forms/form-entry";
|
||||
import {isNullOrWhitespace} from "../../../utils";
|
||||
import {InfoList} from "../../../components/shared/forms/info-list";
|
||||
import {TabChangedArgs, Variable} from "../../../models";
|
||||
import {TabChangedArgs, Variable, VersionedEntity} from "../../../models";
|
||||
import {WorkflowDefinitionsApi} from "../../workflow-definitions/services/api";
|
||||
|
||||
@Component({
|
||||
tag: 'elsa-workflow-definition-properties-editor',
|
||||
|
|
@ -14,9 +15,11 @@ import {TabChangedArgs, Variable} from "../../../models";
|
|||
export class WorkflowDefinitionPropertiesEditor {
|
||||
private readonly eventBus: EventBus;
|
||||
private slideOverPanel: HTMLElsaSlideOverPanelElement;
|
||||
private readonly workflowDefinitionApi: WorkflowDefinitionsApi;
|
||||
|
||||
constructor() {
|
||||
this.eventBus = Container.get(EventBus);
|
||||
this.workflowDefinitionApi = Container.get(WorkflowDefinitionsApi);
|
||||
|
||||
this.model = {
|
||||
tabModels: [],
|
||||
|
|
@ -24,7 +27,11 @@ export class WorkflowDefinitionPropertiesEditor {
|
|||
}
|
||||
|
||||
@Prop() workflowDefinition?: WorkflowDefinition;
|
||||
@Prop() workflowVersions: Array<WorkflowDefinition>;
|
||||
@Event() workflowPropsUpdated: EventEmitter<WorkflowDefinitionPropsUpdatedArgs>;
|
||||
@Event() versionSelected: EventEmitter<WorkflowDefinition>;
|
||||
@Event() deleteVersionClicked: EventEmitter<WorkflowDefinition>;
|
||||
@Event() revertVersionClicked: EventEmitter<WorkflowDefinition>;
|
||||
@State() private model: WorkflowPropertiesEditorModel;
|
||||
@State() private selectedTabIndex: number = 0;
|
||||
|
||||
|
|
@ -43,6 +50,11 @@ export class WorkflowDefinitionPropertiesEditor {
|
|||
await this.createModel();
|
||||
}
|
||||
|
||||
@Watch('workflowVersions')
|
||||
async onWorkflowVersionsChanged() {
|
||||
await this.createModel();
|
||||
}
|
||||
|
||||
async componentWillLoad() {
|
||||
await this.createModel();
|
||||
}
|
||||
|
|
@ -127,7 +139,15 @@ export class WorkflowDefinitionPropertiesEditor {
|
|||
}
|
||||
}
|
||||
|
||||
model.tabModels = [propertiesTabModel, variablesTabModel];
|
||||
const versionHistoryTabModel: TabModel = {
|
||||
name: 'versionHistory',
|
||||
tab: {
|
||||
displayText: 'Version History',
|
||||
content: () => this.renderVersionHistoryTab()
|
||||
}
|
||||
}
|
||||
|
||||
model.tabModels = [propertiesTabModel, variablesTabModel, versionHistoryTabModel];
|
||||
|
||||
const args: WorkflowPropertiesEditorDisplayingArgs = {model};
|
||||
|
||||
|
|
@ -152,6 +172,15 @@ export class WorkflowDefinitionPropertiesEditor {
|
|||
</div>
|
||||
};
|
||||
|
||||
private renderVersionHistoryTab = () => {
|
||||
return <div>
|
||||
<elsa-workflow-definition-version-history
|
||||
selectedVersion={this.workflowDefinition}
|
||||
workflowVersions={this.workflowVersions}
|
||||
/>
|
||||
</div>
|
||||
};
|
||||
|
||||
private onSelectedTabIndexChanged = (e: CustomEvent<TabChangedArgs>) => this.selectedTabIndex = e.detail.selectedTabIndex;
|
||||
|
||||
private onPropertyEditorChanged = (apply: (w: WorkflowDefinition) => void) => {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,100 @@
|
|||
import {Component, Event, EventEmitter, h, Host, Method, Prop, State, Watch} from '@stencil/core';
|
||||
import {Container} from "typedi";
|
||||
import {EventBus} from "../../../services";
|
||||
import {WorkflowDefinition} from "../models/entities";
|
||||
import {VersionedEntity} from "../../../models";
|
||||
import {WorkflowDefinitionsApi} from "../../workflow-definitions/services/api";
|
||||
import {DeleteIcon, RevertIcon, PublishedIcon} from "../../../components/icons/tooling";
|
||||
import moment from "moment";
|
||||
|
||||
@Component({
|
||||
tag: 'elsa-workflow-definition-version-history',
|
||||
})
|
||||
export class WorkflowDefinitionVersionHistory {
|
||||
private readonly eventBus: EventBus;
|
||||
private readonly workflowDefinitionApi: WorkflowDefinitionsApi;
|
||||
|
||||
constructor() {
|
||||
this.eventBus = Container.get(EventBus);
|
||||
this.workflowDefinitionApi = Container.get(WorkflowDefinitionsApi);
|
||||
}
|
||||
|
||||
@Prop() selectedVersion: WorkflowDefinition;
|
||||
@Prop() workflowVersions: Array<WorkflowDefinition>;
|
||||
@Prop() serverUrl: string;
|
||||
@Event() versionSelected: EventEmitter<WorkflowDefinition>;
|
||||
@Event() deleteVersionClicked: EventEmitter<WorkflowDefinition>;
|
||||
@Event() revertVersionClicked: EventEmitter<WorkflowDefinition>;
|
||||
|
||||
@Watch('workflowDefinition')
|
||||
async onWorkflowDefinitionChanged(value: WorkflowDefinition) {
|
||||
|
||||
}
|
||||
|
||||
async componentWillLoad() {
|
||||
|
||||
}
|
||||
|
||||
onViewVersionClick = (e: Event, version: WorkflowDefinition) => {
|
||||
e.preventDefault();
|
||||
this.versionSelected.emit(version);
|
||||
};
|
||||
|
||||
onDeleteVersionClick = async (e: Event, version: WorkflowDefinition) => {
|
||||
e.preventDefault();
|
||||
this.deleteVersionClicked.emit(version);
|
||||
};
|
||||
|
||||
onRevertVersionClick = (e: Event, version: WorkflowDefinition) => {
|
||||
e.preventDefault();
|
||||
this.revertVersionClicked.emit(version);
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th/>
|
||||
<th>Version</th>
|
||||
<th>Created</th>
|
||||
<th/>
|
||||
<th/>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{this.workflowVersions.map(v => {
|
||||
return (
|
||||
<tr>
|
||||
<td>{v.isPublished ? <PublishedIcon/> : ""}</td>
|
||||
<td>{v.version}</td>
|
||||
<td>{moment(v.createdAt).format('DD-MM-YYYY HH:mm:ss')}</td>
|
||||
<td>
|
||||
<button onClick={e => this.onViewVersionClick(e, v)}
|
||||
type="button"
|
||||
disabled={this.selectedVersion.version == v.version}
|
||||
class="btn btn-secondary">
|
||||
View
|
||||
</button>
|
||||
</td>
|
||||
<td>
|
||||
{v.isPublished || v.isPublished ? undefined :
|
||||
<elsa-context-menu
|
||||
menuItems={[
|
||||
{text: 'Delete', clickHandler: e => this.onDeleteVersionClick(e, v), icon: <DeleteIcon/>},
|
||||
{text: 'Reverse', clickHandler: e => this.onRevertVersionClick(e, v), icon: <RevertIcon/>},
|
||||
]}
|
||||
/>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@ export interface ActivityPropertyChangedEventArgs {
|
|||
|
||||
export interface WorkflowDefinitionUpdatedArgs {
|
||||
workflowDefinition: WorkflowDefinition;
|
||||
latestVersionNumber: number;
|
||||
}
|
||||
|
||||
export interface WorkflowDefinitionPropsUpdatedArgs {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import {WorkflowDefinitionUpdatedArgs} from "./models/ui";
|
|||
import {PublishClickedArgs} from "./components/publish-button";
|
||||
import {WorkflowDefinitionsApi} from "./services/api";
|
||||
import {DefaultActions, ModalDialogInstance, ModalDialogService} from "../../components/shared/modal-dialog";
|
||||
import {isEqual} from 'lodash'
|
||||
|
||||
const FlowchartTypeName = 'Elsa.Flowchart';
|
||||
|
||||
|
|
@ -106,8 +107,20 @@ export class WorkflowDefinitionsPlugin implements Plugin {
|
|||
};
|
||||
|
||||
private onWorkflowUpdated = async (e: CustomEvent<WorkflowDefinitionUpdatedArgs>) => {
|
||||
const workflowDefinition = e.detail.workflowDefinition;
|
||||
await this.saveWorkflowDefinition(workflowDefinition, false);
|
||||
const updatedWorkflowDefinition = e.detail.workflowDefinition;
|
||||
|
||||
if(e.detail.latestVersionNumber == undefined)
|
||||
{
|
||||
await this.saveWorkflowDefinition(updatedWorkflowDefinition, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if(updatedWorkflowDefinition.version == e.detail.latestVersionNumber)
|
||||
{
|
||||
const currentWorkflowDefinition = await this.api.get({definitionId: updatedWorkflowDefinition.definitionId, versionOptions: {version: updatedWorkflowDefinition.version}});
|
||||
if(!isEqual(currentWorkflowDefinition.root.activities, updatedWorkflowDefinition.root.activities))
|
||||
await this.saveWorkflowDefinition(updatedWorkflowDefinition, false);
|
||||
}
|
||||
}
|
||||
|
||||
private onBrowseWorkflowDefinitions = async () => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { getVersionOptionsString, serializeQueryString } from '../../../utils';
|
||||
import {WorkflowDefinition, WorkflowDefinitionSummary} from "../models/entities";
|
||||
import {Activity, PagedList, Variable, VersionOptions} from "../../../models";
|
||||
import {Activity, PagedList, Variable, VersionedEntity, VersionOptions} from "../../../models";
|
||||
import {Service} from "typedi";
|
||||
import {ElsaApiClientProvider} from "../../../services";
|
||||
|
||||
|
|
@ -30,6 +30,18 @@ export class WorkflowDefinitionsApi {
|
|||
return response.data;
|
||||
}
|
||||
|
||||
async deleteVersion(request: DeleteWorkflowVersionRequest): Promise<WorkflowDefinition> {
|
||||
const httpClient = await this.getHttpClient();
|
||||
const response = await httpClient.delete<WorkflowDefinition>(`workflow-definitions/${request.definitionId}/version/${request.version}`);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async revertVersion(request: RevertWorkflowVersionRequest): Promise<WorkflowDefinition> {
|
||||
const httpClient = await this.getHttpClient();
|
||||
const response = await httpClient.post<WorkflowDefinition>(`workflow-definitions/${request.definitionId}/revert/${request.version}`);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async post(request: SaveWorkflowDefinitionRequest): Promise<WorkflowDefinition> {
|
||||
const httpClient = await this.getHttpClient();
|
||||
const response = await httpClient.post<WorkflowDefinition>('workflow-definitions', request);
|
||||
|
|
@ -47,6 +59,12 @@ export class WorkflowDefinitionsApi {
|
|||
return response.data;
|
||||
}
|
||||
|
||||
async getVersions(workflowDefinitionId: string): Promise<Array<WorkflowDefinition>> {
|
||||
const httpClient = await this.getHttpClient();
|
||||
const response = await httpClient.get<Array<WorkflowDefinition>>(`workflow-definitions/${workflowDefinitionId}/versions`);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async list(request: ListWorkflowDefinitionsRequest): Promise<PagedList<WorkflowDefinitionSummary>> {
|
||||
const queryString: any = {};
|
||||
|
||||
|
|
@ -137,6 +155,7 @@ export class WorkflowDefinitionsApi {
|
|||
|
||||
export interface SaveWorkflowDefinitionRequest {
|
||||
definitionId: string;
|
||||
version?: number;
|
||||
name?: string;
|
||||
description?: string;
|
||||
publish: boolean;
|
||||
|
|
@ -155,6 +174,16 @@ export interface DeleteWorkflowDefinitionRequest {
|
|||
definitionId: string;
|
||||
}
|
||||
|
||||
export interface DeleteWorkflowVersionRequest {
|
||||
definitionId: string;
|
||||
version: number;
|
||||
}
|
||||
|
||||
export interface RevertWorkflowVersionRequest {
|
||||
definitionId: string;
|
||||
version: number;
|
||||
}
|
||||
|
||||
export interface RetractWorkflowDefinitionRequest {
|
||||
definitionId: string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ export class WorkflowDefinitionManager {
|
|||
public saveWorkflow = async (definition: WorkflowDefinition, publish: boolean): Promise<WorkflowDefinition> => {
|
||||
const request: SaveWorkflowDefinitionRequest = {
|
||||
definitionId: definition.definitionId,
|
||||
version: definition.version,
|
||||
name: definition.name,
|
||||
description: definition.description,
|
||||
publish: publish,
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ public class WorkflowInstanceGrain : WorkflowInstanceGrainBase
|
|||
throw new Exception($"No workflow instance found with ID {workflowInstanceId}");
|
||||
|
||||
var workflowDefinitionId = workflowInstance.DefinitionId;
|
||||
var workflow = await _workflowDefinitionStore.FindByDefinitionIdAsync(workflowDefinitionId, VersionOptions.SpecificVersion(workflowInstance.Version), cancellationToken);
|
||||
var workflow = (await _workflowDefinitionStore.FindByDefinitionIdAsync(workflowDefinitionId, VersionOptions.SpecificVersion(workflowInstance.Version), cancellationToken)).FirstOrDefault();
|
||||
|
||||
if (workflow == null)
|
||||
throw new Exception($"No workflow definition found with ID {workflowDefinitionId}");
|
||||
|
|
@ -79,7 +79,7 @@ public class WorkflowInstanceGrain : WorkflowInstanceGrainBase
|
|||
var workflowDefinitionId = request.DefinitionId;
|
||||
var correlationId = request.CorrelationId == "" ? default : request.CorrelationId;
|
||||
var workflowInstance = await _workflowInstanceFactory.CreateAsync(workflowDefinitionId, versionOptions, correlationId, cancellationToken);
|
||||
var workflow = await _workflowDefinitionStore.FindByDefinitionIdAsync(workflowDefinitionId, VersionOptions.SpecificVersion(workflowInstance.Version), cancellationToken);
|
||||
var workflow = (await _workflowDefinitionStore.FindByDefinitionIdAsync(workflowDefinitionId, VersionOptions.SpecificVersion(workflowInstance.Version), cancellationToken)).FirstOrDefault();
|
||||
|
||||
if (workflow == null)
|
||||
throw new Exception($"No workflow definition found with ID {workflowDefinitionId}");
|
||||
|
|
@ -100,7 +100,7 @@ public class WorkflowInstanceGrain : WorkflowInstanceGrainBase
|
|||
var workflowDefinitionId = request.DefinitionId;
|
||||
var bookmark = request.Bookmark;
|
||||
var input = request.Input?.Deserialize();
|
||||
var workflow = await _workflowDefinitionStore.FindByDefinitionIdAsync(workflowDefinitionId, versionOptions, cancellationToken);
|
||||
var workflow = (await _workflowDefinitionStore.FindByDefinitionIdAsync(workflowDefinitionId, versionOptions, cancellationToken)).FirstOrDefault();
|
||||
|
||||
if (workflow == null)
|
||||
throw new Exception($"No workflow definition found with ID {workflowDefinitionId}");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Abstractions;
|
||||
|
|
@ -34,7 +35,7 @@ public class BulkPublish : ElsaEndpoint<Request, Response>
|
|||
|
||||
foreach (var definitionId in request.DefinitionIds)
|
||||
{
|
||||
var definition = await _store.FindByDefinitionIdAsync(definitionId, VersionOptions.Latest, cancellationToken);
|
||||
var definition = (await _store.FindByDefinitionIdAsync(definitionId, VersionOptions.Latest, cancellationToken)).FirstOrDefault();
|
||||
|
||||
if (definition == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Abstractions;
|
||||
|
|
@ -33,7 +34,7 @@ public class BulkRetract : ElsaEndpoint<Request, Response>
|
|||
|
||||
foreach (var definitionId in request.DefinitionIds)
|
||||
{
|
||||
var definition = await _store.FindByDefinitionIdAsync(definitionId, VersionOptions.Latest, cancellationToken);
|
||||
var definition = (await _store.FindByDefinitionIdAsync(definitionId, VersionOptions.Latest, cancellationToken)).FirstOrDefault();
|
||||
|
||||
if (definition == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ public class Export : ElsaEndpoint<Request>
|
|||
{
|
||||
var serializerOptions = _serializerOptionsProvider.CreateApiOptions();
|
||||
var versionOptions = request.VersionOptions != null ? VersionOptions.FromString(request.VersionOptions) : VersionOptions.Latest;
|
||||
var definition = await _store.FindByDefinitionIdAsync(request.DefinitionId, versionOptions, cancellationToken);
|
||||
var definition = (await _store.FindByDefinitionIdAsync(request.DefinitionId, versionOptions, cancellationToken)).FirstOrDefault();
|
||||
|
||||
if (definition == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Abstractions;
|
||||
|
|
@ -26,7 +27,7 @@ public class Get : ElsaEndpoint<Request, WorkflowDefinitionResponse, WorkflowDef
|
|||
public override async Task HandleAsync(Request request, CancellationToken cancellationToken)
|
||||
{
|
||||
var versionOptions = request.VersionOptions != null ? VersionOptions.FromString(request.VersionOptions) : VersionOptions.Latest;
|
||||
var definition = await _store.FindByDefinitionIdAsync(request.DefinitionId, versionOptions, cancellationToken);
|
||||
var definition = (await _store.FindByDefinitionIdAsync(request.DefinitionId, versionOptions, cancellationToken)).FirstOrDefault();
|
||||
|
||||
if (definition == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public class Import : ElsaEndpoint<WorkflowDefinitionRequest, WorkflowDefinition
|
|||
|
||||
// Get a workflow draft version.
|
||||
var draft = !string.IsNullOrWhiteSpace(definitionId)
|
||||
? await _workflowDefinitionPublisher.GetDraftAsync(definitionId, cancellationToken)
|
||||
? await _workflowDefinitionPublisher.GetDraftAsync(definitionId, cancellationToken:cancellationToken)
|
||||
: default;
|
||||
|
||||
var isNew = draft == null;
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ public class Post : ElsaEndpoint<WorkflowDefinitionRequest, WorkflowDefinitionRe
|
|||
|
||||
// Get a workflow draft version.
|
||||
var draft = !string.IsNullOrWhiteSpace(definitionId)
|
||||
? await _workflowDefinitionPublisher.GetDraftAsync(definitionId, cancellationToken)
|
||||
? await _workflowDefinitionPublisher.GetDraftAsync(definitionId, request.Version, cancellationToken)
|
||||
: default;
|
||||
|
||||
var isNew = draft == null;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Abstractions;
|
||||
|
|
@ -28,7 +29,7 @@ public class Publish : ElsaEndpoint<Request, WorkflowDefinitionResponse, Workflo
|
|||
|
||||
public override async Task HandleAsync(Request request, CancellationToken cancellationToken)
|
||||
{
|
||||
var definition = await _store.FindByDefinitionIdAsync(request.DefinitionId, VersionOptions.Latest, cancellationToken);
|
||||
var definition = (await _store.FindByDefinitionIdAsync(request.DefinitionId, VersionOptions.Latest, cancellationToken)).FirstOrDefault();
|
||||
|
||||
if (definition == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Abstractions;
|
||||
|
|
@ -28,7 +29,7 @@ public class Retract : ElsaEndpoint<Request, WorkflowDefinitionResponse, Workflo
|
|||
|
||||
public override async Task HandleAsync(Request request, CancellationToken cancellationToken)
|
||||
{
|
||||
var definition = await _store.FindByDefinitionIdAsync(request.DefinitionId, VersionOptions.LatestOrPublished, cancellationToken);
|
||||
var definition = (await _store.FindByDefinitionIdAsync(request.DefinitionId, VersionOptions.LatestOrPublished, cancellationToken)).FirstOrDefault();
|
||||
|
||||
if (definition == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Workflows.Management.Services;
|
||||
using FastEndpoints;
|
||||
|
||||
namespace Elsa.Workflows.Api.Endpoints.WorkflowDefinitions.Version;
|
||||
|
||||
public class DeleteVersion : EndpointWithoutRequest
|
||||
{
|
||||
private readonly IWorkflowDefinitionManager _workflowDefinitionManager;
|
||||
|
||||
public DeleteVersion(IWorkflowDefinitionManager workflowDefinitionManager)
|
||||
{
|
||||
_workflowDefinitionManager = workflowDefinitionManager;
|
||||
}
|
||||
|
||||
public override void Configure()
|
||||
{
|
||||
Delete("workflow-definitions/{definitionId}/version/{version}");
|
||||
AllowAnonymous();
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CancellationToken ct)
|
||||
{
|
||||
var definitionId = Route<string>("definitionId")!;
|
||||
var version = Route<int>("version");
|
||||
|
||||
var result = await _workflowDefinitionManager.DeleteVersionAsync(definitionId, version, ct);
|
||||
if (!result)
|
||||
{
|
||||
await SendNotFoundAsync(ct);
|
||||
return;
|
||||
}
|
||||
|
||||
await SendOkAsync(ct);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Models;
|
||||
using Elsa.Workflows.Persistence.Services;
|
||||
using FastEndpoints;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Elsa.Workflows.Api.Endpoints.WorkflowDefinitions.Version;
|
||||
|
||||
public class ListVersions : EndpointWithoutRequest
|
||||
{
|
||||
private readonly IWorkflowDefinitionStore _store;
|
||||
|
||||
public ListVersions(IWorkflowDefinitionStore store)
|
||||
{
|
||||
_store = store;
|
||||
}
|
||||
|
||||
public override void Configure()
|
||||
{
|
||||
Get("workflow-definitions/{definitionId}/versions");
|
||||
AllowAnonymous();
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CancellationToken ct)
|
||||
{
|
||||
var definitionId = Route<string>("definitionId")!;
|
||||
|
||||
var result = await _store.FindByDefinitionIdAsync(definitionId, VersionOptions.All, ct);
|
||||
if (!result.Any())
|
||||
{
|
||||
await SendNotFoundAsync(ct);
|
||||
return;
|
||||
}
|
||||
|
||||
await SendAsync(result, StatusCodes.Status200OK, ct);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Workflows.Management.Services;
|
||||
using FastEndpoints;
|
||||
|
||||
namespace Elsa.Workflows.Api.Endpoints.WorkflowDefinitions.Version;
|
||||
|
||||
public class RevertVersion : EndpointWithoutRequest
|
||||
{
|
||||
private readonly IWorkflowDefinitionManager _workflowDefinitionManager;
|
||||
|
||||
public RevertVersion(IWorkflowDefinitionManager workflowDefinitionManager)
|
||||
{
|
||||
_workflowDefinitionManager = workflowDefinitionManager;
|
||||
}
|
||||
|
||||
public override void Configure()
|
||||
{
|
||||
Post("workflow-definitions/{definitionId}/revert/{version}");
|
||||
AllowAnonymous();
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(CancellationToken ct)
|
||||
{
|
||||
var definitionId = Route<string>("definitionId")!;
|
||||
var version = Route<int>("version");
|
||||
|
||||
await _workflowDefinitionManager.RevertVersionAsync(definitionId, version, ct);
|
||||
|
||||
await SendOkAsync(ct);
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ public class WorkflowDefinitionRequest
|
|||
public string? DefinitionId { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Description { get; set; } = default!;
|
||||
public int? Version { get; set; }
|
||||
public ICollection<VariableDefinition>? Variables { get; set; } = default!;
|
||||
public IDictionary<string, object>? Metadata { get; set; } = default!;
|
||||
public IDictionary<string, object>? ApplicationProperties { get; set; } = default!;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
using Elsa.Mediator.Services;
|
||||
using Elsa.Models;
|
||||
using Elsa.Persistence.Common.Extensions;
|
||||
using Elsa.Workflows.Core.Services;
|
||||
using Elsa.Workflows.Management.Notifications;
|
||||
using Elsa.Workflows.Management.Services;
|
||||
using Elsa.Workflows.Persistence.Entities;
|
||||
using Elsa.Workflows.Persistence.Services;
|
||||
|
||||
namespace Elsa.Workflows.Management.Implementations;
|
||||
|
|
@ -9,11 +13,19 @@ public class WorkflowDefinitionManager : IWorkflowDefinitionManager
|
|||
{
|
||||
private readonly IWorkflowDefinitionStore _store;
|
||||
private readonly IEventPublisher _eventPublisher;
|
||||
private readonly IWorkflowDefinitionPublisher _workflowPublisher;
|
||||
private readonly IIdentityGenerator _identityGenerator;
|
||||
|
||||
public WorkflowDefinitionManager(IWorkflowDefinitionStore store, IEventPublisher eventPublisher)
|
||||
public WorkflowDefinitionManager(
|
||||
IWorkflowDefinitionStore store,
|
||||
IEventPublisher eventPublisher,
|
||||
IWorkflowDefinitionPublisher workflowPublisher,
|
||||
IIdentityGenerator identityGenerator)
|
||||
{
|
||||
_store = store;
|
||||
_eventPublisher = eventPublisher;
|
||||
_workflowPublisher = workflowPublisher;
|
||||
_identityGenerator = identityGenerator;
|
||||
}
|
||||
|
||||
public async Task<int> DeleteByDefinitionIdAsync(string definitionId, CancellationToken cancellationToken = default)
|
||||
|
|
@ -30,4 +42,55 @@ public class WorkflowDefinitionManager : IWorkflowDefinitionManager
|
|||
await _eventPublisher.PublishAsync(new WorkflowDefinitionsDeleted(ids), cancellationToken);
|
||||
return count;
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteVersionAsync(string definitionId, int versionToDelete, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var workflows = (await _store.FindLatestAndPublishedByDefinitionIdAsync(definitionId, cancellationToken)).ToList();
|
||||
var latestVersion = workflows.WithVersion(VersionOptions.Latest).First();
|
||||
var publishedVersion = workflows.WithVersion(VersionOptions.Published).FirstOrDefault();
|
||||
|
||||
if (versionToDelete == publishedVersion?.Version)
|
||||
{
|
||||
throw new Exception("Published version cannot be deleted");
|
||||
}
|
||||
|
||||
var isDeleted = await _store.DeleteByDefinitionIdAndVersionAsync(definitionId, versionToDelete, cancellationToken) > 0;
|
||||
|
||||
if (isDeleted)
|
||||
{
|
||||
await _eventPublisher.PublishAsync(new WorkflowDefinitionVersionDeleted(definitionId, versionToDelete), cancellationToken);
|
||||
if (latestVersion.Version == versionToDelete)
|
||||
{
|
||||
var lastVersion = await _store.FindLastVersionByDefinitionIdAsync(definitionId, cancellationToken);
|
||||
if (lastVersion is not null)
|
||||
{
|
||||
lastVersion.IsLatest = true;
|
||||
await _store.SaveAsync(lastVersion, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isDeleted;
|
||||
}
|
||||
|
||||
public async Task<WorkflowDefinition> RevertVersionAsync(string definitionId, int version, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var publishedAndLatestVersions = (await _store.FindLatestAndPublishedByDefinitionIdAsync(definitionId, cancellationToken)).ToList();
|
||||
if (publishedAndLatestVersions.Any(v => v.Version == version))
|
||||
{
|
||||
throw new Exception("Latest or published versions cannot be reverted");
|
||||
}
|
||||
|
||||
var latestVersion = publishedAndLatestVersions.First(v => v.IsLatest);
|
||||
latestVersion.IsLatest = false;
|
||||
await _store.SaveAsync(latestVersion, cancellationToken);
|
||||
|
||||
var draft = await _workflowPublisher.GetDraftAsync(definitionId, version, cancellationToken);
|
||||
draft!.Id = _identityGenerator.GenerateId();
|
||||
draft.Version = latestVersion.Version + 1;
|
||||
draft.IsLatest = true;
|
||||
|
||||
await _store.SaveAsync(draft, cancellationToken);
|
||||
return draft;
|
||||
}
|
||||
}
|
||||
|
|
@ -56,7 +56,7 @@ namespace Elsa.Workflows.Management.Implementations
|
|||
|
||||
public async Task<WorkflowDefinition?> PublishAsync(string definitionId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var definition = await _workflowDefinitionStore.FindByDefinitionIdAsync(definitionId, VersionOptions.Latest, cancellationToken);
|
||||
var definition = (await _workflowDefinitionStore.FindByDefinitionIdAsync(definitionId, VersionOptions.Latest, cancellationToken)).FirstOrDefault();
|
||||
|
||||
if (definition == null)
|
||||
return null;
|
||||
|
|
@ -94,7 +94,7 @@ namespace Elsa.Workflows.Management.Implementations
|
|||
|
||||
public async Task<WorkflowDefinition?> RetractAsync(string definitionId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var definition = await _workflowDefinitionStore.FindByDefinitionIdAsync(definitionId, VersionOptions.Published, cancellationToken);
|
||||
var definition = (await _workflowDefinitionStore.FindByDefinitionIdAsync(definitionId, VersionOptions.Published, cancellationToken)).FirstOrDefault();
|
||||
|
||||
if (definition == null)
|
||||
return null;
|
||||
|
|
@ -116,9 +116,9 @@ namespace Elsa.Workflows.Management.Implementations
|
|||
return definition;
|
||||
}
|
||||
|
||||
public async Task<WorkflowDefinition?> GetDraftAsync(string definitionId, CancellationToken cancellationToken = default)
|
||||
public async Task<WorkflowDefinition?> GetDraftAsync(string definitionId, int? version, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var definition = await _workflowDefinitionStore.FindByDefinitionIdAsync(definitionId, VersionOptions.Latest, cancellationToken);
|
||||
var definition = (await _workflowDefinitionStore.FindByDefinitionIdAsync(definitionId, version.HasValue ? VersionOptions.SpecificVersion(version.Value) : VersionOptions.Latest, cancellationToken)).FirstOrDefault();
|
||||
|
||||
if (definition == null)
|
||||
return null;
|
||||
|
|
@ -139,7 +139,7 @@ namespace Elsa.Workflows.Management.Implementations
|
|||
{
|
||||
var draft = definition;
|
||||
var definitionId = definition.DefinitionId;
|
||||
var latestVersion = await _workflowDefinitionStore.FindByDefinitionIdAsync(definitionId, VersionOptions.Latest, cancellationToken);
|
||||
var latestVersion = (await _workflowDefinitionStore.FindByDefinitionIdAsync(definitionId, VersionOptions.Latest, cancellationToken)).FirstOrDefault();
|
||||
|
||||
if (latestVersion is { IsPublished: true, IsLatest: true })
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
using Elsa.Mediator.Services;
|
||||
|
||||
namespace Elsa.Workflows.Management.Notifications;
|
||||
|
||||
public record WorkflowDefinitionVersionDeleted(string DefinitionId, int Version) : INotification;
|
||||
|
|
@ -1,7 +1,11 @@
|
|||
using Elsa.Workflows.Persistence.Entities;
|
||||
|
||||
namespace Elsa.Workflows.Management.Services;
|
||||
|
||||
public interface IWorkflowDefinitionManager
|
||||
{
|
||||
Task<int> DeleteByDefinitionIdAsync(string definitionId, CancellationToken cancellationToken = default);
|
||||
Task<bool> DeleteVersionAsync(string definitionId, int version, CancellationToken cancellationToken = default);
|
||||
Task<int> BulkDeleteByDefinitionIdsAsync(IEnumerable<string> definitionIds, CancellationToken cancellationToken = default);
|
||||
Task<WorkflowDefinition> RevertVersionAsync(string definitionId, int version, CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ namespace Elsa.Workflows.Management.Services
|
|||
Task<WorkflowDefinition> PublishAsync(WorkflowDefinition definition, CancellationToken cancellationToken = default);
|
||||
Task<WorkflowDefinition?> RetractAsync(string definitionId, CancellationToken cancellationToken = default);
|
||||
Task<WorkflowDefinition> RetractAsync(WorkflowDefinition definition, CancellationToken cancellationToken = default);
|
||||
Task<WorkflowDefinition?> GetDraftAsync(string definitionId, CancellationToken cancellationToken = default);
|
||||
Task<WorkflowDefinition?> GetDraftAsync(string definitionId, int? version = null, CancellationToken cancellationToken = default);
|
||||
Task<WorkflowDefinition> SaveDraftAsync(WorkflowDefinition definition, CancellationToken cancellationToken = default);
|
||||
}
|
||||
}
|
||||
|
|
@ -18,4 +18,8 @@
|
|||
<ProjectReference Include="..\Elsa.Workflows.Persistence.EntityFrameworkCore\Elsa.Workflows.Persistence.EntityFrameworkCore.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Migrations" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|||
namespace Elsa.Workflows.Persistence.EntityFrameworkCore.Sqlite.Migrations
|
||||
{
|
||||
[DbContext(typeof(WorkflowsDbContext))]
|
||||
[Migration("20220814124730_Initial")]
|
||||
[Migration("20220828110255_Initial")]
|
||||
partial class Initial
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
|
|
@ -56,6 +56,9 @@ namespace Elsa.Workflows.Persistence.EntityFrameworkCore.Sqlite.Migrations
|
|||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("WorkflowVersion")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ActivityId")
|
||||
|
|
@ -188,6 +191,9 @@ namespace Elsa.Workflows.Persistence.EntityFrameworkCore.Sqlite.Migrations
|
|||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("WorkflowVersion")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ActivityId")
|
||||
|
|
@ -214,6 +220,9 @@ namespace Elsa.Workflows.Persistence.EntityFrameworkCore.Sqlite.Migrations
|
|||
b.HasIndex("WorkflowInstanceId")
|
||||
.HasDatabaseName("IX_WorkflowExecutionLogRecord_WorkflowInstanceId");
|
||||
|
||||
b.HasIndex("WorkflowVersion")
|
||||
.HasDatabaseName("IX_WorkflowExecutionLogRecord_WorkflowVersion");
|
||||
|
||||
b.ToTable("WorkflowExecutionLogRecords");
|
||||
});
|
||||
|
||||
|
|
@ -19,6 +19,7 @@ namespace Elsa.Workflows.Persistence.EntityFrameworkCore.Sqlite.Migrations
|
|||
Data = table.Column<string>(type: "TEXT", nullable: true),
|
||||
WorkflowDefinitionId = table.Column<string>(type: "TEXT", nullable: false),
|
||||
WorkflowInstanceId = table.Column<string>(type: "TEXT", nullable: false),
|
||||
WorkflowVersion = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
CorrelationId = table.Column<string>(type: "TEXT", nullable: true),
|
||||
ActivityId = table.Column<string>(type: "TEXT", nullable: false),
|
||||
ActivityInstanceId = table.Column<string>(type: "TEXT", nullable: false),
|
||||
|
|
@ -59,6 +60,7 @@ namespace Elsa.Workflows.Persistence.EntityFrameworkCore.Sqlite.Migrations
|
|||
Id = table.Column<string>(type: "TEXT", nullable: false),
|
||||
WorkflowDefinitionId = table.Column<string>(type: "TEXT", nullable: false),
|
||||
WorkflowInstanceId = table.Column<string>(type: "TEXT", nullable: false),
|
||||
WorkflowVersion = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
ActivityInstanceId = table.Column<string>(type: "TEXT", nullable: false),
|
||||
ParentActivityInstanceId = table.Column<string>(type: "TEXT", nullable: true),
|
||||
ActivityId = table.Column<string>(type: "TEXT", nullable: false),
|
||||
|
|
@ -209,6 +211,11 @@ namespace Elsa.Workflows.Persistence.EntityFrameworkCore.Sqlite.Migrations
|
|||
table: "WorkflowExecutionLogRecords",
|
||||
column: "WorkflowInstanceId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_WorkflowExecutionLogRecord_WorkflowVersion",
|
||||
table: "WorkflowExecutionLogRecords",
|
||||
column: "WorkflowVersion");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_WorkflowInstance_CorrelationId",
|
||||
table: "WorkflowInstances",
|
||||
|
|
@ -54,6 +54,9 @@ namespace Elsa.Workflows.Persistence.EntityFrameworkCore.Sqlite.Migrations
|
|||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("WorkflowVersion")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ActivityId")
|
||||
|
|
@ -186,6 +189,9 @@ namespace Elsa.Workflows.Persistence.EntityFrameworkCore.Sqlite.Migrations
|
|||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("WorkflowVersion")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ActivityId")
|
||||
|
|
@ -212,6 +218,9 @@ namespace Elsa.Workflows.Persistence.EntityFrameworkCore.Sqlite.Migrations
|
|||
b.HasIndex("WorkflowInstanceId")
|
||||
.HasDatabaseName("IX_WorkflowExecutionLogRecord_WorkflowInstanceId");
|
||||
|
||||
b.HasIndex("WorkflowVersion")
|
||||
.HasDatabaseName("IX_WorkflowExecutionLogRecord_WorkflowVersion");
|
||||
|
||||
b.ToTable("WorkflowExecutionLogRecords");
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ namespace Elsa.Workflows.Persistence.EntityFrameworkCore.EntityConfiguration
|
|||
builder.HasIndex(x => x.EventName).HasDatabaseName($"IX_{nameof(WorkflowExecutionLogRecord)}_{nameof(WorkflowExecutionLogRecord.EventName)}");
|
||||
builder.HasIndex(x => x.WorkflowDefinitionId).HasDatabaseName($"IX_{nameof(WorkflowExecutionLogRecord)}_{nameof(WorkflowExecutionLogRecord.WorkflowDefinitionId)}");
|
||||
builder.HasIndex(x => x.WorkflowInstanceId).HasDatabaseName($"IX_{nameof(WorkflowExecutionLogRecord)}_{nameof(WorkflowExecutionLogRecord.WorkflowInstanceId)}");
|
||||
builder.HasIndex(x => x.WorkflowVersion).HasDatabaseName($"IX_{nameof(WorkflowExecutionLogRecord)}_{nameof(WorkflowExecutionLogRecord.WorkflowVersion)}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ using Elsa.Persistence.EntityFrameworkCore.Common.Services;
|
|||
using Elsa.Workflows.Persistence.Entities;
|
||||
using Elsa.Workflows.Persistence.Models;
|
||||
using Elsa.Workflows.Persistence.Services;
|
||||
using Open.Linq.AsyncExtensions;
|
||||
|
||||
namespace Elsa.Workflows.Persistence.EntityFrameworkCore.Implementations;
|
||||
|
||||
|
|
@ -17,11 +18,11 @@ public class EFCoreWorkflowDefinitionStore : IWorkflowDefinitionStore
|
|||
public async Task<WorkflowDefinition?> FindByIdAsync(string id, CancellationToken cancellationToken = default) =>
|
||||
await _store.FindAsync(x => x.Id == id, cancellationToken);
|
||||
|
||||
public async Task<WorkflowDefinition?> FindByDefinitionIdAsync(string definitionId, VersionOptions versionOptions, CancellationToken cancellationToken = default)
|
||||
public async Task<IEnumerable<WorkflowDefinition>> FindByDefinitionIdAsync(string definitionId, VersionOptions versionOptions, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Expression<Func<WorkflowDefinition, bool>> predicate = x => x.DefinitionId == definitionId;
|
||||
predicate = predicate.WithVersion(versionOptions);
|
||||
return await _store.FindAsync(predicate, cancellationToken);
|
||||
return await _store.FindManyAsync(predicate, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<WorkflowDefinition?> FindByNameAsync(string name, VersionOptions versionOptions, CancellationToken cancellationToken = default)
|
||||
|
|
@ -48,6 +49,14 @@ public class EFCoreWorkflowDefinitionStore : IWorkflowDefinitionStore
|
|||
public async Task<IEnumerable<WorkflowDefinition>> FindLatestAndPublishedByDefinitionIdAsync(string definitionId, CancellationToken cancellationToken = default) =>
|
||||
await _store.FindManyAsync(x => x.DefinitionId == definitionId && (x.IsLatest || x.IsPublished), cancellationToken);
|
||||
|
||||
public async Task<WorkflowDefinition?> FindLastVersionByDefinitionIdAsync(string definitionId, CancellationToken cancellationToken)
|
||||
{
|
||||
await using var dbContext = await _store.CreateDbContextAsync(cancellationToken);
|
||||
var set = dbContext.WorkflowDefinitions;
|
||||
var query = set.AsQueryable();
|
||||
return query.Where(w => w.DefinitionId == definitionId).OrderByDescending(w => w.Version).FirstOrDefault();
|
||||
}
|
||||
|
||||
public async Task SaveAsync(WorkflowDefinition record, CancellationToken cancellationToken = default) => await _store.SaveAsync(record, cancellationToken);
|
||||
public async Task SaveManyAsync(IEnumerable<WorkflowDefinition> records, CancellationToken cancellationToken = default) => await _store.SaveManyAsync(records, cancellationToken);
|
||||
|
||||
|
|
@ -60,6 +69,15 @@ public class EFCoreWorkflowDefinitionStore : IWorkflowDefinitionStore
|
|||
await dbContext.WorkflowBookmarks.DeleteWhereAsync(dbContext, x => x.WorkflowDefinitionId == definitionId, cancellationToken);
|
||||
return await dbContext.WorkflowDefinitions.DeleteWhereAsync(dbContext, x => x.DefinitionId == definitionId, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<int> DeleteByDefinitionIdAndVersionAsync(string definitionId, int version, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await using var dbContext = await _store.CreateDbContextAsync(cancellationToken);
|
||||
await dbContext.WorkflowExecutionLogRecords.DeleteWhereAsync(dbContext, x => x.WorkflowDefinitionId == definitionId && x.WorkflowVersion == version, cancellationToken);
|
||||
await dbContext.WorkflowInstances.DeleteWhereAsync(dbContext, x => x.DefinitionId == definitionId && x.Version == version, cancellationToken);
|
||||
await dbContext.WorkflowBookmarks.DeleteWhereAsync(dbContext, x => x.WorkflowDefinitionId == definitionId && x.WorkflowVersion == version, cancellationToken);
|
||||
return await dbContext.WorkflowDefinitions.DeleteWhereAsync(dbContext, x => x.DefinitionId == definitionId && x.Version == version, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<int> DeleteByDefinitionIdsAsync(IEnumerable<string> definitionIds, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ public class WorkflowBookmark : Entity
|
|||
public string? Data { get; set; }
|
||||
public string WorkflowDefinitionId { get; init; } = default!;
|
||||
public string WorkflowInstanceId { get; init; } = default!;
|
||||
public int WorkflowVersion { get; init; } = default!;
|
||||
public string? CorrelationId { get; init; }
|
||||
public string ActivityId { get; init; } = default!;
|
||||
public string ActivityInstanceId { get; init; } = default!;
|
||||
|
|
@ -23,6 +24,7 @@ public class WorkflowBookmark : Entity
|
|||
Id = bookmark.Id,
|
||||
WorkflowDefinitionId = workflowInstance.DefinitionId,
|
||||
WorkflowInstanceId = workflowInstance.Id,
|
||||
WorkflowVersion = workflowInstance.Version,
|
||||
CorrelationId = workflowInstance.CorrelationId,
|
||||
Hash = bookmark.Hash,
|
||||
Data = bookmark.Data,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ namespace Elsa.Workflows.Persistence.Entities
|
|||
{
|
||||
public string WorkflowDefinitionId { get; set; } = default!;
|
||||
public string WorkflowInstanceId { get; set; } = default!;
|
||||
public int WorkflowVersion { get; init; }
|
||||
public string ActivityInstanceId { get; set; } = default!;
|
||||
public string? ParentActivityInstanceId { get; set; }
|
||||
public string ActivityId { get; set; } = default!;
|
||||
|
|
|
|||
|
|
@ -32,9 +32,9 @@ public class MemoryWorkflowDefinitionStore : IWorkflowDefinitionStore
|
|||
return Task.FromResult(definition);
|
||||
}
|
||||
|
||||
public Task<WorkflowDefinition?> FindByDefinitionIdAsync(string definitionId, VersionOptions versionOptions, CancellationToken cancellationToken = default)
|
||||
public Task<IEnumerable<WorkflowDefinition>> FindByDefinitionIdAsync(string definitionId, VersionOptions versionOptions, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var definition = _store.Find(x => x.DefinitionId == definitionId && x.WithVersion(versionOptions));
|
||||
var definition = _store.FindMany(x => x.DefinitionId == definitionId && x.WithVersion(versionOptions));
|
||||
return Task.FromResult(definition);
|
||||
}
|
||||
|
||||
|
|
@ -64,6 +64,12 @@ public class MemoryWorkflowDefinitionStore : IWorkflowDefinitionStore
|
|||
return Task.FromResult(definitions);
|
||||
}
|
||||
|
||||
public Task<WorkflowDefinition?> FindLastVersionByDefinitionIdAsync(string definitionId, CancellationToken cancellationToken)
|
||||
{
|
||||
var query = _store.List();
|
||||
return Task.FromResult(query.Where(w => w.DefinitionId == definitionId).OrderByDescending(w => w.Version).FirstOrDefault());
|
||||
}
|
||||
|
||||
public Task SaveAsync(WorkflowDefinition record, CancellationToken cancellationToken = default)
|
||||
{
|
||||
_store.Save(record);
|
||||
|
|
@ -84,6 +90,14 @@ public class MemoryWorkflowDefinitionStore : IWorkflowDefinitionStore
|
|||
var result = _store.DeleteWhere(x => x.DefinitionId == definitionId);
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
public Task<int> DeleteByDefinitionIdAndVersionAsync(string definitionId, int version, CancellationToken cancellationToken = default)
|
||||
{
|
||||
_bookmarkStore.DeleteWhere(x => x.WorkflowDefinitionId == definitionId && x.WorkflowVersion == version);
|
||||
_instanceStore.DeleteWhere(x => x.DefinitionId == definitionId && x.Version == version);
|
||||
var result = _store.DeleteWhere(x => x.DefinitionId == definitionId && x.Version == version);
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
public Task<int> DeleteByDefinitionIdsAsync(IEnumerable<string> definitionIds, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ public interface IWorkflowDefinitionStore
|
|||
/// <summary>
|
||||
/// Finds a workflow definition by its logical definition ID and specified version options.
|
||||
/// </summary>
|
||||
Task<WorkflowDefinition?> FindByDefinitionIdAsync(string definitionId, VersionOptions versionOptions, CancellationToken cancellationToken = default);
|
||||
Task<IEnumerable<WorkflowDefinition>> FindByDefinitionIdAsync(string definitionId, VersionOptions versionOptions, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Finds a workflow definition by name and specified version options.
|
||||
|
|
@ -23,9 +23,11 @@ public interface IWorkflowDefinitionStore
|
|||
|
||||
Task<IEnumerable<WorkflowDefinitionSummary>> FindManySummariesAsync(IEnumerable<string> definitionIds, VersionOptions? versionOptions = default, CancellationToken cancellationToken = default);
|
||||
Task<IEnumerable<WorkflowDefinition>> FindLatestAndPublishedByDefinitionIdAsync(string definitionId, CancellationToken cancellationToken = default);
|
||||
Task<WorkflowDefinition?> FindLastVersionByDefinitionIdAsync(string definitionId, CancellationToken cancellationToken);
|
||||
Task SaveAsync(WorkflowDefinition record, CancellationToken cancellationToken = default);
|
||||
Task SaveManyAsync(IEnumerable<WorkflowDefinition> records, CancellationToken cancellationToken = default);
|
||||
Task<int> DeleteByDefinitionIdAsync(string definitionId, CancellationToken cancellationToken = default);
|
||||
Task<int> DeleteByDefinitionIdAndVersionAsync(string definitionId, int version, CancellationToken cancellationToken = default);
|
||||
Task<int> DeleteByDefinitionIdsAsync(IEnumerable<string> definitionIds, CancellationToken cancellationToken = default);
|
||||
|
||||
Task<Page<WorkflowDefinitionSummary>> ListSummariesAsync(
|
||||
|
|
|
|||
|
|
@ -44,10 +44,10 @@ public class PopulateWorkflowDefinitionStore : IHostedService
|
|||
private async Task AddOrUpdateAsync(WorkflowDefinition definition, CancellationToken cancellationToken = default)
|
||||
{
|
||||
// Check if there's already a workflow definition by the definition ID and version.
|
||||
var existingDefinition = await _workflowDefinitionStore.FindByDefinitionIdAsync(
|
||||
var existingDefinition = (await _workflowDefinitionStore.FindByDefinitionIdAsync(
|
||||
definition.DefinitionId,
|
||||
VersionOptions.SpecificVersion(definition.Version),
|
||||
cancellationToken);
|
||||
cancellationToken)).FirstOrDefault();
|
||||
|
||||
if (existingDefinition == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ public class DefaultWorkflowInvoker : IWorkflowInvoker
|
|||
|
||||
public async Task<RunWorkflowResult> InvokeAsync(WorkflowInstance workflowInstance, Bookmark? bookmark = default, IDictionary<string, object>? input = default, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var workflow = await _workflowDefinitionStore.FindByDefinitionIdAsync(workflowInstance.DefinitionId, VersionOptions.SpecificVersion(workflowInstance.Version), cancellationToken);
|
||||
var workflow = (await _workflowDefinitionStore.FindByDefinitionIdAsync(workflowInstance.DefinitionId, VersionOptions.SpecificVersion(workflowInstance.Version), cancellationToken)).FirstOrDefault();
|
||||
|
||||
if (workflow == null)
|
||||
throw new Exception($"Workflow instance references a workflow that does not exist");
|
||||
|
|
@ -73,7 +73,7 @@ public class DefaultWorkflowInvoker : IWorkflowInvoker
|
|||
|
||||
private async Task<WorkflowDefinition> GetWorkflowDefinitionAsync(string definitionId, VersionOptions versionOptions, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var definition = await _workflowDefinitionStore.FindByDefinitionIdAsync(definitionId, versionOptions, cancellationToken);
|
||||
var definition = (await _workflowDefinitionStore.FindByDefinitionIdAsync(definitionId, versionOptions, cancellationToken)).FirstOrDefault();
|
||||
|
||||
if (definition == null)
|
||||
throw new Exception($"Workflow instance references a workflow that does not exist");
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ public class WorkflowInstanceFactory : IWorkflowInstanceFactory
|
|||
|
||||
public async Task<WorkflowInstance> CreateAsync(string workflowDefinitionId, VersionOptions versionOptions, string? correlationId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var workflow = (await _workflowDefinitionStore.FindByDefinitionIdAsync(workflowDefinitionId, versionOptions, cancellationToken))!;
|
||||
var workflow = (await _workflowDefinitionStore.FindByDefinitionIdAsync(workflowDefinitionId, versionOptions, cancellationToken)).FirstOrDefault()!;
|
||||
return await CreateAsync(workflow, correlationId, cancellationToken);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public class ResumeWorkflowInstructionInterpreter : WorkflowInstructionInterpret
|
|||
return null;
|
||||
}
|
||||
|
||||
var definition = await _workflowDefinitionStore.FindByDefinitionIdAsync(workflowDefinitionId, VersionOptions.SpecificVersion(workflowInstance.Version), cancellationToken);
|
||||
var definition = (await _workflowDefinitionStore.FindByDefinitionIdAsync(workflowDefinitionId, VersionOptions.SpecificVersion(workflowInstance.Version), cancellationToken)).FirstOrDefault();
|
||||
|
||||
if (definition == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ public class PersistWorkflowExecutionLogMiddleware : WorkflowExecutionMiddleware
|
|||
EventName = x.EventName,
|
||||
WorkflowDefinitionId = context.Workflow.Identity.DefinitionId,
|
||||
WorkflowInstanceId = context.Id,
|
||||
WorkflowVersion = context.Workflow.Version,
|
||||
Source = x.Source,
|
||||
Payload = x.Payload,
|
||||
Timestamp = x.Timestamp
|
||||
|
|
|
|||
Loading…
Reference in a new issue