Dashboard hosting model improvements
This commit is contained in:
parent
832afc1110
commit
c62cac9ecb
|
|
@ -1,4 +1,5 @@
|
|||
using System.Runtime.Serialization;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Elsa.Client.Models
|
||||
{
|
||||
|
|
@ -9,6 +10,6 @@ namespace Elsa.Client.Models
|
|||
[DataMember(Order = 2)] public string UIHint { get; set; } = default!;
|
||||
[DataMember(Order = 3)] public string? Label { get; set; }
|
||||
[DataMember(Order = 4)] public string? Hint { get; set; }
|
||||
[DataMember(Order = 5)] public object? Options { get; set; }
|
||||
[DataMember(Order = 5)] public JToken? Options { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ namespace ElsaDashboard.Shared.Surrogates
|
|||
Type = value.UIHint;
|
||||
Label = value.Label;
|
||||
Hint = value.Hint;
|
||||
Options = value.Options != null ? JsonConvert.SerializeObject(value.Options, SerializerSettings) : default;
|
||||
Options = value.Options?.ToString(Formatting.None);
|
||||
}
|
||||
|
||||
[ProtoMember(1)] public string? Name { get; }
|
||||
|
|
@ -44,7 +44,7 @@ namespace ElsaDashboard.Shared.Surrogates
|
|||
UIHint = surrogate.Type!,
|
||||
Hint = surrogate.Hint,
|
||||
Label = surrogate.Label,
|
||||
Options = !string.IsNullOrEmpty(surrogate.Options) ? JsonConvert.DeserializeObject<JObject>(surrogate.Options) : new JObject()
|
||||
Options = surrogate.Options is null or "" ? default : JToken.Parse(surrogate.Options)
|
||||
}
|
||||
: default;
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ namespace ElsaDashboard.Shared.Surrogates
|
|||
};
|
||||
|
||||
/// <summary>
|
||||
/// Register all NodaTime surrogate types with the protobuf runtime model.
|
||||
/// Register all surrogate types with the protobuf runtime model.
|
||||
/// </summary>
|
||||
public static RuntimeTypeModel AddElsaGrpcSurrogates(this RuntimeTypeModel runtimeTypeModel)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="..\..\..\..\common.props" />
|
||||
<Import Project="..\..\..\..\configureawait.props" />
|
||||
|
|
@ -15,8 +15,6 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Grpc.Net.Client.Web" Version="2.36.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components" Version="5.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="5.0.2" PrivateAssets="all" />
|
||||
<PackageReference Include="protobuf-net.NodaTime" Version="3.0.73" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
using System;
|
||||
using System.Net.Http;
|
||||
using ElsaDashboard.WebAssembly.Options;
|
||||
using Grpc.Core;
|
||||
using Grpc.Net.Client;
|
||||
using Grpc.Net.Client.Web;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using ProtoBuf.Grpc.Client;
|
||||
|
||||
namespace ElsaDashboard.WebAssembly.Extensions
|
||||
|
|
@ -17,8 +19,10 @@ namespace ElsaDashboard.WebAssembly.Extensions
|
|||
private static GrpcChannel CreateGrpcChannel(IServiceProvider sp)
|
||||
{
|
||||
var navigationManager = sp.GetRequiredService<NavigationManager>();
|
||||
var backendUrl = navigationManager.BaseUri;
|
||||
var options = sp.GetRequiredService<IOptions<ElsaDashboardWebAssemblyOptions>>();
|
||||
var backendUrl = options.Value.BackendUrl?.ToString() ?? navigationManager.BaseUri;
|
||||
var httpClient = new HttpClient(new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));
|
||||
|
||||
//var tokenManager = sp.GetRequiredService<ITokenManager>();
|
||||
|
||||
var credentials = CallCredentials.FromInterceptor(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
using ElsaDashboard.Shared.Rpc;
|
||||
using System;
|
||||
using ElsaDashboard.Shared.Rpc;
|
||||
using ElsaDashboard.Shared.Surrogates;
|
||||
using ElsaDashboard.WebAssembly.Options;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ProtoBuf.Meta;
|
||||
|
||||
|
|
@ -7,8 +9,13 @@ namespace ElsaDashboard.WebAssembly.Extensions
|
|||
{
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddElsaDashboardBackend(this IServiceCollection services)
|
||||
public static IServiceCollection AddElsaDashboardBackend(this IServiceCollection services, Action<ElsaDashboardWebAssemblyOptions>? configure = default)
|
||||
{
|
||||
if (configure != null)
|
||||
services.Configure(configure);
|
||||
else
|
||||
services.AddOptions<ElsaDashboardWebAssemblyOptions>();
|
||||
|
||||
RuntimeTypeModel.Default.AddElsaGrpcSurrogates();
|
||||
RuntimeTypeModel.Default.AddNodaTime();
|
||||
return services
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
|
||||
namespace ElsaDashboard.WebAssembly.Options
|
||||
{
|
||||
public class ElsaDashboardWebAssemblyOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// The URL of the dashboard's backend.
|
||||
/// When the web assembly project is hosted from an ASP.NET Core host, that host will be used by default.
|
||||
/// When the web assembly project on the other hand is hosted directly from e.g. blob storage, the URL to the gRPC backend needs to be specified explicitly.
|
||||
/// </summary>
|
||||
public Uri? BackendUrl { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,6 @@
|
|||
public enum BlazorRuntimeModel
|
||||
{
|
||||
Server,
|
||||
Browser
|
||||
WebAssembly
|
||||
}
|
||||
}
|
||||
|
|
@ -19,9 +19,9 @@
|
|||
<ProjectReference Include="..\..\..\core\Elsa\Elsa.csproj" />
|
||||
<ProjectReference Include="..\..\..\dashboards\blazor\ElsaDashboard.Application\ElsaDashboard.Application.csproj" />
|
||||
<ProjectReference Include="..\..\..\dashboards\blazor\ElsaDashboard.Backend\ElsaDashboard.Backend.csproj" />
|
||||
<ProjectReference Include="..\..\..\dashboards\blazor\ElsaDashboard.WebAssembly\ElsaDashboard.WebAssembly.csproj" />
|
||||
<ProjectReference Include="..\..\..\persistence\Elsa.Persistence.EntityFramework\Elsa.Persistence.EntityFramework.Sqlite\Elsa.Persistence.EntityFramework.Sqlite.csproj" />
|
||||
<ProjectReference Include="..\..\..\server\Elsa.Server.Api\Elsa.Server.Api.csproj" />
|
||||
<ProjectReference Include="..\ElsaDashboard.Samples.WebAssembly\ElsaDashboard.Samples.WebAssembly.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -24,23 +24,17 @@
|
|||
|
||||
<!-- Until I figure out why the ESM loader doesn't work properly, we need to include these scripts manually. -->
|
||||
<script src="https://unpkg.com/monaco-editor@latest/min/vs/loader.js"></script>
|
||||
|
||||
<script>
|
||||
require.config({paths: {'vs': 'https://unpkg.com/monaco-editor@latest/min/vs'}});
|
||||
window.MonacoEnvironment = {getWorkerUrl: () => proxy};
|
||||
|
||||
let proxy = URL.createObjectURL(new Blob([`
|
||||
self.MonacoEnvironment = {
|
||||
baseUrl: 'https://unpkg.com/monaco-editor@latest/min/'
|
||||
};
|
||||
importScripts('https://unpkg.com/monaco-editor@latest/min/vs/base/worker/workerMain.js');
|
||||
`], {type: 'text/javascript'}));
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body class="antialiased font-sans bg-gray-200">
|
||||
|
||||
<component type="typeof(App)" render-mode="@Program.RenderMode"/>
|
||||
@if (Program.RuntimeModel == BlazorRuntimeModel.Server)
|
||||
{
|
||||
<component type="typeof(App)" render-mode="@Program.RenderMode"/>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div id="app">Loading...</div>
|
||||
}
|
||||
|
||||
<div id="blazor-error-ui">
|
||||
<environment include="Staging,Production">
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:54938/",
|
||||
"sslPort": 44399
|
||||
"applicationUrl": "https://localhost:11000/",
|
||||
"sslPort": 11000
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "https://localhost:5001;http://localhost:5000"
|
||||
"applicationUrl": "https://localhost:11000"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -71,7 +71,7 @@ namespace ElsaDashboard.Samples.Monolith
|
|||
app.UseSwagger();
|
||||
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Elsa"));
|
||||
|
||||
if (Program.RuntimeModel == BlazorRuntimeModel.Browser)
|
||||
if (Program.RuntimeModel == BlazorRuntimeModel.WebAssembly)
|
||||
app.UseWebAssemblyDebugging();
|
||||
}
|
||||
else
|
||||
|
|
@ -80,7 +80,7 @@ namespace ElsaDashboard.Samples.Monolith
|
|||
app.UseHsts();
|
||||
}
|
||||
|
||||
if (Program.RuntimeModel == BlazorRuntimeModel.Browser)
|
||||
if (Program.RuntimeModel == BlazorRuntimeModel.WebAssembly)
|
||||
app.UseBlazorFrameworkFiles();
|
||||
|
||||
app.UseStaticFiles();
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
"AllowedHosts": "*",
|
||||
"Elsa": {
|
||||
"Http": {
|
||||
"BaseUrl": "https://localhost:3956"
|
||||
"BaseUrl": "https://localhost:11000"
|
||||
},
|
||||
"Smtp": {
|
||||
"Host": "localhost",
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
}
|
||||
},
|
||||
"Dashboard": {
|
||||
"ElsaServerUrl": "https://localhost:3956"
|
||||
"ElsaServerUrl": "https://localhost:11000"
|
||||
},
|
||||
"Telnyx": {
|
||||
"ApiUrl": " https://api.telnyx.com",
|
||||
|
|
|
|||
|
|
@ -3,6 +3,6 @@
|
|||
public enum BlazorRuntimeModel
|
||||
{
|
||||
Server,
|
||||
Browser
|
||||
WebAssembly
|
||||
}
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
<ProjectReference Include="..\..\..\activities\Elsa.Activities.Http\Elsa.Activities.Http.csproj" />
|
||||
<ProjectReference Include="..\..\..\dashboards\blazor\ElsaDashboard.Application\ElsaDashboard.Application.csproj" />
|
||||
<ProjectReference Include="..\..\..\dashboards\blazor\ElsaDashboard.Backend\ElsaDashboard.Backend.csproj" />
|
||||
<ProjectReference Include="..\..\..\dashboards\blazor\ElsaDashboard.WebAssembly\ElsaDashboard.WebAssembly.csproj" />
|
||||
<ProjectReference Include="..\ElsaDashboard.Samples.WebAssembly\ElsaDashboard.Samples.WebAssembly.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -25,22 +25,17 @@
|
|||
<!-- Until I figure out why the ESM loader doesn't work properly, we need to include these scripts manually. -->
|
||||
<script src="https://unpkg.com/monaco-editor@latest/min/vs/loader.js"></script>
|
||||
|
||||
<script>
|
||||
require.config({paths: {'vs': 'https://unpkg.com/monaco-editor@latest/min/vs'}});
|
||||
window.MonacoEnvironment = {getWorkerUrl: () => proxy};
|
||||
|
||||
let proxy = URL.createObjectURL(new Blob([`
|
||||
self.MonacoEnvironment = {
|
||||
baseUrl: 'https://unpkg.com/monaco-editor@latest/min/'
|
||||
};
|
||||
importScripts('https://unpkg.com/monaco-editor@latest/min/vs/base/worker/workerMain.js');
|
||||
`], {type: 'text/javascript'}));
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body class="antialiased font-sans bg-gray-200">
|
||||
|
||||
<component type="typeof(App)" render-mode="@Program.RenderMode"/>
|
||||
@if (Program.RuntimeModel == BlazorRuntimeModel.Server)
|
||||
{
|
||||
<component type="typeof(App)" render-mode="@Program.RenderMode"/>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div id="app">Loading...</div>
|
||||
}
|
||||
|
||||
<div id="blazor-error-ui">
|
||||
<environment include="Staging,Production">
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ namespace ElsaDashboard.Samples.Server
|
|||
{
|
||||
public class Program
|
||||
{
|
||||
public static BlazorRuntimeModel RuntimeModel => BlazorRuntimeModel.Browser;
|
||||
public static BlazorRuntimeModel RuntimeModel => BlazorRuntimeModel.WebAssembly;
|
||||
public static RenderMode RenderMode => RuntimeModel == BlazorRuntimeModel.Server ? RenderMode.ServerPrerendered : RenderMode.WebAssemblyPrerendered;
|
||||
|
||||
public static void Main(string[] args)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
"dotnetRunMessages": "true",
|
||||
"launchBrowser": false,
|
||||
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
|
||||
"applicationUrl": "https://localhost:53451",
|
||||
"applicationUrl": "https://localhost:54938",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using ElsaDashboard.Backend.Extensions;
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
|
@ -22,9 +23,13 @@ namespace ElsaDashboard.Samples.Server
|
|||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddRazorPages();
|
||||
services.AddElsaDashboardUI();
|
||||
services.AddElsaDashboardBackend(options => options.ServerUrl = Configuration.GetValue<Uri>("Elsa:HostUrl"));
|
||||
|
||||
var elsaServerUrl = Configuration.GetValue<Uri>("Elsa:HostUrl");
|
||||
|
||||
services
|
||||
.AddElsaDashboardUI(options => options.ElsaServerUrl = elsaServerUrl)
|
||||
.AddElsaDashboardBackend(options => options.ServerUrl = elsaServerUrl);
|
||||
|
||||
if (Program.RuntimeModel == BlazorRuntimeModel.Server)
|
||||
services.AddServerSideBlazor(options =>
|
||||
{
|
||||
|
|
@ -39,7 +44,7 @@ namespace ElsaDashboard.Samples.Server
|
|||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
|
||||
if (Program.RuntimeModel == BlazorRuntimeModel.Browser)
|
||||
if (Program.RuntimeModel == BlazorRuntimeModel.WebAssembly)
|
||||
app.UseWebAssemblyDebugging();
|
||||
}
|
||||
else
|
||||
|
|
@ -48,17 +53,19 @@ namespace ElsaDashboard.Samples.Server
|
|||
app.UseHsts();
|
||||
}
|
||||
|
||||
if (Program.RuntimeModel == BlazorRuntimeModel.Browser)
|
||||
if (Program.RuntimeModel == BlazorRuntimeModel.WebAssembly)
|
||||
app.UseBlazorFrameworkFiles();
|
||||
|
||||
app.UseStaticFiles();
|
||||
app.UseRouting();
|
||||
app.UseElsaGrpcServices();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
if (Program.RuntimeModel == BlazorRuntimeModel.Server)
|
||||
endpoints.MapBlazorHub();
|
||||
|
||||
endpoints.MapRazorPages();
|
||||
endpoints.MapFallbackToPage("/_Host");
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using Microsoft.Extensions.DependencyInjection;
|
|||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using ElsaDashboard.Application;
|
||||
using ElsaDashboard.WebAssembly.Extensions;
|
||||
|
||||
namespace ElsaDashboard.Samples.WebAssembly
|
||||
|
|
@ -14,9 +15,15 @@ namespace ElsaDashboard.Samples.WebAssembly
|
|||
var builder = WebAssemblyHostBuilder.CreateDefault(args);
|
||||
var services = builder.Services;
|
||||
|
||||
//builder.RootComponents.Add<App>("#app");
|
||||
services.AddScoped(sp => new HttpClient {BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)});
|
||||
services.AddElsaDashboardUI();
|
||||
builder.RootComponents.Add<App>("#app");
|
||||
|
||||
// Change the Elsa Server URL to point to wherever you have hosted Elsa. In this example, Elsa is either hosted by "ElsaDashboard.Samples.Monolith" or "Elsa.Samples.Server.Host"
|
||||
services.AddElsaDashboardUI(options => options.ElsaServerUrl = new Uri("https://localhost:11000"));
|
||||
|
||||
// When the web assembly project is hosted directly from e.g. blob storage, the URL to the gRPC backend needs to be specified explicitly.
|
||||
// When hosted from ElsaDashboard.Samples.Monolith or ElsaDashboard.Samples.Server, we don't need to specify a backend URL.
|
||||
//services.AddElsaDashboardBackend(options => options.BackendUrl = new Uri("https://localhost:11000"));
|
||||
|
||||
services.AddElsaDashboardBackend();
|
||||
|
||||
await builder.Build().RunAsync();
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ namespace Elsa.Server.Api.Endpoints.WorkflowDefinitions
|
|||
OperationId = "WorkflowDefinitions.Post",
|
||||
Tags = new[] { "WorkflowDefinitions" })
|
||||
]
|
||||
public async Task<ActionResult<WorkflowDefinition>> Handle(SaveRequest request, ApiVersion apiVersion, CancellationToken cancellationToken)
|
||||
public async Task<ActionResult<WorkflowDefinition>> Handle([FromBody]SaveRequest request, [FromRoute]ApiVersion apiVersion, CancellationToken cancellationToken)
|
||||
{
|
||||
var workflowDefinitionId = request.WorkflowDefinitionId;
|
||||
var workflowDefinition = !string.IsNullOrWhiteSpace(workflowDefinitionId) ? await _workflowPublisher.GetDraftAsync(workflowDefinitionId, cancellationToken) : default;
|
||||
|
|
|
|||
Loading…
Reference in a new issue