From fa0f2d994baa1612f1dba906723915be7fe3b39d Mon Sep 17 00:00:00 2001 From: Leendert de Borst Date: Sun, 26 Apr 2026 18:51:30 +0200 Subject: [PATCH] Update web app to refresh folder counts when a filter is active (#1970) --- .../Main/Pages/Items/Home.razor | 60 +++++++++++++++---- 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/apps/server/AliasVault.Client/Main/Pages/Items/Home.razor b/apps/server/AliasVault.Client/Main/Pages/Items/Home.razor index d6fbcc22d..dc9a93ecd 100644 --- a/apps/server/AliasVault.Client/Main/Pages/Items/Home.razor +++ b/apps/server/AliasVault.Client/Main/Pages/Items/Home.razor @@ -361,9 +361,21 @@ else /// /// Gets the folders to display at the current level (root folders if not in folder, subfolders if in folder). + /// Item counts are recomputed against the active filter so that folder badges always + /// reflect the number of items the user will actually see when navigating into the folder. /// private List CurrentLevelFolders => - Folders.Where(f => f.ParentFolderId == FolderId).ToList(); + Folders + .Where(f => f.ParentFolderId == FolderId) + .Select(f => new FolderWithCount + { + Id = f.Id, + Name = f.Name, + ParentFolderId = f.ParentFolderId, + Weight = f.Weight, + ItemCount = GetFilteredItemCountForFolder(f.Id), + }) + .ToList(); /// /// Gets whether we can create a subfolder at the current level. @@ -557,17 +569,7 @@ else } // Then apply type/feature filter - filtered = FilterType switch - { - ItemFilterType.Passkeys => filtered.Where(x => x.HasPasskey), - ItemFilterType.Attachments => filtered.Where(x => x.HasAttachment), - ItemFilterType.Totp => filtered.Where(x => x.HasTotp), - ItemFilterType.Login => filtered.Where(x => x.ItemType == ItemType.Login), - ItemFilterType.Alias => filtered.Where(x => x.ItemType == ItemType.Alias), - ItemFilterType.CreditCard => filtered.Where(x => x.ItemType == ItemType.CreditCard), - ItemFilterType.Note => filtered.Where(x => x.ItemType == ItemType.Note), - _ => filtered, // All - }; + filtered = ApplyTypeFilter(filtered); // Apply sort - use table column sort if in table view, otherwise use settings dropdown sort if (ViewMode == "table") @@ -584,6 +586,40 @@ else } } + /// + /// Applies the active type/feature filter to a sequence of items. + /// + /// The items to filter. + /// The filtered items. + private IEnumerable ApplyTypeFilter(IEnumerable items) + { + return FilterType switch + { + ItemFilterType.Passkeys => items.Where(x => x.HasPasskey), + ItemFilterType.Attachments => items.Where(x => x.HasAttachment), + ItemFilterType.Totp => items.Where(x => x.HasTotp), + ItemFilterType.Login => items.Where(x => x.ItemType == ItemType.Login), + ItemFilterType.Alias => items.Where(x => x.ItemType == ItemType.Alias), + ItemFilterType.CreditCard => items.Where(x => x.ItemType == ItemType.CreditCard), + ItemFilterType.Note => items.Where(x => x.ItemType == ItemType.Note), + _ => items, // All + }; + } + + /// + /// Counts the items in a folder (and all of its descendants) that pass the active type/feature filter. + /// + /// The folder ID. + /// The filtered, recursive item count. + private int GetFilteredItemCountForFolder(Guid folderId) + { + var descendantIds = FolderTreeUtilities.GetDescendantFolderIds(folderId, AllFolders); + var folderIds = new HashSet(descendantIds) { folderId }; + + return ApplyTypeFilter(Items) + .Count(item => item.FolderId.HasValue && folderIds.Contains(item.FolderId.Value)); + } + /// /// Applies table column sorting to the filtered items. ///