diff --git a/apps/meteor/client/views/admin/users/AdminUsersPage.tsx b/apps/meteor/client/views/admin/users/AdminUsersPage.tsx index 14757e3710b06..afe881f64cc9f 100644 --- a/apps/meteor/client/views/admin/users/AdminUsersPage.tsx +++ b/apps/meteor/client/views/admin/users/AdminUsersPage.tsx @@ -147,12 +147,12 @@ const AdminUsersPage = (): ReactElement => { diff --git a/apps/meteor/client/views/admin/users/UsersPageHeaderContent.spec.tsx b/apps/meteor/client/views/admin/users/UsersPageHeaderContent.spec.tsx index f4691eb4dd69a..6181fe4fed50f 100644 --- a/apps/meteor/client/views/admin/users/UsersPageHeaderContent.spec.tsx +++ b/apps/meteor/client/views/admin/users/UsersPageHeaderContent.spec.tsx @@ -5,12 +5,31 @@ import '@testing-library/jest-dom'; import UsersPageHeaderContent from './UsersPageHeaderContent'; -it('should render "Associate Extension" button when VoIP_TeamCollab_Enabled setting is enabled', async () => { +it('should not show "Assign Extension" button if voip setting is enabled but user dont have required permission', async () => { render(, { legacyRoot: true, wrapper: mockAppRoot().withJohnDoe().withSetting('VoIP_TeamCollab_Enabled', true).build(), }); + expect(screen.queryByRole('button', { name: 'Assign_extension' })).not.toBeInTheDocument(); +}); + +it('should not show "Assign Extension" button if user has required permission but voip setting is disabled', async () => { + render(, { + legacyRoot: true, + wrapper: mockAppRoot().withJohnDoe().withSetting('VoIP_TeamCollab_Enabled', true).build(), + }); + + expect(screen.queryByRole('button', { name: 'Assign_extension' })).not.toBeInTheDocument(); +}); + +it('should show "Assign Extension" button if user has required permission and voip setting is enabled', async () => { + render(, { + legacyRoot: true, + wrapper: mockAppRoot().withJohnDoe().withSetting('VoIP_TeamCollab_Enabled', true).withPermission('manage-voip-extensions').build(), + }); + + expect(screen.getByRole('button', { name: 'Assign_extension' })).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'Assign_extension' })).toBeEnabled(); }); diff --git a/apps/meteor/client/views/admin/users/UsersPageHeaderContent.tsx b/apps/meteor/client/views/admin/users/UsersPageHeaderContent.tsx index e6794a9f98f6c..89916c3e6f2e7 100644 --- a/apps/meteor/client/views/admin/users/UsersPageHeaderContent.tsx +++ b/apps/meteor/client/views/admin/users/UsersPageHeaderContent.tsx @@ -1,5 +1,5 @@ import { Button, ButtonGroup, Margins } from '@rocket.chat/fuselage'; -import { usePermission, useRouter, useSetModal, useSetting } from '@rocket.chat/ui-contexts'; +import { usePermission, useRouter } from '@rocket.chat/ui-contexts'; import React from 'react'; import { useTranslation } from 'react-i18next'; @@ -7,7 +7,8 @@ import { useExternalLink } from '../../../hooks/useExternalLink'; import { useCheckoutUrl } from '../subscription/hooks/useCheckoutUrl'; import SeatsCapUsage from './SeatsCapUsage'; import type { SeatCapProps } from './useSeatsCap'; -import AssignExtensionModal from './voip/AssignExtensionModal'; +import AssignExtensionButton from './voip/AssignExtensionButton'; +import { useVoipExtensionPermission } from './voip/hooks/useVoipExtensionPermission'; type UsersPageHeaderContentProps = { isSeatsCapExceeded: boolean; @@ -17,10 +18,9 @@ type UsersPageHeaderContentProps = { const UsersPageHeaderContent = ({ isSeatsCapExceeded, seatsCap }: UsersPageHeaderContentProps) => { const { t } = useTranslation(); const router = useRouter(); - const setModal = useSetModal(); const canCreateUser = usePermission('create-user'); const canBulkCreateUser = usePermission('bulk-register-user'); - const canRegisterExtension = useSetting('VoIP_TeamCollab_Enabled'); + const canManageVoipExtension = useVoipExtensionPermission(); const manageSubscriptionUrl = useCheckoutUrl()({ target: 'user-page', action: 'buy_more' }); const openExternalLink = useExternalLink(); @@ -41,11 +41,7 @@ const UsersPageHeaderContent = ({ isSeatsCapExceeded, seatsCap }: UsersPageHeade )} - {canRegisterExtension && ( - - )} + {canManageVoipExtension && } {canBulkCreateUser && ( ); }; diff --git a/apps/meteor/client/views/admin/users/voip/hooks/useVoipExtensionAction.tsx b/apps/meteor/client/views/admin/users/voip/hooks/useVoipExtensionAction.tsx new file mode 100644 index 0000000000000..e5f25683586a7 --- /dev/null +++ b/apps/meteor/client/views/admin/users/voip/hooks/useVoipExtensionAction.tsx @@ -0,0 +1,37 @@ +import { useEffectEvent } from '@rocket.chat/fuselage-hooks'; +import { useSetModal } from '@rocket.chat/ui-contexts'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; + +import type { Action } from '../../../../hooks/useActionSpread'; +import AssignExtensionModal from '../AssignExtensionModal'; +import RemoveExtensionModal from '../RemoveExtensionModal'; + +type VoipExtensionActionParams = { + name: string; + username: string; + extension?: string; + enabled: boolean; +}; + +export const useVoipExtensionAction = ({ name, username, extension, enabled }: VoipExtensionActionParams): Action | undefined => { + const { t } = useTranslation(); + const setModal = useSetModal(); + + const handleExtensionAssignment = useEffectEvent(() => { + if (extension) { + setModal( setModal(null)} />); + return; + } + + setModal( setModal(null)} />); + }); + + return enabled + ? { + icon: extension ? 'phone-disabled' : 'phone', + label: extension ? t('Unassign_extension') : t('Assign_extension'), + action: handleExtensionAssignment, + } + : undefined; +}; diff --git a/apps/meteor/client/views/admin/users/voip/hooks/useVoipExtensionPermission.tsx b/apps/meteor/client/views/admin/users/voip/hooks/useVoipExtensionPermission.tsx new file mode 100644 index 0000000000000..70e9e2ce91af9 --- /dev/null +++ b/apps/meteor/client/views/admin/users/voip/hooks/useVoipExtensionPermission.tsx @@ -0,0 +1,8 @@ +import { useSetting, usePermission } from '@rocket.chat/ui-contexts'; + +export const useVoipExtensionPermission = () => { + const isVoipSettingEnabled = useSetting('VoIP_TeamCollab_Enabled', false); + const canManageVoipExtensions = usePermission('manage-voip-extensions'); + + return isVoipSettingEnabled && canManageVoipExtensions; +};