mirror of
https://github.com/logto-io/logto.git
synced 2025-02-17 22:04:19 -05:00
feat(console): control console content by tenant env tag (#4830)
This commit is contained in:
parent
c65dcb9552
commit
65d8444988
12 changed files with 77 additions and 29 deletions
|
@ -155,7 +155,7 @@ function CreateConnectorForm({ onClose, isOpen: isFormOpen, type }: Props) {
|
|||
<>
|
||||
<div className={styles.standardLabel}>
|
||||
<DynamicT forKey="connectors.standard_connectors" />
|
||||
{isStandardConnectorDisabled && <ProTag />}
|
||||
<ProTag isVisibleInProdTenant={isStandardConnectorDisabled} />
|
||||
</div>
|
||||
<ConnectorRadioGroup
|
||||
name="group"
|
||||
|
|
|
@ -75,7 +75,9 @@ function GuideCard({ data, onClick, hasBorder, hasButton }: Props) {
|
|||
<div className={styles.infoWrapper}>
|
||||
<div className={styles.flexRow}>
|
||||
<div className={styles.name}>{name}</div>
|
||||
{isSubscriptionRequired && <ProTag />}
|
||||
{target === ApplicationType.MachineToMachine && (
|
||||
<ProTag isVisibleInProdTenant={isSubscriptionRequired} />
|
||||
)}
|
||||
</div>
|
||||
<div className={styles.description} title={description}>
|
||||
{description}
|
||||
|
|
|
@ -1,19 +1,25 @@
|
|||
import classNames from 'classnames';
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { isCloud, isDevFeaturesEnabled } from '@/consts/env';
|
||||
import { TenantsContext } from '@/contexts/TenantsProvider';
|
||||
import DynamicT from '@/ds-components/DynamicT';
|
||||
|
||||
import * as styles from './index.module.scss';
|
||||
|
||||
type Props = {
|
||||
isVisibleInProdTenant: boolean;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
function ProTag({ className }: Props) {
|
||||
return (
|
||||
function ProTag({ isVisibleInProdTenant, className }: Props) {
|
||||
const { isDevTenant } = useContext(TenantsContext);
|
||||
|
||||
return isCloud && ((isDevFeaturesEnabled && isDevTenant) || isVisibleInProdTenant) ? (
|
||||
<div className={classNames(styles.tag, className)}>
|
||||
<DynamicT forKey="upsell.pro_tag" />
|
||||
</div>
|
||||
);
|
||||
) : null;
|
||||
}
|
||||
|
||||
export default ProTag;
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
import { useContext } from 'react';
|
||||
|
||||
import MauExceededModal from '@/components/MauExceededModal';
|
||||
import PaymentOverdueModal from '@/components/PaymentOverdueModal';
|
||||
import { isCloud, isDevFeaturesEnabled } from '@/consts/env';
|
||||
import { TenantsContext } from '@/contexts/TenantsProvider';
|
||||
|
||||
function TenantNotificationContainer() {
|
||||
const { currentTenant, isDevTenant } = useContext(TenantsContext);
|
||||
const isTenantSuspended = currentTenant?.isSuspended;
|
||||
|
||||
// Todo @xiaoyijun remove isDevFeaturesEnabled when the dev tenant feature is ready
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
if (!isCloud || isTenantSuspended || (isDevFeaturesEnabled && isDevTenant)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<MauExceededModal />
|
||||
<PaymentOverdueModal />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default TenantNotificationContainer;
|
|
@ -3,8 +3,6 @@ import { useContext, useRef } from 'react';
|
|||
import { Navigate, Outlet, useParams } from 'react-router-dom';
|
||||
|
||||
import AppLoading from '@/components/AppLoading';
|
||||
import MauExceededModal from '@/components/MauExceededModal';
|
||||
import PaymentOverdueModal from '@/components/PaymentOverdueModal';
|
||||
import Topbar from '@/components/Topbar';
|
||||
import { isCloud } from '@/consts/env';
|
||||
import { TenantsContext } from '@/contexts/TenantsProvider';
|
||||
|
@ -14,6 +12,7 @@ import useUserPreferences from '@/hooks/use-user-preferences';
|
|||
import { getPath } from '../ConsoleContent/Sidebar';
|
||||
import { useSidebarMenuItems } from '../ConsoleContent/Sidebar/hook';
|
||||
|
||||
import TenantNotificationContainer from './TenantNotificationContainer';
|
||||
import TenantSuspendedPage from './TenantSuspendedPage';
|
||||
import * as styles from './index.module.scss';
|
||||
import { type AppContentOutletContext } from './types';
|
||||
|
@ -22,7 +21,6 @@ export default function AppContent() {
|
|||
const { isLoading } = useUserPreferences();
|
||||
const { currentTenant } = useContext(TenantsContext);
|
||||
const isTenantSuspended = isCloud && currentTenant?.isSuspended;
|
||||
const shouldCheckSubscriptionState = isCloud && !currentTenant?.isSuspended;
|
||||
|
||||
const scrollableContent = useRef<HTMLDivElement>(null);
|
||||
const { scrollTop } = useScroll(scrollableContent.current);
|
||||
|
@ -40,12 +38,7 @@ export default function AppContent() {
|
|||
<Outlet context={{ scrollableContent } satisfies AppContentOutletContext} />
|
||||
)}
|
||||
</div>
|
||||
{shouldCheckSubscriptionState && (
|
||||
<>
|
||||
<MauExceededModal />
|
||||
<PaymentOverdueModal />
|
||||
</>
|
||||
)}
|
||||
<TenantNotificationContainer />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { useContext } from 'react';
|
||||
import { Navigate, Route, Routes, useOutletContext } from 'react-router-dom';
|
||||
|
||||
import {
|
||||
|
@ -10,6 +11,7 @@ import {
|
|||
ApplicationDetailsTabs,
|
||||
} from '@/consts';
|
||||
import { isCloud, isDevFeaturesEnabled } from '@/consts/env';
|
||||
import { TenantsContext } from '@/contexts/TenantsProvider';
|
||||
import OverlayScrollbar from '@/ds-components/OverlayScrollbar';
|
||||
import useUserPreferences from '@/hooks/use-user-preferences';
|
||||
import ApiResourceDetails from '@/pages/ApiResourceDetails';
|
||||
|
@ -67,6 +69,7 @@ function ConsoleContent() {
|
|||
const {
|
||||
data: { getStartedHidden },
|
||||
} = useUserPreferences();
|
||||
const { isDevTenant } = useContext(TenantsContext);
|
||||
|
||||
return (
|
||||
<div className={styles.content}>
|
||||
|
@ -177,8 +180,12 @@ function ConsoleContent() {
|
|||
<Route index element={<Navigate replace to={TenantSettingsTabs.Settings} />} />
|
||||
<Route path={TenantSettingsTabs.Settings} element={<TenantBasicSettings />} />
|
||||
<Route path={TenantSettingsTabs.Domains} element={<TenantDomainSettings />} />
|
||||
<Route path={TenantSettingsTabs.Subscription} element={<Subscription />} />
|
||||
<Route path={TenantSettingsTabs.BillingHistory} element={<BillingHistory />} />
|
||||
{(!isDevFeaturesEnabled || !isDevTenant) && (
|
||||
<>
|
||||
<Route path={TenantSettingsTabs.Subscription} element={<Subscription />} />
|
||||
<Route path={TenantSettingsTabs.BillingHistory} element={<BillingHistory />} />
|
||||
</>
|
||||
)}
|
||||
</Route>
|
||||
)}
|
||||
</Routes>
|
||||
|
|
|
@ -101,7 +101,10 @@ function GuideLibrary({ className, hasCardBorder, hasCardButton, hasFilters }: P
|
|||
setFilterCategories(sortedValue);
|
||||
}}
|
||||
/>
|
||||
{isM2mDisabledForCurrentPlan && <ProTag className={styles.proTag} />}
|
||||
<ProTag
|
||||
className={styles.proTag}
|
||||
isVisibleInProdTenant={isM2mDisabledForCurrentPlan}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -31,7 +31,7 @@ function TypeDescription({
|
|||
<div className={styles.description}>{description}</div>
|
||||
{hasProTag && (
|
||||
<div className={styles.proTag}>
|
||||
<ProTag />
|
||||
<ProTag isVisibleInProdTenant />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { conditional } from '@silverhand/essentials';
|
||||
import { useContext, type ReactNode } from 'react';
|
||||
|
||||
import PageMeta from '@/components/PageMeta';
|
||||
|
@ -24,7 +23,7 @@ function PageWrapper({ children }: Props) {
|
|||
<PageMeta titleKey="mfa.title" />
|
||||
<CardTitle
|
||||
title="mfa.title"
|
||||
titleTag={conditional(!isMfaEnabled && <ProTag />)}
|
||||
titleTag={<ProTag isVisibleInProdTenant={!isMfaEnabled} />}
|
||||
subtitle="mfa.description"
|
||||
className={styles.cardTitle}
|
||||
/>
|
||||
|
|
|
@ -222,8 +222,12 @@ function CreateRoleForm({ totalRoleCount, onClose }: Props) {
|
|||
title={<DynamicT forKey={key} />}
|
||||
value={value}
|
||||
trailingIcon={
|
||||
proTagCheck &&
|
||||
isM2mDisabledForCurrentPlan && <ProTag className={styles.proTag} />
|
||||
proTagCheck && (
|
||||
<ProTag
|
||||
isVisibleInProdTenant={isM2mDisabledForCurrentPlan}
|
||||
className={styles.proTag}
|
||||
/>
|
||||
)
|
||||
}
|
||||
/>
|
||||
))}
|
||||
|
|
|
@ -47,7 +47,7 @@ function TenantDomainSettings() {
|
|||
<PageMeta titleKey={['tenants.tabs.domains', 'tenants.title']} />
|
||||
<FormCard
|
||||
title="domain.custom.custom_domain"
|
||||
tag={!customDomainEnabled && <ProTag />}
|
||||
tag={<ProTag isVisibleInProdTenant={!customDomainEnabled} />}
|
||||
description="domain.custom.custom_domain_description"
|
||||
learnMoreLink={getDocumentationUrl('docs/recipes/custom-domain')}
|
||||
>
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import { useContext } from 'react';
|
||||
import { Outlet } from 'react-router-dom';
|
||||
|
||||
import { TenantSettingsTabs } from '@/consts';
|
||||
import { isDevFeaturesEnabled } from '@/consts/env';
|
||||
import { TenantsContext } from '@/contexts/TenantsProvider';
|
||||
import CardTitle from '@/ds-components/CardTitle';
|
||||
import DynamicT from '@/ds-components/DynamicT';
|
||||
import TabNav, { TabNavItem } from '@/ds-components/TabNav';
|
||||
|
@ -8,6 +11,7 @@ import TabNav, { TabNavItem } from '@/ds-components/TabNav';
|
|||
import * as styles from './index.module.scss';
|
||||
|
||||
function TenantSettings() {
|
||||
const { isDevTenant } = useContext(TenantsContext);
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<CardTitle
|
||||
|
@ -22,12 +26,16 @@ function TenantSettings() {
|
|||
<TabNavItem href={`/tenant-settings/${TenantSettingsTabs.Domains}`}>
|
||||
<DynamicT forKey="tenants.tabs.domains" />
|
||||
</TabNavItem>
|
||||
<TabNavItem href={`/tenant-settings/${TenantSettingsTabs.Subscription}`}>
|
||||
<DynamicT forKey="tenants.tabs.subscription" />
|
||||
</TabNavItem>
|
||||
<TabNavItem href={`/tenant-settings/${TenantSettingsTabs.BillingHistory}`}>
|
||||
<DynamicT forKey="tenants.tabs.billing_history" />
|
||||
</TabNavItem>
|
||||
{(!isDevFeaturesEnabled || !isDevTenant) && (
|
||||
<>
|
||||
<TabNavItem href={`/tenant-settings/${TenantSettingsTabs.Subscription}`}>
|
||||
<DynamicT forKey="tenants.tabs.subscription" />
|
||||
</TabNavItem>
|
||||
<TabNavItem href={`/tenant-settings/${TenantSettingsTabs.BillingHistory}`}>
|
||||
<DynamicT forKey="tenants.tabs.billing_history" />
|
||||
</TabNavItem>
|
||||
</>
|
||||
)}
|
||||
</TabNav>
|
||||
<Outlet />
|
||||
</div>
|
||||
|
|
Loading…
Add table
Reference in a new issue