Compare commits
3 Commits
9b9272cd6e
...
94c1aac0ac
| Author | SHA1 | Date | |
|---|---|---|---|
| 94c1aac0ac | |||
| 3bddd64d91 | |||
| 5ad7a6db7b |
26
Moonlight.Frontend/Configuration/LayoutMiddlewareOptions.cs
Normal file
26
Moonlight.Frontend/Configuration/LayoutMiddlewareOptions.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Moonlight.Frontend.Interfaces;
|
||||
|
||||
namespace Moonlight.Frontend.Configuration;
|
||||
|
||||
public class LayoutMiddlewareOptions
|
||||
{
|
||||
public IReadOnlyList<Type> Components => InnerComponents;
|
||||
|
||||
private readonly List<Type> InnerComponents = new();
|
||||
|
||||
public void Add<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>() where T : LayoutMiddlewareBase
|
||||
{
|
||||
InnerComponents.Add(typeof(T));
|
||||
}
|
||||
|
||||
public void Insert<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>(int index) where T : LayoutMiddlewareBase
|
||||
{
|
||||
InnerComponents.Insert(index, typeof(T));
|
||||
}
|
||||
|
||||
public void Remove<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>() where T : LayoutMiddlewareBase
|
||||
{
|
||||
InnerComponents.Remove(typeof(T));
|
||||
}
|
||||
}
|
||||
33
Moonlight.Frontend/Configuration/LayoutPageOptions.cs
Normal file
33
Moonlight.Frontend/Configuration/LayoutPageOptions.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace Moonlight.Frontend.Configuration;
|
||||
|
||||
public class LayoutPageOptions
|
||||
{
|
||||
public IReadOnlyList<LayoutPageComponent> Components => InnerComponents;
|
||||
|
||||
private readonly List<LayoutPageComponent> InnerComponents = new();
|
||||
|
||||
public void Add<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>(LayoutPageSlot slot, int order)
|
||||
where T : ComponentBase
|
||||
=> Add(typeof(T), slot, order);
|
||||
|
||||
public void Add(Type componentType, LayoutPageSlot slot, int order)
|
||||
=> InnerComponents.Add(new LayoutPageComponent(componentType, order, slot));
|
||||
|
||||
public void Remove<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>()
|
||||
where T : ComponentBase
|
||||
=> Remove(typeof(T));
|
||||
|
||||
public void Remove(Type componentType)
|
||||
=> InnerComponents.RemoveAll(x => x.ComponentType == componentType);
|
||||
}
|
||||
|
||||
public record LayoutPageComponent(Type ComponentType, int Order, LayoutPageSlot Slot);
|
||||
|
||||
public enum LayoutPageSlot
|
||||
{
|
||||
Header = 0,
|
||||
Footer = 1
|
||||
}
|
||||
8
Moonlight.Frontend/Interfaces/LayoutMiddlewareBase.cs
Normal file
8
Moonlight.Frontend/Interfaces/LayoutMiddlewareBase.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace Moonlight.Frontend.Interfaces;
|
||||
|
||||
public abstract class LayoutMiddlewareBase : ComponentBase
|
||||
{
|
||||
[Parameter] public RenderFragment ChildContent { get; set; }
|
||||
}
|
||||
@@ -9,6 +9,10 @@
|
||||
@using ShadcnBlazor.Emptys
|
||||
@using Moonlight.Frontend.UI.Shared.Components.Auth
|
||||
@using Moonlight.Frontend.UI.Shared.Partials
|
||||
@using ShadcnBlazor.Extras.AlertDialogs
|
||||
@using ShadcnBlazor.Extras.Dialogs
|
||||
@using ShadcnBlazor.Extras.Toasts
|
||||
@using ShadcnBlazor.Portals
|
||||
|
||||
@inject NavigationManager Navigation
|
||||
@inject IOptions<NavigationAssemblyOptions> NavigationOptions
|
||||
@@ -17,15 +21,23 @@
|
||||
<ChildContent>
|
||||
<AuthorizeView>
|
||||
<ChildContent>
|
||||
<Router AppAssembly="@typeof(App).Assembly" AdditionalAssemblies="Assemblies" NotFoundPage="typeof(NotFound)">
|
||||
<Found Context="routeData">
|
||||
<AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)">
|
||||
<NotAuthorized Context="authRouteViewContext">
|
||||
<AccessDenied/>
|
||||
</NotAuthorized>
|
||||
</AuthorizeRouteView>
|
||||
</Found>
|
||||
</Router>
|
||||
<LayoutMiddleware>
|
||||
<Router AppAssembly="@typeof(App).Assembly" AdditionalAssemblies="Assemblies" NotFoundPage="typeof(NotFound)">
|
||||
<Found Context="routeData">
|
||||
<AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)">
|
||||
<NotAuthorized Context="authRouteViewContext">
|
||||
<AccessDenied/>
|
||||
</NotAuthorized>
|
||||
</AuthorizeRouteView>
|
||||
</Found>
|
||||
</Router>
|
||||
</LayoutMiddleware>
|
||||
|
||||
<ToastLauncher/>
|
||||
<DialogLauncher/>
|
||||
<AlertDialogLauncher/>
|
||||
|
||||
<PortalOutlet />
|
||||
</ChildContent>
|
||||
<Authorizing>
|
||||
<Authenticating/>
|
||||
|
||||
34
Moonlight.Frontend/UI/Shared/LayoutMiddleware.razor
Normal file
34
Moonlight.Frontend/UI/Shared/LayoutMiddleware.razor
Normal file
@@ -0,0 +1,34 @@
|
||||
@using Microsoft.Extensions.Options
|
||||
@using Moonlight.Frontend.Configuration
|
||||
@using Moonlight.Frontend.Interfaces
|
||||
|
||||
@inject IOptions<LayoutMiddlewareOptions> Options
|
||||
|
||||
@Chain
|
||||
|
||||
@code
|
||||
{
|
||||
[Parameter] public RenderFragment ChildContent { get; set; }
|
||||
|
||||
private RenderFragment Chain;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
Chain = ChildContent;
|
||||
|
||||
foreach (var component in Options.Value.Components)
|
||||
{
|
||||
// Capture current values
|
||||
var currentChain = Chain;
|
||||
var currentComponent = component;
|
||||
|
||||
Chain = builder =>
|
||||
{
|
||||
builder.OpenComponent(0, currentComponent);
|
||||
builder.SetKey(component);
|
||||
builder.AddComponentParameter(1, nameof(LayoutMiddlewareBase.ChildContent), currentChain);
|
||||
builder.CloseComponent();
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +1,53 @@
|
||||
@using ShadcnBlazor.Extras.AlertDialogs
|
||||
@using Microsoft.Extensions.Options
|
||||
@using Moonlight.Frontend.Configuration
|
||||
@using ShadcnBlazor.Extras.Alerts
|
||||
@using ShadcnBlazor.Extras.Dialogs
|
||||
@using ShadcnBlazor.Extras.Toasts
|
||||
@using ShadcnBlazor.Portals
|
||||
@using ShadcnBlazor.Sidebars
|
||||
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
@inject IOptions<LayoutPageOptions> LayoutPageOptions
|
||||
|
||||
<SidebarProvider DefaultOpen="true">
|
||||
<AppSidebar/>
|
||||
|
||||
<SidebarInset>
|
||||
<AppHeader/>
|
||||
|
||||
@foreach (var headerComponent in HeaderComponents)
|
||||
{
|
||||
<DynamicComponent Type="headerComponent" />
|
||||
}
|
||||
|
||||
<div class="mx-8 my-8 max-w-full">
|
||||
<AlertLauncher/>
|
||||
|
||||
@Body
|
||||
</div>
|
||||
|
||||
<ToastLauncher/>
|
||||
<DialogLauncher/>
|
||||
<AlertDialogLauncher/>
|
||||
|
||||
<PortalOutlet />
|
||||
@foreach (var footerComponent in FooterComponents)
|
||||
{
|
||||
<DynamicComponent Type="footerComponent" />
|
||||
}
|
||||
</SidebarInset>
|
||||
</SidebarProvider>
|
||||
</SidebarProvider>
|
||||
|
||||
@code
|
||||
{
|
||||
private Type[] HeaderComponents;
|
||||
private Type[] FooterComponents;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
HeaderComponents = LayoutPageOptions.Value.Components
|
||||
.Where(x => x.Slot == LayoutPageSlot.Header)
|
||||
.OrderBy(x => x.Order)
|
||||
.Select(x => x.ComponentType)
|
||||
.ToArray();
|
||||
|
||||
FooterComponents = LayoutPageOptions.Value.Components
|
||||
.Where(x => x.Slot == LayoutPageSlot.Footer)
|
||||
.OrderBy(x => x.Order)
|
||||
.Select(x => x.ComponentType)
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user