Skip to content

Commit

Permalink
[NEW] VoIP admin section (#23837)
Browse files Browse the repository at this point in the history
Co-authored-by: Kevin Aleman <kevin.aleman@rocket.chat>
  • Loading branch information
MartinSchoeler and KevLehman committed Dec 2, 2021
1 parent ac3595d commit 38bb1ec
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 14 deletions.
92 changes: 92 additions & 0 deletions app/lib/server/startup/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3041,3 +3041,95 @@ settingsRegistry.addGroup('Troubleshoot', function() {
alert: 'Troubleshoot_Disable_Workspace_Sync_Alert',
});
});


settingsRegistry.addGroup('VoIP', function() {
this.add('VoIP_Enabled', false, {
type: 'boolean',
public: true,
alert: 'Experimental_Feature_Alert',
});

this.section('Server Configuration', function() {
// TODO: Remove default values before deploying
this.add('VoIP_Server_Host', 'omni-asterisk.dev.rocket.chat', {
type: 'string',
public: true,
enableQuery: {
_id: 'VoIP_Enabled',
value: true,
},
});
this.add('VoIP_Server_Websocket_Port', '443', {
type: 'string',
public: true,
enableQuery: {
_id: 'VoIP_Enabled',
value: true,
},
});
this.add('VoIP_Server_Name', 'OmniAsterisk', {
type: 'string',
public: true,
enableQuery: {
_id: 'VoIP_Enabled',
value: true,
},
});
this.add('VoIP_Server_Websocket_Path', 'wss://omni-asterisk.dev.rocket.chat/ws', {
type: 'string',
public: true,
enableQuery: {
_id: 'VoIP_Enabled',
value: true,
},
});
});

this.section('Management Server', function() {
this.add('VoIP_Management_Server_Host', 'omni-asterisk.dev.rocket.chat', {
type: 'string',
public: true,
enableQuery: {
_id: 'VoIP_Enabled',
value: true,
},
});

this.add('VoIP_Management_Server_Port', '5038', {
type: 'string',
public: true,
enableQuery: {
_id: 'VoIP_Enabled',
value: true,
},
});

this.add('VoIP_Management_Server_Name', 'OmniAsterisk', {
type: 'string',
public: true,
enableQuery: {
_id: 'VoIP_Enabled',
value: true,
},
});

this.add('VoIP_Management_Server_Username', 'amol', {
type: 'string',
public: true,
enableQuery: {
_id: 'VoIP_Enabled',
value: true,
},
});

this.add('VoIP_Management_Server_Password', '1234', {
type: 'string',
public: true,
enableQuery: {
_id: 'VoIP_Enabled',
value: true,
},
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,59 @@ import {
Select,
} from '@rocket.chat/fuselage';
import { useMutableCallback } from '@rocket.chat/fuselage-hooks';
import React, { useMemo, useRef, useState } from 'react';
import React, { useMemo, useRef, useState, FC, ReactElement } from 'react';
import { useSubscription } from 'use-subscription';

import { IUser } from '../../../../definition/IUser';
import { getUserEmailAddress } from '../../../../lib/getUserEmailAddress';
import VerticalBar from '../../../components/VerticalBar';
import { useRoute } from '../../../contexts/RouterContext';
import { useMethod } from '../../../contexts/ServerContext';
import { useSetting } from '../../../contexts/SettingsContext';
import { useToastMessageDispatch } from '../../../contexts/ToastMessagesContext';
import { useTranslation } from '../../../contexts/TranslationContext';
import { useForm } from '../../../hooks/useForm';
import UserInfo from '../../room/contextualBar/UserInfo';
import { formsSubscription } from '../additionalForms';

function AgentEdit({ data, userDepartments, availableDepartments, uid, reset, ...props }) {
// TODO: TYPE:
// Department

type dataType = {
status: string;
user: IUser;
};

type AgentEditProps = {
data: dataType;
userDepartments: { departments: Array<{ departmentId: string }> };
availableDepartments: { departments: Array<{ _id: string; name?: string }> };
uid: string;
reset: () => void;
};

const AgentEdit: FC<AgentEditProps> = ({
data,
userDepartments,
availableDepartments,
uid,
reset,
...props
}) => {
const t = useTranslation();
const agentsRoute = useRoute('omnichannel-agents');
const [maxChatUnsaved, setMaxChatUnsaved] = useState();
const voipEnabled = useSetting('VoIP_Enabled');

const { user } = data || { user: {} };
const { name, username, statusLivechat } = user;

const email = getUserEmailAddress(user);
const options = useMemo(

const options: [string, string][] = useMemo(
() =>
availableDepartments && availableDepartments.departments
? availableDepartments.departments.map(({ _id, name }) => [_id, name || _id])
? availableDepartments.departments.map(({ _id, name }) => (name ? [_id, name] : [_id, _id]))
: [],
[availableDepartments],
);
Expand All @@ -47,7 +74,14 @@ function AgentEdit({ data, userDepartments, availableDepartments, uid, reset, ..
);
const eeForms = useSubscription(formsSubscription);

const saveRef = useRef({ values: {}, hasUnsavedChanges: false });
const saveRef = useRef({
values: {},
hasUnsavedChanges: false,
reset: () => undefined,
commit: () => undefined,
});

const { reset: resetMaxChats, commit: commitMaxChats } = saveRef.current;

const onChangeMaxChats = useMutableCallback(({ hasUnsavedChanges, ...value }) => {
saveRef.current = value;
Expand All @@ -57,17 +91,21 @@ function AgentEdit({ data, userDepartments, availableDepartments, uid, reset, ..
}
});

const { useMaxChatsPerAgent = () => {} } = eeForms;
const { useMaxChatsPerAgent = (): ReactElement | null => null } = eeForms as any; // TODO: Find out how to use ts with eeForms

const { values, handlers, hasUnsavedChanges, commit } = useForm({
departments: initialDepartmentValue,
status: statusLivechat,
maxChats: 0,
voipExtension: '',
});
const { reset: resetMaxChats, commit: commitMaxChats } = saveRef.current;

const { handleDepartments, handleStatus } = handlers;
const { departments, status } = values;
const { handleDepartments, handleStatus, handleVoipExtension } = handlers;
const { departments, status, voipExtension } = values as {
departments: string[];
status: string;
voipExtension: string;
};

const MaxChats = useMaxChatsPerAgent();

Expand All @@ -85,11 +123,11 @@ function AgentEdit({ data, userDepartments, availableDepartments, uid, reset, ..
try {
await saveAgentInfo(uid, saveRef.current.values, departments);
await saveAgentStatus({ status, agentId: uid });
dispatchToastMessage({ type: 'success', message: t('saved') });
dispatchToastMessage({ type: 'success', message: t('Success') });
agentsRoute.push({});
reset();
} catch (error) {
dispatchToastMessage({ type: 'error', message: error });
dispatchToastMessage({ type: 'error', message: error as string });
}
commit();
commitMaxChats();
Expand Down Expand Up @@ -148,6 +186,19 @@ function AgentEdit({ data, userDepartments, availableDepartments, uid, reset, ..

{MaxChats && <MaxChats data={user} onChange={onChangeMaxChats} />}

{voipEnabled && (
<Field>
<Field.Label>{t('VoIP_Extension')}</Field.Label>
<Field.Row>
<TextInput
flexGrow={1}
value={voipExtension as string}
onChange={handleVoipExtension}
/>
</Field.Row>
</Field>
)}

<Field.Row>
<Box display='flex' flexDirection='row' justifyContent='space-between' w='full'>
<Margins inlineEnd='x4'>
Expand All @@ -172,6 +223,6 @@ function AgentEdit({ data, userDepartments, availableDepartments, uid, reset, ..
</Field.Row>
</VerticalBar.ScrollableContent>
);
}
};

export default AgentEdit;
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { NumberInput, Field } from '@rocket.chat/fuselage';
import React from 'react';
import React, { FC } from 'react';

import { useTranslation } from '../../../../client/contexts/TranslationContext';

const MaxChatsPerAgent = ({ values, handlers }) => {
const MaxChatsPerAgent: FC<{
values: { maxNumberSimultaneousChat: number };
handlers: { handleMaxNumberSimultaneousChat: () => void };
}> = ({ values, handlers }) => {
const t = useTranslation();
const { maxNumberSimultaneousChat } = values;
const { handleMaxNumberSimultaneousChat } = handlers;
Expand Down
13 changes: 13 additions & 0 deletions packages/rocketchat-i18n/i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -4599,6 +4599,19 @@
"Visitor_Navigation": "Visitor Navigation",
"Visitor_page_URL": "Visitor page URL",
"Visitor_time_on_site": "Visitor time on site",
"VoIP_Enabled": "VoIP Enabled",
"VoIP_Extension": "VoIP Extension",
"Voip_Server_Configuration": "Server Configuration",
"VoIP_Server_Host": "VoIP Server Host",
"VoIP_Server_Websocket_Port": "VoIP Server Websocket Port",
"VoIP_Server_Name": "VoIP Server Name",
"VoIP_Server_Websocket_Path": "VoIP Server Websocket Path",
"VoIP_Management_Server": "VoIP Management Server",
"VoIP_Management_Server_Host": "VoIP Management Server Host",
"VoIP_Management_Server_Port": "VoIP Management Server Port",
"VoIP_Management_Server_Name": "VoIP Management Server Name",
"VoIP_Management_Server_Username": "VoIP Management Server Username",
"VoIP_Management_Server_Password": "VoIP Management Server Password",
"Chat_opened_by_visitor": "Chat opened by the visitor",
"Wait_activation_warning": "Before you can login, your account must be manually activated by an administrator.",
"Waiting_queue": "Waiting queue",
Expand Down

0 comments on commit 38bb1ec

Please sign in to comment.