< Summary

Information
Class: Chronicis.Client.Pages.ArcDetail
Assembly: Chronicis.Client
File(s): /home/runner/work/chronicis/chronicis/src/Chronicis.Client/Pages/ArcDetail.razor
Line coverage
100%
Covered lines: 5
Uncovered lines: 0
Coverable lines: 5
Total lines: 207
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/ArcDetail.razor

#LineLine coverage
 1@attribute [Authorize]
 2@implements IDisposable
 3@using Chronicis.Shared.DTOs
 4@using Chronicis.Shared.DTOs.Quests
 5@using Chronicis.Shared.DTOs.Sessions
 6@using Chronicis.Client.Components.Dialogs
 7@using Chronicis.Client.Components.Shared
 8@using Chronicis.Client.Components.Quests
 9@inject ArcDetailViewModel ViewModel
 10@inject IAppContextService AppContext
 11
 312@if (ViewModel.IsLoading)
 13{
 14    <LoadingSkeleton />
 15}
 216else if (ViewModel.Arc != null)
 17{
 18    <MudPaper Elevation="2" Class="chronicis-article-card chronicis-fade-in">
 19        <DetailPageHeader Breadcrumbs="ViewModel.Breadcrumbs"
 20                          Icon="@Icons.Material.Filled.Bookmark"
 21                          Title="@ViewModel.EditName"
 22                          TitleChanged="@(v => ViewModel.EditName = v)"
 23                          Placeholder="Arc Name"
 24                          OnTitleEdited="@(() => {})"
 25                          OnEnterPressed="@(() => ViewModel.SaveAsync())"
 26                          ReadOnly="@(!ViewModel.CanManageArcDetails)" />
 27
 28        <MudTabs Elevation="0"
 29                 Rounded="true"
 30                 ApplyEffectsToContainer="true"
 31                 PanelClass="pa-4">
 32            <MudTabPanel Text="Overview" Icon="@Icons.Material.Filled.Bookmark">
 33                <MudTextField Value="@ViewModel.EditDescription"
 34                              ValueChanged="@((string v) => ViewModel.EditDescription = v)"
 35                              Label="Description"
 36                              Variant="Variant.Outlined"
 37                              Lines="3"
 38                              Placeholder="Describe this arc..."
 39                              Class="mb-4"
 40                              Immediate="true"
 41                              ReadOnly="@(!ViewModel.CanManageArcDetails)" />
 42
 43                <MudNumericField Value="@ViewModel.EditSortOrder"
 44                                 ValueChanged="@((int v) => ViewModel.EditSortOrder = v)"
 45                                 Label="Sort Order"
 46                                 Variant="Variant.Outlined"
 47                                 Min="0"
 48                                 Class="mb-4"
 49                                 Style="max-width: 150px;"
 50                                 Immediate="true"
 51                                 Disabled="@(!ViewModel.CanManageArcDetails)" />
 52
 53                <div class="d-flex align-center justify-space-between mb-3">
 54                    <MudText Typo="Typo.h6" Style="color: var(--chronicis-beige-gold);">
 55                        <MudIcon Icon="@Icons.Material.Filled.EventNote" Size="Size.Small" Class="mr-2" />
 56                        Sessions
 57                    </MudText>
 58                    @if (ViewModel.IsCurrentUserGM)
 59                    {
 60                        <MudButton Variant="Variant.Filled"
 61                                   Color="Color.Primary"
 62                                   Size="Size.Small"
 63                                   StartIcon="@Icons.Material.Filled.Add"
 64                                   OnClick="@(() => ViewModel.CreateSessionAsync())">
 65                            New Session
 66                        </MudButton>
 67                    }
 68                </div>
 69
 70                @if (ViewModel.Sessions.Any())
 71                {
 72                    <MudList T="SessionTreeDto" Dense="true" Class="mb-4">
 73                        @foreach (var session in ViewModel.Sessions.OrderBy(s => s.Name))
 74                        {
 75                            <EntityListItem Icon="@Icons.Material.Filled.EventNote"
 76                                            Title="@(string.IsNullOrEmpty(session.Name) ? "Untitled Session" : session.N
 77                                            OnClick="@(() => ViewModel.NavigateToSessionAsync(session))" />
 78                        }
 79                    </MudList>
 80                }
 81                else
 82                {
 83                    <MudAlert Severity="Severity.Info" Class="mb-4">
 84                        No sessions yet. Create your first session to start documenting your adventures!
 85                    </MudAlert>
 86                }
 87
 88                <ArcQuestList ArcId="@ArcId" IsGm="ViewModel.IsCurrentUserGM" OnEditQuest="ViewModel.OnEditQuest" />
 89
 90                @if (ViewModel.SelectedQuest != null)
 91                {
 92                    <MudDivider Class="my-4" />
 93                    <ArcQuestEditor Quest="ViewModel.SelectedQuest"
 94                                    OnQuestUpdated="ViewModel.OnQuestUpdated" />
 95                    <ArcQuestTimeline Quest="ViewModel.SelectedQuest"
 96                                      IsGm="ViewModel.IsCurrentUserGM"
 97                                      CurrentUserId="ViewModel.CurrentUserId" />
 98                }
 99
 100                <MudText Typo="Typo.h6" Class="mb-3" Style="color: var(--chronicis-beige-gold);">
 101                    Arc Info
 102                </MudText>
 103
 104                <MudSimpleTable Dense="true" Hover="true" Class="mb-4">
 105                    <tbody>
 106                        <tr>
 107                            <td><MudIcon Icon="@Icons.Material.Filled.PlayCircle" Size="Size.Small" Class="mr-2" />Activ
 108                            <td>
 109                                <MudSwitch T="bool"
 110                                           Value="ViewModel.Arc.IsActive"
 111                                           ValueChanged="@((bool v) => ViewModel.OnActiveToggleAsync(v))"
 112                                           Color="Color.Success"
 113                                           Size="Size.Small"
 114                                           Disabled="@(ViewModel.IsTogglingActive || !ViewModel.CanManageArcDetails)" />
 115                            </td>
 116                        </tr>
 117                        <tr>
 118                            <td><MudIcon Icon="@Icons.Material.Filled.EventNote" Size="Size.Small" Class="mr-2" />Sessio
 119                            <td>@ViewModel.Arc.SessionCount</td>
 120                        </tr>
 121                        <tr>
 122                            <td><MudIcon Icon="@Icons.Material.Filled.Sort" Size="Size.Small" Class="mr-2" />Sort Order<
 123                            <td>@ViewModel.Arc.SortOrder</td>
 124                        </tr>
 125                        <tr>
 126                            <td><MudIcon Icon="@Icons.Material.Filled.CalendarToday" Size="Size.Small" Class="mr-2" />Cr
 127                            <td>@ViewModel.Arc.CreatedAt.ToString("MMMM d, yyyy")</td>
 128                        </tr>
 129                    </tbody>
 130                </MudSimpleTable>
 131
 132                <AISummarySection EntityId="ArcId"
 133                                  EntityType="Arc"
 134                                  IsExpanded="ViewModel.SummaryExpanded"
 135                                  IsExpandedChanged="@((bool v) => ViewModel.SummaryExpanded = v)" />
 136            </MudTabPanel>
 137
 138            @if (ViewModel.CanViewPrivateNotes)
 139            {
 140                <MudTabPanel Text="Private Notes" Icon="@Icons.Material.Filled.Lock">
 141                    <MudText Typo="Typo.body2" Class="mud-text-secondary mb-3">
 142                        Visible only to the world owner and GMs.
 143                    </MudText>
 144                    <PrivateNotesTipTapEditor WorldId="@ViewModel.Campaign!.WorldId"
 145                                             Value="@ViewModel.EditPrivateNotes"
 146                                             ValueChanged="@((string v) => ViewModel.EditPrivateNotes = v)"
 147                                             ReadOnly="@(!ViewModel.CanManageArcDetails)"
 148                                             UploadContextLabel="arc private notes" />
 149                </MudTabPanel>
 150            }
 151        </MudTabs>
 152
 153        <div class="chronicis-flex-between mt-4">
 154            <SaveStatusIndicator IsSaving="ViewModel.IsSaving" HasUnsavedChanges="ViewModel.HasUnsavedChanges" />
 155
 156            <div class="d-flex gap-2">
 157                           <MudButton Variant="Variant.Filled"
 158                                       Color="Color.Primary"
 159                                       OnClick="@(() => ViewModel.SaveAsync())"
 160                                       Disabled="@(ViewModel.IsSaving || !ViewModel.CanManageArcDetails)"
 161                                       StartIcon="@Icons.Material.Filled.Save">
 162                    Save
 163                </MudButton>
 164
 165                <MudButton Variant="Variant.Outlined"
 166                           Color="Color.Error"
 167                           OnClick="@(() => ViewModel.DeleteAsync())"
 168                           Disabled="@(ViewModel.IsSaving || ViewModel.Sessions.Any() || !ViewModel.IsCurrentUserGM)"
 169                           StartIcon="@Icons.Material.Filled.Delete">
 170                    Delete
 171                </MudButton>
 172            </div>
 173        </div>
 174
 175        @if (ViewModel.Sessions.Any())
 176        {
 177            <MudText Typo="Typo.caption" Class="mt-2" Style="color: var(--mud-palette-text-secondary);">
 178                Delete all sessions before deleting this arc.
 179            </MudText>
 180        }
 181    </MudPaper>
 182}
 183
 184@code {
 185    [Parameter]
 186    public Guid ArcId { get; set; }
 187
 188    protected override async Task OnParametersSetAsync()
 189    {
 190        ViewModel.PropertyChanged += OnViewModelChanged;
 191        await ViewModel.LoadAsync(ArcId);
 192
 193        if (ViewModel.Campaign != null &&
 194            (AppContext.CurrentWorldId != ViewModel.Campaign.WorldId || AppContext.CurrentCampaignId != ViewModel.Campai
 195        {
 196            await AppContext.SelectWorldAsync(ViewModel.Campaign.WorldId, ViewModel.Campaign.Id);
 197        }
 198    }
 199
 200    private void OnViewModelChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
 17201        => InvokeAsync(StateHasChanged);
 202
 203    public void Dispose()
 204    {
 3205        ViewModel.PropertyChanged -= OnViewModelChanged;
 3206    }
 207}