diff --git a/.betterer.results b/.betterer.results index 423a379c096..1def782e11d 100644 --- a/.betterer.results +++ b/.betterer.results @@ -104,9 +104,6 @@ exports[`no enzyme tests`] = { "public/app/features/folders/FolderSettingsPage.test.tsx:1109052730": [ [0, 19, 13, "RegExp match", "2409514259"] ], - "public/app/features/org/OrgDetailsPage.test.tsx:3835042085": [ - [0, 19, 13, "RegExp match", "2409514259"] - ], "public/app/plugins/datasource/cloudwatch/components/ConfigEditor.test.tsx:227258837": [ [0, 19, 13, "RegExp match", "2409514259"] ], diff --git a/public/app/core/components/SharedPreferences/SharedPreferences.test.tsx b/public/app/core/components/SharedPreferences/SharedPreferences.test.tsx index 7ab303c8800..4b09e4bef47 100644 --- a/public/app/core/components/SharedPreferences/SharedPreferences.test.tsx +++ b/public/app/core/components/SharedPreferences/SharedPreferences.test.tsx @@ -9,6 +9,19 @@ import { UserPreferencesDTO } from 'app/types'; import SharedPreferences from './SharedPreferences'; +jest.mock('@grafana/runtime', () => { + const originalModule = jest.requireActual('@grafana/runtime'); + return { + ...originalModule, + config: { + ...originalModule.config, + featureToggles: { + internationalization: true, + }, + }, + }; +}); + jest.mock('app/core/services/backend_srv', () => { return { backendSrv: { @@ -58,6 +71,7 @@ const mockPreferences: UserPreferencesDTO = { queryHistory: { homeTab: '', }, + locale: '', }; const mockPrefsPatch = jest.fn(); @@ -126,6 +140,11 @@ describe('SharedPreferences', () => { expect(weekSelect).toHaveTextContent('Monday'); }); + it('renders the locale preference', async () => { + const weekSelect = getSelectParent(screen.getByLabelText(/language/i)); + expect(weekSelect).toHaveTextContent('Default'); + }); + it("saves the user's new preferences", async () => { const darkThemeRadio = assertInstanceOf(screen.getByLabelText('Dark'), HTMLInputElement); await userEvent.click(darkThemeRadio); @@ -133,6 +152,7 @@ describe('SharedPreferences', () => { await selectOptionInTest(screen.getByLabelText('Home Dashboard'), 'Another Dashboard'); await selectOptionInTest(screen.getByLabelText('Timezone'), 'Australia/Sydney'); await selectOptionInTest(screen.getByLabelText('Week start'), 'Saturday'); + await selectOptionInTest(screen.getByLabelText(/language/i), 'French'); await userEvent.click(screen.getByText('Save')); expect(mockPrefsUpdate).toHaveBeenCalledWith({ @@ -143,6 +163,29 @@ describe('SharedPreferences', () => { queryHistory: { homeTab: '', }, + locale: 'fr', + }); + }); + + it("saves the user's default preferences", async () => { + const defThemeRadio = assertInstanceOf(screen.getByLabelText('Default'), HTMLInputElement); + await userEvent.click(defThemeRadio); + + await selectOptionInTest(screen.getByLabelText('Home Dashboard'), 'Default'); + await selectOptionInTest(screen.getByLabelText('Timezone'), 'Default'); + await selectOptionInTest(screen.getByLabelText('Week start'), 'Default'); + await selectOptionInTest(screen.getByLabelText(/language/i), 'Default'); + + await userEvent.click(screen.getByText('Save')); + expect(mockPrefsUpdate).toHaveBeenCalledWith({ + timezone: 'browser', + weekStart: '', + theme: '', + homeDashboardId: 0, + queryHistory: { + homeTab: '', + }, + locale: '', }); }); diff --git a/public/app/core/components/SharedPreferences/SharedPreferences.tsx b/public/app/core/components/SharedPreferences/SharedPreferences.tsx index 5e3d780c9a9..326df7e5a0f 100644 --- a/public/app/core/components/SharedPreferences/SharedPreferences.tsx +++ b/public/app/core/components/SharedPreferences/SharedPreferences.tsx @@ -2,8 +2,9 @@ import { css } from '@emotion/css'; import { t, Trans } from '@lingui/macro'; import React, { PureComponent } from 'react'; -import { SelectableValue } from '@grafana/data'; +import { FeatureState, SelectableValue } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; +import { config } from '@grafana/runtime'; import { Button, Field, @@ -17,6 +18,7 @@ import { TimeZonePicker, Tooltip, WeekStartPicker, + FeatureBadge, } from '@grafana/ui'; import { PreferencesService } from 'app/core/services/PreferencesService'; import { backendSrv } from 'app/core/services/backend_srv'; @@ -39,6 +41,39 @@ const themes: SelectableValue[] = [ { value: 'light', label: t({ id: 'shared-preferences.theme.light-label', message: 'Light' }) }, ]; +const languages: Array> = [ + { + value: '', + label: t({ + id: 'common.locale.default', + message: 'Default', + }), + }, + { + value: 'en', + label: t({ + id: 'common.locale.en', + message: 'English', + }), + }, + { + value: 'es', + label: t({ + id: 'common.locale.es', + message: 'Spanish', + }), + }, + { + value: 'fr', + label: t({ + id: 'common.locale.fr', + message: 'French', + }), + }, +]; + +const i18nFlag = Boolean(config.featureToggles.internationalization); + export class SharedPreferences extends PureComponent { service: PreferencesService; @@ -51,6 +86,7 @@ export class SharedPreferences extends PureComponent { theme: '', timezone: '', weekStart: '', + locale: '', dashboards: [], queryHistory: { homeTab: '' }, }; @@ -88,14 +124,15 @@ export class SharedPreferences extends PureComponent { theme: prefs.theme, timezone: prefs.timezone, weekStart: prefs.weekStart, + locale: prefs.locale, dashboards: [defaultDashboardHit, ...dashboards], queryHistory: prefs.queryHistory, }); } onSubmitForm = async () => { - const { homeDashboardId, theme, timezone, weekStart, queryHistory } = this.state; - await this.service.update({ homeDashboardId, theme, timezone, weekStart, queryHistory }); + const { homeDashboardId, theme, timezone, weekStart, locale, queryHistory } = this.state; + await this.service.update({ homeDashboardId, theme, timezone, weekStart, locale, queryHistory }); window.location.reload(); }; @@ -118,6 +155,10 @@ export class SharedPreferences extends PureComponent { this.setState({ homeDashboardId: dashboardId }); }; + onLocaleChanged = (locale: string) => { + this.setState({ locale }); + }; + getFullDashName = (dashboard: SelectableValue) => { if (typeof dashboard.folderTitle === 'undefined' || dashboard.folderTitle === '') { return dashboard.title; @@ -126,7 +167,7 @@ export class SharedPreferences extends PureComponent { }; render() { - const { theme, timezone, weekStart, homeDashboardId, dashboards } = this.state; + const { theme, timezone, weekStart, homeDashboardId, locale, dashboards } = this.state; const { disabled } = this.props; const styles = getStyles(); @@ -206,6 +247,31 @@ export class SharedPreferences extends PureComponent { /> + {i18nFlag ? ( + + + Language + + + + } + data-testid="User preferences language drop down" + > +