From 41b10267d741b1cc9c12bdddba699da79896d9bd Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 14 Sep 2023 21:12:29 +0200 Subject: [PATCH] user-settings: update to use new translation APIs Signed-off-by: Patrik Oldsberg --- plugins/user-settings/package.json | 1 - .../UserSettingsLanguageToggle.test.tsx | 119 ++++++------------ .../General/UserSettingsLanguageToggle.tsx | 49 ++++---- .../General/UserSettingsThemeToggle.tsx | 2 +- yarn.lock | 1 - 5 files changed, 61 insertions(+), 111 deletions(-) diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index db2dad223a..1ca1929cfc 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -57,7 +57,6 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", "@types/react": "^16.13.1 || ^17.0.0", - "react-i18next": "^12.3.1", "react-use": "^17.2.4", "zen-observable": "^0.10.0" }, diff --git a/plugins/user-settings/src/components/General/UserSettingsLanguageToggle.test.tsx b/plugins/user-settings/src/components/General/UserSettingsLanguageToggle.test.tsx index 51b277c8f8..6e3a01c3c5 100644 --- a/plugins/user-settings/src/components/General/UserSettingsLanguageToggle.test.tsx +++ b/plugins/user-settings/src/components/General/UserSettingsLanguageToggle.test.tsx @@ -16,111 +16,66 @@ import React from 'react'; import { screen, fireEvent } from '@testing-library/react'; -import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; import { UserSettingsLanguageToggle } from './UserSettingsLanguageToggle'; -import { renderInTestApp } from '@backstage/test-utils'; -import { useTranslation } from 'react-i18next'; - -jest.mock('@backstage/core-plugin-api/alpha', () => ({ - ...jest.requireActual('@backstage/core-plugin-api/alpha'), - useTranslationRef: jest.fn(), -})); - -jest.mock('react-i18next', () => ({ - ...jest.requireActual('react-i18next'), - useTranslation: jest.fn(), -})); +import { TestApiProvider, renderInTestApp } from '@backstage/test-utils'; +import { appLanguageApiRef } from '@backstage/core-plugin-api/alpha'; describe('UserSettingsLanguageToggle', () => { beforeEach(() => { jest.clearAllMocks(); }); - it('should render correctly with multiple supported languages', async () => { - const messages: Record = { - en: 'English', - fr: 'French', - de: 'German', - language: 'language', - change_the_language: 'Change the language', - }; + it('should not render with only one available language', async () => { + const rendered = await renderInTestApp(); - const i18nMock = { - language: 'en', - options: { - supportedLngs: ['en', 'fr', 'de'], - }, - changeLanguage: jest.fn(), - }; - - (useTranslation as jest.Mock).mockReturnValue({ - i18n: i18nMock, - }); - - (useTranslationRef as jest.Mock).mockReturnValue( - (key: string, option: any) => - messages[option?.language || key] || 'translatedValue', - ); - - await renderInTestApp(); - - expect(screen.getAllByText('Change the language')).toHaveLength(1); - expect(screen.getAllByText('English')).toHaveLength(1); - expect(screen.getAllByText('French')).toHaveLength(1); - expect(screen.getAllByText('German')).toHaveLength(1); + expect(rendered.container).toBeEmptyDOMElement(); }); - it('should not render when only one supported language', async () => { - const tMock = jest.fn().mockReturnValue('translatedValue'); - const i18nMock = { - language: 'en', - options: { - supportedLngs: ['en'], - }, - changeLanguage: jest.fn(), + it('should render correctly with multiple available languages', async () => { + const mockLanguageApi: typeof appLanguageApiRef.T = { + getAvailableLanguages: jest + .fn() + .mockReturnValue({ languages: ['en', 'de'] }), + getLanguage: jest.fn().mockReturnValue({ language: 'en' }), + language$: jest.fn().mockReturnValue({ + subscribe: jest.fn().mockReturnValue({ unsubscribe: jest.fn() }), + }), + setLanguage: jest.fn(), }; - (useTranslationRef as jest.Mock).mockReturnValue(tMock); + await renderInTestApp( + + + , + ); - (useTranslation as jest.Mock).mockReturnValue({ - i18n: i18nMock, - }); - - await renderInTestApp(); - - expect(screen.queryByText('translatedValue')).toBeNull(); - expect(screen.queryByText('English')).toBeNull(); + expect(screen.getByText('Change the language')).toBeInTheDocument(); }); it('should handle language change', async () => { - const messages: Record = { - en: 'English', - fr: 'French', - language: 'language', - change_the_language: 'Change the language', + const mockLanguageApi: typeof appLanguageApiRef.T = { + getAvailableLanguages: jest + .fn() + .mockReturnValue({ languages: ['en', 'de'] }), + getLanguage: jest.fn().mockReturnValue({ language: 'en' }), + language$: jest.fn().mockReturnValue({ + subscribe: jest.fn().mockReturnValue({ unsubscribe: jest.fn() }), + }), + setLanguage: jest.fn(), }; - const i18nMock = { - language: 'en', - options: { - supportedLngs: ['en', 'fr'], - }, - changeLanguage: jest.fn(), - }; - - (useTranslationRef as jest.Mock).mockReturnValue( - (key: string, option: any) => - messages[option?.language || key] || 'translatedValue', + await renderInTestApp( + + + , ); - (useTranslation as jest.Mock).mockReturnValue({ - i18n: i18nMock, - }); + expect(screen.getByText('Change the language')).toBeInTheDocument(); await renderInTestApp(); - fireEvent.click(screen.getByText('French')); + fireEvent.click(screen.getByText('de')); - expect(i18nMock.changeLanguage).toHaveBeenCalledWith('fr'); + expect(mockLanguageApi.setLanguage).toHaveBeenCalledWith('de'); }); }); diff --git a/plugins/user-settings/src/components/General/UserSettingsLanguageToggle.tsx b/plugins/user-settings/src/components/General/UserSettingsLanguageToggle.tsx index 3c5772ab16..1f5bb025ee 100644 --- a/plugins/user-settings/src/components/General/UserSettingsLanguageToggle.tsx +++ b/plugins/user-settings/src/components/General/UserSettingsLanguageToggle.tsx @@ -14,8 +14,11 @@ * limitations under the License. */ -import React, { useMemo } from 'react'; -import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; +import React, { useState } from 'react'; +import { + useTranslationRef, + appLanguageApiRef, +} from '@backstage/core-plugin-api/alpha'; import ToggleButton from '@material-ui/lab/ToggleButton'; import ToggleButtonGroup from '@material-ui/lab/ToggleButtonGroup'; import { @@ -26,7 +29,8 @@ import { makeStyles, } from '@material-ui/core'; import { userSettingsTranslationRef } from '../../translation'; -import { useTranslation } from 'react-i18next'; +import { useApi } from '@backstage/core-plugin-api'; +import useObservable from 'react-use/lib/useObservable'; type TooltipToggleButtonProps = { children: JSX.Element; @@ -85,15 +89,18 @@ const TooltipToggleButton = ({ /** @public */ export const UserSettingsLanguageToggle = () => { const classes = useStyles(); - const { i18n } = useTranslation(); - const t = useTranslationRef(userSettingsTranslationRef); + const languageApi = useApi(appLanguageApiRef); + const { t } = useTranslationRef(userSettingsTranslationRef); - const supportedLngs = useMemo( - () => (i18n.options.supportedLngs || []).filter(lng => lng !== 'cimode'), - [i18n], + const [languageObservable] = useState(() => languageApi.language$()); + const { language: currentLanguage } = useObservable( + languageObservable, + languageApi.getLanguage(), ); - if (supportedLngs.length <= 1) { + const { languages } = languageApi.getAvailableLanguages(); + + if (languages.length <= 1) { return null; } @@ -101,11 +108,7 @@ export const UserSettingsLanguageToggle = () => { _event: React.MouseEvent, newLanguage: string | undefined, ) => { - if (supportedLngs.some(it => it === newLanguage)) { - i18n.changeLanguage(newLanguage); - } else { - i18n.changeLanguage(undefined); - } + languageApi.setLanguage(newLanguage); }; return ( @@ -122,23 +125,17 @@ export const UserSettingsLanguageToggle = () => { - {supportedLngs.map(lng => { + {languages.map(language => { return ( - <> - {t('lng', { - language: lng, - })} - + <>{t('lng', { language })} ); })} diff --git a/plugins/user-settings/src/components/General/UserSettingsThemeToggle.tsx b/plugins/user-settings/src/components/General/UserSettingsThemeToggle.tsx index 42490ec118..a97355eb07 100644 --- a/plugins/user-settings/src/components/General/UserSettingsThemeToggle.tsx +++ b/plugins/user-settings/src/components/General/UserSettingsThemeToggle.tsx @@ -110,7 +110,7 @@ export const UserSettingsThemeToggle = () => { const themeIds = appThemeApi.getInstalledThemes(); - const t = useTranslationRef(userSettingsTranslationRef); + const { t } = useTranslationRef(userSettingsTranslationRef); const handleSetTheme = ( _event: React.MouseEvent, diff --git a/yarn.lock b/yarn.lock index 2a037184fa..ac000ff20c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9879,7 +9879,6 @@ __metadata: "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 msw: ^1.0.0 - react-i18next: ^12.3.1 react-use: ^17.2.4 zen-observable: ^0.10.0 peerDependencies: