From 591f78f74374e691c1dfa526f76f0a52612d2e58 Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Thu, 20 Jul 2023 14:06:09 +0800 Subject: [PATCH] feat(console): apply quota limit for roles (#4189) --- .../CreateConnectorForm/Footer/index.tsx | 10 +-- .../CreatePermissionModal/index.tsx | 6 +- .../components/CreateForm/index.tsx | 6 +- .../components/CreateForm/Footer/index.tsx | 10 +-- .../AssignPermissionsModal/index.tsx | 57 +++++++++++--- .../RoleDetails/RolePermissions/index.tsx | 3 +- .../Roles/components/CreateRoleForm/index.tsx | 77 ++++++++++++++++--- .../components/CreateRoleModal/index.tsx | 5 +- packages/console/src/pages/Roles/index.tsx | 4 +- .../components/CreateFormModal/CreateForm.tsx | 4 +- packages/console/src/utils/quota.ts | 4 +- 11 files changed, 140 insertions(+), 46 deletions(-) diff --git a/packages/console/src/components/CreateConnectorForm/Footer/index.tsx b/packages/console/src/components/CreateConnectorForm/Footer/index.tsx index ab8f8146d..4b6e6149a 100644 --- a/packages/console/src/components/CreateConnectorForm/Footer/index.tsx +++ b/packages/console/src/components/CreateConnectorForm/Footer/index.tsx @@ -13,7 +13,7 @@ import { ReservedPlanId } from '@/consts/subscriptions'; import Button from '@/ds-components/Button'; import useCurrentSubscriptionPlan from '@/hooks/use-current-subscription-plan'; import { type ConnectorGroup } from '@/types/connector'; -import { isOverQuota } from '@/utils/quota'; +import { hasReachedQuotaLimit } from '@/utils/quota'; type Props = { isCreatingSocialConnector: boolean; @@ -49,13 +49,13 @@ function Footer({ [existingConnectors] ); - const isStandardConnectorsOverQuota = isOverQuota({ + const isStandardConnectorsReachLimit = hasReachedQuotaLimit({ quotaKey: 'standardConnectorsLimit', plan: currentPlan, usage: standardConnectorCount, }); - const isSocialConnectorsOverQuota = isOverQuota({ + const isSocialConnectorsReachLimit = hasReachedQuotaLimit({ quotaKey: 'socialConnectorsLimit', plan: currentPlan, usage: socialConnectorCount, @@ -64,7 +64,7 @@ function Footer({ if (isCreatingSocialConnector && currentPlan && selectedConnectorGroup) { const { id: planId, name: planName, quota } = currentPlan; - if (isStandardConnectorsOverQuota && selectedConnectorGroup.isStandard) { + if (isStandardConnectorsReachLimit && selectedConnectorGroup.isStandard) { return ( !isManagementApi(indicator)).length ?? 0; - const isResourcesOverQuota = isOverQuota({ + const isResourcesReachLimit = hasReachedQuotaLimit({ quotaKey: 'resourcesLimit', plan: currentPlan, usage: resourceCount, @@ -68,7 +68,7 @@ function CreateForm({ onClose }: Props) { title="api_resources.create" subtitle="api_resources.subtitle" footer={ - isResourcesOverQuota && currentPlan ? ( + isResourcesReachLimit && currentPlan ? ( {quota.machineToMachineLimit === 0 && planId === ReservedPlanId.free ? ( @@ -74,7 +74,7 @@ function Footer({ selectedType, isLoading, onClickCreate }: Props) { ); } - if (selectedType !== ApplicationType.MachineToMachine && isNonM2mAppsOverQuota) { + if (selectedType !== ApplicationType.MachineToMachine && isNonM2mAppsReachLimit) { return ( void; }; -function AssignPermissionsModal({ roleId, onClose }: Props) { +function AssignPermissionsModal({ roleId, totalRoleScopeCount, onClose }: Props) { const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); - + const { data: currentPlan } = useCurrentSubscriptionPlan(); const [isSubmitting, setIsSubmitting] = useState(false); const [scopes, setScopes] = useState([]); @@ -42,6 +48,18 @@ function AssignPermissionsModal({ roleId, onClose }: Props) { } }; + const shouldBlockScopeAssignment = hasReachedQuotaLimit({ + quotaKey: 'scopesPerRoleLimit', + plan: currentPlan, + /** + * If usage is equal to the limit, it means the current role has reached the maximum allowed scope. + * Therefore, we should not assign any more scopes at this point. + * However, the currently selected scopes haven't been assigned yet, so we subtract 1 + * to allow the assignment when the scope count is equal to the limit. + */ + usage: totalRoleScopeCount + scopes.length - 1, + }); + return ( + shouldBlockScopeAssignment && currentPlan ? ( + + , + planName: , + }} + > + {t('upsell.paywall.scopes_per_role', { + count: currentPlan.quota.scopesPerRoleLimit ?? 0, + })} + + + ) : ( +