mirror of
https://github.com/jambonz/jambonz-webapp.git
synced 2026-10-29 23:04:30 +00:00
Reorganize components
This commit is contained in:
1 parent
74572e3940
commit
13201ef03e
43 files changed
+87
-87
No files matched your search
@@ -0,0 +1,644 @@
|
||||
import React, { useState, useEffect, useContext, useRef } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import axios from 'axios';
|
||||
import { NotificationDispatchContext } from '../../contexts/NotificationContext';
|
||||
import Form from '../elements/Form';
|
||||
import Input from '../elements/Input';
|
||||
import Label from '../elements/Label';
|
||||
import Checkbox from '../elements/Checkbox';
|
||||
import InputGroup from '../elements/InputGroup';
|
||||
import FormError from '../blocks/FormError';
|
||||
import Button from '../elements/Button';
|
||||
import TrashButton from '../elements/TrashButton';
|
||||
import Loader from '../blocks/Loader';
|
||||
|
||||
const SipTrunkForm = props => {
|
||||
const history = useHistory();
|
||||
const dispatch = useContext(NotificationDispatchContext);
|
||||
|
||||
// Refs
|
||||
const refName = useRef(null);
|
||||
const refIp = useRef([]);
|
||||
const refPort = useRef([]);
|
||||
const refInbound = useRef([]);
|
||||
const refOutbound = useRef([]);
|
||||
const refTrash = useRef([]);
|
||||
const refAdd = useRef(null);
|
||||
|
||||
// Form inputs
|
||||
const [ name, setName ] = useState('');
|
||||
const [ nameInvalid, setNameInvalid ] = useState(false);
|
||||
const [ description, setDescription ] = useState('');
|
||||
const [ sipGateways, setSipGateways ] = useState([
|
||||
{
|
||||
sip_gateway_sid: '',
|
||||
ip: '',
|
||||
port: 5060,
|
||||
inbound: true,
|
||||
outbound: true,
|
||||
invalidIp: false,
|
||||
invalidPort: false,
|
||||
invalidInbound: false,
|
||||
invalidOutbound: false,
|
||||
}
|
||||
]);
|
||||
|
||||
const [ sipTrunks, setSipTrunks ] = useState([]);
|
||||
const [ sipTrunkSid, setSipTrunkSid ] = useState('');
|
||||
const [ showLoader, setShowLoader ] = useState(true);
|
||||
const [ errorMessage, setErrorMessage ] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
if (!localStorage.getItem('token')) {
|
||||
history.push('/');
|
||||
dispatch({
|
||||
type: 'ADD',
|
||||
level: 'error',
|
||||
message: 'You must log in to view that page.',
|
||||
});
|
||||
}
|
||||
}, [history, dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
const getAPIData = async () => {
|
||||
const sipTrunksPromise = axios({
|
||||
method: 'get',
|
||||
baseURL: process.env.REACT_APP_API_BASE_URL,
|
||||
url: `/VoipCarriers`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${localStorage.getItem('token')}`,
|
||||
},
|
||||
});
|
||||
const sipGatewaysPromise = axios({
|
||||
method: 'get',
|
||||
baseURL: process.env.REACT_APP_API_BASE_URL,
|
||||
url: `/SipGateways`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${localStorage.getItem('token')}`,
|
||||
},
|
||||
});
|
||||
const promiseAllValues = await Promise.all([
|
||||
sipTrunksPromise,
|
||||
sipGatewaysPromise,
|
||||
]);
|
||||
|
||||
const allSipTrunks = promiseAllValues[0].data;
|
||||
const allSipGateways = promiseAllValues[1].data;
|
||||
|
||||
setSipTrunks(allSipTrunks);
|
||||
|
||||
if (props.type === 'setup' && allSipTrunks.length > 1) {
|
||||
history.push('/internal/sip-trunks');
|
||||
dispatch({
|
||||
type: 'ADD',
|
||||
level: 'error',
|
||||
message: 'That page is only accessible during setup',
|
||||
});
|
||||
}
|
||||
|
||||
if (props.type === 'edit' || props.type === 'setup') {
|
||||
const currentSipTrunk = props.type === 'edit'
|
||||
? allSipTrunks.filter(s => s.voip_carrier_sid === props.voip_carrier_sid)
|
||||
: allSipTrunks;
|
||||
|
||||
if (props.type === 'edit' && !currentSipTrunk.length) {
|
||||
history.push('/internal/sip-trunks');
|
||||
dispatch({
|
||||
type: 'ADD',
|
||||
level: 'error',
|
||||
message: 'That SIP trunk does not exist',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const currentSipGateways = allSipGateways.filter(s => {
|
||||
return s.voip_carrier_sid === currentSipTrunk[0].voip_carrier_sid;
|
||||
});
|
||||
|
||||
if (currentSipTrunk.length) {
|
||||
setName(currentSipTrunk[0].name);
|
||||
setDescription(currentSipTrunk[0].description);
|
||||
setSipGateways(currentSipGateways.map(s => ({
|
||||
sip_gateway_sid: s.sip_gateway_sid,
|
||||
ip: s.ipv4,
|
||||
port: s.port,
|
||||
inbound: s.inbound === 1,
|
||||
outbound: s.outbound === 1,
|
||||
invalidIp: false,
|
||||
invalidPort: false,
|
||||
invalidInbound: false,
|
||||
invalidOutbound: false,
|
||||
})));
|
||||
setSipTrunkSid(currentSipTrunk[0].voip_carrier_sid);
|
||||
}
|
||||
}
|
||||
setShowLoader(false);
|
||||
};
|
||||
getAPIData();
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
|
||||
const addSipGateway = () => {
|
||||
const newSipGateways = [
|
||||
...sipGateways,
|
||||
{
|
||||
sip_gateway_sid: '',
|
||||
ip: '',
|
||||
port: 5060,
|
||||
inbound: true,
|
||||
outbound: true,
|
||||
invalidIp: false,
|
||||
invalidPort: false,
|
||||
invalidInbound: false,
|
||||
invalidOutbound: false,
|
||||
}
|
||||
];
|
||||
setSipGateways(newSipGateways);
|
||||
};
|
||||
|
||||
const removeSipGateway = index => {
|
||||
const newSipGateways = sipGateways.filter((s,i) => i !== index);
|
||||
setSipGateways(newSipGateways);
|
||||
setErrorMessage('');
|
||||
};
|
||||
|
||||
const updateSipGateways = (e, i, key) => {
|
||||
const newSipGateways = [...sipGateways];
|
||||
const newValue =
|
||||
key === 'invalidIp' ||
|
||||
key === 'invalidPort' ||
|
||||
key === 'invalidInbound' ||
|
||||
key === 'invalidOutbound'
|
||||
? true
|
||||
: (key === 'inbound') || (key === 'outbound')
|
||||
? e.target.checked
|
||||
: e.target.value;
|
||||
newSipGateways[i][key] = newValue;
|
||||
setSipGateways(newSipGateways);
|
||||
};
|
||||
|
||||
const resetInvalidFields = () => {
|
||||
setNameInvalid(false);
|
||||
const newSipGateways = [...sipGateways];
|
||||
newSipGateways.forEach((s, i) => {
|
||||
newSipGateways[i].invalidIp = false;
|
||||
newSipGateways[i].invalidPort = false;
|
||||
newSipGateways[i].invalidInbound = false;
|
||||
newSipGateways[i].invalidOutbound = false;
|
||||
});
|
||||
setSipGateways(newSipGateways);
|
||||
};
|
||||
|
||||
const handleSumit = async e => {
|
||||
try {
|
||||
e.preventDefault();
|
||||
setErrorMessage('');
|
||||
resetInvalidFields();
|
||||
let errorMessages = [];
|
||||
let focusHasBeenSet = false;
|
||||
|
||||
if (!name) {
|
||||
errorMessages.push('Please enter a name for this SIP Trunk.');
|
||||
setNameInvalid(true);
|
||||
if (!focusHasBeenSet) {
|
||||
refName.current.focus();
|
||||
focusHasBeenSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sipGateways.length) {
|
||||
errorMessages.push('You must provide at least one SIP Gateway.');
|
||||
if (!focusHasBeenSet) {
|
||||
refAdd.current.focus();
|
||||
focusHasBeenSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
const regIp = /^((25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9])$/;
|
||||
const regFqdn = /^([a-zA-Z][^.]*)(\.[^.]+){2,}$/;
|
||||
const regFqdnTopLevel = /^([a-zA-Z][^.]*)(\.[^.]+)$/;
|
||||
const regPort = /^[0-9]+$/;
|
||||
|
||||
sipGateways.forEach(async (gateway, i) => {
|
||||
//-----------------------------------------------------------------------------
|
||||
// IP validation
|
||||
//-----------------------------------------------------------------------------
|
||||
const type = regIp.test(gateway.ip)
|
||||
? 'ip'
|
||||
: regFqdn.test(gateway.ip)
|
||||
? 'fqdn'
|
||||
: regFqdnTopLevel.test(gateway.ip)
|
||||
? 'fqdn-top-level'
|
||||
: 'invalid';
|
||||
|
||||
if (!gateway.ip) {
|
||||
errorMessages.push('The IP Address cannot be blank. Please provide an IP address or delete the row.');
|
||||
updateSipGateways(null, i, 'invalidIp');
|
||||
if (!focusHasBeenSet) {
|
||||
refIp.current[i].focus();
|
||||
focusHasBeenSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
else if (type === 'fqdn-top-level') {
|
||||
errorMessages.push('When using an FQDN, you must use a subdomain (e.g. sip.example.com).');
|
||||
updateSipGateways(null, i, 'invalidIp');
|
||||
if (!focusHasBeenSet) {
|
||||
refIp.current[i].focus();
|
||||
focusHasBeenSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
else if (type === 'invalid') {
|
||||
errorMessages.push('Please provide a valid IP address or fully qualified domain name.');
|
||||
updateSipGateways(null, i, 'invalidIp');
|
||||
if (!focusHasBeenSet) {
|
||||
refIp.current[i].focus();
|
||||
focusHasBeenSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Port validation
|
||||
//-----------------------------------------------------------------------------
|
||||
if (
|
||||
gateway.port && (
|
||||
!(regPort.test(gateway.port))
|
||||
|| (parseInt(gateway.port) < 0)
|
||||
|| (parseInt(gateway.port) > 65535)
|
||||
)
|
||||
) {
|
||||
errorMessages.push('Please provide a valid port number between 0 and 65535');
|
||||
updateSipGateways(null, i, 'invalidPort');
|
||||
if (!focusHasBeenSet) {
|
||||
refPort.current[i].focus();
|
||||
focusHasBeenSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// inbound/outbound validation
|
||||
//-----------------------------------------------------------------------------
|
||||
if (type === 'fqdn' && (!gateway.outbound || gateway.inbound)) {
|
||||
errorMessages.push('A fully qualified domain name may only be used for outbound calls.');
|
||||
updateSipGateways(null, i, 'invalidIp');
|
||||
if (gateway.inbound) updateSipGateways(null, i, 'invalidInbound');
|
||||
if (!gateway.outbound) updateSipGateways(null, i, 'invalidOutbound');
|
||||
if (!focusHasBeenSet) {
|
||||
if (gateway.inbound) {
|
||||
refInbound.current[i].focus();
|
||||
} else {
|
||||
refOutbound.current[i].focus();
|
||||
}
|
||||
focusHasBeenSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
else if (!gateway.inbound && !gateway.outbound) {
|
||||
errorMessages.push('Each SIP Gateway must accept inbound calls, outbound calls, or both.');
|
||||
updateSipGateways(null, i, 'invalidInbound');
|
||||
updateSipGateways(null, i, 'invalidOutbound');
|
||||
if (!focusHasBeenSet) {
|
||||
refInbound.current[i].focus();
|
||||
focusHasBeenSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// duplicates validation
|
||||
//-----------------------------------------------------------------------------
|
||||
sipGateways.forEach((otherGateway, j) => {
|
||||
if (i >= j) return;
|
||||
if (!gateway.ip) return;
|
||||
if (type === 'invalid') return;
|
||||
if (gateway.ip === otherGateway.ip && gateway.port === otherGateway.port) {
|
||||
errorMessages.push('Each row must have a unique IP/Port combination. Please delete the duplicate row.');
|
||||
updateSipGateways(null, i, 'invalidIp');
|
||||
updateSipGateways(null, i, 'invalidPort');
|
||||
updateSipGateways(null, j, 'invalidIp');
|
||||
updateSipGateways(null, j, 'invalidPort');
|
||||
if (!focusHasBeenSet) {
|
||||
refTrash.current[j].focus();
|
||||
focusHasBeenSet = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// remove duplicate error messages
|
||||
for (let i = 0; i < errorMessages.length; i++) {
|
||||
for (let j = 0; j < errorMessages.length; j++) {
|
||||
if (i >= j) continue;
|
||||
if (errorMessages[i] === errorMessages[j]) {
|
||||
errorMessages.splice(j, 1);
|
||||
j = j - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (errorMessages.length > 1) {
|
||||
setErrorMessage(errorMessages);
|
||||
return;
|
||||
} else if (errorMessages.length === 1) {
|
||||
setErrorMessage(errorMessages[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Submit
|
||||
//=============================================================================
|
||||
const creatingNewTrunk = props.type === 'add' || (props.type === 'setup' && !sipTrunks.length);
|
||||
|
||||
const method = creatingNewTrunk
|
||||
? 'post'
|
||||
: 'put';
|
||||
|
||||
|
||||
const url = creatingNewTrunk
|
||||
? '/VoipCarriers'
|
||||
: `/VoipCarriers/${sipTrunkSid}`;
|
||||
|
||||
// Create or update SIP Trunk / VoIP Carrier
|
||||
const voipCarrier = await axios({
|
||||
method,
|
||||
baseURL: process.env.REACT_APP_API_BASE_URL,
|
||||
url,
|
||||
headers: {
|
||||
Authorization: `Bearer ${localStorage.getItem('token')}`,
|
||||
},
|
||||
data: {
|
||||
name,
|
||||
description,
|
||||
},
|
||||
});
|
||||
const voip_carrier_sid = voipCarrier.data.sid;
|
||||
|
||||
// get updated gateway info from API in order to delete ones that user has removed from UI
|
||||
let sipGatewaysFromAPI;
|
||||
if (!creatingNewTrunk) {
|
||||
const results = await axios({
|
||||
method: 'get',
|
||||
baseURL: process.env.REACT_APP_API_BASE_URL,
|
||||
url: '/SipGateways',
|
||||
headers: {
|
||||
Authorization: `Bearer ${localStorage.getItem('token')}`,
|
||||
},
|
||||
});
|
||||
sipGatewaysFromAPI = results.data.filter(s => s.voip_carrier_sid === sipTrunkSid);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Create or Update SIP Gateways
|
||||
//-----------------------------------------------------------------------------
|
||||
// Keeping track of created SIP gateways in case one throws an error, then all
|
||||
// of the ones created before that (as well as the sip trunk) have to be deleted.
|
||||
let completedSipGateways = [];
|
||||
try {
|
||||
for (const s of sipGateways) {
|
||||
const creatingNewGateway = creatingNewTrunk || s.sip_gateway_sid === '';
|
||||
|
||||
const method = creatingNewGateway
|
||||
? 'post'
|
||||
: 'put';
|
||||
|
||||
const url = creatingNewGateway
|
||||
? '/SipGateways'
|
||||
: `/SipGateways/${s.sip_gateway_sid}`;
|
||||
|
||||
const data = {
|
||||
ipv4: s.ip,
|
||||
port: s.port,
|
||||
inbound: s.inbound,
|
||||
outbound: s.outbound,
|
||||
};
|
||||
|
||||
if (creatingNewGateway) {
|
||||
data.voip_carrier_sid = voip_carrier_sid || sipTrunkSid;
|
||||
}
|
||||
|
||||
const result = await axios({
|
||||
method,
|
||||
baseURL: process.env.REACT_APP_API_BASE_URL,
|
||||
url,
|
||||
headers: {
|
||||
Authorization: `Bearer ${localStorage.getItem('token')}`,
|
||||
},
|
||||
data,
|
||||
});
|
||||
completedSipGateways.push(result.data.sid);
|
||||
};
|
||||
} catch (err) {
|
||||
if (completedSipGateways.length) {
|
||||
for (const sid of completedSipGateways) {
|
||||
await axios({
|
||||
method: 'delete',
|
||||
baseURL: process.env.REACT_APP_API_BASE_URL,
|
||||
url: `/SipGateways/${sid}`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${localStorage.getItem('token')}`,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
await axios({
|
||||
method: 'delete',
|
||||
baseURL: process.env.REACT_APP_API_BASE_URL,
|
||||
url: `/VoipCarriers/${voip_carrier_sid}`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${localStorage.getItem('token')}`,
|
||||
},
|
||||
});
|
||||
setErrorMessage((err.response && err.response.data && err.response.data.msg) || 'Something went wrong, please try again');
|
||||
console.log(err.response || err);
|
||||
}
|
||||
|
||||
// delete removed gateways (after add/update in case add/update caused errors)
|
||||
if (!creatingNewTrunk) {
|
||||
for (const remote of sipGatewaysFromAPI) {
|
||||
const match = sipGateways.filter(local => local.sip_gateway_sid === remote.sip_gateway_sid);
|
||||
if (!match.length) {
|
||||
await axios({
|
||||
method: 'delete',
|
||||
baseURL: process.env.REACT_APP_API_BASE_URL,
|
||||
url: `/SipGateways/${remote.sip_gateway_sid}`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${localStorage.getItem('token')}`,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (props.type === 'setup') {
|
||||
history.push('/setup-complete');
|
||||
} else {
|
||||
history.push('/internal/sip-trunks');
|
||||
const dispatchMessage = props.type === 'add'
|
||||
? 'SIP trunk created successfully'
|
||||
: 'SIP trunk updated successfully';
|
||||
dispatch({
|
||||
type: 'ADD',
|
||||
level: 'success',
|
||||
message: dispatchMessage
|
||||
});
|
||||
}
|
||||
|
||||
} catch(err) {
|
||||
if (err.response && err.response.status === 401) {
|
||||
localStorage.removeItem('token');
|
||||
sessionStorage.clear();
|
||||
history.push('/');
|
||||
dispatch({
|
||||
type: 'ADD',
|
||||
level: 'error',
|
||||
message: 'Your session has expired. Please log in and try again',
|
||||
});
|
||||
} else {
|
||||
setErrorMessage((err.response && err.response.data && err.response.data.msg) || 'Something went wrong, please try again');
|
||||
console.log(err.response || err);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
showLoader
|
||||
? <Loader height={props.type === 'setup' ? '424px' : '376px'}/>
|
||||
: <Form
|
||||
large
|
||||
onSubmit={handleSumit}
|
||||
>
|
||||
<Label htmlFor="name">Name</Label>
|
||||
<Input
|
||||
large={props.type === 'setup'}
|
||||
name="name"
|
||||
id="name"
|
||||
value={name}
|
||||
onChange={e => setName(e.target.value)}
|
||||
placeholder="SIP trunk provider name"
|
||||
invalid={nameInvalid}
|
||||
autoFocus
|
||||
ref={refName}
|
||||
/>
|
||||
<Label htmlFor="description">Description</Label>
|
||||
<Input
|
||||
large={props.type === 'setup'}
|
||||
name="description"
|
||||
id="description"
|
||||
value={description}
|
||||
onChange={e => setDescription(e.target.value)}
|
||||
placeholder="Optional"
|
||||
/>
|
||||
<hr style={{ margin: '0.5rem -2rem' }} />
|
||||
<div
|
||||
style={{ whiteSpace: 'nowrap' }}
|
||||
>SIP Gateways</div>
|
||||
{
|
||||
sipGateways.length
|
||||
? <div>{/* for CSS grid layout */}</div>
|
||||
: null
|
||||
}
|
||||
{sipGateways.map((g, i) => (
|
||||
<React.Fragment key={i}>
|
||||
<Label htmlFor={`sipGatewaysIp[${i}]`}>IP Address</Label>
|
||||
<InputGroup>
|
||||
<Input
|
||||
large={props.type === 'setup'}
|
||||
name={`sipGatewaysIp[${i}]`}
|
||||
id={`sipGatewaysIp[${i}]`}
|
||||
value={sipGateways[i].ip}
|
||||
onChange={e => updateSipGateways(e, i, 'ip')}
|
||||
placeholder={'1.2.3.4'}
|
||||
invalid={sipGateways[i].invalidIp}
|
||||
ref={ref => refIp.current[i] = ref}
|
||||
/>
|
||||
<Label
|
||||
middle
|
||||
htmlFor={`sipGatewaysPort[${i}]`}
|
||||
>
|
||||
Port
|
||||
</Label>
|
||||
<Input
|
||||
large={props.type === 'setup'}
|
||||
width="5rem"
|
||||
name={`sipGatewaysPort[${i}]`}
|
||||
id={`sipGatewaysPort[${i}]`}
|
||||
value={sipGateways[i].port}
|
||||
onChange={e => updateSipGateways(e, i, 'port')}
|
||||
placeholder="5060"
|
||||
invalid={sipGateways[i].invalidPort}
|
||||
ref={ref => refPort.current[i] = ref}
|
||||
/>
|
||||
<Checkbox
|
||||
large={props.type === 'setup'}
|
||||
id={`inbound[${i}]`}
|
||||
label="Inbound"
|
||||
tooltip="Sends us calls"
|
||||
checked={sipGateways[i].inbound}
|
||||
onChange={e => updateSipGateways(e, i, 'inbound')}
|
||||
invalid={sipGateways[i].invalidInbound}
|
||||
ref={ref => refInbound.current[i] = ref}
|
||||
/>
|
||||
<Checkbox
|
||||
large={props.type === 'setup'}
|
||||
id={`outbound[${i}]`}
|
||||
label="Outbound"
|
||||
tooltip="Accepts calls from us"
|
||||
checked={sipGateways[i].outbound}
|
||||
onChange={e => updateSipGateways(e, i, 'outbound')}
|
||||
invalid={sipGateways[i].invalidOutbound}
|
||||
ref={ref => refOutbound.current[i] = ref}
|
||||
/>
|
||||
<TrashButton
|
||||
onClick={() => removeSipGateway(i)}
|
||||
ref={ref => refTrash.current[i] = ref}
|
||||
/>
|
||||
</InputGroup>
|
||||
</React.Fragment>
|
||||
))}
|
||||
<Button
|
||||
square
|
||||
type="button"
|
||||
onClick={addSipGateway}
|
||||
ref={refAdd}
|
||||
>
|
||||
+
|
||||
</Button>
|
||||
{errorMessage && (
|
||||
<FormError grid message={errorMessage} />
|
||||
)}
|
||||
|
||||
<InputGroup flexEnd spaced>
|
||||
{props.type === 'edit' && (
|
||||
<Button
|
||||
grid
|
||||
gray
|
||||
type="button"
|
||||
onClick={() => {
|
||||
history.push('/internal/sip-trunks');
|
||||
dispatch({
|
||||
type: 'ADD',
|
||||
level: 'info',
|
||||
message: 'Changes canceled',
|
||||
});
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
large={props.type === 'setup'}
|
||||
grid
|
||||
fullWidth={props.type === 'setup' || props.type === 'add'}
|
||||
>
|
||||
{props.type === 'setup'
|
||||
? 'Save and Continue'
|
||||
: props.type === 'add'
|
||||
? 'Add SIP Trunk'
|
||||
: 'Save'
|
||||
}
|
||||
</Button>
|
||||
</InputGroup>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
export default SipTrunkForm;
|
||||
Reference in new issue
Block a user