diff --git a/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IDiagramDesigner.cs b/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IDiagramDesigner.cs
index e77f26fe6..df0d984f2 100644
--- a/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IDiagramDesigner.cs
+++ b/src/modules/Elsa.Studio.Workflows.Core/UI/Contracts/IDiagramDesigner.cs
@@ -1,7 +1,6 @@
using System.Text.Json.Nodes;
using Elsa.Studio.Workflows.Domain.Models;
using Elsa.Studio.Workflows.UI.Contexts;
-using Elsa.Studio.Workflows.UI.Models;
using Microsoft.AspNetCore.Components;
namespace Elsa.Studio.Workflows.UI.Contracts;
diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/package.json b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/package.json
index 414289dea..b618ee26e 100644
--- a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/package.json
+++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/package.json
@@ -8,6 +8,7 @@
"@antv/layout": "^0.3.25",
"@antv/x6": "^2.18.1",
"@antv/x6-plugin-clipboard": "^2.1.6",
+ "@antv/x6-plugin-export": "^2.1.6",
"@antv/x6-plugin-history": "^2.2.4",
"@antv/x6-plugin-keyboard": "^2.2.3",
"@antv/x6-plugin-scroller": "^2.0.10",
diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/create-graph.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/create-graph.ts
index 09b6d97fe..10816b8e6 100644
--- a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/create-graph.ts
+++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/create-graph.ts
@@ -4,7 +4,8 @@ import {Snapline} from "@antv/x6-plugin-snapline";
import {Transform} from "@antv/x6-plugin-transform";
import {Keyboard} from "@antv/x6-plugin-keyboard";
import {Clipboard} from '@antv/x6-plugin-clipboard';
-import {History} from '@antv/x6-plugin-history';
+import { History } from '@antv/x6-plugin-history';
+import { Export } from "@antv/x6-plugin-export";
import {DotNetComponentRef, graphBindings} from "./graph-bindings";
import {DotNetFlowchartDesigner} from "./dotnet-flowchart-designer";
import {Activity} from "../models";
@@ -109,6 +110,8 @@ export async function createGraph(containerId: string, componentRef: DotNetCompo
}
});
+ graph.use(new Export());
+
graph.use(
new History({
enabled: true,
diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/export-content.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/export-content.ts
new file mode 100644
index 000000000..e6d70276a
--- /dev/null
+++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/export-content.ts
@@ -0,0 +1,30 @@
+import { graphBindings } from "./graph-bindings";
+
+export interface CaptureOptions {
+ fileName?: string;
+ padding?: number;
+ format?: string;
+}
+
+export function exportContentToJPEG(graphId: string, options: CaptureOptions) {
+ const { graph } = graphBindings[graphId];
+ if (!graph) return;
+
+ graph.exportJPEG(options.fileName + ".jpeg", {
+ padding: options.padding,
+ });
+}
+export function exportContentToPNG(graphId: string, options: CaptureOptions) {
+ const { graph } = graphBindings[graphId];
+ if (!graph) return;
+
+ graph.exportPNG(options.fileName + ".png", {
+ padding: options.padding,
+ });
+}
+export function exportContentToSVG(graphId: string, options: CaptureOptions) {
+ const { graph } = graphBindings[graphId];
+ if (!graph) return;
+
+ graph.exportSVG(options.fileName + ".svg", {});
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/index.ts b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/index.ts
index 6fc148758..a7ba4b364 100644
--- a/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/index.ts
+++ b/src/modules/Elsa.Studio.Workflows.Designer/ClientLib/src/designer/api/index.ts
@@ -3,6 +3,7 @@ export * from './calculate-activity-size';
export * from './center-content';
export * from './create-graph';
export * from './dispose-graph';
+export * from './export-content';
export * from './graph-bindings';
export * from './load-graph';
export * from './paste-cells';
diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Components/FlowchartDesigner.razor.cs b/src/modules/Elsa.Studio.Workflows.Designer/Components/FlowchartDesigner.razor.cs
index 43a45b277..6d855508b 100644
--- a/src/modules/Elsa.Studio.Workflows.Designer/Components/FlowchartDesigner.razor.cs
+++ b/src/modules/Elsa.Studio.Workflows.Designer/Components/FlowchartDesigner.razor.cs
@@ -327,6 +327,12 @@ public async Task SelectActivityAsync(string id)
///
public async Task CenterContentAsync() => await ScheduleGraphActionAsync(() => _graphApi.CenterContentAsync());
+ ///
+ /// Exports the graphs content to a supplied format.
+ ///
+ /// The capture options
+ public async Task ExportContentToFormatAsync(CaptureOptions captureOptions) => await ScheduleGraphActionAsync(() => _graphApi.ExportContentToFormatAsync(captureOptions));
+
/// Update the Graph Layout.
public async Task AutoLayoutAsync(
JsonObject activity,
diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Elsa.Studio.Workflows.Designer.csproj b/src/modules/Elsa.Studio.Workflows.Designer/Elsa.Studio.Workflows.Designer.csproj
index 721bdb1c8..0412f23eb 100644
--- a/src/modules/Elsa.Studio.Workflows.Designer/Elsa.Studio.Workflows.Designer.csproj
+++ b/src/modules/Elsa.Studio.Workflows.Designer/Elsa.Studio.Workflows.Designer.csproj
@@ -6,25 +6,16 @@
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Interop/X6GraphApi.cs b/src/modules/Elsa.Studio.Workflows.Designer/Interop/X6GraphApi.cs
index c28d41fea..63b12aea0 100644
--- a/src/modules/Elsa.Studio.Workflows.Designer/Interop/X6GraphApi.cs
+++ b/src/modules/Elsa.Studio.Workflows.Designer/Interop/X6GraphApi.cs
@@ -3,6 +3,7 @@
using System.Text.Json.Serialization;
using Elsa.Studio.Workflows.Designer.Contracts;
using Elsa.Studio.Workflows.Designer.Models;
+using Elsa.Studio.Workflows.Designer.Options;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.JSInterop;
@@ -93,6 +94,9 @@ public async Task LoadGraphAsync(X6Graph graph)
/// Center the canvas content.
public async Task CenterContentAsync() => await InvokeAsync(module => module.InvokeVoidAsync("centerContent", _containerId));
+ /// Exports the graphs content to a supplied
+ public async Task ExportContentToFormatAsync(CaptureOptions captureOptions) => await InvokeAsync(module => module.InvokeVoidAsync($"exportContentTo{captureOptions.Format}", _containerId, captureOptions));
+
/// Adjusts the graph layout.
public async Task AutoLayoutAsync(X6Graph graph)
{
diff --git a/src/modules/Elsa.Studio.Workflows.Designer/Options/CaptureOptions.cs b/src/modules/Elsa.Studio.Workflows.Designer/Options/CaptureOptions.cs
new file mode 100644
index 000000000..d6ecfc603
--- /dev/null
+++ b/src/modules/Elsa.Studio.Workflows.Designer/Options/CaptureOptions.cs
@@ -0,0 +1,28 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace Elsa.Studio.Workflows.Designer.Options;
+
+///
+/// Represents the workflow capture options
+///
+public class CaptureOptions
+{
+ ///
+ /// Gets or sets the export format.
+ /// Supported formats are JPEG, SVG and PNG.
+ /// Default: PNG.
+ ///
+ [Required] public string? Format { get; set; } = "PNG";
+
+ ///
+ /// Gets or sets the filename.
+ /// Default: Flowchart
+ ///
+ [Required] public string? FileName { get; set; } = "Flowchart";
+
+ ///
+ /// Gets or sets the padding around the workflow.
+ /// Default: 150.
+ ///
+ public int Padding { get; set; } = 150;
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/CaptureFlowChartDialog.razor.cs b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/CaptureFlowChartDialog.razor.cs
new file mode 100644
index 000000000..d6b21308d
--- /dev/null
+++ b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/CaptureFlowChartDialog.razor.cs
@@ -0,0 +1,48 @@
+using Blazored.FluentValidation;
+using Elsa.Studio.Workflows.Designer.Options;
+using Elsa.Studio.Workflows.Validators;
+using Microsoft.AspNetCore.Components;
+using Microsoft.AspNetCore.Components.Forms;
+using MudBlazor;
+
+namespace Elsa.Studio.Workflows.DiagramDesigners.Flowcharts
+{
+ public partial class CaptureFlowchartDialog
+ {
+ private readonly CaptureOptions _captureModel = new();
+ private EditContext _editContext = null!;
+ private CaptureOptionsValidator _validator = null!;
+ private FluentValidationValidator _fluentValidationValidator = null!;
+ private bool loading = false;
+
+ [CascadingParameter] private IMudDialogInstance MudDialog { get; set; } = null!;
+ [Parameter] public string FileName { get; set; } = null!;
+
+ protected override void OnParametersSet()
+ {
+ _captureModel.FileName = FileName;
+ _editContext = new(_captureModel);
+ _validator = new(Localizer);
+ }
+
+ private Task OnCancelClicked()
+ {
+ MudDialog.Cancel();
+ return Task.CompletedTask;
+ }
+
+ private async Task OnSubmitClicked()
+ {
+ if (!await _fluentValidationValidator.ValidateAsync())
+ return;
+
+ await OnValidSubmit();
+ }
+
+ private Task OnValidSubmit()
+ {
+ MudDialog.Close(_captureModel);
+ return Task.CompletedTask;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/CaptureFlowchartDialog.razor b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/CaptureFlowchartDialog.razor
new file mode 100644
index 000000000..10d40e64a
--- /dev/null
+++ b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/CaptureFlowchartDialog.razor
@@ -0,0 +1,28 @@
+@using Variant = MudBlazor.Variant
+@inherits StudioComponentBase
+@using Elsa.Studio.Workflows.Services
+@inject ILocalizer Localizer
+
+
+
+
+
+
+
+ PNG
+ JPEG
+ SVG
+
+
+ @if (_captureModel.Format != "SVG")
+ {
+
+ }
+
+
+
+
+ @Localizer["Cancel"]
+ @Localizer["Ok"]
+
+
\ No newline at end of file
diff --git a/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDesignerWrapper.razor.cs b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDesignerWrapper.razor.cs
index 86d777038..1b668996c 100644
--- a/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDesignerWrapper.razor.cs
+++ b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDesignerWrapper.razor.cs
@@ -1,10 +1,9 @@
-using System.Text.Json;
-using System.Text.Json.Nodes;
using Elsa.Api.Client.Extensions;
using Elsa.Api.Client.Resources.ActivityDescriptors.Enums;
using Elsa.Api.Client.Resources.ActivityDescriptors.Models;
using Elsa.Api.Client.Shared.Models;
using Elsa.Studio.Workflows.Designer.Components;
+using Elsa.Studio.Workflows.Designer.Options;
using Elsa.Studio.Workflows.Domain.Contracts;
using Elsa.Studio.Workflows.Domain.Models;
using Elsa.Studio.Workflows.Extensions;
@@ -14,6 +13,8 @@
using Humanizer;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
+using System.Text.Json;
+using System.Text.Json.Nodes;
namespace Elsa.Studio.Workflows.DiagramDesigners.Flowcharts;
@@ -137,7 +138,14 @@ public async Task UpdateActivityAsync(string id, JsonObject activity)
/// Centers the content of the designer.
///
public async Task CenterContentAsync() => await Designer.CenterContentAsync();
-
+
+ ///
+ /// Exports the graphs content to a supplied format.
+ ///
+ /// The capture options
+ ///
+ public async Task ExportContentToFormatAsync(CaptureOptions captureOptions) => await Designer.ExportContentToFormatAsync(captureOptions);
+
///
/// Auto layouts the flowchart.
///
@@ -207,7 +215,4 @@ private async Task OnCanvasSelected()
if (ActivitySelected.HasDelegate)
await ActivitySelected.InvokeAsync(Flowchart);
}
-
- private async Task OnZoomToFitClick() => await Designer.ZoomToFitAsync();
- private async Task OnCenterContentClick() => await Designer.CenterContentAsync();
}
\ No newline at end of file
diff --git a/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDiagramDesigner.cs b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDiagramDesigner.cs
index 9965a032b..c2404ce43 100644
--- a/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDiagramDesigner.cs
+++ b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDiagramDesigner.cs
@@ -1,53 +1,38 @@
-using System.Text.Json.Nodes;
+using Elsa.Api.Client.Extensions;
using Elsa.Studio.Localization;
+using Elsa.Studio.Workflows.Designer.Options;
using Elsa.Studio.Workflows.Domain.Models;
-using Elsa.Studio.Workflows.Models;
using Elsa.Studio.Workflows.UI.Contexts;
using Elsa.Studio.Workflows.UI.Contracts;
-using Elsa.Studio.Workflows.UI.Models;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using MudBlazor;
+using System.Text.Json.Nodes;
namespace Elsa.Studio.Workflows.DiagramDesigners.Flowcharts;
///
/// A diagram designer that displays a flowchart.
///
-public class FlowchartDiagramDesigner(ILocalizer localizer) : IDiagramDesignerToolboxProvider
+public class FlowchartDiagramDesigner(ILocalizer localizer, IDialogService dialogService) : IDiagramDesignerToolboxProvider
{
private FlowchartDesignerWrapper? _designerWrapper;
private readonly Guid _id = Guid.NewGuid();
///
- public async Task LoadRootActivityAsync(JsonObject activity, IDictionary? activityStatsMap)
- {
- await InvokeDesignerActionAsync(x => x.LoadFlowchartAsync(activity, activityStatsMap));
- }
+ public async Task LoadRootActivityAsync(JsonObject activity, IDictionary? activityStatsMap) => await InvokeDesignerActionAsync(x => x.LoadFlowchartAsync(activity, activityStatsMap));
///
- public async Task UpdateActivityAsync(string id, JsonObject activity)
- {
- await InvokeDesignerActionAsync(x => x.UpdateActivityAsync(id, activity));
- }
-
+ public async Task UpdateActivityAsync(string id, JsonObject activity) => await InvokeDesignerActionAsync(x => x.UpdateActivityAsync(id, activity));
+
///
- public async Task UpdateActivityStatsAsync(string id, ActivityStats stats)
- {
- await InvokeDesignerActionAsync(x => x.UpdateActivityStatsAsync(id, stats));
- }
+ public async Task UpdateActivityStatsAsync(string id, ActivityStats stats) => await InvokeDesignerActionAsync(x => x.UpdateActivityStatsAsync(id, stats));
///
- public async Task SelectActivityAsync(string id)
- {
- await InvokeDesignerActionAsync(x => x.SelectActivityAsync(id));
- }
+ public async Task SelectActivityAsync(string id) => await InvokeDesignerActionAsync(x => x.SelectActivityAsync(id));
///
- public async Task ReadRootActivityAsync()
- {
- return await _designerWrapper!.ReadRootActivityAsync();
- }
+ public async Task ReadRootActivityAsync() => await _designerWrapper!.ReadRootActivityAsync();
///
public RenderFragment DisplayDesigner(DisplayContext context)
@@ -83,6 +68,8 @@ public IEnumerable GetToolboxItems(bool isReadonly)
{
yield return DisplayToolboxItem(localizer["Auto layout"], Icons.Material.Outlined.AutoAwesomeMosaic, localizer["Auto layout"], OnAutoLayoutClicked);
}
+
+ yield return DisplayToolboxItem(localizer["Capture"], @Icons.Material.Outlined.Fullscreen, localizer["Capture flowchart"], OnCaptureClicked);
}
private RenderFragment DisplayToolboxItem(string title, string icon, string description, Func onClick)
@@ -113,4 +100,36 @@ private async Task InvokeDesignerActionAsync(Func _designerWrapper != null ? _designerWrapper.ZoomToFitAsync() : Task.CompletedTask;
private Task OnCenterClicked() => _designerWrapper != null ? _designerWrapper!.CenterContentAsync() : Task.CompletedTask;
private Task OnAutoLayoutClicked() => _designerWrapper != null ? _designerWrapper!.AutoLayoutAsync() : Task.CompletedTask;
+ private async Task OnCaptureClicked()
+ {
+ if (_designerWrapper is null) return;
+
+ var flowchart = _designerWrapper.Flowchart;
+ var invalidChars = Path.GetInvalidFileNameChars();
+ var name = flowchart?.GetName() ?? "Workflow";
+ var version = flowchart?.GetVersion();
+ var validFileName = string.Concat(name.Select(c => invalidChars.Contains(c) ? "_" : c.ToString())).Trim()
+ + (version is null ? string.Empty : $"_v{version}");
+
+ var parameters = new DialogParameters
+ {
+ { x => x.FileName, validFileName },
+ };
+
+ var options = new DialogOptions
+ {
+ CloseOnEscapeKey = true,
+ Position = DialogPosition.Center,
+ CloseButton = true,
+ FullWidth = true,
+ MaxWidth = MaxWidth.Small
+ };
+
+ var dialogInstance = await dialogService.ShowAsync(localizer["Capture content"], parameters, options);
+ var dialogResult = await dialogInstance.Result;
+ if (dialogResult?.Canceled ?? true) return;
+
+ var captureOptions = dialogResult?.Data as CaptureOptions ?? new();
+ await _designerWrapper.ExportContentToFormatAsync(captureOptions);
+ }
}
\ No newline at end of file
diff --git a/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDiagramDesignerProvider.cs b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDiagramDesignerProvider.cs
index 4c3c76f71..ccb30aa94 100644
--- a/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDiagramDesignerProvider.cs
+++ b/src/modules/Elsa.Studio.Workflows/DiagramDesigners/Flowcharts/FlowchartDiagramDesignerProvider.cs
@@ -1,20 +1,19 @@
-using System.Text.Json.Nodes;
using Elsa.Api.Client.Extensions;
-using Elsa.Api.Client.Resources.WorkflowDefinitions.Models;
using Elsa.Studio.Localization;
using Elsa.Studio.Workflows.UI.Contracts;
using JetBrains.Annotations;
+using MudBlazor;
+using System.Text.Json.Nodes;
namespace Elsa.Studio.Workflows.DiagramDesigners.Flowcharts;
-///
-/// A diagram designer provider for the Flowchart designer.
-///
-[UsedImplicitly]
///
/// Provides flowchart diagram designer services.
///
-public class FlowchartDiagramDesignerProvider(ILocalizer localizer) : IDiagramDesignerProvider
+/// The localizer used to provide localized strings for the designer interface.
+/// The dialog service used to display dialogs within the designer.
+[UsedImplicitly]
+public class FlowchartDiagramDesignerProvider(ILocalizer localizer, IDialogService dialogService) : IDiagramDesignerProvider
{
///
public double Priority => 0;
@@ -23,5 +22,5 @@ public class FlowchartDiagramDesignerProvider(ILocalizer localizer) : IDiagramDe
public bool GetSupportsActivity(JsonObject activity) => activity.GetTypeName() == "Elsa.Flowchart";
///
- public IDiagramDesigner GetEditor() => new FlowchartDiagramDesigner(localizer);
+ public IDiagramDesigner GetEditor() => new FlowchartDiagramDesigner(localizer, dialogService);
}
\ No newline at end of file
diff --git a/src/modules/Elsa.Studio.Workflows/Shared/Components/DiagramDesignerWrapper.razor.cs b/src/modules/Elsa.Studio.Workflows/Shared/Components/DiagramDesignerWrapper.razor.cs
index 2b268ce94..b97030a22 100644
--- a/src/modules/Elsa.Studio.Workflows/Shared/Components/DiagramDesignerWrapper.razor.cs
+++ b/src/modules/Elsa.Studio.Workflows/Shared/Components/DiagramDesignerWrapper.razor.cs
@@ -6,12 +6,9 @@
using Elsa.Studio.Workflows.Domain.Extensions;
using Elsa.Studio.Workflows.Domain.Models;
using Elsa.Studio.Workflows.Extensions;
-using Elsa.Studio.Workflows.Models;
using Elsa.Studio.Workflows.Shared.Args;
using Elsa.Studio.Workflows.UI.Args;
-using Elsa.Studio.Workflows.UI.Contexts;
using Elsa.Studio.Workflows.UI.Contracts;
-using Elsa.Studio.Workflows.UI.Models;
using Humanizer;
using Microsoft.AspNetCore.Components;
using MudBlazor;
@@ -21,108 +18,76 @@ namespace Elsa.Studio.Workflows.Shared.Components;
/// A wrapper around the diagram designer that provides a breadcrumb and a toolbar.
public partial class DiagramDesignerWrapper
{
+ private string? _lastSelectedNodeId;
private IDiagramDesigner? _diagramDesigner;
private Stack _pathSegments = new();
private JsonObject? _currentContainerActivity;
private List _breadcrumbItems = new();
- private IDictionary _activityStats =
- new Dictionary();
+ private IDictionary _activityStats = new Dictionary();
private ActivityGraph _activityGraph = null!;
- private IDictionary _indexedActivityNodes =
- new Dictionary();
+ private IDictionary _indexedActivityNodes = new Dictionary();
+
+ [Inject] private IDiagramDesignerService DiagramDesignerService { get; set; } = null!;
+ [Inject] private IActivityDisplaySettingsRegistry ActivityDisplaySettingsRegistry { get; set; } = null!;
+ [Inject] private IActivityPortService ActivityPortService { get; set; } = null!;
+ [Inject] private IActivityRegistry ActivityRegistry { get; set; } = null!;
+ [Inject] private IIdentityGenerator IdentityGenerator { get; set; } = null!;
+ [Inject] private IActivityExecutionService ActivityExecutionService { get; set; } = null!;
+ [Inject] private IActivityVisitor ActivityVisitor { get; set; } = null!;
+ [Inject] private IWorkflowDefinitionService WorkflowDefinitionService { get; set; } = null!;
+ [Inject] private ISnackbar Snackbar { get; set; } = null!;
- /// The workflow definition version ID.
- [Parameter]
///
/// Gets or sets the workflow definition version id.
///
- public string WorkflowDefinitionVersionId { get; set; } = null!;
+ [Parameter] public string WorkflowDefinitionVersionId { get; set; } = null!;
- /// The root activity to display.
- [Parameter]
///
- /// Gets or sets the activity.
+ /// Gets or sets the root activity.
///
- public JsonObject Activity { get; set; } = null!;
+ [Parameter] public JsonObject Activity { get; set; } = null!;
- /// Whether the designer is read-only.
- [Parameter]
///
/// Indicates whether is read only.
///
- public bool IsReadOnly { get; set; }
+ [Parameter] public bool IsReadOnly { get; set; }
- /// The workflow instance ID, if any.
- [Parameter]
///
/// Gets or sets the workflow instance id.
///
- public string? WorkflowInstanceId { get; set; }
+ [Parameter] public string? WorkflowInstanceId { get; set; }
- /// A custom toolbar to display.
- [Parameter]
///
/// Gets or sets the custom toolbar items.
///
- public RenderFragment? CustomToolbarItems { get; set; }
+ [Parameter] public RenderFragment? CustomToolbarItems { get; set; }
- /// Whether the designer is progressing.
- [Parameter]
///
/// Indicates whether is progressing.
///
- public bool IsProgressing { get; set; }
+ [Parameter] public bool IsProgressing { get; set; }
- /// An event raised when an activity is selected.
- [Parameter]
///
- /// Gets or sets the activity selected event callback.
+ /// Gets or sets the callback event when an activity is selected.
///
- public EventCallback ActivitySelected { get; set; }
+ [Parameter] public EventCallback ActivitySelected { get; set; }
- /// An event raised when an embedded port is selected.
+ ///
+ /// Gets or sets the callback event when an embedded port is selected.
+ ///
[Parameter] public EventCallback GraphUpdated { get; set; }
+ ///
+ /// Gets or sets the callback event when the activity is updated.
+ ///
[Parameter] public EventCallback ActivityUpdated { get; set; }
- /// An event raised when the path changes.
- [Parameter]
///
- /// Gets or sets the path changed event callback.
+ /// Gets or sets the callback event when a path is changed.
///
- public EventCallback PathChanged { get; set; }
-
- [Inject]
- private IDiagramDesignerService DiagramDesignerService { get; set; } = null!;
-
- [Inject]
- private IActivityDisplaySettingsRegistry ActivityDisplaySettingsRegistry { get; set; } = null!;
-
- [Inject]
- private IActivityPortService ActivityPortService { get; set; } = null!;
+ [Parameter] public EventCallback PathChanged { get; set; }
- [Inject]
- private IActivityRegistry ActivityRegistry { get; set; } = null!;
-
- [Inject]
- private IIdentityGenerator IdentityGenerator { get; set; } = null!;
-
- [Inject]
- private IActivityExecutionService ActivityExecutionService { get; set; } = null!;
-
- [Inject]
- private IActivityVisitor ActivityVisitor { get; set; } = null!;
-
- [Inject]
- private IWorkflowDefinitionService WorkflowDefinitionService { get; set; } = null!;
-
- [Inject]
- private ISnackbar Snackbar { get; set; } = null!;
-
- private ActivityPathSegment? CurrentPathSegment =>
- _pathSegments.TryPeek(out var segment) ? segment : null;
-
- private string? _lastSelectedNodeId;
+ private ActivityPathSegment? CurrentPathSegment => _pathSegments.TryPeek(out var segment) ? segment : null;
/// Selects the activity with the specified ID.
/// The ID of the activity ID select.
diff --git a/src/modules/Elsa.Studio.Workflows/Validators/CaptureOptionsValidator.cs b/src/modules/Elsa.Studio.Workflows/Validators/CaptureOptionsValidator.cs
new file mode 100644
index 000000000..b23ab1bcc
--- /dev/null
+++ b/src/modules/Elsa.Studio.Workflows/Validators/CaptureOptionsValidator.cs
@@ -0,0 +1,17 @@
+using Elsa.Studio.Localization;
+using Elsa.Studio.Workflows.Designer.Options;
+using FluentValidation;
+
+namespace Elsa.Studio.Workflows.Validators;
+
+///
+/// A validator for instances.
+///
+public class CaptureOptionsValidator : AbstractValidator
+{
+ public CaptureOptionsValidator(ILocalizer localizer)
+ {
+ RuleFor(x => x.FileName).NotEmpty().WithMessage(localizer["Please enter a filename for the export."]);
+ RuleFor(x => x.Padding).GreaterThanOrEqualTo(0);
+ }
+}
\ No newline at end of file