Skip to content

Commit 03eae9d

Browse files
authored
Merge pull request #439 from serverlessworkflow/feat-dashboard-restart-workflow
Added capability to replay a workflow with the same input in the Dashboard
2 parents c6b75bb + e8ca80c commit 03eae9d

File tree

9 files changed

+43
-14
lines changed

9 files changed

+43
-14
lines changed

src/dashboard/Synapse.Dashboard/Components/DocumentDetails/Store.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ public async Task OnCopyToClipboard()
372372
try
373373
{
374374
await this.JSRuntime.InvokeVoidAsync("navigator.clipboard.writeText", text);
375-
this.ToastService.Notify(new(ToastType.Success, "Definition copied to the clipboard!"));
375+
this.ToastService.Notify(new(ToastType.Success, "Copied to the clipboard!"));
376376
}
377377
catch (Exception ex)
378378
{

src/dashboard/Synapse.Dashboard/Components/MonacoEditor/Store.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ public async Task OnCopyToClipboard()
290290
try
291291
{
292292
await this.JSRuntime.InvokeVoidAsync("navigator.clipboard.writeText", text);
293-
this.ToastService.Notify(new(ToastType.Success, "Definition copied to the clipboard!"));
293+
this.ToastService.Notify(new(ToastType.Success, "Copied to the clipboard!"));
294294
}
295295
catch (Exception ex)
296296
{

src/dashboard/Synapse.Dashboard/Components/ResourceEditor/ResourceEditor.razor

+1-1
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@
256256
try
257257
{
258258
await this.JSRuntime.InvokeVoidAsync("navigator.clipboard.writeText", text);
259-
this.ToastService.Notify(new(ToastType.Success, "Definition copied to the clipboard!"));
259+
this.ToastService.Notify(new(ToastType.Success, "Copied to the clipboard!"));
260260
}
261261
catch (Exception ex)
262262
{

src/dashboard/Synapse.Dashboard/Components/WorkflowInstanceCreation/WorkflowInstanceCreation.razor

+11-6
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
@inject MonacoInterop MonacoInterop
2020
@inject IJsonSerializer Serializer
2121

22-
<MonacoEditor OnTextChanged="OnTextChanged" ModelName="@modelName" />
22+
<MonacoEditor OnTextChanged="OnTextChanged" ModelName="@modelName" Document="input" />
2323
<div class="text-center">
2424
<Button Outline="true" Color="ButtonColor.Primary" class="m-auto mt-3" @onclick="async (_) => await OnStart()">
2525
<Icon Name="IconName.Play" />
@@ -30,8 +30,10 @@
3030
@code {
3131
string payload = string.Empty;
3232
string modelName = string.Empty;
33+
EquatableDictionary<string, object>? input;
3334

3435
[Parameter] public WorkflowDefinition? WorkflowDefinition { get; set; }
36+
[Parameter] public EquatableDictionary<string, object>? Input { get; set; }
3537
[Parameter] public EventCallback<string> OnCreate { get; set; }
3638

3739
void OnTextChanged(string value)
@@ -50,12 +52,15 @@
5052
protected override async Task OnParametersSetAsync()
5153
{
5254
await base.OnParametersSetAsync();
53-
if (this.WorkflowDefinition?.Input?.Schema?.Document != null)
55+
if (Input != input)
5456
{
55-
modelName = this.WorkflowDefinition.Document.Name + "-" + this.WorkflowDefinition.Document.Version;
56-
await this.MonacoInterop.AddValidationSchemaAsync(this.Serializer.SerializeToText(this.WorkflowDefinition.Input.Schema.Document), $"https://synapse.io/schemas/{modelName}.json", $"{modelName}*").ConfigureAwait(false);
57-
}
58-
57+
input = Input;
58+
}
59+
if (WorkflowDefinition?.Input?.Schema?.Document != null)
60+
{
61+
modelName = WorkflowDefinition.Document.Name + "-" + WorkflowDefinition.Document.Version;
62+
await MonacoInterop.AddValidationSchemaAsync(Serializer.SerializeToText(WorkflowDefinition.Input.Schema.Document), $"https://synapse.io/schemas/{modelName}.json", $"{modelName}*").ConfigureAwait(false);
63+
}
5964
}
6065

6166
}

src/dashboard/Synapse.Dashboard/Components/WorkflowInstancesList/WorkflowInstancesList.razor

+19-1
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@
149149
</ul>
150150
</div>
151151
break;
152+
case "Replay":
153+
<button class="btn btn-sm text-primary" @onclick="async _ => await OnReplayClickedAsync(instance)" @onclick:stopPropagation="true"><Icon Name="IconName.ArrowClockwise" /></button>
154+
break;
152155
case "Delete":
153156
<button class="btn btn-sm text-danger" @onclick="async _ => await OnDeleteClickedAsync(instance)" @onclick:stopPropagation="true"><Icon Name="IconName.Trash" /></button>
154157
break;
@@ -204,6 +207,7 @@
204207
[Parameter] public EventCallback<WorkflowInstance> OnShowDetails { get; set; }
205208
[Parameter] public EventCallback<string?> OnToggleSelected { get; set; }
206209
[Parameter] public EventCallback<WorkflowInstance> OnDelete { get; set; }
210+
[Parameter] public EventCallback<WorkflowInstance> OnReplay { get; set; }
207211
[Parameter] public EventCallback OnDeleteSelected { get; set; }
208212

209213
IEnumerable<string> knownColumns = [
@@ -217,6 +221,7 @@
217221
"Duration",
218222
"Operator",
219223
"Actions",
224+
"Replay",
220225
"Delete"
221226
];
222227

@@ -391,7 +396,7 @@
391396
}
392397

393398
/// <summary>
394-
/// Handles the clikc on the delete button
399+
/// Handles the click on the delete button
395400
/// </summary>
396401
/// <param name="instance"></param>
397402
/// <returns></returns>
@@ -402,4 +407,17 @@
402407
await this.OnDelete.InvokeAsync(instance);
403408
}
404409
}
410+
411+
/// <summary>
412+
/// Handles the click on the replay button
413+
/// </summary>
414+
/// <param name="instance"></param>
415+
/// <returns></returns>
416+
protected async Task OnReplayClickedAsync(WorkflowInstance instance)
417+
{
418+
if (this.OnReplay.HasDelegate)
419+
{
420+
await this.OnReplay.InvokeAsync(instance);
421+
}
422+
}
405423
}

src/dashboard/Synapse.Dashboard/Pages/Functions/Create/Store.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -334,9 +334,10 @@ async Task SetTextEditorValueAsync()
334334
{
335335
return;
336336
}
337-
await this.TextEditor.SetValue(document);
338337
try
339338
{
339+
await this.TextEditor.SetValue(document);
340+
await Task.Delay(10);
340341
await this.TextEditor.Trigger("", "editor.action.formatDocument");
341342
}
342343
catch (Exception ex)

src/dashboard/Synapse.Dashboard/Pages/Workflows/Create/Store.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -338,9 +338,10 @@ async Task SetTextEditorValueAsync()
338338
{
339339
return;
340340
}
341-
await this.TextEditor.SetValue(document);
342341
try
343342
{
343+
await this.TextEditor.SetValue(document);
344+
await Task.Delay(10);
344345
await this.TextEditor.Trigger("", "editor.action.formatDocument");
345346
}
346347
catch (Exception ex)
@@ -357,6 +358,7 @@ async Task SetTextEditorValueAsync()
357358
public async Task OnDidChangeModelContent(ModelContentChangedEvent e)
358359
{
359360
if (this.TextEditor == null) return;
361+
360362
var document = await this.TextEditor.GetValue();
361363
this.Reduce(state => state with
362364
{

src/dashboard/Synapse.Dashboard/Pages/Workflows/Details/Store.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ public async Task OnCopyToClipboard()
309309
try
310310
{
311311
await this.JSRuntime.InvokeVoidAsync("navigator.clipboard.writeText", text);
312-
this.ToastService.Notify(new(ToastType.Success, "Definition copied to the clipboard!"));
312+
this.ToastService.Notify(new(ToastType.Success, "Copied to the clipboard!"));
313313
}
314314
catch (Exception ex)
315315
{
@@ -322,13 +322,14 @@ public async Task OnCopyToClipboard()
322322
/// Displays the modal used to provide the new workflow input
323323
/// </summary>
324324
/// <returns>A awaitable task</returns>
325-
public async Task OnShowCreateInstanceAsync(WorkflowDefinition workflowDefinition)
325+
public async Task OnShowCreateInstanceAsync(WorkflowDefinition workflowDefinition, EquatableDictionary<string, object>? input = null)
326326
{
327327
if (this.Modal != null)
328328
{
329329
var parameters = new Dictionary<string, object>
330330
{
331331
{ nameof(WorkflowInstanceCreation.WorkflowDefinition), workflowDefinition },
332+
{ nameof(WorkflowInstanceCreation.Input), input! },
332333
{ nameof(WorkflowInstanceCreation.OnCreate), EventCallback.Factory.Create<string>(this, CreateInstanceAsync) }
333334
};
334335
await this.Modal.ShowAsync<WorkflowInstanceCreation>(title: "Start a new worklfow", parameters: parameters);

src/dashboard/Synapse.Dashboard/Pages/Workflows/Details/View.razor

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
OnSearchInput="Store.SetSearchTerm"
3838
OnShowDetails="OnShowInstanceDetails"
3939
OnDelete="OnDeleteWorkflowInstanceAsync"
40+
OnReplay="async instance => await Store.OnShowCreateInstanceAsync(workflowDefinition, instance.Spec?.Input)"
4041
OnToggleSelected="Store.ToggleResourceSelection"
4142
OnDeleteSelected="OnDeleteSelectedResourcesAsync" />
4243
<Button Outline="true" Color="ButtonColor.Primary" @onclick="async _ => await Store.OnShowCreateInstanceAsync(workflowDefinition)" class="w-100 mt-3">
@@ -126,6 +127,7 @@
126127
"Status",
127128
"Start Time",
128129
"End Time",
130+
"Replay",
129131
"Delete"
130132
];
131133

0 commit comments

Comments
 (0)