Skip to content

Commit

Permalink
Merge branch 'develop' into imported-fixes-2025-01-07
Browse files Browse the repository at this point in the history
  • Loading branch information
julio-rocketchat authored Jan 8, 2025
2 parents c68a8d6 + 1cc2bc7 commit d7a77b1
Show file tree
Hide file tree
Showing 7 changed files with 455 additions and 84 deletions.
5 changes: 5 additions & 0 deletions .changeset/kind-ducks-thank.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Fixes apps actions showing in toolbar without an icon
46 changes: 4 additions & 42 deletions apps/meteor/client/views/room/Header/RoomToolbox/RoomToolbox.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import type { Box } from '@rocket.chat/fuselage';
import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
import { GenericMenu } from '@rocket.chat/ui-client';
import type { GenericMenuItemProps } from '@rocket.chat/ui-client';
import { useLayout } from '@rocket.chat/ui-contexts';
import type { ComponentProps } from 'react';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';

import { useRoomToolboxActions } from './hooks/useRoomToolboxActions';
import { HeaderToolbarAction, HeaderToolbarDivider } from '../../../../components/Header';
import { useRoomToolbox } from '../../contexts/RoomToolboxContext';
import type { RoomToolboxActionConfig } from '../../contexts/RoomToolboxContext';
Expand All @@ -15,48 +14,13 @@ type RoomToolboxProps = {
className?: ComponentProps<typeof Box>['className'];
};

type MenuActionsProps = {
id: string;
items: GenericMenuItemProps[];
}[];

const RoomToolbox = ({ className }: RoomToolboxProps) => {
const { t } = useTranslation();
const { roomToolboxExpanded } = useLayout();

const toolbox = useRoomToolbox();
const { actions, openTab } = toolbox;

const featuredActions = actions.filter((action) => action.featured);
const normalActions = actions.filter((action) => !action.featured);
const visibleActions = !roomToolboxExpanded ? [] : normalActions.slice(0, 6);

const hiddenActions = (!roomToolboxExpanded ? actions : normalActions.slice(6))
.filter((item) => !item.disabled && !item.featured)
.map((item) => ({
'key': item.id,
'content': t(item.title),
'onClick':
item.action ??
((): void => {
openTab(item.id);
}),
'data-qa-id': `ToolBoxAction-${item.icon}`,
...item,
}))
.reduce((acc, item) => {
const group = item.type ? item.type : '';
const section = acc.find((section: { id: string }) => section.id === group);
if (section) {
section.items.push(item);
return acc;
}

const newSection = { id: group, key: item.key, title: group === 'apps' ? t('Apps') : '', items: [item] };
acc.push(newSection);
const { featuredActions, hiddenActions, visibleActions } = useRoomToolboxActions(toolbox);

return acc;
}, [] as MenuActionsProps);
const showKebabMenu = hiddenActions.length > 0;

const renderDefaultToolboxItem: RoomToolboxActionConfig['renderToolboxItem'] = useEffectEvent(
({ id, className, index, icon, title, toolbox: { tab }, action, disabled, tooltip }) => {
Expand Down Expand Up @@ -92,9 +56,7 @@ const RoomToolbox = ({ className }: RoomToolboxProps) => {
{featuredActions.map(mapToToolboxItem)}
{featuredActions.length > 0 && <HeaderToolbarDivider />}
{visibleActions.map(mapToToolboxItem)}
{(normalActions.length > 6 || !roomToolboxExpanded) && !!hiddenActions.length && (
<GenericMenu title={t('Options')} data-qa-id='ToolBox-Menu' sections={hiddenActions} placement='bottom-end' />
)}
{showKebabMenu && <GenericMenu title={t('Options')} data-qa-id='ToolBox-Menu' sections={hiddenActions} placement='bottom-end' />}
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import { mockAppRoot } from '@rocket.chat/mock-providers';
import { renderHook } from '@testing-library/react';

import { useRoomToolboxActions } from './useRoomToolboxActions';
import type { RoomToolboxActionConfig } from '../../../contexts/RoomToolboxContext';

describe('useRoomToolboxActions', () => {
it('should return an empty array if there are no actions', () => {
const { result } = renderHook(() => useRoomToolboxActions({ actions: [], openTab: () => undefined }), {
legacyRoot: true,
wrapper: mockAppRoot().build(),
});
expect(result.current.featuredActions).toEqual([]);
expect(result.current.hiddenActions).toEqual([]);
expect(result.current.visibleActions).toEqual([]);
});

it('should return apps actions only inside hiddenActions', () => {
const { result } = renderHook(() => useRoomToolboxActions({ actions: appsActions, openTab: () => undefined }), {
legacyRoot: true,
wrapper: mockAppRoot().build(),
});
const appsSection = result.current.hiddenActions[0];
const appsItems = appsSection.items;

expect(appsSection).toBeDefined();
expect(appsSection).toHaveProperty('id', 'apps');
expect(appsItems).toMatchObject(appsActions);
});

it('should return max of 6 items on visibleActions and the rest items inside hiddenActions', () => {
const { result } = renderHook(() => useRoomToolboxActions({ actions, openTab: () => undefined }), {
legacyRoot: true,
wrapper: mockAppRoot().build(),
});
expect(result.current.hiddenActions.length).toBeGreaterThan(0);
expect(result.current.visibleActions.length).toBe(6);
});

it('should return featured items inside featuredActions', () => {
const { result } = renderHook(() => useRoomToolboxActions({ actions, openTab: () => undefined }), {
legacyRoot: true,
wrapper: mockAppRoot().build(),
});
expect(result.current.featuredActions).toMatchObject(actions.filter((action) => action.featured));
});
});

const appsActions: RoomToolboxActionConfig[] = [
{
id: 'app1',
title: 'app-42212581-0966-44aa-8366-b3e92aa00df4.action_button_label_files',
groups: ['group', 'channel', 'live', 'team', 'direct', 'direct_multiple'],
type: 'apps',
},
{
id: 'app2',
title: 'app-42212581-0966-44aa-8366-b3e92aa00df4.action_button_label_files',
groups: ['group', 'channel', 'live', 'team', 'direct', 'direct_multiple'],
type: 'apps',
},
];

const actions: RoomToolboxActionConfig[] = [
{
id: 'team-info',
groups: ['team'],
anonymous: true,
full: true,
title: 'Teams_Info',
icon: 'info-circled',
order: 1,
},
{
id: 'thread',
groups: ['channel', 'group', 'direct', 'direct_multiple', 'team'],
full: true,
title: 'Threads',
icon: 'thread',
order: 2,
},
{
id: 'team-channels',
groups: ['team'],
anonymous: true,
full: true,
title: 'Team_Channels',
icon: 'hash',
order: 2,
},
{
id: 'discussions',
groups: ['channel', 'group', 'direct', 'direct_multiple', 'team'],
title: 'Discussions',
icon: 'discussion',
full: true,
order: 3,
},
{
id: 'start-call',
title: 'Call',
icon: 'phone',
groups: ['direct', 'direct_multiple', 'group', 'team', 'channel', 'direct'],
disabled: false,
full: true,
order: 4,
featured: true,
},
{
id: 'rocket-search',
groups: ['channel', 'group', 'direct', 'direct_multiple', 'live', 'team'],
title: 'Search_Messages',
icon: 'magnifier',
order: 5,
},
{
id: 'mentions',
groups: ['channel', 'group', 'team'],
title: 'Mentions',
icon: 'at',
order: 6,
type: 'organization',
},
{
id: 'members-list',
groups: ['channel', 'group', 'team'],
title: 'Teams_members',
icon: 'members',
order: 7,
},
{
id: 'uploaded-files-list',
groups: ['channel', 'group', 'direct', 'direct_multiple', 'live', 'team'],
title: 'Files',
icon: 'clip',
order: 8,
type: 'organization',
},
{
id: 'pinned-messages',
groups: ['channel', 'group', 'direct', 'direct_multiple', 'team'],
title: 'Pinned_Messages',
icon: 'pin',
order: 9,
type: 'organization',
},
{
id: 'starred-messages',
groups: ['channel', 'group', 'direct', 'direct_multiple', 'team'],
title: 'Starred_Messages',
icon: 'star',
order: 10,
type: 'organization',
},
{
id: 'keyboard-shortcut-list',
groups: ['channel', 'group', 'direct', 'direct_multiple', 'team'],
title: 'Keyboard_Shortcuts_Title',
icon: 'keyboard',
order: 99,
type: 'customization',
},
{
id: 'clean-history',
groups: ['channel', 'group', 'team', 'direct_multiple', 'direct'],
full: true,
title: 'Prune_Messages',
icon: 'eraser',
order: 250,
type: 'customization',
},
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import type { GenericMenuItemProps } from '@rocket.chat/ui-client';
import { useLayout } from '@rocket.chat/ui-contexts';
import { useTranslation } from 'react-i18next';

import type { RoomToolboxContextValue } from '../../../contexts/RoomToolboxContext';

type MenuActionsProps = {
id: string;
items: GenericMenuItemProps[];
}[];

export const useRoomToolboxActions = ({ actions, openTab }: Pick<RoomToolboxContextValue, 'actions' | 'openTab'>) => {
const { t } = useTranslation();
const { roomToolboxExpanded } = useLayout();

const normalActions = actions.filter((action) => !action.featured && action.type !== 'apps');
const featuredActions = actions.filter((action) => action.featured);
const appsActions = actions.filter((action) => action.type === 'apps');
const visibleActions = !roomToolboxExpanded ? [] : normalActions.slice(0, 6);

const hiddenActions = (!roomToolboxExpanded ? actions : [...appsActions, ...normalActions.slice(6)])
.filter((item) => !item.disabled && !item.featured)
.map((item) => ({
'key': item.id,
'content': t(item.title),
'onClick':
item.action ??
((): void => {
openTab(item.id);
}),
'data-qa-id': `ToolBoxAction-${item.icon}`,
...item,
}))
.reduce((acc, item) => {
const group = item.type ? item.type : '';
const section = acc.find((section: { id: string }) => section.id === group);
if (section) {
section.items.push(item);
return acc;
}

const newSection = { id: group, key: item.key, title: group === 'apps' ? t('Apps') : '', items: [item] };
acc.push(newSection);

return acc;
}, [] as MenuActionsProps);

return { hiddenActions, featuredActions, visibleActions };
};
46 changes: 4 additions & 42 deletions apps/meteor/client/views/room/HeaderV2/RoomToolbox/RoomToolbox.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import type { Box } from '@rocket.chat/fuselage';
import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
import { GenericMenu } from '@rocket.chat/ui-client';
import type { GenericMenuItemProps } from '@rocket.chat/ui-client';
import { useLayout } from '@rocket.chat/ui-contexts';
import type { ComponentProps } from 'react';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';

import { useRoomToolboxActions } from './hooks/useRoomToolboxActions';
import { HeaderToolbarAction, HeaderToolbarDivider } from '../../../../components/Header';
import { useRoomToolbox } from '../../contexts/RoomToolboxContext';
import type { RoomToolboxActionConfig } from '../../contexts/RoomToolboxContext';
Expand All @@ -15,48 +14,13 @@ type RoomToolboxProps = {
className?: ComponentProps<typeof Box>['className'];
};

type MenuActionsProps = {
id: string;
items: GenericMenuItemProps[];
}[];

const RoomToolbox = ({ className }: RoomToolboxProps) => {
const { t } = useTranslation();
const { roomToolboxExpanded } = useLayout();

const toolbox = useRoomToolbox();
const { actions, openTab } = toolbox;

const featuredActions = actions.filter((action) => action.featured);
const normalActions = actions.filter((action) => !action.featured);
const visibleActions = !roomToolboxExpanded ? [] : normalActions.slice(0, 6);

const hiddenActions = (!roomToolboxExpanded ? actions : normalActions.slice(6))
.filter((item) => !item.disabled && !item.featured)
.map((item) => ({
'key': item.id,
'content': t(item.title),
'onClick':
item.action ??
((): void => {
openTab(item.id);
}),
'data-qa-id': `ToolBoxAction-${item.icon}`,
...item,
}))
.reduce((acc, item) => {
const group = item.type ? item.type : '';
const section = acc.find((section: { id: string }) => section.id === group);
if (section) {
section.items.push(item);
return acc;
}

const newSection = { id: group, key: item.key, title: group === 'apps' ? t('Apps') : '', items: [item] };
acc.push(newSection);
const { featuredActions, hiddenActions, visibleActions } = useRoomToolboxActions(toolbox);

return acc;
}, [] as MenuActionsProps);
const showKebabMenu = hiddenActions.length > 0;

const renderDefaultToolboxItem: RoomToolboxActionConfig['renderToolboxItem'] = useEffectEvent(
({ id, className, index, icon, title, toolbox: { tab }, action, disabled, tooltip }) => {
Expand Down Expand Up @@ -92,9 +56,7 @@ const RoomToolbox = ({ className }: RoomToolboxProps) => {
{featuredActions.map(mapToToolboxItem)}
{featuredActions.length > 0 && <HeaderToolbarDivider />}
{visibleActions.map(mapToToolboxItem)}
{(normalActions.length > 6 || !roomToolboxExpanded) && !!hiddenActions.length && (
<GenericMenu title={t('Options')} data-qa-id='ToolBox-Menu' sections={hiddenActions} placement='bottom-end' />
)}
{showKebabMenu && <GenericMenu title={t('Options')} data-qa-id='ToolBox-Menu' sections={hiddenActions} placement='bottom-end' />}
</>
);
};
Expand Down
Loading

0 comments on commit d7a77b1

Please sign in to comment.