From 9fbb4196f3787f45244679d602dd8e6288c0cb68 Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Fri, 23 Feb 2024 10:32:54 +0800 Subject: [PATCH] refactor(console): reorg downgrade plan notification modal (#5419) --- .../PlanQuotaList/QuotaListItem/index.tsx | 36 ------- .../src/components/PlanQuotaList/index.tsx | 40 -------- packages/console/src/consts/plan-quotas.ts | 93 ++++++------------- .../console/src/consts/quota-item-phrases.ts | 13 --- packages/console/src/consts/tenants.ts | 1 - .../DiffQuotaItem/index.module.scss | 12 --- .../PlanQuotaDiffCard/DiffQuotaItem/index.tsx | 37 -------- .../DiffQuotaItem}/QuotaItemPhrase.tsx | 9 +- .../DiffQuotaItem}/index.module.scss | 13 +++ .../PlanQuotaList/DiffQuotaItem/index.tsx | 43 +++++++++ .../PlanQuotaList/index.module.scss | 0 .../PlanQuotaDiffCard/PlanQuotaList/index.tsx | 29 ++++++ .../PlanQuotaDiffCard/index.tsx | 32 +++---- .../index.tsx | 1 - packages/console/src/types/subscriptions.ts | 49 +--------- packages/console/src/utils/subscription.ts | 6 +- .../admin-console/subscription/quota-item.ts | 7 -- .../admin-console/subscription/quota-item.ts | 7 -- .../admin-console/subscription/quota-item.ts | 7 -- .../admin-console/subscription/quota-item.ts | 7 -- .../admin-console/subscription/quota-item.ts | 7 -- .../admin-console/subscription/quota-item.ts | 7 -- .../admin-console/subscription/quota-item.ts | 7 -- .../admin-console/subscription/quota-item.ts | 7 -- .../admin-console/subscription/quota-item.ts | 7 -- .../admin-console/subscription/quota-item.ts | 7 -- .../admin-console/subscription/quota-item.ts | 7 -- .../admin-console/subscription/quota-item.ts | 7 -- .../admin-console/subscription/quota-item.ts | 7 -- .../admin-console/subscription/quota-item.ts | 7 -- .../admin-console/subscription/quota-item.ts | 7 -- 31 files changed, 137 insertions(+), 382 deletions(-) delete mode 100644 packages/console/src/components/PlanQuotaList/QuotaListItem/index.tsx delete mode 100644 packages/console/src/components/PlanQuotaList/index.tsx delete mode 100644 packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/DiffQuotaItem/index.module.scss delete mode 100644 packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/DiffQuotaItem/index.tsx rename packages/console/src/{components/PlanQuotaList/QuotaListItem => pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/PlanQuotaList/DiffQuotaItem}/QuotaItemPhrase.tsx (78%) rename packages/console/src/{components/PlanQuotaList/QuotaListItem => pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/PlanQuotaList/DiffQuotaItem}/index.module.scss (69%) create mode 100644 packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/PlanQuotaList/DiffQuotaItem/index.tsx rename packages/console/src/{components => pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard}/PlanQuotaList/index.module.scss (100%) create mode 100644 packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/PlanQuotaList/index.tsx diff --git a/packages/console/src/components/PlanQuotaList/QuotaListItem/index.tsx b/packages/console/src/components/PlanQuotaList/QuotaListItem/index.tsx deleted file mode 100644 index 36bc96aa0..000000000 --- a/packages/console/src/components/PlanQuotaList/QuotaListItem/index.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import classNames from 'classnames'; -import { type ReactNode } from 'react'; - -import { type SubscriptionPlanQuota } from '@/types/subscriptions'; - -import QuotaItemPhrase from './QuotaItemPhrase'; -import * as styles from './index.module.scss'; - -type Props = { - quotaKey: keyof SubscriptionPlanQuota; - quotaValue: SubscriptionPlanQuota[keyof SubscriptionPlanQuota]; - icon?: ReactNode; - suffix?: ReactNode; - isAddOn?: boolean; - phraseClassName?: string; -}; - -function QuotaListItem({ icon, suffix, phraseClassName, ...rest }: Props) { - return ( -
  • - {/** - * Add a `span` as a wrapper to apply the flex layout to the content. - * If we apply the flex layout to the `li` directly, the `li` circle bullet will disappear. - */} - - {icon} - - - - {suffix} - -
  • - ); -} - -export default QuotaListItem; diff --git a/packages/console/src/components/PlanQuotaList/index.tsx b/packages/console/src/components/PlanQuotaList/index.tsx deleted file mode 100644 index 5672db829..000000000 --- a/packages/console/src/components/PlanQuotaList/index.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import classNames from 'classnames'; -import { useMemo, type ReactNode } from 'react'; - -import { planQuotaItemOrder } from '@/consts/plan-quotas'; -import { - type SubscriptionPlanQuotaEntries, - type SubscriptionPlanQuota, -} from '@/types/subscriptions'; -import { sortBy } from '@/utils/sort'; - -import * as styles from './index.module.scss'; - -type Props = { - entries: SubscriptionPlanQuotaEntries; - itemRenderer: ( - quotaKey: keyof SubscriptionPlanQuota, - quotaValue: SubscriptionPlanQuota[keyof SubscriptionPlanQuota] - ) => ReactNode; - className?: string; -}; - -function PlanQuotaList({ entries, itemRenderer, className }: Props) { - const sortedEntries = useMemo( - () => - entries - .slice() - .sort(([preQuotaKey], [nextQuotaKey]) => - sortBy(planQuotaItemOrder)(preQuotaKey, nextQuotaKey) - ), - [entries] - ); - - return ( - - ); -} - -export default PlanQuotaList; diff --git a/packages/console/src/consts/plan-quotas.ts b/packages/console/src/consts/plan-quotas.ts index 28a2af47c..2346a3f20 100644 --- a/packages/console/src/consts/plan-quotas.ts +++ b/packages/console/src/consts/plan-quotas.ts @@ -1,75 +1,40 @@ import { ReservedPlanId } from '@logto/schemas'; -import { - type SubscriptionPlanTableGroupKeyMap, - SubscriptionPlanTableGroupKey, - type SubscriptionPlanQuota, -} from '@/types/subscriptions'; +import { type SubscriptionPlanQuota } from '@/types/subscriptions'; -type EnabledFeatureMap = Record; - -export const communitySupportEnabledMap: EnabledFeatureMap = { - [ReservedPlanId.Free]: true, - [ReservedPlanId.Hobby]: true, - [ReservedPlanId.Pro]: true, -}; - -export const ticketSupportResponseTimeMap: Record = { +/** + * Manually add this support quota item to the plan since it will be compared in the downgrade plan notification modal. + */ +export const ticketSupportResponseTimeMap: Record = { [ReservedPlanId.Free]: 0, [ReservedPlanId.Hobby]: 48, [ReservedPlanId.Pro]: 48, }; -const planTableGroupKeyMap: SubscriptionPlanTableGroupKeyMap = Object.freeze({ - [SubscriptionPlanTableGroupKey.base]: ['basePrice', 'mauLimit', 'tokenLimit'], - [SubscriptionPlanTableGroupKey.applications]: [ - 'applicationsLimit', - 'machineToMachineLimit', - 'thirdPartyApplicationsLimit', - ], - [SubscriptionPlanTableGroupKey.resources]: ['resourcesLimit', 'scopesPerResourceLimit'], - [SubscriptionPlanTableGroupKey.branding]: [ - 'customDomainEnabled', - 'customCssEnabled', - 'appLogoAndFaviconEnabled', - 'darkModeEnabled', - 'i18nEnabled', - ], - [SubscriptionPlanTableGroupKey.userAuthentication]: [ - 'omniSignInEnabled', - 'passwordSignInEnabled', - 'passwordlessSignInEnabled', - 'emailConnectorsEnabled', - 'smsConnectorsEnabled', - 'socialConnectorsLimit', - 'mfaEnabled', - 'ssoEnabled', - ], - [SubscriptionPlanTableGroupKey.roles]: [ - 'userManagementEnabled', - 'rolesLimit', - 'machineToMachineRolesLimit', - 'scopesPerRoleLimit', - ], - [SubscriptionPlanTableGroupKey.organizations]: [ - 'organizationsEnabled', - 'allowedUsersPerOrganization', - 'invitationEnabled', - 'orgRolesLimit', - 'orgPermissionsLimit', - 'justInTimeProvisioningEnabled', - ], - [SubscriptionPlanTableGroupKey.auditLogs]: ['auditLogsRetentionDays'], - [SubscriptionPlanTableGroupKey.hooks]: ['hooksLimit'], - [SubscriptionPlanTableGroupKey.support]: [ - 'communitySupportEnabled', - 'ticketSupportResponseTime', - 'soc2ReportEnabled', - 'hipaaOrBaaReportEnabled', - ], -}) satisfies SubscriptionPlanTableGroupKeyMap; - -export const planQuotaItemOrder = Object.values(planTableGroupKeyMap).flat(); +/** + * Define the order of quota items in the downgrade plan notification modal and not eligible for downgrade plan modal. + */ +export const planQuotaItemOrder: Array = [ + 'mauLimit', + 'tokenLimit', + 'applicationsLimit', + 'machineToMachineLimit', + 'thirdPartyApplicationsLimit', + 'resourcesLimit', + 'scopesPerResourceLimit', + 'customDomainEnabled', + 'omniSignInEnabled', + 'socialConnectorsLimit', + 'mfaEnabled', + 'ssoEnabled', + 'rolesLimit', + 'machineToMachineRolesLimit', + 'scopesPerRoleLimit', + 'organizationsEnabled', + 'auditLogsRetentionDays', + 'hooksLimit', + 'ticketSupportResponseTime', +]; /** * Unreleased quota keys will be added here, and it will effect the following: diff --git a/packages/console/src/consts/quota-item-phrases.ts b/packages/console/src/consts/quota-item-phrases.ts index 2a1967090..41ae37a20 100644 --- a/packages/console/src/consts/quota-item-phrases.ts +++ b/packages/console/src/consts/quota-item-phrases.ts @@ -22,7 +22,6 @@ export const quotaItemPhrasesMap: Record< scopesPerRoleLimit: 'scopes_per_role_limit.name', hooksLimit: 'hooks_limit.name', auditLogsRetentionDays: 'audit_logs_retention_days.name', - communitySupportEnabled: 'community_support_enabled.name', ticketSupportResponseTime: 'email_ticket_support.name', mfaEnabled: 'mfa_enabled.name', organizationsEnabled: 'organizations_enabled.name', @@ -49,7 +48,6 @@ export const quotaItemUnlimitedPhrasesMap: Record< scopesPerRoleLimit: 'scopes_per_role_limit.unlimited', hooksLimit: 'hooks_limit.unlimited', auditLogsRetentionDays: 'audit_logs_retention_days.unlimited', - communitySupportEnabled: 'community_support_enabled.unlimited', ticketSupportResponseTime: 'email_ticket_support.unlimited', mfaEnabled: 'mfa_enabled.unlimited', organizationsEnabled: 'organizations_enabled.unlimited', @@ -76,7 +74,6 @@ export const quotaItemLimitedPhrasesMap: Record< scopesPerRoleLimit: 'scopes_per_role_limit.limited', hooksLimit: 'hooks_limit.limited', auditLogsRetentionDays: 'audit_logs_retention_days.limited', - communitySupportEnabled: 'community_support_enabled.limited', ticketSupportResponseTime: 'email_ticket_support.limited', mfaEnabled: 'mfa_enabled.limited', organizationsEnabled: 'organizations_enabled.limited', @@ -103,18 +100,8 @@ export const quotaItemNotEligiblePhrasesMap: Record< scopesPerRoleLimit: 'scopes_per_role_limit.not_eligible', hooksLimit: 'hooks_limit.not_eligible', auditLogsRetentionDays: 'audit_logs_retention_days.not_eligible', - communitySupportEnabled: 'community_support_enabled.not_eligible', ticketSupportResponseTime: 'email_ticket_support.not_eligible', mfaEnabled: 'mfa_enabled.not_eligible', organizationsEnabled: 'organizations_enabled.not_eligible', ssoEnabled: 'sso_enabled.not_eligible', }; - -export const quotaItemAddOnPhrasesMap: Partial< - Record< - keyof SubscriptionPlanQuota, - TFuncKey<'translation', 'admin_console.subscription.quota_item'> - > -> = { - machineToMachineLimit: 'machine_to_machine_limit.add_on', -}; diff --git a/packages/console/src/consts/tenants.ts b/packages/console/src/consts/tenants.ts index fb85838c1..fc54f4c98 100644 --- a/packages/console/src/consts/tenants.ts +++ b/packages/console/src/consts/tenants.ts @@ -64,7 +64,6 @@ export const defaultSubscriptionPlan: SubscriptionPlan = { hooksLimit: null, organizationsEnabled: true, ssoEnabled: true, - communitySupportEnabled: true, ticketSupportResponseTime: 48, thirdPartyApplicationsLimit: null, }, diff --git a/packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/DiffQuotaItem/index.module.scss b/packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/DiffQuotaItem/index.module.scss deleted file mode 100644 index a5f8a27c0..000000000 --- a/packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/DiffQuotaItem/index.module.scss +++ /dev/null @@ -1,12 +0,0 @@ -.icon { - width: 16px; - height: 16px; - - &.notCapable { - color: var(--color-error); - } -} - -.lineThrough { - text-decoration: line-through; -} diff --git a/packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/DiffQuotaItem/index.tsx b/packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/DiffQuotaItem/index.tsx deleted file mode 100644 index 508ad9a65..000000000 --- a/packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/DiffQuotaItem/index.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { cond } from '@silverhand/essentials'; -import classNames from 'classnames'; - -import DescendArrow from '@/assets/icons/descend-arrow.svg'; -import Failed from '@/assets/icons/failed.svg'; -import QuotaListItem from '@/components/PlanQuotaList/QuotaListItem'; -import { type SubscriptionPlanQuota } from '@/types/subscriptions'; - -import * as styles from './index.module.scss'; - -type Props = { - quotaKey: keyof SubscriptionPlanQuota; - quotaValue: SubscriptionPlanQuota[keyof SubscriptionPlanQuota]; - isForDowngradeTargetPlan?: boolean; -}; - -function DiffQuotaItem({ quotaKey, quotaValue, isForDowngradeTargetPlan }: Props) { - const isNotCapable = quotaValue === 0 || quotaValue === false; - const DowngradeStatusIcon = isNotCapable ? Failed : DescendArrow; - - return ( - - ) - )} - phraseClassName={cond(isNotCapable && styles.lineThrough)} - /> - ); -} - -export default DiffQuotaItem; diff --git a/packages/console/src/components/PlanQuotaList/QuotaListItem/QuotaItemPhrase.tsx b/packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/PlanQuotaList/DiffQuotaItem/QuotaItemPhrase.tsx similarity index 78% rename from packages/console/src/components/PlanQuotaList/QuotaListItem/QuotaItemPhrase.tsx rename to packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/PlanQuotaList/DiffQuotaItem/QuotaItemPhrase.tsx index d51024c72..4feeab73b 100644 --- a/packages/console/src/components/PlanQuotaList/QuotaListItem/QuotaItemPhrase.tsx +++ b/packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/PlanQuotaList/DiffQuotaItem/QuotaItemPhrase.tsx @@ -4,7 +4,6 @@ import { quotaItemUnlimitedPhrasesMap, quotaItemPhrasesMap, quotaItemLimitedPhrasesMap, - quotaItemAddOnPhrasesMap, } from '@/consts/quota-item-phrases'; import DynamicT from '@/ds-components/DynamicT'; import { type SubscriptionPlanQuota } from '@/types/subscriptions'; @@ -14,21 +13,17 @@ const quotaItemPhraseKeyPrefix = 'subscription.quota_item'; type Props = { quotaKey: keyof SubscriptionPlanQuota; quotaValue: SubscriptionPlanQuota[keyof SubscriptionPlanQuota]; - isAddOn?: boolean; }; -function QuotaItemPhrase({ quotaKey, quotaValue, isAddOn = false }: Props) { +function QuotaItemPhrase({ quotaKey, quotaValue }: Props) { const isUnlimited = quotaValue === null; const isNotCapable = quotaValue === 0 || quotaValue === false; const isLimited = Boolean(quotaValue); - const limitedPhraseKey = - cond(isAddOn && quotaItemAddOnPhrasesMap[quotaKey]) ?? quotaItemLimitedPhrasesMap[quotaKey]; - const phraseKey = cond(isUnlimited && quotaItemUnlimitedPhrasesMap[quotaKey]) ?? cond(isNotCapable && quotaItemPhrasesMap[quotaKey]) ?? - cond(isLimited && limitedPhraseKey); + cond(isLimited && quotaItemLimitedPhrasesMap[quotaKey]); if (!phraseKey) { // Should not happen diff --git a/packages/console/src/components/PlanQuotaList/QuotaListItem/index.module.scss b/packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/PlanQuotaList/DiffQuotaItem/index.module.scss similarity index 69% rename from packages/console/src/components/PlanQuotaList/QuotaListItem/index.module.scss rename to packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/PlanQuotaList/DiffQuotaItem/index.module.scss index 674629374..49eed8c32 100644 --- a/packages/console/src/components/PlanQuotaList/QuotaListItem/index.module.scss +++ b/packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/PlanQuotaList/DiffQuotaItem/index.module.scss @@ -11,6 +11,19 @@ gap: _.unit(2); } + .icon { + width: 16px; + height: 16px; + + &.notCapable { + color: var(--color-error); + } + } + + .lineThrough { + text-decoration: line-through; + } + &.withIcon { list-style-type: none; // Unset a margin to the left for the list item marker diff --git a/packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/PlanQuotaList/DiffQuotaItem/index.tsx b/packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/PlanQuotaList/DiffQuotaItem/index.tsx new file mode 100644 index 000000000..2965a74ec --- /dev/null +++ b/packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/PlanQuotaList/DiffQuotaItem/index.tsx @@ -0,0 +1,43 @@ +import { cond } from '@silverhand/essentials'; +import classNames from 'classnames'; + +import DescendArrow from '@/assets/icons/descend-arrow.svg'; +import Failed from '@/assets/icons/failed.svg'; +import { type SubscriptionPlanQuota } from '@/types/subscriptions'; + +import QuotaItemPhrase from './QuotaItemPhrase'; +import * as styles from './index.module.scss'; + +type Props = { + quotaKey: keyof SubscriptionPlanQuota; + quotaValue: SubscriptionPlanQuota[keyof SubscriptionPlanQuota]; + hasStatusIcon?: boolean; +}; + +function DiffQuotaItem({ quotaKey, quotaValue, hasStatusIcon }: Props) { + const isNotCapable = quotaValue === 0 || quotaValue === false; + const DowngradeStatusIcon = isNotCapable ? Failed : DescendArrow; + + return ( +
  • + {/** + * Add a `span` as a wrapper to apply the flex layout to the content. + * If we apply the flex layout to the `li` directly, the `li` circle bullet will disappear. + */} + + {cond( + hasStatusIcon && ( + + ) + )} + + + + +
  • + ); +} + +export default DiffQuotaItem; diff --git a/packages/console/src/components/PlanQuotaList/index.module.scss b/packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/PlanQuotaList/index.module.scss similarity index 100% rename from packages/console/src/components/PlanQuotaList/index.module.scss rename to packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/PlanQuotaList/index.module.scss diff --git a/packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/PlanQuotaList/index.tsx b/packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/PlanQuotaList/index.tsx new file mode 100644 index 000000000..1a415482a --- /dev/null +++ b/packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/PlanQuotaList/index.tsx @@ -0,0 +1,29 @@ +import classNames from 'classnames'; + +import { type SubscriptionPlanQuotaEntries } from '@/types/subscriptions'; + +import DiffQuotaItem from './DiffQuotaItem'; +import * as styles from './index.module.scss'; + +type Props = { + entries: SubscriptionPlanQuotaEntries; + isDowngradeTargetPlan: boolean; + className?: string; +}; + +function PlanQuotaList({ entries, isDowngradeTargetPlan, className }: Props) { + return ( +
      + {entries.map(([quotaKey, quotaValue]) => ( + + ))} +
    + ); +} + +export default PlanQuotaList; diff --git a/packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/index.tsx b/packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/index.tsx index f7dac01e7..3cf65dfea 100644 --- a/packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/index.tsx +++ b/packages/console/src/pages/TenantSettings/Subscription/DowngradeConfirmModalContent/PlanQuotaDiffCard/index.tsx @@ -1,14 +1,16 @@ +import { useMemo } from 'react'; import { Trans } from 'react-i18next'; import PlanName from '@/components/PlanName'; -import PlanQuotaList from '@/components/PlanQuotaList'; +import { planQuotaItemOrder } from '@/consts/plan-quotas'; import DynamicT from '@/ds-components/DynamicT'; import { type SubscriptionPlanQuotaEntries, type SubscriptionPlanQuota, } from '@/types/subscriptions'; +import { sortBy } from '@/utils/sort'; -import DiffQuotaItem from './DiffQuotaItem'; +import PlanQuotaList from './PlanQuotaList'; import * as styles from './index.module.scss'; type Props = { @@ -18,6 +20,17 @@ type Props = { }; function PlanQuotaDiffCard({ planName, quotaDiff, isDowngradeTargetPlan = false }: Props) { + // eslint-disable-next-line no-restricted-syntax + const sortedEntries = useMemo( + () => + Object.entries(quotaDiff) + .slice() + .sort(([preQuotaKey], [nextQuotaKey]) => + sortBy(planQuotaItemOrder)(preQuotaKey, nextQuotaKey) + ), + [quotaDiff] + ) as SubscriptionPlanQuotaEntries; + return (
    @@ -31,20 +44,7 @@ function PlanQuotaDiffCard({ planName, quotaDiff, isDowngradeTargetPlan = false />
    - ( - - )} - /> +
    ); } diff --git a/packages/console/src/pages/TenantSettings/components/NotEligibleSwitchPlanModalContent/index.tsx b/packages/console/src/pages/TenantSettings/components/NotEligibleSwitchPlanModalContent/index.tsx index c001d47b3..275ffa386 100644 --- a/packages/console/src/pages/TenantSettings/components/NotEligibleSwitchPlanModalContent/index.tsx +++ b/packages/console/src/pages/TenantSettings/components/NotEligibleSwitchPlanModalContent/index.tsx @@ -22,7 +22,6 @@ import * as styles from './index.module.scss'; const excludedQuotaKeys = new Set([ 'auditLogsRetentionDays', - 'communitySupportEnabled', 'ticketSupportResponseTime', ]); diff --git a/packages/console/src/types/subscriptions.ts b/packages/console/src/types/subscriptions.ts index a8d76577b..daf3db0c8 100644 --- a/packages/console/src/types/subscriptions.ts +++ b/packages/console/src/types/subscriptions.ts @@ -1,4 +1,3 @@ -import { type Nullable } from '@silverhand/essentials'; import { z } from 'zod'; import { type InvoicesResponse, type SubscriptionPlanResponse } from '@/cloud/types/router'; @@ -14,8 +13,7 @@ export type SubscriptionPlanQuota = Omit< SubscriptionPlanResponse['quota'], 'builtInEmailConnectorEnabled' > & { - // Support - communitySupportEnabled: boolean; + // Add ticket support quota item to the plan since it will be compared in the downgrade plan notification modal. ticketSupportResponseTime: number; }; @@ -27,51 +25,6 @@ export type SubscriptionPlan = Omit & { quota: SubscriptionPlanQuota; }; -type SubscriptionPlanTable = Partial< - SubscriptionPlanQuota & { - // Base quota - basePrice: string; - // UI and branding - customCssEnabled: boolean; - appLogoAndFaviconEnabled: boolean; - darkModeEnabled: boolean; - i18nEnabled: boolean; - // User authn - passwordSignInEnabled: boolean; - passwordlessSignInEnabled: boolean; - emailConnectorsEnabled: boolean; - smsConnectorsEnabled: boolean; - // User management - userManagementEnabled: boolean; - // Organization - allowedUsersPerOrganization: Nullable; - invitationEnabled: boolean; - orgRolesLimit: Nullable; - orgPermissionsLimit: Nullable; - justInTimeProvisioningEnabled: boolean; - // Support - soc2ReportEnabled: boolean; - hipaaOrBaaReportEnabled: boolean; - } ->; - -export enum SubscriptionPlanTableGroupKey { - base = 'base', - applications = 'applications', - resources = 'resources', - branding = 'branding', - userAuthentication = 'userAuthentication', - roles = 'roles', - auditLogs = 'auditLogs', - hooks = 'hooks', - organizations = 'organizations', - support = 'support', -} - -export type SubscriptionPlanTableGroupKeyMap = { - [key in SubscriptionPlanTableGroupKey]: Array>; -}; - export const localCheckoutSessionGuard = z.object({ state: z.string(), sessionId: z.string(), diff --git a/packages/console/src/utils/subscription.ts b/packages/console/src/utils/subscription.ts index a34401927..8213a6821 100644 --- a/packages/console/src/utils/subscription.ts +++ b/packages/console/src/utils/subscription.ts @@ -4,7 +4,7 @@ import dayjs from 'dayjs'; import { tryReadResponseErrorBody } from '@/cloud/hooks/use-cloud-api'; import { type SubscriptionPlanResponse } from '@/cloud/types/router'; -import { communitySupportEnabledMap, ticketSupportResponseTimeMap } from '@/consts/plan-quotas'; +import { ticketSupportResponseTimeMap } from '@/consts/plan-quotas'; import { featuredPlanIdOrder, featuredPlanIds } from '@/consts/subscriptions'; import { type SubscriptionPlanQuota, type SubscriptionPlan } from '@/types/subscriptions'; @@ -15,7 +15,9 @@ export const addSupportQuotaToPlan = (subscriptionPlanResponse: SubscriptionPlan ...subscriptionPlanResponse, quota: { ...quota, - communitySupportEnabled: communitySupportEnabledMap[id] ?? false, // Fallback to not supported + /** + * Manually add this support quota item to the plan since it will be compared in the downgrade plan notification modal. + */ ticketSupportResponseTime: ticketSupportResponseTimeMap[id] ?? 0, // Fallback to not supported }, }; diff --git a/packages/phrases/src/locales/de/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/de/translation/admin-console/subscription/quota-item.ts index 3f62ddda2..ebd9f56a3 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/subscription/quota-item.ts @@ -32,7 +32,6 @@ const quota_item = { limited_other: '{{count, number}} Maschine-zu-Maschine-Apps', unlimited: 'Unbegrenzte Maschine-zu-Maschine-Apps', not_eligible: 'Entferne deine Maschine-zu-Maschine-Apps', - add_on: 'Zusätzliche Maschine-zu-Maschine-Apps', }, third_party_applications_limit: { /** UNTRANSLATED */ @@ -133,12 +132,6 @@ const quota_item = { unlimited: 'Unbegrenzte Tage', not_eligible: 'Keine Audit-Logs', }, - community_support_enabled: { - name: 'Community-Support', - limited: 'Community-Support', - unlimited: 'Community-Support', - not_eligible: 'Kein Community-Support', - }, email_ticket_support: { name: 'E-Mail-Ticket-Support', limited: '{{count, number}} Stunde E-Mail-Ticket-Support', diff --git a/packages/phrases/src/locales/en/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/en/translation/admin-console/subscription/quota-item.ts index 5dbb0d187..fdb8ec8f9 100644 --- a/packages/phrases/src/locales/en/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/en/translation/admin-console/subscription/quota-item.ts @@ -32,7 +32,6 @@ const quota_item = { limited_other: '{{count, number}} machine to machine apps', unlimited: 'Unlimited machine to machine apps', not_eligible: 'Remove your machine to machine apps', - add_on: 'Additional machine-to-machine apps', }, third_party_applications_limit: { name: 'Third-party apps', @@ -128,12 +127,6 @@ const quota_item = { unlimited: 'Unlimited days', not_eligible: 'No audit logs', }, - community_support_enabled: { - name: 'Community support', - limited: 'Community support', - unlimited: 'Community support', - not_eligible: 'No community support', - }, email_ticket_support: { name: 'Email ticket support', limited: '{{count, number}} hour email ticket support', diff --git a/packages/phrases/src/locales/es/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/es/translation/admin-console/subscription/quota-item.ts index f9cc0777d..cd042c6be 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/subscription/quota-item.ts @@ -32,7 +32,6 @@ const quota_item = { limited_other: '{{count, number}} aplicaciones de dispositivo a dispositivo', unlimited: 'Aplicaciones de dispositivo a dispositivo ilimitadas', not_eligible: 'Elimine sus aplicaciones de dispositivo a dispositivo', - add_on: 'Aplicaciones de máquina a máquina adicionales', }, third_party_applications_limit: { /** UNTRANSLATED */ @@ -133,12 +132,6 @@ const quota_item = { unlimited: 'Días ilimitados', not_eligible: 'Sin registros de auditoría', }, - community_support_enabled: { - name: 'Soporte de la comunidad', - limited: 'Soporte de la comunidad', - unlimited: 'Soporte de la comunidad', - not_eligible: 'Sin soporte de la comunidad', - }, email_ticket_support: { name: 'Soporte de boletos de correo electrónico', limited: '{{count, number}} hora de soporte de boletos de correo electrónico', diff --git a/packages/phrases/src/locales/fr/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/fr/translation/admin-console/subscription/quota-item.ts index 1716b7b97..4ad1a291e 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/subscription/quota-item.ts @@ -32,7 +32,6 @@ const quota_item = { limited_other: '{{count, number}} applications machine à machine', unlimited: 'Illimité applications machine à machine', not_eligible: 'Supprimez vos applications machine à machine', - add_on: 'Applications machine à machine supplémentaires', }, third_party_applications_limit: { /** UNTRANSLATED */ @@ -133,12 +132,6 @@ const quota_item = { unlimited: 'Jours illimités', not_eligible: "Pas de journalisation d'audit", }, - community_support_enabled: { - name: 'Support de la communauté', - limited: 'Support de la communauté', - unlimited: 'Support de la communauté', - not_eligible: 'Pas de support de la communauté', - }, email_ticket_support: { name: 'Assistance par ticket de messagerie électronique', limited: "{{count, number}} heure d'assistance par ticket de messagerie électronique", diff --git a/packages/phrases/src/locales/it/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/it/translation/admin-console/subscription/quota-item.ts index 9e74d24a2..876cc0004 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/subscription/quota-item.ts @@ -32,7 +32,6 @@ const quota_item = { limited_other: '{{count, number}} applicazioni Machine-to-Machine', unlimited: 'Applicazioni Machine-to-Machine illimitate', not_eligible: 'Rimuovi le tue applicazioni Machine-to-Machine', - add_on: 'Applicazioni Machine-to-Machine aggiuntive', }, third_party_applications_limit: { /** UNTRANSLATED */ @@ -133,12 +132,6 @@ const quota_item = { unlimited: 'Giorni illimitati', not_eligible: 'Nessun log di audit', }, - community_support_enabled: { - name: 'Supporto della comunità', - limited: 'Supporto della comunità', - unlimited: 'Supporto della comunità', - not_eligible: 'Nessun supporto della comunità', - }, email_ticket_support: { name: 'Supporto tramite ticket email', limited: '{{count, number}} ora di supporto tramite ticket email', diff --git a/packages/phrases/src/locales/ja/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/ja/translation/admin-console/subscription/quota-item.ts index 2e4eb66bf..a96ce4659 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/subscription/quota-item.ts @@ -32,7 +32,6 @@ const quota_item = { limited_other: '{{count, number}} マシン間アプリケーション', unlimited: '無制限のマシン間アプリケーション', not_eligible: 'マシン間アプリケーションを削除してください', - add_on: '追加のマシン間アプリケーション', }, third_party_applications_limit: { /** UNTRANSLATED */ @@ -133,12 +132,6 @@ const quota_item = { unlimited: '無制限の日数', not_eligible: '監査ログがありません', }, - community_support_enabled: { - name: 'コミュニティサポート', - limited: 'コミュニティサポート', - unlimited: 'コミュニティサポート', - not_eligible: 'コミュニティサポートなし', - }, email_ticket_support: { name: 'メールチケットサポート', limited: '{{count, number}}時間のメールチケットサポート', diff --git a/packages/phrases/src/locales/ko/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/ko/translation/admin-console/subscription/quota-item.ts index 3009f98e3..b6dbd2316 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/subscription/quota-item.ts @@ -32,7 +32,6 @@ const quota_item = { limited_other: '{{count, number}} 기계 간 앱', unlimited: '제한 없는 기계 간 앱', not_eligible: '기계 간 앱을 제거하십시오', - add_on: '추가 기계간 앱', }, third_party_applications_limit: { /** UNTRANSLATED */ @@ -133,12 +132,6 @@ const quota_item = { unlimited: '제한 없는 기간', not_eligible: '감사 로그 없음', }, - community_support_enabled: { - name: '커뮤니티 지원', - limited: '커뮤니티 지원', - unlimited: '커뮤니티 지원', - not_eligible: '커뮤니티 지원 없음', - }, email_ticket_support: { name: '이메일 지원 티켓', limited: '{{count, number}}시간 이메일 지원 티켓', diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/subscription/quota-item.ts index 57dcf5645..ea626d312 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/subscription/quota-item.ts @@ -32,7 +32,6 @@ const quota_item = { limited_other: '{{count, number}} aplikacje machine to machine', unlimited: 'Nieograniczona liczba aplikacji machine to machine', not_eligible: 'Usuń swoje aplikacje machine to machine', - add_on: 'Dodatkowe aplikacje machine-to-machine', }, third_party_applications_limit: { /** UNTRANSLATED */ @@ -133,12 +132,6 @@ const quota_item = { unlimited: 'Nieograniczona liczba dni', not_eligible: 'Brak dzienników audytowych', }, - community_support_enabled: { - name: 'Wsparcie społeczności', - limited: 'Wsparcie społeczności', - unlimited: 'Wsparcie społeczności', - not_eligible: 'Brak wsparcia społecznościowego', - }, email_ticket_support: { name: 'Wsparcie poprzez e-maile', limited: '{{count, number}} godzina wsparcia poprzez e-maile', diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/subscription/quota-item.ts index 2a93d3d59..7a52b4cbf 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/subscription/quota-item.ts @@ -32,7 +32,6 @@ const quota_item = { limited_other: '{{count, number}} aplicações de máquina a máquina', unlimited: 'Aplicações de máquina a máquina ilimitadas', not_eligible: 'Remova suas aplicações de máquina a máquina', - add_on: 'Aplicativos adicionais de máquina a máquina', }, third_party_applications_limit: { /** UNTRANSLATED */ @@ -133,12 +132,6 @@ const quota_item = { unlimited: 'Dias ilimitados', not_eligible: 'Nenhum registro de auditoria', }, - community_support_enabled: { - name: 'Suporte da comunidade', - limited: 'Suporte da comunidade', - unlimited: 'Suporte da comunidade', - not_eligible: 'Nenhum suporte da comunidade', - }, email_ticket_support: { name: 'Suporte de ingressos de e-mail', limited: '{{count, number}} hora de suporte de ingressos de e-mail', diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/subscription/quota-item.ts index 2b5f135c9..b28ca6470 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/subscription/quota-item.ts @@ -32,7 +32,6 @@ const quota_item = { limited_other: '{{count, number}} aplicações de máquina para máquina', unlimited: 'Aplicações de máquina para máquina ilimitadas', not_eligible: 'Remover as tuas aplicações de máquina para máquina', - add_on: 'Aplicações adicionais de máquina para máquina', }, third_party_applications_limit: { /** UNTRANSLATED */ @@ -133,12 +132,6 @@ const quota_item = { unlimited: 'Dias ilimitados', not_eligible: 'Sem registos de auditoria', }, - community_support_enabled: { - name: 'Apoio da comunidade', - limited: 'Apoio da comunidade', - unlimited: 'Apoio da comunidade', - not_eligible: 'Sem apoio da comunidade', - }, email_ticket_support: { name: 'Suporte por e-mail', limited: '{{count, number}} horas de suporte por e-mail', diff --git a/packages/phrases/src/locales/ru/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/ru/translation/admin-console/subscription/quota-item.ts index d79b0f2b7..615cfcb79 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/subscription/quota-item.ts @@ -32,7 +32,6 @@ const quota_item = { limited_other: '{{count, number}} приложения для машин ко машине', unlimited: 'Неограниченное количество приложений для машин ко машине', not_eligible: 'Удалите свои приложения для машин ко машине', - add_on: 'Дополнительные приложения для машины ко машине', }, third_party_applications_limit: { /** UNTRANSLATED */ @@ -133,12 +132,6 @@ const quota_item = { unlimited: 'Неограниченное количество дней', not_eligible: 'Без аудит-логов', }, - community_support_enabled: { - name: 'Поддержка сообщества', - limited: 'Поддержка сообщества', - unlimited: 'Поддержка сообщества', - not_eligible: 'Без поддержки сообщества', - }, email_ticket_support: { name: 'Поддержка по электронной почте', limited: '{{count, number}} час поддержки по электронной почте', diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/subscription/quota-item.ts index 40233e20e..b15bad262 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/subscription/quota-item.ts @@ -32,7 +32,6 @@ const quota_item = { limited_other: '{{count, number}} makineye makine uygulamalar', unlimited: 'Sınırsız makineye makine uygulamalar', not_eligible: 'Makineye makine uygulamalarınızı kaldırın', - add_on: 'Ek makineye makine uygulamaları', }, third_party_applications_limit: { /** UNTRANSLATED */ @@ -133,12 +132,6 @@ const quota_item = { unlimited: 'Sınırsız günler', not_eligible: 'Denetim günlüğünüz yok', }, - community_support_enabled: { - name: 'Topluluk desteği', - limited: 'Topluluk desteği', - unlimited: 'Topluluk desteği', - not_eligible: 'Topluluk desteği yok', - }, email_ticket_support: { name: 'E-posta bilet desteği', limited: '{{count, number}} saat e-posta bilet desteği', diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/subscription/quota-item.ts index 12fbcc93c..17e34b74f 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/subscription/quota-item.ts @@ -32,7 +32,6 @@ const quota_item = { limited_other: '{{count, number}} 个机器到机器应用', unlimited: '无限制机器到机器应用', not_eligible: '移除你的机器到机器应用', - add_on: '更多机器到机器应用', }, third_party_applications_limit: { /** UNTRANSLATED */ @@ -133,12 +132,6 @@ const quota_item = { unlimited: '无限制天数', not_eligible: '无审计日志', }, - community_support_enabled: { - name: '社区支持', - limited: '社区支持', - unlimited: '社区支持', - not_eligible: '无社区支持', - }, email_ticket_support: { name: '电子邮件支持', limited: '{{count, number}} 小时电子邮件支持', diff --git a/packages/phrases/src/locales/zh-hk/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/zh-hk/translation/admin-console/subscription/quota-item.ts index b799ed351..cdd6e43ca 100644 --- a/packages/phrases/src/locales/zh-hk/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/zh-hk/translation/admin-console/subscription/quota-item.ts @@ -32,7 +32,6 @@ const quota_item = { limited_other: '{{count, number}} 個機器對機器應用程式', unlimited: '無限機器對機器應用程式', not_eligible: '刪除您的機器對機器應用程式', - add_on: '附加的機器對機器應用程式', }, third_party_applications_limit: { /** UNTRANSLATED */ @@ -133,12 +132,6 @@ const quota_item = { unlimited: '無限天數', not_eligible: '無審計日誌', }, - community_support_enabled: { - name: '社區支援', - limited: '社區支援', - unlimited: '社區支援', - not_eligible: '無社區支援', - }, email_ticket_support: { name: '電子郵件票務支援', limited: '{{count, number}} 小時電子郵件票務支援', diff --git a/packages/phrases/src/locales/zh-tw/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/zh-tw/translation/admin-console/subscription/quota-item.ts index 4a7877274..481df26ca 100644 --- a/packages/phrases/src/locales/zh-tw/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/zh-tw/translation/admin-console/subscription/quota-item.ts @@ -32,7 +32,6 @@ const quota_item = { limited_other: '{{count, number}} 機器對機器應用程式', unlimited: '不限機器對機器應用程式數', not_eligible: '移除你的機器對機器應用程式', - add_on: '額外的機器對機器應用程式', }, third_party_applications_limit: { /** UNTRANSLATED */ @@ -133,12 +132,6 @@ const quota_item = { unlimited: '不限天數', not_eligible: '無審計記錄', }, - community_support_enabled: { - name: '社群支援', - limited: '社群支援', - unlimited: '社群支援', - not_eligible: '無社群支援', - }, email_ticket_support: { name: '電子郵件票務支援', limited: '{{count, number}}小時的電子郵件票務支援',