< Summary

Information
Class: MyNet.UI.ViewModels.Export.FileExportViewModelBase<T>
Assembly: MyNet.UI
File(s): https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.UI/ViewModels/Export/FileExportViewModelBase.cs
Tag: 323_28699572109
Line coverage
0%
Covered lines: 0
Uncovered lines: 28
Coverable lines: 28
Total lines: 109
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 28
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)0%110100%
set_Destination(...)100%210%
Load(...)0%620%
SetFilePathAsync()0%110100%
GetInitialDirectory()0%4260%

File(s)

https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.UI/ViewModels/Export/FileExportViewModelBase.cs

#LineLine coverage
 1// -----------------------------------------------------------------------
 2// <copyright file="FileExportViewModelBase.cs" company="Stéphane ANDRE">
 3// Copyright (c) Stéphane ANDRE. All rights reserved.
 4// </copyright>
 5// -----------------------------------------------------------------------
 6
 7using System;
 8using System.Collections.Generic;
 9using System.IO;
 10using System.Threading;
 11using System.Threading.Tasks;
 12using System.Windows.Input;
 13using FluentValidation;
 14using MyNet.UI.Commands;
 15using MyNet.UI.Dialogs;
 16using MyNet.UI.Notifications;
 17
 18namespace MyNet.UI.ViewModels.Export;
 19
 20/// <summary>
 21/// Provides a reusable base implementation for file export dialogs.
 22/// </summary>
 23/// <typeparam name="T">The exported item type.</typeparam>
 24public abstract class FileExportViewModelBase<T> : ExportViewModelBase<T>
 25{
 26    private readonly IDialogService _dialogService;
 27    private readonly string _defaultFolder;
 28    private readonly Func<string> _defaultExportName;
 29
 30    /// <summary>
 31    /// Initializes a new instance of the <see cref="FileExportViewModelBase{T}"/> class.
 32    /// </summary>
 33    /// <param name="dialogService">Dialog service used to select a destination file.</param>
 34    /// <param name="fileType">The supported file type constraints.</param>
 35    /// <param name="defaultExportName">Function used to generate default file name (without extension).</param>
 36    /// <param name="defaultFolder">Optional default destination folder.</param>
 37    /// <param name="notificationPublisher">Optional notification publisher used to display validation/export errors.</p
 38    /// <param name="commandFactory">Optional command factory used to create commands.</param>
 39    /// <param name="validator">Optional validator used to validate this view model.</param>
 40    protected FileExportViewModelBase(
 41        IDialogService dialogService,
 42        ExportFileType fileType,
 43        Func<string> defaultExportName,
 44        string? defaultFolder = null,
 45        INotificationPublisher? notificationPublisher = null,
 46        ICommandFactory? commandFactory = null,
 47        IValidator? validator = null)
 048        : base(notificationPublisher, commandFactory, validator ?? new FileExportViewModelValidator<T>())
 49    {
 050        _dialogService = dialogService ?? throw new ArgumentNullException(nameof(dialogService));
 051        FileType = fileType ?? throw new ArgumentNullException(nameof(fileType));
 052        _defaultExportName = defaultExportName ?? throw new ArgumentNullException(nameof(defaultExportName));
 053        _defaultFolder = string.IsNullOrWhiteSpace(defaultFolder)
 054            ? Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
 055            : defaultFolder;
 56
 57        SetFilePathCommand = Commands.Create(() => SetFilePathAsync());
 058    }
 59
 60    /// <summary>
 61    /// Gets file type constraints.
 62    /// </summary>
 63    public ExportFileType FileType { get; }
 64
 65    /// <summary>
 66    /// Gets or sets destination file path.
 67    /// </summary>
 068    public string? Destination { get; set => SetProperty(ref field, value); }
 69
 70    /// <summary>
 71    /// Gets the command that lets the user select a destination path.
 72    /// </summary>
 73    public ICommand SetFilePathCommand { get; }
 74
 75    /// <inheritdoc />
 76    public override void Load(ICollection<T> items)
 77    {
 078        base.Load(items);
 079        var directory = Path.GetDirectoryName(Destination) ?? _defaultFolder;
 080        Destination = Path.Combine(directory, Path.ChangeExtension(_defaultExportName(), FileType.DefaultExtension));
 081    }
 82
 83    private async Task SetFilePathAsync(CancellationToken cancellationToken = default)
 84    {
 085        var result = await _dialogService.SaveFile()
 086            .WithFileName(Path.GetFileNameWithoutExtension(Destination) ?? string.Empty)
 087            .WithInitialDirectory(GetInitialDirectory())
 088            .WithFilters(FileType.DialogFilter)
 089            .WithDefaultExtension(FileType.DefaultExtension)
 090            .PickAsync(cancellationToken)
 091            .ConfigureAwait(false);
 92
 093        if (result is { IsCancelled: false, Files.Count: > 0 })
 094            Destination = result.Files[0];
 095    }
 96
 97    private string GetInitialDirectory()
 98    {
 099        if (!string.IsNullOrWhiteSpace(Destination))
 100        {
 0101            var directory = Path.GetDirectoryName(Destination);
 0102            if (!string.IsNullOrWhiteSpace(directory) && Directory.Exists(directory))
 0103                return directory;
 104        }
 105
 0106        return _defaultFolder;
 107    }
 108}
 109