-
Notifications
You must be signed in to change notification settings - Fork 11k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
134f456
commit 7eec447
Showing
12 changed files
with
208 additions
and
85 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
apps/meteor/client/views/admin/users/hooks/useVoiceCallExtensionAction.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { useEffectEvent } from '@rocket.chat/fuselage-hooks'; | ||
import { useSetModal, useSetting } from '@rocket.chat/ui-contexts'; | ||
import React from 'react'; | ||
import { useTranslation } from 'react-i18next'; | ||
|
||
import type { Action } from '../../../hooks/useActionSpread'; | ||
import AssignExtensionModal from '../voip/AssignExtensionModal'; | ||
import RemoveExtensionModal from '../voip/RemoveExtensionModal'; | ||
|
||
type VoiceCallExtensionActionParams = { | ||
name: string; | ||
username: string; | ||
extension?: string; | ||
}; | ||
|
||
export const useVoiceCallExtensionAction = ({ name, username, extension }: VoiceCallExtensionActionParams): Action | undefined => { | ||
const isVoiceCallEnabled = useSetting('VoIP_TeamCollab_Enabled'); | ||
const { t } = useTranslation(); | ||
const setModal = useSetModal(); | ||
|
||
const handleExtensionAssignment = useEffectEvent(() => { | ||
if (extension) { | ||
setModal(<RemoveExtensionModal name={name} username={username} extension={extension} onClose={(): void => setModal(null)} />); | ||
return; | ||
} | ||
|
||
setModal(<AssignExtensionModal defaultUsername={username} onClose={(): void => setModal(null)} />); | ||
}); | ||
|
||
return isVoiceCallEnabled | ||
? { | ||
icon: extension ? 'phone-disabled' : 'phone', | ||
label: extension ? t('Unassign_extension') : t('Assign_extension'), | ||
action: handleExtensionAssignment, | ||
} | ||
: undefined; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 0 additions & 61 deletions
61
apps/meteor/client/views/admin/users/voip/RemoveExtensionButton.tsx
This file was deleted.
Oops, something went wrong.
54 changes: 54 additions & 0 deletions
54
apps/meteor/client/views/admin/users/voip/RemoveExtensionModal.spec.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { mockAppRoot } from '@rocket.chat/mock-providers'; | ||
import { render, screen, waitFor } from '@testing-library/react'; | ||
import React from 'react'; | ||
|
||
import '@testing-library/jest-dom'; | ||
import RemoveExtensionModal from './RemoveExtensionModal'; | ||
|
||
const appRoot = mockAppRoot().withJohnDoe(); | ||
|
||
it('should have user and extension informed', async () => { | ||
render(<RemoveExtensionModal name='John Doe' username='john.doe' extension='1000' onClose={() => undefined} />, { | ||
legacyRoot: true, | ||
wrapper: appRoot.build(), | ||
}); | ||
|
||
expect(screen.getByLabelText('User')).toHaveValue('John Doe'); | ||
expect(screen.getByLabelText('Extension')).toHaveValue('1000'); | ||
}); | ||
|
||
it('should call assign endpoint and onClose when extension is removed', async () => { | ||
const closeFn = jest.fn(); | ||
const assignFn = jest.fn(() => null); | ||
render(<RemoveExtensionModal name='John Doe' username='john.doe' extension='1000' onClose={closeFn} />, { | ||
legacyRoot: true, | ||
wrapper: appRoot.withEndpoint('POST', '/v1/voip-freeswitch.extension.assign', assignFn).build(), | ||
}); | ||
|
||
screen.getByRole('button', { name: /Remove/i, hidden: true }).click(); | ||
|
||
await waitFor(() => expect(assignFn).toHaveBeenCalled()); | ||
await waitFor(() => expect(closeFn).toHaveBeenCalled()); | ||
}); | ||
|
||
it('should call onClose when cancel button is clicked', () => { | ||
const closeFn = jest.fn(); | ||
render(<RemoveExtensionModal name='John Doe' username='john.doe' extension='1000' onClose={closeFn} />, { | ||
legacyRoot: true, | ||
wrapper: appRoot.build(), | ||
}); | ||
|
||
screen.getByRole('button', { name: /Cancel/i, hidden: true }).click(); | ||
expect(closeFn).toHaveBeenCalled(); | ||
}); | ||
|
||
it('should call onClose when cancel button is clicked', () => { | ||
const closeFn = jest.fn(); | ||
render(<RemoveExtensionModal name='John Doe' username='john.doe' extension='1000' onClose={closeFn} />, { | ||
legacyRoot: true, | ||
wrapper: appRoot.build(), | ||
}); | ||
|
||
screen.getByRole('button', { name: /Close/i, hidden: true }).click(); | ||
expect(closeFn).toHaveBeenCalled(); | ||
}); |
81 changes: 81 additions & 0 deletions
81
apps/meteor/client/views/admin/users/voip/RemoveExtensionModal.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import { Button, Modal, Field, FieldGroup, FieldLabel, FieldRow, TextInput } from '@rocket.chat/fuselage'; | ||
import { useUniqueId } from '@rocket.chat/fuselage-hooks'; | ||
import { useToastMessageDispatch, useEndpoint, useUser } from '@rocket.chat/ui-contexts'; | ||
import { useMutation, useQueryClient } from '@tanstack/react-query'; | ||
import React from 'react'; | ||
import { useTranslation } from 'react-i18next'; | ||
|
||
type RemoveExtensionModalProps = { | ||
name: string; | ||
extension: string; | ||
username: string; | ||
onClose: () => void; | ||
}; | ||
|
||
const RemoveExtensionModal = ({ name, extension, username, onClose }: RemoveExtensionModalProps) => { | ||
const { t } = useTranslation(); | ||
const dispatchToastMessage = useToastMessageDispatch(); | ||
const queryClient = useQueryClient(); | ||
|
||
const loggedUser = useUser(); | ||
|
||
const removeExtension = useEndpoint('POST', '/v1/voip-freeswitch.extension.assign'); | ||
|
||
const modalTitleId = useUniqueId(); | ||
const userFieldId = useUniqueId(); | ||
const freeExtensionNumberId = useUniqueId(); | ||
|
||
const handleRemoveExtension = useMutation({ | ||
mutationFn: (username: string) => removeExtension({ username }), | ||
onSuccess: () => { | ||
dispatchToastMessage({ type: 'success', message: t('Extension_removed') }); | ||
|
||
queryClient.invalidateQueries(['users.list']); | ||
if (loggedUser?.username === username) { | ||
queryClient.invalidateQueries(['voice-call-client']); | ||
} | ||
|
||
onClose(); | ||
}, | ||
onError: (error) => { | ||
dispatchToastMessage({ type: 'error', message: error }); | ||
onClose(); | ||
}, | ||
}); | ||
|
||
return ( | ||
<Modal aria-labelledby={modalTitleId}> | ||
<Modal.Header> | ||
<Modal.Title id={modalTitleId}>{t('Remove_extension')}</Modal.Title> | ||
<Modal.Close aria-label={t('Close')} onClick={onClose} /> | ||
</Modal.Header> | ||
<Modal.Content> | ||
<FieldGroup> | ||
<Field> | ||
<FieldLabel htmlFor={userFieldId}>{t('User')}</FieldLabel> | ||
<FieldRow> | ||
<TextInput disabled id={userFieldId} value={name} /> | ||
</FieldRow> | ||
</Field> | ||
|
||
<Field> | ||
<FieldLabel htmlFor={freeExtensionNumberId}>{t('Extension')}</FieldLabel> | ||
<FieldRow> | ||
<TextInput disabled id={freeExtensionNumberId} value={extension} /> | ||
</FieldRow> | ||
</Field> | ||
</FieldGroup> | ||
</Modal.Content> | ||
<Modal.Footer> | ||
<Modal.FooterControllers> | ||
<Button onClick={onClose}>{t('Cancel')}</Button> | ||
<Button danger onClick={() => handleRemoveExtension.mutate(username)} loading={handleRemoveExtension.isLoading}> | ||
{t('Remove')} | ||
</Button> | ||
</Modal.FooterControllers> | ||
</Modal.Footer> | ||
</Modal> | ||
); | ||
}; | ||
|
||
export default RemoveExtensionModal; |
Oops, something went wrong.