Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
ba7625b
Add `GetCallStackAsync` method to `IActivityExecutionService` and its…
sfmskywalker Jan 23, 2026
715fcae
Add call stack viewer to `WorkflowInstanceViewer` with activity selec…
sfmskywalker Jan 23, 2026
1084f8b
Add `SelectActivityByIdAsync` method to `WorkflowInstanceWorkspace` a…
sfmskywalker Jan 23, 2026
9645293
Refactor `Journal.razor`: simplify structure by removing unused `MudT…
sfmskywalker Jan 23, 2026
576bba4
Remove unused `MudDynamicTabs` reference and obsolete namespace impor…
sfmskywalker Jan 23, 2026
3314a48
Add call stack visualization for activity executions
sfmskywalker Jan 23, 2026
ffccf77
Add `ExecutionSelected` callback to `ActivityExecutionsTab` and invok…
sfmskywalker Jan 23, 2026
cc5bce0
Add support for `SelectedActivityExecutionId` and `ActivityExecutionS…
sfmskywalker Jan 23, 2026
a7e587f
Remove support for activity execution selection callbacks.
sfmskywalker Jan 23, 2026
4f7ffb6
Add pinning support to call stack and improve activity selection logic
sfmskywalker Jan 24, 2026
3000129
Enhance call stack handling with `ActivityExecutionSelected` logic an…
sfmskywalker Jan 24, 2026
2061e72
Refactor activity execution details and improve UX.
sfmskywalker Feb 4, 2026
8a0c86b
Set default pin state and optimize activity execution handling
sfmskywalker Feb 4, 2026
423a0fe
Refactor `Journal.razor`: remove unused `Color` property and streamli…
sfmskywalker Feb 4, 2026
feecd87
Update src/modules/Elsa.Studio.Workflows/Shared/Components/DiagramDes…
sfmskywalker Feb 4, 2026
5e800d4
Remove unused `Models` import and redundant icon style calculation fr…
sfmskywalker Feb 4, 2026
d266ca2
Merge remote-tracking branch 'origin/feat/activity-call-stack' into f…
sfmskywalker Feb 4, 2026
2660d19
Make WorkflowInstanceDetails and WorkflowInstanceDesigner readonly fo…
sfmskywalker Feb 4, 2026
7a7632d
Remove readonly keyword from WorkflowInstanceDetails and WorkflowInst…
sfmskywalker Feb 4, 2026
1edcaa1
Refactor `ActivityCallStack` and `WorkflowInstanceViewer` for streaml…
sfmskywalker Feb 5, 2026
5e7d1cf
Enhance journal selection logic and refactor workflow log record sele…
sfmskywalker Feb 5, 2026
925fc67
Refactor `WorkflowInstanceViewer` to improve programmatic selection h…
sfmskywalker Feb 5, 2026
79df730
Enhance `ActivityCallStack` with selected entry tracking and virtuali…
sfmskywalker Feb 6, 2026
3507fab
Implement activity name retrieval in `WorkflowInstanceViewer`
sfmskywalker Feb 6, 2026
6d31297
Merge remote-tracking branch 'origin/main' into feat/activity-call-stack
sfmskywalker Feb 20, 2026
b21302f
Update `ShowMessageBox` to `ShowMessageBoxAsync` and upgrade package …
sfmskywalker Feb 20, 2026
752354d
Upgrade `CodeBeam.MudBlazor.Extensions` to `9.0.0-rc.1` and optimize …
sfmskywalker Feb 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 57 additions & 53 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,75 +4,79 @@
<CentralPackageTransitivePinningEnabled>false</CentralPackageTransitivePinningEnabled>
</PropertyGroup>
<ItemGroup Label="Elsa">
<PackageVersion Include="Elsa.Api.Client" Version="3.6.0-rc2" />
<PackageVersion Include="Elsa.Api.Client" Version="3.7.0-preview.4406" />
</ItemGroup>
<ItemGroup>
<PackageVersion Include="Blazored.FluentValidation" Version="2.2.0" />
<PackageVersion Include="Blazored.LocalStorage" Version="4.5.0" />
<PackageVersion Include="BlazorMonaco" Version="3.4.0" />
<PackageVersion Include="CodeBeam.MudBlazor.Extensions" Version="8.3.0" />
<PackageVersion Include="FluentValidation" Version="12.1.0" />
<PackageVersion Include="CodeBeam.MudBlazor.Extensions" Version="9.0.0-rc.1" />
<PackageVersion Include="FluentValidation" Version="12.1.1" />
<PackageVersion Include="JetBrains.Annotations" Version="2025.2.4" PrivateAssets="all" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="all" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="10.0.103" PrivateAssets="all" />
<PackageVersion Include="Microsoft.AspNetCore.App" Version="2.2.8" />
<PackageVersion Include="MudBlazor" Version="8.15.0" />
<PackageVersion Include="MudBlazor" Version="9.0.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.ResxSourceGenerator" Version="5.0.0-1.25277.114" />
<PackageVersion Include="MudBlazor.Translations" Version="2.7.0" />
<PackageVersion Include="Radzen.Blazor" Version="8.3.5" />
<PackageVersion Include="Radzen.Blazor" Version="9.0.5" />
<PackageVersion Include="ShortGuid" Version="2.0.1" />
<PackageVersion Include="ThrottleDebounce" Version="2.0.1" />
<PackageVersion Include="Refit.HttpClientFactory" Version="9.0.2" />
<PackageVersion Include="Refit" Version="9.0.2" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.22" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="8.0.22" />
<PackageVersion Include="Microsoft.AspNetCore.Components" Version="8.0.22" />
<PackageVersion Include="Microsoft.AspNetCore.Components.Authorization" Version="8.0.22" />
<PackageVersion Include="Microsoft.AspNetCore.Components.CustomElements" Version="8.0.22" />
<PackageVersion Include="Microsoft.AspNetCore.Components.Web" Version="8.0.22" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.22" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="8.0.22" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.22" PrivateAssets="all" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.22" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.11" />
<PackageVersion Include="Microsoft.JSInterop" Version="8.0.22" />
<PackageVersion Include="Microsoft.AspNetCore.WebUtilities" Version="8.0.22" />
<PackageVersion Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.22" />
<PackageVersion Include="Microsoft.Extensions.Http.Polly" Version="9.0.11" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.24" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="8.0.24" />
<PackageVersion Include="Microsoft.AspNetCore.Components" Version="8.0.24" />
<PackageVersion Include="Microsoft.AspNetCore.Components.Authorization" Version="8.0.24" />
<PackageVersion Include="Microsoft.AspNetCore.Components.CustomElements" Version="8.0.24" />
<PackageVersion Include="Microsoft.AspNetCore.Components.Web" Version="8.0.24" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.24" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="8.0.24" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.24" PrivateAssets="all" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.24" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.13" />
<PackageVersion Include="Microsoft.JSInterop" Version="8.0.24" />
<PackageVersion Include="Microsoft.AspNetCore.WebUtilities" Version="8.0.24" />
<PackageVersion Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.24" />
<PackageVersion Include="Microsoft.Extensions.Http.Polly" Version="9.0.13" />
<PackageVersion Include="Refit.HttpClientFactory" Version="9.0.2" />
<PackageVersion Include="Refit" Version="9.0.2" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.11" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="9.0.11" />
<PackageVersion Include="Microsoft.AspNetCore.Components" Version="9.0.11" />
<PackageVersion Include="Microsoft.AspNetCore.Components.Authorization" Version="9.0.11" />
<PackageVersion Include="Microsoft.AspNetCore.Components.CustomElements" Version="9.0.11" />
<PackageVersion Include="Microsoft.AspNetCore.Components.Web" Version="9.0.11" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.11" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="9.0.11" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="9.0.11" PrivateAssets="all" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.11" />
<PackageVersion Include="Microsoft.AspNetCore.WebUtilities" Version="9.0.11" />
<PackageVersion Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.11" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.11" />
<PackageVersion Include="Microsoft.JSInterop" Version="9.0.11" />
<PackageVersion Include="Microsoft.Extensions.Http.Polly" Version="9.0.11" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.13" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="9.0.13" />
<PackageVersion Include="Microsoft.AspNetCore.Components" Version="9.0.13" />
<PackageVersion Include="Microsoft.AspNetCore.Components.Authorization" Version="9.0.13" />
<PackageVersion Include="Microsoft.AspNetCore.Components.CustomElements" Version="9.0.13" />
<PackageVersion Include="Microsoft.AspNetCore.Components.Web" Version="9.0.13" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.13" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="9.0.13" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="9.0.13" PrivateAssets="all" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.13" />
<PackageVersion Include="Microsoft.AspNetCore.WebUtilities" Version="9.0.13" />
<PackageVersion Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.13" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.13" />
<PackageVersion Include="Microsoft.JSInterop" Version="9.0.13" />
<PackageVersion Include="Microsoft.Extensions.Http.Polly" Version="9.0.13" />
<PackageVersion Include="Refit.HttpClientFactory" Version="9.0.2" />
<PackageVersion Include="Refit" Version="9.0.2" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net10.0'">
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="10.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Components" Version="10.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Components.Authorization" Version="10.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Components.CustomElements" Version="10.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Components.Web" Version="10.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="10.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="10.0.1" PrivateAssets="all" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="10.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.SignalR.Client" Version="10.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.WebUtilities" Version="10.0.1" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.1" />
<PackageVersion Include="Microsoft.JSInterop" Version="10.0.1" />
<PackageVersion Include="Microsoft.Extensions.Http.Polly" Version="10.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.3" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="10.0.3" />
<PackageVersion Include="Microsoft.AspNetCore.Components" Version="10.0.3" />
<PackageVersion Include="Microsoft.AspNetCore.Components.Authorization" Version="10.0.3" />
<PackageVersion Include="Microsoft.AspNetCore.Components.CustomElements" Version="10.0.3" />
<PackageVersion Include="Microsoft.AspNetCore.Components.Web" Version="10.0.3" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.0.3" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="10.0.3" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="10.0.3" PrivateAssets="all" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="10.0.3" />
<PackageVersion Include="Microsoft.AspNetCore.SignalR.Client" Version="10.0.3" />
<PackageVersion Include="Microsoft.AspNetCore.WebUtilities" Version="10.0.3" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.3" />
<PackageVersion Include="Microsoft.JSInterop" Version="10.0.3" />
<PackageVersion Include="Microsoft.Extensions.Http.Polly" Version="10.0.3" />
<PackageVersion Include="Refit.HttpClientFactory" Version="10.0.1" />
<PackageVersion Include="Refit" Version="10.0.1" />
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion src/modules/Elsa.Studio.Labels/UI/Pages/Labels.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ private async Task OnRowClick(TableRowClickEventArgs<LabelModel> e)
/// <param name="model">The label to delete.</param>
private async Task OnDeleteClicked(LabelModel model)
{
var result = await DialogService.ShowMessageBox("Delete label?", "Are you sure you want to delete this label?", yesText: "Delete", cancelText: "Cancel");
var result = await DialogService.ShowMessageBoxAsync("Delete label?", "Are you sure you want to delete this label?", yesText: "Delete", cancelText: "Cancel");

if (result != true)
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,13 @@ public interface IActivityExecutionService
/// </summary>
Task<ActivityExecutionRecord?> GetAsync(string id, CancellationToken cancellationToken = default);

/// <summary>
/// Gets the call stack (execution chain) for a given activity execution.
/// </summary>
Task<ActivityExecutionCallStack> GetCallStackAsync(string activityExecutionId, bool? includeCrossWorkflowChain = null, int? skip = null, int? take = null, CancellationToken cancellationToken = default);

/// <summary>
/// Retrieves a paginated list of retry attempt records for a specific activity instance.
/// </summary>
Task<PagedListResponse<RetryAttemptRecord>> GetRetriesAsync(string activityInstanceId, int? skip = null, int? take = null, CancellationToken cancellationToken = default);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,17 @@ public async Task<IEnumerable<ActivityExecutionRecordSummary>> ListSummariesAsyn
return await api.GetAsync(id, cancellationToken);
}

/// <inheritdoc />
public async Task<ActivityExecutionCallStack> GetCallStackAsync(string activityExecutionId, bool? includeCrossWorkflowChain = null, int? skip = null, int? take = null, CancellationToken cancellationToken = default)
{
var api = await backendApiClientProvider.GetApiAsync<IActivityExecutionsApi>(cancellationToken);
return await api.GetCallStackAsync(activityExecutionId, includeCrossWorkflowChain, skip, take, cancellationToken);
}

/// <inheritdoc />
public async Task<PagedListResponse<RetryAttemptRecord>> GetRetriesAsync(string activityInstanceId, int? skip = null, int? take = null, CancellationToken cancellationToken = default)
{
var api = await backendApiClientProvider.GetApiAsync<IRetryAttemptsApi>(cancellationToken);
return await api.ListAsync(activityInstanceId, skip, take, cancellationToken);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,18 @@ protected override async Task OnParametersSetAsync()
await ActivityRegistry.EnsureLoadedAsync();

var activity = Activity;
var activityName = activity.GetName()?.Trim();
var activityDisplayText = activity.GetDisplayText()?.Trim();
var activityDescription = activity.GetDescription()?.Trim();
var activityType = activity.GetTypeName();
var activityVersion = activity.GetVersion();
var descriptor = ActivityRegistry.Find(activityType, activityVersion);
var displaySettings = ActivityDisplaySettingsRegistry.GetSettings(activityType);

Label = !string.IsNullOrEmpty(activityDisplayText) ? activityDisplayText : descriptor?.DisplayName ?? descriptor?.Name ?? "Unknown Activity";
// Hierarchy: Activity Name > Custom Display Text > Type Name
Label = !string.IsNullOrEmpty(activityName)
? activityName
: (!string.IsNullOrEmpty(activityDisplayText) ? activityDisplayText : descriptor?.DisplayName ?? descriptor?.Name ?? "Unknown Activity");
TypeName = descriptor?.DisplayName ?? "Unknown Activity";
Description = !string.IsNullOrEmpty(activityDescription) ? activityDescription : descriptor?.Description ?? string.Empty;
var currentShowDescription = activity.GetShowDescription() == true;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
@using Elsa.Studio.Workflows.Services
@using Variant = MudBlazor.Variant
@using Elsa.Api.Client.Resources.ActivityDescriptors.Models
@using System.Text.Json.Nodes
@using System.Text.Json
@using Elsa.Studio.Workflows.Domain.Contracts
@using Elsa.Studio.Workflows.Models
@using Elsa.Studio.Workflows.UI.Contracts
@inherits StudioComponentBase
@using Microsoft.Extensions.Localization
@inject ILocalizer Localizer

<style>
Expand Down Expand Up @@ -48,7 +41,7 @@
<MudTreeView @ref="_treeView"
Items="@_treeItemData"
FilterFunc="@(x => MatchesName((ActivityTreeItem)x))"
SelectionMode="MudBlazor.SelectionMode.SingleSelection"
SelectionMode="SelectionMode.SingleSelection"
Dense="true">
<ItemTemplate>
@{
Expand All @@ -59,10 +52,10 @@
Visible="@item.Visible"
Items="@item.Children"
OnDoubleClick="@(() => OnItemDoubleClick(item))"
title="@Localizer[item.ActivityDescriptor?.Description]"
title="@(item.ActivityDescriptor?.Description is { } description ? Localizer[description] : "")"
@bind-Expanded="@item.Expanded"
draggable="@(item.ActivityDescriptor is not null ? "true" : "false")"
@ondragstart="@((e) => {
@ondragstart="@(() => {
if (item.ActivityDescriptor is not null)
{
OnDragStart(item.ActivityDescriptor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ namespace Elsa.Studio.Workflows.ActivityPickers.Treeview;
/// </summary>
public partial class ActivityPicker
{
private bool _expanded = false;
private bool _expanded;
private string _searchText = "";
private MudTreeView<string> _treeView;
private List<TreeItemData<string>> _treeItemData = [];
private MudTreeView<string> _treeView = null!;
private readonly List<ITreeItemData<string>> _treeItemData = [];

private IEnumerable<ActivityDescriptor> ActivityDescriptors { get; set; } = new List<ActivityDescriptor>();

Expand Down Expand Up @@ -59,36 +59,36 @@ private void BuildTree()
foreach (var category in categories)
{
var node = FindOrCreateCategoryNode(currentLevel, category, activity.Category);
currentLevel = node.Children;
currentLevel = node.ChildrenList;
}

// Add the activity node
var displaySettings = ActivityDisplaySettingsRegistry.GetSettings(activity.TypeName);
var activityNode = new ActivityTreeItem(activity.DisplayName ?? activity.Name)
{
ActivityDescriptor = activity,
CategoryPath = activity.Category,
Icon = displaySettings?.Icon,
IconColor = displaySettings?.Color
CategoryPath = activity.Category ?? string.Empty,
Icon = displaySettings.Icon,
IconColor = displaySettings.Color
};

// Insert node in an alphabetically sorted order
InsertSorted(currentLevel, activityNode);
}
}

private ActivityTreeItem FindOrCreateCategoryNode(List<TreeItemData<string>> level, string category, string? path)
private ActivityTreeItem FindOrCreateCategoryNode(List<ITreeItemData<string>> level, string category, string? path)
{
var node = level.OfType<ActivityTreeItem>().FirstOrDefault(x => x.Text.Equals(category, StringComparison.OrdinalIgnoreCase));
if (node == null)
{
node = new ActivityTreeItem(category) { CategoryPath = path };
node = new(category) { CategoryPath = path ?? string.Empty };
InsertSorted(level, node);
}
return node;
}

private void InsertSorted(List<TreeItemData<string>> list, ActivityTreeItem node)
private void InsertSorted(List<ITreeItemData<string>> list, ActivityTreeItem node)
{
var index = list.OfType<ActivityTreeItem>()
.ToList()
Expand Down
Loading
Loading