Skip to content

Commit

Permalink
feat: Add alert message in the FE when exceeded the API usage (#4027)
Browse files Browse the repository at this point in the history
Co-authored-by: Matthew Elwell <[email protected]>
  • Loading branch information
novakzaballa and matthewelwell authored Jun 18, 2024
1 parent 85f30f5 commit da46dab
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 21 deletions.
1 change: 1 addition & 0 deletions frontend/common/services/useOrganisationUsage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
})}`,
}
Expand Down
4 changes: 4 additions & 0 deletions frontend/common/types/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion frontend/common/types/responses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ export type Res = {
rolesPermissionUsers: PagedResponse<RolePermissionUser>
createRolePermissionGroup: RolePermissionGroup
rolePermissionGroup: PagedResponse<RolePermissionGroup>
getSubscriptionMetadata: { id: string }
getSubscriptionMetadata: { id: string; max_api_calls: number }
environment: Environment
metadataModelFieldList: PagedResponse<MetadataModelField>
metadataModelField: MetadataModelField
Expand Down
3 changes: 3 additions & 0 deletions frontend/web/components/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,9 @@ const App = class extends Component {
{user && (
<OrganisationLimit
id={AccountStore.getOrganisation()?.id}
organisationPlan={
AccountStore.getOrganisation()?.subscription.plan
}
/>
)}
{user && showBanner && (
Expand Down
1 change: 1 addition & 0 deletions frontend/web/components/ButterBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const ButterBar: React.FC<ButterBarProps> = ({ billingStatus, projectId }) => {
{ skip: !projectId },
)
const processingRef = useRef(false)

const checkProcessing = useCallback(
(processing: FeatureImport | undefined) => {
if (processing) {
Expand Down
72 changes: 52 additions & 20 deletions frontend/web/components/OrganisationLimit.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,75 @@
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<OrganisationLimitType> = ({ id }) => {
const { data: totalApiCalls } = useGetOrganisationUsageQuery(
{
organisationId: id,
},
{ skip: !id },
)
const OrganisationLimit: FC<OrganisationLimitType> = ({
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,
maxApiCalls?.max_api_calls,
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 (
<div
className={'alert alert-danger announcement'}
style={{ display: 'initial' }}
>
<span className='icon-alert'>
<Icon name='close-circle' />
</span>
<>
Your organisation has exceeded its API usage quota{' '}
{`(${alertMaxApiCallsText}).`}{' '}
{Utils.getPlanName(organisationPlan) === 'Free' ? (
<b>Please upgrade your plan to continue receiving service.</b>
) : (
<b>Automated billing for the overages may apply.</b>
)}
</>
<Button
className='btn ml-3'
onClick={() => {
document.location.replace(Constants.upgradeURL)
}}
>
Upgrade plan
</Button>
</div>
)
}

return (
<Row>
<Row className='justify-content-center'>
{Utils.getFlagsmithHasFeature('payments_enabled') &&
Utils.getFlagsmithHasFeature('max_api_calls_alert') &&
(maxApiCallsPercentage < 100 ? (
Expand All @@ -41,13 +79,7 @@ const OrganisationLimit: FC<OrganisationLimitType> = ({ id }) => {
enabledButton
/>
) : (
maxApiCallsPercentage >= 100 && (
<ErrorMessage
error={alertMaxApiCallsText}
errorMessageClass={'announcement'}
enabledButton
/>
)
maxApiCallsPercentage >= 100 && <QuotaExceededMessage />
))}
</Row>
)
Expand Down

0 comments on commit da46dab

Please sign in to comment.