-
Notifications
You must be signed in to change notification settings - Fork 13.6k
feat(sidebar): add Teams and channels merged category #40750
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| --- | ||
| '@rocket.chat/meteor': minor | ||
| '@rocket.chat/rest-typings': minor | ||
| --- | ||
|
|
||
| Adds two sidebar grouping user preferences: | ||
|
|
||
| - `sidebarGroupTeamsAndChannels`: merges the Teams and Channels sidebar groups into a single "Teams and channels" category when grouping by type is enabled. | ||
| - `sidebarGroupUnlistedInConversations`: routes rooms whose group is not part of the visible sidebar sections into "Conversations" instead of dropping them from the sidebar. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,10 +25,16 @@ const order = [ | |
| 'Teams', | ||
| 'Discussions', | ||
| 'Channels', | ||
| 'Teams_and_channels', | ||
| 'Direct_Messages', | ||
| 'Conversations', | ||
| ] as const; | ||
|
|
||
| // Type groups that hold regular conversations and can be routed into "Conversations" | ||
| // when they are not part of the visible sidebar sections. Override buckets (Unread, | ||
| // Drafts, Favorites) and system groups (omnichannel, incoming calls) are excluded. | ||
| const routableGroups: string[] = ['Teams', 'Discussions', 'Channels', 'Teams_and_channels', 'Direct_Messages']; | ||
|
|
||
| type useRoomListReturnType = { | ||
| roomList: Array<SubscriptionWithRoom>; | ||
| groupsCount: number[]; | ||
|
|
@@ -41,6 +47,8 @@ type useRoomListReturnType = { | |
| export const useRoomList = ({ collapsedGroups }: { collapsedGroups?: string[] }): useRoomListReturnType => { | ||
| const showOmnichannel = useOmnichannelEnabled(); | ||
| const sidebarGroupByType = useUserPreference('sidebarGroupByType'); | ||
| const sidebarGroupTeamsAndChannels = useUserPreference('sidebarGroupTeamsAndChannels'); | ||
| const groupUnlistedInConversations = useUserPreference('sidebarGroupUnlistedInConversations'); | ||
| const favoritesEnabled = useUserPreference('sidebarShowFavorites'); | ||
| const sidebarDrafts = useFeaturePreview('sidebarDrafts'); | ||
| const sidebarOrder = useUserPreference<typeof order>('sidebarSectionsOrder') ?? order; | ||
|
|
@@ -134,17 +142,56 @@ export const useRoomList = ({ collapsedGroups }: { collapsedGroups?: string[] }) | |
|
|
||
| favoritesEnabled && favorite.size && groups.set('Favorites', favorite); | ||
|
|
||
| sidebarGroupByType && team.size && groups.set('Teams', team); | ||
| const mergeTeamsAndChannels = sidebarGroupByType && sidebarGroupTeamsAndChannels; | ||
|
|
||
| sidebarGroupByType && !mergeTeamsAndChannels && team.size && groups.set('Teams', team); | ||
|
|
||
| sidebarGroupByType && isDiscussionEnabled && discussion.size && groups.set('Discussions', discussion); | ||
|
|
||
| sidebarGroupByType && channels.size && groups.set('Channels', channels); | ||
| sidebarGroupByType && !mergeTeamsAndChannels && channels.size && groups.set('Channels', channels); | ||
|
|
||
| if (mergeTeamsAndChannels) { | ||
| const teamsAndChannels = new Set([...team, ...channels]); | ||
| teamsAndChannels.size && groups.set('Teams_and_channels', teamsAndChannels); | ||
| } | ||
|
|
||
| sidebarGroupByType && direct.size && groups.set('Direct_Messages', direct); | ||
|
|
||
| !sidebarGroupByType && groups.set('Conversations', conversation); | ||
|
|
||
| const { groupsCount, groupsList, roomList, groupedUnreadInfo } = sidebarOrder.reduce( | ||
| // Users with a `sidebarSectionsOrder` saved before this group existed won't have the | ||
| // 'Teams_and_channels' key, so the merged group would never render. Inject it after 'Channels'. | ||
| // Build the render order. Users with a `sidebarSectionsOrder` saved before the | ||
| // 'Teams_and_channels' group existed won't have the key, so inject it after 'Channels'. | ||
| const effectiveOrder: string[] = [...sidebarOrder]; | ||
| if (!effectiveOrder.includes('Teams_and_channels')) { | ||
| const channelsIndex = effectiveOrder.indexOf('Channels'); | ||
| effectiveOrder.splice(channelsIndex === -1 ? effectiveOrder.length : channelsIndex + 1, 0, 'Teams_and_channels'); | ||
| } | ||
|
Comment on lines
+166
to
+170
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Only inject This reinserts the merged section whenever the key is absent, which makes it impossible to hide that group via Proposed fix const effectiveOrder: string[] = [...sidebarOrder];
- if (!effectiveOrder.includes('Teams_and_channels')) {
+ const shouldInjectMergedGroup =
+ mergeTeamsAndChannels &&
+ !effectiveOrder.includes('Teams_and_channels') &&
+ (effectiveOrder.includes('Teams') || effectiveOrder.includes('Channels'));
+
+ if (shouldInjectMergedGroup) {
const channelsIndex = effectiveOrder.indexOf('Channels');
effectiveOrder.splice(channelsIndex === -1 ? effectiveOrder.length : channelsIndex + 1, 0, 'Teams_and_channels');
}🤖 Prompt for AI Agents |
||
|
|
||
| // When enabled, rooms belonging to a routable group that is not part of the visible | ||
| // sections would otherwise vanish from the sidebar. Route them into "Conversations" | ||
| // instead of dropping them. | ||
| if (sidebarGroupByType && groupUnlistedInConversations) { | ||
| const unlisted = new Set<SubscriptionWithRoom>(); | ||
| for (const [key, set] of groups) { | ||
| if (!routableGroups.includes(key) || effectiveOrder.includes(key)) { | ||
| continue; | ||
| } | ||
| set.forEach((room) => unlisted.add(room as SubscriptionWithRoom)); | ||
| groups.delete(key); | ||
| } | ||
|
|
||
| if (unlisted.size) { | ||
| const existing = groups.get('Conversations'); | ||
| groups.set('Conversations', existing ? new Set([...existing, ...unlisted]) : unlisted); | ||
| if (!effectiveOrder.includes('Conversations')) { | ||
| effectiveOrder.push('Conversations'); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| const { groupsCount, groupsList, roomList, groupedUnreadInfo } = effectiveOrder.reduce( | ||
| (acc, key) => { | ||
| const value = groups.get(key); | ||
|
|
||
|
|
@@ -208,6 +255,8 @@ export const useRoomList = ({ collapsedGroups }: { collapsedGroups?: string[] }) | |
| sidebarShowUnread, | ||
| favoritesEnabled, | ||
| sidebarGroupByType, | ||
| sidebarGroupTeamsAndChannels, | ||
| groupUnlistedInConversations, | ||
| isDiscussionEnabled, | ||
| sidebarOrder, | ||
| collapsedGroups, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Unconditionally injecting
Teams_and_channelsintoeffectiveOrderwhenever it is absent makes it impossible for users to intentionally hide this group (it always gets re-added) and prevents the unlisted-to-Conversations routing from applying to merged-group rooms. Gate the injection onmergeTeamsAndChannelsbeing active and on a legacy-order signal (e.g.,TeamsorChannelsstill being present in the saved order).Prompt for AI agents