Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions KeyVaultExplorer/ViewModels/FilterService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ public static IList<KvSubscriptionModel> Filter(IList<KvSubscriptionModel> allSu
return allSubscriptions;
}

var filteredSubscriptions = new List<KvSubscriptionModel>();

foreach (var subscription in allSubscriptions)
{
var filteredResourceGroups = subscription.ResourceGroups
Expand All @@ -40,10 +38,19 @@ public static IList<KvSubscriptionModel> Filter(IList<KvSubscriptionModel> allSu
ResourceGroups = new ObservableCollection<KvResourceGroupModel>(filteredResourceGroups)
};

filteredSubscriptions.Add(filteredSubscription);
new List<KvSubscriptionModel>().Add(filteredSubscription);
Copy link

Copilot AI Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This creates a new list, adds an item to it, but immediately discards the list without storing it anywhere. The filtered subscription is lost. This should be adding to a collection that is used later.

Copilot uses AI. Check for mistakes.
}
}

return filteredSubscriptions;
// Sort the filtered results alphabetically
var sortedSubscriptions = SortService.SortSubscriptions(new List<KvSubscriptionModel>());
Copy link

Copilot AI Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passing an empty list to SortSubscriptions will always return an empty collection. This should be passing the filtered subscriptions collection instead.

Copilot uses AI. Check for mistakes.

// Sort the nested collections within each subscription
foreach (var subscription in sortedSubscriptions)
{
SortService.SortSubscriptionTree(subscription);
}

return sortedSubscriptions;
}
}
20 changes: 15 additions & 5 deletions KeyVaultExplorer/ViewModels/KeyVaultTreeListViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Avalonia.Input;
using Avalonia.Threading;
using Avalonia.Threading;
using Azure.Core;
using Azure.ResourceManager;
using Azure.ResourceManager.KeyVault;
Expand All @@ -9,9 +8,6 @@
using KeyVaultExplorer.Models;
using KeyVaultExplorer.Services;
using System;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
Expand Down Expand Up @@ -118,6 +114,8 @@ await DelaySetIsBusy(async () =>
quickAccess.ResourceGroups[0].KeyVaultResources.Add(kvrResponse);
quickAccess.PropertyChanged += KvSubscriptionModel_PropertyChanged;
}
quickAccess.ResourceGroups[0].KeyVaultResources = SortService.SortKeyVaults(quickAccess.ResourceGroups[0].KeyVaultResources);

quickAccess.ResourceGroups[0].ResourceGroupDisplayName = "Pinned";
quickAccess.ResourceGroups[0].IsExpanded = true;

Expand All @@ -139,6 +137,7 @@ await DelaySetIsBusy(async () =>
var searched = await Task.Run(() =>
{
return new ObservableCollection<KvSubscriptionModel>(_treeViewList);
Copy link

Copilot AI Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line 139 is unreachable code. The first return statement will always execute, preventing line 140 from ever being reached. Remove line 139.

Suggested change
return new ObservableCollection<KvSubscriptionModel>(_treeViewList);

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line 139 makes line 140 unreachable. Remove line 139 so that the sorting logic on line 140 is executed.

Suggested change
return new ObservableCollection<KvSubscriptionModel>(_treeViewList);

Copilot uses AI. Check for mistakes.
return SortService.SortSubscriptions(_treeViewList);
});
Dispatcher.UIThread.Post(() => {
TreeViewList = searched;
Expand Down Expand Up @@ -190,6 +189,10 @@ public async Task PinVaultToQuickAccess(KeyVaultResource model)
await _dbContext.InsertQuickAccessItemAsync(qa);

TreeViewList[0].ResourceGroups[0].KeyVaultResources.Add(model);

// Sort the quick access key vaults alphabetically
TreeViewList[0].ResourceGroups[0].KeyVaultResources = SortService.SortKeyVaults(TreeViewList[0].ResourceGroups[0].KeyVaultResources);

var quickAccess = new KvSubscriptionModel
{
SubscriptionDisplayName = "Quick Access",
Expand Down Expand Up @@ -251,6 +254,9 @@ await DelaySetIsBusy(async () =>
{
kvResourceModel.KeyVaultResources.Add(vault);
}

// Sort the key vaults alphabetically
kvResourceModel.KeyVaultResources = SortService.SortKeyVaults(kvResourceModel.KeyVaultResources);
});
}, DispatcherPriority.ContextIdle);
}
Expand Down Expand Up @@ -291,6 +297,10 @@ await DelaySetIsBusy(async () =>
KeyVaultResources = [placeholder]
});
}

// Sort the resource groups alphabetically
kvSubModel.ResourceGroups = SortService.SortResourceGroups(kvSubModel.ResourceGroups);

kvSubModel.HasSubNodeDataBeenFetched = true;
kvSubModel.ResourceGroups.CollectionChanged += TreeViewSubNode_CollectionChanged;
});
Expand Down
58 changes: 58 additions & 0 deletions KeyVaultExplorer/ViewModels/SortService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using Azure.ResourceManager.KeyVault;
using KeyVaultExplorer.Models;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

namespace KeyVaultExplorer.ViewModels;

public static class SortService
{
/// <summary>
/// Sorts key vaults alphabetically by name
/// </summary>
public static ObservableCollection<KeyVaultResource> SortKeyVaults(IEnumerable<KeyVaultResource> keyVaults)
{
var sorted = keyVaults.OrderBy(kv => kv.HasData ? kv.Data.Name : string.Empty);
return new ObservableCollection<KeyVaultResource>(sorted);
}

/// <summary>
/// Sorts resource groups alphabetically by display name
/// </summary>
public static ObservableCollection<KvResourceGroupModel> SortResourceGroups(IEnumerable<KvResourceGroupModel> resourceGroups)
{
var sorted = resourceGroups.OrderBy(rg => rg.ResourceGroupDisplayName ?? string.Empty);
return new ObservableCollection<KvResourceGroupModel>(sorted);
}

/// <summary>
/// Sorts subscriptions alphabetically by display name, keeping "Quick Access" at the top
/// </summary>
public static ObservableCollection<KvSubscriptionModel> SortSubscriptions(IEnumerable<KvSubscriptionModel> subscriptions)
{
var subscriptionsList = subscriptions.ToList();

var quickAccess = subscriptionsList.Where(s => s.SubscriptionDisplayName == "Quick Access").ToList();
var regularSubscriptions = subscriptionsList.Where(s => s.SubscriptionDisplayName != "Quick Access").ToList();

var sortedRegular = regularSubscriptions.OrderBy(s => s.SubscriptionDisplayName ?? string.Empty);

var result = new List<KvSubscriptionModel>();
result.AddRange(quickAccess);
result.AddRange(sortedRegular);

return new ObservableCollection<KvSubscriptionModel>(result);
}
/// <summary>
/// Sorts an entire subscription model tree, including all nested collections
/// </summary>
public static void SortSubscriptionTree(KvSubscriptionModel subscription)
{
subscription.ResourceGroups = SortResourceGroups(subscription.ResourceGroups);
foreach (var resourceGroup in subscription.ResourceGroups)
{
resourceGroup.KeyVaultResources = SortKeyVaults(resourceGroup.KeyVaultResources);
}
}
}
Loading