From 23c9bf2fc9c831dd0edbfae0469cca023255440d Mon Sep 17 00:00:00 2001 From: Leendert de Borst Date: Wed, 26 Nov 2025 11:09:41 +0100 Subject: [PATCH] Fix related users navigation refresh in admin (#1400) --- .../View/Components/RelatedUsersTable.razor | 25 +++++++++++++++++++ .../Main/Pages/Users/View/Index.razor | 12 +++++++++ 2 files changed, 37 insertions(+) diff --git a/apps/server/AliasVault.Admin/Main/Pages/Users/View/Components/RelatedUsersTable.razor b/apps/server/AliasVault.Admin/Main/Pages/Users/View/Components/RelatedUsersTable.razor index 533e1031c..f38ba8994 100644 --- a/apps/server/AliasVault.Admin/Main/Pages/Users/View/Components/RelatedUsersTable.razor +++ b/apps/server/AliasVault.Admin/Main/Pages/Users/View/Components/RelatedUsersTable.razor @@ -15,6 +15,8 @@ else if (RelatedUsers.Any()) @relatedUser.SharedIpAddresses.ToString("N0") @relatedUser.MostRecentSharedIp + @relatedUser.CredentialsCount.ToString("N0") + @relatedUser.EmailClaimsCount.ToString("N0") @relatedUser.RegistrationDate.ToString("yyyy-MM-dd HH:mm") @@ -65,6 +67,8 @@ else new TableColumn { Title = "Username", PropertyName = "Username" }, new TableColumn { Title = "Shared IPs", PropertyName = "SharedIpAddresses" }, new TableColumn { Title = "Most Recent IP", PropertyName = "MostRecentSharedIp" }, + new TableColumn { Title = "Credentials", PropertyName = "CredentialsCount" }, + new TableColumn { Title = "Email Claims", PropertyName = "EmailClaimsCount" }, new TableColumn { Title = "Registered", PropertyName = "RegistrationDate" }, new TableColumn { Title = "Status", PropertyName = "IsBlocked" }, ]; @@ -152,15 +156,32 @@ else TotalRelatedUsers = users.Count; + // Get vault statistics for all related users (from their latest vault) + var userIds = users.Select(u => u.Id).ToList(); + var vaultStats = await dbContext.Vaults + .Where(v => userIds.Contains(v.UserId)) + .GroupBy(v => v.UserId) + .Select(g => new + { + UserId = g.Key, + CredentialsCount = g.OrderByDescending(v => v.RevisionNumber).First().CredentialsCount, + EmailClaimsCount = g.OrderByDescending(v => v.RevisionNumber).First().EmailClaimsCount + }) + .ToListAsync(); + // Combine the data RelatedUsers = (from user in users join data in relatedUserData on user.UserName equals data.Username + join vaultStat in vaultStats on user.Id equals vaultStat.UserId into vaultGroup + from vault in vaultGroup.DefaultIfEmpty() select new RelatedUserInfo { UserId = user.Id, Username = user.UserName ?? "Unknown", SharedIpAddresses = data.SharedIps, MostRecentSharedIp = data.MostRecentSharedIp ?? "-", + CredentialsCount = vault?.CredentialsCount ?? 0, + EmailClaimsCount = vault?.EmailClaimsCount ?? 0, RegistrationDate = user.CreatedAt, IsBlocked = user.Blocked }) @@ -186,6 +207,8 @@ else "Username" => SortableTable.SortListByProperty(relatedUsers, r => r.Username, sortDirection), "SharedIpAddresses" => SortableTable.SortListByProperty(relatedUsers, r => r.SharedIpAddresses, sortDirection), "MostRecentSharedIp" => SortableTable.SortListByProperty(relatedUsers, r => r.MostRecentSharedIp, sortDirection), + "CredentialsCount" => SortableTable.SortListByProperty(relatedUsers, r => r.CredentialsCount, sortDirection), + "EmailClaimsCount" => SortableTable.SortListByProperty(relatedUsers, r => r.EmailClaimsCount, sortDirection), "RegistrationDate" => SortableTable.SortListByProperty(relatedUsers, r => r.RegistrationDate, sortDirection), "IsBlocked" => SortableTable.SortListByProperty(relatedUsers, r => r.IsBlocked, sortDirection), _ => relatedUsers @@ -206,6 +229,8 @@ else public string Username { get; set; } = string.Empty; public int SharedIpAddresses { get; set; } public string MostRecentSharedIp { get; set; } = string.Empty; + public int CredentialsCount { get; set; } + public int EmailClaimsCount { get; set; } public DateTime RegistrationDate { get; set; } public bool IsBlocked { get; set; } } diff --git a/apps/server/AliasVault.Admin/Main/Pages/Users/View/Index.razor b/apps/server/AliasVault.Admin/Main/Pages/Users/View/Index.razor index 3919f7b75..b070456c6 100644 --- a/apps/server/AliasVault.Admin/Main/Pages/Users/View/Index.razor +++ b/apps/server/AliasVault.Admin/Main/Pages/Users/View/Index.razor @@ -332,6 +332,18 @@ else } } + /// + protected override async Task OnParametersSetAsync() + { + await base.OnParametersSetAsync(); + + // Refresh data when navigating to a different user (e.g., clicking related user links) + if (!IsLoading && User?.Id != Id) + { + await RefreshData(); + } + } + private async Task RefreshData() { IsLoading = true;