< Summary

Information
Class: Chronicis.Client.Components.Routing.ChronicisRouteView
Assembly: Chronicis.Client
File(s): /home/runner/work/chronicis/chronicis/src/Chronicis.Client/Components/Routing/ChronicisRouteView.razor
Line coverage
100%
Covered lines: 51
Uncovered lines: 0
Coverable lines: 51
Total lines: 96
Line coverage: 100%
Branch coverage
100%
Covered branches: 6
Total branches: 6
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
RenderPageWithLayout()100%11100%
RenderPageComponent(...)100%22100%
DetermineLayoutType(...)100%44100%

File(s)

/home/runner/work/chronicis/chronicis/src/Chronicis.Client/Components/Routing/ChronicisRouteView.razor

#LineLine coverage
 1@using Microsoft.AspNetCore.Components.Authorization
 2@using Microsoft.AspNetCore.Components.Routing
 3@using Microsoft.AspNetCore.Components.Rendering
 4@using Microsoft.AspNetCore.Authorization
 5
 6@*
 7    ChronicisRouteView - Custom route view that prevents layout flicker
 8
 9    This component intelligently determines which layout to use based on:
 10    1. Explicit @layout directive on the page (public pages with PublicLayout)
 11    2. [Authorize] attribute (authenticated pages get AuthenticatedLayout)
 12    3. Default to PublicLayout for pages without explicit layout or auth
 13
 14    This prevents the "flash" of AuthenticatedLayout on public pages.
 15
 16    It also provides a styled "Authorizing" screen instead of the default
 17    unstyled "Authorizing..." text.
 18*@
 19
 20<CascadingAuthenticationState>
 21    @RenderPageWithLayout()
 22</CascadingAuthenticationState>
 23
 24@code {
 25    [Parameter]
 26    public RouteData RouteData { get; set; } = default!;
 27
 428    private RenderFragment RenderPageWithLayout() => builder =>
 429    {
 430        var pageType = RouteData.PageType;
 431        var layoutType = DetermineLayoutType(pageType);
 432        var requiresAuth = pageType.GetCustomAttributes(typeof(AuthorizeAttribute), true).Any();
 433
 434        // DetermineLayoutType always returns a concrete layout.
 435        builder.OpenComponent<LayoutView>(0);
 436        builder.AddAttribute(1, "Layout", layoutType);
 437        builder.AddAttribute(2, "ChildContent", (RenderFragment)(contentBuilder =>
 438        {
 439            if (requiresAuth)
 440            {
 441                // Use AuthorizeRouteView for pages with [Authorize]
 442                contentBuilder.OpenComponent<AuthorizeRouteView>(0);
 443                contentBuilder.AddAttribute(1, "RouteData", RouteData);
 444                contentBuilder.AddAttribute(2, "Authorizing", (RenderFragment)(authorizingBuilder =>
 445                {
 446                    authorizingBuilder.OpenComponent<AuthorizingScreen>(0);
 447                    authorizingBuilder.CloseComponent();
 448                }));
 449                contentBuilder.AddAttribute(3, "NotAuthorized", (RenderFragment<AuthenticationState>)(authState =>
 450                {
 451                    return notAuthBuilder =>
 452                    {
 453                        notAuthBuilder.OpenComponent<RedirectToLogin>(0);
 454                        notAuthBuilder.CloseComponent();
 455                    };
 456                }));
 457                contentBuilder.CloseComponent();
 458            }
 459            else
 460            {
 461                // Render public page directly
 462                RenderPageComponent(contentBuilder, pageType, RouteData);
 463            }
 464        }));
 465        builder.CloseComponent();
 466    };
 67
 68    private void RenderPageComponent(RenderTreeBuilder builder, Type pageType, RouteData routeData)
 69    {
 270        builder.OpenComponent(0, pageType);
 671        foreach (var kvp in routeData.RouteValues)
 72        {
 173            builder.AddAttribute(1, kvp.Key, kvp.Value);
 74        }
 275        builder.CloseComponent();
 276    }
 77
 78    private Type DetermineLayoutType(Type pageType)
 79    {
 80        // Check if page has explicit @layout directive
 781        var layoutAttribute = pageType.GetCustomAttributes(typeof(LayoutAttribute), true)
 782            .OfType<LayoutAttribute>()
 783            .FirstOrDefault();
 84
 785        if (layoutAttribute != null)
 86        {
 587            return layoutAttribute.LayoutType;
 88        }
 89
 90        // Check if page requires authentication
 291        var requiresAuth = pageType.GetCustomAttributes(typeof(AuthorizeAttribute), true).Any();
 92
 93        // Default to AuthenticatedLayout for pages requiring auth, PublicLayout otherwise
 294        return requiresAuth ? typeof(AuthenticatedLayout) : typeof(PublicLayout);
 95    }
 96}