From 03e52e3dc5d4e461bb1ce31a851ae9c5cee8b0ba Mon Sep 17 00:00:00 2001 From: Hoan Luu Huu <110280845+xquanluu@users.noreply.github.com> Date: Mon, 2 Jun 2025 18:14:01 +0700 Subject: [PATCH] fixed Cannot delete Carrier, show message that there is link to LCR (#533) * fixed Cannot delete Carrier, show message that there is link to LCR * wip --- .../internal/views/carriers/delete.tsx | 100 ++++++++++++++---- .../views/least-cost-routing/form.tsx | 29 +++-- 2 files changed, 93 insertions(+), 36 deletions(-) diff --git a/src/containers/internal/views/carriers/delete.tsx b/src/containers/internal/views/carriers/delete.tsx index 7189a89..4e04d46 100644 --- a/src/containers/internal/views/carriers/delete.tsx +++ b/src/containers/internal/views/carriers/delete.tsx @@ -2,11 +2,11 @@ import React, { useEffect, useState } from "react"; import { P } from "@jambonz/ui-kit"; import { Modal, ModalClose } from "src/components"; -import { getFetch } from "src/api"; +import { getFetch, getLcrRoutes, getLcrs } from "src/api"; import { API_PHONE_NUMBERS } from "src/api/constants"; import { formatPhoneNumber, hasLength } from "src/utils"; -import type { Carrier, PhoneNumber } from "src/api/types"; +import type { Carrier, Lcr, PhoneNumber } from "src/api/types"; type DeleteProps = { carrier: Carrier; @@ -20,28 +20,63 @@ export const DeleteCarrier = ({ handleSubmit, }: DeleteProps) => { const [phoneNumbers, setPhoneNumbers] = useState(); + const [lcrs, setLcrs] = useState(); useEffect(() => { let ignore = false; - getFetch(API_PHONE_NUMBERS).then(({ json }) => { + Promise.all([ + getFetch(API_PHONE_NUMBERS), + new Promise((resolve, reject) => { + getLcrs() + .then(({ json }) => { + Promise.all( + json.map((lcr: Lcr) => + getLcrRoutes(lcr.lcr_sid!) + .then(({ json }) => { + if ( + json.some((route) => + route.lcr_carrier_set_entries?.some( + (entry) => + entry.voip_carrier_sid === carrier.voip_carrier_sid, + ), + ) + ) { + return lcr; + } + }) + .catch((error) => reject(error)), + ), + ) + .then((lcrs) => { + resolve(lcrs as Lcr[]); + }) + .catch((error) => reject(error)); + }) + .catch((error) => reject(error)); + }), + ]).then(([numbers, fetchedLcrs]) => { if (!ignore) { setPhoneNumbers( - json.filter( + numbers.json.filter( (phone) => phone.voip_carrier_sid === carrier.voip_carrier_sid, ), ); + + setLcrs(fetchedLcrs); } }); return function cleanup() { ignore = true; }; - }, []); + }, [carrier.voip_carrier_sid]); + + const hasBlockingDependencies = hasLength(phoneNumbers) || hasLength(lcrs); return ( <> - {phoneNumbers && !hasLength(phoneNumbers) && ( + {phoneNumbers && lcrs && !hasBlockingDependencies && (

Are you sure you want to delete carrier{" "} @@ -49,24 +84,49 @@ export const DeleteCarrier = ({

)} - {hasLength(phoneNumbers) && ( + {hasBlockingDependencies && (

In order to delete the carrier it cannot be in use by any{" "} - Phone Numbers ({phoneNumbers.length}). + {hasLength(phoneNumbers) && ( + Phone Numbers ({phoneNumbers.length}) + )} + {hasLength(phoneNumbers) && hasLength(lcrs) && " or "} + {hasLength(lcrs) && ( + Outbound call Routings ({lcrs.length}) + )} + .

-
    -
  • - Phone Numbers: -
  • - {phoneNumbers.map((phone) => { - return ( -
  • - {formatPhoneNumber(phone.number)} -
  • - ); - })} -
+ + {hasLength(phoneNumbers) && ( +
    +
  • + Phone Numbers: +
  • + {phoneNumbers.map((phone) => { + return ( +
  • + {formatPhoneNumber(phone.number)} +
  • + ); + })} +
+ )} + + {hasLength(lcrs) && ( +
    +
  • + Outbound Call Routing: +
  • + {lcrs.map((lcr) => { + return ( +
  • + {lcr.name || "Default route"} +
  • + ); + })} +
+ )}
)} diff --git a/src/containers/internal/views/least-cost-routing/form.tsx b/src/containers/internal/views/least-cost-routing/form.tsx index 3a39bf1..5186db9 100644 --- a/src/containers/internal/views/least-cost-routing/form.tsx +++ b/src/containers/internal/views/least-cost-routing/form.tsx @@ -82,7 +82,7 @@ export const LcrForm = ({ lcrDataMap, lcrRouteDataMap }: LcrFormProps) => { setLocation(); if (currentServiceProvider) { setApiUrl( - `ServiceProviders/${currentServiceProvider.service_provider_sid}/VoipCarriers`, + `ServiceProviders/${currentServiceProvider.service_provider_sid}/VoipCarriers${accountSid ? `?account_sid=${accountSid}` : ""}`, ); } }, [user, currentServiceProvider, accountSid]); @@ -92,16 +92,8 @@ export const LcrForm = ({ lcrDataMap, lcrRouteDataMap }: LcrFormProps) => { setAccountSid(user?.account_sid); } - const carriersFiltered = carriers - ? carriers.filter((carrier) => - accountSid - ? carrier.account_sid === accountSid - : carrier.account_sid === null, - ) - : []; - - const ret = carriersFiltered - ? carriersFiltered.map((c: Carrier, i) => { + const ret = carriers + ? carriers.map((c: Carrier, i) => { if (i === 0) { setDefaultCarrier(c.voip_carrier_sid); } @@ -123,11 +115,16 @@ export const LcrForm = ({ lcrDataMap, lcrRouteDataMap }: LcrFormProps) => { return ret; }, [accountSid, carriers]); - if (lcrDataMap && lcrDataMap.data && lcrDataMap.data !== previouseLcr) { - setLcrName(lcrDataMap.data.name || ""); - setIsActive(lcrDataMap.data.is_active); - setPreviousLcr(lcrDataMap.data); - } + useEffect(() => { + if (lcrDataMap && lcrDataMap.data && lcrDataMap.data !== previouseLcr) { + setLcrName(lcrDataMap.data.name || ""); + setIsActive(lcrDataMap.data.is_active); + setPreviousLcr(lcrDataMap.data); + if (lcrDataMap.data.account_sid) { + setAccountSid(lcrDataMap.data.account_sid); + } + } + }, [lcrDataMap?.data, previouseLcr]); useMemo(() => { let default_lcr_route_sid = "";