diff --git a/OrchardCore.sln b/OrchardCore.sln index 4335d613af5..43c9e68ae23 100644 --- a/OrchardCore.sln +++ b/OrchardCore.sln @@ -521,6 +521,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Email.Smtp", "s EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OrchardCore.Rules.Core", "src\OrchardCore\OrchardCore.Rules.Core\OrchardCore.Rules.Core.csproj", "{4BAA08A2-878C-4B96-86BF-5B3DB2B6C2C7}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "OrchardCore.Components", "OrchardCore.Components", "{7525406F-AEA0-4397-8E6B-3837ABEC2A36}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Admin.Components", "src\OrchardCore.Components\OrchardCore.Admin.Components\OrchardCore.Admin.Components.csproj", "{0734E6A3-5D42-4698-91F1-4068364E8FCC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Admin.WebAssembly.App", "src\OrchardCore.Components\OrchardCore.Admin.WebAssembly.App\OrchardCore.Admin.WebAssembly.App.csproj", "{361B5892-DE24-4249-827E-3D144CC68643}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Common.Components", "src\OrchardCore.Components\OrchardCore.Common.Components\OrchardCore.Common.Components.csproj", "{2C2CD2A9-BFD8-4A9C-A30F-3CA973E734B7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1377,6 +1385,18 @@ Global {4BAA08A2-878C-4B96-86BF-5B3DB2B6C2C7}.Debug|Any CPU.Build.0 = Debug|Any CPU {4BAA08A2-878C-4B96-86BF-5B3DB2B6C2C7}.Release|Any CPU.ActiveCfg = Release|Any CPU {4BAA08A2-878C-4B96-86BF-5B3DB2B6C2C7}.Release|Any CPU.Build.0 = Release|Any CPU + {0734E6A3-5D42-4698-91F1-4068364E8FCC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0734E6A3-5D42-4698-91F1-4068364E8FCC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0734E6A3-5D42-4698-91F1-4068364E8FCC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0734E6A3-5D42-4698-91F1-4068364E8FCC}.Release|Any CPU.Build.0 = Release|Any CPU + {361B5892-DE24-4249-827E-3D144CC68643}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {361B5892-DE24-4249-827E-3D144CC68643}.Debug|Any CPU.Build.0 = Debug|Any CPU + {361B5892-DE24-4249-827E-3D144CC68643}.Release|Any CPU.ActiveCfg = Release|Any CPU + {361B5892-DE24-4249-827E-3D144CC68643}.Release|Any CPU.Build.0 = Release|Any CPU + {2C2CD2A9-BFD8-4A9C-A30F-3CA973E734B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2C2CD2A9-BFD8-4A9C-A30F-3CA973E734B7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2C2CD2A9-BFD8-4A9C-A30F-3CA973E734B7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2C2CD2A9-BFD8-4A9C-A30F-3CA973E734B7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1615,6 +1635,10 @@ Global {C35AB37B-5A09-4896-BEEE-B126B7E7018A} = {A066395F-6F73-45DC-B5A6-B4E306110DCE} {E8A1097D-A65A-4B17-A3A2-F50D79552732} = {A066395F-6F73-45DC-B5A6-B4E306110DCE} {4BAA08A2-878C-4B96-86BF-5B3DB2B6C2C7} = {F23AC6C2-DE44-4699-999D-3C478EF3D691} + {7525406F-AEA0-4397-8E6B-3837ABEC2A36} = {275E087F-A4E2-4A7B-A924-ED68E3A52086} + {0734E6A3-5D42-4698-91F1-4068364E8FCC} = {7525406F-AEA0-4397-8E6B-3837ABEC2A36} + {361B5892-DE24-4249-827E-3D144CC68643} = {7525406F-AEA0-4397-8E6B-3837ABEC2A36} + {2C2CD2A9-BFD8-4A9C-A30F-3CA973E734B7} = {7525406F-AEA0-4397-8E6B-3837ABEC2A36} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {46A1D25A-78D1-4476-9CBF-25B75E296341} diff --git a/src/OrchardCore.Build/Dependencies.AspNetCore.props b/src/OrchardCore.Build/Dependencies.AspNetCore.props index ea300bc3e6f..19c327f6bbb 100644 --- a/src/OrchardCore.Build/Dependencies.AspNetCore.props +++ b/src/OrchardCore.Build/Dependencies.AspNetCore.props @@ -42,6 +42,11 @@ + + + + + diff --git a/src/OrchardCore.Cms.Web/OrchardCore.Cms.Web.csproj b/src/OrchardCore.Cms.Web/OrchardCore.Cms.Web.csproj index a5ac7fee774..ecb0407c3ea 100644 --- a/src/OrchardCore.Cms.Web/OrchardCore.Cms.Web.csproj +++ b/src/OrchardCore.Cms.Web/OrchardCore.Cms.Web.csproj @@ -1,4 +1,4 @@ - + @@ -30,10 +30,13 @@ + + + diff --git a/src/OrchardCore.Cms.Web/Program.cs b/src/OrchardCore.Cms.Web/Program.cs index f5e06716d21..dbc1af10d87 100644 --- a/src/OrchardCore.Cms.Web/Program.cs +++ b/src/OrchardCore.Cms.Web/Program.cs @@ -10,7 +10,11 @@ var app = builder.Build(); -if (!app.Environment.IsDevelopment()) +if (app.Environment.IsDevelopment()) +{ + app.UseWebAssemblyDebugging(); +} +else { app.UseExceptionHandler("/Error"); } diff --git a/src/OrchardCore.Cms.Web/Properties/launchSettings.json b/src/OrchardCore.Cms.Web/Properties/launchSettings.json index ef8cc6e703c..f849a819433 100644 --- a/src/OrchardCore.Cms.Web/Properties/launchSettings.json +++ b/src/OrchardCore.Cms.Web/Properties/launchSettings.json @@ -18,9 +18,11 @@ "Kestrel": { "commandName": "Project", "launchBrowser": true, + "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", "launchUrl": "https://localhost:5001", "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" + "ASPNETCORE_ENVIRONMENT": "Development", + "ORCHARD_APP_DATA": "C:\\k8s\\oc_github" }, "applicationUrl": "https://localhost:5001;http://localhost:5000" } diff --git a/src/OrchardCore.Components/Directory.Build.props b/src/OrchardCore.Components/Directory.Build.props new file mode 100644 index 00000000000..a49d641582b --- /dev/null +++ b/src/OrchardCore.Components/Directory.Build.props @@ -0,0 +1,10 @@ + + + + + + + $(CommonTargetFrameworks) + + + diff --git a/src/OrchardCore.Components/Directory.Build.targets b/src/OrchardCore.Components/Directory.Build.targets new file mode 100644 index 00000000000..f20824469e8 --- /dev/null +++ b/src/OrchardCore.Components/Directory.Build.targets @@ -0,0 +1,5 @@ + + + + + diff --git a/src/OrchardCore.Components/OrchardCore.Admin.Components/OrchardAdminApp.razor b/src/OrchardCore.Components/OrchardCore.Admin.Components/OrchardAdminApp.razor new file mode 100644 index 00000000000..770e28d99ed --- /dev/null +++ b/src/OrchardCore.Components/OrchardCore.Admin.Components/OrchardAdminApp.razor @@ -0,0 +1,7 @@ +@using Microsoft.AspNetCore.Components.Routing + + + + + + \ No newline at end of file diff --git a/src/OrchardCore.Components/OrchardCore.Admin.Components/OrchardCore.Admin.Components.csproj b/src/OrchardCore.Components/OrchardCore.Admin.Components/OrchardCore.Admin.Components.csproj new file mode 100644 index 00000000000..73a3385b13d --- /dev/null +++ b/src/OrchardCore.Components/OrchardCore.Admin.Components/OrchardCore.Admin.Components.csproj @@ -0,0 +1,21 @@ + + + + $(CommonTargetFrameworks) + enable + enable + + + + + + + + + + + + + + + diff --git a/src/OrchardCore.Components/OrchardCore.Admin.Components/_Imports.razor b/src/OrchardCore.Components/OrchardCore.Admin.Components/_Imports.razor new file mode 100644 index 00000000000..97a9ff29cf3 --- /dev/null +++ b/src/OrchardCore.Components/OrchardCore.Admin.Components/_Imports.razor @@ -0,0 +1,8 @@ +@using System.Net.Http +@using System.Net.Http.Json +@using Microsoft.AspNetCore.Components.Forms +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web +@using static Microsoft.AspNetCore.Components.Web.RenderMode +@using Microsoft.AspNetCore.Components.Web.Virtualization +@using Microsoft.JSInterop \ No newline at end of file diff --git a/src/OrchardCore.Components/OrchardCore.Admin.WebAssembly.App/Initializer.razor b/src/OrchardCore.Components/OrchardCore.Admin.WebAssembly.App/Initializer.razor new file mode 100644 index 00000000000..c863efaac91 --- /dev/null +++ b/src/OrchardCore.Components/OrchardCore.Admin.WebAssembly.App/Initializer.razor @@ -0,0 +1,5 @@ +

Initializer

+ +@code { + +} diff --git a/src/OrchardCore.Components/OrchardCore.Admin.WebAssembly.App/OrchardCore.Admin.WebAssembly.App.csproj b/src/OrchardCore.Components/OrchardCore.Admin.WebAssembly.App/OrchardCore.Admin.WebAssembly.App.csproj new file mode 100644 index 00000000000..9c989392163 --- /dev/null +++ b/src/OrchardCore.Components/OrchardCore.Admin.WebAssembly.App/OrchardCore.Admin.WebAssembly.App.csproj @@ -0,0 +1,22 @@ + + + + $(CommonTargetFrameworks) + + enable + enable + true + Default + + + + + + + + + + + + + diff --git a/src/OrchardCore.Components/OrchardCore.Admin.WebAssembly.App/Program.cs b/src/OrchardCore.Components/OrchardCore.Admin.WebAssembly.App/Program.cs new file mode 100644 index 00000000000..d66eeba41d8 --- /dev/null +++ b/src/OrchardCore.Components/OrchardCore.Admin.WebAssembly.App/Program.cs @@ -0,0 +1,11 @@ +using Microsoft.AspNetCore.Components.Web; +using Microsoft.AspNetCore.Components.WebAssembly.Hosting; +using OrchardCore.Admin.WebAssembly.App; +using OrchardCore.Common.Components; + +var builder = WebAssemblyHostBuilder.CreateDefault(args); +builder.RootComponents.RegisterCustomElement("option-editor"); +builder.RootComponents.RegisterCustomElement("init"); + + +await builder.Build().RunAsync(); diff --git a/src/OrchardCore.Components/OrchardCore.Admin.WebAssembly.App/_Imports.razor b/src/OrchardCore.Components/OrchardCore.Admin.WebAssembly.App/_Imports.razor new file mode 100644 index 00000000000..8a2c0c8c0a4 --- /dev/null +++ b/src/OrchardCore.Components/OrchardCore.Admin.WebAssembly.App/_Imports.razor @@ -0,0 +1,9 @@ +@using System.Net.Http +@using System.Net.Http.Json +@using Microsoft.AspNetCore.Components.Forms +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web +@using static Microsoft.AspNetCore.Components.Web.RenderMode +@using Microsoft.AspNetCore.Components.Web.Virtualization +@using Microsoft.JSInterop +@using OrchardCore.Admin.WebAssembly.App diff --git a/src/OrchardCore.Components/OrchardCore.Common.Components/CollocatedJSComponent.cs b/src/OrchardCore.Components/OrchardCore.Common.Components/CollocatedJSComponent.cs new file mode 100644 index 00000000000..fde28f25fdd --- /dev/null +++ b/src/OrchardCore.Components/OrchardCore.Common.Components/CollocatedJSComponent.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; + +namespace OrchardCore.Common.Components; + +public class CollocatedJSComponent : ComponentBase, IAsyncDisposable +{ + [Inject] + private IJSRuntime? JS { get; set; } + + [Parameter] + public bool RaiseDomEvents { get; set; } + + protected IJSObjectReference? JSModule { get; private set; } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + var ns = GetType().Namespace; + var cmp = GetType().Name; + if (JS is not null) + { + JSModule = await JS.InvokeAsync("import", + $"./_content/{ns}/{cmp}.razor.js"); + } + } + } + + async ValueTask IAsyncDisposable.DisposeAsync() + { + if (JSModule is not null) + { + await JSModule.DisposeAsync(); + } + } + +} diff --git a/src/OrchardCore.Components/OrchardCore.Common.Components/ModalDialog.razor b/src/OrchardCore.Components/OrchardCore.Common.Components/ModalDialog.razor new file mode 100644 index 00000000000..8ff6dfd03b0 --- /dev/null +++ b/src/OrchardCore.Components/OrchardCore.Common.Components/ModalDialog.razor @@ -0,0 +1,59 @@ + + +@if (ShowBackdrop && IsOpen) +{ + +} + +@code { + + [Parameter] + public string? Title { get; set; } + [Parameter] + public bool ShowBackdrop { get; set; } + [Parameter] + public RenderFragment? Body { get; set; } + [Parameter] + public RenderFragment? Actions { get; set; } + + + public bool IsOpen { get; set; } + + string IsOpenClass { get; set; } = string.Empty; + + string IsOpenDisplayStyle { get; set; } = "none"; + + public async Task Open() + { + IsOpenDisplayStyle = "block"; + IsOpen = true; + await Task.Delay(100);//Delay allows bootstrap to perform nice fade animation + IsOpenClass = "show"; + StateHasChanged(); + + } + + public async Task Close() + { + IsOpenClass = ""; + IsOpen = false; + await Task.Delay(250);//Delay allows bootstrap to perform nice fade animation + IsOpenDisplayStyle = "none"; + StateHasChanged(); + } +} diff --git a/src/OrchardCore.Components/OrchardCore.Common.Components/OptionEditor.razor b/src/OrchardCore.Components/OrchardCore.Common.Components/OptionEditor.razor new file mode 100644 index 00000000000..2183b811b8b --- /dev/null +++ b/src/OrchardCore.Components/OrchardCore.Common.Components/OptionEditor.razor @@ -0,0 +1,309 @@ +@using System.Text.Json +@using System.ComponentModel.DataAnnotations +@using Microsoft.AspNetCore.Components.Forms +@using Microsoft.JSInterop + +@inherits CollocatedJSComponent + + + + + + + + + + + + + + + + + @for (var keyIndex = 0; keyIndex < Options!.Count; keyIndex++) + { + var option = Options![keyIndex]; + + + + + + + + + + + } + + + + + + + +
Option LabelValueDefault?
+ + +
+ + +
+
+ + +
+ +
+
+ +
+ + + + +
+ + + @("A JSON representation of the allowed values, e.g. {0}") @("[{ name: 'First option', value: 'option1' }, { name: 'Second option', value: 'option2' } ]") +
+
+ + + @("(Optional) The default to assign to the text field.") +
+ + + + + +
+ +@code { + [Parameter] + public string? OptionsJson { get; set; } + + [Parameter] + public string? DefaultValue { get; set; } + + + ElementReference tableElement; + + private ModalDialog? Modal { get; set; } + + private List? Options { get; set; } + private string? OptionsJsonInternal { get; set; } + private string? DefaultValueInternal { get; set; } + private string IsInvalidClass { get; set; } = string.Empty; + private const string OptionsJsonEmpty = "[]"; + + + + private void SetOptionsEmpty() + { + Options = new List(); + OptionsJsonInternal = OptionsJsonEmpty; + } + + private bool TryJsonValid(string? json) + { + if (string.IsNullOrWhiteSpace(json)) + return false; + try + { + _ = JsonSerializer.Deserialize>(json, new JsonSerializerOptions(JsonSerializerDefaults.Web)); + return true; + } + catch (JsonException) + { + return false; + } + } + + private bool TryUpdateOptions(string? json) + { + if (string.IsNullOrWhiteSpace(json)) + return false; + try + { + + var updated = JsonSerializer.Deserialize>(json, new JsonSerializerOptions(JsonSerializerDefaults.Web)); + if (updated != null && !Options!.Equals(updated)) + { + Options.Clear(); + Options.AddRange(updated!); + } + return true; + } + catch (JsonException ex) + { + Console.WriteLine(ex); + return false; + } + } + + private bool TryUpdateOptionsJson(List? options) + { + if (options is null) + return false; + try + { + OptionsJsonInternal = JsonSerializer.Serialize(options!, new JsonSerializerOptions(JsonSerializerDefaults.Web)); + return true; + } + catch (JsonException ex) + { + Console.WriteLine(ex); + return false; + } + } + + private async Task OptionItemChangeAsync(Action update) + { + update(); + TryUpdateOptionsJson(Options); + await TriggerEventAsync(); + } + + + protected override Task OnInitializedAsync() + { + SetOptionsEmpty(); + return base.OnInitializedAsync(); + } + + + protected override Task OnParametersSetAsync() + { + if (!string.IsNullOrWhiteSpace(OptionsJson)) + { + if (TryUpdateOptions(OptionsJson)) + { + OptionsJsonInternal = OptionsJson; + } + } + + if (!string.IsNullOrWhiteSpace(DefaultValue)) + DefaultValueInternal = DefaultValue.Trim(); + else + DefaultValueInternal = string.Empty; + + return base.OnParametersSetAsync(); + } + private Task AddNewOptionAsync() + { + Options!.Add(new OptionsModel()); + TryUpdateOptionsJson(Options); + return TriggerEventAsync(); + } + + private Task RemoveOptionAsync(OptionsModel option) + { + Options!.Remove(option); + TryUpdateOptionsJson(Options); + return TriggerEventAsync(); + } + + async Task DefaultOptionChangedAsync(ChangeEventArgs args) + { + DefaultValueInternal = args.Value?.ToString(); + await TriggerEventAsync(); + } + + async Task OptionsJsonChangedAsync(ChangeEventArgs e) + { + var newVal = e.Value?.ToString(); + if (TryJsonValid(newVal)) + { + IsInvalidClass = ""; + OptionsJsonInternal = newVal; + } + else + { + IsInvalidClass = "is-invalid"; + } + + await Task.CompletedTask; + } + + async Task SubmitAsync() + { + if (TryUpdateOptions(OptionsJsonInternal)) + { + await Modal!.Close(); + await TriggerEventAsync(); + StateHasChanged(); + } + } + + async Task CancelAsync() + { + TryUpdateOptionsJson(Options); + await Modal!.Close(); + } + + public class OptionsModel + { + [Required(AllowEmptyStrings = false, ErrorMessage = "Provide option name")] + public string? Name { get; set; } + [Required(AllowEmptyStrings = false, ErrorMessage = "Provide option value")] + public string? Value { get; set; } + } + + + int currentIndex; + + void StartDrag(OptionsModel item) + => currentIndex = GetIndex(item); + + int GetIndex(OptionsModel item) + => Options!.FindIndex(a => string.Equals(a.Name, item.Name)); + + async Task Drop(OptionsModel item) + { + if (item != null) + { + var index = GetIndex(item); + + // get current item + var current = Options![currentIndex]; + + // remove game from current index + Options!.RemoveAt(currentIndex); + Options!.Insert(index, current); + + // update current selection + currentIndex = index; + + TryUpdateOptionsJson(Options); + await TriggerEventAsync(); + } + else + { + await Task.CompletedTask; + } + } + + async Task TriggerEventAsync() + { + StateHasChanged(); + if (JSModule is not null) + { + await JSModule.InvokeVoidAsync("optionsChanged", tableElement, OptionsJsonInternal, DefaultValueInternal); + } + } + +} diff --git a/src/OrchardCore.Components/OrchardCore.Common.Components/OptionEditor.razor.js b/src/OrchardCore.Components/OrchardCore.Common.Components/OptionEditor.razor.js new file mode 100644 index 00000000000..ae59baa0fa1 --- /dev/null +++ b/src/OrchardCore.Components/OrchardCore.Common.Components/OptionEditor.razor.js @@ -0,0 +1,10 @@ +export function optionsChanged(element, jsonValue, defaultValue) { + const evt = new CustomEvent("blazor:optionsChanged", { + bubbles: true, + detail: { + options: jsonValue, + defaultValue: defaultValue + } + }); + element.dispatchEvent(evt); +} diff --git a/src/OrchardCore.Components/OrchardCore.Common.Components/OrchardCore.Common.Components.csproj b/src/OrchardCore.Components/OrchardCore.Common.Components/OrchardCore.Common.Components.csproj new file mode 100644 index 00000000000..2dc00f31670 --- /dev/null +++ b/src/OrchardCore.Components/OrchardCore.Common.Components/OrchardCore.Common.Components.csproj @@ -0,0 +1,19 @@ + + + + $(CommonTargetFrameworks) + enable + enable + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/OrchardCore.Components/OrchardCore.Common.Components/_Imports.razor b/src/OrchardCore.Components/OrchardCore.Common.Components/_Imports.razor new file mode 100644 index 00000000000..d96cabe770a --- /dev/null +++ b/src/OrchardCore.Components/OrchardCore.Common.Components/_Imports.razor @@ -0,0 +1,4 @@ +@using Microsoft.AspNetCore.Components.Web +@using System.Text.Json + + diff --git a/src/OrchardCore.Modules/OrchardCore.Admin/Manifest.cs b/src/OrchardCore.Modules/OrchardCore.Admin/Manifest.cs index d97764dd742..d6c11303f0c 100644 --- a/src/OrchardCore.Modules/OrchardCore.Admin/Manifest.cs +++ b/src/OrchardCore.Modules/OrchardCore.Admin/Manifest.cs @@ -4,11 +4,27 @@ Name = "Admin", Author = ManifestConstants.OrchardCoreTeam, Website = ManifestConstants.OrchardCoreWebsite, - Version = ManifestConstants.OrchardCoreVersion, - Description = "Creates an admin section for the site.", + Version = ManifestConstants.OrchardCoreVersion +)] + +[assembly: Feature( + Id = "OrchardCore.Admin", + Name = "Admin", + Description = "Creates an admin section for the site.", Category = "Infrastructure", Dependencies = [ "OrchardCore.Settings" ] )] + +[assembly: Feature( + Id = ManifestConstants.Features.BlazorUI, + Name = "Blazor UI for Admin", + Category = "Infrastructure", + Description = "Adds support for the Blazor UI for Admin section.", + Dependencies = + [ + "OrchardCore.Admin" + ] +)] diff --git a/src/OrchardCore.Modules/OrchardCore.Admin/OrchardCore.Admin.csproj b/src/OrchardCore.Modules/OrchardCore.Admin/OrchardCore.Admin.csproj index 0c2da034003..cb6f73eb467 100644 --- a/src/OrchardCore.Modules/OrchardCore.Admin/OrchardCore.Admin.csproj +++ b/src/OrchardCore.Modules/OrchardCore.Admin/OrchardCore.Admin.csproj @@ -14,8 +14,12 @@ - + + + + + @@ -24,5 +28,5 @@ - +
diff --git a/src/OrchardCore.Modules/OrchardCore.Admin/Startup.cs b/src/OrchardCore.Modules/OrchardCore.Admin/Startup.cs index c8357e3f5fe..255ee3fffec 100644 --- a/src/OrchardCore.Modules/OrchardCore.Admin/Startup.cs +++ b/src/OrchardCore.Modules/OrchardCore.Admin/Startup.cs @@ -2,15 +2,20 @@ using Fluid; using Fluid.Values; using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Rendering; +using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ApplicationModels; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; +using OrchardCore.Admin.Components; using OrchardCore.Admin.Controllers; using OrchardCore.Admin.Drivers; using OrchardCore.Admin.Models; +using OrchardCore.Common.Components; using OrchardCore.DisplayManagement; using OrchardCore.DisplayManagement.Handlers; using OrchardCore.DisplayManagement.ModelBinding; @@ -19,6 +24,7 @@ using OrchardCore.Environment.Shell.Scope; using OrchardCore.Liquid; using OrchardCore.Modules; +using OrchardCore.Modules.Manifest; using OrchardCore.Mvc.Core.Utilities; using OrchardCore.Mvc.Routing; using OrchardCore.Navigation; @@ -90,6 +96,34 @@ public override void ConfigureServices(IServiceCollection services) } } + [Modules.Feature(ManifestConstants.Features.BlazorUI)] + public class AdminComponentsStartup : StartupBase + { + public override int Order => 1; + + public override void ConfigureServices(IServiceCollection services) + { + services.AddRazorComponents() + .AddInteractiveServerComponents() + .AddInteractiveWebAssemblyComponents(); + ; + + } + + public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider) + { + app.UseAntiforgery(); + app.UseStaticFiles(); + routes.MapRazorComponents() + .AddInteractiveServerRenderMode() + .AddInteractiveWebAssemblyRenderMode() + .AddAdditionalAssemblies(typeof(OptionEditor).Assembly) + ; + + } + } + + [RequireFeatures("OrchardCore.Deployment")] public class DeploymentStartup : StartupBase { diff --git a/src/OrchardCore.Modules/OrchardCore.ContentFields/OrchardCore.ContentFields.csproj b/src/OrchardCore.Modules/OrchardCore.ContentFields/OrchardCore.ContentFields.csproj index d50cedac85f..782a30f5356 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentFields/OrchardCore.ContentFields.csproj +++ b/src/OrchardCore.Modules/OrchardCore.ContentFields/OrchardCore.ContentFields.csproj @@ -15,6 +15,7 @@ + diff --git a/src/OrchardCore.Modules/OrchardCore.ContentFields/Views/TextFieldPredefinedListEditorSettings.Edit.cshtml b/src/OrchardCore.Modules/OrchardCore.ContentFields/Views/TextFieldPredefinedListEditorSettings.Edit.cshtml index 448266b0a1b..345aa6d5c43 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentFields/Views/TextFieldPredefinedListEditorSettings.Edit.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.ContentFields/Views/TextFieldPredefinedListEditorSettings.Edit.cshtml @@ -1,13 +1,20 @@ +@using Microsoft.AspNetCore.Components +@using Microsoft.AspNetCore.Components.Endpoints +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.Extensions.DependencyInjection +@using OrchardCore.Admin.Components +@using OrchardCore.Common.Components @using OrchardCore.ContentFields.Settings @model OrchardCore.ContentFields.ViewModels.PredefinedListSettingsViewModel - +@* - - - + *@ +@* + *@
-
-
- - -
-
+
+
+ + +
+
-
-
- - - - -
-
+
+
+ + @* + *@ + + +
+
+ \ No newline at end of file diff --git a/src/OrchardCore.Modules/OrchardCore.Resources/ResourceManagementOptionsConfiguration.cs b/src/OrchardCore.Modules/OrchardCore.Resources/ResourceManagementOptionsConfiguration.cs index 26e8fa46cfd..af01574fb37 100644 --- a/src/OrchardCore.Modules/OrchardCore.Resources/ResourceManagementOptionsConfiguration.cs +++ b/src/OrchardCore.Modules/OrchardCore.Resources/ResourceManagementOptionsConfiguration.cs @@ -500,6 +500,16 @@ ResourceManifest BuildManifest() .SetDependencies("monaco-loader") .SetVersion(MonacoEditorVersion); + manifest + .DefineScript("blazor-custom-elements") + .SetUrl("~/_content/Microsoft.AspNetCore.Components.CustomElements/Microsoft.AspNetCore.Components.CustomElements.lib.module.js") + .SetVersion("8.0.1"); + + manifest + .DefineScript("blazor-web-js") + .SetUrl("~/_framework/blazor.web.js") + .SetVersion("8.0.1"); + return manifest; } diff --git a/src/OrchardCore.Themes/TheAdmin/Views/Layout.cshtml b/src/OrchardCore.Themes/TheAdmin/Views/Layout.cshtml index be7a31a8c0d..51e2979b85a 100644 --- a/src/OrchardCore.Themes/TheAdmin/Views/Layout.cshtml +++ b/src/OrchardCore.Themes/TheAdmin/Views/Layout.cshtml @@ -21,8 +21,8 @@ - - + + @@ -39,10 +39,13 @@ } + + @await RenderSectionAsync("HeadMeta", required: false) +
@@ -91,5 +94,6 @@
+ diff --git a/src/OrchardCore/OrchardCore.Abstractions/Modules/Manifest/ManifestConstants.cs b/src/OrchardCore/OrchardCore.Abstractions/Modules/Manifest/ManifestConstants.cs index e01761f5c0f..e88f0584658 100644 --- a/src/OrchardCore/OrchardCore.Abstractions/Modules/Manifest/ManifestConstants.cs +++ b/src/OrchardCore/OrchardCore.Abstractions/Modules/Manifest/ManifestConstants.cs @@ -10,4 +10,9 @@ public static class ManifestConstants public const string OrchardCoreWebsite = "https://orchardcore.net"; public const string AdminTag = "Admin"; + + public static class Features + { + public const string BlazorUI = "OrchardCore.Admin.BlazorUI"; + } }