Skip to content

Commit

Permalink
refactor: Remove Accountbox usage (#29786)
Browse files Browse the repository at this point in the history
  • Loading branch information
ggazzo authored Jul 11, 2023
1 parent 54579fb commit bd231a0
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 157 deletions.
13 changes: 0 additions & 13 deletions apps/meteor/app/lib/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,6 @@ settingsRegistry.addGroup('Settings_Group', function() {
* `enableQuery` - Only enable this setting if the correspondent setting has the value specified
* `alert` - Shows an alert message with the given text

### AccountBox

You can add items to the left upper corner drop menu:
```javascript
AccountBox.addItem({
name: 'Livechat',
icon: 'icon-chat-empty',
class: 'livechat-manager',
condition: () => {
return RocketChat.authz.hasPermission('view-livechat-manager');
}
});
```

### Functions
n/a
Expand Down
12 changes: 1 addition & 11 deletions apps/meteor/app/livechat/client/ui.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,4 @@
import { settings } from '../../settings/client';
import { hasAllPermission } from '../../authorization/client';
import { AccountBox, MessageTypes } from '../../ui-utils/client';

AccountBox.addItem({
name: 'Omnichannel',
icon: 'headset',
href: '/omnichannel/current',
sideNav: 'omnichannelFlex',
condition: () => settings.get('Livechat_enabled') && hasAllPermission('view-livechat-manager'),
});
import { MessageTypes } from '../../ui-utils/client';

MessageTypes.registerType({
id: 'livechat-close',
Expand Down
1 change: 0 additions & 1 deletion apps/meteor/app/ui-utils/client/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import './lib/messageActionDefault';

export { AccountBox } from './lib/AccountBox';
export { MessageAction } from './lib/MessageAction';
export { messageBox } from './lib/messageBox';
export { readMessage } from './lib/readMessages';
Expand Down
32 changes: 0 additions & 32 deletions apps/meteor/app/ui-utils/client/lib/AccountBox.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import type { IUIActionButton, IUActionButtonWhen } from '@rocket.chat/apps-engine/definition/ui/IUIActionButtonDescriptor';
import type { UserStatus } from '@rocket.chat/core-typings';
import { ReactiveVar } from 'meteor/reactive-var';
import { Tracker } from 'meteor/tracker';
import type { TranslationKey, LocationPathname } from '@rocket.chat/ui-contexts';
import type { Icon } from '@rocket.chat/fuselage';
import type { ComponentProps } from 'react';

import { applyDropdownActionButtonFilters } from '../../../ui-message/client/actionButtons/lib/applyButtonFilters';
import { sdk } from '../../../utils/client/lib/SDKClient';

export interface IAppAccountBoxItem extends IUIActionButton {
Expand All @@ -30,38 +27,9 @@ export type AccountBoxItem = {
export const isAppAccountBoxItem = (item: IAppAccountBoxItem | AccountBoxItem): item is IAppAccountBoxItem => 'isAppButtonItem' in item;

class AccountBoxBase {
private items = new ReactiveVar<IAppAccountBoxItem[]>([]);

public setStatus(status: UserStatus, statusText?: string): any {
return sdk.rest.post('/v1/users.setStatus', { status, message: statusText });
}

public async addItem(newItem: IAppAccountBoxItem): Promise<void> {
Tracker.nonreactive(() => {
const actual = this.items.get();
actual.push(newItem);
this.items.set(actual);
});
}

public async deleteItem(item: IAppAccountBoxItem): Promise<void> {
Tracker.nonreactive(() => {
const actual = this.items.get();
const itemIndex = actual.findIndex((actualItem: IAppAccountBoxItem) => actualItem.appId === item.appId);
actual.splice(itemIndex, 1);
this.items.set(actual);
});
}

public getItems(): (IAppAccountBoxItem | AccountBoxItem)[] {
return this.items.get().filter((item: IAppAccountBoxItem | AccountBoxItem) => {
if ('condition' in item) {
return item.condition();
}

return applyDropdownActionButtonFilters(item);
});
}
}

export const AccountBox = new AccountBoxBase();
Original file line number Diff line number Diff line change
@@ -1,26 +1,62 @@
import { useTranslation, useRoute, useMethod, useSetModal, useRole, useRouter } from '@rocket.chat/ui-contexts';
import {
useTranslation,
useRoute,
useMethod,
useSetModal,
useRole,
useRouter,
useAtLeastOnePermission,
usePermission,
} from '@rocket.chat/ui-contexts';
import { useQuery } from '@tanstack/react-query';
import React from 'react';

import type { AccountBoxItem } from '../../../../../app/ui-utils/client/lib/AccountBox';
import type { UpgradeTabVariant } from '../../../../../lib/upgradeTab';
import { getUpgradeTabLabel, isFullyFeature } from '../../../../../lib/upgradeTab';
import Emoji from '../../../../components/Emoji';
import type { GenericMenuItemProps } from '../../../../components/GenericMenu/GenericMenuItem';
import RegisterWorkspaceModal from '../../../../views/admin/cloud/modals/RegisterWorkspaceModal';
import { useUpgradeTabParams } from '../../../../views/hooks/useUpgradeTabParams';

type useAdministrationItemProps = {
accountBoxItems: AccountBoxItem[];
showWorkspace: boolean;
};
export const useAdministrationItems = ({ accountBoxItems, showWorkspace }: useAdministrationItemProps): GenericMenuItemProps[] => {
const ADMIN_PERMISSIONS = [
'view-statistics',
'run-import',
'view-user-administration',
'view-room-administration',
'create-invite-links',
'manage-cloud',
'view-logs',
'manage-sounds',
'view-federation-data',
'manage-email-inbox',
'manage-emoji',
'manage-outgoing-integrations',
'manage-own-outgoing-integrations',
'manage-incoming-integrations',
'manage-own-incoming-integrations',
'manage-oauth-apps',
'access-mailer',
'manage-user-status',
'access-permissions',
'access-setting-permissions',
'view-privileged-setting',
'edit-privileged-setting',
'manage-selected-settings',
'view-engagement-dashboard',
'view-moderation-console',
];

export const useAdministrationItems = (): GenericMenuItemProps[] => {
const router = useRouter();
const t = useTranslation();

const shouldShowAdminMenu = useAtLeastOnePermission(ADMIN_PERMISSIONS);

const { tabType, trialEndDate, isLoading } = useUpgradeTabParams();
const shouldShowEmoji = isFullyFeature(tabType);

const label = getUpgradeTabLabel(tabType);

const isAdmin = useRole('admin');
const setModal = useSetModal();

Expand All @@ -36,8 +72,18 @@ export const useAdministrationItems = ({ accountBoxItems, showWorkspace }: useAd
const adminRoute = useRoute('admin-index');
const upgradeRoute = useRoute('upgrade');
const cloudRoute = useRoute('cloud');

const omnichannel = usePermission('view-livechat-manager');

const showUpgradeItem = !isLoading && tabType;

const omnichannelItem: GenericMenuItemProps = {
id: 'omnichannel',
content: t('Omnichannel'),
icon: 'headset',
onClick: () => router.navigate('/omnichannel/current'),
};

const upgradeItem: GenericMenuItemProps = {
id: 'showUpgradeItem',
content: (
Expand Down Expand Up @@ -71,24 +117,10 @@ export const useAdministrationItems = ({ accountBoxItems, showWorkspace }: useAd
},
};

const accountBoxItem: GenericMenuItemProps[] = accountBoxItems.map((item, key) => {
const action = () => {
if (item.href) {
router.navigate(item.href);
}
};
return {
id: `account-box-item-${key}`,
content: t(item.name),
icon: item.icon,
onClick: action,
};
});

return [
...(showUpgradeItem ? [upgradeItem] : []),
...(isAdmin ? [adminItem] : []),
...(showWorkspace ? [workspaceItem] : []),
...(accountBoxItems.length ? accountBoxItem : []),
];
showUpgradeItem && upgradeItem,
isAdmin && adminItem,
omnichannel && omnichannelItem,
shouldShowAdminMenu && workspaceItem,
].filter(Boolean) as GenericMenuItemProps[];
};
Original file line number Diff line number Diff line change
@@ -1,72 +1,20 @@
import { useMutableCallback } from '@rocket.chat/fuselage-hooks';
import { useAtLeastOnePermission, usePermission, useTranslation } from '@rocket.chat/ui-contexts';
import { useTranslation } from '@rocket.chat/ui-contexts';

import { AccountBox } from '../../../../../app/ui-utils/client';
import type { IAppAccountBoxItem, AccountBoxItem } from '../../../../../app/ui-utils/client/lib/AccountBox';
import { isAppAccountBoxItem } from '../../../../../app/ui-utils/client/lib/AccountBox';
import { useHasLicenseModule } from '../../../../../ee/client/hooks/useHasLicenseModule';
import { useReactiveValue } from '../../../../hooks/useReactiveValue';
import type { GenericMenuItemProps } from '../../../../components/GenericMenu/GenericMenuItem';
import { useAdministrationItems } from './useAdministrationItems';
import { useAppsItems } from './useAppsItems';
import { useAuditItems } from './useAuditItems';

const ADMIN_PERMISSIONS = [
'view-statistics',
'run-import',
'view-user-administration',
'view-room-administration',
'create-invite-links',
'manage-cloud',
'view-logs',
'manage-sounds',
'view-federation-data',
'manage-email-inbox',
'manage-emoji',
'manage-outgoing-integrations',
'manage-own-outgoing-integrations',
'manage-incoming-integrations',
'manage-own-incoming-integrations',
'manage-oauth-apps',
'access-mailer',
'manage-user-status',
'access-permissions',
'access-setting-permissions',
'view-privileged-setting',
'edit-privileged-setting',
'manage-selected-settings',
'view-engagement-dashboard',
'view-moderation-console',
];

export const useAdministrationMenu = () => {
const t = useTranslation();
const getAccountBoxItems = useMutableCallback(() => AccountBox.getItems());
const accountBoxItems = useReactiveValue(getAccountBoxItems);

const hasAuditLicense = useHasLicenseModule('auditing') === true;
const hasManageAppsPermission = usePermission('manage-apps');
const hasAccessMarketplacePermission = usePermission('access-marketplace');
const hasAdminPermission = useAtLeastOnePermission(ADMIN_PERMISSIONS);
const hasAuditPermission = usePermission('can-audit') && hasAuditLicense;
const hasAuditLogPermission = usePermission('can-audit-log') && hasAuditLicense;

const appBoxItems = accountBoxItems.filter((item): item is IAppAccountBoxItem => isAppAccountBoxItem(item));
const adminBoxItems = accountBoxItems.filter((item): item is AccountBoxItem => !isAppAccountBoxItem(item));

const showAdmin = hasAdminPermission || !!adminBoxItems.length;
const showAudit = hasAuditPermission || hasAuditLogPermission;
const showWorkspace = hasAdminPermission;
const showApps = hasAccessMarketplacePermission || hasManageAppsPermission || !!appBoxItems.length;

const administrationItems = useAdministrationItems({ accountBoxItems: adminBoxItems, showWorkspace });
const administrationItems = useAdministrationItems();
const appItems = useAppsItems();
const auditItems = useAuditItems({ showAudit: hasAuditPermission, showAuditLog: hasAuditLogPermission });

const sections = [
{ title: t('Administration'), items: administrationItems, permission: showAdmin },
{ title: t('Apps'), items: appItems, permission: showApps },
{ title: t('Audit'), items: auditItems, permission: showAudit },
];
const auditItems = useAuditItems();

return sections.filter(({ permission }) => permission);
return [
administrationItems.length && { title: t('Administration'), items: administrationItems },
appItems.length && { title: t('Apps'), items: appItems },
auditItems.length && { title: t('Audit'), items: auditItems },
].filter(Boolean) as Array<{ title: string; items: GenericMenuItemProps[] }>;
};
19 changes: 12 additions & 7 deletions apps/meteor/client/sidebar/header/actions/hooks/useAuditItems.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import { useTranslation, useRoute } from '@rocket.chat/ui-contexts';
import { useTranslation, useRoute, usePermission } from '@rocket.chat/ui-contexts';

import { useHasLicenseModule } from '../../../../../ee/client/hooks/useHasLicenseModule';
import type { GenericMenuItemProps } from '../../../../components/GenericMenu/GenericMenuItem';

type useAuditItemsProps = {
showAudit: boolean;
showAuditLog: boolean;
};
export const useAuditItems = (): GenericMenuItemProps[] => {
const hasAuditLicense = useHasLicenseModule('auditing') === true;

const hasAuditPermission = usePermission('can-audit') && hasAuditLicense;
const hasAuditLogPermission = usePermission('can-audit-log') && hasAuditLicense;

export const useAuditItems = ({ showAudit, showAuditLog }: useAuditItemsProps): GenericMenuItemProps[] => {
const t = useTranslation();

const auditHomeRoute = useRoute('audit-home');
const auditSettingsRoute = useRoute('audit-log');

if (!hasAuditPermission && !hasAuditLogPermission) {
return [];
}

const auditMessageItem: GenericMenuItemProps = {
id: 'messages',
icon: 'document-eye',
Expand All @@ -26,5 +31,5 @@ export const useAuditItems = ({ showAudit, showAuditLog }: useAuditItemsProps):
onClick: () => auditSettingsRoute.push(),
};

return [...(showAudit ? [auditMessageItem] : []), ...(showAuditLog ? [auditLogItem] : [])];
return [hasAuditPermission && auditMessageItem, hasAuditLogPermission && auditLogItem].filter(Boolean) as GenericMenuItemProps[];
};
10 changes: 5 additions & 5 deletions apps/meteor/client/sidebar/header/hooks/useStatusItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ import type { IUser, ValueOf } from '@rocket.chat/core-typings';
import { UserStatus as UserStatusEnum } from '@rocket.chat/core-typings';
import { Box } from '@rocket.chat/fuselage';
import type { TranslationKey } from '@rocket.chat/ui-contexts';
import { useSetting, useTranslation } from '@rocket.chat/ui-contexts';
import { useEndpoint, useSetting, useTranslation } from '@rocket.chat/ui-contexts';
import React from 'react';

import { AccountBox } from '../../../../app/ui-utils/client';
import { userStatus } from '../../../../app/user-status/client';
import { callbacks } from '../../../../lib/callbacks';
import type { GenericMenuItemProps } from '../../../components/GenericMenu/GenericMenuItem';
Expand All @@ -27,9 +26,10 @@ const translateStatusName = (t: ReturnType<typeof useTranslation>, status: (type
export const useStatusItems = (user: IUser): GenericMenuItemProps[] => {
const t = useTranslation();
const presenceDisabled = useSetting<boolean>('Presence_broadcast_disabled');
const setStatus = useEndpoint('POST', '/v1/users.setStatus');

const setStatus = (status: (typeof userStatus.list)['']): void => {
AccountBox.setStatus(status.statusType, !isDefaultStatus(status.id) ? status.name : '');
const setStatusAction = (status: (typeof userStatus.list)['']): void => {
setStatus({ status: status.statusType, message: !isDefaultStatus(status.id) ? status.name : '' });
void callbacks.run('userStatusManuallySet', status);
};

Expand Down Expand Up @@ -64,7 +64,7 @@ export const useStatusItems = (user: IUser): GenericMenuItemProps[] => {
id: status.id,
status: <UserStatus status={modifier} />,
content: <MarkdownText content={name} parseEmoji={true} variant='inline' />,
onClick: () => setStatus(status),
onClick: () => setStatusAction(status),
disabled: presenceDisabled,
};
});
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/client/startup/iframeCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Meteor } from 'meteor/meteor';
import { ServiceConfiguration } from 'meteor/service-configuration';

import { settings } from '../../app/settings/client';
import { AccountBox } from '../../app/ui-utils/client';
import { AccountBox } from '../../app/ui-utils/client/lib/AccountBox';
import { sdk } from '../../app/utils/client/lib/SDKClient';
import { callbacks } from '../../lib/callbacks';
import { capitalize, ltrim, rtrim } from '../../lib/utils/stringUtils';
Expand Down

0 comments on commit bd231a0

Please sign in to comment.