Skip to content
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

feat: introduce new categories field for UI Action Buttons #33066

Merged
merged 31 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
3657d89
init add new hook
Dnouv Aug 15, 2024
01fd0c6
add message action menu
Dnouv Aug 15, 2024
6bc0a97
Add AI Actions to en.i18n.json
Dnouv Aug 15, 2024
822c21c
add changeset
Dnouv Aug 15, 2024
5f54fbf
update apps engine
Dnouv Aug 20, 2024
74553f2
Merge branch 'develop' into new/app_ui_menu
Dnouv Aug 21, 2024
7a16d55
update rc-icons
Dnouv Aug 21, 2024
f99b4cd
Revert "update rc-icons"
Dnouv Aug 21, 2024
659e3df
Merge branch 'develop' into new/app_ui_menu
Dnouv Aug 21, 2024
26ace4c
Merge branch 'develop' into new/app_ui_menu
Dnouv Aug 22, 2024
b126016
Add blank space in en.i18n.json
Dnouv Aug 23, 2024
9cdf49a
Merge branch 'develop' into new/app_ui_menu
Dnouv Aug 23, 2024
2ee01f8
Merge branch 'develop' into new/app_ui_menu
Dnouv Sep 9, 2024
8b2fbf1
Merge branch 'develop' into new/app_ui_menu
Dnouv Sep 9, 2024
7e60300
update to use category
Dnouv Sep 18, 2024
81b0daa
optimize bool checks
Dnouv Sep 18, 2024
06dc501
update changeset
Dnouv Sep 18, 2024
c7f44bb
Merge branch 'develop' into new/app_ui_menu
Dnouv Sep 26, 2024
290f5ed
bump apps-engine
Dnouv Sep 26, 2024
abb8b4f
fix generic menu import
Dnouv Sep 27, 2024
f2f7dff
fix enum import
Dnouv Sep 27, 2024
d43a644
remove unused interaction
Dnouv Sep 27, 2024
452399c
Merge branch 'develop' into new/app_ui_menu
Dnouv Sep 27, 2024
6dcd1e2
update changeset
Dnouv Sep 30, 2024
631a471
reduce reduce
Dnouv Sep 30, 2024
e840508
Merge branch 'develop' into new/app_ui_menu
Dnouv Sep 30, 2024
d93ad3e
add newline
Dnouv Sep 30, 2024
f95c4f9
update changeset
Dnouv Oct 1, 2024
ccb6e46
Merge branch 'develop' into new/app_ui_menu
Dnouv Oct 7, 2024
d238277
Avoid any conversion
tassoevan Oct 8, 2024
d587947
Merge branch 'develop' into new/app_ui_menu
kodiakhq[bot] Oct 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/red-crews-behave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@rocket.chat/ui-kit': minor
'@rocket.chat/i18n': minor
'@rocket.chat/meteor': minor
---

New UI context for Rocket.Chat Apps to register actions, apps can use this new context by registering buttons under the `category: AI`
Dnouv marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { useAutoTranslate } from '../../../views/room/MessageList/hooks/useAutoT
import { useChat } from '../../../views/room/contexts/ChatContext';
import { useRoomToolbox } from '../../../views/room/contexts/RoomToolboxContext';
import MessageActionMenu from './MessageActionMenu';
import MessageToolbarStarsActionMenu from './MessageToolbarStarsActionMenu';
import { useWebDAVMessageAction } from './useWebDAVMessageAction';

const getMessageContext = (message: IMessage, room: IRoom, context?: MessageActionContext): MessageActionContext => {
Expand Down Expand Up @@ -78,6 +79,8 @@ const MessageToolbar = ({

const actionButtonApps = useMessageActionAppsActionButtons(context);

const starsAction = useMessageActionAppsActionButtons(context, 'ai');

const { messageToolbox: hiddenActions } = useLayoutHiddenActions();

// TODO: move this to another place
Expand Down Expand Up @@ -135,6 +138,19 @@ const MessageToolbar = ({
disabled={action?.disabled?.({ message, room, user, subscription, settings: mapSettings, chat, context })}
/>
))}
{starsAction.data && starsAction.data.length > 0 && (
<MessageToolbarStarsActionMenu
options={starsAction.data.map((action) => ({
...action,
action: (e) => action.action(e, { message, tabbar: toolbox, room, chat, autoTranslateOptions }),
}))}
onChangeMenuVisibility={onChangeMenuVisibility}
data-qa-type='message-action-stars-menu-options'
context={{ message, room, user, subscription, settings: mapSettings, chat, context }}
isMessageEncrypted={isE2EEMessage(message)}
/>
)}

{actionsQueryResult.isSuccess && actionsQueryResult.data.menu.length > 0 && (
<MessageActionMenu
options={[...actionsQueryResult.data?.menu, ...(actionButtonApps.data ?? [])].filter(Boolean).map((action) => ({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { useUniqueId } from '@rocket.chat/fuselage-hooks';
import { GenericMenu, type GenericMenuItemProps } from '@rocket.chat/ui-client';
import { useTranslation } from '@rocket.chat/ui-contexts';
import type { MouseEvent, ReactElement } from 'react';
import React from 'react';

import type { MessageActionConditionProps, MessageActionConfig } from '../../../../app/ui-utils/client/lib/MessageAction';

type MessageActionConfigOption = Omit<MessageActionConfig, 'condition' | 'context' | 'order' | 'action'> & {
action: (e?: MouseEvent<HTMLElement>) => void;
};

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

type MessageActionMenuProps = {
onChangeMenuVisibility: (visible: boolean) => void;
options: MessageActionConfigOption[];
context: MessageActionConditionProps;
isMessageEncrypted: boolean;
};

const MessageToolbarStarsActionMenu = ({
options,
onChangeMenuVisibility,
context,
isMessageEncrypted,
}: MessageActionMenuProps): ReactElement => {
const t = useTranslation();
const id = useUniqueId();
const groupOptions = options
.map((option) => ({
Dnouv marked this conversation as resolved.
Show resolved Hide resolved
variant: option.color === 'alert' ? 'danger' : '',
id: option.id,
icon: option.icon,
content: t(option.label),
onClick: option.action,
type: option.type,
...(option.disabled && { disabled: option?.disabled?.(context) }),
...(option.disabled &&
option?.disabled?.(context) && { tooltip: t('Action_not_available_encrypted_content', { action: t(option.label) }) }),
}))
.reduce((acc, option) => {
const group = option.type ? option.type : '';
const section = acc.find((section: { id: string }) => section.id === group);
if (section) {
section.items.push(option);
return acc;
}

const newSection = { id: group, title: '', items: [option] };
acc.push(newSection);
return acc;
}, [] as unknown as MessageActionSection[])
Dnouv marked this conversation as resolved.
Show resolved Hide resolved
.map((section) => {
if (section.id !== 'apps') {
return section;
}

if (!isMessageEncrypted) {
return section;
}

return {
id: 'apps',
title: t('Apps'),
items: [
{
content: t('Unavailable'),
type: 'apps',
id,
disabled: true,
gap: false,
tooltip: t('Action_not_available_encrypted_content', { action: t('Apps') }),
},
],
};
});

return (
<GenericMenu
onOpenChange={onChangeMenuVisibility}
detached
icon='stars'
title={t('AI_Actions')}
data-qa-id='menu'
data-qa-type='message-action-menu'
sections={groupOptions}
placement='bottom-end'
/>
);
};

export default MessageToolbarStarsActionMenu;
13 changes: 6 additions & 7 deletions apps/meteor/client/hooks/useAppActionButtons.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { IUIActionButton, UIActionButtonContext } from '@rocket.chat/apps-engine/definition/ui';
import { type IUIActionButton, type UIActionButtonContext } from '@rocket.chat/apps-engine/definition/ui';
import { useDebouncedCallback } from '@rocket.chat/fuselage-hooks';
import type { GenericMenuItemProps } from '@rocket.chat/ui-client';
import { useEndpoint, useStream, useToastMessageDispatch, useUserId } from '@rocket.chat/ui-contexts';
Expand All @@ -13,6 +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';

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

Expand Down Expand Up @@ -160,20 +161,18 @@ export const useUserDropdownAppsActionButtons = () => {
} as UseQueryResult<GenericMenuItemProps[]>;
};

export const useMessageActionAppsActionButtons = (context?: MessageActionContext) => {
export const useMessageActionAppsActionButtons = (context?: MessageActionContext, category?: string) => {
const result = useAppActionButtons('messageAction');
const actionManager = useUiKitActionManager();
const applyButtonFilters = useApplyButtonFilters();
const dispatchToastMessage = useToastMessageDispatch();
const { t } = useTranslation();
const filterActionsByContextAndCategory = useFilterActionsByContextAndCategory(context, category);
const data = useMemo(
Dnouv marked this conversation as resolved.
Show resolved Hide resolved
() =>
result.data
?.filter((action) => {
if (
context &&
!(action.when?.messageActionContext || ['message', 'message-mobile', 'threads', 'starred']).includes(context as any)
) {
if (!filterActionsByContextAndCategory(action)) {
return false;
}
return applyButtonFilters(action);
Expand Down Expand Up @@ -212,7 +211,7 @@ export const useMessageActionAppsActionButtons = (context?: MessageActionContext

return item;
}),
[actionManager, applyButtonFilters, context, dispatchToastMessage, result.data, t],
[actionManager, applyButtonFilters, dispatchToastMessage, filterActionsByContextAndCategory, result.data, t],
);
return {
...result,
Expand Down
24 changes: 24 additions & 0 deletions apps/meteor/client/hooks/useFilterActions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
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') => {
return useCallback(
(action: IUIActionButton) => {
if (!context) {
return true;
}

const actionCategory = action?.category ?? DEFAULT_CATEGORY;
tassoevan marked this conversation as resolved.
Show resolved Hide resolved
const isContextMatch = (action.when?.messageActionContext || ['message', 'message-mobile', 'threads', 'starred']).includes(
context as any,
tassoevan marked this conversation as resolved.
Show resolved Hide resolved
);

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

return isContextMatch && isCategoryMatch;
},
[context, category],
);
};
2 changes: 1 addition & 1 deletion apps/meteor/ee/server/services/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"author": "Rocket.Chat",
"license": "MIT",
"dependencies": {
"@rocket.chat/apps-engine": "1.45.0-alpha.868",
"@rocket.chat/apps-engine": "1.47.0-alpha.899",
"@rocket.chat/core-services": "workspace:^",
"@rocket.chat/core-typings": "workspace:^",
"@rocket.chat/emitter": "~0.31.25",
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@
"@rocket.chat/agenda": "workspace:^",
"@rocket.chat/api-client": "workspace:^",
"@rocket.chat/apps": "workspace:^",
"@rocket.chat/apps-engine": "1.45.0-alpha.868",
"@rocket.chat/apps-engine": "1.47.0-alpha.899",
"@rocket.chat/base64": "workspace:^",
"@rocket.chat/cas-validate": "workspace:^",
"@rocket.chat/core-services": "workspace:^",
Expand Down
2 changes: 1 addition & 1 deletion ee/apps/ddp-streamer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
],
"author": "Rocket.Chat",
"dependencies": {
"@rocket.chat/apps-engine": "1.45.0-alpha.868",
"@rocket.chat/apps-engine": "1.47.0-alpha.899",
"@rocket.chat/core-services": "workspace:^",
"@rocket.chat/core-typings": "workspace:^",
"@rocket.chat/emitter": "~0.31.25",
Expand Down
2 changes: 1 addition & 1 deletion ee/packages/presence/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"@babel/core": "~7.22.20",
"@babel/preset-env": "~7.22.20",
"@babel/preset-typescript": "~7.22.15",
"@rocket.chat/apps-engine": "1.45.0-alpha.868",
"@rocket.chat/apps-engine": "1.47.0-alpha.899",
"@rocket.chat/eslint-config": "workspace:^",
"@rocket.chat/rest-typings": "workspace:^",
"@types/node": "^14.18.63",
Expand Down
2 changes: 1 addition & 1 deletion packages/apps/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"/dist"
],
"dependencies": {
"@rocket.chat/apps-engine": "1.45.0-alpha.868",
"@rocket.chat/apps-engine": "1.47.0-alpha.899",
"@rocket.chat/core-typings": "workspace:^",
"@rocket.chat/model-typings": "workspace:^"
}
Expand Down
2 changes: 1 addition & 1 deletion packages/core-services/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"extends": "../../package.json"
},
"dependencies": {
"@rocket.chat/apps-engine": "1.45.0-alpha.868",
"@rocket.chat/apps-engine": "1.47.0-alpha.899",
"@rocket.chat/core-typings": "workspace:^",
"@rocket.chat/icons": "~0.38.0",
"@rocket.chat/message-parser": "workspace:^",
Expand Down
2 changes: 1 addition & 1 deletion packages/core-typings/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"/dist"
],
"dependencies": {
"@rocket.chat/apps-engine": "1.45.0-alpha.868",
"@rocket.chat/apps-engine": "1.47.0-alpha.899",
"@rocket.chat/icons": "~0.38.0",
"@rocket.chat/message-parser": "workspace:^",
"@rocket.chat/ui-kit": "workspace:~",
Expand Down
2 changes: 1 addition & 1 deletion packages/fuselage-ui-kit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"@babel/preset-env": "~7.22.20",
"@babel/preset-react": "~7.22.15",
"@babel/preset-typescript": "~7.22.15",
"@rocket.chat/apps-engine": "1.45.0-alpha.868",
"@rocket.chat/apps-engine": "1.47.0-alpha.899",
"@rocket.chat/core-typings": "workspace:^",
"@rocket.chat/eslint-config": "workspace:^",
"@rocket.chat/fuselage": "^0.59.1",
Expand Down
1 change: 1 addition & 0 deletions packages/i18n/src/locales/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@
"Agent_Without_Extensions": "Agent Without Extensions",
"Agents": "Agents",
"Agree": "Agree",
"AI_Actions": "AI Actions",
"Alerts": "Alerts",
"Alias": "Alias",
"Alias_Format": "Alias Format",
Expand Down
2 changes: 1 addition & 1 deletion packages/rest-typings/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"/dist"
],
"dependencies": {
"@rocket.chat/apps-engine": "1.45.0-alpha.868",
"@rocket.chat/apps-engine": "1.47.0-alpha.899",
"@rocket.chat/core-typings": "workspace:^",
"@rocket.chat/message-parser": "workspace:^",
"@rocket.chat/ui-kit": "workspace:~",
Expand Down
Loading
Loading