< Summary

Information
Class: MyNet.UI.ViewModels.List.Grouping.GroupingViewModel<T>
Assembly: MyNet.UI
File(s): https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.UI/ViewModels/List/Grouping/GroupingViewModel.cs
Tag: 323_28699572109
Line coverage
0%
Covered lines: 0
Uncovered lines: 42
Coverable lines: 42
Total lines: 175
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 24
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_CurrentGrouping(...)100%210%
get_HasActiveGrouping()100%210%
Apply()100%210%
Clear()0%620%
Reset()0%2040%
SetActive(...)0%620%
ComputeCurrentGrouping()0%4260%
HandlePropertyChanged(...)100%210%
RaiseGroupingChanged()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/Grouping/GroupingViewModel.cs

#LineLine coverage
 1// -----------------------------------------------------------------------
 2// <copyright file="GroupingViewModel.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.Grouping;
 15using MyNet.Utilities.Deferring;
 16
 17namespace MyNet.UI.ViewModels.List.Grouping;
 18
 19/// <summary>
 20/// Represents a view model for managing grouping configuration of a collection.
 21/// </summary>
 22/// <typeparam name="T">The type of items in the collection.</typeparam>
 23public class GroupingViewModel<T> : ObservableObject, IGroupingViewModel<T>
 24{
 25    private readonly DeferredAction _deferredAction;
 26
 27    /// <summary>
 28    /// Creates a fluent builder used to configure and instantiate a <see cref="GroupingViewModel{T}"/>.
 29    /// </summary>
 030    public static GroupingViewModelBuilder<T> CreateBuilder() => new();
 31
 32    /// <summary>
 33    /// Initializes a new instance of the <see cref="GroupingViewModel{T}"/> class with the specified grouping propertie
 34    /// </summary>
 35    /// <param name="properties">The grouping properties for the collection.</param>
 36    /// <param name="defaultGrouping">The optional default grouping configuration.</param>
 037    public GroupingViewModel(IEnumerable<IGroupingPropertyViewModel<T>> properties, IEnumerable<IGroupingProperty<T>>? d
 38    {
 039        Properties = new(new(properties));
 040        DefaultGrouping = defaultGrouping?.ToList() ?? [];
 41
 042        _deferredAction = new(RaiseGroupingChanged);
 43
 044        Reset();
 45
 046        foreach (var property in Properties)
 047            property.PropertyChanged += HandlePropertyChanged;
 048    }
 49
 50    /// <summary>
 51    /// Gets the collection of grouping property view models that can be configured for grouping. This collection is rea
 52    /// </summary>
 53    public ReadOnlyObservableCollection<IGroupingPropertyViewModel<T>> Properties { get; }
 54
 55    /// <summary>
 56    /// Gets the current grouping configuration built from the UI. This collection is read-only and represents the activ
 57    /// </summary>
 058    public IReadOnlyList<IGroupingProperty<T>> CurrentGrouping { get; private set => SetProperty(ref field, value); } = 
 59
 60    /// <summary>
 61    /// Gets the default grouping configuration for the collection. This collection is read-only and represents the init
 62    /// </summary>
 63    public IReadOnlyList<IGroupingProperty<T>> DefaultGrouping { get; }
 64
 65    /// <summary>
 66    /// Gets a value indicating whether there are any active grouping properties in the current configuration. This prop
 67    /// </summary>
 068    public bool HasActiveGrouping => CurrentGrouping.Any();
 69
 70    /// <summary>
 71    /// Occurs when the grouping configuration has changed. Subscribers can react to this event to apply the new groupin
 72    /// </summary>
 73    public event EventHandler<GroupingChangedEventArgs<T>>? GroupingChanged;
 74
 75    /// <summary>
 76    /// Applies the current grouping configuration. This method triggers the grouping update process by invoking the def
 77    /// </summary>
 078    public void Apply() => _deferredAction.Request();
 79
 80    /// <summary>
 81    /// Clears all active grouping by disabling all grouping properties. This method iterates through the Properties col
 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 grouping configuration to its default state. This method first clears all active grouping properties 
 91    /// </summary>
 92    public void Reset()
 93    {
 094        using (_deferredAction.Defer())
 95        {
 096            Clear();
 97
 098            foreach (var def in DefaultGrouping)
 99            {
 0100                var vm = FindMatching(def);
 101
 0102                vm?.IsEnabled = true;
 103            }
 104        }
 0105    }
 106
 107    /// <summary>
 108    /// Sets the active state of a grouping property identified by the specified key. This method finds the grouping pro
 109    /// </summary>
 110    /// <param name="key">The key of the grouping property to update.</param>
 111    /// <param name="isActive">A value indicating whether the grouping property should be active.</param>
 112    public void SetActive(string key, bool isActive)
 113    {
 0114        var property = Find(key);
 115
 0116        if (property is null) return;
 117
 0118        using (_deferredAction.Defer())
 0119            property.IsEnabled = isActive;
 0120    }
 121
 122    /// <summary>
 123    /// Computes the current grouping configuration based on the enabled grouping properties in the Properties collectio
 124    /// </summary>
 125    /// <returns>A read-only list of the current grouping properties.</returns>
 126    private IReadOnlyList<IGroupingProperty<T>> ComputeCurrentGrouping() =>
 0127    [
 0128        .. Properties
 0129            .Where(p => p.IsEnabled)
 0130            .OrderBy(p => p.ActivatedAt)
 0131            .Select(p => p.Build())
 0132    ];
 133
 134    /// <summary>
 135    /// Handles the PropertyChanged event for the grouping property view models. When any property of a grouping propert
 136    /// </summary>
 137    /// <param name="sender">The source of the event.</param>
 138    /// <param name="e">The event data.</param>
 0139    private void HandlePropertyChanged(object? sender, PropertyChangedEventArgs e) => _deferredAction.Request();
 140
 141    /// <summary>
 142    /// Handles the logic for when the grouping configuration has changed. This method computes the current grouping con
 143    /// </summary>
 144    private void RaiseGroupingChanged()
 145    {
 0146        CurrentGrouping = ComputeCurrentGrouping();
 0147        GroupingChanged?.Invoke(this, new(CurrentGrouping));
 0148    }
 149
 150    /// <summary>
 151    /// Finds a grouping property view model in the Properties collection by its unique key. This method searches throug
 152    /// </summary>
 153    /// <param name="key">The unique key of the grouping property to find.</param>
 154    /// <returns>The grouping property view model with the specified key, or null if not found.</returns>
 155    private IGroupingPropertyViewModel<T>? Find(string key)
 0156        => Properties.FirstOrDefault(p => p.Key == key);
 157
 158    /// <summary>
 159    /// Finds a grouping property view model in the Properties collection that matches the specified grouping property. 
 160    /// </summary>
 161    /// <param name="property">The grouping property to match.</param>
 162    /// <returns>The grouping property view model that matches the specified grouping property, or null if not found.</r
 163    private IGroupingPropertyViewModel<T>? FindMatching(IGroupingProperty<T> property)
 0164        => Properties.FirstOrDefault(p => p.Matches(property));
 165
 166    /// <inheritdoc />
 167    protected override void DisposeManagedResources()
 168    {
 0169        foreach (var property in Properties)
 0170            property.PropertyChanged -= HandlePropertyChanged;
 171
 0172        base.DisposeManagedResources();
 0173    }
 174}
 175