Skip to content

Commit 0584a8a

Browse files
committed
fix(Dashboard): Workflow create vs update
- An `IsNew` variable was added to the state, which tracks whether the workflow is new or existing. This change prevents unnecessary API calls, reducing 404 errors and improving efficiency. Signed-off-by: Jean-Baptiste Bianchi <[email protected]>
1 parent f532e8a commit 0584a8a

File tree

3 files changed

+62
-44
lines changed

3 files changed

+62
-44
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ public record CreateWorkflowViewState
3636
/// </summary>
3737
public string? DslVersion { get; set; }
3838

39+
/// <summary>
40+
/// Gets/sets a boolean determining if the workflow is new or if it's an update
41+
/// </summary>
42+
public bool IsNew { get; set; } = true;
43+
3944
/// <summary>
4045
/// Gets/sets the definition of the workflow to create
4146
/// </summary>

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

Lines changed: 51 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@
1212
// limitations under the License.
1313

1414
using JsonCons.Utilities;
15-
using Neuroglia.Collections;
1615
using Neuroglia.Data;
1716
using Semver;
1817
using ServerlessWorkflow.Sdk.Models;
1918
using ServerlessWorkflow.Sdk.Validation;
2019
using Synapse.Api.Client.Services;
2120
using Synapse.Resources;
2221
using System.Text.RegularExpressions;
22+
using System.Xml.Linq;
2323

2424
namespace Synapse.Dashboard.Pages.Workflows.Create;
2525

@@ -102,7 +102,7 @@ IWorkflowDefinitionValidator workflowDefinitionValidator
102102
protected MonacoInterop MonacoInterop { get; } = monacoInterop;
103103

104104
/// <summary>
105-
/// Gets the service to to validate workflow defintions
105+
/// Gets the service to to validate workflow definitions
106106
/// </summary>
107107
protected IWorkflowDefinitionValidator WorkflowDefinitionValidator { get; } = workflowDefinitionValidator;
108108

@@ -218,6 +218,18 @@ public void SetName(string? name)
218218
});
219219
}
220220

221+
/// <summary>
222+
/// Sets the state's <see cref="CreateWorkflowViewState.IsNew"/>
223+
/// </summary>
224+
/// <param name="isNew">The new <see cref="CreateWorkflowViewState.IsNew"/> value</param>
225+
public void SetIsNew(bool isNew)
226+
{
227+
this.Reduce(state => state with
228+
{
229+
IsNew = isNew
230+
});
231+
}
232+
221233
/// <summary>
222234
/// Sets the state's <see cref="CreateWorkflowViewState" /> <see cref="ProblemDetails"/>'s related data
223235
/// </summary>
@@ -415,57 +427,56 @@ public async Task SaveWorkflowDefinitionAsync()
415427
var @namespace = workflowDefinition!.Document.Namespace;
416428
var name = workflowDefinition.Document.Name;
417429
var version = workflowDefinition.Document.Version;
430+
var isNew = this.Get(state => state.IsNew);
418431
this.Reduce(s => s with
419432
{
420433
Saving = true
421434
});
422435
Workflow? workflow = null;
423-
try
424-
{
425-
workflow = await this.Api.Workflows.GetAsync(name, @namespace);
426-
}
427-
catch
436+
if (isNew)
428437
{
429-
// Assume 404, might need actual handling
430-
}
431-
if (workflow == null)
432-
{
433-
workflow = await this.Api.Workflows.CreateAsync(new()
434-
{
435-
Metadata = new()
436-
{
437-
Namespace = workflowDefinition!.Document.Namespace,
438-
Name = workflowDefinition.Document.Name
439-
},
440-
Spec = new()
438+
try {
439+
workflow = await this.Api.Workflows.CreateAsync(new()
441440
{
442-
Versions = [workflowDefinition]
443-
}
444-
});
445-
}
446-
else
447-
{
448-
var updatedResource = workflow.Clone()!;
449-
var documentVersion = SemVersion.Parse(version, SemVersionStyles.Strict)!;
450-
var latestVersion = SemVersion.Parse(updatedResource.Spec.Versions.GetLatest().Document.Version, SemVersionStyles.Strict)!;
451-
if (updatedResource.Spec.Versions.Any(v => SemVersion.Parse(v.Document.Version, SemVersionStyles.Strict).CompareSortOrderTo(documentVersion) >= 0))
452-
{
453-
this.Reduce(state => state with
454-
{
455-
ProblemTitle = "Invalid version",
456-
ProblemDetail = $"The specified version '{documentVersion}' must be strictly superior to the latest version '{latestVersion}'."
441+
Metadata = new()
442+
{
443+
Namespace = workflowDefinition!.Document.Namespace,
444+
Name = workflowDefinition.Document.Name
445+
},
446+
Spec = new()
447+
{
448+
Versions = [workflowDefinition]
449+
}
457450
});
451+
this.NavigationManager.NavigateTo($"/workflows/details/{@namespace}/{name}/{version}");
458452
return;
459453
}
460-
updatedResource.Spec.Versions.Add(workflowDefinition!);
461-
var jsonPatch = JsonPatch.FromDiff(this.JsonSerializer.SerializeToElement(workflow)!.Value, this.JsonSerializer.SerializeToElement(updatedResource)!.Value);
462-
var patch = this.JsonSerializer.Deserialize<Json.Patch.JsonPatch>(jsonPatch.RootElement);
463-
if (patch != null)
454+
catch (ProblemDetailsException ex) when (ex.Problem.Title == "Conflict" && ex.Problem.Detail != null && ex.Problem.Detail.EndsWith("already exists"))
464455
{
465-
var resourcePatch = new Patch(PatchType.JsonPatch, jsonPatch);
466-
await this.Api.ManageNamespaced<Workflow>().PatchAsync(name, @namespace, resourcePatch, null, this.CancellationTokenSource.Token);
456+
// the workflow exists, try to update it instead
467457
}
468458
}
459+
workflow = await this.Api.Workflows.GetAsync(name, @namespace);
460+
var updatedResource = workflow.Clone()!;
461+
var documentVersion = SemVersion.Parse(version, SemVersionStyles.Strict)!;
462+
var latestVersion = SemVersion.Parse(updatedResource.Spec.Versions.GetLatest().Document.Version, SemVersionStyles.Strict)!;
463+
if (updatedResource.Spec.Versions.Any(v => SemVersion.Parse(v.Document.Version, SemVersionStyles.Strict).CompareSortOrderTo(documentVersion) >= 0))
464+
{
465+
this.Reduce(state => state with
466+
{
467+
ProblemTitle = "Invalid version",
468+
ProblemDetail = $"The specified version '{documentVersion}' must be strictly superior to the latest version '{latestVersion}'."
469+
});
470+
return;
471+
}
472+
updatedResource.Spec.Versions.Add(workflowDefinition!);
473+
var jsonPatch = JsonPatch.FromDiff(this.JsonSerializer.SerializeToElement(workflow)!.Value, this.JsonSerializer.SerializeToElement(updatedResource)!.Value);
474+
var patch = this.JsonSerializer.Deserialize<Json.Patch.JsonPatch>(jsonPatch.RootElement);
475+
if (patch != null)
476+
{
477+
var resourcePatch = new Patch(PatchType.JsonPatch, jsonPatch);
478+
await this.Api.ManageNamespaced<Workflow>().PatchAsync(name, @namespace, resourcePatch, null, this.CancellationTokenSource.Token);
479+
}
469480
this.NavigationManager.NavigateTo($"/workflows/details/{@namespace}/{name}/{version}");
470481
}
471482
catch (ProblemDetailsException ex)

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ else
3737
<PreferredLanguageSelector PreferredLanguageChange="Store.ToggleTextBasedEditorLanguageAsync" />
3838
</div>
3939
<StandaloneCodeEditor @ref="Store.TextEditor"
40-
ConstructionOptions="Store.StandaloneEditorConstructionOptions"
41-
OnDidInit="Store.OnTextBasedEditorInitAsync"
42-
OnDidChangeModelContent="Store.OnDidChangeModelContent"
43-
CssClass="h-100" />
40+
ConstructionOptions="Store.StandaloneEditorConstructionOptions"
41+
OnDidInit="Store.OnTextBasedEditorInitAsync"
42+
OnDidChangeModelContent="Store.OnDidChangeModelContent"
43+
CssClass="h-100" />
4444
@if (problemDetails != null)
4545
{
4646
<div class="problems px-3">
@@ -93,6 +93,7 @@ else
9393
await base.OnInitializedAsync();
9494
BreadcrumbManager.Use(Breadcrumbs.Workflows);
9595
BreadcrumbManager.Add(new($"New", $"/workflows/new"));
96+
Store.SetIsNew(true);
9697
Store.Namespace.Subscribe(value => OnStateChanged(_ => ns = value), token: CancellationTokenSource.Token);
9798
Store.Name.Subscribe(value => OnStateChanged(_ => name = value), token: CancellationTokenSource.Token);
9899
Store.Loading.Subscribe(value => OnStateChanged(_ => loading = value), token: CancellationTokenSource.Token);
@@ -110,6 +111,7 @@ else
110111
if (Name != name)
111112
{
112113
Store.SetName(Name);
114+
Store.SetIsNew(false);
113115
}
114116
}
115117

0 commit comments

Comments
 (0)