< Summary

Information
Class: Chronicis.Client.Pages.CampaignDetail
Assembly: Chronicis.Client
File(s): /home/runner/work/chronicis/chronicis/src/Chronicis.Client/Pages/CampaignDetail.razor
Line coverage
100%
Covered lines: 5
Uncovered lines: 0
Coverable lines: 5
Total lines: 176
Line coverage: 100%
Branch coverage
100%
Covered branches: 4
Total branches: 4
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%44100%
OnViewModelChanged(...)100%11100%
Dispose()100%11100%

File(s)

/home/runner/work/chronicis/chronicis/src/Chronicis.Client/Pages/CampaignDetail.razor

#LineLine coverage
 1@page "/campaign/{CampaignId:guid}"
 2@attribute [Authorize]
 3@implements IDisposable
 4@using Chronicis.Client.Components.Dialogs
 5@using Chronicis.Client.Components.Shared
 6@inject CampaignDetailViewModel ViewModel
 7@inject IAppContextService AppContext
 8
 39@if (ViewModel.IsLoading)
 10{
 11    <LoadingSkeleton />
 12}
 213else if (ViewModel.Campaign != null)
 14{
 15    <MudPaper Elevation="2" Class="chronicis-article-card chronicis-fade-in">
 16        <DetailPageHeader Breadcrumbs="ViewModel.Breadcrumbs"
 17                          Icon="@Icons.Material.Filled.AutoStories"
 18                          Title="@ViewModel.EditName"
 19                          TitleChanged="@(v => ViewModel.EditName = v)"
 20                          Placeholder="Campaign Name"
 21                          OnTitleEdited="@(() => {})"
 22                          OnEnterPressed="@(() => ViewModel.SaveAsync())"
 23                          ReadOnly="@(!ViewModel.CanManageCampaignDetails)" />
 24
 25        <MudTabs Elevation="0"
 26                 Rounded="true"
 27                 ApplyEffectsToContainer="true"
 28                 PanelClass="pa-4">
 29            <MudTabPanel Text="Overview" Icon="@Icons.Material.Filled.AutoStories">
 30                <MudTextField Value="@ViewModel.EditDescription"
 31                              ValueChanged="@((string v) => ViewModel.EditDescription = v)"
 32                              Label="Description"
 33                              Variant="Variant.Outlined"
 34                              Lines="3"
 35                              Placeholder="Describe your campaign..."
 36                              Class="mb-4"
 37                              Immediate="true"
 38                              ReadOnly="@(!ViewModel.CanManageCampaignDetails)" />
 39
 40                <div class="d-flex align-center justify-space-between mb-3">
 41                    <MudText Typo="Typo.h6" Style="color: var(--chronicis-beige-gold);">
 42                        <MudIcon Icon="@Icons.Material.Filled.Bookmark" Size="Size.Small" Class="mr-2" />
 43                        Arcs / Acts
 44                    </MudText>
 45                    @if (ViewModel.IsCurrentUserGM)
 46                    {
 47                        <MudButton Variant="Variant.Filled"
 48                                   Color="Color.Primary"
 49                                   Size="Size.Small"
 50                                   StartIcon="@Icons.Material.Filled.Add"
 51                                   OnClick="@(() => ViewModel.CreateArcAsync())">
 52                            New Arc
 53                        </MudButton>
 54                    }
 55                </div>
 56
 57                @if (ViewModel.Arcs.Any())
 58                {
 59                    <MudList T="ArcDto" Dense="true" Class="mb-4">
 60                        @foreach (var arc in ViewModel.Arcs.OrderBy(a => a.SortOrder))
 61                        {
 62                            <EntityListItem Icon="@Icons.Material.Filled.Bookmark"
 63                                            Title="@arc.Name"
 64                                            OnClick="@(() => ViewModel.NavigateToArc(arc.Id))">
 65                                <MudChip T="string" Size="Size.Small" Variant="Variant.Outlined">
 66                                    @arc.SessionCount sessions
 67                                </MudChip>
 68                            </EntityListItem>
 69                        }
 70                    </MudList>
 71                }
 72                else
 73                {
 74                    <MudAlert Severity="Severity.Info" Class="mb-4">
 75                        No arcs yet. Create your first arc to organize your sessions!
 76                    </MudAlert>
 77                }
 78
 79                <MudText Typo="Typo.h6" Class="mb-3" Style="color: var(--chronicis-beige-gold);">
 80                    Campaign Info
 81                </MudText>
 82
 83                <MudSimpleTable Dense="true" Hover="true" Class="mb-4">
 84                    <tbody>
 85                        <tr>
 86                            <td><MudIcon Icon="@Icons.Material.Filled.PlayCircle" Size="Size.Small" Class="mr-2" />Activ
 87                            <td>
 88                                <MudSwitch T="bool"
 89                                           Value="ViewModel.Campaign.IsActive"
 90                                           ValueChanged="@((bool v) => ViewModel.OnActiveToggleAsync(v))"
 91                                           Color="Color.Success"
 92                                           Size="Size.Small"
 93                                           Disabled="@(ViewModel.IsTogglingActive || !ViewModel.CanManageCampaignDetails
 94                            </td>
 95                        </tr>
 96                        <tr>
 97                            <td><MudIcon Icon="@Icons.Material.Filled.Layers" Size="Size.Small" Class="mr-2" />Arcs</td>
 98                            <td>@ViewModel.Campaign.ArcCount</td>
 99                        </tr>
 100                        <tr>
 101                            <td><MudIcon Icon="@Icons.Material.Filled.Person" Size="Size.Small" Class="mr-2" />Owner</td
 102                            <td>@ViewModel.Campaign.OwnerName</td>
 103                        </tr>
 104                        <tr>
 105                            <td><MudIcon Icon="@Icons.Material.Filled.CalendarToday" Size="Size.Small" Class="mr-2" />Cr
 106                            <td>@ViewModel.Campaign.CreatedAt.ToString("MMMM d, yyyy")</td>
 107                        </tr>
 108                        @if (ViewModel.Campaign.StartedAt.HasValue)
 109                        {
 110                            <tr>
 111                                <td><MudIcon Icon="@Icons.Material.Filled.PlayArrow" Size="Size.Small" Class="mr-2" />St
 112                                <td>@ViewModel.Campaign.StartedAt.Value.ToString("MMMM d, yyyy")</td>
 113                            </tr>
 114                        }
 115                    </tbody>
 116                </MudSimpleTable>
 117
 118                <AISummarySection EntityId="CampaignId"
 119                                  EntityType="Campaign"
 120                                  IsExpanded="ViewModel.SummaryExpanded"
 121                                  IsExpandedChanged="@((bool v) => ViewModel.SummaryExpanded = v)" />
 122            </MudTabPanel>
 123
 124            @if (ViewModel.CanViewPrivateNotes)
 125            {
 126                <MudTabPanel Text="Private Notes" Icon="@Icons.Material.Filled.Lock">
 127                    <MudText Typo="Typo.body2" Class="mud-text-secondary mb-3">
 128                        Visible only to the world owner and GMs.
 129                    </MudText>
 130                    <PrivateNotesTipTapEditor WorldId="@ViewModel.Campaign!.WorldId"
 131                                             Value="@ViewModel.EditPrivateNotes"
 132                                             ValueChanged="@((string v) => ViewModel.EditPrivateNotes = v)"
 133                                             ReadOnly="@(!ViewModel.CanManageCampaignDetails)"
 134                                             UploadContextLabel="campaign private notes" />
 135                </MudTabPanel>
 136            }
 137        </MudTabs>
 138
 139        <div class="chronicis-flex-between mt-4">
 140            <SaveStatusIndicator IsSaving="ViewModel.IsSaving" HasUnsavedChanges="ViewModel.HasUnsavedChanges" />
 141
 142            <MudButton Variant="Variant.Filled"
 143                       Color="Color.Primary"
 144                       OnClick="@(() => ViewModel.SaveAsync())"
 145                       Disabled="@(ViewModel.IsSaving || !ViewModel.CanManageCampaignDetails)"
 146                       StartIcon="@Icons.Material.Filled.Save">
 147                Save
 148            </MudButton>
 149        </div>
 150    </MudPaper>
 151}
 152
 153@code {
 154    [Parameter]
 155    public Guid CampaignId { get; set; }
 156
 157    protected override async Task OnParametersSetAsync()
 158    {
 159        ViewModel.PropertyChanged += OnViewModelChanged;
 160        await ViewModel.LoadAsync(CampaignId);
 161
 162        if (ViewModel.Campaign != null &&
 163            (AppContext.CurrentWorldId != ViewModel.Campaign.WorldId || AppContext.CurrentCampaignId != ViewModel.Campai
 164        {
 165            await AppContext.SelectWorldAsync(ViewModel.Campaign.WorldId, ViewModel.Campaign.Id);
 166        }
 167    }
 168
 169    private void OnViewModelChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
 15170        => InvokeAsync(StateHasChanged);
 171
 172    public void Dispose()
 173    {
 3174        ViewModel.PropertyChanged -= OnViewModelChanged;
 3175    }
 176}