diff --git a/packages/console/src/components/TenantEnvTag/index.module.scss b/packages/console/src/components/TenantEnvTag/index.module.scss index d4330e7b7..d841d832a 100644 --- a/packages/console/src/components/TenantEnvTag/index.module.scss +++ b/packages/console/src/components/TenantEnvTag/index.module.scss @@ -1,15 +1,11 @@ @use '@/scss/underscore' as _; .tag { - display: flex; - align-items: center; + display: inline-block; + vertical-align: middle; padding: 0 _.unit(1.5); border-radius: _.unit(1); - height: 18px; - - .text { - font: var(--font-label-3); - } + font: var(--font-label-3); &.development { background: var(--color-env-tag-development); @@ -22,4 +18,8 @@ &.production { background: var(--color-env-tag-production); } + + &.large { + font: var(--font-label-1); + } } diff --git a/packages/console/src/components/TenantEnvTag/index.tsx b/packages/console/src/components/TenantEnvTag/index.tsx index 4bcfabbea..194046065 100644 --- a/packages/console/src/components/TenantEnvTag/index.tsx +++ b/packages/console/src/components/TenantEnvTag/index.tsx @@ -9,24 +9,34 @@ import * as styles from './index.module.scss'; type Props = { tag: TenantTag; className?: string; + isAbbreviated?: boolean; + size?: 'default' | 'large'; }; type TenantTagMap = { [key in TenantTag]: AdminConsoleKey; }; -export const tenantTagMap = Object.freeze({ +export const tenantAbbreviatedTagNameMap = Object.freeze({ [TenantTag.Development]: 'tenants.settings.environment_tag_development', + // Todo @xiaoyijun Remove staging tag before release [TenantTag.Staging]: 'tenants.settings.environment_tag_staging', [TenantTag.Production]: 'tenants.settings.environment_tag_production', }) satisfies TenantTagMap; -function TenantEnvTag({ tag, className }: Props) { +const tenantTagNameMap = Object.freeze({ + [TenantTag.Development]: 'tenants.full_env_tag.development', + // Todo @xiaoyijun Remove staging tag before release + [TenantTag.Staging]: 'tenants.settings.environment_tag_staging', + [TenantTag.Production]: 'tenants.full_env_tag.production', +}) satisfies TenantTagMap; + +function TenantEnvTag({ tag, className, isAbbreviated = true, size = 'default' }: Props) { + const phrasesMap = isAbbreviated ? tenantAbbreviatedTagNameMap : tenantTagNameMap; + return ( -
-
- -
+
+
); } diff --git a/packages/console/src/components/Topbar/TenantSelector/index.module.scss b/packages/console/src/components/Topbar/TenantSelector/index.module.scss index 3b1a36a88..f06ff2128 100644 --- a/packages/console/src/components/Topbar/TenantSelector/index.module.scss +++ b/packages/console/src/components/Topbar/TenantSelector/index.module.scss @@ -36,7 +36,6 @@ $dropdown-item-height: 40px; } .tag { - font: var(--font-body-3); margin-right: _.unit(2); } diff --git a/packages/console/src/consts/external-links.ts b/packages/console/src/consts/external-links.ts index 4635d965e..206784eec 100644 --- a/packages/console/src/consts/external-links.ts +++ b/packages/console/src/consts/external-links.ts @@ -10,3 +10,4 @@ export const reservationLink = buildUrl('https://calendly.com/logto/30min', { // Note: month format is YYYY-MM month: new Date().toISOString().slice(0, 7), }); +export const trustAndSecurityLink = 'https://logto.io/trust-and-security'; diff --git a/packages/console/src/pages/TenantSettings/TenantBasicSettings/DeleteModal/index.tsx b/packages/console/src/pages/TenantSettings/TenantBasicSettings/DeleteModal/index.tsx index bb9325bda..25eea9431 100644 --- a/packages/console/src/pages/TenantSettings/TenantBasicSettings/DeleteModal/index.tsx +++ b/packages/console/src/pages/TenantSettings/TenantBasicSettings/DeleteModal/index.tsx @@ -2,7 +2,7 @@ import classNames from 'classnames'; import { useTranslation, Trans } from 'react-i18next'; import { type TenantResponse } from '@/cloud/types/router'; -import { tenantTagMap } from '@/components/TenantEnvTag'; +import { tenantAbbreviatedTagNameMap } from '@/components/TenantEnvTag'; import { contactEmailLink } from '@/consts'; import DeleteConfirmModal from '@/ds-components/DeleteConfirmModal'; import TextLink from '@/ds-components/TextLink'; @@ -38,7 +38,7 @@ function DeleteModal({ isOpen, isLoading, onClose, onDelete, tenant }: Props) { }}> {t('tenants.delete_modal.description_line1', { name, - tag: t(tenantTagMap[tag], {}), // Referred to the use in DynamicT component. + tag: t(tenantAbbreviatedTagNameMap[tag], {}), // Referred to the use in DynamicT component. })}

diff --git a/packages/console/src/pages/TenantSettings/TenantBasicSettings/ProfileForm/TenantEnvironment/index.module.scss b/packages/console/src/pages/TenantSettings/TenantBasicSettings/ProfileForm/TenantEnvironment/index.module.scss new file mode 100644 index 000000000..16c55b315 --- /dev/null +++ b/packages/console/src/pages/TenantSettings/TenantBasicSettings/ProfileForm/TenantEnvironment/index.module.scss @@ -0,0 +1,13 @@ +@use '@/scss/underscore' as _; + +.container { + padding: _.unit(5.5) _.unit(6); + border: 1px solid var(--color-divider); + border-radius: 12px; +} + +.description { + margin-top: _.unit(2); + font: var(--font-body-2); + color: var(--color-text-secondary); +} diff --git a/packages/console/src/pages/TenantSettings/TenantBasicSettings/ProfileForm/TenantEnvironment/index.tsx b/packages/console/src/pages/TenantSettings/TenantBasicSettings/ProfileForm/TenantEnvironment/index.tsx new file mode 100644 index 000000000..36774ddc2 --- /dev/null +++ b/packages/console/src/pages/TenantSettings/TenantBasicSettings/ProfileForm/TenantEnvironment/index.tsx @@ -0,0 +1,37 @@ +import { TenantTag } from '@logto/schemas/lib/models/tenants.js'; +import { Trans, useTranslation } from 'react-i18next'; + +import TenantEnvTag from '@/components/TenantEnvTag'; +import TextLink from '@/ds-components/TextLink'; + +import * as styles from './index.module.scss'; + +type Props = { + tag: TenantTag; +}; + +function TenantEnvironment({ tag }: Props) { + const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); + + return ( +
+ +
+ , + }} + > + {t( + tag === TenantTag.Development + ? 'tenants.settings.development_description' + : 'tenants.create_modal.production_description' + )} + +
+
+ ); +} + +export default TenantEnvironment; diff --git a/packages/console/src/pages/TenantSettings/TenantBasicSettings/ProfileForm/TenantRegion/index.module.scss b/packages/console/src/pages/TenantSettings/TenantBasicSettings/ProfileForm/TenantRegion/index.module.scss new file mode 100644 index 000000000..cc064d53f --- /dev/null +++ b/packages/console/src/pages/TenantSettings/TenantBasicSettings/ProfileForm/TenantRegion/index.module.scss @@ -0,0 +1,21 @@ +@use '@/scss/underscore' as _; + +.container { + padding: _.unit(5.5) _.unit(6); + border: 1px solid var(--color-divider); + border-radius: 12px; +} + +.region { + font: var(--font-label-1); + + .icon { + margin-right: _.unit(2); + } +} + +.regionTip { + font: var(--font-body-2); + color: var(--color-text-secondary); + margin-top: _.unit(2); +} diff --git a/packages/console/src/pages/TenantSettings/TenantBasicSettings/ProfileForm/TenantRegion/index.tsx b/packages/console/src/pages/TenantSettings/TenantBasicSettings/ProfileForm/TenantRegion/index.tsx new file mode 100644 index 000000000..16e7576e2 --- /dev/null +++ b/packages/console/src/pages/TenantSettings/TenantBasicSettings/ProfileForm/TenantRegion/index.tsx @@ -0,0 +1,29 @@ +import { Trans, useTranslation } from 'react-i18next'; + +import { trustAndSecurityLink } from '@/consts'; +import TextLink from '@/ds-components/TextLink'; + +import * as styles from './index.module.scss'; + +function TenantRegion() { + const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); + + return ( +
+
+ 🇪🇺EU +
+
+ , + }} + > + {t('tenants.settings.tenant_region_tip', { region: 'EU' })} + +
+
+ ); +} + +export default TenantRegion; diff --git a/packages/console/src/pages/TenantSettings/TenantBasicSettings/ProfileForm/index.tsx b/packages/console/src/pages/TenantSettings/TenantBasicSettings/ProfileForm/index.tsx index 000f88a6f..eec7f1a24 100644 --- a/packages/console/src/pages/TenantSettings/TenantBasicSettings/ProfileForm/index.tsx +++ b/packages/console/src/pages/TenantSettings/TenantBasicSettings/ProfileForm/index.tsx @@ -4,6 +4,7 @@ import { Controller, useFormContext } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import FormCard from '@/components/FormCard'; +import { isDevFeaturesEnabled } from '@/consts/env'; import CopyToClipboard from '@/ds-components/CopyToClipboard'; import FormField from '@/ds-components/FormField'; import RadioGroup, { Radio } from '@/ds-components/RadioGroup'; @@ -11,6 +12,8 @@ import TextInput from '@/ds-components/TextInput'; import { type TenantSettingsForm } from '../types.js'; +import TenantEnvironment from './TenantEnvironment/index.js'; +import TenantRegion from './TenantRegion/index.js'; import * as styles from './index.module.scss'; type Props = { @@ -41,6 +44,7 @@ function ProfileForm({ currentTenantId }: Props) { control, register, formState: { errors }, + getValues, } = useFormContext(); return ( @@ -54,22 +58,34 @@ function ProfileForm({ currentTenantId }: Props) { error={Boolean(errors.profile?.name)} /> - - ( - - {tagOptions.map(({ value: optionValue, title }) => ( - - ))} - - )} - /> -
- {t('tenants.settings.environment_tag_description')} -
-
+ {isDevFeaturesEnabled && ( + + + + )} + {!isDevFeaturesEnabled && ( + + ( + + {tagOptions.map(({ value: optionValue, title }) => ( + + ))} + + )} + /> +
+ {t('tenants.settings.environment_tag_description')} +
+
+ )} + {isDevFeaturesEnabled && ( + + + + )} ); }