0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-30 20:33:54 -05:00

refactor(console): sort quota list items (#4246)

This commit is contained in:
Xiao Yijun 2023-07-26 11:41:15 +08:00 committed by GitHub
parent 0aa00307cb
commit 5a1c9d3a7b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 29 deletions

View file

@ -1,7 +1,9 @@
import classNames from 'classnames';
import { useMemo } from 'react';
import { planQuotaItemOrder } from '@/consts/plan-quotas';
import { type SubscriptionPlanQuota } from '@/types/subscriptions';
import { sortBy } from '@/utils/sort';
import QuotaItem from './QuotaItem';
import * as styles from './index.module.scss';
@ -16,7 +18,6 @@ type Props = {
function PlanQuotaList({ quota, featuredQuotaKeys, isDiff, hasIcon, className }: Props) {
const items = useMemo(() => {
// Todo: @xiaoyijun LOG-6540 order keys
// eslint-disable-next-line no-restricted-syntax
const entries = Object.entries(quota) as Array<
[keyof SubscriptionPlanQuota, SubscriptionPlanQuota[keyof SubscriptionPlanQuota]]
@ -26,7 +27,11 @@ function PlanQuotaList({ quota, featuredQuotaKeys, isDiff, hasIcon, className }:
? entries.filter(([key]) => featuredQuotaKeys.includes(key))
: entries;
return featuredEntries;
return featuredEntries
.slice()
.sort(([preQuotaKey], [nextQuotaKey]) =>
sortBy(planQuotaItemOrder)(preQuotaKey, nextQuotaKey)
);
}, [quota, featuredQuotaKeys]);
return (

View file

@ -149,3 +149,5 @@ export const planTableGroupKeyMap: SubscriptionPlanTableGroupKeyMap = Object.fre
[SubscriptionPlanTableGroupKey.hooks]: ['hooksLimit'],
[SubscriptionPlanTableGroupKey.support]: ['communitySupportEnabled', 'ticketSupportResponseTime'],
}) satisfies SubscriptionPlanTableGroupKeyMap;
export const planQuotaItemOrder = Object.values(planTableGroupKeyMap).flat();

View file

@ -7,6 +7,7 @@ import { type SubscriptionPlanResponse } from '@/cloud/types/router';
import { isCloud } from '@/consts/env';
import { reservedPlanIdOrder } from '@/consts/subscriptions';
import { type SubscriptionPlan } from '@/types/subscriptions';
import { sortBy } from '@/utils/sort';
import { addSupportQuotaToPlan } from '@/utils/subscription';
const useSubscriptionPlans = () => {
@ -26,28 +27,9 @@ const useSubscriptionPlans = () => {
return subscriptionPlansResponse
.map((plan) => addSupportQuotaToPlan(plan))
.slice()
.sort(({ id: previousId }, { id: nextId }) => {
const previousIndex = reservedPlanIdOrder.indexOf(previousId);
const nextIndex = reservedPlanIdOrder.indexOf(nextId);
if (previousIndex === -1 && nextIndex === -1) {
// Note: If both plan ids not present in `reservedPlanIdOrder`, sort them in default order
return 0;
}
if (previousIndex === -1) {
// Note: If only the previous plan has an id not present in `reservedPlanIdOrder`, move it to the end
return 1;
}
if (nextIndex === -1) {
// Note: If only the next plan has an id not present in `reservedPlanIdOrder`, move it to the end
return -1;
}
// Note: Compare them based on the index in the `reservedPlanIdOrder` array
return previousIndex - nextIndex;
});
.sort(({ id: previousId }, { id: nextId }) =>
sortBy(reservedPlanIdOrder)(previousId, nextId)
);
}, [subscriptionPlansResponse]);
return {

View file

@ -1,14 +1,17 @@
import { conditional } from '@silverhand/essentials';
import { useMemo } from 'react';
import { Trans, useTranslation } from 'react-i18next';
import ContactUsPhraseLink from '@/components/ContactUsPhraseLink';
import PlanName from '@/components/PlanName';
import { planQuotaItemOrder } from '@/consts/plan-quotas';
import {
quotaItemLimitedPhrasesMap,
quotaItemNotEligiblePhrasesMap,
} from '@/consts/quota-item-phrases';
import DynamicT from '@/ds-components/DynamicT';
import { type SubscriptionPlan, type SubscriptionPlanQuota } from '@/types/subscriptions';
import { sortBy } from '@/utils/sort';
import * as styles from './index.module.scss';
@ -30,10 +33,17 @@ function NotEligibleSwitchPlanModalContent({ targetPlan, isDowngrade = false }:
const { name, quota } = targetPlan;
// eslint-disable-next-line no-restricted-syntax
const entries = Object.entries(quota) as Array<
[keyof SubscriptionPlanQuota, SubscriptionPlanQuota[keyof SubscriptionPlanQuota]]
>;
const orderedEntries = useMemo(() => {
// eslint-disable-next-line no-restricted-syntax
const entries = Object.entries(quota) as Array<
[keyof SubscriptionPlanQuota, SubscriptionPlanQuota[keyof SubscriptionPlanQuota]]
>;
return entries
.slice()
.sort(([preQuotaKey], [nextQuotaKey]) =>
sortBy(planQuotaItemOrder)(preQuotaKey, nextQuotaKey)
);
}, [quota]);
return (
<div className={styles.container}>
@ -47,7 +57,7 @@ function NotEligibleSwitchPlanModalContent({ targetPlan, isDowngrade = false }:
</Trans>
</div>
<ul className={styles.list}>
{entries.map(([quotaKey, quotaValue]) => {
{orderedEntries.map(([quotaKey, quotaValue]) => {
if (
excludedQuotaKeys.has(quotaKey) ||
quotaValue === null || // Unlimited items

View file

@ -0,0 +1,23 @@
export const sortBy = (order: string[]) => {
return (previous: string, next: string) => {
const preIndex = order.indexOf(previous);
const nextIndex = order.indexOf(next);
// Note: If both plan ids not present in the order array, sort them in default order
if (preIndex === -1 && nextIndex === -1) {
return 0;
}
// Note: If only the previous item is not present in the order array, move it to the end
if (preIndex === -1) {
return 1;
}
// Note: If only the next item is not present in the order array, keep it in the end
if (nextIndex === -1) {
return -1;
}
// Note: Compare them based on the index in the order array
return preIndex - nextIndex;
};
};