0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-03-17 22:31:28 -05:00

fix(console): remove legacy charge notification components (#6505)

This commit is contained in:
Darcy Ye 2024-08-22 18:18:43 +08:00 committed by GitHub
parent ed774bf62d
commit f1ecec5487
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 1 additions and 163 deletions

View file

@ -1,91 +0,0 @@
import { type AdminConsoleData, ReservedPlanId } from '@logto/schemas';
import { cond, type Truthy } from '@silverhand/essentials';
import { type TFuncKey } from 'i18next';
import { useContext } from 'react';
import { Trans, useTranslation } from 'react-i18next';
import { addOnPricingExplanationLink } from '@/consts';
import { SubscriptionDataContext } from '@/contexts/SubscriptionDataProvider';
import InlineNotification from '@/ds-components/InlineNotification';
import TextLink from '@/ds-components/TextLink';
import useConfigs from '@/hooks/use-configs';
type Props = {
readonly hasSurpassedLimit: boolean;
readonly quotaItemPhraseKey: TFuncKey<'translation', 'admin_console.upsell.add_on_quota_item'>;
readonly quotaLimit?: number;
readonly className?: string;
/**
* The key of the flag in `checkedChargeNotification` config from the AdminConsoleData.
* Used to determine whether the notification has been checked.
* @see{@link AdminConsoleData}
*/
readonly checkedFlagKey: keyof Truthy<AdminConsoleData['checkedChargeNotification']>;
};
/**
* Charge notification for add-on quota limit features
*
* CAUTION:
* - This notification will be rendered only when the tenant's subscription plan is a paid plan. We won't render it for free plan since we will not charge for free plan.
* - If the notification has been marked as checked, it will not be rendered.
*/
function ChargeNotification({
hasSurpassedLimit,
quotaItemPhraseKey,
quotaLimit,
className,
checkedFlagKey,
}: Props) {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console.upsell' });
const { currentSku } = useContext(SubscriptionDataContext);
const { configs, updateConfigs } = useConfigs();
// Display null when loading
if (!configs) {
return null;
}
const { checkedChargeNotification } = configs;
if (
Boolean(checkedChargeNotification?.[checkedFlagKey]) ||
!hasSurpassedLimit ||
// No charge notification for free plan
currentSku.id === ReservedPlanId.Free
) {
return null;
}
return (
<InlineNotification
className={className}
action="general.got_it"
onClick={() => {
void updateConfigs({
checkedChargeNotification: {
...checkedChargeNotification,
[checkedFlagKey]: true,
},
});
}}
>
<Trans
components={{ a: <TextLink href={addOnPricingExplanationLink} targetBlank="noopener" /> }}
>
{t('charge_notification_for_quota_limit', {
item: t(`add_on_quota_item.${quotaItemPhraseKey}`, {
...cond(
// Note: tokens use 'M' as unit
quotaLimit && {
limit: quotaItemPhraseKey === 'tokens' ? quotaLimit / 1_000_000 : quotaLimit,
}
),
}),
})}
</Trans>
</InlineNotification>
);
}
export default ChargeNotification;

View file

@ -3,7 +3,3 @@
.icon {
flex-shrink: 0;
}
.chargeNotification {
margin-top: _.unit(4);
}

View file

@ -8,17 +8,14 @@ import ApiResourceDark from '@/assets/icons/api-resource-dark.svg?react';
import ApiResource from '@/assets/icons/api-resource.svg?react';
import ManagementApiResourceDark from '@/assets/icons/management-api-resource-dark.svg?react';
import ManagementApiResource from '@/assets/icons/management-api-resource.svg?react';
import ChargeNotification from '@/components/ChargeNotification';
import EmptyDataPlaceholder from '@/components/EmptyDataPlaceholder';
import ItemPreview from '@/components/ItemPreview';
import ListPage from '@/components/ListPage';
import { defaultPageSize } from '@/consts';
import { isCloud } from '@/consts/env';
import { ApiResourceDetailsTabs } from '@/consts/page-tabs';
import CopyToClipboard from '@/ds-components/CopyToClipboard';
import Tag from '@/ds-components/Tag';
import type { RequestError } from '@/hooks/use-api';
import useApiResourcesUsage from '@/hooks/use-api-resources-usage';
import useSearchParametersWatcher from '@/hooks/use-search-parameters-watcher';
import useTenantPathname from '@/hooks/use-tenant-pathname';
import useTheme from '@/hooks/use-theme';
@ -41,7 +38,6 @@ const icons = {
function ApiResources() {
const { search } = useLocation();
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { hasSurpassedLimit } = useApiResourcesUsage();
const [{ page }, updateSearchParameters] = useSearchParametersWatcher({
page: 1,
});
@ -78,16 +74,6 @@ function ApiResources() {
});
},
}}
subHeader={
isCloud && (
<ChargeNotification
hasSurpassedLimit={hasSurpassedLimit}
quotaItemPhraseKey="api_resource"
checkedFlagKey="apiResource"
className={styles.chargeNotification}
/>
)
}
table={{
rowGroups: [{ key: 'apiResources', data: apiResources }],
rowIndexKey: 'id',

View file

@ -1,9 +1,5 @@
@use '@/scss/underscore' as _;
.chargeNotification {
margin: _.unit(4) 0 0;
}
.icon {
flex-shrink: 0;
}

View file

@ -6,17 +6,14 @@ import { useLocation } from 'react-router-dom';
import Plus from '@/assets/icons/plus.svg?react';
import ApplicationCreation from '@/components/ApplicationCreation';
import ChargeNotification from '@/components/ChargeNotification';
import { type SelectedGuide } from '@/components/Guide/GuideCard';
import ApplicationPreview from '@/components/ItemPreview/ApplicationPreview';
import PageMeta from '@/components/PageMeta';
import { isCloud } from '@/consts/env';
import Button from '@/ds-components/Button';
import CardTitle from '@/ds-components/CardTitle';
import CopyToClipboard from '@/ds-components/CopyToClipboard';
import TabNav, { TabNavItem } from '@/ds-components/TabNav';
import Table from '@/ds-components/Table';
import useApplicationsUsage from '@/hooks/use-applications-usage';
import useTenantPathname from '@/hooks/use-tenant-pathname';
import pageLayout from '@/scss/page-layout.module.scss';
import { buildUrl } from '@/utils/url';
@ -54,7 +51,6 @@ function Applications({ tab }: Props) {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const isCreating = match(createApplicationPathname);
const { hasMachineToMachineAppsSurpassedLimit } = useApplicationsUsage();
/**
* Selected guide from the guide library
* - `undefined`: No guide is selected
@ -121,15 +117,6 @@ function Applications({ tab }: Props) {
/>
)}
</div>
{isCloud && (
<ChargeNotification
hasSurpassedLimit={hasMachineToMachineAppsSurpassedLimit}
quotaItemPhraseKey="machine_to_machine"
className={styles.chargeNotification}
checkedFlagKey="machineToMachineApp"
/>
)}
{showThirdPartyApplicationTab && (
<TabNav className={styles.tabs}>
<TabNavItem

View file

@ -13,7 +13,3 @@
color: var(--color-text-secondary);
}
}
.notification {
margin-top: _.unit(6);
}

View file

@ -3,7 +3,6 @@ import { useContext, useMemo } from 'react';
import { type NewSubscriptionPeriodicUsage } from '@/cloud/types/router';
import BillInfo from '@/components/BillInfo';
import ChargeNotification from '@/components/ChargeNotification';
import FormCard from '@/components/FormCard';
import PlanDescription from '@/components/PlanDescription';
import PlanUsage from '@/components/PlanUsage';
@ -11,7 +10,6 @@ import SkuName from '@/components/SkuName';
import { SubscriptionDataContext } from '@/contexts/SubscriptionDataProvider';
import { TenantsContext } from '@/contexts/TenantsProvider';
import FormField from '@/ds-components/FormField';
import { hasSurpassedSubscriptionQuotaLimit } from '@/utils/quota';
import AddOnUsageChangesNotification from './AddOnUsageChangesNotification';
import MauLimitExceedNotification from './MauLimitExceededNotification';
@ -23,8 +21,7 @@ type Props = {
};
function CurrentPlan({ periodicUsage: rawPeriodicUsage }: Props) {
const { currentSku, currentSubscription, currentSubscriptionQuota } =
useContext(SubscriptionDataContext);
const { currentSku, currentSubscription } = useContext(SubscriptionDataContext);
const { currentTenant } = useContext(TenantsContext);
const periodicUsage = useMemo(
@ -52,12 +49,6 @@ function CurrentPlan({ periodicUsage: rawPeriodicUsage }: Props) {
return null;
}
const hasTokenSurpassedLimit = hasSurpassedSubscriptionQuotaLimit({
quotaKey: 'tokenLimit',
usage: periodicUsage.tokenLimit,
quota: currentSubscriptionQuota,
});
return (
<FormCard title="subscription.current_plan" description="subscription.current_plan_description">
<div className={styles.planInfo}>
@ -81,16 +72,6 @@ function CurrentPlan({ periodicUsage: rawPeriodicUsage }: Props) {
periodicUsage={rawPeriodicUsage}
className={styles.notification}
/>
<ChargeNotification
hasSurpassedLimit={hasTokenSurpassedLimit}
quotaItemPhraseKey="tokens"
checkedFlagKey="token"
className={styles.notification}
quotaLimit={cond(
typeof currentSubscriptionQuota.tokenLimit === 'number' &&
currentSubscriptionQuota.tokenLimit
)}
/>
<PaymentOverdueNotification className={styles.notification} />
</FormCard>
);

View file

@ -5,10 +5,6 @@
flex-direction: column;
gap: _.unit(4);
.chargeNotification {
margin: _.unit(4) 0 0;
}
.tabButtons {
display: flex;
align-items: center;

View file

@ -7,7 +7,6 @@ import InvitationIcon from '@/assets/icons/invitation.svg?react';
import MembersIcon from '@/assets/icons/members.svg?react';
import PlusIcon from '@/assets/icons/plus.svg?react';
import { useAuthedCloudApi } from '@/cloud/hooks/use-cloud-api';
import ChargeNotification from '@/components/ChargeNotification';
import { TenantSettingsTabs } from '@/consts';
import { TenantsContext } from '@/contexts/TenantsProvider';
import Button from '@/ds-components/Button';
@ -16,11 +15,9 @@ import useCurrentTenantScopes from '@/hooks/use-current-tenant-scopes';
import useTenantPathname from '@/hooks/use-tenant-pathname';
import InviteMemberModal from './InviteMemberModal';
import useTenantMembersUsage from './hooks';
import styles from './index.module.scss';
function TenantMembers() {
const { hasTenantMembersSurpassedLimit } = useTenantMembersUsage();
const { navigate, match } = useTenantPathname();
const [showInviteModal, setShowInviteModal] = useState(false);
const {
@ -39,12 +36,6 @@ function TenantMembers() {
return (
<div className={styles.container}>
<ChargeNotification
hasSurpassedLimit={hasTenantMembersSurpassedLimit}
quotaItemPhraseKey="tenant_member"
className={styles.chargeNotification}
checkedFlagKey="tenantMember"
/>
{canInviteMember && (
<div className={styles.tabButtons}>
<Button