diff --git a/js/apps/account-ui/package.json b/js/apps/account-ui/package.json index 104e17ea7a..8bcea108ae 100644 --- a/js/apps/account-ui/package.json +++ b/js/apps/account-ui/package.json @@ -11,7 +11,7 @@ "@patternfly/react-core": "^4.276.8", "@patternfly/react-icons": "^4.93.6", "@patternfly/react-table": "^4.113.0", - "i18next": "^22.5.1", + "i18next": "^23.2.0", "i18next-http-backend": "^2.2.1", "keycloak-js": "workspace:*", "keycloak-masthead": "workspace:*", @@ -19,7 +19,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-hook-form": "^7.44.3", - "react-i18next": "^12.3.1", + "react-i18next": "^13.0.0", "react-router-dom": "6.12.1", "ui-shared": "workspace:*" }, diff --git a/js/apps/account-ui/src/account-security/DeviceActivity.tsx b/js/apps/account-ui/src/account-security/DeviceActivity.tsx index 532e0957aa..92927c4176 100644 --- a/js/apps/account-ui/src/account-security/DeviceActivity.tsx +++ b/js/apps/account-ui/src/account-security/DeviceActivity.tsx @@ -18,22 +18,22 @@ import { Tooltip, } from "@patternfly/react-core"; import { - SyncAltIcon, - MobileAltIcon, DesktopIcon, + MobileAltIcon, + SyncAltIcon, } from "@patternfly/react-icons"; -import { TFuncKey } from "i18next"; import { useState } from "react"; import { useTranslation } from "react-i18next"; +import { ContinueCancelModal, useAlerts } from "ui-shared"; import { deleteSession, getDevices } from "../api/methods"; import { + ClientRepresentation, DeviceRepresentation, SessionRepresentation, - ClientRepresentation, } from "../api/representations"; -import { useAlerts, ContinueCancelModal } from "ui-shared"; import useFormatter from "../components/formatter/format-date"; import { Page } from "../components/page/Page"; +import { TFuncKey } from "../i18n"; import { keycloak } from "../keycloak"; import { usePromise } from "../utils/usePromise"; diff --git a/js/apps/account-ui/src/account-security/SigningIn.tsx b/js/apps/account-ui/src/account-security/SigningIn.tsx index add3c43a0b..e8ac936124 100644 --- a/js/apps/account-ui/src/account-security/SigningIn.tsx +++ b/js/apps/account-ui/src/account-security/SigningIn.tsx @@ -15,7 +15,6 @@ import { SplitItem, Title, } from "@patternfly/react-core"; -import { TFuncKey } from "i18next"; import { CSSProperties, useState } from "react"; import { Trans, useTranslation } from "react-i18next"; import { ContinueCancelModal, useAlerts } from "ui-shared"; @@ -28,6 +27,7 @@ import { import { EmptyRow } from "../components/datalist/EmptyRow"; import useFormatter from "../components/format/format-date"; import { Page } from "../components/page/Page"; +import { TFuncKey } from "../i18n"; import { keycloak } from "../keycloak"; import { usePromise } from "../utils/usePromise"; diff --git a/js/apps/account-ui/src/applications/Applications.tsx b/js/apps/account-ui/src/applications/Applications.tsx index f697e43086..8117706c3d 100644 --- a/js/apps/account-ui/src/applications/Applications.tsx +++ b/js/apps/account-ui/src/applications/Applications.tsx @@ -20,13 +20,13 @@ import { ExternalLinkAltIcon, InfoAltIcon, } from "@patternfly/react-icons"; -import { TFuncKey } from "i18next"; import { useState } from "react"; import { useTranslation } from "react-i18next"; +import { ContinueCancelModal, useAlerts } from "ui-shared"; import { deleteConsent, getApplications } from "../api/methods"; import { ClientRepresentation } from "../api/representations"; -import { useAlerts, ContinueCancelModal } from "ui-shared"; import { Page } from "../components/page/Page"; +import { TFuncKey } from "../i18n"; import { usePromise } from "../utils/usePromise"; type Application = ClientRepresentation & { diff --git a/js/apps/account-ui/src/i18n.ts b/js/apps/account-ui/src/i18n.ts index 18498c8bc8..08082ede00 100644 --- a/js/apps/account-ui/src/i18n.ts +++ b/js/apps/account-ui/src/i18n.ts @@ -1,4 +1,4 @@ -import { createInstance } from "i18next"; +import { TFunction, createInstance } from "i18next"; import HttpBackend from "i18next-http-backend"; import { initReactI18next } from "react-i18next"; @@ -8,6 +8,8 @@ import { joinPath } from "./utils/joinPath"; const DEFAULT_LOCALE = "en"; const DEFAULT_NAMESPACE = "translation"; +export type TFuncKey = Parameters[1]; + export const i18n = createInstance({ defaultNS: DEFAULT_NAMESPACE, fallbackLng: DEFAULT_LOCALE, diff --git a/js/apps/account-ui/src/i18next.d.ts b/js/apps/account-ui/src/i18next.d.ts index e284e143ba..8365abae5c 100644 --- a/js/apps/account-ui/src/i18next.d.ts +++ b/js/apps/account-ui/src/i18next.d.ts @@ -3,8 +3,6 @@ import "i18next"; import translation from "../public/locales/en/translation.json"; -export type TranslationKeys = keyof translation; - declare module "i18next" { interface CustomTypeOptions { defaultNS: "translation"; diff --git a/js/apps/account-ui/src/personal-info/FormField.tsx b/js/apps/account-ui/src/personal-info/FormField.tsx index 8d03bbad47..38dca01727 100644 --- a/js/apps/account-ui/src/personal-info/FormField.tsx +++ b/js/apps/account-ui/src/personal-info/FormField.tsx @@ -1,11 +1,11 @@ import { FormGroup, Select, SelectOption } from "@patternfly/react-core"; -import { TFuncKey } from "i18next"; import { get } from "lodash-es"; import { useState } from "react"; -import { useFormContext, Controller } from "react-hook-form"; +import { Controller, useFormContext } from "react-hook-form"; import { useTranslation } from "react-i18next"; import { KeycloakTextInput } from "ui-shared"; import { UserProfileAttributeMetadata } from "../api/representations"; +import { TFuncKey } from "../i18n"; import { fieldName, isBundleKey, unWrap } from "./PersonalInfo"; type FormFieldProps = { diff --git a/js/apps/account-ui/src/personal-info/PersonalInfo.tsx b/js/apps/account-ui/src/personal-info/PersonalInfo.tsx index 9a25249de0..b5f5898553 100644 --- a/js/apps/account-ui/src/personal-info/PersonalInfo.tsx +++ b/js/apps/account-ui/src/personal-info/PersonalInfo.tsx @@ -9,7 +9,6 @@ import { useState } from "react"; import { FormProvider, useForm } from "react-hook-form"; import { useTranslation } from "react-i18next"; import { useAlerts } from "ui-shared"; - import { getPersonalInfo, savePersonalInfo } from "../api/methods"; import { UserProfileMetadata, @@ -17,6 +16,7 @@ import { } from "../api/representations"; import { Page } from "../components/page/Page"; import { environment } from "../environment"; +import { TFuncKey } from "../i18n"; import { keycloak } from "../keycloak"; import { usePromise } from "../utils/usePromise"; import { FormField } from "./FormField"; @@ -64,7 +64,10 @@ const PersonalInfo = () => { e.params.map((p) => (isBundleKey(p) ? unWrap(p) : p)) ); setError(fieldName(e.field) as keyof UserRepresentation, { - message: t(e.errorMessage, { ...params, defaultValue: e.field }), + message: t(e.errorMessage as TFuncKey, { + ...params, + defaultValue: e.field, + }), type: "server", }); }); diff --git a/js/apps/account-ui/src/root/PageNav.tsx b/js/apps/account-ui/src/root/PageNav.tsx index 6f07d655c0..4e179a52dc 100644 --- a/js/apps/account-ui/src/root/PageNav.tsx +++ b/js/apps/account-ui/src/root/PageNav.tsx @@ -5,21 +5,21 @@ import { NavList, PageSidebar, } from "@patternfly/react-core"; -import { TFuncKey } from "i18next"; import { - MouseEvent as ReactMouseEvent, PropsWithChildren, + MouseEvent as ReactMouseEvent, useMemo, } from "react"; import { useTranslation } from "react-i18next"; import { - matchPath, To, + matchPath, useHref, useLinkClickHandler, useLocation, } from "react-router-dom"; import { environment } from "../environment"; +import { TFuncKey } from "../i18n"; type RootMenuItem = { label: TFuncKey; @@ -82,7 +82,7 @@ export const PageNav = () => ( {menuItems .filter((menuItem) => !menuItem.isHidden) .map((menuItem) => ( - + ))} @@ -119,7 +119,7 @@ function NavMenuItem({ menuItem }: NavMenuItemProps) { {menuItem.children .filter((menuItem) => !menuItem.isHidden) .map((child) => ( - + ))} ); diff --git a/js/apps/admin-ui/package.json b/js/apps/admin-ui/package.json index e4bc5c0754..f92fa701a2 100644 --- a/js/apps/admin-ui/package.json +++ b/js/apps/admin-ui/package.json @@ -72,7 +72,7 @@ "file-saver": "^2.0.5", "file-selector": "^0.6.0", "flat": "^5.0.2", - "i18next": "^22.5.1", + "i18next": "^23.2.0", "i18next-http-backend": "^2.2.1", "keycloak-js": "workspace:*", "lodash-es": "^4.17.21", @@ -82,7 +82,7 @@ "react-dropzone": "^14.2.3", "react-error-boundary": "^3.1.4", "react-hook-form": "^7.44.3", - "react-i18next": "^12.3.1", + "react-i18next": "^13.0.0", "react-router": "^6.12.1", "react-router-dom": "6.12.1", "reactflow": "^11.7.2", diff --git a/js/apps/admin-ui/src/i18n/i18n.ts b/js/apps/admin-ui/src/i18n/i18n.ts index 62302f7aaa..53d95ba886 100644 --- a/js/apps/admin-ui/src/i18n/i18n.ts +++ b/js/apps/admin-ui/src/i18n/i18n.ts @@ -11,7 +11,6 @@ export const NAMESPACE_SEPARATOR = ":"; export const KEY_SEPARATOR = "."; export const i18n = createInstance({ - returnNull: false, fallbackLng: DEFAULT_LOCALE, defaultNS: DEFAULT_NAMESPACE, nsSeparator: NAMESPACE_SEPARATOR, diff --git a/js/apps/admin-ui/src/i18next.d.ts b/js/apps/admin-ui/src/i18next.d.ts index 9e4166a75e..d59c506c9f 100644 --- a/js/apps/admin-ui/src/i18next.d.ts +++ b/js/apps/admin-ui/src/i18next.d.ts @@ -5,7 +5,6 @@ declare module "i18next" { interface CustomTypeOptions { // TODO: These flags should be removed and code that errors out should be made functional. // This will have to be done incrementally as the amount of errors the defaults produce is just too much. - returnNull: false; allowObjectInHTMLChildren: true; } } diff --git a/js/package.json b/js/package.json index 00324933fe..294f66d5ba 100644 --- a/js/package.json +++ b/js/package.json @@ -21,7 +21,7 @@ "lint-staged": "^13.2.2", "prettier": "^2.8.8", "tslib": "^2.5.3", - "typescript": "^5.0.4", + "typescript": "~5.0.4", "wireit": "^0.9.5" }, "packageManager": "pnpm@8.6.2", diff --git a/js/pnpm-lock.yaml b/js/pnpm-lock.yaml index 2783defcb8..a426d28368 100644 --- a/js/pnpm-lock.yaml +++ b/js/pnpm-lock.yaml @@ -60,7 +60,7 @@ importers: specifier: ^2.5.3 version: 2.5.3 typescript: - specifier: ^5.0.4 + specifier: ~5.0.4 version: 5.0.4 wireit: specifier: ^0.9.5 @@ -81,8 +81,8 @@ importers: specifier: ^4.113.0 version: 4.113.0(react-dom@18.2.0)(react@18.2.0) i18next: - specifier: ^22.5.1 - version: 22.5.1 + specifier: ^23.2.0 + version: 23.2.0 i18next-http-backend: specifier: ^2.2.1 version: 2.2.1 @@ -105,8 +105,8 @@ importers: specifier: ^7.44.3 version: 7.44.3(react@18.2.0) react-i18next: - specifier: ^12.3.1 - version: 12.3.1(i18next@22.5.1)(react-dom@18.2.0)(react@18.2.0) + specifier: ^13.0.0 + version: 13.0.0(i18next@23.2.0)(react-dom@18.2.0)(react@18.2.0) react-router-dom: specifier: 6.12.1 version: 6.12.1(react-dom@18.2.0)(react@18.2.0) @@ -172,8 +172,8 @@ importers: specifier: ^5.0.2 version: 5.0.2 i18next: - specifier: ^22.5.1 - version: 22.5.1 + specifier: ^23.2.0 + version: 23.2.0 i18next-http-backend: specifier: ^2.2.1 version: 2.2.1 @@ -202,8 +202,8 @@ importers: specifier: ^7.44.3 version: 7.44.3(react@18.2.0) react-i18next: - specifier: ^12.3.1 - version: 12.3.1(i18next@22.5.1)(react-dom@18.2.0)(react@18.2.0) + specifier: ^13.0.0 + version: 13.0.0(i18next@23.2.0)(react-dom@18.2.0)(react@18.2.0) react-router: specifier: ^6.12.1 version: 6.12.1(react@18.2.0) @@ -4229,8 +4229,8 @@ packages: - encoding dev: false - /i18next@22.5.1: - resolution: {integrity: sha512-8TGPgM3pAD+VRsMtUMNknRz3kzqwp/gPALrWMsDnmC1mKqJwpWyooQRLMcbTwq8z8YwSmuj+ZYvc+xCuEpkssA==} + /i18next@23.2.0: + resolution: {integrity: sha512-fAJHauzKpsHNP66ThBcexsrPJ9FoIuFgj2c0y9LmL9936XQL10ijfLe/fGm1r7GlmO7jhMdWt78oUi8jM3UCKQ==} dependencies: '@babel/runtime': 7.22.5 dev: false @@ -5575,10 +5575,10 @@ packages: react: 18.2.0 dev: false - /react-i18next@12.3.1(i18next@22.5.1)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-5v8E2XjZDFzK7K87eSwC7AJcAkcLt5xYZ4+yTPDAW1i7C93oOY1dnr4BaQM7un4Hm+GmghuiPvevWwlca5PwDA==} + /react-i18next@13.0.0(i18next@23.2.0)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-qRFbrSgynsBSjfnSTb/Um3mw9uPjOfDi4Iq2rMCuzfsRsYGdkEdyCr0i+T0bR0bG6xwULvK4k1oRVLLd7ZDBVw==} peerDependencies: - i18next: '>= 19.0.0' + i18next: '>= 23.0.1' react: '>= 16.8.0' react-dom: '*' react-native: '*' @@ -5590,7 +5590,7 @@ packages: dependencies: '@babel/runtime': 7.22.5 html-parse-stringify: 3.0.1 - i18next: 22.5.1 + i18next: 23.2.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false @@ -7060,7 +7060,7 @@ packages: file-saver: 2.0.5 file-selector: 0.6.0 flat: 5.0.2 - i18next: 22.5.1 + i18next: 23.2.0 i18next-http-backend: 2.2.1 keycloak-js: link:libs/keycloak-js lodash-es: 4.17.21 @@ -7070,7 +7070,7 @@ packages: react-dropzone: 14.2.3(react@18.2.0) react-error-boundary: 3.1.4(react@18.2.0) react-hook-form: 7.44.3(react@18.2.0) - react-i18next: 12.3.1(i18next@22.5.1)(react-dom@18.2.0)(react@18.2.0) + react-i18next: 13.0.0(i18next@23.2.0)(react-dom@18.2.0)(react@18.2.0) react-router: 6.12.1(react@18.2.0) react-router-dom: 6.12.1(react-dom@18.2.0)(react@18.2.0) reactflow: 11.7.2(react-dom@18.2.0)(react@18.2.0)