From 4550c4130b471f746ff2dd112528a3778b6e27df Mon Sep 17 00:00:00 2001 From: Sony Mathew Date: Fri, 22 May 2026 13:11:29 +0530 Subject: [PATCH] fix: order labels, teams, channels in sidebar by unread count (CW-7151) (#14510) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Pull Request Template ## Description Ordered the conversation sidebar labels, teams and channels by the unread count. Fixes # CW-7151 ## Type of change Please delete options that are not relevant. - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality not to work as expected) - [ ] This change requires a documentation update ## How Has This Been Tested? Verified manually. Adding the screenshot below. Screenshot 2026-05-20 at 10 24 30 PM ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --- .../components-next/sidebar/Sidebar.vue | 42 +++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/app/javascript/dashboard/components-next/sidebar/Sidebar.vue b/app/javascript/dashboard/components-next/sidebar/Sidebar.vue index a71cd680c..d9f523dfc 100644 --- a/app/javascript/dashboard/components-next/sidebar/Sidebar.vue +++ b/app/javascript/dashboard/components-next/sidebar/Sidebar.vue @@ -204,8 +204,44 @@ watch([accountId, hasConversationUnreadCounts], fetchConversationUnreadCounts, { immediate: true, }); +const normalizeUnreadCount = count => { + const unreadCount = Number(count); + return Number.isFinite(unreadCount) && unreadCount > 0 ? unreadCount : 0; +}; + +const sortByUnreadCount = (items, labelKey, unreadCountKey) => + items.slice().sort((a, b) => { + const unreadCountDiff = + normalizeUnreadCount(unreadCountKey(b)) - + normalizeUnreadCount(unreadCountKey(a)); + + if (unreadCountDiff !== 0) return unreadCountDiff; + + return labelKey(a).localeCompare(labelKey(b)); + }); + +const sortedTeams = computed(() => + sortByUnreadCount( + teams.value, + team => team.name, + team => getTeamUnreadCount.value(team.id) + ) +); + const sortedInboxes = computed(() => - inboxes.value.slice().sort((a, b) => a.name.localeCompare(b.name)) + sortByUnreadCount( + inboxes.value, + inbox => inbox.name, + inbox => getInboxUnreadCount.value(inbox.id) + ) +); + +const sortedLabels = computed(() => + sortByUnreadCount( + labels.value, + label => label.title, + label => getLabelUnreadCount.value(label.id) + ) ); const closeMobileSidebar = () => { @@ -298,7 +334,7 @@ const menuItems = computed(() => { label: t('SIDEBAR.TEAMS'), icon: 'i-lucide-users', activeOn: ['conversations_through_team'], - children: teams.value.map(team => ({ + children: sortedTeams.value.map(team => ({ name: `${team.name}-${team.id}`, label: team.name, badgeCount: getTeamUnreadCount.value(team.id), @@ -330,7 +366,7 @@ const menuItems = computed(() => { label: t('SIDEBAR.LABELS'), icon: 'i-lucide-tag', activeOn: ['conversations_through_label'], - children: labels.value.map(label => ({ + children: sortedLabels.value.map(label => ({ name: `${label.title}-${label.id}`, label: label.title, badgeCount: getLabelUnreadCount.value(label.id),