From da46dab0f82dfa38d68c0108ee6fdbfb2c3a344f Mon Sep 17 00:00:00 2001 From: Novak Zaballa <41410593+novakzaballa@users.noreply.github.com> Date: Tue, 18 Jun 2024 09:05:32 -0400 Subject: [PATCH] feat: Add alert message in the FE when exceeded the API usage (#4027) Co-authored-by: Matthew Elwell --- .../common/services/useOrganisationUsage.ts | 1 + frontend/common/types/requests.ts | 4 ++ frontend/common/types/responses.ts | 2 +- frontend/web/components/App.js | 3 + frontend/web/components/ButterBar.tsx | 1 + frontend/web/components/OrganisationLimit.tsx | 72 +++++++++++++------ 6 files changed, 62 insertions(+), 21 deletions(-) diff --git a/frontend/common/services/useOrganisationUsage.ts b/frontend/common/services/useOrganisationUsage.ts index 64abde4904e1..c8e34bad4754 100644 --- a/frontend/common/services/useOrganisationUsage.ts +++ b/frontend/common/services/useOrganisationUsage.ts @@ -18,6 +18,7 @@ export const organisationUsageService = service query.organisationId }/usage-data/?${Utils.toParam({ environment_id: query.environmentId, + period: query.billing_period, project_id: query.projectId, })}`, } diff --git a/frontend/common/types/requests.ts b/frontend/common/types/requests.ts index 82fdcb1ee1d6..f5ac0efa5828 100644 --- a/frontend/common/types/requests.ts +++ b/frontend/common/types/requests.ts @@ -59,6 +59,10 @@ export type Req = { organisationId: string projectId?: string environmentId?: string + billing_period?: + | 'current_billing_period' + | 'previous_billing_period' + | '90_day_period' } deleteIdentity: { id: string diff --git a/frontend/common/types/responses.ts b/frontend/common/types/responses.ts index 74f4fc7ee0f0..9093d36c526f 100644 --- a/frontend/common/types/responses.ts +++ b/frontend/common/types/responses.ts @@ -633,7 +633,7 @@ export type Res = { rolesPermissionUsers: PagedResponse createRolePermissionGroup: RolePermissionGroup rolePermissionGroup: PagedResponse - getSubscriptionMetadata: { id: string } + getSubscriptionMetadata: { id: string; max_api_calls: number } environment: Environment metadataModelFieldList: PagedResponse metadataModelField: MetadataModelField diff --git a/frontend/web/components/App.js b/frontend/web/components/App.js index c35417700218..6df452e5e766 100644 --- a/frontend/web/components/App.js +++ b/frontend/web/components/App.js @@ -378,6 +378,9 @@ const App = class extends Component { {user && ( )} {user && showBanner && ( diff --git a/frontend/web/components/ButterBar.tsx b/frontend/web/components/ButterBar.tsx index 3fb8660d9fd0..c7ff78ec0349 100644 --- a/frontend/web/components/ButterBar.tsx +++ b/frontend/web/components/ButterBar.tsx @@ -26,6 +26,7 @@ const ButterBar: React.FC = ({ billingStatus, projectId }) => { { skip: !projectId }, ) const processingRef = useRef(false) + const checkProcessing = useCallback( (processing: FeatureImport | undefined) => { if (processing) { diff --git a/frontend/web/components/OrganisationLimit.tsx b/frontend/web/components/OrganisationLimit.tsx index a9af7ccab933..db8dca99deea 100644 --- a/frontend/web/components/OrganisationLimit.tsx +++ b/frontend/web/components/OrganisationLimit.tsx @@ -1,22 +1,30 @@ import { FC } from 'react' import WarningMessage from './WarningMessage' -import ErrorMessage from './ErrorMessage' import Utils from 'common/utils/utils' import { useGetSubscriptionMetadataQuery } from 'common/services/useSubscriptionMetadata' import Format from 'common/utils/format' import { useGetOrganisationUsageQuery } from 'common/services/useOrganisationUsage' +import Icon from './Icon' +import { Button } from './base/forms/Button' +import Constants from 'common/constants' type OrganisationLimitType = { id: string + organisationPlan: string } -const OrganisationLimit: FC = ({ id }) => { - const { data: totalApiCalls } = useGetOrganisationUsageQuery( - { - organisationId: id, - }, - { skip: !id }, - ) +const OrganisationLimit: FC = ({ + id, + organisationPlan, +}) => { + let body = { organisationId: id } + if (Utils.getPlanName(organisationPlan) !== 'free') { + body = { ...body, ...{ billing_period: 'current_billing_period' } } + } + + const { data: totalApiCalls } = useGetOrganisationUsageQuery(body, { + skip: !id, + }) const { data: maxApiCalls } = useGetSubscriptionMetadataQuery({ id }) const maxApiCallsPercentage = Utils.calculateRemainingLimitsPercentage( totalApiCalls?.totals.total, @@ -24,14 +32,44 @@ const OrganisationLimit: FC = ({ id }) => { 70, ).percentage - const alertMaxApiCallsText = `You have used ${Format.shortenNumber( + const apiUsageMessageText = `${Format.shortenNumber( totalApiCalls?.totals.total, - )}/${Format.shortenNumber( - maxApiCalls?.max_api_calls, - )} of your allowed requests.` + )}/${Format.shortenNumber(maxApiCalls?.max_api_calls)}` + + const alertMaxApiCallsText = `You have used ${apiUsageMessageText} of your allowed requests.` + + const QuotaExceededMessage = () => { + return ( +
+ + + + <> + Your organisation has exceeded its API usage quota{' '} + {`(${alertMaxApiCallsText}).`}{' '} + {Utils.getPlanName(organisationPlan) === 'Free' ? ( + Please upgrade your plan to continue receiving service. + ) : ( + Automated billing for the overages may apply. + )} + + +
+ ) + } return ( - + {Utils.getFlagsmithHasFeature('payments_enabled') && Utils.getFlagsmithHasFeature('max_api_calls_alert') && (maxApiCallsPercentage < 100 ? ( @@ -41,13 +79,7 @@ const OrganisationLimit: FC = ({ id }) => { enabledButton /> ) : ( - maxApiCallsPercentage >= 100 && ( - - ) + maxApiCallsPercentage >= 100 && ))} )