Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix existing standalone web examples #420

Merged
merged 8 commits into from
Feb 2, 2024

This file was deleted.

34 changes: 25 additions & 9 deletions src/shell/dotnet/Shell/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@
// */

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows;
using Microsoft.Extensions.Configuration;
Expand All @@ -32,6 +33,7 @@
using MorganStanley.ComposeUI.Shell.Modules;
using MorganStanley.ComposeUI.Shell.Utilities;
using MorganStanley.ComposeUI.Utilities;
using static MorganStanley.ComposeUI.Shell.Modules.ModuleCatalog;

namespace MorganStanley.ComposeUI.Shell;

Expand Down Expand Up @@ -162,6 +164,7 @@ void ConfigureModules()
services.Configure<ModuleCatalogOptions>(
context.Configuration.GetSection(ModuleCatalogOptions.ConfigurationPath));
services.AddHostedService<ModuleService>();
services.AddTransient<IStartupAction, WebWindowOptionsStartupAction>();
}

void ConfigureFdc3()
Expand All @@ -170,7 +173,7 @@ void ConfigureFdc3()
var fdc3Options = fdc3ConfigurationSection.Get<Fdc3Options>();

// TODO: Use feature flag instead
if (fdc3Options is {EnableFdc3: true})
if (fdc3Options is { EnableFdc3: true })
{
services.AddFdc3DesktopAgent();
services.AddFdc3AppDirectory();
Expand Down Expand Up @@ -200,7 +203,26 @@ private void OnAsyncStartupCompleted(StartupEventArgs e)
&& CommandLineParser.TryParse<WebWindowOptions>(e.Args, out var webWindowOptions)
&& webWindowOptions.Url != null)
{
StartWithWebWindowOptions(webWindowOptions);
var moduleId = Guid.NewGuid().ToString();

var moduleCatalog = _host.Services.GetRequiredService<ModuleCatalog>();
moduleCatalog.Add(new WebModuleManifest
{
Id = moduleId,
Name = webWindowOptions.Url,
ModuleType = ModuleType.Web,
Details = new WebManifestDetails
{
Url = new Uri(webWindowOptions.Url),
IconUrl = webWindowOptions.IconUrl == null ? null : new Uri(webWindowOptions.IconUrl)
}
});

var moduleLoader = _host.Services.GetRequiredService<IModuleLoader>();
moduleLoader.StartModule(new StartRequest(moduleId, new List<KeyValuePair<string, string>>()
{
{ new(WebWindowOptions.ParameterName, JsonSerializer.Serialize(webWindowOptions)) }
}));

return;
}
Expand Down Expand Up @@ -236,10 +258,4 @@ private async Task StopAsync()
}
}
}

private void StartWithWebWindowOptions(WebWindowOptions options)
{
ShutdownMode = ShutdownMode.OnLastWindowClose;
CreateWindow<WebWindow>(options).Show();
}
}
36 changes: 18 additions & 18 deletions src/shell/dotnet/Shell/Modules/ModuleCatalog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,31 +67,14 @@ private async Task LoadFromFile(string path)
?? new Dictionary<string, ModuleManifest>();
}

private void Add(ModuleManifest manifest)
internal void Add(ModuleManifest manifest)
{
_modules.Add(manifest.Id, manifest);
}

private static readonly JsonSerializerOptions JsonSerializerOptions =
new() { Converters = { new ModuleManifestConverter() } };

private class ModuleManifest : IModuleManifest
{
public string Id { get; set; }
public string Name { get; set; }
public string ModuleType { get; set; }
}

private class WebModuleManifest : ModuleManifest, IModuleManifest<WebManifestDetails>
{
public WebManifestDetails GetDetails()
{
return Details;
}

public WebManifestDetails Details { get; set; }
}

private class ModuleManifestConverter : JsonConverter<ModuleManifest>
{
public override bool CanConvert(Type objectType)
Expand Down Expand Up @@ -133,4 +116,21 @@ private struct ManifestTypeHelper
public string ModuleType { get; set; }
}
}

internal class ModuleManifest : IModuleManifest
ztanczos marked this conversation as resolved.
Show resolved Hide resolved
{
public string Id { get; set; }
public string Name { get; set; }
public string ModuleType { get; set; }
}

internal class WebModuleManifest : ModuleManifest, IModuleManifest<WebManifestDetails>
{
public WebManifestDetails GetDetails()
{
return Details;
}

public WebManifestDetails Details { get; set; }
}
}
5 changes: 3 additions & 2 deletions src/shell/dotnet/Shell/Modules/ModuleService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,18 @@ public Task StopAsync(CancellationToken cancellationToken)
private async void OnWebModuleStarted(LifetimeEvent.Started e)
{
var properties = e.Instance.GetProperties().OfType<WebStartupProperties>().FirstOrDefault();

if (properties == null) return;

var webWindowOptions = e.Instance.GetProperties().OfType<WebWindowOptions>().FirstOrDefault();

try
{
await _application.Dispatcher.InvokeAsync(
() =>
{
var window = _application.CreateWindow<WebWindow>(
e.Instance,
new WebWindowOptions
webWindowOptions ?? new WebWindowOptions
{
Url = properties.Url.ToString(),
IconUrl = properties.IconUrl?.ToString()
Expand Down
38 changes: 38 additions & 0 deletions src/shell/dotnet/Shell/Modules/WebWindowOptionsStartupAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Morgan Stanley makes this available to you under the Apache License,
// Version 2.0 (the "License"). You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0.
//
// See the NOTICE file distributed with this work for additional information
// regarding copyright ownership. 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 System;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using MorganStanley.ComposeUI.ModuleLoader;

namespace MorganStanley.ComposeUI.Shell.Modules
{
internal class WebWindowOptionsStartupAction : IStartupAction
{
public Task InvokeAsync(StartupContext startupContext, Func<Task> next)
{
if (startupContext.ModuleInstance.Manifest.ModuleType == ModuleType.Web)
{
var webWindowOptions = startupContext.StartRequest.Parameters
.FirstOrDefault(p => p.Key == WebWindowOptions.ParameterName).Value;
if (webWindowOptions != null)
{
startupContext.AddProperty(JsonSerializer.Deserialize<WebWindowOptions>(webWindowOptions));
BalassaMarton marked this conversation as resolved.
Show resolved Hide resolved
}
}

return next();
}
}
}
1 change: 1 addition & 0 deletions src/shell/dotnet/Shell/WebWindowOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ public sealed class WebWindowOptions
public const string DefaultTitle = "Compose Web Container";
public const string DefaultUrl = "about:blank";
public const double DefaultWidth = 800;
public const string ParameterName = nameof(WebWindowOptions);
lilla28 marked this conversation as resolved.
Show resolved Hide resolved
}
11 changes: 10 additions & 1 deletion src/shell/dotnet/examples/module-catalog.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[
[
{
"Id": "Morgan Stanley",
"Name": "Morgan Stanley",
Expand Down Expand Up @@ -43,5 +43,14 @@
"Url": "https://finos.github.io/FDC3-conformance-framework/v2.0/app/",
"IconUrl": "https://fdc3.finos.org/assets/fdc3-logo.png"
}
},
{
"Id": "js-grid",
"Name": "Grid",
"ModuleType": "web",
"Details": {
"Url": "http://localhost:4200/",
"IconUrl": "http://localhost:4200/favicon.ico"
}
}
]
Loading