Skip to content

Commit

Permalink
feat: adds a new featured room action on the header for non-default c…
Browse files Browse the repository at this point in the history
…ategory (#33562)
  • Loading branch information
Dnouv authored Oct 15, 2024
1 parent eebb212 commit 08d0df2
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 16 deletions.
5 changes: 5 additions & 0 deletions .changeset/four-experts-compare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': minor
---

Introduces a new featured action on the room header for action buttons using the non-default category to enhance user accessibility.
82 changes: 82 additions & 0 deletions apps/meteor/client/hooks/roomActions/useAppsRoomStarActions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { Box } from '@rocket.chat/fuselage';
import { GenericMenu, HeaderToolbarAction } from '@rocket.chat/ui-client';
import { useToastMessageDispatch } from '@rocket.chat/ui-contexts';
import React, { useMemo } from 'react';
import { useTranslation } from 'react-i18next';

import { UiKitTriggerTimeoutError } from '../../../app/ui-message/client/UiKitTriggerTimeoutError';
import { Utilities } from '../../../ee/lib/misc/Utilities';
import { useUiKitActionManager } from '../../uikit/hooks/useUiKitActionManager';
import { useRoom } from '../../views/room/contexts/RoomContext';
import type { RoomToolboxActionConfig } from '../../views/room/contexts/RoomToolboxContext';
import { useAppActionButtons } from '../useAppActionButtons';
import { useApplyButtonFilters } from '../useApplyButtonFilters';

export const useAppsRoomStarActions = () => {
const result = useAppActionButtons('roomAction');
const actionManager = useUiKitActionManager();
const applyButtonFilters = useApplyButtonFilters('ai');
const room = useRoom();
const { t } = useTranslation();
const dispatchToastMessage = useToastMessageDispatch();

return useMemo((): RoomToolboxActionConfig | undefined => {
if (!result.data) {
return undefined;
}

const filteredActions = result.data.filter(applyButtonFilters);

if (filteredActions.length === 0) {
return undefined;
}

return {
id: 'ai-actions',
title: 'AI_Actions',
icon: 'stars',
groups: ['group', 'channel', 'live', 'team', 'direct', 'direct_multiple'],
featured: true,
renderToolboxItem: ({ id, icon, title, disabled, className }) => (
<GenericMenu
button={<HeaderToolbarAction />}
key={id}
title={title}
disabled={disabled}
items={filteredActions.map((action) => ({
id: action.actionId,
icon: undefined,
title: Utilities.getI18nKeyForApp(action.labelI18n, action.appId),
content: <Box is='span'>{t(`${Utilities.getI18nKeyForApp(action.labelI18n, action.appId)}`)}</Box>,
variant: action.variant,
groups: ['group', 'channel', 'live', 'team', 'direct', 'direct_multiple'],
onClick: () => {
void actionManager
.emitInteraction(action.appId, {
type: 'actionButton',
actionId: action.actionId,
rid: room._id,
payload: { context: action.context },
})
.catch(async (reason) => {
if (reason instanceof UiKitTriggerTimeoutError) {
dispatchToastMessage({
type: 'error',
message: t('UIKit_Interaction_Timeout'),
});
return;
}

return reason;
});
},
type: 'apps',
}))}
className={className}
placement='bottom-start'
icon={icon}
/>
),
};
}, [actionManager, applyButtonFilters, dispatchToastMessage, result.data, room._id, t]);
};
10 changes: 5 additions & 5 deletions apps/meteor/client/hooks/useAppActionButtons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import type { MessageBoxAction } from '../../app/ui-utils/client/lib/messageBox'
import { Utilities } from '../../ee/lib/misc/Utilities';
import { useUiKitActionManager } from '../uikit/hooks/useUiKitActionManager';
import { useApplyButtonFilters, useApplyButtonAuthFilter } from './useApplyButtonFilters';
import { useFilterActionsByContextAndCategory } from './useFilterActions';
import { useFilterActionsByContext } from './useFilterActions';

const getIdForActionButton = ({ appId, actionId }: IUIActionButton): string => `${appId}/${actionId}`;

Expand Down Expand Up @@ -164,15 +164,15 @@ export const useUserDropdownAppsActionButtons = () => {
export const useMessageActionAppsActionButtons = (context?: MessageActionContext, category?: string) => {
const result = useAppActionButtons('messageAction');
const actionManager = useUiKitActionManager();
const applyButtonFilters = useApplyButtonFilters();
const applyButtonFilters = useApplyButtonFilters(category);
const dispatchToastMessage = useToastMessageDispatch();
const { t } = useTranslation();
const filterActionsByContextAndCategory = useFilterActionsByContextAndCategory(context, category);
const filterActionsByContext = useFilterActionsByContext(context);
const data = useMemo(
() =>
result.data
?.filter((action) => {
if (!filterActionsByContextAndCategory(action)) {
if (!filterActionsByContext(action)) {
return false;
}
return applyButtonFilters(action);
Expand Down Expand Up @@ -211,7 +211,7 @@ export const useMessageActionAppsActionButtons = (context?: MessageActionContext

return item;
}),
[actionManager, applyButtonFilters, dispatchToastMessage, filterActionsByContextAndCategory, result.data, t],
[actionManager, applyButtonFilters, dispatchToastMessage, filterActionsByContext, result.data, t],
);
return {
...result,
Expand Down
17 changes: 14 additions & 3 deletions apps/meteor/client/hooks/useApplyButtonFilters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,26 @@ const applyRoomFilter = (button: IUIActionButton, room: IRoom): boolean => {
return !roomTypes || roomTypes.some((filter): boolean => enumToFilter[filter]?.(room));
};

export const useApplyButtonFilters = (): ((button: IUIActionButton) => boolean) => {
const applyCategoryFilter = (button: IUIActionButton, category: string): boolean => {
const { category: buttonCategory } = button;

if (category === 'default') {
return !buttonCategory || buttonCategory === 'default';
}

return buttonCategory === category;
};

export const useApplyButtonFilters = (category = 'default'): ((button: IUIActionButton) => boolean) => {
const room = useRoom();
if (!room) {
throw new Error('useApplyButtonFilters must be used inside a room context');
}
const applyAuthFilter = useApplyButtonAuthFilter();
return useCallback(
(button: IUIActionButton) => applyAuthFilter(button) && (!room || applyRoomFilter(button, room)),
[applyAuthFilter, room],
(button: IUIActionButton) =>
applyAuthFilter(button) && (!room || applyRoomFilter(button, room)) && applyCategoryFilter(button, category),
[applyAuthFilter, category, room],
);
};

Expand Down
11 changes: 3 additions & 8 deletions apps/meteor/client/hooks/useFilterActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,18 @@ import { MessageActionContext } from '@rocket.chat/apps-engine/definition/ui';
import type { IUIActionButton } from '@rocket.chat/apps-engine/definition/ui';
import { useCallback } from 'react';

const DEFAULT_CATEGORY = 'default';

export const useFilterActionsByContextAndCategory = (context: string | undefined, category = 'default') => {
export const useFilterActionsByContext = (context: string | undefined) => {
return useCallback(
(action: IUIActionButton) => {
if (!context) {
return true;
}

const actionCategory = action?.category ?? DEFAULT_CATEGORY;
const messageActionContext = action.when?.messageActionContext || Object.values(MessageActionContext);
const isContextMatch = messageActionContext.includes(context as MessageActionContext);

const isCategoryMatch = category === DEFAULT_CATEGORY ? actionCategory === DEFAULT_CATEGORY : actionCategory === category;

return isContextMatch && isCategoryMatch;
return isContextMatch;
},
[context, category],
[context],
);
};
2 changes: 2 additions & 0 deletions apps/meteor/client/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useCloseChatQuickAction } from './hooks/quickActions/useCloseChatQuickA
import { useMoveQueueQuickAction } from './hooks/quickActions/useMoveQueueQuickAction';
import { useOnHoldChatQuickAction } from './hooks/quickActions/useOnHoldChatQuickAction';
import { useTranscriptQuickAction } from './hooks/quickActions/useTranscriptQuickAction';
import { useAppsRoomStarActions } from './hooks/roomActions/useAppsRoomStarActions';
import { useAutotranslateRoomAction } from './hooks/roomActions/useAutotranslateRoomAction';
import { useCallsRoomAction } from './hooks/roomActions/useCallsRoomAction';
import { useCannedResponsesRoomAction } from './hooks/roomActions/useCannedResponsesRoomAction';
Expand Down Expand Up @@ -69,6 +70,7 @@ export const roomActionHooks = [
useUploadedFilesListRoomAction,
useVoIPRoomInfoRoomAction,
useWebRTCVideoRoomAction,
useAppsRoomStarActions,
] satisfies (() => RoomToolboxActionConfig | undefined)[];

export const quickActionHooks = [
Expand Down

0 comments on commit 08d0df2

Please sign in to comment.