Skip to content

Commit

Permalink
fix(Dashboard): Multiple fixes and improvements
Browse files Browse the repository at this point in the history
Signed-off-by: Charles d'Avernas <[email protected]>
  • Loading branch information
cdavernas committed Dec 11, 2024
1 parent dd5177e commit 9f9c8d4
Show file tree
Hide file tree
Showing 29 changed files with 403 additions and 146 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<NeutralLanguage>en</NeutralLanguage>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<VersionPrefix>1.0.0</VersionPrefix>
<VersionSuffix>alpha5.3</VersionSuffix>
<VersionSuffix>alpha5.7</VersionSuffix>
<AssemblyVersion>$(VersionPrefix)</AssemblyVersion>
<FileVersion>$(VersionPrefix)</FileVersion>
<Authors>The Synapse Authors</Authors>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<NeutralLanguage>en</NeutralLanguage>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<VersionPrefix>1.0.0</VersionPrefix>
<VersionSuffix>alpha5.3</VersionSuffix>
<VersionSuffix>alpha5.7</VersionSuffix>
<AssemblyVersion>$(VersionPrefix)</AssemblyVersion>
<FileVersion>$(VersionPrefix)</FileVersion>
<Authors>The Synapse Authors</Authors>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<NeutralLanguage>en</NeutralLanguage>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<VersionPrefix>1.0.0</VersionPrefix>
<VersionSuffix>alpha5.3</VersionSuffix>
<VersionSuffix>alpha5.7</VersionSuffix>
<AssemblyVersion>$(VersionPrefix)</AssemblyVersion>
<FileVersion>$(VersionPrefix)</FileVersion>
<Authors>The Synapse Authors</Authors>
Expand Down
2 changes: 1 addition & 1 deletion src/api/Synapse.Api.Http/Synapse.Api.Http.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<OutputType>Library</OutputType>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<VersionPrefix>1.0.0</VersionPrefix>
<VersionSuffix>alpha5.3</VersionSuffix>
<VersionSuffix>alpha5.7</VersionSuffix>
<AssemblyVersion>$(VersionPrefix)</AssemblyVersion>
<FileVersion>$(VersionPrefix)</FileVersion>
<Authors>The Synapse Authors</Authors>
Expand Down
2 changes: 1 addition & 1 deletion src/api/Synapse.Api.Server/Synapse.Api.Server.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<NeutralLanguage>en</NeutralLanguage>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<VersionPrefix>1.0.0</VersionPrefix>
<VersionSuffix>alpha5.3</VersionSuffix>
<VersionSuffix>alpha5.7</VersionSuffix>
<AssemblyVersion>$(VersionPrefix)</AssemblyVersion>
<FileVersion>$(VersionPrefix)</FileVersion>
<Authors>The Synapse Authors</Authors>
Expand Down
2 changes: 1 addition & 1 deletion src/cli/Synapse.Cli/Synapse.Cli.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<NeutralLanguage>en</NeutralLanguage>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<VersionPrefix>1.0.0</VersionPrefix>
<VersionSuffix>alpha5.3</VersionSuffix>
<VersionSuffix>alpha5.7</VersionSuffix>
<AssemblyVersion>$(VersionPrefix)</AssemblyVersion>
<FileVersion>$(VersionPrefix)</FileVersion>
<Authors>The Synapse Authors</Authors>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<NeutralLanguage>en</NeutralLanguage>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<VersionPrefix>1.0.0</VersionPrefix>
<VersionSuffix>alpha5.3</VersionSuffix>
<VersionSuffix>alpha5.7</VersionSuffix>
<AssemblyVersion>$(VersionPrefix)</AssemblyVersion>
<FileVersion>$(VersionPrefix)</FileVersion>
<Authors>The Synapse Authors</Authors>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<NeutralLanguage>en</NeutralLanguage>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<VersionPrefix>1.0.0</VersionPrefix>
<VersionSuffix>alpha5.3</VersionSuffix>
<VersionSuffix>alpha5.7</VersionSuffix>
<AssemblyVersion>$(VersionPrefix)</AssemblyVersion>
<FileVersion>$(VersionPrefix)</FileVersion>
<Authors>The Synapse Authors</Authors>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<NeutralLanguage>en</NeutralLanguage>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<VersionPrefix>1.0.0</VersionPrefix>
<VersionSuffix>alpha5.3</VersionSuffix>
<VersionSuffix>alpha5.7</VersionSuffix>
<AssemblyVersion>$(VersionPrefix)</AssemblyVersion>
<FileVersion>$(VersionPrefix)</FileVersion>
<Authors>The Synapse Authors</Authors>
Expand Down
2 changes: 1 addition & 1 deletion src/core/Synapse.Core/Synapse.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<NeutralLanguage>en</NeutralLanguage>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<VersionPrefix>1.0.0</VersionPrefix>
<VersionSuffix>alpha5.3</VersionSuffix>
<VersionSuffix>alpha5.7</VersionSuffix>
<AssemblyVersion>$(VersionPrefix)</AssemblyVersion>
<FileVersion>$(VersionPrefix)</FileVersion>
<Authors>The Synapse Authors</Authors>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<NeutralLanguage>en</NeutralLanguage>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<VersionPrefix>1.0.0</VersionPrefix>
<VersionSuffix>alpha5.3</VersionSuffix>
<VersionSuffix>alpha5.7</VersionSuffix>
<AssemblyVersion>$(VersionPrefix)</AssemblyVersion>
<FileVersion>$(VersionPrefix)</FileVersion>
<Authors>The Synapse Authors</Authors>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
@*
Copyright © 2024-Present The Synapse Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*@

@using Json.Schema
@using Neuroglia.Data.Infrastructure.ResourceOriented.Properties
@using ServerlessWorkflow.Sdk
@using ServerlessWorkflow.Sdk.Models
@using System.Xml.Schema
@using Synapse.Core.Infrastructure.Services
@using System.Text.Json.Nodes
@namespace Synapse.Dashboard.Components
@inject MonacoInterop MonacoInterop
@inject IExternalResourceProvider ExternalResourceProvider
@inject IJsonSerializer JsonSerializer
@inject IXmlSerializer XmlSerializer

<Tabs>
@if(schema != null)
{
<Tab Title="Form" Active="true">
<Content>
<div class="pt-3">
<DynamicForm Schema="schema" OnValueChanged="value => OnValueChanged(value)" />
</div>
</Content>
</Tab>
}
<Tab Title="Text">
<Content>
<div class="pt-3">
<MonacoEditor OnTextChanged="OnTextChanged" ModelName="@modelName" Document="input" />
</div>
</Content>
</Tab>
</Tabs>

<div class="text-center">
<Button Outline="true" Color="ButtonColor.Primary" class="m-auto mt-3 w-100" @onclick="async _ => await OnStartAsync()">
<Icon Name="IconName.Play" />
Start
</Button>
</div>

@code {

WorkflowDefinition? workflowDefinition;
JsonSchema? schema;
string payload = string.Empty;
string modelName = string.Empty;
EquatableDictionary<string, object>? input;

[Parameter] public WorkflowDefinition? WorkflowDefinition { get; set; }
[Parameter] public EquatableDictionary<string, object>? Input { get; set; }
[Parameter] public EventCallback<string> OnCreate { get; set; }
[Parameter] public EventCallback<ProblemDetails> OnProblem { get; set; }

void OnValueChanged(object? value)
{
payload = value == null ? string.Empty : JsonSerializer.SerializeToText(value);
}

void OnTextChanged(string value)
{
payload = value;
}

protected override async Task OnParametersSetAsync()
{
await base.OnParametersSetAsync();
if (input != Input) input = Input;
if (workflowDefinition != WorkflowDefinition)
{
workflowDefinition = WorkflowDefinition;
await LoadSchemaAsync();
}
if (WorkflowDefinition?.Input?.Schema?.Document != null)
{
modelName = WorkflowDefinition.Document.Name + "-" + WorkflowDefinition.Document.Version;
await MonacoInterop.AddValidationSchemaAsync(JsonSerializer.SerializeToText(WorkflowDefinition.Input.Schema.Document), $"https://synapse.io/schemas/{modelName}.json", $"{modelName}*").ConfigureAwait(false);
}
}

async Task OnStartAsync()
{
if (schema != null)
{
var node = string.IsNullOrWhiteSpace(payload) ? null : JsonSerializer.Deserialize<JsonNode>(payload);
var evaluationOptions = new EvaluationOptions()
{
OutputFormat = OutputFormat.List
};
var evaluationResult = schema.Evaluate(node, evaluationOptions);
if (!evaluationResult.IsValid)
{
var errors = evaluationResult.Details.Where(d => d.Errors != null).SelectMany(d => d.Errors!).GroupBy(e => e.Key).Select(e => new KeyValuePair<string, string[]>(e.Key, e.Select(e => e.Value).ToArray())).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
var problemDetails = new ProblemDetails(ErrorTypes.Invalid, ProblemTitles.ValidationFailed, ErrorStatus.Validation, "Workflow instance input validation failed", errors: errors);
if (OnProblem.HasDelegate) await OnProblem.InvokeAsync(problemDetails);
return;
}
}
if (OnCreate.HasDelegate) await OnCreate.InvokeAsync(payload);
}

async Task LoadSchemaAsync()
{
var schemaDefinition = WorkflowDefinition?.Input?.Schema;
if (schemaDefinition == null) return;
if (schemaDefinition.Resource == null)
{
switch (schemaDefinition.Format)
{
case SchemaFormat.Avro:
schema = Avro.Schema.Parse(JsonSerializer.SerializeToText(schemaDefinition.Document)).ToJsonSchema();
break;
case SchemaFormat.Json:
schema = JsonSchema.FromText(JsonSerializer.SerializeToText(schemaDefinition.Document));
break;
case SchemaFormat.Xml:
var xml = XmlSerializer.SerializeToText(schemaDefinition.Document);
var stringReader = new StringReader(xml);
schema = XmlSchema.Read(stringReader, null)!.ToJsonSchema();
break;
default:
throw new NotSupportedException($"The specified schema format '{schemaDefinition.Format}' is not supported");
}
}
else
{
using var stream = await ExternalResourceProvider.ReadAsync(schemaDefinition.Resource).ConfigureAwait(false);
using var streamReader = new StreamReader(stream);
schema = schemaDefinition.Format switch
{
SchemaFormat.Avro => Avro.Schema.Parse(await streamReader.ReadToEndAsync()).ToJsonSchema(),
SchemaFormat.Json => await JsonSchema.FromStream(stream).ConfigureAwait(false),
SchemaFormat.Xml => XmlSchema.Read(stream, null)!.ToJsonSchema(),
_ => throw new NotSupportedException($"The specified schema format '{schemaDefinition.Format}' is not supported"),
};
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,13 @@
case SchemaValueType.Null:
break;
case SchemaValueType.Array:

var itemsSchema = schema.GetItems();
if (itemsSchema != null)
{
<div class="border border-muted rounded p-3">
<DynamicFormArray Schema="Schema" OnValueChanged="async value => await OnValueChangedAsync(value)" />
</div>
}
break;
case SchemaValueType.Object:
var properties = schema.GetProperties() ?? new Dictionary<string, JsonSchema>();
Expand Down Expand Up @@ -65,7 +71,7 @@
/// <summary>
/// Gets/sets the handler to call whenever the form's value changes
/// </summary>
[Parameter] public EventCallback<object?> OnValueChanged{ get; set; }
[Parameter] public EventCallback<object?> OnValueChanged { get; set; }

/// <inheritdoc/>
protected override async Task OnInitializedAsync()
Expand All @@ -84,6 +90,12 @@
if (this.Schema != null && this.Schema != this.schema) this.Store.SetSchema(this.Schema);
}

async Task OnValueChangedAsync(object? value)
{
this.Store.SetValue(value);
await this.OnValueChanged.InvokeAsync(currentValue);
}

async Task OnValueChangedAsync(string name, object? value)
{
this.Store.SetPropertyValue(name, value);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
@using Json.Schema
@namespace Synapse.Dashboard

@if(schema != null)
{
if (itemsSchema != null)
{
@foreach (var form in forms.OrderBy(kvp => kvp.Key))
{
<div @key="@form.Key">
@form.Value
<Button Outline="true" Color="ButtonColor.Danger" Class="w-100" @onclick="@(() => OnRemoveItemAsync(form.Key))">
<Icon Name="IconName.Dash" />
Remove
</Button>
<hr />
</div>
}
<Button Outline="true" Color="ButtonColor.Success" Class="w-100" @onclick="OnAddItemAsync">
<Icon Name="IconName.Plus" />
Add
</Button>
}
}

@code {

JsonSchema? schema;
JsonSchema? itemsSchema;
Dictionary<int, RenderFragment> forms = [];
Dictionary<int, object> items = [];

/// <summary>
/// Gets/sets the form field's schema
/// </summary>
[Parameter] public JsonSchema Schema { get; set; } = null!;

/// <summary>
/// Gets/sets the handler to call whenever the field's value changes
/// </summary>
[Parameter] public EventCallback<object?> OnValueChanged { get; set; }

/// <inheritdoc/>
protected override void OnParametersSet()
{
base.OnParametersSet();
if (schema != Schema)
{
schema = Schema;
itemsSchema = schema.GetItems();
}
}

async Task OnAddItemAsync()
{
var key = forms.Count < 1 ? 0 : forms.Max(kvp => kvp.Key) + 1;
forms[key] = CreateDynamicForm(key);
items[key] = new { };
await OnValueChanged.InvokeAsync(items.Values);
}

async Task OnItemChangedAsync(int key, object value)
{
items[key] = value;
await this.OnValueChanged.InvokeAsync(items.Values);
}

async Task OnRemoveItemAsync(int key)
{
var form = forms[key];
forms.Remove(key);
items.Remove(key);
await this.OnValueChanged.InvokeAsync(items.Values);
}

RenderFragment CreateDynamicForm(int key) => builder =>
{
builder.OpenComponent<DynamicForm>(0);
builder.AddAttribute(1, "Schema", itemsSchema);
builder.AddAttribute(2, "OnValueChanged", EventCallback.Factory.Create<object>(this, value => OnItemChangedAsync(key, value)));
builder.CloseComponent();
};

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
@switch (schema.GetJsonType())
{
case SchemaValueType.Array:

<div class="border border-muted rounded p-3">
<DynamicFormArray Schema="Schema" OnValueChanged="async e => await OnValueChanged.InvokeAsync(e)" />
</div>
break;
case SchemaValueType.Object:
<div class="border border-muted rounded p-3">
Expand Down
Loading

0 comments on commit 9f9c8d4

Please sign in to comment.