Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(core,console): disable quota guard and unblock resource creation for pro tenants #6487

Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion packages/console/src/ds-components/TabNav/TabNavItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@ function TabNavItem<Paths extends string>({
)}
</div>
{errorCount > 0 && (
<div className={styles.errors}>{t('general.tab_errors', { count: errorCount })}</div>
<div className={styles.errors}>
{errorCount === 1
? t('general.tab_error', { count: errorCount })
: t('general.tab_errors', { count: errorCount })}
</div>
)}
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ function SsoCreationModal({ isOpen, onClose: rawOnClose }: Props) {
const isSsoEnabled =
!isCloud ||
currentSubscriptionQuota.enterpriseSsoLimit === null ||
currentSubscriptionQuota.enterpriseSsoLimit > 0;
currentSubscriptionQuota.enterpriseSsoLimit > 0 ||
planId === ReservedPlanId.Pro;

const { data, error } = useSWR<SsoConnectorProvidersResponse, RequestError>(
'api/sso-connector-providers'
Expand Down
5 changes: 3 additions & 2 deletions packages/console/src/pages/EnterpriseSso/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,16 @@ function EnterpriseSso() {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { isDevTenant } = useContext(TenantsContext);
const {
currentSubscription: { isAddOnAvailable },
currentSubscription: { planId, isAddOnAvailable },
currentSubscriptionQuota,
} = useContext(SubscriptionDataContext);

const [{ page }, updateSearchParameters] = useSearchParametersWatcher({
page: 1,
});

const isSsoEnabled = !isCloud || currentSubscriptionQuota.enterpriseSsoLimit !== 0;
const isSsoEnabled =
!isCloud || currentSubscriptionQuota.enterpriseSsoLimit !== 0 || planId === ReservedPlanId.Pro;

const url = buildUrl('api/sso-connectors', {
page: String(page),
Expand Down
12 changes: 8 additions & 4 deletions packages/console/src/pages/Mfa/MfaForm/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MfaFactor, MfaPolicy, type SignInExperience } from '@logto/schemas';
import { MfaFactor, MfaPolicy, ReservedPlanId, type SignInExperience } from '@logto/schemas';
import { useContext, useMemo } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
Expand Down Expand Up @@ -33,9 +33,13 @@ type Props = {
};

function MfaForm({ data, onMfaUpdated }: Props) {
const { currentSubscriptionQuota, mutateSubscriptionQuotaAndUsages } =
useContext(SubscriptionDataContext);
const isMfaDisabled = isCloud && !currentSubscriptionQuota.mfaEnabled;
const {
currentSubscription: { planId },
currentSubscriptionQuota,
mutateSubscriptionQuotaAndUsages,
} = useContext(SubscriptionDataContext);
const isMfaDisabled =
isCloud && !currentSubscriptionQuota.mfaEnabled && planId !== ReservedPlanId.Pro;

const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { getDocumentationUrl } = useDocumentationUrl();
Expand Down
4 changes: 2 additions & 2 deletions packages/console/src/pages/Mfa/PageWrapper/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ type Props = {
function PageWrapper({ children }: Props) {
const { isDevTenant } = useContext(TenantsContext);
const {
currentSubscription: { isAddOnAvailable },
currentSubscription: { planId, isAddOnAvailable },
currentSubscriptionQuota: { mfaEnabled },
} = useContext(SubscriptionDataContext);
const isMfaEnabled = !isCloud || mfaEnabled;
const isMfaEnabled = !isCloud || mfaEnabled || planId === ReservedPlanId.Pro;

return (
<div className={styles.container}>
Expand Down
8 changes: 6 additions & 2 deletions packages/console/src/pages/OrganizationTemplate/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,13 @@ const basePathname = '/organization-template';
function OrganizationTemplate() {
const { getDocumentationUrl } = useDocumentationUrl();
const [isGuideDrawerOpen, setIsGuideDrawerOpen] = useState(false);
const { currentSubscriptionQuota } = useContext(SubscriptionDataContext);
const {
currentSubscription: { planId },
currentSubscriptionQuota,
} = useContext(SubscriptionDataContext);
const { isDevTenant } = useContext(TenantsContext);
const isOrganizationsDisabled = isCloud && !currentSubscriptionQuota.organizationsEnabled;
const isOrganizationsDisabled =
isCloud && !currentSubscriptionQuota.organizationsEnabled && planId !== ReservedPlanId.Pro;
const { navigate } = useTenantPathname();

const handleUpgradePlan = useCallback(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ function CreateOrganizationModal({ isOpen, onClose }: Props) {
data: { organizationUpsellNoticeAcknowledged },
update,
} = useUserPreferences();
const isOrganizationsDisabled = isCloud && !currentSubscriptionQuota.organizationsEnabled;
const isOrganizationsDisabled =
isCloud && !currentSubscriptionQuota.organizationsEnabled && planId !== ReservedPlanId.Pro;

const {
reset,
Expand Down
5 changes: 3 additions & 2 deletions packages/console/src/pages/Organizations/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,16 @@ const organizationsPathname = '/organizations';
function Organizations() {
const { getDocumentationUrl } = useDocumentationUrl();
const {
currentSubscription: { isAddOnAvailable },
currentSubscription: { planId, isAddOnAvailable },
currentSubscriptionQuota,
} = useContext(SubscriptionDataContext);
const { isDevTenant } = useContext(TenantsContext);

const { navigate } = useTenantPathname();
const [isCreating, setIsCreating] = useState(false);

const isOrganizationsDisabled = isCloud && !currentSubscriptionQuota.organizationsEnabled;
const isOrganizationsDisabled =
isCloud && !currentSubscriptionQuota.organizationsEnabled && planId !== ReservedPlanId.Pro;

const upgradePlan = useCallback(() => {
navigate(subscriptionPage);
Expand Down
14 changes: 9 additions & 5 deletions packages/core/src/libraries/quota.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,16 @@

export type QuotaLibrary = ReturnType<typeof createQuotaLibrary>;

/**
* @remarks
* Should report usage changes to the Cloud only when the following conditions are met:
* 1. The tenant is on the Pro plan.
* 2. The usage key is add-on related usage key.
*/
const shouldReportSubscriptionUpdates = (
planId: string,
key: keyof SubscriptionQuota,
isAddOnAvailable?: boolean
) => planId === ReservedPlanId.Pro && isAddOnAvailable && isReportSubscriptionUpdatesUsageKey(key);
) => planId === ReservedPlanId.Pro && isReportSubscriptionUpdatesUsageKey(key);

export const createQuotaLibrary = (cloudConnection: CloudConnectionLibrary) => {
const guardTenantUsageByKey = async (key: keyof SubscriptionQuota) => {
Expand All @@ -36,13 +41,12 @@

const {
planId,
isAddOnAvailable,
quota: fullQuota,
usage: fullUsage,
} = await getTenantSubscriptionData(cloudConnection);

// Do not block Pro plan from adding add-on resources.
if (shouldReportSubscriptionUpdates(planId, key, isAddOnAvailable)) {
if (shouldReportSubscriptionUpdates(planId,key)) {

Check warning on line 49 in packages/core/src/libraries/quota.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/libraries/quota.ts#L49

Added line #L49 was not covered by tests
return;
}

Expand Down Expand Up @@ -159,7 +163,7 @@

const { planId, isAddOnAvailable } = await getTenantSubscriptionData(cloudConnection);

if (shouldReportSubscriptionUpdates(planId, key, isAddOnAvailable)) {
if (shouldReportSubscriptionUpdates(planId, key) && isAddOnAvailable) {
await reportSubscriptionUpdates(cloudConnection, key);
}
};
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/utils/subscription/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ export const reportSubscriptionUpdates = async (
);
};

/**
* @remarks
* Check whether the provided usage key is add-on related usage key.
*/
export const isReportSubscriptionUpdatesUsageKey = (
value: string
): value is ReportSubscriptionUpdatesUsageKey => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ const general = {
continue: 'Continue',
page_info: '{{min, number}}-{{max, number}} of {{total, number}}',
learn_more: 'Learn more',
tab_error: '{{count, number}} error',
tab_errors: '{{count, number}} errors',
darcyYe marked this conversation as resolved.
Show resolved Hide resolved
skip_for_now: 'Skip for now',
remove: 'Remove',
Expand Down
Loading