0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-01-27 21:39:16 -05:00

refactor(console): avoid getSubscription call before authentication (#6426)

avoid getSubscription call before authentication
This commit is contained in:
simeng-li 2024-08-09 16:33:19 +08:00 committed by GitHub
parent 25187ef63b
commit eca4501af8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 62 additions and 60 deletions

View file

@ -24,16 +24,11 @@ export default function AppContent() {
const { isLoading: isLoadingPreference } = useUserPreferences();
const { currentTenant } = useContext(TenantsContext);
const isTenantSuspended = isCloud && currentTenant?.isSuspended;
// TODO: @darcyYe remove this
const { isLoading: isLoadingSubscriptionData, ...subscriptionDta } = useSubscriptionData();
const {
isLoading: isLoadingNewSubscriptionData,
logtoSkus,
currentSku,
currentSubscriptionQuota,
currentSubscriptionUsage,
currentSubscriptionScopeResourceUsage,
currentSubscriptionScopeRoleUsage,
} = useNewSubscriptionData();
const { isLoading: isLoadingNewSubscriptionData, ...newSubscriptionData } =
useNewSubscriptionData();
const scrollableContent = useRef<HTMLDivElement>(null);
const { scrollTop } = useScroll(scrollableContent.current);
@ -49,12 +44,7 @@ export default function AppContent() {
<SubscriptionDataProvider
subscriptionData={{
...subscriptionDta,
logtoSkus,
currentSku,
currentSubscriptionQuota,
currentSubscriptionUsage,
currentSubscriptionScopeResourceUsage,
currentSubscriptionScopeRoleUsage,
...newSubscriptionData,
}}
>
<div className={styles.app}>

View file

@ -32,6 +32,7 @@ export const SubscriptionDataContext = createContext<FullContext>({
currentSubscriptionUsage: defaultSubscriptionUsage,
currentSubscriptionScopeResourceUsage: {},
currentSubscriptionScopeRoleUsage: {},
mutateSubscriptionQuotaAndUsages: noop,
/* ==== For new pricing model ==== */
});

View file

@ -23,6 +23,7 @@ type NewSubscriptionSupplementContext = {
currentSubscriptionUsage: NewSubscriptionUsage;
currentSubscriptionScopeResourceUsage: NewSubscriptionScopeUsage;
currentSubscriptionScopeRoleUsage: NewSubscriptionScopeUsage;
mutateSubscriptionQuotaAndUsages: () => void;
};
export type NewSubscriptionContext = Omit<Context, 'subscriptionPlans' | 'currentPlan'> &

View file

@ -1,5 +1,5 @@
import { cond, condString } from '@silverhand/essentials';
import { useContext, useMemo } from 'react';
import { useCallback, useContext, useMemo } from 'react';
import {
defaultLogtoSku,
@ -7,7 +7,7 @@ import {
defaultSubscriptionQuota,
defaultSubscriptionUsage,
} from '@/consts';
import { isCloud } from '@/consts/env';
import { isCloud, isDevFeaturesEnabled } from '@/consts/env';
import { TenantsContext } from '@/contexts/TenantsProvider';
import useLogtoSkus from '@/hooks/use-logto-skus';
import useNewSubscriptionQuota from '@/hooks/use-new-subscription-quota';
@ -26,15 +26,48 @@ const useNewSubscriptionData: () => NewSubscriptionContext & { isLoading: boolea
isLoading: isSubscriptionLoading,
mutate: mutateSubscription,
} = useSubscription(condString(currentTenant?.id));
const { data: currentSubscriptionQuota, isLoading: isSubscriptionQuotaLoading } =
useNewSubscriptionQuota(condString(currentTenant?.id));
const { data: currentSubscriptionUsage, isLoading: isSubscriptionUsageLoading } =
useNewSubscriptionUsage(condString(currentTenant?.id));
const {
scopeResourceUsage: { data: scopeResourceUsage, isLoading: isScopePerResourceUsageLoading },
scopeRoleUsage: { data: scopeRoleUsage, isLoading: isScopePerRoleUsageLoading },
data: currentSubscriptionQuota,
isLoading: isSubscriptionQuotaLoading,
mutate: mutateSubscriptionQuota,
} = useNewSubscriptionQuota(condString(currentTenant?.id));
const {
data: currentSubscriptionUsage,
isLoading: isSubscriptionUsageLoading,
mutate: mutateSubscriptionUsage,
} = useNewSubscriptionUsage(condString(currentTenant?.id));
const {
scopeResourceUsage: {
data: scopeResourceUsage,
isLoading: isScopePerResourceUsageLoading,
mutate: mutateScopeResourceUsage,
},
scopeRoleUsage: {
data: scopeRoleUsage,
isLoading: isScopePerRoleUsageLoading,
mutate: mutateScopeRoleUsage,
},
} = useNewSubscriptionScopeUsage(condString(currentTenant?.id));
const mutateSubscriptionQuotaAndUsages = useCallback(() => {
if (!isDevFeaturesEnabled) {
return;
}
void mutateSubscriptionQuota();
void mutateSubscriptionUsage();
void mutateScopeResourceUsage();
void mutateScopeRoleUsage();
}, [
mutateScopeResourceUsage,
mutateScopeRoleUsage,
mutateSubscriptionQuota,
mutateSubscriptionUsage,
]);
const logtoSkus = useMemo(() => cond(isCloud && fetchedLogtoSkus) ?? [], [fetchedLogtoSkus]);
const currentSku = useMemo(
@ -54,6 +87,7 @@ const useNewSubscriptionData: () => NewSubscriptionContext & { isLoading: boolea
currentSku,
currentSubscription: currentSubscription ?? defaultTenantResponse.subscription,
onCurrentSubscriptionUpdated: mutateSubscription,
mutateSubscriptionQuotaAndUsages,
currentSubscriptionQuota: currentSubscriptionQuota ?? defaultSubscriptionQuota,
currentSubscriptionUsage: currentSubscriptionUsage ?? defaultSubscriptionUsage,
currentSubscriptionScopeResourceUsage: scopeResourceUsage ?? {},

View file

@ -22,12 +22,11 @@ import { useTranslation } from 'react-i18next';
import { requestTimeout } from '@/consts';
import { isCloud, isDevFeaturesEnabled } from '@/consts/env';
import { AppDataContext } from '@/contexts/AppDataProvider';
import { SubscriptionDataContext } from '@/contexts/SubscriptionDataProvider';
import { TenantsContext } from '@/contexts/TenantsProvider';
import { useConfirmModal } from '@/hooks/use-confirm-modal';
import useRedirectUri from '@/hooks/use-redirect-uri';
import useSubscribe from './use-subscribe';
export class RequestError extends Error {
constructor(
public readonly status: number,
@ -118,6 +117,7 @@ export const useStaticApi = ({
}: StaticApiProps): KyInstance => {
const { isAuthenticated, getAccessToken, getOrganizationToken } = useLogto();
const { i18n } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { mutateSubscriptionQuotaAndUsages } = useContext(SubscriptionDataContext);
// Disable global error handling if `hideErrorToast` is true.
const disableGlobalErrorHandling = hideErrorToast === true;
@ -125,7 +125,6 @@ export const useStaticApi = ({
const toastDisabledErrorCodes = Array.isArray(hideErrorToast) ? hideErrorToast : undefined;
const { handleError } = useGlobalRequestErrorHandler(toastDisabledErrorCodes);
const { syncSubscriptionData } = useSubscribe();
const api = useMemo(
() =>
@ -162,7 +161,7 @@ export const useStaticApi = ({
response.status >= 200 &&
response.status < 300
) {
syncSubscriptionData();
mutateSubscriptionQuotaAndUsages();
}
},
],
@ -179,7 +178,7 @@ export const useStaticApi = ({
getOrganizationToken,
getAccessToken,
i18n.language,
syncSubscriptionData,
mutateSubscriptionQuotaAndUsages,
]
);

View file

@ -1,7 +1,7 @@
import { ReservedPlanId } from '@logto/schemas';
import dayjs from 'dayjs';
import { nanoid } from 'nanoid';
import { useCallback, useContext, useState } from 'react';
import { useContext, useState } from 'react';
import { toast } from 'react-hot-toast';
import { useTranslation } from 'react-i18next';
@ -9,14 +9,11 @@ import { toastResponseError, useCloudApi } from '@/cloud/hooks/use-cloud-api';
import { type CreateTenantData } from '@/components/CreateTenantModal/types';
import { isDevFeaturesEnabled } from '@/consts/env';
import { checkoutStateQueryKey } from '@/consts/subscriptions';
import { SubscriptionDataContext } from '@/contexts/SubscriptionDataProvider';
import { GlobalRoute, TenantsContext } from '@/contexts/TenantsProvider';
import { createLocalCheckoutSession } from '@/utils/checkout';
import { dropLeadingSlash } from '@/utils/url';
import useNewSubscriptionQuota from './use-new-subscription-quota';
import useNewSubscriptionScopeUsage from './use-new-subscription-scopes-usage';
import useNewSubscriptionUsage from './use-new-subscription-usage';
import useSubscription from './use-subscription';
import useTenantPathname from './use-tenant-pathname';
type SubscribeProps = {
@ -36,34 +33,13 @@ type SubscribeProps = {
const useSubscribe = () => {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const cloudApi = useCloudApi({ hideErrorToast: true });
const { updateTenant, currentTenantId } = useContext(TenantsContext);
const { updateTenant } = useContext(TenantsContext);
const { mutateSubscriptionQuotaAndUsages, onCurrentSubscriptionUpdated } =
useContext(SubscriptionDataContext);
const { getUrl } = useTenantPathname();
const [isSubscribeLoading, setIsSubscribeLoading] = useState(false);
const { mutate: mutateSubscription } = useSubscription(currentTenantId);
const { mutate: mutateSubscriptionQuota } = useNewSubscriptionQuota(currentTenantId);
const { mutate: mutateSubscriptionUsage } = useNewSubscriptionUsage(currentTenantId);
const {
scopeResourceUsage: { mutate: mutateScopeResourceUsage },
scopeRoleUsage: { mutate: mutateScopeRoleUsage },
} = useNewSubscriptionScopeUsage(currentTenantId);
const syncSubscriptionData = useCallback(() => {
void mutateSubscription();
if (isDevFeaturesEnabled) {
void mutateSubscriptionQuota();
void mutateSubscriptionUsage();
void mutateScopeResourceUsage();
void mutateScopeRoleUsage();
}
}, [
mutateScopeResourceUsage,
mutateScopeRoleUsage,
mutateSubscription,
mutateSubscriptionQuota,
mutateSubscriptionUsage,
]);
const subscribe = async ({
skuId,
planId,
@ -133,7 +109,9 @@ const useSubscribe = () => {
},
});
syncSubscriptionData();
mutateSubscriptionQuotaAndUsages();
onCurrentSubscriptionUpdated();
updateTenant(tenantId, {
planId: rest.planId,
subscription: rest,
@ -177,7 +155,6 @@ const useSubscribe = () => {
isSubscribeLoading,
subscribe,
cancelSubscription,
syncSubscriptionData,
visitManagePaymentPage,
};
};