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 ShadcnBlazor.Emptys
|
||||||
@using Moonlight.Frontend.UI.Shared.Components.Auth
|
@using Moonlight.Frontend.UI.Shared.Components.Auth
|
||||||
@using Moonlight.Frontend.UI.Shared.Partials
|
@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 NavigationManager Navigation
|
||||||
@inject IOptions<NavigationAssemblyOptions> NavigationOptions
|
@inject IOptions<NavigationAssemblyOptions> NavigationOptions
|
||||||
@@ -17,15 +21,23 @@
|
|||||||
<ChildContent>
|
<ChildContent>
|
||||||
<AuthorizeView>
|
<AuthorizeView>
|
||||||
<ChildContent>
|
<ChildContent>
|
||||||
<Router AppAssembly="@typeof(App).Assembly" AdditionalAssemblies="Assemblies" NotFoundPage="typeof(NotFound)">
|
<LayoutMiddleware>
|
||||||
<Found Context="routeData">
|
<Router AppAssembly="@typeof(App).Assembly" AdditionalAssemblies="Assemblies" NotFoundPage="typeof(NotFound)">
|
||||||
<AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)">
|
<Found Context="routeData">
|
||||||
<NotAuthorized Context="authRouteViewContext">
|
<AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)">
|
||||||
<AccessDenied/>
|
<NotAuthorized Context="authRouteViewContext">
|
||||||
</NotAuthorized>
|
<AccessDenied/>
|
||||||
</AuthorizeRouteView>
|
</NotAuthorized>
|
||||||
</Found>
|
</AuthorizeRouteView>
|
||||||
</Router>
|
</Found>
|
||||||
|
</Router>
|
||||||
|
</LayoutMiddleware>
|
||||||
|
|
||||||
|
<ToastLauncher/>
|
||||||
|
<DialogLauncher/>
|
||||||
|
<AlertDialogLauncher/>
|
||||||
|
|
||||||
|
<PortalOutlet />
|
||||||
</ChildContent>
|
</ChildContent>
|
||||||
<Authorizing>
|
<Authorizing>
|
||||||
<Authenticating/>
|
<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.Alerts
|
||||||
@using ShadcnBlazor.Extras.Dialogs
|
|
||||||
@using ShadcnBlazor.Extras.Toasts
|
|
||||||
@using ShadcnBlazor.Portals
|
|
||||||
@using ShadcnBlazor.Sidebars
|
@using ShadcnBlazor.Sidebars
|
||||||
|
|
||||||
@inherits LayoutComponentBase
|
@inherits LayoutComponentBase
|
||||||
|
|
||||||
|
@inject IOptions<LayoutPageOptions> LayoutPageOptions
|
||||||
|
|
||||||
<SidebarProvider DefaultOpen="true">
|
<SidebarProvider DefaultOpen="true">
|
||||||
<AppSidebar/>
|
<AppSidebar/>
|
||||||
|
|
||||||
<SidebarInset>
|
<SidebarInset>
|
||||||
<AppHeader/>
|
<AppHeader/>
|
||||||
|
|
||||||
|
@foreach (var headerComponent in HeaderComponents)
|
||||||
|
{
|
||||||
|
<DynamicComponent Type="headerComponent" />
|
||||||
|
}
|
||||||
|
|
||||||
<div class="mx-8 my-8 max-w-full">
|
<div class="mx-8 my-8 max-w-full">
|
||||||
<AlertLauncher/>
|
<AlertLauncher/>
|
||||||
|
|
||||||
@Body
|
@Body
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ToastLauncher/>
|
|
||||||
<DialogLauncher/>
|
|
||||||
<AlertDialogLauncher/>
|
|
||||||
|
|
||||||
<PortalOutlet />
|
@foreach (var footerComponent in FooterComponents)
|
||||||
|
{
|
||||||
|
<DynamicComponent Type="footerComponent" />
|
||||||
|
}
|
||||||
</SidebarInset>
|
</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