diff --git a/.changeset/quiet-lions-unite.md b/.changeset/quiet-lions-unite.md new file mode 100644 index 000000000000..723d773c0b02 --- /dev/null +++ b/.changeset/quiet-lions-unite.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': patch +--- + +Fixes sidepanel list not sorting by last message inside thread diff --git a/apps/meteor/client/sidebarv2/RoomList/RoomListRow.tsx b/apps/meteor/client/sidebarv2/RoomList/RoomListRow.tsx index 473fad9b0e42..af4a7f66ffde 100644 --- a/apps/meteor/client/sidebarv2/RoomList/RoomListRow.tsx +++ b/apps/meteor/client/sidebarv2/RoomList/RoomListRow.tsx @@ -1,4 +1,4 @@ -import type { IRoom, ISubscription } from '@rocket.chat/core-typings'; +import type { SubscriptionWithRoom } from '@rocket.chat/ui-contexts'; import type { TFunction } from 'i18next'; import React, { memo, useMemo } from 'react'; @@ -17,7 +17,7 @@ type RoomListRowProps = { sidebarViewMode: 'extended' | 'condensed' | 'medium'; isAnonymous: boolean; }; - item: ISubscription & IRoom; + item: SubscriptionWithRoom; }; const RoomListRow = ({ data, item }: RoomListRowProps) => { diff --git a/apps/meteor/client/sidebarv2/RoomList/SidebarItemTemplateWithData.tsx b/apps/meteor/client/sidebarv2/RoomList/SidebarItemTemplateWithData.tsx index 5417d3075c1e..b0961aeeb616 100644 --- a/apps/meteor/client/sidebarv2/RoomList/SidebarItemTemplateWithData.tsx +++ b/apps/meteor/client/sidebarv2/RoomList/SidebarItemTemplateWithData.tsx @@ -1,6 +1,7 @@ -import type { IMessage, IRoom, ISubscription } from '@rocket.chat/core-typings'; +import type { IMessage } from '@rocket.chat/core-typings'; import { isDirectMessageRoom, isMultipleDirectMessageRoom, isOmnichannelRoom, isVideoConfMessage } from '@rocket.chat/core-typings'; import { SidebarV2Action, SidebarV2Actions, SidebarV2ItemBadge, SidebarV2ItemIcon } from '@rocket.chat/fuselage'; +import type { SubscriptionWithRoom } from '@rocket.chat/ui-contexts'; import { useLayout } from '@rocket.chat/ui-contexts'; import type { TFunction } from 'i18next'; import type { AllHTMLAttributes, ComponentType, ReactElement, ReactNode } from 'react'; @@ -16,7 +17,7 @@ import { OmnichannelBadges } from '../badges/OmnichannelBadges'; import type { useAvatarTemplate } from '../hooks/useAvatarTemplate'; import { useUnreadDisplay } from '../hooks/useUnreadDisplay'; -export const getMessage = (room: IRoom, lastMessage: IMessage | undefined, t: TFunction): string | undefined => { +export const getMessage = (room: SubscriptionWithRoom, lastMessage: IMessage | undefined, t: TFunction): string | undefined => { if (!lastMessage) { return t('No_messages_yet'); } @@ -62,7 +63,7 @@ type RoomListRowProps = { // sidebarViewMode: 'extended'; isAnonymous?: boolean; - room: ISubscription & IRoom; + room: SubscriptionWithRoom; id?: string; /* @deprecated */ style?: AllHTMLAttributes['style']; diff --git a/apps/meteor/client/sidebarv2/header/hooks/useSearchItems.ts b/apps/meteor/client/sidebarv2/header/hooks/useSearchItems.ts index 7dfdb577dd9f..cc7bf02249b7 100644 --- a/apps/meteor/client/sidebarv2/header/hooks/useSearchItems.ts +++ b/apps/meteor/client/sidebarv2/header/hooks/useSearchItems.ts @@ -1,5 +1,5 @@ -import type { IRoom, ISubscription } from '@rocket.chat/core-typings'; import { escapeRegExp } from '@rocket.chat/string-helpers'; +import type { SubscriptionWithRoom } from '@rocket.chat/ui-contexts'; import { useMethod, useUserSubscriptions } from '@rocket.chat/ui-contexts'; import { useQuery, type UseQueryResult } from '@tanstack/react-query'; import { useMemo } from 'react'; @@ -16,7 +16,7 @@ const options = { limit: LIMIT, } as const; -export const useSearchItems = (filterText: string): UseQueryResult<(ISubscription & IRoom)[] | undefined, Error> => { +export const useSearchItems = (filterText: string): UseQueryResult => { const [, mention, name] = useMemo(() => filterText.match(/(@|#)?(.*)/i) || [], [filterText]); const query = useMemo(() => { const filterRegex = new RegExp(escapeRegExp(name), 'i'); diff --git a/apps/meteor/client/sidebarv2/hooks/useAvatarTemplate.tsx b/apps/meteor/client/sidebarv2/hooks/useAvatarTemplate.tsx index e5bf780ee5b0..8d31f0818857 100644 --- a/apps/meteor/client/sidebarv2/hooks/useAvatarTemplate.tsx +++ b/apps/meteor/client/sidebarv2/hooks/useAvatarTemplate.tsx @@ -1,5 +1,5 @@ -import type { IRoom } from '@rocket.chat/core-typings'; import { RoomAvatar } from '@rocket.chat/ui-avatar'; +import type { SubscriptionWithRoom } from '@rocket.chat/ui-contexts'; import { useUserPreference } from '@rocket.chat/ui-contexts'; import type { ComponentType } from 'react'; import React, { useMemo } from 'react'; @@ -7,7 +7,7 @@ import React, { useMemo } from 'react'; export const useAvatarTemplate = ( sidebarViewMode?: 'extended' | 'medium' | 'condensed', sidebarDisplayAvatar?: boolean, -): null | ComponentType => { +): null | ComponentType => { const sidebarViewModeFromSettings = useUserPreference<'extended' | 'medium' | 'condensed'>('sidebarViewMode'); const sidebarDisplayAvatarFromSettings = useUserPreference('sidebarDisplayAvatar'); @@ -30,7 +30,7 @@ export const useAvatarTemplate = ( } })(); - const renderRoomAvatar: ComponentType = (room) => ( + const renderRoomAvatar: ComponentType = (room) => ( ); diff --git a/apps/meteor/client/sidebarv2/hooks/useRoomList.ts b/apps/meteor/client/sidebarv2/hooks/useRoomList.ts index 921d956147ba..bebaf962ecf3 100644 --- a/apps/meteor/client/sidebarv2/hooks/useRoomList.ts +++ b/apps/meteor/client/sidebarv2/hooks/useRoomList.ts @@ -1,4 +1,4 @@ -import type { ILivechatInquiryRecord, IRoom, ISubscription } from '@rocket.chat/core-typings'; +import type { ILivechatInquiryRecord } from '@rocket.chat/core-typings'; import { useDebouncedValue } from '@rocket.chat/fuselage-hooks'; import type { SubscriptionWithRoom, TranslationKey } from '@rocket.chat/ui-contexts'; import { useUserPreference, useUserSubscriptions, useSetting } from '@rocket.chat/ui-contexts'; @@ -28,7 +28,7 @@ const order = [ ] as const; type useRoomListReturnType = { - roomList: Array; + roomList: Array; groupsCount: number[]; groupsList: TranslationKey[]; groupedUnreadInfo: Pick< diff --git a/apps/meteor/client/sidebarv2/search/Row.tsx b/apps/meteor/client/sidebarv2/search/Row.tsx index c0d332c5fa7e..1cd61299dea3 100644 --- a/apps/meteor/client/sidebarv2/search/Row.tsx +++ b/apps/meteor/client/sidebarv2/search/Row.tsx @@ -1,4 +1,4 @@ -import type { IRoom, ISubscription } from '@rocket.chat/core-typings'; +import type { SubscriptionWithRoom } from '@rocket.chat/ui-contexts'; import type { ReactElement } from 'react'; import React, { memo } from 'react'; @@ -6,7 +6,7 @@ import UserItem from './UserItem'; import SidebarItemTemplateWithData from '../RoomList/SidebarItemTemplateWithData'; type RowProps = { - item: ISubscription & IRoom; + item: SubscriptionWithRoom; data: Record; }; diff --git a/apps/meteor/client/views/room/Sidepanel/SidepanelItem/RoomSidepanelItem.tsx b/apps/meteor/client/views/room/Sidepanel/SidepanelItem/RoomSidepanelItem.tsx index 4181b13765de..b17db4fc7082 100644 --- a/apps/meteor/client/views/room/Sidepanel/SidepanelItem/RoomSidepanelItem.tsx +++ b/apps/meteor/client/views/room/Sidepanel/SidepanelItem/RoomSidepanelItem.tsx @@ -1,5 +1,4 @@ -import type { IRoom, ISubscription } from '@rocket.chat/core-typings'; -import { useUserSubscription } from '@rocket.chat/ui-contexts'; +import type { SubscriptionWithRoom } from '@rocket.chat/ui-contexts'; import React, { memo } from 'react'; import { goToRoomById } from '../../../../lib/utils/goToRoomById'; @@ -8,20 +7,15 @@ import { useItemData } from '../hooks/useItemData'; type RoomSidepanelItemProps = { openedRoom?: string; - room: IRoom; + room: SubscriptionWithRoom; parentRid: string; viewMode?: 'extended' | 'medium' | 'condensed'; }; const RoomSidepanelItem = ({ room, openedRoom, viewMode }: RoomSidepanelItemProps) => { const SidepanelItem = useTemplateByViewMode(); - const subscription = useUserSubscription(room._id); - const itemData = useItemData({ ...room, ...subscription } as ISubscription & IRoom, { viewMode, openedRoom }); // as any because of divergent and overlaping timestamp types in subs and room (type Date vs type string) - - if (!subscription) { - return ; - } + const itemData = useItemData(room, { viewMode, openedRoom }); return ; }; diff --git a/apps/meteor/client/views/room/Sidepanel/hooks/useItemData.tsx b/apps/meteor/client/views/room/Sidepanel/hooks/useItemData.tsx index bdf3ceb65ee6..06d89c1cfde5 100644 --- a/apps/meteor/client/views/room/Sidepanel/hooks/useItemData.tsx +++ b/apps/meteor/client/views/room/Sidepanel/hooks/useItemData.tsx @@ -1,5 +1,5 @@ -import type { IRoom, ISubscription } from '@rocket.chat/core-typings'; import { SidebarV2ItemBadge as SidebarItemBadge, SidebarV2ItemIcon as SidebarItemIcon } from '@rocket.chat/fuselage'; +import type { SubscriptionWithRoom } from '@rocket.chat/ui-contexts'; import React, { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; @@ -10,7 +10,7 @@ import { useAvatarTemplate } from '../../../../sidebarv2/hooks/useAvatarTemplate import { useUnreadDisplay } from '../../../../sidebarv2/hooks/useUnreadDisplay'; export const useItemData = ( - room: ISubscription & IRoom, + room: SubscriptionWithRoom, { openedRoom, viewMode }: { openedRoom: string | undefined; viewMode?: 'extended' | 'medium' | 'condensed' }, ) => { const { t } = useTranslation(); diff --git a/apps/meteor/client/views/room/Sidepanel/hooks/useTeamslistChildren.ts b/apps/meteor/client/views/room/Sidepanel/hooks/useTeamslistChildren.ts index e186a3b0a806..f18753ed15c1 100644 --- a/apps/meteor/client/views/room/Sidepanel/hooks/useTeamslistChildren.ts +++ b/apps/meteor/client/views/room/Sidepanel/hooks/useTeamslistChildren.ts @@ -1,9 +1,9 @@ -import type { IRoom } from '@rocket.chat/core-typings'; +import type { ISubscription } from '@rocket.chat/core-typings'; import { useQuery } from '@tanstack/react-query'; import type { Mongo } from 'meteor/mongo'; import { useEffect, useMemo } from 'react'; -import { Rooms } from '../../../../../app/models/client'; +import { Subscriptions } from '../../../../../app/models/client'; import { useSortQueryOptions } from '../../../../hooks/useSortQueryOptions'; export const useTeamsListChildrenUpdate = ( @@ -14,7 +14,7 @@ export const useTeamsListChildrenUpdate = ( const options = useSortQueryOptions(); const query = useMemo(() => { - const query: Mongo.Selector = { + const query: Mongo.Selector = { $or: [ { _id: parentRid, @@ -38,7 +38,7 @@ export const useTeamsListChildrenUpdate = ( const result = useQuery({ queryKey: ['sidepanel', 'list', parentRid, sidepanelItems, options], - queryFn: () => Rooms.find(query, options).fetch(), + queryFn: () => Subscriptions.find(query, options).fetch(), enabled: sidepanelItems !== null && teamId !== null, refetchInterval: 5 * 60 * 1000, keepPreviousData: true, @@ -47,7 +47,7 @@ export const useTeamsListChildrenUpdate = ( const { refetch } = result; useEffect(() => { - const liveQueryHandle = Rooms.find(query).observe({ + const liveQueryHandle = Subscriptions.find(query).observe({ added: () => queueMicrotask(() => refetch({ exact: false })), changed: () => queueMicrotask(() => refetch({ exact: false })), removed: () => queueMicrotask(() => refetch({ exact: false })), diff --git a/apps/meteor/tests/e2e/feature-preview.spec.ts b/apps/meteor/tests/e2e/feature-preview.spec.ts index 4e6b62827c85..85969debb8fc 100644 --- a/apps/meteor/tests/e2e/feature-preview.spec.ts +++ b/apps/meteor/tests/e2e/feature-preview.spec.ts @@ -280,8 +280,7 @@ test.describe.serial('feature preview', () => { await expect(poHomeChannel.sidepanel.getItemByName(targetChannel)).toBeVisible(); }); - // remove .fail after fix - test.fail('should sort by last message even if unread message is inside thread', async ({ page, browser }) => { + test('should sort by last message even if unread message is inside thread', async ({ page, browser }) => { const user1Page = await browser.newPage({ storageState: Users.user1.state }); const user1Channel = new HomeChannel(user1Page);