登录页:英文、简体中文、繁体中文主题文案。
账户中心:完整简体中文,并修正“我的资源”和品牌标题。 Admin:浏览器标题跟随当前语言。 Email:页脚支持英文、简体中文、繁体中文;其他语言回退英文。 增加中英文 Storybook 验证场景。
This commit is contained in:
+7
-7
@@ -2,8 +2,15 @@
|
||||
|
||||
# === Owned files start ===
|
||||
# admin/index.css
|
||||
# admin/KcAdminUi.tsx
|
||||
# admin/assets/logo.svg
|
||||
# admin/i18n/messages_en.properties
|
||||
# admin/i18n/messages_zh_Hans.properties
|
||||
# admin/i18n/messages_zh_Hant.properties
|
||||
# email/html/template.ftl
|
||||
# email/messages/messages_en.properties
|
||||
# email/messages/messages_zh_CN.properties
|
||||
# email/messages/messages_zh_TW.properties
|
||||
# === Owned files end =====
|
||||
|
||||
# === @keycloakify/email-native v260007.0.0 ===
|
||||
@@ -30,7 +37,6 @@
|
||||
/email/messages/messages_da.properties
|
||||
/email/messages/messages_de.properties
|
||||
/email/messages/messages_el.properties
|
||||
/email/messages/messages_en.properties
|
||||
/email/messages/messages_es.properties
|
||||
/email/messages/messages_fa.properties
|
||||
/email/messages/messages_fi.properties
|
||||
@@ -51,8 +57,6 @@
|
||||
/email/messages/messages_th.properties
|
||||
/email/messages/messages_tr.properties
|
||||
/email/messages/messages_uk.properties
|
||||
/email/messages/messages_zh_CN.properties
|
||||
/email/messages/messages_zh_TW.properties
|
||||
/email/text/email-test.ftl
|
||||
/email/text/email-update-confirmation.ftl
|
||||
/email/text/email-verification-with-code.ftl
|
||||
@@ -81,7 +85,6 @@
|
||||
/admin/ForbiddenSection.tsx
|
||||
/admin/help-urls.ts
|
||||
/admin/i18next.d.ts
|
||||
/admin/KcAdminUi.tsx
|
||||
/admin/KcContext.ts
|
||||
/admin/KcPage.tsx
|
||||
/admin/page-nav.css
|
||||
@@ -152,7 +155,6 @@
|
||||
/admin/i18n/messages_cs.properties
|
||||
/admin/i18n/messages_de.properties
|
||||
/admin/i18n/messages_el.properties
|
||||
/admin/i18n/messages_en.properties
|
||||
/admin/i18n/messages_es.properties
|
||||
/admin/i18n/messages_eu.properties
|
||||
/admin/i18n/messages_fr.properties
|
||||
@@ -175,8 +177,6 @@
|
||||
/admin/i18n/messages_tr.properties
|
||||
/admin/i18n/messages_uk.properties
|
||||
/admin/i18n/messages_vi.properties
|
||||
/admin/i18n/messages_zh_Hans.properties
|
||||
/admin/i18n/messages_zh_Hant.properties
|
||||
/admin/identity-providers/IdentityProvidersSection.tsx
|
||||
/admin/identity-providers/ManageOrderDialog.tsx
|
||||
/admin/identity-providers/OIDCConfigurationRepresentation.ts
|
||||
|
||||
@@ -54,11 +54,11 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
|
||||
</a>
|
||||
|
||||
<div className="nexus-account-header__realm">
|
||||
<span>IDENTITY CONTROL</span>
|
||||
<span>{msg("nexusIdentityControl")}</span>
|
||||
<strong>{msg("accountManagementTitle")}</strong>
|
||||
</div>
|
||||
|
||||
<nav className="nexus-account-utility" aria-label="Account utilities">
|
||||
<nav className="nexus-account-utility" aria-label={msgStr("nexusAccountUtilities")}>
|
||||
{enabledLanguages.length > 1 && (
|
||||
<details className="nexus-account-language">
|
||||
<summary>{currentLanguage.label}</summary>
|
||||
@@ -87,7 +87,7 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
|
||||
<div className="nexus-account-orbit" aria-hidden="true">
|
||||
<span />
|
||||
</div>
|
||||
<p className="nexus-account-sidebar__label">ACCOUNT MATRIX</p>
|
||||
<p className="nexus-account-sidebar__label">{msg("nexusAccountMatrix")}</p>
|
||||
<nav aria-label={msgStr("accountManagementTitle")}>
|
||||
<ul>
|
||||
{navigationItems.map(item => (
|
||||
@@ -101,7 +101,7 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
|
||||
</ul>
|
||||
</nav>
|
||||
<div className="nexus-account-sidebar__status">
|
||||
<span /> SECURE SESSION
|
||||
<span /> {msg("nexusSecureSession")}
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
|
||||
+21
-1
@@ -3,7 +3,27 @@ import { i18nBuilder } from "keycloakify/account";
|
||||
import type { ThemeName } from "../kc.gen";
|
||||
|
||||
/** @see: https://docs.keycloakify.dev/features/i18n */
|
||||
const { useI18n, ofTypeI18n } = i18nBuilder.withThemeName<ThemeName>().build();
|
||||
const { useI18n, ofTypeI18n } = i18nBuilder
|
||||
.withThemeName<ThemeName>()
|
||||
.withCustomTranslations({
|
||||
en: {
|
||||
accountManagementTitle: "Account Management",
|
||||
myResources: "My Resources",
|
||||
nexusIdentityControl: "IDENTITY CONTROL",
|
||||
nexusAccountUtilities: "Account utilities",
|
||||
nexusAccountMatrix: "ACCOUNT MATRIX",
|
||||
nexusSecureSession: "SECURE SESSION"
|
||||
},
|
||||
"zh-CN": {
|
||||
accountManagementTitle: "账户管理",
|
||||
myResources: "我的资源",
|
||||
nexusIdentityControl: "身份控制",
|
||||
nexusAccountUtilities: "账户操作",
|
||||
nexusAccountMatrix: "账户矩阵",
|
||||
nexusSecureSession: "安全会话"
|
||||
}
|
||||
})
|
||||
.build();
|
||||
|
||||
type I18n = typeof ofTypeI18n;
|
||||
|
||||
|
||||
@@ -16,6 +16,16 @@ export const Default: Story = {
|
||||
render: () => <KcPageStory />
|
||||
};
|
||||
|
||||
export const SimplifiedChinese: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
locale: { currentLanguageTag: "zh-CN" }
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
export const WithSuccessMessage: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* This file has been claimed for ownership from @keycloakify/keycloak-admin-ui version 260700.0.2.
|
||||
* To relinquish ownership and restore this file to its original content, run the following command:
|
||||
*
|
||||
* $ npx keycloakify own --path "admin/KcAdminUi.tsx" --revert
|
||||
*/
|
||||
|
||||
import "@patternfly/patternfly/patternfly-addons.css";
|
||||
import "@patternfly/react-core/dist/styles/base.css";
|
||||
import { useEffect, useReducer } from "react";
|
||||
import { startColorSchemeManagement } from "./colorScheme";
|
||||
import { createHashRouter, RouterProvider } from "react-router-dom";
|
||||
import { i18n } from "./i18n/i18n";
|
||||
import { Root } from "./Root";
|
||||
import { routes } from "./routes";
|
||||
|
||||
import "./index.css";
|
||||
|
||||
const router = createHashRouter([
|
||||
{
|
||||
path: "/",
|
||||
element: <Root />,
|
||||
children: routes
|
||||
}
|
||||
]);
|
||||
const prI18nInitialized = i18n.init();
|
||||
startColorSchemeManagement();
|
||||
|
||||
export default function KcAdminUi() {
|
||||
const [isI18nInitialized, setI18nInitialized] = useReducer(() => true, false);
|
||||
|
||||
useEffect(() => {
|
||||
prI18nInitialized.then(() => setI18nInitialized());
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isI18nInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
const updateDocumentTitle = () => {
|
||||
document.title = i18n.t("nexusAdminConsoleTitle");
|
||||
};
|
||||
|
||||
updateDocumentTitle();
|
||||
i18n.on("languageChanged", updateDocumentTitle);
|
||||
|
||||
return () => {
|
||||
i18n.off("languageChanged", updateDocumentTitle);
|
||||
};
|
||||
}, [isI18nInitialized]);
|
||||
|
||||
if (!isI18nInitialized) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <RouterProvider router={router} />;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -47,8 +47,8 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="nexus-email-meta">
|
||||
IDENTITY ACCESS LAYER / <span class="nexus-email-online">SECURE MESSAGE</span><br>
|
||||
This message was generated automatically. Please do not reply.
|
||||
${msg("nexusIdentityAccessLayer")} / <span class="nexus-email-online">${msg("nexusSecureMessage")}</span><br>
|
||||
${msg("nexusAutomatedMessageNotice")}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
# This file has been claimed for ownership from @keycloakify/email-native version 260007.0.0.
|
||||
# To relinquish ownership and restore this file to its original content, run the following command:
|
||||
#
|
||||
# $ npx keycloakify own --path "email/messages/messages_en.properties" --revert
|
||||
|
||||
# IMPORTANT: This file contains the base translation. Modifying it directly is not recommended.
|
||||
# To override or add custom messages, create a file named messages_en_override.properties in the same directory.
|
||||
# This file will be automatically loaded and merged with the base translation.
|
||||
# If you're implementing theme variants, you can also create variant-specific `.properties` files.
|
||||
# For example let's say you have defined `themeName: ["vanilla", "chocolate"]` then you can create the following files:
|
||||
# messages_en_override_vanilla.properties
|
||||
# messages_en_override_chocolate.properties
|
||||
|
||||
emailVerificationSubject=Verify email
|
||||
emailVerificationBody=Someone has created a {2} account with this email address. If this was you, click the link below to verify your email address\n\n{0}\n\nThis link will expire within {3}.\n\nIf you didn''t create this account, just ignore this message.
|
||||
emailVerificationBodyHtml=<p>Someone has created a {2} account with this email address. If this was you, click the link below to verify your email address</p><p><a href="{0}">Link to e-mail address verification</a></p><p>This link will expire within {3}.</p><p>If you didn''t create this account, just ignore this message.</p>
|
||||
orgInviteSubject=Invitation to join the {0} organization
|
||||
orgInviteBody=You were invited to join the "{3}" organization. Click the link below to join.\n\n{0}\n\nThis link will expire within {4}.\n\nIf you don't want to join the organization, just ignore this message.
|
||||
orgInviteBodyHtml=<p>You were invited to join the {3} organization. Click the link below to join. </p><p><a href="{0}">Link to join the organization</a></p><p>This link will expire within {4}.</p><p>If you don't want to join the organization, just ignore this message.</p>
|
||||
orgInviteBodyPersonalized=Hi, "{5}" "{6}".\n\n You were invited to join the "{3}" organization. Click the link below to join.\n\n{0}\n\nThis link will expire within {4}.\n\nIf you don't want to join the organization, just ignore this message.
|
||||
orgInviteBodyPersonalizedHtml=<p>Hi, {5} {6}.</p><p>You were invited to join the {3} organization. Click the link below to join. </p><p><a href="{0}">Link to join the organization</a></p><p>This link will expire within {4}.</p><p>If you don't want to join the organization, just ignore this message.</p>
|
||||
emailUpdateConfirmationSubject=Verify new email
|
||||
emailUpdateConfirmationBody=To update your {2} account with email address {1}, click the link below\n\n{0}\n\nThis link will expire within {3}.\n\nIf you don''t want to proceed with this modification, just ignore this message.
|
||||
emailUpdateConfirmationBodyHtml=<p>To update your {2} account with email address {1}, click the link below</p><p><a href="{0}">{0}</a></p><p>This link will expire within {3}.</p><p>If you don''t want to proceed with this modification, just ignore this message.</p>
|
||||
emailTestSubject=[KEYCLOAK] - SMTP test message
|
||||
emailTestBody=This is a test message
|
||||
emailTestBodyHtml=<p>This is a test message</p>
|
||||
identityProviderLinkSubject=Link {0}
|
||||
identityProviderLinkBody=Someone wants to link your "{1}" account with "{0}" account of user {2} . If this was you, click the link below to link accounts\n\n{3}\n\nThis link will expire within {5}.\n\nIf you don''t want to link account, just ignore this message. If you link accounts, you will be able to login to {1} through {0}.
|
||||
identityProviderLinkBodyHtml=<p>Someone wants to link your <b>{1}</b> account with <b>{0}</b> account of user {2}. If this was you, click the link below to link accounts</p><p><a href="{3}">Link to confirm account linking</a></p><p>This link will expire within {5}.</p><p>If you don''t want to link account, just ignore this message. If you link accounts, you will be able to login to {1} through {0}.</p>
|
||||
passwordResetSubject=Reset password
|
||||
passwordResetBody=Someone just requested to change your {2} account''s credentials. If this was you, click on the link below to reset them.\n\n{0}\n\nThis link and code will expire within {3}.\n\nIf you don''t want to reset your credentials, just ignore this message and nothing will be changed.
|
||||
passwordResetBodyHtml=<p>Someone just requested to change your {2} account''s credentials. If this was you, click on the link below to reset them.</p><p><a href="{0}">Link to reset credentials</a></p><p>This link will expire within {3}.</p><p>If you don''t want to reset your credentials, just ignore this message and nothing will be changed.</p>
|
||||
executeActionsSubject=Update Your Account
|
||||
executeActionsBody=Your administrator has just requested that you update your {2} account by performing the following action(s): {3}. Click on the link below to start this process.\n\n{0}\n\nThis link will expire within {4}.\n\nIf you are unaware that your administrator has requested this, just ignore this message and nothing will be changed.
|
||||
executeActionsBodyHtml=<p>Your administrator has just requested that you update your {2} account by performing the following action(s): {3}. Click on the link below to start this process.</p><p><a href="{0}">Link to account update</a></p><p>This link will expire within {4}.</p><p>If you are unaware that your administrator has requested this, just ignore this message and nothing will be changed.</p>
|
||||
eventLoginErrorSubject=Login error
|
||||
eventLoginErrorBody=A failed login attempt was detected to your account on {0} from {1}. If this was not you, please contact an administrator.
|
||||
eventLoginErrorBodyHtml=<p>A failed login attempt was detected to your account on {0} from {1}. If this was not you, please contact an administrator.</p>
|
||||
eventRemoveTotpSubject=Remove OTP
|
||||
eventRemoveTotpBody=OTP was removed from your account on {0} from {1}. If this was not you, please contact an administrator.
|
||||
eventRemoveTotpBodyHtml=<p>OTP was removed from your account on {0} from {1}. If this was not you, please contact an administrator.</p>
|
||||
eventUpdatePasswordSubject=Update password
|
||||
eventUpdatePasswordBody=Your password was changed on {0} from {1}. If this was not you, please contact an administrator.
|
||||
eventUpdatePasswordBodyHtml=<p>Your password was changed on {0} from {1}. If this was not you, please contact an administrator.</p>
|
||||
eventUpdateTotpSubject=Update OTP
|
||||
eventUpdateTotpBody=OTP was updated for your account on {0} from {1}. If this was not you, please contact an administrator.
|
||||
eventUpdateTotpBodyHtml=<p>OTP was updated for your account on {0} from {1}. If this was not you, please contact an administrator.</p>
|
||||
eventUpdateCredentialSubject=Update credential
|
||||
eventUpdateCredentialBody=Your {0} credential was changed on {1} from {2}. If this was not you, please contact an administrator.
|
||||
eventUpdateCredentialBodyHtml=<p>Your {0} credential was changed on {1} from {2}. If this was not you, please contact an administrator.</p>
|
||||
eventRemoveCredentialSubject=Remove credential
|
||||
eventRemoveCredentialBody=Credential {0} was removed from your account on {1} from {2}. If this was not you, please contact an administrator.
|
||||
eventRemoveCredentialBodyHtml=<p>Credential {0} was removed from your account on {1} from {2}. If this was not you, please contact an administrator.</p>
|
||||
eventUserDisabledByTemporaryLockoutSubject=User disabled by temporary lockout
|
||||
eventUserDisabledByTemporaryLockoutBody=Your user has been disabled temporarily because of multiple failed attemps on {0}. Please contact an administrator if needed.
|
||||
eventUserDisabledByTemporaryLockoutHtml=<p>Your user has been disabled temporarily because of multiple failed attemps on {0}. Please contact an administrator if needed.</p>
|
||||
eventUserDisabledByPermanentLockoutSubject=User disabled by permament lockout
|
||||
eventUserDisabledByPermanentLockoutBody=Your user has been disabled permanently because of multiple failed attemps on {0}. Please contact an administrator.
|
||||
eventUserDisabledByPermanentLockoutHtml=<p>Your user has been disabled permanently because of multiple failed attemps on {0}. Please contact an administrator.</p>
|
||||
|
||||
requiredAction.CONFIGURE_TOTP=Configure OTP
|
||||
requiredAction.TERMS_AND_CONDITIONS=Terms and Conditions
|
||||
requiredAction.UPDATE_PASSWORD=Update Password
|
||||
requiredAction.UPDATE_PROFILE=Update Profile
|
||||
requiredAction.VERIFY_EMAIL=Verify Email
|
||||
requiredAction.CONFIGURE_RECOVERY_AUTHN_CODES=Generate Recovery Codes
|
||||
|
||||
# units for link expiration timeout formatting
|
||||
# for languages which have more unit plural forms depending on the value (eg. Czech and other Slavic langs) you can override unit text for some other values like described in the Java choice format which is documented here. For Czech, it would be '{0,choice,0#minut|1#minuta|2#minuty|2<minut}'
|
||||
# https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/text/MessageFormat.html
|
||||
# https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/text/ChoiceFormat.html
|
||||
linkExpirationFormatter.timePeriodUnit.seconds={0,choice,0#seconds|1#second|1<seconds}
|
||||
linkExpirationFormatter.timePeriodUnit.minutes={0,choice,0#minutes|1#minute|1<minutes}
|
||||
linkExpirationFormatter.timePeriodUnit.hours={0,choice,0#hours|1#hour|1<hours}
|
||||
linkExpirationFormatter.timePeriodUnit.days={0,choice,0#days|1#day|1<days}
|
||||
|
||||
emailVerificationBodyCode=Please verify your email address by entering in the following code.\n\n{0}\n\n.
|
||||
emailVerificationBodyCodeHtml=<p>Please verify your email address by entering in the following code.</p><p><b>{0}</b></p>
|
||||
nexusIdentityAccessLayer=IDENTITY ACCESS LAYER
|
||||
nexusSecureMessage=SECURE MESSAGE
|
||||
nexusAutomatedMessageNotice=This message was generated automatically. Please do not reply.
|
||||
@@ -0,0 +1,40 @@
|
||||
# This file has been claimed for ownership from @keycloakify/email-native version 260007.0.0.
|
||||
# To relinquish ownership and restore this file to its original content, run the following command:
|
||||
#
|
||||
# $ npx keycloakify own --path "email/messages/messages_zh_CN.properties" --revert
|
||||
|
||||
# IMPORTANT: This file contains the base translation. Modifying it directly is not recommended.
|
||||
# To override or add custom messages, create a file named messages_zh_CN_override.properties in the same directory.
|
||||
# This file will be automatically loaded and merged with the base translation.
|
||||
# If you're implementing theme variants, you can also create variant-specific `.properties` files.
|
||||
# For example let's say you have defined `themeName: ["vanilla", "chocolate"]` then you can create the following files:
|
||||
# messages_zh_CN_override_vanilla.properties
|
||||
# messages_zh_CN_override_chocolate.properties
|
||||
|
||||
emailVerificationSubject=验证电子邮件
|
||||
emailVerificationBody=用户使用当前电子邮件注册 {2} 账户。如是本人操作,请点击以下链接完成邮箱验证\n\n{0}\n\n这个链接会在 {1} 分钟后过期.\n\n如果您没有注册用户,请忽略这条消息。
|
||||
emailVerificationBodyHtml=<p>用户使用当前电子邮件注册 {2} 账户。如是本人操作,请点击以下链接完成邮箱验证</p><p><a href="{0}">{0}</a></p><p>这个链接会在 {1} 分钟后过期.</p><p>如果您没有注册用户,请忽略这条消息。</p>
|
||||
identityProviderLinkSubject=链接 {0}
|
||||
identityProviderLinkBody=有用户想要将账户 "{1}" 与用户{2}的账户"{0}" 做链接 . 如果是本人操作,请点击以下链接完成链接请求\n\n{3}\n\n这个链接会在 {4} 分钟后过期.\n\n如非本人操作,请忽略这条消息。如果您链接账户,您将可以通过{0}登录账户 {1}.
|
||||
identityProviderLinkBodyHtml=<p>有用户想要将账户 <b>{1}</b> 与用户{2} 的账户<b>{0}</b> 做链接 . 如果是本人操作,请点击以下链接完成链接请求</p><p><a href="{3}">{3}</a></p><p>这个链接会在 {4} 分钟后过期。</p><p>如非本人操作,请忽略这条消息。如果您链接账户,您将可以通过{0}登录账户 {1}.</p>
|
||||
passwordResetSubject=重置密码
|
||||
passwordResetBody=有用户要求修改账户 {2} 的密码.如是本人操作,请点击下面链接进行重置.\n\n{0}\n\n这个链接会在 {1} 分钟后过期.\n\n如果您不想重置您的密码,请忽略这条消息,密码不会改变。
|
||||
passwordResetBodyHtml=<p>有用户要求修改账户 {2} 的密码如是本人操作,请点击下面链接进行重置.</p><p><a href="{0}">{0}</a></p><p>这个链接会在 {1} 分钟后过期</p><p>如果您不想重置您的密码,请忽略这条消息,密码不会改变。</p>
|
||||
executeActionsSubject=更新您的账户
|
||||
executeActionsBody=您的管理员要求您更新账户 {2}. 点击以下链接开始更新\n\n{0}\n\n这个链接会在 {1} 分钟后失效.\n\n如果您不知道管理员要求更新账户信息,请忽略这条消息。账户信息不会修改。
|
||||
executeActionsBodyHtml=<p>您的管理员要求您更新账户{2}. 点击以下链接开始更新.</p><p><a href="{0}">{0}</a></p><p>这个链接会在 {1} 分钟后失效.</p><p>如果您不知道管理员要求更新账户信息,请忽略这条消息。账户信息不会修改。</p>
|
||||
eventLoginErrorSubject=登录错误
|
||||
eventLoginErrorBody=在{0} 由 {1}使用您的账户登录失败. 如果这不是您本人操作,请联系管理员.
|
||||
eventLoginErrorBodyHtml=<p>在{0} 由 {1}使用您的账户登录失败. 如果这不是您本人操作,请联系管理员.</p>
|
||||
eventRemoveTotpSubject=删除 OTP
|
||||
eventRemoveTotpBody=OTP在 {0} 由{1} 从您的账户中删除.如果这不是您本人操作,请联系管理员
|
||||
eventRemoveTotpBodyHtml=<p>OTP在 {0} 由{1} 从您的账户中删除.如果这不是您本人操作,请联系管理员。</p>
|
||||
eventUpdatePasswordSubject=更新密码
|
||||
eventUpdatePasswordBody=您的密码在{0} 由 {1}更改. 如非本人操作,请联系管理员
|
||||
eventUpdatePasswordBodyHtml=<p>您的密码在{0} 由 {1}更改. 如非本人操作,请联系管理员</p>
|
||||
eventUpdateTotpSubject=更新 OTP
|
||||
eventUpdateTotpBody=您账户的OTP 配置在{0} 由 {1}更改. 如非本人操作,请联系管理员。
|
||||
eventUpdateTotpBodyHtml=<p>您账户的OTP 配置在{0} 由 {1}更改. 如非本人操作,请联系管理员。</p>
|
||||
nexusIdentityAccessLayer=身份访问层
|
||||
nexusSecureMessage=安全消息
|
||||
nexusAutomatedMessageNotice=此邮件由系统自动生成,请勿直接回复。
|
||||
@@ -0,0 +1,65 @@
|
||||
# This file has been claimed for ownership from @keycloakify/email-native version 260007.0.0.
|
||||
# To relinquish ownership and restore this file to its original content, run the following command:
|
||||
#
|
||||
# $ npx keycloakify own --path "email/messages/messages_zh_TW.properties" --revert
|
||||
|
||||
# IMPORTANT: This file contains the base translation. Modifying it directly is not recommended.
|
||||
# To override or add custom messages, create a file named messages_zh_TW_override.properties in the same directory.
|
||||
# This file will be automatically loaded and merged with the base translation.
|
||||
# If you're implementing theme variants, you can also create variant-specific `.properties` files.
|
||||
# For example let's say you have defined `themeName: ["vanilla", "chocolate"]` then you can create the following files:
|
||||
# messages_zh_TW_override_vanilla.properties
|
||||
# messages_zh_TW_override_chocolate.properties
|
||||
|
||||
emailVerificationSubject=驗證電子信箱
|
||||
emailVerificationBody=有人使用了這個電子信箱建立了一個 {2} 帳號。如果這是您的操作,請點擊下列連結驗證您的電子信箱\n\n{0}\n\n此連結將在 {3} 內失效。\n\n如果這不是您的操作,請忽略此訊息。
|
||||
emailVerificationBodyHtml=<p>有人使用了這個電子信箱建立了一個 {2} 帳號。如果這是您的操作,請點擊下列連結驗證您的電子信箱</p><p><a href="{0}">驗證電子信箱連結</a></p><p>此連結將在 {3} 內失效。</p><p>如果您沒有建立帳號,請忽略此訊息。</p>
|
||||
emailUpdateConfirmationSubject=驗證新的電子信箱
|
||||
emailUpdateConfirmationBody=為了更新您的 {2} 帳號的電子信箱 {1},請點擊下列連結\n\n{0}\n\n此連結將在 {3} 內失效。\n\n如果您不想進行這個修改,請忽略此訊息。
|
||||
emailUpdateConfirmationBodyHtml=<p>為了更新您的 {2} 帳號的電子信箱 {1},請點擊下列連結</p><p><a href="{0}">{0}</a></p><p>此連結將在 {3} 內失效。</p><p>如果您不想進行這個修改,請忽略此訊息。</p>
|
||||
emailTestSubject=[KEYCLOAK] - SMTP 測試訊息
|
||||
emailTestBody=這是一個測試訊息
|
||||
emailTestBodyHtml=<p>這是一個測試訊息</p>
|
||||
identityProviderLinkSubject=連結到 {0}
|
||||
identityProviderLinkBody=有人試圖連結您的 "{1}" 帳號與使用者 {2} 的 "{0}" 帳號。如果這是您的操作,請點擊下列連結連結帳號\n\n{3}\n\n此連結將在 {5} 內失效。\n\n如果這不是您的操作,請忽略此訊息。如果您連結帳號,您將能夠透過 {0} 登入 {1}。
|
||||
identityProviderLinkBodyHtml=<p>有人試圖連結您的 <b>{1}</b> 帳號與使用者 {2} 的 <b>{0}</b> 帳號。如果這是您的操作,請點擊下列連結連結帳號</p><p><a href="{3}">確認連結帳號</a></p><p>此連結將在 {5} 內失效。</p><p>如果這不是您的操作,請忽略此訊息。如果您連結帳號,您將能夠透過 {0} 登入 {1}。</p>
|
||||
passwordResetSubject=重設密碼
|
||||
passwordResetBody=有人剛剛要求重設您 {2} 的密碼。如果這是您的操作,請點擊下列連結重設它們。\n\n{0}\n\n此連結和代碼將在 {3} 內失效。\n\n如果您不想重設您的密碼,請忽略此訊息。
|
||||
passwordResetBodyHtml=<p>有人剛剛要求重設您 {2} 的密碼。如果這是您的操作,請點擊下列連結重設它們。</p><p><a href="{0}">重設密碼連結</a></p><p>此連結和代碼將在 {3} 內失效。</p><p>如果您不想重設您的密碼,請忽略此訊息,甚麼都不會改變。</p>
|
||||
executeActionsSubject=更新您的帳號
|
||||
executeActionsBody=您的管理員剛剛要求您更新您的 {2} 帳號,透過執行以下動作:{3}。點擊下列連結開始這個流程。\n\n{0}\n\n此連結將在 {4} 內失效。\n\n如果您不知道您的管理員剛剛要求這個,請忽略此訊息,甚麼都不會改變。
|
||||
executeActionsBodyHtml=<p>您的管理員剛剛要求您更新您的 {2} 帳號,透過執行以下動作:{3}。點擊下列連結開始這個流程。</p><p><a href="{0}">更新帳號連結</a></p><p>此連結將在 {4} 內失效。</p><p>如果您不知道您的管理員剛剛要求這個,請忽略此訊息,甚麼都不會改變。</p>
|
||||
eventLoginErrorSubject=登入錯誤
|
||||
eventLoginErrorBody=登入失敗,偵測到您的帳號在 {0} 從 {1} 進行登入。如果這不是您的操作,請聯絡系統管理員。
|
||||
eventLoginErrorBodyHtml=<p>登入失敗,偵測到您的帳號在 {0} 從 {1} 進行登入。如果這不是您的操作,請聯絡系統管理員。</p>
|
||||
eventRemoveTotpSubject=移除 OTP 設定
|
||||
eventRemoveTotpBody=在 {0} OTP 設定已從您的帳號 {1} 移除。如果這不是您的操作,請聯絡系統管理員。
|
||||
eventRemoveTotpBodyHtml=<p>在 {0} OTP 設定已從您的帳號 {1} 移除。如果這不是您的操作,請聯絡系統管理員。</p>
|
||||
eventUpdatePasswordSubject=更新密碼
|
||||
eventUpdatePasswordBody=您的密碼已在 {0} 從 {1} 更改。如果這不是您的操作,請聯絡系統管理員。
|
||||
eventUpdatePasswordBodyHtml=<p>您的密碼已在 {0} 從 {1} 更改。如果這不是您的操作,請聯絡系統管理員。</p>
|
||||
eventUpdateTotpSubject=更新 OTP 設定
|
||||
eventUpdateTotpBody=您帳號的 OTP 設定已在 {0} 從 {1} 更新。如果這不是您的操作,請聯絡系統管理員。
|
||||
eventUpdateTotpBodyHtml=<p>您帳號的 OTP 設定已在 {0} 從 {1} 更新。如果這不是您的操作,請聯絡系統管理員。</p>
|
||||
|
||||
requiredAction.CONFIGURE_TOTP=設定 OTP
|
||||
requiredAction.TERMS_AND_CONDITIONS=服務條款
|
||||
requiredAction.UPDATE_PASSWORD=更新密碼
|
||||
requiredAction.UPDATE_PROFILE=更新個人資訊
|
||||
requiredAction.VERIFY_EMAIL=驗證電子信箱
|
||||
requiredAction.CONFIGURE_RECOVERY_AUTHN_CODES=產生復原代碼
|
||||
|
||||
# units for link expiration timeout formatting
|
||||
# for languages which have more unit plural forms depending on the value (eg. Czech and other Slavic langs) you can override unit text for some other values like described in the Java choice format which is documented here. For Czech, it would be '{0,choice,0#minut|1#minuta|2#minuty|2<minut}'
|
||||
# https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/text/MessageFormat.html
|
||||
# https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/text/ChoiceFormat.html
|
||||
linkExpirationFormatter.timePeriodUnit.seconds=秒
|
||||
linkExpirationFormatter.timePeriodUnit.minutes=分
|
||||
linkExpirationFormatter.timePeriodUnit.hours=小時
|
||||
linkExpirationFormatter.timePeriodUnit.days=天
|
||||
|
||||
emailVerificationBodyCode=驗證您的電子信箱,請輸入以下代碼。\n\n{0}\n\n.
|
||||
emailVerificationBodyCodeHtml=<p>驗證您的電子信箱,請輸入以下代碼。</p><p><b>{0}</b></p>
|
||||
nexusIdentityAccessLayer=身分存取層
|
||||
nexusSecureMessage=安全訊息
|
||||
nexusAutomatedMessageNotice=此郵件由系統自動產生,請勿直接回覆。
|
||||
@@ -4,6 +4,8 @@ import type { KcContext } from "./KcContext";
|
||||
import type { I18n } from "./i18n";
|
||||
|
||||
export default function Template(props: TemplateProps<KcContext, I18n>) {
|
||||
const { msg } = props.i18n;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="nexus-atmosphere" aria-hidden="true">
|
||||
@@ -25,15 +27,15 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
|
||||
NEXUS <b>/ ID</b>
|
||||
</div>
|
||||
<div className="nexus-manifesto__copy">
|
||||
<p>IDENTITY ACCESS LAYER</p>
|
||||
<p>{msg("nexusIdentityAccessLayer")}</p>
|
||||
<h2>
|
||||
Secure access.
|
||||
<span>Precisely orchestrated.</span>
|
||||
{msg("nexusSecureAccess")}
|
||||
<span>{msg("nexusPreciselyOrchestrated")}</span>
|
||||
</h2>
|
||||
</div>
|
||||
<div className="nexus-system-status">
|
||||
<span>SECURE CHANNEL</span>
|
||||
<span className="nexus-system-status__state">SYSTEM ONLINE</span>
|
||||
<span>{msg("nexusSecureChannel")}</span>
|
||||
<span className="nexus-system-status__state">{msg("nexusSystemOnline")}</span>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
|
||||
+26
-1
@@ -3,7 +3,32 @@ import { i18nBuilder } from "keycloakify/login";
|
||||
import type { ThemeName } from "../kc.gen";
|
||||
|
||||
/** @see: https://docs.keycloakify.dev/features/i18n */
|
||||
const { useI18n, ofTypeI18n } = i18nBuilder.withThemeName<ThemeName>().build();
|
||||
const { useI18n, ofTypeI18n } = i18nBuilder
|
||||
.withThemeName<ThemeName>()
|
||||
.withCustomTranslations({
|
||||
en: {
|
||||
nexusIdentityAccessLayer: "IDENTITY ACCESS LAYER",
|
||||
nexusSecureAccess: "Secure access.",
|
||||
nexusPreciselyOrchestrated: "Precisely orchestrated.",
|
||||
nexusSecureChannel: "SECURE CHANNEL",
|
||||
nexusSystemOnline: "SYSTEM ONLINE"
|
||||
},
|
||||
"zh-CN": {
|
||||
nexusIdentityAccessLayer: "身份访问层",
|
||||
nexusSecureAccess: "安全访问。",
|
||||
nexusPreciselyOrchestrated: "精准编排。",
|
||||
nexusSecureChannel: "安全通道",
|
||||
nexusSystemOnline: "系统在线"
|
||||
},
|
||||
"zh-TW": {
|
||||
nexusIdentityAccessLayer: "身分存取層",
|
||||
nexusSecureAccess: "安全存取。",
|
||||
nexusPreciselyOrchestrated: "精準編排。",
|
||||
nexusSecureChannel: "安全通道",
|
||||
nexusSystemOnline: "系統在線"
|
||||
}
|
||||
})
|
||||
.build();
|
||||
|
||||
type I18n = typeof ofTypeI18n;
|
||||
|
||||
|
||||
@@ -16,6 +16,26 @@ export const Default: Story = {
|
||||
render: () => <KcPageStory />
|
||||
};
|
||||
|
||||
export const SimplifiedChinese: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
locale: { currentLanguageTag: "zh-CN" }
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
export const TraditionalChinese: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
locale: { currentLanguageTag: "zh-TW" }
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
export const WithInvalidCredential: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
|
||||
Reference in New Issue
Block a user