0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-04-07 23:01:25 -05:00

feat(console,phrases): add feature tag and pricing table ()

* feat(console,phrases): add feature tag and pricing table

add feature tag and pricing table

* feat(console): add third-party tips

add third-party tips
This commit is contained in:
simeng-li 2024-01-31 09:28:01 +08:00 committed by GitHub
parent 1b0602708a
commit 185491d699
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
45 changed files with 362 additions and 14 deletions
packages
console
package.json
src
components
consts
ds-components/Checkbox
Checkbox
CheckboxGroup
pages
Applications/components/GuideLibrary
TenantSettings/Subscription/PlanComparisonTable
PlanQuotaKeyLabel
renderers
phrases/src/locales
de/translation/admin-console/subscription
en/translation/admin-console/subscription
es/translation/admin-console/subscription
fr/translation/admin-console/subscription
it/translation/admin-console/subscription
ja/translation/admin-console/subscription
ko/translation/admin-console/subscription
pl-pl/translation/admin-console/subscription
pt-br/translation/admin-console/subscription
pt-pt/translation/admin-console/subscription
ru/translation/admin-console/subscription
tr-tr/translation/admin-console/subscription
zh-cn/translation/admin-console/subscription
zh-hk/translation/admin-console/subscription
zh-tw/translation/admin-console/subscription
pnpm-lock.yaml

View file

@ -26,7 +26,7 @@
"@fontsource/roboto-mono": "^5.0.0",
"@jest/types": "^29.5.0",
"@logto/app-insights": "workspace:^1.3.1",
"@logto/cloud": "0.2.5-c6ed487",
"@logto/cloud": "0.2.5-faca9a9",
"@logto/connector-kit": "workspace:^2.0.0",
"@logto/core-kit": "workspace:^2.2.1",
"@logto/language-kit": "workspace:^1.0.0",

View file

@ -0,0 +1,19 @@
import classNames from 'classnames';
/**
* BetaTag static component
*
* Used to indicate that a new released feature is in beta.
*/
import * as styles from './index.module.scss';
type Props = {
className?: string;
};
function BetaTag({ className }: Props) {
return <div className={classNames(styles.tag, styles.beta, className)}>Beta</div>;
}
export default BetaTag;

View file

@ -10,3 +10,7 @@
color: var(--color-white);
text-transform: capitalize;
}
.beta {
background-color: var(--color-specific-tag-test);
}

View file

@ -6,6 +6,8 @@ import { TenantsContext } from '@/contexts/TenantsProvider';
import * as styles from './index.module.scss';
export { default as BetaTag } from './BetaTag';
type Props = {
/**
* Whether the tag should be visible. It should be `true` if the tenant's subscription

View file

@ -37,6 +37,12 @@
flex-shrink: 0;
}
.tagWrapper {
display: flex;
align-items: center;
gap: _.unit(1);
}
.infoWrapper {
display: flex;
flex-direction: column;

View file

@ -1,7 +1,11 @@
import { ReservedPlanId } from '@logto/schemas';
import classNames from 'classnames';
import { Suspense, useCallback } from 'react';
import { Suspense, useCallback, useContext } from 'react';
import { type Guide, type GuideMetadata } from '@/assets/docs/guides/types';
import FeatureTag, { BetaTag } from '@/components/FeatureTag';
import { isCloud } from '@/consts/env';
import { SubscriptionDataContext } from '@/contexts/SubscriptionDataProvider';
import Button from '@/ds-components/Button';
import { onKeyDownHandler } from '@/utils/a11y';
@ -29,10 +33,14 @@ function GuideCard({ data, onClick, hasBorder, hasButton }: Props) {
} = data;
const buttonText = target === 'API' ? 'guide.get_started' : 'guide.start_building';
const { currentPlan } = useContext(SubscriptionDataContext);
const showPaywallTag = isCloud && isThirdParty;
const showBetaTag = isCloud && isThirdParty;
const handleClick = useCallback(() => {
onClick({ id, target, name, isThirdParty });
}, [id, name, target, onClick]);
}, [onClick, id, target, name, isThirdParty]);
return (
<div
@ -55,6 +63,18 @@ function GuideCard({ data, onClick, hasBorder, hasButton }: Props) {
<div className={styles.infoWrapper}>
<div className={styles.flexRow}>
<div className={styles.name}>{name}</div>
{/* eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing */}
{showPaywallTag || showBetaTag ? (
<div className={styles.tagWrapper}>
{showPaywallTag && (
<FeatureTag
isVisible={currentPlan.quota.thirdPartyApplicationsLimit === 0}
plan={ReservedPlanId.Pro}
/>
)}
{showBetaTag && <BetaTag />}
</div>
) : null}
</div>
<div className={styles.description} title={description}>
{description}

View file

@ -173,7 +173,11 @@ export const enterprisePlanTableData: SubscriptionPlanTableData = {
export const planTableGroupKeyMap: SubscriptionPlanTableGroupKeyMap = Object.freeze({
[SubscriptionPlanTableGroupKey.base]: ['basePrice', 'mauLimit', 'tokenLimit'],
[SubscriptionPlanTableGroupKey.applications]: ['applicationsLimit', 'machineToMachineLimit'],
[SubscriptionPlanTableGroupKey.applications]: [
'applicationsLimit',
'machineToMachineLimit',
'thirdPartyApplicationsLimit',
],
[SubscriptionPlanTableGroupKey.resources]: ['resourcesLimit', 'scopesPerResourceLimit'],
[SubscriptionPlanTableGroupKey.branding]: [
'customDomainEnabled',

View file

@ -10,6 +10,7 @@ export const quotaItemPhrasesMap: Record<
tokenLimit: 'token_limit.name',
applicationsLimit: 'applications_limit.name',
machineToMachineLimit: 'machine_to_machine_limit.name',
thirdPartyApplicationsLimit: 'third_party_applications_limit.name',
resourcesLimit: 'resources_limit.name',
scopesPerResourceLimit: 'scopes_per_resource_limit.name',
customDomainEnabled: 'custom_domain_enabled.name',
@ -36,6 +37,7 @@ export const quotaItemUnlimitedPhrasesMap: Record<
tokenLimit: 'token_limit.unlimited',
applicationsLimit: 'applications_limit.unlimited',
machineToMachineLimit: 'machine_to_machine_limit.unlimited',
thirdPartyApplicationsLimit: 'third_party_applications_limit.unlimited',
resourcesLimit: 'resources_limit.unlimited',
scopesPerResourceLimit: 'scopes_per_resource_limit.unlimited',
customDomainEnabled: 'custom_domain_enabled.unlimited',
@ -62,6 +64,7 @@ export const quotaItemLimitedPhrasesMap: Record<
tokenLimit: 'token_limit.limited',
applicationsLimit: 'applications_limit.limited',
machineToMachineLimit: 'machine_to_machine_limit.limited',
thirdPartyApplicationsLimit: 'third_party_applications_limit.limited',
resourcesLimit: 'resources_limit.limited',
scopesPerResourceLimit: 'scopes_per_resource_limit.limited',
customDomainEnabled: 'custom_domain_enabled.limited',
@ -88,6 +91,7 @@ export const quotaItemNotEligiblePhrasesMap: Record<
tokenLimit: 'token_limit.not_eligible',
applicationsLimit: 'applications_limit.not_eligible',
machineToMachineLimit: 'machine_to_machine_limit.not_eligible',
thirdPartyApplicationsLimit: 'third_party_applications_limit.not_eligible',
resourcesLimit: 'resources_limit.not_eligible',
scopesPerResourceLimit: 'scopes_per_resource_limit.not_eligible',
customDomainEnabled: 'custom_domain_enabled.not_eligible',

View file

@ -66,6 +66,7 @@ export const defaultSubscriptionPlan: SubscriptionPlan = {
ssoEnabled: true,
communitySupportEnabled: true,
ticketSupportResponseTime: 48,
thirdPartyApplicationsLimit: null,
},
};

View file

@ -57,6 +57,9 @@
color: var(--color-text);
white-space: nowrap;
cursor: inherit;
display: flex;
align-items: center;
gap: _.unit(1);
}
&.disabled {

View file

@ -1,5 +1,6 @@
import { type AdminConsoleKey } from '@logto/phrases';
import classNames from 'classnames';
import { type ReactNode } from 'react';
import DynamicT from '@/ds-components/DynamicT';
@ -9,6 +10,7 @@ import * as styles from './index.module.scss';
type Option<T> = {
title: AdminConsoleKey;
tag?: ReactNode;
value: T;
};
@ -35,10 +37,15 @@ function CheckboxGroup<T extends string>({
return (
<div className={classNames(styles.group, className)}>
{options.map(({ title, value }) => (
{options.map(({ title, value, tag }) => (
<Checkbox
key={value}
label={<DynamicT forKey={title} />}
label={
<>
<DynamicT forKey={title} />
{tag}
</>
}
checked={checkedValues.includes(value)}
onChange={() => {
toggleValue(value);

View file

@ -1,15 +1,18 @@
import { ApplicationType, type Application } from '@logto/schemas';
import { ApplicationType, type Application, ReservedPlanId } from '@logto/schemas';
import { cond } from '@silverhand/essentials';
import classNames from 'classnames';
import { useCallback, useMemo, useState } from 'react';
import { useCallback, useContext, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useLocation } from 'react-router-dom';
import SearchIcon from '@/assets/icons/search.svg';
import EmptyDataPlaceholder from '@/components/EmptyDataPlaceholder';
import FeatureTag from '@/components/FeatureTag';
import { type SelectedGuide } from '@/components/Guide/GuideCard';
import GuideCardGroup from '@/components/Guide/GuideCardGroup';
import { useAppGuideMetadata } from '@/components/Guide/hooks';
import { isCloud, isDevFeaturesEnabled } from '@/consts/env';
import { SubscriptionDataContext } from '@/contexts/SubscriptionDataProvider';
import { CheckboxGroup } from '@/ds-components/Checkbox';
import OverlayScrollbar from '@/ds-components/OverlayScrollbar';
import TextInput from '@/ds-components/TextInput';
@ -39,6 +42,7 @@ function GuideLibrary({ className, hasCardBorder, hasCardButton }: Props) {
const { getFilteredAppGuideMetadata, getStructuredAppGuideMetadata } = useAppGuideMetadata();
const [showCreateForm, setShowCreateForm] = useState<boolean>(false);
const isApplicationCreateModal = pathname.includes('/applications/create');
const { currentPlan } = useContext(SubscriptionDataContext);
const structuredMetadata = useMemo(
() => getStructuredAppGuideMetadata({ categories: filterCategories }),
@ -111,6 +115,17 @@ function GuideLibrary({ className, hasCardBorder, hasCardButton }: Props) {
.map((category) => ({
title: `guide.categories.${category}`,
value: category,
...cond(
isCloud &&
category === 'ThirdParty' && {
tag: (
<FeatureTag
isVisible={currentPlan.quota.thirdPartyApplicationsLimit === 0}
plan={ReservedPlanId.Pro}
/>
),
}
),
}))}
value={filterCategories}
onChange={(value) => {

View file

@ -17,6 +17,7 @@ const planQuotaKeyPhraseMap: {
tokenLimit: 'quota.included_tokens',
applicationsLimit: 'application.total',
machineToMachineLimit: 'application.m2m',
thirdPartyApplicationsLimit: 'application.third_party',
resourcesLimit: 'resource.resource_count',
scopesPerResourceLimit: 'resource.scopes_per_resource',
customDomainEnabled: 'branding.custom_domain',
@ -60,6 +61,7 @@ const planQuotaTipPhraseMap: Partial<
mauLimit: 'mau_tip',
tokenLimit: 'tokens_tip',
organizationsEnabled: 'mao_tip',
thirdPartyApplicationsLimit: 'third_party_tip',
};
type Props = {

View file

@ -71,6 +71,9 @@ export const quotaValueRenderer: Record<
/>
);
},
thirdPartyApplicationsLimit: ({ id, table: { thirdPartyApplicationsLimit } }) => {
return <GenericQuotaLimit quota={thirdPartyApplicationsLimit} />;
},
// Resources
resourcesLimit: ({ id, table: { resourcesLimit } }) => {
const isPaidPlan = id === ReservedPlanId.Hobby;

View file

@ -34,6 +34,18 @@ const quota_item = {
not_eligible: 'Entferne deine Maschine-zu-Maschine-Apps',
add_on: 'Zusätzliche Maschine-zu-Maschine-Apps',
},
third_party_applications_limit: {
/** UNTRANSLATED */
name: 'Third-party apps',
/** UNTRANSLATED */
limited: '{{count, number}} third-party app',
/** UNTRANSLATED */
limited_other: '{{count, number}} third-party apps',
/** UNTRANSLATED */
unlimited: 'Unlimited third-party apps',
/** UNTRANSLATED */
not_eligible: 'Remove your third-party apps',
},
resources_limit: {
name: 'API-Ressourcen',
limited: '{{count, number}} API-Ressource',

View file

@ -9,6 +9,8 @@ const quota_table = {
title: 'Anwendungen',
total: 'Gesamtzahl der Anwendungen',
m2m: 'Maschine-zu-Maschine',
/** UNTRANSLATED */
third_party: 'Third-party apps',
},
resource: {
title: 'API-Ressourcen',
@ -90,6 +92,9 @@ const quota_table = {
'Alle Arten von Tokens, die von Logto ausgegeben wurden, einschließlich Zugriffstoken, Aktualisierungstoken, usw.',
mao_tip:
'MAO (Monthly Active Org) bezeichnet die Anzahl der einzigartigen Organisationen, die in einem Abrechnungszyklus mindestens einen MAU (Monthly Active User) haben.',
/** UNTRANSLATED */
third_party_tip:
'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.',
included: '{{value, number}} inklusive',
included_mao: '{{value, number}} MAO enthalten',
extra_quota_price: 'Dann ${{value, number}} pro Monat / je danach',

View file

@ -34,6 +34,13 @@ const quota_item = {
not_eligible: 'Remove your machine to machine apps',
add_on: 'Additional machine-to-machine apps',
},
third_party_applications_limit: {
name: 'Third-party apps',
limited: '{{count, number}} third-party app',
limited_other: '{{count, number}} third-party apps',
unlimited: 'Unlimited third-party apps',
not_eligible: 'Remove your third-party apps',
},
resources_limit: {
name: 'API resources',
limited: '{{count, number}} API resource',

View file

@ -8,7 +8,8 @@ const quota_table = {
application: {
title: 'Applications',
total: 'Total applications',
m2m: 'Machine-to-machine',
m2m: 'Machine-to-machine apps',
third_party: 'Third-party apps',
},
resource: {
title: 'API resources',
@ -90,6 +91,8 @@ const quota_table = {
'All kinds of tokens that issued by Logto, including access token, refresh token, etc.',
mao_tip:
'MAO (monthly active org) means the number of unique organizations who has at least one MAU (monthly active user) in a billing cycle.',
third_party_tip:
'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.',
included: '{{value, number}} included',
included_mao: '{{value, number}} MAO included',
extra_quota_price: 'Then ${{value, number}} per mo / ea after',

View file

@ -34,6 +34,18 @@ const quota_item = {
not_eligible: 'Elimine sus aplicaciones de dispositivo a dispositivo',
add_on: 'Aplicaciones de máquina a máquina adicionales',
},
third_party_applications_limit: {
/** UNTRANSLATED */
name: 'Third-party apps',
/** UNTRANSLATED */
limited: '{{count, number}} third-party app',
/** UNTRANSLATED */
limited_other: '{{count, number}} third-party apps',
/** UNTRANSLATED */
unlimited: 'Unlimited third-party apps',
/** UNTRANSLATED */
not_eligible: 'Remove your third-party apps',
},
resources_limit: {
name: 'Recursos de API',
limited: '{{count, number}} recurso de API',

View file

@ -9,6 +9,8 @@ const quota_table = {
title: 'Aplicaciones',
total: 'Total de aplicaciones',
m2m: 'Aplicación machine-to-machine',
/** UNTRANSLATED */
third_party: 'Third-party apps',
},
resource: {
title: 'Recursos de API',
@ -90,6 +92,9 @@ const quota_table = {
'Todo tipo de tokens emitidos por Logto, incluyendo tokens de acceso, tokens de actualización, etc.',
mao_tip:
'MAO (Organización activa mensual) significa la cantidad de organizaciones únicas que tienen al menos un MAU (usuario activo mensual) en un ciclo de facturación.',
/** UNTRANSLATED */
third_party_tip:
'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.',
included: 'incluido{{value, number}}',
included_mao: '{{value, number}} MAO incluido',
extra_quota_price: 'Luego ${{value, number}} por mes / cada uno después',

View file

@ -34,6 +34,18 @@ const quota_item = {
not_eligible: 'Supprimez vos applications machine à machine',
add_on: 'Applications machine à machine supplémentaires',
},
third_party_applications_limit: {
/** UNTRANSLATED */
name: 'Third-party apps',
/** UNTRANSLATED */
limited: '{{count, number}} third-party app',
/** UNTRANSLATED */
limited_other: '{{count, number}} third-party apps',
/** UNTRANSLATED */
unlimited: 'Unlimited third-party apps',
/** UNTRANSLATED */
not_eligible: 'Remove your third-party apps',
},
resources_limit: {
name: 'Ressources API',
limited: '{{count, number}} ressource API',

View file

@ -9,6 +9,8 @@ const quota_table = {
title: 'Applications',
total: 'Total des applications',
m2m: 'Machine-à-machine',
/** UNTRANSLATED */
third_party: 'Third-party apps',
},
resource: {
title: 'Ressources API',
@ -90,6 +92,9 @@ const quota_table = {
"Tous types de jetons émis par Logto, y compris les jetons d'accès, les jetons de rafraîchissement, etc.",
mao_tip:
"MAO (Organisation active mensuelle) désigne le nombre d'organisations uniques ayant au moins un MAU (utilisateur actif mensuel) au cours d'un cycle de facturation.",
/** UNTRANSLATED */
third_party_tip:
'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.',
included: '{{value, number}} inclus',
included_mao: '{{value, number}} MAO inclus',
extra_quota_price: 'Ensuite ${{value, number}} par mois / chacun après',

View file

@ -34,6 +34,18 @@ const quota_item = {
not_eligible: 'Rimuovi le tue applicazioni Machine-to-Machine',
add_on: 'Applicazioni Machine-to-Machine aggiuntive',
},
third_party_applications_limit: {
/** UNTRANSLATED */
name: 'Third-party apps',
/** UNTRANSLATED */
limited: '{{count, number}} third-party app',
/** UNTRANSLATED */
limited_other: '{{count, number}} third-party apps',
/** UNTRANSLATED */
unlimited: 'Unlimited third-party apps',
/** UNTRANSLATED */
not_eligible: 'Remove your third-party apps',
},
resources_limit: {
name: 'Risorse API',
limited: '{{count, number}} risorsa API',

View file

@ -9,6 +9,8 @@ const quota_table = {
title: 'Applicazioni',
total: 'Totale applicazioni',
m2m: 'Machine-to-machine',
/** UNTRANSLATED */
third_party: 'Third-party apps',
},
resource: {
title: 'Risorse API',
@ -90,6 +92,9 @@ const quota_table = {
'Tutti i tipi di token emessi da Logto, inclusi token di accesso, token di aggiornamento, ecc.',
mao_tip:
'MAO (Organizzazione attiva mensile) indica il numero di organizzazioni uniche che hanno almeno un MAU (utente attivo mensile) in un ciclo di fatturazione.',
/** UNTRANSLATED */
third_party_tip:
'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.',
included: '{{value, number}} incluso',
included_mao: '{{value, number}} MAO inclusi',
extra_quota_price: 'Quindi ${{value, number}} al mese / ognuno dopo',

View file

@ -34,6 +34,18 @@ const quota_item = {
not_eligible: 'マシン間アプリケーションを削除してください',
add_on: '追加のマシン間アプリケーション',
},
third_party_applications_limit: {
/** UNTRANSLATED */
name: 'Third-party apps',
/** UNTRANSLATED */
limited: '{{count, number}} third-party app',
/** UNTRANSLATED */
limited_other: '{{count, number}} third-party apps',
/** UNTRANSLATED */
unlimited: 'Unlimited third-party apps',
/** UNTRANSLATED */
not_eligible: 'Remove your third-party apps',
},
resources_limit: {
name: 'APIリソース',
limited: '{{count, number}} APIリソース',

View file

@ -9,6 +9,8 @@ const quota_table = {
title: 'アプリケーション',
total: '総アプリケーション数',
m2m: 'マシン・ツー・マシン',
/** UNTRANSLATED */
third_party: 'Third-party apps',
},
resource: {
title: 'APIリソース',
@ -90,6 +92,9 @@ const quota_table = {
'Logtoによって発行されたすべての種類のトークン、アクセストークン、リフレッシュトークンなどを含みます。',
mao_tip:
'MAO月間アクティブ組織は、請求サイクル内で少なくとも1つのMAU月間アクティブユーザーを持つユニークな組織の数を意味します。',
/** UNTRANSLATED */
third_party_tip:
'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.',
included: '{{value, number}} 込み',
included_mao: '{{value, number}} MAO込み',
extra_quota_price: 'その後、各${{value, number}} / 月ごと',

View file

@ -34,6 +34,18 @@ const quota_item = {
not_eligible: '기계 간 앱을 제거하십시오',
add_on: '추가 기계간 앱',
},
third_party_applications_limit: {
/** UNTRANSLATED */
name: 'Third-party apps',
/** UNTRANSLATED */
limited: '{{count, number}} third-party app',
/** UNTRANSLATED */
limited_other: '{{count, number}} third-party apps',
/** UNTRANSLATED */
unlimited: 'Unlimited third-party apps',
/** UNTRANSLATED */
not_eligible: 'Remove your third-party apps',
},
resources_limit: {
name: 'API 리소스',
limited: '{{count, number}} API 리소스',

View file

@ -9,6 +9,8 @@ const quota_table = {
title: '애플리케이션',
total: '총 애플리케이션 수',
m2m: '머신 투 머신',
/** UNTRANSLATED */
third_party: 'Third-party apps',
},
resource: {
title: 'API 리소스',
@ -89,6 +91,9 @@ const quota_table = {
tokens_tip: 'Logto에서 발행한 모든 종류의 토큰, 액세스 토큰, 리프레시 토큰 등을 포함합니다.',
mao_tip:
'MAO (월간 활성 조직)는 빌링 주기 내에서 적어도 하나의 MAU (월간 활성 사용자)를 가진 고유한 조직의 수를 의미합니다.',
/** UNTRANSLATED */
third_party_tip:
'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.',
included: '{{value, number}} 포함',
included_mao: '{{value, number}} MAO 포함',
extra_quota_price: '이후 월당 ${{value, number}} / 각각',

View file

@ -34,6 +34,18 @@ const quota_item = {
not_eligible: 'Usuń swoje aplikacje machine to machine',
add_on: 'Dodatkowe aplikacje machine-to-machine',
},
third_party_applications_limit: {
/** UNTRANSLATED */
name: 'Third-party apps',
/** UNTRANSLATED */
limited: '{{count, number}} third-party app',
/** UNTRANSLATED */
limited_other: '{{count, number}} third-party apps',
/** UNTRANSLATED */
unlimited: 'Unlimited third-party apps',
/** UNTRANSLATED */
not_eligible: 'Remove your third-party apps',
},
resources_limit: {
name: 'Zasoby API',
limited: '{{count, number}} zasób API',

View file

@ -9,6 +9,8 @@ const quota_table = {
title: 'Aplikacje',
total: 'Liczba aplikacji',
m2m: 'Aplikacja typu maszyna-maszyna',
/** UNTRANSLATED */
third_party: 'Third-party apps',
},
resource: {
title: 'Zasoby API',
@ -90,6 +92,9 @@ const quota_table = {
'Wszystkie rodzaje tokenów wydanych przez Logto, w tym tokeny dostępu, tokeny odświeżania, itp.',
mao_tip:
'MAO (aktywna organizacja miesięczna) oznacza liczbę unikalnych organizacji, które mają co najmniej jednego aktywnego użytkownika miesięcznie w cyklu rozliczeniowym.',
/** UNTRANSLATED */
third_party_tip:
'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.',
included: '{{value, number}} zawarte',
included_mao: '{{value, number}} MAO wliczone',
extra_quota_price: 'Następnie ${{value, number}} za miesiąc / każdy po',

View file

@ -34,6 +34,18 @@ const quota_item = {
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 */
name: 'Third-party apps',
/** UNTRANSLATED */
limited: '{{count, number}} third-party app',
/** UNTRANSLATED */
limited_other: '{{count, number}} third-party apps',
/** UNTRANSLATED */
unlimited: 'Unlimited third-party apps',
/** UNTRANSLATED */
not_eligible: 'Remove your third-party apps',
},
resources_limit: {
name: 'Recursos da API',
limited: '{{count, number}} recurso da API',

View file

@ -9,6 +9,8 @@ const quota_table = {
title: 'Aplicações',
total: 'Total de aplicações',
m2m: 'Aplicação máquina-a-máquina',
/** UNTRANSLATED */
third_party: 'Third-party apps',
},
resource: {
title: 'Recursos de API',
@ -90,6 +92,9 @@ const quota_table = {
'Todos os tipos de tokens emitidos pelo Logto, incluindo token de acesso, token de atualização, etc.',
mao_tip:
'MAO (Organização Ativa Mensal) significa o número de organizações únicas que têm pelo menos um MAU (Usuário Ativo Mensal) em um ciclo de faturamento.',
/** UNTRANSLATED */
third_party_tip:
'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.',
included: 'incluído{{value, number}}',
included_mao: '{{value, number}} MAO incluído',
extra_quota_price: 'Então ${{value, number}} por mês / cada depois',

View file

@ -34,6 +34,18 @@ const quota_item = {
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 */
name: 'Third-party apps',
/** UNTRANSLATED */
limited: '{{count, number}} third-party app',
/** UNTRANSLATED */
limited_other: '{{count, number}} third-party apps',
/** UNTRANSLATED */
unlimited: 'Unlimited third-party apps',
/** UNTRANSLATED */
not_eligible: 'Remove your third-party apps',
},
resources_limit: {
name: 'Recursos de API',
limited: '{{count, number}} recurso de API',

View file

@ -9,6 +9,8 @@ const quota_table = {
title: 'Aplicações',
total: 'Total de aplicações',
m2m: 'Aplicações de máquina para máquina',
/** UNTRANSLATED */
third_party: 'Third-party apps',
},
resource: {
title: 'Recursos da API',
@ -90,6 +92,9 @@ const quota_table = {
'Todos os tipos de tokens emitidos pelo Logto, incluindo token de acesso, token de atualização, etc.',
mao_tip:
'MAO (Organização Ativa Mensal) significa o número de organizações únicas que têm pelo menos um MAU (Utilizador Ativo Mensal) num ciclo de faturação.',
/** UNTRANSLATED */
third_party_tip:
'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.',
included: 'incluído{{value, number}}',
included_mao: '{{value, number}} MAO incluída',
extra_quota_price: 'Depois ${{value, number}} por mês / cada um depois',

View file

@ -34,6 +34,18 @@ const quota_item = {
not_eligible: 'Удалите свои приложения для машин ко машине',
add_on: 'Дополнительные приложения для машины ко машине',
},
third_party_applications_limit: {
/** UNTRANSLATED */
name: 'Third-party apps',
/** UNTRANSLATED */
limited: '{{count, number}} third-party app',
/** UNTRANSLATED */
limited_other: '{{count, number}} third-party apps',
/** UNTRANSLATED */
unlimited: 'Unlimited third-party apps',
/** UNTRANSLATED */
not_eligible: 'Remove your third-party apps',
},
resources_limit: {
name: 'API ресурсы',
limited: '{{count, number}} API ресурс',

View file

@ -9,6 +9,8 @@ const quota_table = {
title: 'Приложения',
total: 'Всего приложений',
m2m: 'Приложения "машина-машина"',
/** UNTRANSLATED */
third_party: 'Third-party apps',
},
resource: {
title: 'Ресурсы API',
@ -90,6 +92,9 @@ const quota_table = {
'Все виды токенов, выпущенных Logto, включая токены доступа, токены обновления и т. д.',
mao_tip:
'MAO (ежемесячно активная организация) означает количество уникальных организаций, у которых есть хотя бы один MAU (ежемесячно активный пользователь) в биллинговом цикле.',
/** UNTRANSLATED */
third_party_tip:
'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.',
included: 'включено{{value, number}}',
included_mao: '{{value, number}} MAO включено',
extra_quota_price: 'Затем ${{value, number}} в месяц / за каждый после',

View file

@ -34,6 +34,18 @@ const quota_item = {
not_eligible: 'Makineye makine uygulamalarınızı kaldırın',
add_on: 'Ek makineye makine uygulamaları',
},
third_party_applications_limit: {
/** UNTRANSLATED */
name: 'Third-party apps',
/** UNTRANSLATED */
limited: '{{count, number}} third-party app',
/** UNTRANSLATED */
limited_other: '{{count, number}} third-party apps',
/** UNTRANSLATED */
unlimited: 'Unlimited third-party apps',
/** UNTRANSLATED */
not_eligible: 'Remove your third-party apps',
},
resources_limit: {
name: 'API kaynakları',
limited: '{{count, number}} API kaynak',

View file

@ -9,6 +9,8 @@ const quota_table = {
title: 'Uygulamalar',
total: 'Toplam uygulama sayısı',
m2m: 'Makine-makine uygulamaları',
/** UNTRANSLATED */
third_party: 'Third-party apps',
},
resource: {
title: 'API Kaynakları',
@ -90,6 +92,9 @@ const quota_table = {
'Logto tarafından ihraç edilen erişim tokeni, yenileme tokeni vb. dahil olmak üzere tüm token türleri.',
mao_tip:
"MAO (aylık aktif kuruluş) bir fatura döngüsünde en az bir MAU'ya (aylık aktif kullanıcı) sahip olan benzersiz kuruluşların sayısını ifade eder.",
/** UNTRANSLATED */
third_party_tip:
'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.',
included: '{{value, number}} dahil',
included_mao: '{{value, number}} MAO dahil',
extra_quota_price: 'Sonra aylık ${{value, number}} / sonrasında her biri',

View file

@ -34,6 +34,18 @@ const quota_item = {
not_eligible: '移除你的机器到机器应用',
add_on: '更多机器到机器应用',
},
third_party_applications_limit: {
/** UNTRANSLATED */
name: 'Third-party apps',
/** UNTRANSLATED */
limited: '{{count, number}} third-party app',
/** UNTRANSLATED */
limited_other: '{{count, number}} third-party apps',
/** UNTRANSLATED */
unlimited: 'Unlimited third-party apps',
/** UNTRANSLATED */
not_eligible: 'Remove your third-party apps',
},
resources_limit: {
name: 'API 资源',
limited: '{{count, number}} 个 API 资源',

View file

@ -9,6 +9,8 @@ const quota_table = {
title: '应用',
total: '总应用数',
m2m: '机器对机器',
/** UNTRANSLATED */
third_party: 'Third-party apps',
},
resource: {
title: 'API 资源',
@ -87,6 +89,9 @@ const quota_table = {
mau_tip: 'MAU月活跃用户是指在计费周期内与Logto交换过至少一个令牌的独立用户数量。',
tokens_tip: 'Logto 发行的所有类型令牌,包括访问令牌、刷新令牌等。',
mao_tip: 'MAO月度活跃组织是指在计费周期内至少有一个MAU月度活跃用户的独特组织数量。',
/** UNTRANSLATED */
third_party_tip:
'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.',
included: '已包含{{value, number}}',
included_mao: '已包含 {{value, number}} MAO',
extra_quota_price: '然后每月 ${{value, number}} / 每个之后',

View file

@ -34,6 +34,18 @@ const quota_item = {
not_eligible: '刪除您的機器對機器應用程式',
add_on: '附加的機器對機器應用程式',
},
third_party_applications_limit: {
/** UNTRANSLATED */
name: 'Third-party apps',
/** UNTRANSLATED */
limited: '{{count, number}} third-party app',
/** UNTRANSLATED */
limited_other: '{{count, number}} third-party apps',
/** UNTRANSLATED */
unlimited: 'Unlimited third-party apps',
/** UNTRANSLATED */
not_eligible: 'Remove your third-party apps',
},
resources_limit: {
name: 'API 資源',
limited: '{{count, number}} 個API 資源',

View file

@ -9,6 +9,8 @@ const quota_table = {
title: '應用程式',
total: '應用程式總數',
m2m: '機器到機器',
/** UNTRANSLATED */
third_party: 'Third-party apps',
},
resource: {
title: 'API 資源',
@ -87,6 +89,9 @@ const quota_table = {
mau_tip: 'MAU每月活躍用戶是指在計費週期內與Logto交換過至少一個令牌的獨立用戶數量。',
tokens_tip: 'Logto 發行的所有類型令牌,包括訪問令牌、刷新令牌等。',
mao_tip: 'MAO月度活躍組織指的是在計費週期內至少有一個MAU月度活躍用戶的獨特組織數量。',
/** UNTRANSLATED */
third_party_tip:
'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.',
included: '已包含 {{value, number}}',
included_mao: '已包含 {{value, number}} MAO',
extra_quota_price: '然後每月 ${{value, number}} / 每個之後',

View file

@ -34,6 +34,18 @@ const quota_item = {
not_eligible: '移除你的機器對機器應用程式',
add_on: '額外的機器對機器應用程式',
},
third_party_applications_limit: {
/** UNTRANSLATED */
name: 'Third-party apps',
/** UNTRANSLATED */
limited: '{{count, number}} third-party app',
/** UNTRANSLATED */
limited_other: '{{count, number}} third-party apps',
/** UNTRANSLATED */
unlimited: 'Unlimited third-party apps',
/** UNTRANSLATED */
not_eligible: 'Remove your third-party apps',
},
resources_limit: {
name: 'API 資源',
limited: '{{count, number}} API 資源',

View file

@ -9,6 +9,8 @@ const quota_table = {
title: '應用程式',
total: '總應用程式數',
m2m: '機器對機器',
/** UNTRANSLATED */
third_party: 'Third-party apps',
},
resource: {
title: 'API 資源',
@ -87,6 +89,9 @@ const quota_table = {
mau_tip: 'MAU每月活躍用戶是指在計費週期內與Logto交換過至少一個令牌的獨立用戶數量。',
tokens_tip: 'Logto 發行的所有類型令牌,包括訪問令牌、刷新令牌等。',
mao_tip: 'MAO月度活躍組織指的是在計費週期內至少有一個MAU月度活躍用戶的獨特組織數量。',
/** UNTRANSLATED */
third_party_tip:
'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.',
included: '已包含{{value, number}}',
included_mao: '已包含 {{value, number}} MAO',
extra_quota_price: '然後每月 ${{value, number}} / 每個之後',

20
pnpm-lock.yaml generated
View file

@ -2840,8 +2840,8 @@ importers:
specifier: workspace:^1.3.1
version: link:../app-insights
'@logto/cloud':
specifier: 0.2.5-c6ed487
version: 0.2.5-c6ed487(zod@3.22.4)
specifier: 0.2.5-faca9a9
version: 0.2.5-faca9a9(zod@3.22.4)
'@logto/connector-kit':
specifier: workspace:^2.0.0
version: link:../toolkit/connector-kit
@ -4530,7 +4530,7 @@ packages:
'@aws-sdk/util-user-agent-node': 3.224.0
'@aws-sdk/util-utf8-browser': 3.188.0
'@aws-sdk/util-utf8-node': 3.208.0
tslib: 2.5.0
tslib: 2.6.2
transitivePeerDependencies:
- aws-crt
dev: false
@ -4570,7 +4570,7 @@ packages:
'@aws-sdk/util-user-agent-browser': 3.310.0
'@aws-sdk/util-user-agent-node': 3.310.0
'@aws-sdk/util-utf8': 3.310.0
tslib: 2.5.0
tslib: 2.6.2
transitivePeerDependencies:
- aws-crt
dev: false
@ -7600,6 +7600,16 @@ packages:
- zod
dev: true
/@logto/cloud@0.2.5-faca9a9(zod@3.22.4):
resolution: {integrity: sha512-hUiuzOPd4bKIV6fIKZLQW2Fc8JYmwKWWps7gZoxGbL3uLmAYYci5JHIP+vM7nbNS+oK1V141sy3JjNS1vAkvGA==}
engines: {node: ^20.9.0}
dependencies:
'@silverhand/essentials': 2.8.8
'@withtyped/server': 0.12.9(zod@3.22.4)
transitivePeerDependencies:
- zod
dev: true
/@logto/js@3.0.1:
resolution: {integrity: sha512-vsU6mH5oiiW3k00pMyVA4V31K2Bd0rOT9qWch2l5e5o1yCQLJ3zUIOjGjChu3m2TRu1d920iiUpZU3Lzf6Pwdw==}
dependencies:
@ -15501,7 +15511,7 @@ packages:
jest: ^28.1.0 || ^29.1.2
react: ^17.0.0 || ^18.0.0
dependencies:
jest: 29.7.0(@types/node@20.10.4)(ts-node@10.9.2)
jest: 29.7.0(@types/node@18.19.3)
react: 18.2.0
dev: true