< Summary

Information
Class: Chronicis.Client.Components.Articles.BacklinksPanel
Assembly: Chronicis.Client
File(s): /home/runner/work/chronicis/chronicis/src/Chronicis.Client/Components/Articles/BacklinksPanel.razor
Line coverage
100%
Covered lines: 10
Uncovered lines: 0
Coverable lines: 10
Total lines: 125
Line coverage: 100%
Branch coverage
100%
Covered branches: 8
Total branches: 8
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
BuildRenderTree(...)100%88100%
get_Backlinks()100%11100%
get_IsLoading()100%11100%
get_OnNavigateToArticle()100%11100%

File(s)

/home/runner/work/chronicis/chronicis/src/Chronicis.Client/Components/Articles/BacklinksPanel.razor

#LineLine coverage
 1@using Chronicis.Shared.DTOs
 2
 3@* Refactored BacklinksPanel - Now accepts data as parameters instead of fetching directly *@
 4
 5<div class="links-panel">
 6    <div class="links-panel-header">
 7        <span class="links-panel-title">Links From</span>
 88        @if (IsLoading)
 9        {
 10            <span class="links-panel-loading">...</span>
 11        }
 812        <span class="links-panel-count">@Backlinks.Count</span>
 13    </div>
 14
 815    @if (Backlinks.Any())
 16    {
 17        <div class="links-chip-container">
 3018            @foreach (var backlink in Backlinks)
 19            {
 20                <span class="link-chip"
 121                      @onclick="() => OnNavigateToArticle.InvokeAsync(backlink.ArticleId)"
 22                      title="@backlink.DisplayPath">
 923                    @backlink.Title
 24                </span>
 25            }
 26        </div>
 27    }
 228    else if (!IsLoading)
 29    {
 30        <div class="links-panel-empty">No incoming links</div>
 31    }
 32</div>
 33
 34@code {
 35    /// <summary>
 36    /// The list of backlinks to display.
 37    /// Parent component is responsible for loading this data.
 38    /// </summary>
 39    [Parameter, EditorRequired]
 3640    public List<BacklinkDto> Backlinks { get; set; } = new();
 41
 42    /// <summary>
 43    /// Whether data is currently being loaded.
 44    /// Controls the loading indicator display.
 45    /// </summary>
 46    [Parameter]
 1247    public bool IsLoading { get; set; }
 48
 49    /// <summary>
 50    /// Callback when user clicks a backlink.
 51    /// Parent handles the navigation logic.
 52    /// </summary>
 53    [Parameter]
 254    public EventCallback<Guid> OnNavigateToArticle { get; set; }
 55}
 56
 57<style>
 58.links-panel {
 59    padding: 12px 16px;
 60}
 61
 62.links-panel-header {
 63    display: flex;
 64    align-items: center;
 65    gap: 8px;
 66    margin-bottom: 10px;
 67}
 68
 69.links-panel-title {
 70    font-size: 13px;
 71    font-weight: 600;
 72    color: var(--mud-palette-text-secondary);
 73    text-transform: uppercase;
 74    letter-spacing: 0.5px;
 75}
 76
 77.links-panel-loading {
 78    font-size: 12px;
 79    color: #C4AF8E;
 80}
 81
 82.links-panel-count {
 83    font-size: 11px;
 84    background: rgba(196, 175, 142, 0.2);
 85    color: var(--mud-palette-text-secondary);
 86    padding: 2px 6px;
 87    border-radius: 10px;
 88    margin-left: auto;
 89}
 90
 91.links-chip-container {
 92    display: flex;
 93    flex-wrap: wrap;
 94    gap: 6px;
 95}
 96
 97.link-chip {
 98    display: inline-block;
 99    padding: 4px 10px;
 100    font-size: 12px;
 101    background: rgba(196, 175, 142, 0.1);
 102    border: 1px solid rgba(196, 175, 142, 0.25);
 103    border-radius: 12px;
 104    color: var(--mud-palette-text-primary);
 105    cursor: pointer;
 106    transition: all 0.15s ease;
 107    max-width: 150px;
 108    overflow: hidden;
 109    text-overflow: ellipsis;
 110    white-space: nowrap;
 111}
 112
 113.link-chip:hover {
 114    background: rgba(196, 175, 142, 0.25);
 115    border-color: rgba(196, 175, 142, 0.5);
 116    color: #C4AF8E;
 117}
 118
 119.links-panel-empty {
 120    font-size: 12px;
 121    color: var(--mud-palette-text-secondary);
 122    opacity: 0.6;
 123    font-style: italic;
 124}
 125</style>