From a47008678f02ab1045c19f277e929465f92fbfee Mon Sep 17 00:00:00 2001 From: Bivan Alzacky Harmanto Date: Wed, 15 Jan 2025 14:17:19 +0800 Subject: [PATCH] feat(upgrade): upgrade keycloakify to v11 --- package.json | 2 +- src/kc.gen.tsx | 52 +++++++------- src/login/Template.tsx | 11 ++- src/login/components/LocaleDropdown/index.tsx | 24 +++---- src/login/i18n.ts | 70 ++++++++++--------- yarn.lock | 12 ++-- 6 files changed, 83 insertions(+), 88 deletions(-) diff --git a/package.json b/package.json index 3ce71ef..125dd71 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "@emotion/react": "^11.13.5", "@emotion/styled": "^11.13.5", "framer-motion": "^11.2.0", - "keycloakify": "^10.1.6", + "keycloakify": "^11", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/src/kc.gen.tsx b/src/kc.gen.tsx index ae262e4..796d1d7 100644 --- a/src/kc.gen.tsx +++ b/src/kc.gen.tsx @@ -1,4 +1,5 @@ -/* prettier-ignore-start */ +// This file is auto-generated by the `update-kc-gen` command. Do not edit it manually. +// Hash: 9ae0fc6db02c7aaca5511c810584dc11912602c9a6a8c8f778a301e8e52807fc /* eslint-disable */ @@ -6,8 +7,6 @@ // noinspection JSUnusedGlobalSymbols -// This file is auto-generated by Keycloakify - import { lazy, Suspense, type ReactNode } from "react"; export type ThemeName = "coursemology-keycloakify"; @@ -19,37 +18,34 @@ export type KcEnvName = "MY_ENV_VARIABLE"; export const kcEnvNames: KcEnvName[] = ["MY_ENV_VARIABLE"]; export const kcEnvDefaults: Record = { - "MY_ENV_VARIABLE": "" + MY_ENV_VARIABLE: "", }; -export type KcContext = - | import("./login/KcContext").KcContext - ; +/** + * NOTE: Do not import this type except maybe in your entrypoint. + * If you need to import the KcContext import it either from src/login/KcContext.ts or src/account/KcContext.ts. + * Depending on the theme type you are working on. + */ +export type KcContext = import("./login/KcContext").KcContext; declare global { - interface Window { - kcContext?: KcContext; - } + interface Window { + kcContext?: KcContext; + } } export const KcLoginPage = lazy(() => import("./login/KcPage")); -export function KcPage( - props: { - kcContext: KcContext; - fallback?: ReactNode; - } -) { - const { kcContext, fallback } = props; - return ( - - {(() => { - switch (kcContext.themeType) { - case "login": return ; - } - })()} - - ); +export function KcPage(props: { kcContext: KcContext; fallback?: ReactNode }) { + const { kcContext, fallback } = props; + return ( + + {(() => { + switch (kcContext.themeType) { + case "login": + return ; + } + })()} + + ); } - -/* prettier-ignore-end */ diff --git a/src/login/Template.tsx b/src/login/Template.tsx index 1135f5f..c61fbef 100644 --- a/src/login/Template.tsx +++ b/src/login/Template.tsx @@ -1,5 +1,6 @@ // Original file: https://github.com/InseeFrLab/keycloakify/blob/main/src/login/Template.tsx +import { kcSanitize } from "keycloakify/lib/kcSanitize"; import { type TemplateProps as KeycloakTemplateProps } from "keycloakify/login/TemplateProps"; import AlertBox from "src/lib/components/core/AlertBox"; @@ -21,9 +22,9 @@ const Template = (props: KeycloakTemplateProps) => { children, } = props; - const { msg } = i18n; + const { msg, enabledLanguages } = i18n; - const { realm, locale, message, isAppInitiatedAction } = kcContext; + const { realm, message, isAppInitiatedAction } = kcContext; const { homeUrl } = useCoursemologyUrls(); return ( @@ -33,9 +34,7 @@ const Template = (props: KeycloakTemplateProps) => { textNode={msg("loginTitleHtml", realm.displayNameHtml)} brandUrl={homeUrl} /> - {realm.internationalizationEnabled && ( - - )} + {enabledLanguages.length > 1 && }
@@ -48,7 +47,7 @@ const Template = (props: KeycloakTemplateProps) => { diff --git a/src/login/components/LocaleDropdown/index.tsx b/src/login/components/LocaleDropdown/index.tsx index f56640d..c3647dc 100644 --- a/src/login/components/LocaleDropdown/index.tsx +++ b/src/login/components/LocaleDropdown/index.tsx @@ -1,43 +1,37 @@ import { ChevronDownIcon } from "@chakra-ui/icons"; import { Button, Menu, MenuButton, MenuItem, MenuList } from "@chakra-ui/react"; -import { assert } from "keycloakify/tools/assert"; import type { I18n } from "../../i18n"; -import type { KcContext } from "../../KcContext"; interface LocaleDropdownProps { - locale: KcContext["locale"]; i18n: I18n; } const LocaleDropdown = (props: LocaleDropdownProps): JSX.Element | null => { - const { locale, i18n } = props; - const { - getChangeLocaleUrl, - labelBySupportedLanguageTag, - currentLanguageTag, - } = i18n; + const { i18n } = props; + const { currentLanguage, enabledLanguages } = i18n; - return (assert(locale !== undefined), true) && locale.supported.length > 1 ? ( + return (
}> - {labelBySupportedLanguageTag[currentLanguageTag]} + {currentLanguage.label} - {locale.supported.map(({ languageTag }) => ( + {enabledLanguages.map(({ languageTag, label, href }, i) => ( - {labelBySupportedLanguageTag[languageTag]} + {label} ))}
- ) : null; + ); }; export default LocaleDropdown; diff --git a/src/login/i18n.ts b/src/login/i18n.ts index 381e29a..e7af65b 100644 --- a/src/login/i18n.ts +++ b/src/login/i18n.ts @@ -1,34 +1,40 @@ -import { createUseI18n } from "keycloakify/login"; +import { i18nBuilder } from "keycloakify/login"; +import type { ThemeName } from "src/kc.gen"; -export const { useI18n, ofTypeI18n } = createUseI18n({ - // NOTE: Here you can override the default i18n messages - // or define new ones that, for example, you would have - // defined in the Keycloak admin UI for UserProfile - // https://user-images.githubusercontent.com/6702424/182050652-522b6fe6-8ee5-49df-aca3-dba2d33f24a5.png - en: { - // Here we overwrite the default english value for the message "doForgotPassword" - // that is "Forgot Password?" see: https://github.com/InseeFrLab/keycloakify/blob/f0ae5ea908e0aa42391af323b6d5e2fd371af851/src/lib/i18n/generated_messages/18.0.1/login/en.ts#L17 - doRegister: "Sign up", - dontYetHaveAnAccount: "Don't yet have an account?", - forgotPassword: "Forgot Password", - rememberMe: "Remember me on this device", - resendConfirmationEmail: "Resend confirmation email", - troubleSigningIn: "Trouble signing in?", - usernameOrEmail: "Email address", - emailNotVerified: - "Your email account has not been verified. Please verify your email before proceeding.", - }, - "zh-CN": { - doRegister: "注册", - dontYetHaveAnAccount: "还没有账户?", - forgotPassword: "忘记密码", - rememberMe: "在这台设备上记住我", - resendConfirmationEmail: "重新发送确认邮件", - troubleSigningIn: "登录遇到问题?", - usernameOrEmail: "电子邮箱地址", - emailNotVerified: - "您的电子邮件帐户尚未经过验证。 请在继续之前验证您的电子邮件。", - }, -}); +const { useI18n, ofTypeI18n } = i18nBuilder + .withThemeName() + .withCustomTranslations({ + // NOTE: Here you can override the default i18n messages + // or define new ones that, for example, you would have + // defined in the Keycloak admin UI for UserProfile + // https://user-images.githubusercontent.com/6702424/182050652-522b6fe6-8ee5-49df-aca3-dba2d33f24a5.png + en: { + // Here we overwrite the default english value for the message "doForgotPassword" + // that is "Forgot Password?" see: https://github.com/InseeFrLab/keycloakify/blob/f0ae5ea908e0aa42391af323b6d5e2fd371af851/src/lib/i18n/generated_messages/18.0.1/login/en.ts#L17 + doRegister: "Sign up", + dontYetHaveAnAccount: "Don't yet have an account?", + forgotPassword: "Forgot Password", + rememberMe: "Remember me on this device", + resendConfirmationEmail: "Resend confirmation email", + troubleSigningIn: "Trouble signing in?", + usernameOrEmail: "Email address", + emailNotVerified: + "Your email account has not been verified. Please verify your email before proceeding.", + }, + "zh-CN": { + doRegister: "注册", + dontYetHaveAnAccount: "还没有账户?", + forgotPassword: "忘记密码", + rememberMe: "在这台设备上记住我", + resendConfirmationEmail: "重新发送确认邮件", + troubleSigningIn: "登录遇到问题?", + usernameOrEmail: "电子邮箱地址", + emailNotVerified: + "您的电子邮件帐户尚未经过验证。 请在继续之前验证您的电子邮件。", + }, + }) + .build(); -export type I18n = typeof ofTypeI18n; +type I18n = typeof ofTypeI18n; + +export { type I18n, useI18n }; diff --git a/yarn.lock b/yarn.lock index 3ba114d..3dbaa42 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2308,12 +2308,12 @@ json5@^2.2.2, json5@^2.2.3: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== -keycloakify@^10.1.6: - version "10.1.6" - resolved "https://registry.yarnpkg.com/keycloakify/-/keycloakify-10.1.6.tgz#f948c0167b2fa64b851c99c2dac029fff496b1a0" - integrity sha512-yuCOM2xHxph8mmxWdK7BmsvkDfo42YOO2oqY0U94MGaBuYaSUqmUQC9dednvyApx2IndzBhd9C18H/86wvIx6Q== +keycloakify@^11: + version "11.8.9" + resolved "https://registry.yarnpkg.com/keycloakify/-/keycloakify-11.8.9.tgz#0e603e544e37c4dafac518f506c7200103c9077a" + integrity sha512-puYkK+4VfkmDfcfT4XkDAEUQfoObAon2+L+8YchBCvcGFcL8c1JkF8S1lLHX9AMuFWX1FW0r7Ye7zGJIpvcz1w== dependencies: - tsafe "^1.6.6" + tsafe "^1.8.5" keyv@^4.5.3: version "4.5.4" @@ -3172,7 +3172,7 @@ ts-interface-checker@^0.1.9: resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== -tsafe@^1.6.6: +tsafe@^1.8.5: version "1.8.5" resolved "https://registry.yarnpkg.com/tsafe/-/tsafe-1.8.5.tgz#cdf9fa3111974ac480d7ee519f8241815e5d22ea" integrity sha512-LFWTWQrW6rwSY+IBNFl2ridGfUzVsPwrZ26T4KUJww/py8rzaQ/SY+MIz6YROozpUCaRcuISqagmlwub9YT9kw==