FiltersViewModel.cs
  1  // Copyright (c) Microsoft Corporation
  2  // The Microsoft Corporation licenses this file to you under the MIT license.
  3  // See the LICENSE file in the project root for more information.
  4  
  5  using System.Collections.Generic;
  6  using Microsoft.CmdPal.Core.ViewModels.Models;
  7  using Microsoft.CommandPalette.Extensions;
  8  using Microsoft.CommandPalette.Extensions.Toolkit;
  9  
 10  namespace Microsoft.CmdPal.Core.ViewModels;
 11  
 12  public partial class FiltersViewModel : ExtensionObjectViewModel
 13  {
 14      private readonly ExtensionObject<IFilters> _filtersModel;
 15  
 16      public string CurrentFilterId { get; private set; } = string.Empty;
 17  
 18      public IFilterItemViewModel? CurrentFilter { get; private set; }
 19  
 20      public IFilterItemViewModel[] Filters { get; private set; } = [];
 21  
 22      public bool ShouldShowFilters => Filters.Length > 0;
 23  
 24      public FiltersViewModel(ExtensionObject<IFilters> filters, WeakReference<IPageContext> context)
 25          : base(context)
 26      {
 27          _filtersModel = filters;
 28      }
 29  
 30      public override void InitializeProperties()
 31      {
 32          try
 33          {
 34              if (_filtersModel.Unsafe is not null)
 35              {
 36                  var filters = _filtersModel.Unsafe.GetFilters();
 37                  var currentFilterId = _filtersModel.Unsafe.CurrentFilterId ?? string.Empty;
 38  
 39                  var result = BuildFilters(filters ?? [], currentFilterId);
 40                  Filters = result.Items;
 41                  CurrentFilterId = currentFilterId;
 42                  CurrentFilter = result.Selected;
 43                  UpdateProperty(nameof(Filters), nameof(ShouldShowFilters), nameof(CurrentFilterId), nameof(CurrentFilter));
 44  
 45                  return;
 46              }
 47          }
 48          catch (Exception ex)
 49          {
 50              ShowException(ex, _filtersModel.Unsafe?.GetType().Name);
 51          }
 52  
 53          Filters = [];
 54          CurrentFilterId = string.Empty;
 55          CurrentFilter = null;
 56          UpdateProperty(nameof(Filters), nameof(ShouldShowFilters), nameof(CurrentFilterId), nameof(CurrentFilter));
 57      }
 58  
 59      private (IFilterItemViewModel[] Items, IFilterItemViewModel? Selected) BuildFilters(IFilterItem[] filters, string currentFilterId)
 60      {
 61          if (filters is null || filters.Length == 0)
 62          {
 63              return ([], null);
 64          }
 65  
 66          var items = new List<IFilterItemViewModel>(filters.Length);
 67          FilterItemViewModel? firstFilterItem = null;
 68          FilterItemViewModel? selectedFilterItem = null;
 69  
 70          foreach (var filter in filters)
 71          {
 72              if (filter is IFilter filterItem)
 73              {
 74                  var filterItemViewModel = new FilterItemViewModel(filterItem, PageContext);
 75                  filterItemViewModel.InitializeProperties();
 76  
 77                  if (firstFilterItem is null)
 78                  {
 79                      firstFilterItem = filterItemViewModel;
 80                  }
 81  
 82                  if (selectedFilterItem is null && filterItemViewModel.Id == currentFilterId)
 83                  {
 84                      selectedFilterItem = filterItemViewModel;
 85                  }
 86  
 87                  items.Add(filterItemViewModel);
 88              }
 89              else
 90              {
 91                  items.Add(new SeparatorViewModel());
 92              }
 93          }
 94  
 95          return (items.ToArray(), selectedFilterItem ?? firstFilterItem);
 96      }
 97  
 98      public override void SafeCleanup()
 99      {
100          base.SafeCleanup();
101  
102          foreach (var filter in Filters)
103          {
104              if (filter is FilterItemViewModel filterItemViewModel)
105              {
106                  filterItemViewModel.SafeCleanup();
107              }
108          }
109  
110          Filters = [];
111      }
112  }