< Summary

Information
Class: Chronicis.Client.Components.Settings.DataManagementSection
Assembly: Chronicis.Client
File(s): /home/runner/work/chronicis/chronicis/src/Chronicis.Client/Components/Settings/DataManagementSection.razor
Line coverage
0%
Covered lines: 0
Uncovered lines: 36
Coverable lines: 36
Total lines: 155
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 26
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
BuildRenderTree(...)0%156120%
get_WorldApi()100%210%
get_ExportApi()100%210%
get_Snackbar()100%210%
.ctor()100%210%
OnInitializedAsync()0%2040%
ExportWorld()0%2040%

File(s)

/home/runner/work/chronicis/chronicis/src/Chronicis.Client/Components/Settings/DataManagementSection.razor

#LineLine coverage
 1@using Chronicis.Shared.DTOs
 2
 3<!-- Export Section -->
 4<div class="mb-6">
 5    <MudText Typo="Typo.subtitle2" Color="Color.Primary" Class="mb-2" Style="font-weight: 600;">
 6        Export World Data
 7    </MudText>
 8    <MudText Typo="Typo.body2" Class="mud-text-secondary mb-4">
 9        Download all articles, sessions, and notes from a world as a zip archive
 10        containing organized Markdown files. Great for backups or migrating to other tools.
 11    </MudText>
 12
 013    @if (_isLoadingWorlds)
 14    {
 15        <MudProgressLinear Indeterminate="true" Color="Color.Primary" Class="mb-3" />
 16    }
 017    else if (_worlds == null || !_worlds.Any())
 18    {
 19        <MudAlert Severity="Severity.Info" Dense="true" Variant="Variant.Outlined">
 20            You don't have any worlds to export yet. Create a world first!
 21        </MudAlert>
 22    }
 23    else
 24    {
 25        <div class="d-flex flex-column flex-sm-row gap-3 align-start">
 26            <MudSelect T="WorldDto"
 27                       @bind-Value="_selectedWorld"
 28                       Label="Select World"
 29                       Variant="Variant.Outlined"
 30                       AnchorOrigin="Origin.BottomCenter"
 31                       Dense="true"
 32                       Style="min-width: 280px;">
 033                @foreach (var world in _worlds)
 34                {
 035                    <MudSelectItem Value="@world">@world.Name</MudSelectItem>
 36                }
 37            </MudSelect>
 38
 39            <MudButton Variant="Variant.Filled"
 40                       Color="Color.Primary"
 41                       StartIcon="@Icons.Material.Filled.Download"
 42                       OnClick="ExportWorld"
 43                       Disabled="@(_selectedWorld == null || _isExporting)">
 044                @if (_isExporting)
 45                {
 46                    <MudProgressCircular Size="Size.Small" Indeterminate="true" Class="mr-2" />
 47                    <span>Exporting...</span>
 48                }
 49                else
 50                {
 51                    <span>Export to Markdown</span>
 52                }
 53            </MudButton>
 54        </div>
 55
 056        @if (_exportSuccess.HasValue)
 57        {
 58            <MudAlert Severity="@(_exportSuccess.Value ? Severity.Success : Severity.Error)"
 59                      Class="mt-4"
 60                      Dense="true"
 61                      Variant="Variant.Outlined"
 62                      ShowCloseIcon="true"
 063                      CloseIconClicked="() => _exportSuccess = null">
 064                @if (_exportSuccess.Value)
 65                {
 66                    <span>Export complete! Your download should begin automatically.</span>
 67                }
 68                else
 69                {
 70                    <span>Export failed. Please try again or contact support if the problem persists.</span>
 71                }
 72            </MudAlert>
 73        }
 74    }
 75</div>
 76
 77<MudDivider Class="my-5" />
 78
 79<!-- Import Section (Placeholder) -->
 80<div>
 81    <MudText Typo="Typo.subtitle2" Color="Color.Primary" Class="mb-2" Style="font-weight: 600;">
 82        Import Data
 83    </MudText>
 84    <MudText Typo="Typo.body2" Class="mud-text-secondary mb-4">
 85        Import content from other tools or restore from a backup.
 86    </MudText>
 87
 88    <MudAlert Severity="Severity.Info" Dense="true" Variant="Variant.Outlined" Icon="@Icons.Material.Filled.Construction
 89        Import functionality is coming soon! We're working on support for importing from
 90        Markdown files, Notion exports, and other popular campaign management tools.
 91    </MudAlert>
 92</div>
 93
 94@code {
 095    [Inject] private IWorldApiService WorldApi { get; set; } = default!;
 096    [Inject] private IExportApiService ExportApi { get; set; } = default!;
 097    [Inject] private ISnackbar Snackbar { get; set; } = default!;
 98
 99    private List<WorldDto>? _worlds;
 100    private WorldDto? _selectedWorld;
 0101    private bool _isLoadingWorlds = true;
 102    private bool _isExporting = false;
 103    private bool? _exportSuccess = null;
 104
 105    protected override async Task OnInitializedAsync()
 106    {
 0107        _isLoadingWorlds = true;
 108        try
 109        {
 0110            _worlds = await WorldApi.GetWorldsAsync();
 0111            if (_worlds?.Any() == true)
 112            {
 0113                _selectedWorld = _worlds.First();
 114            }
 0115        }
 116        finally
 117        {
 0118            _isLoadingWorlds = false;
 119        }
 0120    }
 121
 122    private async Task ExportWorld()
 123    {
 0124        if (_selectedWorld == null) return;
 125
 0126        _isExporting = true;
 0127        _exportSuccess = null;
 0128        StateHasChanged();
 129
 130        try
 131        {
 0132            var success = await ExportApi.ExportWorldToMarkdownAsync(_selectedWorld.Id, _selectedWorld.Name);
 0133            _exportSuccess = success;
 134
 0135            if (success)
 136            {
 0137                Snackbar.Add($"Export of '{_selectedWorld.Name}' completed!", Severity.Success);
 138            }
 139            else
 140            {
 0141                Snackbar.Add("Export failed. Please try again.", Severity.Error);
 142            }
 0143        }
 0144        catch (Exception ex)
 145        {
 0146            _exportSuccess = false;
 0147            Snackbar.Add($"Export error: {ex.Message}", Severity.Error);
 0148        }
 149        finally
 150        {
 0151            _isExporting = false;
 0152            StateHasChanged();
 153        }
 0154    }
 155}