From 543be6dede00e0174383adfa0eba328862af94ff Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Wed, 5 Feb 2025 10:45:41 +0100 Subject: [PATCH] chore(1-3342): extract into hook, use new endpoint if flag on (#9218) Updates the existing BillingDetails pages (pro and payg) to use the new traffic search endpoint (and calculations) if the flag to do so is on. Otherwise, it falls back to using the existing method. I've extracted the overage calculation into a separate shared hook. --- .../BillingPlan/BillingDetailsPAYG.tsx | 31 +------- .../BillingPlan/BillingDetailsPro.tsx | 32 +------- .../BillingPlan/useOverageCost.ts | 76 +++++++++++++++++++ .../NetworkTrafficUsage.tsx | 4 +- .../useInstanceTrafficMetrics.ts | 2 +- 5 files changed, 83 insertions(+), 62 deletions(-) create mode 100644 frontend/src/component/admin/billing/BillingDashboard/BillingPlan/useOverageCost.ts diff --git a/frontend/src/component/admin/billing/BillingDashboard/BillingPlan/BillingDetailsPAYG.tsx b/frontend/src/component/admin/billing/BillingDashboard/BillingPlan/BillingDetailsPAYG.tsx index 54afb5024d..69c854ffb2 100644 --- a/frontend/src/component/admin/billing/BillingDashboard/BillingPlan/BillingDetailsPAYG.tsx +++ b/frontend/src/component/admin/billing/BillingDashboard/BillingPlan/BillingDetailsPAYG.tsx @@ -11,11 +11,8 @@ import { BILLING_PAYG_USER_PRICE, BILLING_TRAFFIC_BUNDLE_PRICE, } from './BillingPlan'; -import { useTrafficDataEstimation } from 'hooks/useTrafficData'; -import { useInstanceTrafficMetrics } from 'hooks/api/getters/useInstanceTrafficMetrics/useInstanceTrafficMetrics'; -import { useMemo } from 'react'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; -import { calculateOverageCost } from 'utils/traffic-calculations'; +import { useOverageCost } from './useOverageCost'; const StyledInfoLabel = styled(Typography)(({ theme }) => ({ fontSize: theme.fontSizes.smallBody, @@ -34,13 +31,6 @@ export const BillingDetailsPAYG = ({ instanceStatus, }: IBillingDetailsPAYGProps) => { const { users, loading } = useUsers(); - const { - currentPeriod, - toChartData, - toTrafficUsageSum, - endpointsInfo, - getDayLabels, - } = useTrafficDataEstimation(); const eligibleUsers = users.filter((user) => user.email); @@ -51,24 +41,7 @@ export const BillingDetailsPAYG = ({ const usersCost = BILLING_PAYG_USER_PRICE * billableUsers; const includedTraffic = BILLING_INCLUDED_REQUESTS; - const traffic = useInstanceTrafficMetrics(currentPeriod.key); - - const overageCost = useMemo(() => { - if (!includedTraffic) { - return 0; - } - const trafficData = toChartData( - getDayLabels(currentPeriod.dayCount), - traffic, - endpointsInfo, - ); - const totalTraffic = toTrafficUsageSum(trafficData); - return calculateOverageCost( - totalTraffic, - includedTraffic, - BILLING_TRAFFIC_BUNDLE_PRICE, - ); - }, [includedTraffic, traffic, currentPeriod, endpointsInfo]); + const overageCost = useOverageCost(includedTraffic); const totalCost = usersCost + overageCost; diff --git a/frontend/src/component/admin/billing/BillingDashboard/BillingPlan/BillingDetailsPro.tsx b/frontend/src/component/admin/billing/BillingDashboard/BillingPlan/BillingDetailsPro.tsx index d4eb3b5e67..84ac700dcd 100644 --- a/frontend/src/component/admin/billing/BillingDashboard/BillingPlan/BillingDetailsPro.tsx +++ b/frontend/src/component/admin/billing/BillingDashboard/BillingPlan/BillingDetailsPro.tsx @@ -6,9 +6,7 @@ import { GridCol } from 'component/common/GridCol/GridCol'; import { GridColLink } from './GridColLink/GridColLink'; import type { IInstanceStatus } from 'interfaces/instance'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; -import { useMemo } from 'react'; import { useUsers } from 'hooks/api/getters/useUsers/useUsers'; -import { useTrafficDataEstimation } from 'hooks/useTrafficData'; import { BILLING_INCLUDED_REQUESTS, BILLING_PLAN_PRICES, @@ -16,8 +14,7 @@ import { BILLING_PRO_USER_PRICE, BILLING_TRAFFIC_BUNDLE_PRICE, } from './BillingPlan'; -import { useInstanceTrafficMetrics } from 'hooks/api/getters/useInstanceTrafficMetrics/useInstanceTrafficMetrics'; -import { calculateOverageCost } from 'utils/traffic-calculations'; +import { useOverageCost } from './useOverageCost'; const StyledInfoLabel = styled(Typography)(({ theme }) => ({ fontSize: theme.fontSizes.smallBody, @@ -42,14 +39,6 @@ export const BillingDetailsPro = ({ }: IBillingDetailsProProps) => { const { users, loading } = useUsers(); - const { - currentPeriod, - toChartData, - toTrafficUsageSum, - endpointsInfo, - getDayLabels, - } = useTrafficDataEstimation(); - const eligibleUsers = users.filter((user) => user.email); const planPrice = BILLING_PLAN_PRICES[instanceStatus.plan]; @@ -59,24 +48,7 @@ export const BillingDetailsPro = ({ const paidAssigned = eligibleUsers.length - freeAssigned; const paidAssignedPrice = BILLING_PRO_USER_PRICE * paidAssigned; const includedTraffic = BILLING_INCLUDED_REQUESTS; - const traffic = useInstanceTrafficMetrics(currentPeriod.key); - - const overageCost = useMemo(() => { - if (!includedTraffic) { - return 0; - } - const trafficData = toChartData( - getDayLabels(currentPeriod.dayCount), - traffic, - endpointsInfo, - ); - const totalTraffic = toTrafficUsageSum(trafficData); - return calculateOverageCost( - totalTraffic, - includedTraffic, - BILLING_TRAFFIC_BUNDLE_PRICE, - ); - }, [includedTraffic, traffic, currentPeriod, endpointsInfo]); + const overageCost = useOverageCost(includedTraffic); const totalCost = planPrice + paidAssignedPrice + overageCost; diff --git a/frontend/src/component/admin/billing/BillingDashboard/BillingPlan/useOverageCost.ts b/frontend/src/component/admin/billing/BillingDashboard/BillingPlan/useOverageCost.ts new file mode 100644 index 0000000000..89a0bae91b --- /dev/null +++ b/frontend/src/component/admin/billing/BillingDashboard/BillingPlan/useOverageCost.ts @@ -0,0 +1,76 @@ +import { endOfMonth, format, startOfMonth } from 'date-fns'; +import { + useInstanceTrafficMetrics, + useTrafficSearch, +} from 'hooks/api/getters/useInstanceTrafficMetrics/useInstanceTrafficMetrics'; +import { useMemo } from 'react'; +import { + calculateOverageCost, + calculateTotalUsage, +} from 'utils/traffic-calculations'; +import { BILLING_TRAFFIC_BUNDLE_PRICE } from './BillingPlan'; +import { useUiFlag } from 'hooks/useUiFlag'; +import { useTrafficDataEstimation } from 'hooks/useTrafficData'; + +export const useOverageCost = (includedTraffic: number) => { + if (useUiFlag('dataUsageMultiMonthView')) { + return useNewOverageCostCalculation(includedTraffic); + } else { + return useOldOverageCostCalculation(includedTraffic); + } +}; + +const useNewOverageCostCalculation = (includedTraffic: number) => { + if (!includedTraffic) { + return 0; + } + + const now = new Date(); + const formatDate = (date: Date) => format(date, 'yyyy-MM-dd'); + const from = formatDate(startOfMonth(now)); + const to = formatDate(endOfMonth(now)); + + const { usage } = useTrafficSearch('daily', { from, to }); + + const overageCost = useMemo(() => { + const totalUsage = calculateTotalUsage(usage); + return calculateOverageCost( + totalUsage, + includedTraffic, + BILLING_TRAFFIC_BUNDLE_PRICE, + ); + }, [includedTraffic, usage]); + + return overageCost; +}; + +const useOldOverageCostCalculation = (includedTraffic: number) => { + const { + currentPeriod, + toChartData, + toTrafficUsageSum, + endpointsInfo, + getDayLabels, + } = useTrafficDataEstimation(); + + const traffic = useInstanceTrafficMetrics(currentPeriod.key); + + const overageCost = useMemo(() => { + if (!includedTraffic) { + return 0; + } + const trafficData = toChartData( + getDayLabels(currentPeriod.dayCount), + traffic, + endpointsInfo, + ); + const totalTraffic = toTrafficUsageSum(trafficData); + return calculateOverageCost( + totalTraffic, + includedTraffic, + BILLING_TRAFFIC_BUNDLE_PRICE, + ); + }, [includedTraffic, traffic, currentPeriod, endpointsInfo]); + + return overageCost; +}; diff --git a/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx b/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx index 2264b5e1f5..0e6b4afcd7 100644 --- a/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx +++ b/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx @@ -22,7 +22,7 @@ import { import { Bar } from 'react-chartjs-2'; import { useInstanceTrafficMetrics, - useInstanceTrafficMetrics2, + useTrafficSearch, } from 'hooks/api/getters/useInstanceTrafficMetrics/useInstanceTrafficMetrics'; import type { Theme } from '@mui/material/styles/createTheme'; import Grid from '@mui/material/Grid'; @@ -231,7 +231,7 @@ const NewNetworkTrafficUsage: FC = () => { ); }, [theme, chartDataSelection]); - const traffic = useInstanceTrafficMetrics2( + const traffic = useTrafficSearch( chartDataSelection.grouping, toDateRange(chartDataSelection, currentDate), ); diff --git a/frontend/src/hooks/api/getters/useInstanceTrafficMetrics/useInstanceTrafficMetrics.ts b/frontend/src/hooks/api/getters/useInstanceTrafficMetrics/useInstanceTrafficMetrics.ts index b5d607fceb..f2e322e427 100644 --- a/frontend/src/hooks/api/getters/useInstanceTrafficMetrics/useInstanceTrafficMetrics.ts +++ b/frontend/src/hooks/api/getters/useInstanceTrafficMetrics/useInstanceTrafficMetrics.ts @@ -47,7 +47,7 @@ export type InstanceTrafficMetricsResponse2 = { error?: Error; }; -export const useInstanceTrafficMetrics2 = ( +export const useTrafficSearch = ( grouping: 'monthly' | 'daily', { from,