< Summary

Information
Class: MyNet.UI.ViewModels.Export.FileExportByColumnsViewModelBase<T1, T2>
Assembly: MyNet.UI
File(s): https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.UI/ViewModels/Export/FileExportByColumnsViewModelBase.cs
Tag: 323_28699572109
Line coverage
0%
Covered lines: 0
Uncovered lines: 29
Coverable lines: 29
Total lines: 147
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 18
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%4260%
get_SelectedColumns()0%2040%
get_OrderedColumns()0%620%
SetSelectedColumns(...)0%620%
SetColumnsOrder(...)0%4260%
ResetColumnsOrder()100%210%

File(s)

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

#LineLine coverage
 1// -----------------------------------------------------------------------
 2// <copyright file="FileExportByColumnsViewModelBase.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.Collections.ObjectModel;
 10using System.Linq;
 11using System.Windows.Input;
 12using FluentValidation;
 13using MyNet.UI.Commands;
 14using MyNet.UI.Dialogs;
 15using MyNet.UI.Notifications;
 16
 17namespace MyNet.UI.ViewModels.Export;
 18
 19/// <summary>
 20/// Provides a reusable base implementation for file exports with selectable columns.
 21/// </summary>
 22/// <typeparam name="T">The exported item type.</typeparam>
 23/// <typeparam name="TColumn">The column metadata type.</typeparam>
 24public abstract class FileExportByColumnsViewModelBase<T, TColumn> : FileExportViewModelBase<T>
 25{
 26    private readonly IReadOnlyDictionary<TColumn, bool> _defaultColumns;
 27
 28    /// <summary>
 29    /// Initializes a new instance of the <see cref="FileExportByColumnsViewModelBase{T, TColumn}"/> class.
 30    /// </summary>
 31    /// <param name="dialogService">The dialog service used to select a destination file.</param>
 32    /// <param name="fileType">The supported file type constraints.</param>
 33    /// <param name="defaultExportName">Function used to generate default file name (without extension).</param>
 34    /// <param name="defaultColumns">The default columns selection.</param>
 35    /// <param name="columnKeySelector">Function used to generate column keys.</param>
 36    /// <param name="presetColumns">Optional column presets.</param>
 37    /// <param name="defaultFolder">Optional default destination folder.</param>
 38    /// <param name="notificationPublisher">Optional notification publisher used to display validation/export errors.</p
 39    /// <param name="commandFactory">Optional command factory used to create commands.</param>
 40    /// <param name="validator">Optional validator used to validate the view model.</param>
 41    protected FileExportByColumnsViewModelBase(
 42        IDialogService dialogService,
 43        ExportFileType fileType,
 44        Func<string> defaultExportName,
 45        IReadOnlyDictionary<TColumn, bool> defaultColumns,
 46        Func<TColumn, string> columnKeySelector,
 47        IEnumerable<ExportColumnsPreset>? presetColumns = null,
 48        string? defaultFolder = null,
 49        INotificationPublisher? notificationPublisher = null,
 50        ICommandFactory? commandFactory = null,
 51        IValidator? validator = null)
 052        : base(
 053            dialogService,
 054            fileType,
 055            defaultExportName,
 056            defaultFolder,
 057            notificationPublisher,
 058            commandFactory,
 059            validator ?? new FileExportByColumnsViewModelValidator<T, TColumn>())
 60    {
 061        ArgumentNullException.ThrowIfNull(defaultColumns);
 062        ArgumentNullException.ThrowIfNull(columnKeySelector);
 63
 064        _defaultColumns = defaultColumns;
 065        ColumnKeySelector = columnKeySelector;
 66
 67        Columns = [.. _defaultColumns.Select(x => new ExportColumnViewModel<TColumn>(x.Key, ColumnKeySelector(x.Key), x.
 068        PresetColumns = [.. presetColumns ?? []];
 69
 70        SetSelectedColumnsCommand = Commands.Create<IReadOnlyCollection<string>>(x => SetSelectedColumns(x ?? []));
 071    }
 72
 73    /// <summary>
 74    /// Gets or sets a value indicating whether column header translations should be exported.
 75    /// </summary>
 076    public bool ShowHeaderColumnTranslation { get; set; } = true;
 77
 78    /// <summary>
 79    /// Gets column presets.
 80    /// </summary>
 81    public IReadOnlyCollection<ExportColumnsPreset> PresetColumns { get; }
 82
 83    /// <summary>
 84    /// Gets selected columns wrappers.
 85    /// </summary>
 86    public ObservableCollection<ExportColumnViewModel<TColumn>> Columns { get; }
 87
 88    /// <summary>
 89    /// Gets the command that applies a selected columns preset.
 90    /// </summary>
 91    public ICommand SetSelectedColumnsCommand { get; }
 92
 93    /// <summary>
 94    /// Gets selector used to map a column to its key.
 95    /// </summary>
 96    protected Func<TColumn, string> ColumnKeySelector { get; }
 97
 98    /// <summary>
 99    /// Gets selected columns metadata in display order.
 100    /// </summary>
 0101    protected IReadOnlyCollection<TColumn> SelectedColumns => [.. Columns.Where(x => x.IsSelected).Select(x => x.Column)
 102
 103    /// <summary>
 104    /// Gets all columns metadata in display order.
 105    /// </summary>
 0106    protected IReadOnlyCollection<TColumn> OrderedColumns => [.. Columns.Select(x => x.Column)];
 107
 108    /// <summary>
 109    /// Applies selected columns by keys.
 110    /// </summary>
 111    /// <param name="columnKeys">The selected column keys.</param>
 112    protected void SetSelectedColumns(IEnumerable<string> columnKeys)
 113    {
 0114        var selected = new HashSet<string>(columnKeys, StringComparer.Ordinal);
 0115        foreach (var column in Columns)
 0116            column.IsSelected = selected.Contains(column.Key);
 0117    }
 118
 119    /// <summary>
 120    /// Applies a new column order according to provided keys.
 121    /// </summary>
 122    /// <param name="columnKeys">The ordered keys.</param>
 123    protected void SetColumnsOrder(IEnumerable<string> columnKeys)
 124    {
 0125        var newIndex = 0;
 0126        foreach (var key in columnKeys)
 127        {
 0128            var currentIndex = Columns.Select(x => x.Key).ToList().IndexOf(key);
 0129            if (currentIndex <= -1)
 130                continue;
 131
 0132            Columns.Move(currentIndex, newIndex);
 0133            newIndex++;
 134        }
 0135    }
 136
 137    /// <summary>
 138    /// Resets column order to default order.
 139    /// </summary>
 0140    protected virtual void ResetColumnsOrder() => SetColumnsOrder(_defaultColumns.Keys.Select(ColumnKeySelector));
 141}
 142
 143/// <summary>
 144/// Represents a named preset for selected export columns.
 145/// </summary>
 146public sealed record ExportColumnsPreset(string Name, IReadOnlyCollection<string> ColumnKeys);
 147