mirror of
https://github.com/jambonz/jambonz-webapp.git
synced 2026-07-24 21:12:26 +00:00
discussed changes
This commit is contained in:
@@ -186,6 +186,9 @@ export const AccountForm = ({ apps, limits, account }: AccountFormProps) => {
|
||||
.then(() => {
|
||||
account.refetch();
|
||||
toastSuccess("Account updated successfully");
|
||||
if (user?.scope !== USER_ACCOUNT) {
|
||||
navigate(ROUTE_INTERNAL_ACCOUNTS);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
toastError(error.msg);
|
||||
|
||||
@@ -164,6 +164,7 @@ export const ApplicationForm = ({ application }: ApplicationFormProps) => {
|
||||
.then(() => {
|
||||
application.refetch();
|
||||
toastSuccess("Application updated successfully");
|
||||
navigate(`${ROUTE_INTERNAL_APPLICATIONS}`);
|
||||
})
|
||||
.catch((error) => {
|
||||
toastError(error.msg);
|
||||
|
||||
@@ -36,7 +36,6 @@ import {
|
||||
AccountSelect,
|
||||
ApplicationSelect,
|
||||
} from "src/components/forms";
|
||||
import { ScopedAccess } from "src/components/scoped-access";
|
||||
import { MSG_REQUIRED_FIELDS } from "src/constants";
|
||||
import { ROUTE_INTERNAL_CARRIERS } from "src/router/routes";
|
||||
import { toastError, toastSuccess, useSelectState } from "src/store";
|
||||
@@ -53,7 +52,6 @@ import type {
|
||||
Smpp,
|
||||
Application,
|
||||
} from "src/api/types";
|
||||
import { Scope } from "src/store/types";
|
||||
|
||||
type CarrierFormProps = {
|
||||
carrier?: UseApiDataMap<Carrier>;
|
||||
@@ -512,6 +510,7 @@ export const CarrierForm = ({
|
||||
|
||||
toastSuccess("Carrier updated successfully");
|
||||
carrier.refetch();
|
||||
navigate(ROUTE_INTERNAL_CARRIERS);
|
||||
})
|
||||
.catch((error) => {
|
||||
toastError(error.msg);
|
||||
@@ -748,122 +747,117 @@ export const CarrierForm = ({
|
||||
</>
|
||||
)}
|
||||
</fieldset>
|
||||
<ScopedAccess
|
||||
user={user}
|
||||
scope={accountSid ? Scope.account : Scope.service_provider}
|
||||
>
|
||||
<fieldset>
|
||||
<Checkzone
|
||||
hidden
|
||||
name="sip_credentials"
|
||||
label="Outbound Authentication"
|
||||
initialCheck={initialRegister}
|
||||
handleChecked={(e) => {
|
||||
if (!e.target.checked) {
|
||||
setSipUser("");
|
||||
setSipPass("");
|
||||
setSipRealm("");
|
||||
setSipRegister(false);
|
||||
setFromUser("");
|
||||
setFromDomain("");
|
||||
setRegPublicIpInContact(false);
|
||||
}
|
||||
<fieldset>
|
||||
<Checkzone
|
||||
hidden
|
||||
name="sip_credentials"
|
||||
label="Outbound Authentication"
|
||||
initialCheck={initialRegister}
|
||||
handleChecked={(e) => {
|
||||
if (!e.target.checked) {
|
||||
setSipUser("");
|
||||
setSipPass("");
|
||||
setSipRealm("");
|
||||
setSipRegister(false);
|
||||
setFromUser("");
|
||||
setFromDomain("");
|
||||
setRegPublicIpInContact(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<MS>
|
||||
Does your carrier require authentication on outbound calls?
|
||||
</MS>
|
||||
<label htmlFor="sip_username">
|
||||
Username {sipPass || sipRegister ? <span>*</span> : ""}
|
||||
</label>
|
||||
<input
|
||||
id="sip_username"
|
||||
name="sip_username"
|
||||
type="text"
|
||||
value={sipUser}
|
||||
placeholder="SIP username for authenticating outbound calls"
|
||||
required={sipRegister || sipPass.length > 0}
|
||||
onChange={(e) => {
|
||||
setSipUser(e.target.value);
|
||||
}}
|
||||
>
|
||||
<MS>
|
||||
Does your carrier require authentication on outbound calls?
|
||||
</MS>
|
||||
<label htmlFor="sip_username">
|
||||
Username {sipPass || sipRegister ? <span>*</span> : ""}
|
||||
</label>
|
||||
/>
|
||||
<label htmlFor="sip_password">
|
||||
Password
|
||||
{sipUser || sipRegister ? <span>*</span> : ""}
|
||||
</label>
|
||||
<Passwd
|
||||
id="sip_password"
|
||||
name="sip_password"
|
||||
value={sipPass}
|
||||
placeholder="SIP password for authenticating outbound calls"
|
||||
required={sipRegister || sipUser.length > 0}
|
||||
onChange={(e) => {
|
||||
setSipPass(e.target.value);
|
||||
}}
|
||||
/>
|
||||
<label htmlFor="sip_register" className="chk">
|
||||
<input
|
||||
id="sip_username"
|
||||
name="sip_username"
|
||||
type="text"
|
||||
value={sipUser}
|
||||
placeholder="SIP username for authenticating outbound calls"
|
||||
required={sipRegister || sipPass.length > 0}
|
||||
onChange={(e) => {
|
||||
setSipUser(e.target.value);
|
||||
}}
|
||||
id="sip_register"
|
||||
name="sip_register"
|
||||
type="checkbox"
|
||||
checked={sipRegister}
|
||||
onChange={(e) => setSipRegister(e.target.checked)}
|
||||
/>
|
||||
<label htmlFor="sip_password">
|
||||
Password
|
||||
{sipUser || sipRegister ? <span>*</span> : ""}
|
||||
</label>
|
||||
<Passwd
|
||||
id="sip_password"
|
||||
name="sip_password"
|
||||
value={sipPass}
|
||||
placeholder="SIP password for authenticating outbound calls"
|
||||
required={sipRegister || sipUser.length > 0}
|
||||
onChange={(e) => {
|
||||
setSipPass(e.target.value);
|
||||
}}
|
||||
/>
|
||||
<label htmlFor="sip_register" className="chk">
|
||||
<div>Require SIP Register</div>
|
||||
</label>
|
||||
{sipRegister && (
|
||||
<>
|
||||
<MS>
|
||||
Carrier requires SIP Register before sending outbound
|
||||
calls.
|
||||
</MS>
|
||||
<label htmlFor="sip_realm">
|
||||
SIP Realm{sipRegister ? <span>*</span> : ""}
|
||||
</label>
|
||||
<input
|
||||
id="sip_register"
|
||||
name="sip_register"
|
||||
type="checkbox"
|
||||
checked={sipRegister}
|
||||
onChange={(e) => setSipRegister(e.target.checked)}
|
||||
id="sip_realm"
|
||||
name="sip_realm"
|
||||
type="text"
|
||||
value={sipRealm}
|
||||
placeholder="SIP realm for registration"
|
||||
required={sipRegister}
|
||||
onChange={(e) => setSipRealm(e.target.value)}
|
||||
/>
|
||||
<div>Require SIP Register</div>
|
||||
</label>
|
||||
{sipRegister && (
|
||||
<>
|
||||
<MS>
|
||||
Carrier requires SIP Register before sending outbound
|
||||
calls.
|
||||
</MS>
|
||||
<label htmlFor="sip_realm">
|
||||
SIP Realm{sipRegister ? <span>*</span> : ""}
|
||||
</label>
|
||||
<label htmlFor="from_user">SIP From User</label>
|
||||
<input
|
||||
id="from_user"
|
||||
name="from_user"
|
||||
type="text"
|
||||
value={fromUser}
|
||||
placeholder="Optional: specify user part of SIP From header"
|
||||
onChange={(e) => setFromUser(e.target.value)}
|
||||
/>
|
||||
<label htmlFor="from_domain">SIP From Domain</label>
|
||||
<input
|
||||
id="from_domain"
|
||||
name="from_domain"
|
||||
type="text"
|
||||
value={fromDomain}
|
||||
placeholder="Optional: specify host part of SIP From header"
|
||||
onChange={(e) => setFromDomain(e.target.value)}
|
||||
/>
|
||||
<label htmlFor="reg_public_ip_in_contact" className="chk">
|
||||
<input
|
||||
id="sip_realm"
|
||||
name="sip_realm"
|
||||
type="text"
|
||||
value={sipRealm}
|
||||
placeholder="SIP realm for registration"
|
||||
required={sipRegister}
|
||||
onChange={(e) => setSipRealm(e.target.value)}
|
||||
id="reg_public_ip_in_contact"
|
||||
name="reg_public_ip_in_contact"
|
||||
type="checkbox"
|
||||
checked={regPublicIpInContact}
|
||||
onChange={(e) =>
|
||||
setRegPublicIpInContact(e.target.checked)
|
||||
}
|
||||
/>
|
||||
<label htmlFor="from_user">SIP From User</label>
|
||||
<input
|
||||
id="from_user"
|
||||
name="from_user"
|
||||
type="text"
|
||||
value={fromUser}
|
||||
placeholder="Optional: specify user part of SIP From header"
|
||||
onChange={(e) => setFromUser(e.target.value)}
|
||||
/>
|
||||
<label htmlFor="from_domain">SIP From Domain</label>
|
||||
<input
|
||||
id="from_domain"
|
||||
name="from_domain"
|
||||
type="text"
|
||||
value={fromDomain}
|
||||
placeholder="Optional: specify host part of SIP From header"
|
||||
onChange={(e) => setFromDomain(e.target.value)}
|
||||
/>
|
||||
<label htmlFor="reg_public_ip_in_contact" className="chk">
|
||||
<input
|
||||
id="reg_public_ip_in_contact"
|
||||
name="reg_public_ip_in_contact"
|
||||
type="checkbox"
|
||||
checked={regPublicIpInContact}
|
||||
onChange={(e) =>
|
||||
setRegPublicIpInContact(e.target.checked)
|
||||
}
|
||||
/>
|
||||
<div>Use Public IP in Contact</div>
|
||||
</label>
|
||||
</>
|
||||
)}
|
||||
</Checkzone>
|
||||
</fieldset>
|
||||
</ScopedAccess>
|
||||
<div>Use Public IP in Contact</div>
|
||||
</label>
|
||||
</>
|
||||
)}
|
||||
</Checkzone>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<Checkzone
|
||||
hidden
|
||||
@@ -1028,61 +1022,50 @@ export const CarrierForm = ({
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<ScopedAccess
|
||||
user={user}
|
||||
scope={
|
||||
accountSid ? Scope.account : Scope.service_provider
|
||||
}
|
||||
|
||||
<button
|
||||
className="btnty"
|
||||
title="Delete SIP Gateway"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setSipMessage("");
|
||||
|
||||
if (sipGateways.length === 1) {
|
||||
setSipMessage(
|
||||
"You must provide at least one SIP Gateway."
|
||||
);
|
||||
} else {
|
||||
handleSipGatewayDelete(
|
||||
sipGateways.find((g2, i2) => i2 === i)
|
||||
);
|
||||
|
||||
setSipGateways(
|
||||
sipGateways.filter((g2, i2) => i2 !== i)
|
||||
);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<button
|
||||
className="btnty"
|
||||
title="Delete SIP Gateway"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setSipMessage("");
|
||||
|
||||
if (sipGateways.length === 1) {
|
||||
setSipMessage(
|
||||
"You must provide at least one SIP Gateway."
|
||||
);
|
||||
} else {
|
||||
handleSipGatewayDelete(
|
||||
sipGateways.find((g2, i2) => i2 === i)
|
||||
);
|
||||
|
||||
setSipGateways(
|
||||
sipGateways.filter((g2, i2) => i2 !== i)
|
||||
);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Icon>
|
||||
<Icons.Trash2 />
|
||||
</Icon>
|
||||
</button>
|
||||
</ScopedAccess>
|
||||
<Icon>
|
||||
<Icons.Trash2 />
|
||||
</Icon>
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
<ScopedAccess
|
||||
user={user}
|
||||
scope={accountSid ? Scope.account : Scope.service_provider}
|
||||
>
|
||||
<ButtonGroup left>
|
||||
<button
|
||||
className="btnty"
|
||||
type="button"
|
||||
title="Add SIP Gateway"
|
||||
onClick={() => {
|
||||
setSipMessage("");
|
||||
addSipGateway();
|
||||
}}
|
||||
>
|
||||
<Icon subStyle="teal">
|
||||
<Icons.Plus />
|
||||
</Icon>
|
||||
</button>
|
||||
</ButtonGroup>
|
||||
</ScopedAccess>
|
||||
<ButtonGroup left>
|
||||
<button
|
||||
className="btnty"
|
||||
type="button"
|
||||
title="Add SIP Gateway"
|
||||
onClick={() => {
|
||||
setSipMessage("");
|
||||
addSipGateway();
|
||||
}}
|
||||
>
|
||||
<Icon subStyle="teal">
|
||||
<Icons.Plus />
|
||||
</Icon>
|
||||
</button>
|
||||
</ButtonGroup>
|
||||
</fieldset>
|
||||
</Tab>
|
||||
<Tab id="smpp" label="SMS">
|
||||
@@ -1104,32 +1087,27 @@ export const CarrierForm = ({
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<label htmlFor="outbound_smpp">Outbound SMPP</label>
|
||||
<ScopedAccess
|
||||
user={user}
|
||||
scope={accountSid ? Scope.account : Scope.service_provider}
|
||||
>
|
||||
<label htmlFor="outbound_id">System ID</label>
|
||||
<input
|
||||
id="outbound_id"
|
||||
name="outbound_id"
|
||||
type="text"
|
||||
value={smppSystemId}
|
||||
placeholder="SMPP system ID to authenticate with"
|
||||
onChange={(e) => {
|
||||
setSmppSystemId(e.target.value);
|
||||
}}
|
||||
/>
|
||||
<label htmlFor="outbound_pass">Password</label>
|
||||
<Passwd
|
||||
id="outbound_pass"
|
||||
name="outbound_pass"
|
||||
value={smppPass}
|
||||
placeholder="SMPP password to authenticate with"
|
||||
onChange={(e) => {
|
||||
setSmppPass(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</ScopedAccess>
|
||||
<label htmlFor="outbound_id">System ID</label>
|
||||
<input
|
||||
id="outbound_id"
|
||||
name="outbound_id"
|
||||
type="text"
|
||||
value={smppSystemId}
|
||||
placeholder="SMPP system ID to authenticate with"
|
||||
onChange={(e) => {
|
||||
setSmppSystemId(e.target.value);
|
||||
}}
|
||||
/>
|
||||
<label htmlFor="outbound_pass">Password</label>
|
||||
<Passwd
|
||||
id="outbound_pass"
|
||||
name="outbound_pass"
|
||||
value={smppPass}
|
||||
placeholder="SMPP password to authenticate with"
|
||||
onChange={(e) => {
|
||||
setSmppPass(e.target.value);
|
||||
}}
|
||||
/>
|
||||
<label htmlFor="outbound_smpp">
|
||||
Carrier SMPP Gateways
|
||||
<span>{smppSystemId || smppPass ? "*" : ""}</span>
|
||||
@@ -1203,103 +1181,86 @@ export const CarrierForm = ({
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<ScopedAccess
|
||||
user={user}
|
||||
scope={
|
||||
accountSid ? Scope.account : Scope.service_provider
|
||||
}
|
||||
<button
|
||||
title="Delete Outbound SMPP Gateway"
|
||||
type="button"
|
||||
className="btnty"
|
||||
onClick={() => {
|
||||
setSmppOutboundMessage("");
|
||||
|
||||
if (
|
||||
hasLength(smpps) &&
|
||||
smppGateways.filter((g) => g.outbound).length <=
|
||||
1 &&
|
||||
(smppSystemId || smppPass)
|
||||
) {
|
||||
setSmppOutboundMessage(
|
||||
"You must provide at least one Outbound Gateway."
|
||||
);
|
||||
} else {
|
||||
handleSmppGatewayDelete(
|
||||
smppGateways.find((g2, i2) => i2 === i)
|
||||
);
|
||||
|
||||
setSmppGateways(
|
||||
smppGateways.filter((g2, i2) => i2 !== i)
|
||||
);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<button
|
||||
title="Delete Outbound SMPP Gateway"
|
||||
type="button"
|
||||
className="btnty"
|
||||
onClick={() => {
|
||||
setSmppOutboundMessage("");
|
||||
|
||||
if (
|
||||
hasLength(smpps) &&
|
||||
smppGateways.filter((g) => g.outbound).length <=
|
||||
1 &&
|
||||
(smppSystemId || smppPass)
|
||||
) {
|
||||
setSmppOutboundMessage(
|
||||
"You must provide at least one Outbound Gateway."
|
||||
);
|
||||
} else {
|
||||
handleSmppGatewayDelete(
|
||||
smppGateways.find((g2, i2) => i2 === i)
|
||||
);
|
||||
|
||||
setSmppGateways(
|
||||
smppGateways.filter((g2, i2) => i2 !== i)
|
||||
);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Icon>
|
||||
<Icons.Trash2 />
|
||||
</Icon>
|
||||
</button>
|
||||
</ScopedAccess>
|
||||
<Icon>
|
||||
<Icons.Trash2 />
|
||||
</Icon>
|
||||
</button>
|
||||
</div>
|
||||
) : null;
|
||||
})}
|
||||
<ScopedAccess
|
||||
user={user}
|
||||
scope={accountSid ? Scope.account : Scope.service_provider}
|
||||
>
|
||||
<ButtonGroup left>
|
||||
<button
|
||||
className="btnty"
|
||||
type="button"
|
||||
onClick={() => addSmppGateway({ inbound: 0, outbound: 1 })}
|
||||
title="Add Outbound SMPP Gateway"
|
||||
>
|
||||
<Icon subStyle="teal">
|
||||
<Icons.Plus />
|
||||
</Icon>
|
||||
</button>
|
||||
</ButtonGroup>
|
||||
</ScopedAccess>
|
||||
<ButtonGroup left>
|
||||
<button
|
||||
className="btnty"
|
||||
type="button"
|
||||
onClick={() => addSmppGateway({ inbound: 0, outbound: 1 })}
|
||||
title="Add Outbound SMPP Gateway"
|
||||
>
|
||||
<Icon subStyle="teal">
|
||||
<Icons.Plus />
|
||||
</Icon>
|
||||
</button>
|
||||
</ButtonGroup>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<label htmlFor="inbound_smpp">Inbound SMPP</label>
|
||||
<ScopedAccess
|
||||
user={user}
|
||||
scope={accountSid ? Scope.account : Scope.service_provider}
|
||||
>
|
||||
<label htmlFor="inbound_id">System ID</label>
|
||||
<input
|
||||
id="inbound_id"
|
||||
name="inbound_id"
|
||||
type="text"
|
||||
value={smppInboundSystemId}
|
||||
placeholder="SMPP system ID to authenticate with"
|
||||
onChange={(e) => {
|
||||
setSmppInboundSystemId(e.target.value);
|
||||
}}
|
||||
/>
|
||||
<label htmlFor="inbound_pass">
|
||||
Password
|
||||
<span>{!hasEmptySmppGateways("inbound") ? "*" : ""}</span>
|
||||
</label>
|
||||
<MXS>
|
||||
<em>
|
||||
Password is required if whitelisting carrier IP address(es)
|
||||
below.
|
||||
</em>
|
||||
</MXS>
|
||||
<Passwd
|
||||
id="inbound_pass"
|
||||
name="inbound_pass"
|
||||
value={smppInboundPass}
|
||||
placeholder="SMPP password for authenticating inbound messages"
|
||||
required={!hasEmptySmppGateways("inbound")}
|
||||
onChange={(e) => {
|
||||
setSmppInboundPass(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</ScopedAccess>
|
||||
<label htmlFor="inbound_id">System ID</label>
|
||||
<input
|
||||
id="inbound_id"
|
||||
name="inbound_id"
|
||||
type="text"
|
||||
value={smppInboundSystemId}
|
||||
placeholder="SMPP system ID to authenticate with"
|
||||
onChange={(e) => {
|
||||
setSmppInboundSystemId(e.target.value);
|
||||
}}
|
||||
/>
|
||||
<label htmlFor="inbound_pass">
|
||||
Password
|
||||
<span>{!hasEmptySmppGateways("inbound") ? "*" : ""}</span>
|
||||
</label>
|
||||
<MXS>
|
||||
<em>
|
||||
Password is required if whitelisting carrier IP address(es)
|
||||
below.
|
||||
</em>
|
||||
</MXS>
|
||||
<Passwd
|
||||
id="inbound_pass"
|
||||
name="inbound_pass"
|
||||
value={smppInboundPass}
|
||||
placeholder="SMPP password for authenticating inbound messages"
|
||||
required={!hasEmptySmppGateways("inbound")}
|
||||
onChange={(e) => {
|
||||
setSmppInboundPass(e.target.value);
|
||||
}}
|
||||
/>
|
||||
<label htmlFor="inbound_smpp">
|
||||
Carrier IP Address(es) to whitelist
|
||||
</label>
|
||||
@@ -1345,51 +1306,39 @@ export const CarrierForm = ({
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<ScopedAccess
|
||||
user={user}
|
||||
scope={
|
||||
accountSid ? Scope.account : Scope.service_provider
|
||||
}
|
||||
>
|
||||
<button
|
||||
className="btnty"
|
||||
title="Delete Inbound SMPP Gateway"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
handleSmppGatewayDelete(
|
||||
smppGateways.find((g2, i2) => i2 === i)
|
||||
);
|
||||
<button
|
||||
className="btnty"
|
||||
title="Delete Inbound SMPP Gateway"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
handleSmppGatewayDelete(
|
||||
smppGateways.find((g2, i2) => i2 === i)
|
||||
);
|
||||
|
||||
setSmppGateways(
|
||||
smppGateways.filter((g2, i2) => i2 !== i)
|
||||
);
|
||||
}}
|
||||
>
|
||||
<Icon>
|
||||
<Icons.Trash2 />
|
||||
</Icon>
|
||||
</button>
|
||||
</ScopedAccess>
|
||||
setSmppGateways(
|
||||
smppGateways.filter((g2, i2) => i2 !== i)
|
||||
);
|
||||
}}
|
||||
>
|
||||
<Icon>
|
||||
<Icons.Trash2 />
|
||||
</Icon>
|
||||
</button>
|
||||
</div>
|
||||
) : null;
|
||||
})}
|
||||
<ScopedAccess
|
||||
user={user}
|
||||
scope={accountSid ? Scope.account : Scope.service_provider}
|
||||
>
|
||||
<ButtonGroup left>
|
||||
<button
|
||||
className="btnty"
|
||||
type="button"
|
||||
onClick={() => addSmppGateway({ outbound: 0, inbound: 1 })}
|
||||
title="Add Inbound SMPP Gateway"
|
||||
>
|
||||
<Icon subStyle="teal">
|
||||
<Icons.Plus />
|
||||
</Icon>
|
||||
</button>
|
||||
</ButtonGroup>
|
||||
</ScopedAccess>
|
||||
<ButtonGroup left>
|
||||
<button
|
||||
className="btnty"
|
||||
type="button"
|
||||
onClick={() => addSmppGateway({ outbound: 0, inbound: 1 })}
|
||||
title="Add Inbound SMPP Gateway"
|
||||
>
|
||||
<Icon subStyle="teal">
|
||||
<Icons.Plus />
|
||||
</Icon>
|
||||
</button>
|
||||
</ButtonGroup>
|
||||
</fieldset>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
@@ -17,6 +17,8 @@ import {
|
||||
Spinner,
|
||||
SearchFilter,
|
||||
} from "src/components";
|
||||
import { ScopedAccess } from "src/components/scoped-access";
|
||||
import { Gateways } from "./gateways";
|
||||
import { hasLength, hasValue, useFilteredResults } from "src/utils";
|
||||
import {
|
||||
API_ACCOUNTS,
|
||||
@@ -28,7 +30,7 @@ import {
|
||||
import { DeleteCarrier } from "./delete";
|
||||
|
||||
import type { Account, Carrier, SipGateway, SmppGateway } from "src/api/types";
|
||||
import { Gateways } from "./gateways";
|
||||
import { Scope } from "src/store/types";
|
||||
|
||||
export const Carriers = () => {
|
||||
const user = useSelectState("user");
|
||||
@@ -174,14 +176,19 @@ export const Carriers = () => {
|
||||
<div className="item" key={carrier.voip_carrier_sid}>
|
||||
<div className="item__info">
|
||||
<div className="item__title">
|
||||
<Link
|
||||
to={`${ROUTE_INTERNAL_CARRIERS}/${carrier.voip_carrier_sid}/edit`}
|
||||
title="Edit Carrier"
|
||||
className="i"
|
||||
>
|
||||
<ScopedAccess user={user} scope={Scope.service_provider}>
|
||||
<Link
|
||||
to={`${ROUTE_INTERNAL_CARRIERS}/${carrier.voip_carrier_sid}/edit`}
|
||||
title="Edit Carrier"
|
||||
className="i"
|
||||
>
|
||||
<strong>{carrier.name}</strong>
|
||||
<Icons.ArrowRight />
|
||||
</Link>
|
||||
</ScopedAccess>
|
||||
{user?.scope === USER_ACCOUNT && (
|
||||
<strong>{carrier.name}</strong>
|
||||
<Icons.ArrowRight />
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
<div className="item__meta">
|
||||
<div>
|
||||
@@ -201,22 +208,27 @@ export const Carriers = () => {
|
||||
<Gateways carrier={carrier} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="item__actions">
|
||||
<Link
|
||||
to={`${ROUTE_INTERNAL_CARRIERS}/${carrier.voip_carrier_sid}/edit`}
|
||||
title="Edit Carrier"
|
||||
>
|
||||
<Icons.Edit3 />
|
||||
</Link>
|
||||
<button
|
||||
type="button"
|
||||
title="Delete Carrier"
|
||||
onClick={() => setCarrier(carrier)}
|
||||
className="btnty"
|
||||
>
|
||||
<Icons.Trash />
|
||||
</button>
|
||||
</div>
|
||||
<ScopedAccess
|
||||
user={user}
|
||||
scope={!accountSid ? Scope.service_provider : Scope.account}
|
||||
>
|
||||
<div className="item__actions">
|
||||
<Link
|
||||
to={`${ROUTE_INTERNAL_CARRIERS}/${carrier.voip_carrier_sid}/edit`}
|
||||
title="Edit Carrier"
|
||||
>
|
||||
<Icons.Edit3 />
|
||||
</Link>
|
||||
<button
|
||||
type="button"
|
||||
title="Delete Carrier"
|
||||
onClick={() => setCarrier(carrier)}
|
||||
className="btnty"
|
||||
>
|
||||
<Icons.Trash />
|
||||
</button>
|
||||
</div>
|
||||
</ScopedAccess>
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
|
||||
@@ -88,6 +88,7 @@ export const PhoneNumberForm = ({ phoneNumber }: PhoneNumberFormProps) => {
|
||||
.then(() => {
|
||||
phoneNumber.refetch();
|
||||
toastSuccess("Phone number updated successfully");
|
||||
navigate(ROUTE_INTERNAL_PHONE_NUMBERS);
|
||||
})
|
||||
.catch((error) => {
|
||||
toastError(error.msg);
|
||||
|
||||
@@ -132,7 +132,7 @@ export const PhoneNumbers = () => {
|
||||
)
|
||||
: accounts
|
||||
}
|
||||
defaultOption
|
||||
defaultOption={user?.scope !== USER_ACCOUNT}
|
||||
/>
|
||||
</section>
|
||||
<Section {...(hasLength(filteredPhoneNumbers) && { slim: true })}>
|
||||
|
||||
@@ -146,6 +146,7 @@ export const SpeechServiceForm = ({ credential }: SpeechServiceFormProps) => {
|
||||
if (credential && credential.data) {
|
||||
toastSuccess("Speech credential updated successfully");
|
||||
credential.refetch();
|
||||
navigate(ROUTE_INTERNAL_SPEECH);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
|
||||
@@ -22,6 +22,8 @@ import { getUsage } from "./utils";
|
||||
import { CredentialStatus } from "./status";
|
||||
|
||||
import type { SpeechCredential, Account } from "src/api/types";
|
||||
import { ScopedAccess } from "src/components/scoped-access";
|
||||
import { Scope } from "src/store/types";
|
||||
|
||||
export const SpeechServices = () => {
|
||||
const user = useSelectState("user");
|
||||
@@ -142,14 +144,24 @@ export const SpeechServices = () => {
|
||||
<div className="item" key={credential.speech_credential_sid}>
|
||||
<div className="item__info">
|
||||
<div className="item__title">
|
||||
<Link
|
||||
to={`${ROUTE_INTERNAL_SPEECH}/${credential.speech_credential_sid}/edit`}
|
||||
title="Edit application"
|
||||
className="i"
|
||||
<ScopedAccess
|
||||
user={user}
|
||||
scope={
|
||||
!accountSid ? Scope.service_provider : Scope.account
|
||||
}
|
||||
>
|
||||
<Link
|
||||
to={`${ROUTE_INTERNAL_SPEECH}/${credential.speech_credential_sid}/edit`}
|
||||
title="Edit application"
|
||||
className="i"
|
||||
>
|
||||
<strong>Vendor: {credential.vendor}</strong>
|
||||
<Icons.ArrowRight />
|
||||
</Link>
|
||||
</ScopedAccess>
|
||||
{user?.scope === USER_ACCOUNT && (
|
||||
<strong>Vendor: {credential.vendor}</strong>
|
||||
<Icons.ArrowRight />
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
<div className="item__meta">
|
||||
<div>
|
||||
@@ -191,22 +203,27 @@ export const SpeechServices = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="item__actions">
|
||||
<Link
|
||||
to={`${ROUTE_INTERNAL_SPEECH}/${credential.speech_credential_sid}/edit`}
|
||||
title="Edit speech service"
|
||||
>
|
||||
<Icons.Edit3 />
|
||||
</Link>
|
||||
<button
|
||||
type="button"
|
||||
title="Delete speech service"
|
||||
onClick={() => setCredential(credential)}
|
||||
className="btnty"
|
||||
>
|
||||
<Icons.Trash />
|
||||
</button>
|
||||
</div>
|
||||
<ScopedAccess
|
||||
user={user}
|
||||
scope={!accountSid ? Scope.service_provider : Scope.account}
|
||||
>
|
||||
<div className="item__actions">
|
||||
<Link
|
||||
to={`${ROUTE_INTERNAL_SPEECH}/${credential.speech_credential_sid}/edit`}
|
||||
title="Edit speech service"
|
||||
>
|
||||
<Icons.Edit3 />
|
||||
</Link>
|
||||
<button
|
||||
type="button"
|
||||
title="Delete speech service"
|
||||
onClick={() => setCredential(credential)}
|
||||
className="btnty"
|
||||
>
|
||||
<Icons.Trash />
|
||||
</button>
|
||||
</div>
|
||||
</ScopedAccess>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
|
||||
@@ -170,6 +170,7 @@ export const UserForm = ({ user }: UserFormProps) => {
|
||||
setIsActive(!!user.data.is_active);
|
||||
setEmail(user.data.email);
|
||||
setScope(getUserScope(user.data));
|
||||
user.data.account_sid ? setAccountSid(user.data.account_sid) : false;
|
||||
}
|
||||
}, [user]);
|
||||
|
||||
|
||||
@@ -110,17 +110,15 @@ export const Users = () => {
|
||||
)
|
||||
: accounts
|
||||
}
|
||||
defaultOption
|
||||
defaultOption={user?.scope !== USER_ACCOUNT}
|
||||
/>
|
||||
</section>
|
||||
|
||||
<Section slim>
|
||||
<div className="grid grid--col5">
|
||||
<div className="grid grid--col3--users">
|
||||
<div className="grid__row grid__th">
|
||||
<div>User Name</div>
|
||||
<div>Email</div>
|
||||
<div>Scope</div>
|
||||
<div>Access</div>
|
||||
<div>Managed resource</div>
|
||||
<div> </div>
|
||||
</div>
|
||||
{!hasValue(users) ? (
|
||||
@@ -129,13 +127,20 @@ export const Users = () => {
|
||||
filteredUsers.map((user) => {
|
||||
return (
|
||||
<div className="grid__row" key={user.user_sid}>
|
||||
<div>{user.name}</div>
|
||||
<div>{user.email}</div>
|
||||
<div>{user.scope}</div>
|
||||
<div>
|
||||
<Link
|
||||
to={`${ROUTE_INTERNAL_USERS}/${user.user_sid}/edit`}
|
||||
title="Edit user"
|
||||
>
|
||||
<div>{user.name}</div>
|
||||
</Link>
|
||||
</div>
|
||||
<div>
|
||||
{user.scope === USER_ADMIN
|
||||
? null
|
||||
: user.account_name || user.service_provider_name}
|
||||
? "All"
|
||||
: user.account_name
|
||||
? `Account: ${user.account_name}`
|
||||
: `Service Provider: ${user.service_provider_name}`}
|
||||
</div>
|
||||
<div className="item__actions">
|
||||
<Link
|
||||
|
||||
@@ -99,9 +99,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
&--col5 {
|
||||
&--col3--users {
|
||||
.grid__row {
|
||||
grid-template-columns: [col] 30% [col] 20% [col] 20% [col] 28% [col] 2%;
|
||||
grid-template-columns: [col] 40% [col] 58% [col] 2%;
|
||||
grid-template-rows: [row] auto [row] auto [row] [row] auto;
|
||||
display: grid;
|
||||
justify-content: space-between;
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
grid-gap: ui-vars.$px02;
|
||||
color: ui-vars.$jambonz;
|
||||
|
||||
+ .item__meta {
|
||||
@include mixins.small() {
|
||||
|
||||
Reference in New Issue
Block a user