Skip to content

Commit fc245e6

Browse files
authored
regression: Enhanced navigation filters regressions (#36748)
1 parent 7ddf710 commit fc245e6

29 files changed

+496
-229
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { SidebarV2Action } from '@rocket.chat/fuselage';
2+
import { GenericMenu } from '@rocket.chat/ui-client';
3+
import type { HTMLAttributes } from 'react';
4+
import { useTranslation } from 'react-i18next';
5+
6+
import { useSortMenu } from './hooks/useSortMenu';
7+
8+
type NavBarItemSortProps = Omit<HTMLAttributes<HTMLElement>, 'is'>;
9+
10+
const NavBarItemSort = (props: NavBarItemSortProps) => {
11+
const { t } = useTranslation();
12+
13+
const sections = useSortMenu();
14+
15+
return <GenericMenu icon='sort' sections={sections} title={t('Display')} selectionMode='multiple' is={SidebarV2Action} {...props} />;
16+
};
17+
18+
export default NavBarItemSort;

apps/meteor/client/NavBarV2/NavBarPagesGroup/NavBarPagesGroup.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import NavBarItemCreateNew from './NavBarItemCreateNew';
66
import NavBarItemDirectoryPage from './NavBarItemDirectoryPage';
77
import NavBarItemHomePage from './NavBarItemHomePage';
88
import NavBarItemMarketPlaceMenu from './NavBarItemMarketPlaceMenu';
9+
import NavBarItemSort from './NavBarItemSort';
910
import NavBarPagesStackMenu from './NavBarPagesStackMenu';
1011

1112
const NavBarPagesGroup = () => {
@@ -26,6 +27,7 @@ const NavBarPagesGroup = () => {
2627
</>
2728
)}
2829
{showMarketplace && !isMobile && <NavBarItemMarketPlaceMenu />}
30+
{!isMobile && <NavBarItemSort />}
2931
<NavBarItemCreateNew />
3032
</NavBarGroup>
3133
);
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { CheckBox } from '@rocket.chat/fuselage';
2+
import type { GenericMenuItemProps } from '@rocket.chat/ui-client';
3+
import { useEndpoint, useUserPreference } from '@rocket.chat/ui-contexts';
4+
import { useCallback } from 'react';
5+
import { useTranslation } from 'react-i18next';
6+
7+
export const useGroupingListItems = (): GenericMenuItemProps[] => {
8+
const { t } = useTranslation();
9+
10+
const sidebarGroupByType = useUserPreference<boolean>('sidebarGroupByType');
11+
const sidebarShowUnread = useUserPreference<boolean>('sidebarShowUnread');
12+
13+
const saveUserPreferences = useEndpoint('POST', '/v1/users.setPreferences');
14+
15+
const useHandleChange = (key: 'sidebarGroupByType' | 'sidebarShowUnread', value: boolean): (() => void) =>
16+
useCallback(() => saveUserPreferences({ data: { [key]: value } }), [key, value]);
17+
18+
const handleChangeGroupByType = useHandleChange('sidebarGroupByType', !sidebarGroupByType);
19+
const handleChangeShowUnread = useHandleChange('sidebarShowUnread', !sidebarShowUnread);
20+
21+
return [
22+
{
23+
id: 'unread',
24+
content: t('Unread'),
25+
icon: 'flag',
26+
addon: <CheckBox onChange={handleChangeShowUnread} checked={sidebarShowUnread} />,
27+
},
28+
{
29+
id: 'types',
30+
content: t('Types'),
31+
icon: 'group-by-type',
32+
addon: <CheckBox onChange={handleChangeGroupByType} checked={sidebarGroupByType} />,
33+
},
34+
];
35+
};
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { renderHook } from '@testing-library/react';
2+
3+
import { useGroupingListItems } from './useGroupingListItems';
4+
5+
it('should render groupingList items', async () => {
6+
const { result } = renderHook(() => useGroupingListItems());
7+
8+
expect(result.current[0]).toEqual(
9+
expect.objectContaining({
10+
id: 'unread',
11+
}),
12+
);
13+
14+
expect(result.current[1]).toEqual(
15+
expect.objectContaining({
16+
id: 'types',
17+
}),
18+
);
19+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { useTranslation } from 'react-i18next';
2+
3+
import { useGroupingListItems } from './useGroupingListItems';
4+
import { useSortModeItems } from './useSortModeItems';
5+
6+
export const useSortMenu = () => {
7+
const { t } = useTranslation();
8+
9+
const sortModeItems = useSortModeItems();
10+
const groupingListItems = useGroupingListItems();
11+
12+
const sections = [
13+
{ title: t('Sort_By'), items: sortModeItems },
14+
{ title: t('Group_by'), items: groupingListItems },
15+
];
16+
17+
return sections;
18+
};
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { renderHook } from '@testing-library/react';
2+
3+
import { useSortModeItems } from './useSortModeItems';
4+
5+
it('should render sortMode items', async () => {
6+
const { result } = renderHook(() => useSortModeItems());
7+
8+
expect(result.current[0]).toEqual(
9+
expect.objectContaining({
10+
id: 'activity',
11+
}),
12+
);
13+
14+
expect(result.current[1]).toEqual(
15+
expect.objectContaining({
16+
id: 'name',
17+
}),
18+
);
19+
});
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { RadioButton } from '@rocket.chat/fuselage';
2+
import type { GenericMenuItemProps } from '@rocket.chat/ui-client';
3+
import { useEndpoint, useUserPreference } from '@rocket.chat/ui-contexts';
4+
import { useCallback } from 'react';
5+
import { useTranslation } from 'react-i18next';
6+
7+
import {
8+
OmnichannelSortingDisclaimer,
9+
useOmnichannelSortingDisclaimer,
10+
} from '../../../components/Omnichannel/OmnichannelSortingDisclaimer';
11+
12+
export const useSortModeItems = (): GenericMenuItemProps[] => {
13+
const { t } = useTranslation();
14+
15+
const saveUserPreferences = useEndpoint('POST', '/v1/users.setPreferences');
16+
const sidebarSortBy = useUserPreference<'activity' | 'alphabetical'>('sidebarSortby', 'activity');
17+
const isOmnichannelEnabled = useOmnichannelSortingDisclaimer();
18+
19+
const useHandleChange = (value: 'alphabetical' | 'activity'): (() => void) =>
20+
useCallback(() => saveUserPreferences({ data: { sidebarSortby: value } }), [value]);
21+
22+
const setToAlphabetical = useHandleChange('alphabetical');
23+
const setToActivity = useHandleChange('activity');
24+
25+
return [
26+
{
27+
id: 'activity',
28+
content: t('Activity'),
29+
icon: 'clock',
30+
addon: <RadioButton onChange={setToActivity} checked={sidebarSortBy === 'activity'} />,
31+
description: sidebarSortBy === 'activity' && isOmnichannelEnabled && <OmnichannelSortingDisclaimer />,
32+
},
33+
{
34+
id: 'name',
35+
content: t('Name'),
36+
icon: 'sort-az',
37+
addon: <RadioButton onChange={setToAlphabetical} checked={sidebarSortBy === 'alphabetical'} />,
38+
description: sidebarSortBy === 'alphabetical' && isOmnichannelEnabled && <OmnichannelSortingDisclaimer />,
39+
},
40+
];
41+
};

apps/meteor/client/components/GenericNoResults/GenericNoResults.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ type GenericNoResultsProps = {
99
icon?: IconName | null;
1010
title?: string;
1111
description?: string;
12-
buttonPrimary?: boolean;
1312
} & LinkProps &
1413
ButtonProps;
1514

@@ -19,7 +18,6 @@ const GenericNoResults = ({
1918
description,
2019
buttonTitle,
2120
buttonAction,
22-
buttonPrimary = true,
2321
linkHref,
2422
linkText,
2523
}: GenericNoResultsProps) => {
@@ -33,9 +31,7 @@ const GenericNoResults = ({
3331
{description && <StatesSubtitle>{description}</StatesSubtitle>}
3432
{buttonTitle && buttonAction && (
3533
<StatesActions>
36-
<StatesAction primary={buttonPrimary} onClick={buttonAction}>
37-
{buttonTitle}
38-
</StatesAction>
34+
<StatesAction onClick={buttonAction}>{buttonTitle}</StatesAction>
3935
</StatesActions>
4036
)}
4137
{linkText && linkHref && (

apps/meteor/client/sidebarv2/RoomList/SidebarItem.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const SidebarItem = ({ icon, title, actions, unread, menu, badges, room, ...prop
2626
const handlePointerEnter = () => setMenuVisibility(true);
2727

2828
return (
29-
<SidebarV2Item {...props} onFocus={handleFocus} onPointerEnter={handlePointerEnter}>
29+
<SidebarV2Item {...props} title={title} onFocus={handleFocus} onPointerEnter={handlePointerEnter}>
3030
<SidebarV2ItemAvatarWrapper>
3131
<RoomAvatar size='x20' room={{ ...room, _id: room.rid || room._id, type: room.t }} />
3232
</SidebarV2ItemAvatarWrapper>

apps/meteor/client/sidebarv2/RoomList/SidebarItemWithData.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ type RoomListRowProps = {
2929

3030
const SidebarItemWithData = ({ room, id, style, t, videoConfActions }: RoomListRowProps) => {
3131
const title = roomCoordinator.getRoomName(room.t, room) || '';
32+
const href = roomCoordinator.getRouteLink(room.t, room) || '';
33+
3234
const { unreadTitle, unreadVariant, showUnread, unreadCount, highlightUnread: highlighted } = useUnreadDisplay(room);
3335

3436
const icon = (
@@ -85,17 +87,15 @@ const SidebarItemWithData = ({ room, id, style, t, videoConfActions }: RoomListR
8587
switchSidePanelTab('channels', { parentRid: room.rid });
8688
}, [room, switchSidePanelTab]);
8789

88-
const buttonProps = useButtonPattern((e) => {
89-
e.preventDefault();
90-
handleClick();
91-
});
90+
const buttonProps = useButtonPattern(handleClick);
9291

9392
return (
9493
<SidebarItem
9594
id={id}
9695
data-qa='sidebar-item'
9796
data-unread={highlighted}
9897
unread={highlighted}
98+
href={href}
9999
selected={selected}
100100
aria-label={showUnread ? t('__unreadTitle__from__roomTitle__', { unreadTitle, roomTitle: title }) : title}
101101
title={title}

0 commit comments

Comments
 (0)