< Summary

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

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
CreateBuilder()100%210%
.ctor(...)0%4260%
set_CurrentSorting(...)100%210%
get_HasActiveSorting()100%210%
Apply()100%210%
Clear()0%620%
Reset()0%2040%
SetActive(...)0%620%
Toggle(...)0%4260%
SetDirection(...)0%620%
ComputeCurrentSorting()0%4260%
HandlePropertyChanged(...)100%210%
RaiseSortingChanged()0%620%
Find(...)100%210%
FindMatching(...)100%210%
DisposeManagedResources()0%620%

File(s)

https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.UI/ViewModels/List/Sorting/SortingViewModel.cs

#LineLine coverage
 1// -----------------------------------------------------------------------
 2// <copyright file="SortingViewModel.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.ComponentModel;
 11using System.Linq;
 12using MyNet.Collections;
 13using MyNet.Observable;
 14using MyNet.Observable.Collections.Sorting;
 15using MyNet.Utilities.Deferring;
 16
 17namespace MyNet.UI.ViewModels.List.Sorting;
 18
 19/// <summary>
 20/// Represents a view model for managing sorting configuration of a collection.
 21/// </summary>
 22/// <typeparam name="T">The type of items in the collection.</typeparam>
 23public class SortingViewModel<T> : ObservableObject, ISortingViewModel<T>
 24{
 25    private readonly DeferredAction _deferredAction;
 26
 27    /// <summary>
 28    /// Creates a fluent builder used to configure and instantiate a <see cref="SortingViewModel{T}"/>.
 29    /// </summary>
 030    public static SortingViewModelBuilder<T> CreateBuilder() => new();
 31
 32    /// <summary>
 33    /// Initializes a new instance of the <see cref="SortingViewModel{T}"/> class with the specified sorting properties 
 34    /// </summary>
 35    /// <param name="properties">The sorting properties for the collection.</param>
 36    /// <param name="defaultSorting">The optional default sorting configuration.</param>
 037    public SortingViewModel(IEnumerable<ISortingPropertyViewModel<T>> properties, IEnumerable<ISortingProperty<T>>? defa
 38    {
 039        Properties = new(new(properties));
 040        DefaultSorting = defaultSorting?.ToList() ?? [];
 41
 042        _deferredAction = new(RaiseSortingChanged);
 43
 044        Reset();
 45
 046        foreach (var property in Properties)
 047            property.PropertyChanged += HandlePropertyChanged;
 048    }
 49
 50    /// <summary>
 51    /// Gets the collection of sorting property view models that can be configured for sorting. This collection is read-
 52    /// </summary>
 53    public ReadOnlyObservableCollection<ISortingPropertyViewModel<T>> Properties { get; }
 54
 55    /// <summary>
 56    /// Gets the current sorting configuration built from the UI. This collection is read-only and represents the active
 57    /// </summary>
 058    public IReadOnlyList<ISortingProperty<T>> CurrentSorting { get; private set => SetProperty(ref field, value); } = []
 59
 60    /// <summary>
 61    /// Gets the default sorting configuration for the collection. This collection is read-only and represents the initi
 62    /// </summary>
 63    public IReadOnlyList<ISortingProperty<T>> DefaultSorting { get; }
 64
 65    /// <summary>
 66    /// Gets a value indicating whether there are any active sorting properties in the current configuration. This prope
 67    /// </summary>
 068    public bool HasActiveSorting => CurrentSorting.Any();
 69
 70    /// <summary>
 71    /// Occurs when the sorting configuration has changed. Subscribers can react to this event to apply the new sorting 
 72    /// </summary>
 73    public event EventHandler<SortingChangedEventArgs<T>>? SortingChanged;
 74
 75    /// <summary>
 76    /// Applies the current sorting configuration. This method triggers the sorting update process by invoking the defer
 77    /// </summary>
 078    public void Apply() => _deferredAction.Request();
 79
 80    /// <summary>
 81    /// Clears all active sorting by disabling all sorting properties. This method iterates through the Properties colle
 82    /// </summary>
 83    public void Clear()
 84    {
 085        using (_deferredAction.Defer())
 086            Properties.ForEach(p => p.IsEnabled = false);
 087    }
 88
 89    /// <summary>
 90    /// Resets the sorting configuration to its default state. This method first clears all active sorting properties an
 91    /// </summary>
 92    public void Reset()
 93    {
 094        using (_deferredAction.Defer())
 95        {
 096            Clear();
 97
 098            foreach (var def in DefaultSorting)
 99            {
 0100                var vm = FindMatching(def);
 101
 0102                if (vm != null)
 103                {
 0104                    vm.IsEnabled = true;
 0105                    vm.Direction = def.Direction;
 106                }
 107            }
 108        }
 0109    }
 110
 111    /// <summary>
 112    /// Sets the active state of a sorting property identified by the specified key. This method finds the sorting prope
 113    /// </summary>
 114    /// <param name="key">The key of the sorting property to update.</param>
 115    /// <param name="isActive">A value indicating whether the sorting property should be active.</param>
 116    public void SetActive(string key, bool isActive)
 117    {
 0118        var property = Find(key);
 119
 0120        if (property is null) return;
 121
 0122        using (_deferredAction.Defer())
 0123            property.IsEnabled = isActive;
 0124    }
 125
 126    /// <summary>
 127    /// Toggles the sort direction of a sorting property identified by the specified key. If the sorting property is cur
 128    /// </summary>
 129    /// <param name="key">The key of the sorting property to toggle.</param>
 130    public void Toggle(string key)
 131    {
 0132        var property = Find(key);
 133
 0134        if (property is null) return;
 135
 0136        using (_deferredAction.Defer())
 137        {
 0138            if (!property.IsEnabled)
 139            {
 0140                property.IsEnabled = true;
 0141                property.Direction = ListSortDirection.Ascending;
 142            }
 143            else
 144            {
 0145                property.Direction = property.Direction == ListSortDirection.Ascending
 0146                    ? ListSortDirection.Descending
 0147                    : ListSortDirection.Ascending;
 148            }
 0149        }
 0150    }
 151
 152    /// <summary>
 153    /// Sets the sort direction of a sorting property identified by the specified key. This method finds the sorting pro
 154    /// </summary>
 155    /// <param name="key">The key of the sorting property to update.</param>
 156    /// <param name="direction">The direction to set for the sorting property.</param>
 157    public void SetDirection(string key, ListSortDirection direction)
 158    {
 0159        var property = Find(key);
 160
 0161        if (property is null) return;
 162
 0163        using (_deferredAction.Defer())
 164        {
 0165            property.IsEnabled = true;
 0166            property.Direction = direction;
 0167        }
 0168    }
 169
 170    /// <summary>
 171    /// Computes the current sorting configuration based on the enabled sorting properties in the Properties collection.
 172    /// </summary>
 173    /// <returns>A read-only list of the current sorting properties.</returns>
 174    private IReadOnlyList<ISortingProperty<T>> ComputeCurrentSorting() =>
 0175    [
 0176        .. Properties
 0177            .Where(p => p.IsEnabled)
 0178            .OrderBy(p => p.ActivatedAt)
 0179            .Select(p => p.Build())
 0180    ];
 181
 182    /// <summary>
 183    /// Handles the PropertyChanged event for the sorting property view models. When any property of a sorting property 
 184    /// </summary>
 185    /// <param name="sender">The source of the event.</param>
 186    /// <param name="e">The event data.</param>
 0187    private void HandlePropertyChanged(object? sender, PropertyChangedEventArgs e) => _deferredAction.Request();
 188
 189    /// <summary>
 190    /// Handles the logic for when the sorting configuration has changed. This method computes the current sorting confi
 191    /// </summary>
 192    private void RaiseSortingChanged()
 193    {
 0194        CurrentSorting = ComputeCurrentSorting();
 0195        SortingChanged?.Invoke(this, new(CurrentSorting));
 0196    }
 197
 198    /// <summary>
 199    /// Finds a sorting property view model in the Properties collection by its unique key. This method searches through
 200    /// </summary>
 201    /// <param name="key">The unique key of the sorting property to find.</param>
 202    /// <returns>The sorting property view model with the specified key, or null if not found.</returns>
 203    private ISortingPropertyViewModel<T>? Find(string key)
 0204        => Properties.FirstOrDefault(p => p.Key == key);
 205
 206    /// <summary>
 207    /// Finds a sorting property view model in the Properties collection that matches the specified sorting property. Th
 208    /// </summary>
 209    /// <param name="property">The sorting property to match.</param>
 210    /// <returns>The sorting property view model that matches the specified sorting property, or null if not found.</ret
 211    private ISortingPropertyViewModel<T>? FindMatching(ISortingProperty<T> property)
 0212        => Properties.FirstOrDefault(p => p.Matches(property));
 213
 214    /// <inheritdoc />
 215    protected override void DisposeManagedResources()
 216    {
 0217        foreach (var property in Properties)
 0218            property.PropertyChanged -= HandlePropertyChanged;
 219
 0220        base.DisposeManagedResources();
 0221    }
 222}
 223