From 496183c1383250f9f71161504e2724a4c668d89f Mon Sep 17 00:00:00 2001 From: Deyan Nenov Date: Tue, 12 Nov 2024 20:08:34 +0000 Subject: [PATCH] DYN-7754: filter exclusivity (#15630) --- src/DynamoCoreWpf/PublicAPI.Unshipped.txt | 2 + .../PackageManagerSearchViewModel.cs | 43 +++++++++++++++ .../Controls/PackageManagerSearchControl.xaml | 1 + ...ckageManagerSearchElementViewModelTests.cs | 53 +++++++++++++++++++ 4 files changed, 99 insertions(+) diff --git a/src/DynamoCoreWpf/PublicAPI.Unshipped.txt b/src/DynamoCoreWpf/PublicAPI.Unshipped.txt index 9b55e04bb31..6fd915b1aa7 100644 --- a/src/DynamoCoreWpf/PublicAPI.Unshipped.txt +++ b/src/DynamoCoreWpf/PublicAPI.Unshipped.txt @@ -874,6 +874,8 @@ Dynamo.PackageManager.PackageManagerSearchViewModel.FilterEntry.FilterName.get - Dynamo.PackageManager.PackageManagerSearchViewModel.FilterEntry.FilterName.set -> void Dynamo.PackageManager.PackageManagerSearchViewModel.FilterEntry.GroupName.get -> string Dynamo.PackageManager.PackageManagerSearchViewModel.FilterEntry.GroupName.set -> void +Dynamo.PackageManager.PackageManagerSearchViewModel.FilterEntry.IsEnabled.get -> bool +Dynamo.PackageManager.PackageManagerSearchViewModel.FilterEntry.IsEnabled.set -> void Dynamo.PackageManager.PackageManagerSearchViewModel.FilterEntry.OnChecked.get -> bool Dynamo.PackageManager.PackageManagerSearchViewModel.FilterEntry.OnChecked.set -> void Dynamo.PackageManager.PackageManagerSearchViewModel.FilterEntry.Tooltip.get -> string diff --git a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs index 9fad081fbd7..abbaa99e46f 100644 --- a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerSearchViewModel.cs @@ -86,6 +86,22 @@ public class FilterEntry : NotificationObject /// public string Tooltip { get; set; } + /// + /// Controls the IsEnabled status of the filter + /// + private bool isEnabled = true; + + public bool IsEnabled + { + get { return isEnabled; } + set + { + isEnabled = value; + RaisePropertyChanged(nameof(IsEnabled)); + } + } + + /// /// Filter entry click command, notice this is a dynamic command /// with command param set to FilterName so that the code is robust @@ -410,6 +426,33 @@ public bool IsAnyFilterOn private void SetFilterChange() { IsAnyFilterOn = HostFilter.Any(f => f.OnChecked) || NonHostFilter.Any(f => f.OnChecked) || CompatibilityFilter.Any(f => f.OnChecked); + ApplyFilterRules(); + } + + /// + /// Executes any additional logic on the filters + /// + internal void ApplyFilterRules() + { + // Enable/disable Compatibility filters if any HostFilter is on + if (CompatibilityFilter.Any(f => f.OnChecked)) + { + HostFilter.ForEach(x => x.IsEnabled = false); + } + else + { + HostFilter.ForEach(x => x.IsEnabled = true); + } + + // Enable/disable Host filters if any CompatibilityFilter is on + if (HostFilter.Any(f => f.OnChecked)) + { + CompatibilityFilter.ForEach(x => x.IsEnabled = false); + } + else + { + CompatibilityFilter.ForEach(x => x.IsEnabled = true); + } } /// diff --git a/src/DynamoCoreWpf/Views/PackageManager/Controls/PackageManagerSearchControl.xaml b/src/DynamoCoreWpf/Views/PackageManager/Controls/PackageManagerSearchControl.xaml index de24db4ee82..27fc671b8e6 100644 --- a/src/DynamoCoreWpf/Views/PackageManager/Controls/PackageManagerSearchControl.xaml +++ b/src/DynamoCoreWpf/Views/PackageManager/Controls/PackageManagerSearchControl.xaml @@ -262,6 +262,7 @@ + diff --git a/test/DynamoCoreWpfTests/PackageManager/PackageManagerSearchElementViewModelTests.cs b/test/DynamoCoreWpfTests/PackageManager/PackageManagerSearchElementViewModelTests.cs index af29c9c6def..fc9c0989dcf 100644 --- a/test/DynamoCoreWpfTests/PackageManager/PackageManagerSearchElementViewModelTests.cs +++ b/test/DynamoCoreWpfTests/PackageManager/PackageManagerSearchElementViewModelTests.cs @@ -1021,6 +1021,57 @@ public void TestComputeVersionNoDynamoCompatibility() Assert.IsTrue(resultFallbackToDynamo, "Expected compatibility to be true when under host but only Dynamo compatibility is provided."); } + [Test] + public void HostCompatibilityFiltersExclusivity() + { + var mockGreg = new Mock(); + + var clientMock = new Mock(mockGreg.Object, MockMaker.Empty(), string.Empty); + var pmCVM = new Mock(ViewModel, clientMock.Object) { CallBase = true }; + var pmSVM = new PackageManagerSearchViewModel(pmCVM.Object); + pmSVM.RegisterTransientHandlers(); + + pmSVM.HostFilter = new List + { + new FilterEntry("host", "group", "tooltip", pmSVM) { OnChecked = false }, + }; + + pmSVM.CompatibilityFilter = new List + { + new FilterEntry("compatibility", "group", "tooltip", pmSVM) { OnChecked = false }, + }; + + pmSVM.HostFilter.ForEach(f => f.PropertyChanged += pmSVM.filter_PropertyChanged); + pmSVM.CompatibilityFilter.ForEach(f => f.PropertyChanged += pmSVM.filter_PropertyChanged); + + Assert.IsTrue(pmSVM.HostFilter.All(x => x.IsEnabled), "Expect starting filter state to be enabled"); + Assert.IsTrue(pmSVM.CompatibilityFilter.All(x => x.IsEnabled), "Expect starting filter state to be enabled"); + + // Act/Assert Host -> Compatibility + pmSVM.HostFilter.First().OnChecked = true; + pmSVM.ApplyFilterRules(); + + Assert.IsFalse(pmSVM.CompatibilityFilter.All(x => x.IsEnabled), "Filter groups should be mutually exclusive"); + + pmSVM.HostFilter.First().OnChecked = false; + pmSVM.ApplyFilterRules(); + + Assert.IsTrue(pmSVM.CompatibilityFilter.All(x => x.IsEnabled), "Filter groups should be mutually exclusive"); + + // Act/Assert Compatibility -> Host + pmSVM.CompatibilityFilter.First().OnChecked = true; + pmSVM.ApplyFilterRules(); + + Assert.IsFalse(pmSVM.HostFilter.All(x => x.IsEnabled), "Filter groups should be mutually exclusive"); + + pmSVM.CompatibilityFilter.First().OnChecked = false; + pmSVM.ApplyFilterRules(); + + Assert.IsTrue(pmSVM.HostFilter.All(x => x.IsEnabled), "Filter groups should be mutually exclusive"); + } + + #region Compatibility Tests + [Test] public void TestReverseDynamoCompatibilityFromHost() { @@ -1329,5 +1380,7 @@ public void IsVersionCompatible_InValidMaxRange_ReturnsTrueForVersionInsideOfMaj "Expected compatibility to be true when major version is greater than Max major version and there is an invalid max range."); } + #endregion + } }