Skip to content

Commit 4e573fb

Browse files
authored
chore: remove multiple custom domain feature guard (#7995)
1 parent 9240877 commit 4e573fb

File tree

22 files changed

+96
-185
lines changed

22 files changed

+96
-185
lines changed

packages/console/src/components/RolesTransfer/components/RoleInformation/index.module.scss

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,6 @@
1010
@include _.text-ellipsis;
1111
}
1212

13-
// Todo @xiaoyijun Remove this `count` style together with the dev feature flag
14-
.count {
15-
flex-shrink: 0;
16-
margin-inline-start: _.unit(2);
17-
color: var(--color-text-secondary);
18-
}
19-
2013
.flag {
2114
flex-shrink: 0;
2215
margin-inline-start: _.unit(2);

packages/console/src/hooks/use-custom-domain.ts

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { DomainStatus, type Domain } from '@logto/schemas';
22
import { conditional } from '@silverhand/essentials';
3-
import { useCallback, useMemo } from 'react';
3+
import { useCallback, useContext, useMemo } from 'react';
44
import useSWR from 'swr';
55

66
import { customDomainSyncInterval } from '@/consts/custom-domain';
77
import { isCloud } from '@/consts/env';
8+
import { SubscriptionDataContext } from '@/contexts/SubscriptionDataProvider';
9+
import { TenantsContext } from '@/contexts/TenantsProvider';
810

911
import { type RequestError } from './use-api';
1012

@@ -18,6 +20,11 @@ const useCustomDomain = (autoSync = false) => {
1820
)
1921
);
2022

23+
const { currentSubscriptionBasicQuota, currentSubscriptionUsage } =
24+
useContext(SubscriptionDataContext);
25+
26+
const { currentTenant } = useContext(TenantsContext);
27+
2128
const isLoading = !data && !error;
2229

2330
/**
@@ -67,6 +74,50 @@ const useCustomDomain = (autoSync = false) => {
6774
[allDomains]
6875
);
6976

77+
/**
78+
* Whether to display the feature add-on tag for custom domains.
79+
* Shows the add-on tag when current usage exceeds the basic quota limit (excluding add-on quota).
80+
*/
81+
const shouldDisplayFeatureAddOnTag = useMemo(() => {
82+
/**
83+
* Specifically for private region users who have enabled multiple custom domains feature flag.
84+
*
85+
* TODO @xiaoyijun: remove this special handling after enterprise subscription is live
86+
*/
87+
if (currentTenant?.featureFlags?.isMultipleCustomDomainsEnabled) {
88+
return false;
89+
}
90+
91+
return (
92+
currentSubscriptionUsage.customDomainsLimit >=
93+
(currentSubscriptionBasicQuota.customDomainsLimit ?? Number.POSITIVE_INFINITY)
94+
);
95+
}, [
96+
currentSubscriptionBasicQuota.customDomainsLimit,
97+
currentSubscriptionUsage.customDomainsLimit,
98+
currentTenant?.featureFlags?.isMultipleCustomDomainsEnabled,
99+
]);
100+
101+
const shouldDisplayUpsellNotification = useMemo(() => {
102+
/**
103+
* Specifically for private region users who have enabled multiple custom domains feature flag.
104+
*
105+
* TODO @xiaoyijun: remove this special handling after enterprise subscription is live
106+
*/
107+
if (currentTenant?.featureFlags?.isMultipleCustomDomainsEnabled) {
108+
return false;
109+
}
110+
111+
return (
112+
currentSubscriptionBasicQuota.customDomainsLimit ===
113+
currentSubscriptionUsage.customDomainsLimit
114+
);
115+
}, [
116+
currentSubscriptionBasicQuota.customDomainsLimit,
117+
currentSubscriptionUsage.customDomainsLimit,
118+
currentTenant?.featureFlags?.isMultipleCustomDomainsEnabled,
119+
]);
120+
70121
return {
71122
/**
72123
* Legacy single custom domain.
@@ -85,6 +136,8 @@ const useCustomDomain = (autoSync = false) => {
85136
isLoading,
86137
mutate: mutateDomain,
87138
activeCustomDomains,
139+
shouldDisplayFeatureAddOnTag,
140+
shouldDisplayUpsellNotification,
88141
};
89142
};
90143

packages/console/src/pages/TenantSettings/TenantDomainSettings/MultipleCustomDomainsFormField/PaywallNotification.tsx

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import SkuName from '@/components/SkuName';
66
import { addOnPricingExplanationLink } from '@/consts';
77
import { customDomainAddOnUnitPrice } from '@/consts/subscriptions';
88
import { SubscriptionDataContext } from '@/contexts/SubscriptionDataProvider';
9-
import { TenantsContext } from '@/contexts/TenantsProvider';
109
import InlineNotification from '@/ds-components/InlineNotification';
1110
import TextLink from '@/ds-components/TextLink';
1211
import usePaywall from '@/hooks/use-paywall';
@@ -21,9 +20,7 @@ export default function PaywallNotification() {
2120
const {
2221
currentSubscription: { planId },
2322
currentSubscriptionQuota,
24-
hasSurpassedSubscriptionQuotaLimit,
2523
} = useContext(SubscriptionDataContext);
26-
const { currentTenant } = useContext(TenantsContext);
2724

2825
if (isFreeTenant) {
2926
return (
@@ -51,16 +48,7 @@ export default function PaywallNotification() {
5148
);
5249
}
5350

54-
/**
55-
* Specifically for private region users who have enabled multiple custom domains feature flag.
56-
*
57-
* TODO @xiaoyijun: remove this special handling after enterprise subscription is live
58-
*/
59-
if (currentTenant?.featureFlags?.isMultipleCustomDomainsEnabled) {
60-
return null;
61-
}
62-
63-
if (isPaidTenant && !hasSurpassedSubscriptionQuotaLimit('customDomainsLimit')) {
51+
if (isPaidTenant) {
6452
return (
6553
<InlineNotification className={styles.paywallNotification}>
6654
<Trans

packages/console/src/pages/TenantSettings/TenantDomainSettings/MultipleCustomDomainsFormField/index.tsx

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { DomainStatus, type Domain } from '@logto/schemas';
2-
import { cond } from '@silverhand/essentials';
2+
import { type Optional } from '@silverhand/essentials';
33
import { useContext, useMemo } from 'react';
44
import { useTranslation } from 'react-i18next';
55

6+
import { type CombinedAddOnAndFeatureTagProps } from '@/components/FeatureTag';
67
import LearnMore from '@/components/LearnMore';
7-
import { isDevFeaturesEnabled } from '@/consts/env';
88
import { customDomain as customDomainDocumentationLink } from '@/consts/external-links';
99
import { latestProPlanId } from '@/consts/subscriptions';
1010
import { SubscriptionDataContext } from '@/contexts/SubscriptionDataProvider';
@@ -23,14 +23,16 @@ import styles from './index.module.scss';
2323

2424
function MultipleCustomDomainsFormField() {
2525
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
26-
const { allDomains, mutate } = useCustomDomain(true);
26+
const { allDomains, mutate, shouldDisplayFeatureAddOnTag, shouldDisplayUpsellNotification } =
27+
useCustomDomain(true);
2728
const api = useApi();
2829
const {
2930
access: { canManageTenant },
3031
} = useCurrentTenantScopes();
3132
const { hasReachedSubscriptionQuotaLimit } = useContext(SubscriptionDataContext);
3233
const { isPaidTenant } = usePaywall();
3334
const { currentTenant } = useContext(TenantsContext);
35+
const { isFreeTenant } = usePaywall();
3436

3537
const hasReachedQuotaLimit = hasReachedSubscriptionQuotaLimit('customDomainsLimit');
3638

@@ -60,20 +62,20 @@ function MultipleCustomDomainsFormField() {
6062
isPaidTenant,
6163
]);
6264

65+
const addOnFeatureTagProps = useMemo<Optional<CombinedAddOnAndFeatureTagProps>>(() => {
66+
if (shouldDisplayFeatureAddOnTag) {
67+
return {
68+
hasAddOnTag: !isFreeTenant,
69+
paywall: latestProPlanId,
70+
};
71+
}
72+
}, [isFreeTenant, shouldDisplayFeatureAddOnTag]);
73+
6374
return (
6475
<>
6576
<FormField
6677
title="domain.custom.add_custom_domain_field"
67-
{...cond(
68-
// TODO @xiaoyijun: remove the dev feature flag
69-
isDevFeaturesEnabled &&
70-
hasReachedQuotaLimit && {
71-
addOnFeatureTag: {
72-
hasAddOnTag: hasReachedQuotaLimit,
73-
paywall: latestProPlanId,
74-
},
75-
}
76-
)}
78+
addOnFeatureTag={addOnFeatureTagProps}
7779
>
7880
<AddDomainForm
7981
isReadonly={!canAddDomain}
@@ -82,10 +84,7 @@ function MultipleCustomDomainsFormField() {
8284
mutate(createdDomain);
8385
}}
8486
/>
85-
{
86-
// TODO @xiaoyijun: remove the dev feature flag
87-
isDevFeaturesEnabled && hasReachedQuotaLimit && <PaywallNotification />
88-
}
87+
{shouldDisplayUpsellNotification && <PaywallNotification />}
8988
</FormField>
9089
{allDomains.length > 0 && (
9190
<FormField title="domain.custom.custom_domain_field">

packages/console/src/pages/TenantSettings/TenantDomainSettings/SingleCustomDomainFormField/index.module.scss

Lines changed: 0 additions & 7 deletions
This file was deleted.

packages/console/src/pages/TenantSettings/TenantDomainSettings/SingleCustomDomainFormField/index.tsx

Lines changed: 0 additions & 55 deletions
This file was deleted.

packages/console/src/pages/TenantSettings/TenantDomainSettings/index.tsx

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
1-
import { useContext } from 'react';
2-
31
import FormCard from '@/components/FormCard';
42
import PageMeta from '@/components/PageMeta';
5-
import { isDevFeaturesEnabled } from '@/consts/env';
6-
import { TenantsContext } from '@/contexts/TenantsProvider';
73
import FormField from '@/ds-components/FormField';
84
import useCustomDomain from '@/hooks/use-custom-domain';
95
import useDocumentationUrl from '@/hooks/use-documentation-url';
@@ -12,17 +8,11 @@ import Skeleton from '../components/Skeleton';
128

139
import DefaultDomain from './DefaultDomain';
1410
import MultipleCustomDomainsFormField from './MultipleCustomDomainsFormField';
15-
import SingleCustomDomainFormField from './SingleCustomDomainFormField';
1611
import styles from './index.module.scss';
1712

1813
function TenantDomainSettings() {
1914
const { isLoading: isLoadingCustomDomain } = useCustomDomain(true);
2015
const { getDocumentationUrl } = useDocumentationUrl();
21-
const { currentTenant } = useContext(TenantsContext);
22-
23-
// TODO @xiaoyijun: remove the dev feature flag
24-
const isMultipleCustomDomainsEnabled =
25-
isDevFeaturesEnabled || Boolean(currentTenant?.featureFlags?.isMultipleCustomDomainsEnabled);
2616

2717
if (isLoadingCustomDomain) {
2818
return <Skeleton />;
@@ -39,11 +29,7 @@ function TenantDomainSettings() {
3929
targetBlank: 'noopener',
4030
}}
4131
>
42-
{isMultipleCustomDomainsEnabled ? (
43-
<MultipleCustomDomainsFormField />
44-
) : (
45-
<SingleCustomDomainFormField />
46-
)}
32+
<MultipleCustomDomainsFormField />
4733
</FormCard>
4834
<FormCard
4935
title="domain.default.default_domain"

packages/core/src/routes/domain.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ export default function domainRoutes<T extends ManagementApiRouter>(
2424
quota,
2525
} = libraries;
2626

27+
const isPrivateRegionFeature = EnvSet.values.isMultipleCustomDomainsEnabled;
28+
2729
router.get(
2830
'/domains',
2931
koaGuard({ response: domainResponseGuard.array(), status: 200 }),
@@ -83,8 +85,7 @@ export default function domainRoutes<T extends ManagementApiRouter>(
8385
const existingDomains = await findAllDomains();
8486

8587
await assertCustomDomainLimit({
86-
isPrivateRegionFeature: EnvSet.values.isMultipleCustomDomainsEnabled,
87-
isDevelopmentFeatureEnabled: EnvSet.values.isDevFeaturesEnabled,
88+
isPrivateRegionFeature,
8889
quotaLibrary: quota,
8990
existingDomainCount: existingDomains.length,
9091
});
@@ -102,7 +103,9 @@ export default function domainRoutes<T extends ManagementApiRouter>(
102103

103104
// Throw 400 error if domain is invalid
104105
const syncedDomain = await addDomain(ctx.guard.body.domain);
105-
106+
if (!isPrivateRegionFeature) {
107+
void quota.reportSubscriptionUpdatesUsage('customDomainsLimit');
108+
}
106109
ctx.status = 201;
107110
ctx.body = pick(syncedDomain, ...domainSelectFields);
108111

@@ -118,6 +121,10 @@ export default function domainRoutes<T extends ManagementApiRouter>(
118121
const { id } = ctx.guard.params;
119122
await deleteDomain(id);
120123

124+
if (!isPrivateRegionFeature) {
125+
void quota.reportSubscriptionUpdatesUsage('customDomainsLimit');
126+
}
127+
121128
await trySafe(async () => {
122129
const domains = await findAllDomains();
123130
const syncedDomains = await Promise.all(

0 commit comments

Comments
 (0)