Skip to content

Commit

Permalink
Improve data display in workflow viewer (#176)
Browse files Browse the repository at this point in the history
Condensed the code for displaying activity state, outcomes, and output data in the workflow instance viewer. Added no-data alerts and revamped refresh mechanisms to enhance user interaction and provide informative feedback when data is missing.
  • Loading branch information
sfmskywalker authored Mar 14, 2024
1 parent af83ebe commit 1c95b3e
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 50 deletions.
64 changes: 44 additions & 20 deletions src/framework/Elsa.Studio.Shared/Components/DataPanel.razor
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,39 @@
<MudSimpleTable Outlined="true" Striped="false" Dense="true" Elevation="0" Bordered="false">
<tbody>
@{
var data = HideEmptyValues ? Data.Where(x => !string.IsNullOrWhiteSpace(x.Value.Text)) : Data;
var data = (HideEmptyValues
? Data.Where(x => !string.IsNullOrWhiteSpace(x.Value.Text))
: Data)
.ToDictionary(x => x.Key, x => x.Value);
}
@foreach (var item in data)
@if (data.Any())
{
<tr>
<td style="width: 200px;">@item.Key</td>
<td style="width: 50px;">
<MudIconButton Icon="@Icons.Material.Outlined.ContentCopy" Size="Size.Small" Title="Copy" OnClick="@(() => OnCopyClicked(item.Value.Text!))" Disabled="@(string.IsNullOrWhiteSpace(item.Value.Text))"/>
</td>
<td>
@if (!string.IsNullOrWhiteSpace(item.Value.Link))
{
<MudLink Href="@item.Value.Link">@item.Value.Text</MudLink>
}
else
{
<span>@item.Value.Text</span>
}
</td>
</tr>
@foreach (var item in data)
{
<tr>
<td style="width: 200px;">@item.Key</td>
<td style="width: 50px;">
<MudIconButton Icon="@Icons.Material.Outlined.ContentCopy" Size="Size.Small" Title="Copy" OnClick="@(() => OnCopyClicked(item.Value.Text!))" Disabled="@(string.IsNullOrWhiteSpace(item.Value.Text))"/>
</td>
<td>
@if (!string.IsNullOrWhiteSpace(item.Value.Link))
{
<MudLink Href="@item.Value.Link">@item.Value.Text</MudLink>
}
else
{
<span>@item.Value.Text</span>
}
</td>
</tr>
}
}
else
{
if (ShowNoDataAlert)
{
<MudAlert Severity="Severity.Normal" Dense="true" Variant="Variant.Text">@NoDataMessage</MudAlert>
}
}
</tbody>
</MudSimpleTable>
Expand All @@ -42,8 +55,19 @@
[Parameter]
public bool HideEmptyValues { get; set; }

[Inject]
private IClipboard Clipboard { get; set; } = default!;
/// <summary>
/// If true, a message will be displayed when there is no data.
/// </summary>
[Parameter]
public bool ShowNoDataAlert { get; set; }

/// <summary>
/// The message to display when there is no data.
/// </summary>
[Parameter]
public string NoDataMessage { get; set; } = "No data available.";

[Inject] private IClipboard Clipboard { get; set; } = default!;

private async Task OnCopyClicked(string value)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,14 @@ public record ActivityExecutionRecordTableRow(int Number, ActivityExecutionRecor

private ActivityExecutionRecord? LastActivityExecution => ActivityExecutions.LastOrDefault();

private IEnumerable<ActivityExecutionRecordTableRow> Items =>
ActivityExecutions.Select((x, i) => new ActivityExecutionRecordTableRow(i + 1, x));

private IEnumerable<ActivityExecutionRecordTableRow> Items
{
get
{
return ActivityExecutions.Select((x, i) => new ActivityExecutionRecordTableRow(i + 1, x));
}
}

private ActivityExecutionRecord? SelectedItem { get; set; } = default!;

private IDictionary<string, DataPanelItem> ActivityInfo { get; set; } = new Dictionary<string, DataPanelItem>();
Expand All @@ -55,16 +60,24 @@ public record ActivityExecutionRecordTableRow(int Number, ActivityExecutionRecor
private IDictionary<string, string?> SelectedOutcomesData { get; set; } = new Dictionary<string, string?>();
private IDictionary<string, string?> SelectedOutputData { get; set; } = new Dictionary<string, string?>();

/// <summary>
/// Refreshes the component.
/// </summary>
public void Refresh()
{
CreateDataModels();
}

/// <inheritdoc />
protected override void OnParametersSet()
{
SelectedItem = null;
CreateDataModels();
}

/// <inheritdoc />
protected override void OnInitialized()
{
SelectedItem = null;
CreateDataModels();
}

private void CreateDataModels()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,30 +37,22 @@
</PagerContent>
</MudTable>

<div>
@if (SelectedActivityState.Any())
{
@if (SelectedItem != null)
{
<div>
<div>
<MudText Typo="Typo.overline" GutterBottom="true" Align="Align.Left">State</MudText>
<DataPanel Data="@SelectedActivityState" HideEmptyValues="false"/>
<DataPanel Data="@SelectedActivityState" HideEmptyValues="false" ShowNoDataAlert="true" NoDataMessage="No state associated with this execution."/>
</div>
}

@if (SelectedOutcomesData.Any())
{
<div>
<MudText Typo="Typo.overline" GutterBottom="true" Align="Align.Left">Outcomes</MudText>
<DataPanel Data="@SelectedOutcomesData" HideEmptyValues="true"/>
<DataPanel Data="@SelectedOutcomesData" HideEmptyValues="true" ShowNoDataAlert="true" NoDataMessage="No outcomes associated with this execution."/>
</div>
}

@if (SelectedOutputData.Any())
{
<div>
<MudText Typo="Typo.overline" GutterBottom="true" Align="Align.Left">Output</MudText>
<DataPanel Data="@SelectedOutputData" HideEmptyValues="false"/>
<DataPanel Data="@SelectedOutputData" HideEmptyValues="false" ShowNoDataAlert="true" NoDataMessage="No output associated with this execution."/>
</div>
}
</div>
</div>
}
</MudStack>
</ScrollableWell>
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ public record ActivityExecutionRecordTableRow(int Number, ActivityExecutionRecor
private IDictionary<string, DataPanelItem> SelectedActivityState { get; set; } = new Dictionary<string, DataPanelItem>();
private IDictionary<string, DataPanelItem> SelectedOutcomesData { get; set; } = new Dictionary<string, DataPanelItem>();
private IDictionary<string, DataPanelItem> SelectedOutputData { get; set; } = new Dictionary<string, DataPanelItem>();

/// <summary>
/// Refreshes the component.
/// </summary>
public void Refresh()
{
SelectedItem = null;
SelectedActivityState = new Dictionary<string, DataPanelItem>();
SelectedOutcomesData = new Dictionary<string, DataPanelItem>();
SelectedOutputData = new Dictionary<string, DataPanelItem>();
}

private void CreateSelectedItemDataModels(ActivityExecutionRecord? record)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@
@if (SelectedActivity != null)
{
<MudTabPanel Text="Activity">
<ActivityDetailsTab Activity="@SelectedActivity" ActivityExecutions="SelectedActivityExecutions" VisiblePaneHeight="@_propertiesPaneHeight"/>
<ActivityDetailsTab @ref="_activityDetailsTab" Activity="@SelectedActivity" ActivityExecutions="SelectedActivityExecutions" VisiblePaneHeight="@_propertiesPaneHeight"/>
</MudTabPanel>

<MudTabPanel Text="Executions" BadgeData="@SelectedActivityExecutions.Count">
<ActivityExecutionsTab Activity="@SelectedActivity" ActivityExecutions="SelectedActivityExecutions" VisiblePaneHeight="@_propertiesPaneHeight"/>
<ActivityExecutionsTab @ref="_activityExecutionsTab" Activity="@SelectedActivity" ActivityExecutions="SelectedActivityExecutions" VisiblePaneHeight="@_propertiesPaneHeight"/>
</MudTabPanel>
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public partial class WorkflowInstanceDesigner : IAsyncDisposable
private WorkflowInstance _workflowInstance = default!;
private RadzenSplitterPane _activityPropertiesPane = default!;
private DiagramDesignerWrapper _designer = default!;
private ActivityDetailsTab? _activityDetailsTab = default!;
private ActivityExecutionsTab? _activityExecutionsTab = default!;
private int _propertiesPaneHeight = 300;
private IDictionary<string, ActivityNode> _activityNodeLookup = new Dictionary<string, ActivityNode>();
private readonly IDictionary<string, ICollection<ActivityExecutionRecord>> _activityExecutionRecordsLookup = new Dictionary<string, ICollection<ActivityExecutionRecord>>();
Expand Down Expand Up @@ -65,12 +67,13 @@ public partial class WorkflowInstanceDesigner : IAsyncDisposable
/// The activity selected callback.
/// </summary>
[Parameter]
public Func<JsonObject, Task>? ActivitySelected { get; set; }
public EventCallback<JsonObject> ActivitySelected { get; set; }

/// <summary>
/// An event that is invoked when a workflow definition is edited.
/// </summary>
[Parameter] public EventCallback<string> EditWorkflowDefinition { get; set; }
[Parameter]
public EventCallback<string> EditWorkflowDefinition { get; set; }

/// <summary>
/// Gets or sets the current selected sub-workflow.
Expand Down Expand Up @@ -223,8 +226,9 @@ private async Task HandleActivitySelectedAsync(JsonObject activity)
SelectedActivity = activity;
ActivityDescriptor = ActivityRegistry.Find(activity!.GetTypeName(), activity!.GetVersion());
SelectedActivityExecutions = await GetActivityExecutionRecordsAsync(activityNodeId);

StateHasChanged();
_activityDetailsTab?.Refresh();
_activityExecutionsTab?.Refresh();
}

private async Task<ICollection<ActivityExecutionRecord>> GetActivityExecutionRecordsAsync(string activityNodeId)
Expand Down Expand Up @@ -262,8 +266,10 @@ private async Task OnActivitySelected(JsonObject activity)
SelectedWorkflowExecutionLogRecord = null;
await HandleActivitySelectedAsync(activity);

if (ActivitySelected != null)
await ActivitySelected(activity);
var activitySelected = ActivitySelected;

if (activitySelected.HasDelegate)
await activitySelected.InvokeAsync(activity);
}

private async Task OnResize(RadzenSplitterResizeEventArgs arg)
Expand All @@ -289,7 +295,7 @@ private Task OnEditClicked()
}
}

var editWorkflowDefinition = this.EditWorkflowDefinition;
var editWorkflowDefinition = EditWorkflowDefinition;

if (editWorkflowDefinition.HasDelegate)
return editWorkflowDefinition.InvokeAsync(definitionId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
WorkflowInstance="workflowInstance"
WorkflowDefinition="definition"
PathChanged="OnPathChanged"
ActivitySelected="ActivitySelected"
ActivitySelected="@ActivitySelected"
SelectedWorkflowExecutionLogRecord="SelectedWorkflowExecutionLogRecord"
EditWorkflowDefinition="EditWorkflowDefinition"
/>
Expand Down

0 comments on commit 1c95b3e

Please sign in to comment.