diff --git a/conf/defaults.ini b/conf/defaults.ini index 57b6abc9a10..050437bf0aa 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -412,8 +412,8 @@ password_hint = password # Default UI theme ("dark" or "light") default_theme = dark -# Default locale (supported IETF language tag, such as en-US) -default_locale = en-US +# Default UI language (supported IETF language tag, such as en-US) +default_language = en-US # Path to a custom home page. Users are only redirected to this if the default home dashboard is used. It should match a frontend route and contain a leading slash. home_page = diff --git a/conf/sample.ini b/conf/sample.ini index 4bbd7bf97e7..7c27b34819b 100644 --- a/conf/sample.ini +++ b/conf/sample.ini @@ -412,8 +412,8 @@ # Default UI theme ("dark" or "light") ;default_theme = dark -# Default locale (supported IETF language tag, such as en-US) -;default_locale = en-US +# Default UI language (supported IETF language tag, such as en-US) +;default_language = en-US # Path to a custom home page. Users are only redirected to this if the default home dashboard is used. It should match a frontend route and contain a leading slash. ;home_page = diff --git a/packages/grafana-data/src/types/config.ts b/packages/grafana-data/src/types/config.ts index 0e592167184..c6f708056b0 100644 --- a/packages/grafana-data/src/types/config.ts +++ b/packages/grafana-data/src/types/config.ts @@ -127,6 +127,7 @@ export interface CurrentUserDTO { timezone: string; weekStart: string; locale: string; + language: string; permissions?: Record; } diff --git a/pkg/api/dtos/models.go b/pkg/api/dtos/models.go index 31d17005756..704d573e1a3 100644 --- a/pkg/api/dtos/models.go +++ b/pkg/api/dtos/models.go @@ -44,6 +44,7 @@ type CurrentUser struct { Timezone string `json:"timezone"` WeekStart string `json:"weekStart"` Locale string `json:"locale"` + Language string `json:"language"` HelpFlags1 user.HelpFlags1 `json:"helpFlags1"` HasEditPermissionInFolders bool `json:"hasEditPermissionInFolders"` Permissions UserPermissionsMap `json:"permissions,omitempty"` diff --git a/pkg/api/dtos/prefs.go b/pkg/api/dtos/prefs.go index 0c5ac67dc6f..4dc3d7cc97c 100644 --- a/pkg/api/dtos/prefs.go +++ b/pkg/api/dtos/prefs.go @@ -10,7 +10,7 @@ type Prefs struct { HomeDashboardUID string `json:"homeDashboardUID,omitempty"` Timezone string `json:"timezone"` WeekStart string `json:"weekStart"` - Locale string `json:"locale"` + Language string `json:"language"` Navbar pref.NavbarPreference `json:"navbar,omitempty"` QueryHistory pref.QueryHistoryPreference `json:"queryHistory,omitempty"` } @@ -28,7 +28,7 @@ type UpdatePrefsCmd struct { WeekStart string `json:"weekStart"` Navbar *pref.NavbarPreference `json:"navbar,omitempty"` QueryHistory *pref.QueryHistoryPreference `json:"queryHistory,omitempty"` - Locale string `json:"locale"` + Language string `json:"language"` } // swagger:model @@ -41,7 +41,7 @@ type PatchPrefsCmd struct { // Enum: utc,browser Timezone *string `json:"timezone,omitempty"` WeekStart *string `json:"weekStart,omitempty"` - Locale *string `json:"locale,omitempty"` + Language *string `json:"language,omitempty"` Navbar *pref.NavbarPreference `json:"navbar,omitempty"` QueryHistory *pref.QueryHistoryPreference `json:"queryHistory,omitempty"` HomeDashboardUID *string `json:"homeDashboardUID,omitempty"` diff --git a/pkg/api/index.go b/pkg/api/index.go index e0d0b8de637..dbf621190ef 100644 --- a/pkg/api/index.go +++ b/pkg/api/index.go @@ -45,15 +45,17 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat return nil, err } - // Set locale to the preference, otherwise fall back to the accept language header. - // In practice, because the preference has configuration-backed default, the header - // shouldn't frequently be used + // Locale is used for some number and date/time formatting, whereas language is used just for + // translating words in the interface acceptLangHeader := c.Req.Header.Get("Accept-Language") locale := "en-US" + language := "" // frontend will set the default language - if hs.Features.IsEnabled(featuremgmt.FlagInternationalization) && prefs.JSONData.Locale != "" { - locale = prefs.JSONData.Locale - } else if len(acceptLangHeader) > 0 { + if hs.Features.IsEnabled(featuremgmt.FlagInternationalization) && prefs.JSONData.Language != "" { + language = prefs.JSONData.Language + } + + if len(acceptLangHeader) > 0 { parts := strings.Split(acceptLangHeader, ",") locale = parts[0] } @@ -100,6 +102,7 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat Timezone: prefs.Timezone, WeekStart: weekStart, Locale: locale, + Language: language, HelpFlags1: c.HelpFlags1, HasEditPermissionInFolders: hasEditPerm, }, diff --git a/pkg/api/preferences.go b/pkg/api/preferences.go index 4b119557a14..e5e2a40a009 100644 --- a/pkg/api/preferences.go +++ b/pkg/api/preferences.go @@ -96,7 +96,7 @@ func (hs *HTTPServer) getPreferencesFor(ctx context.Context, orgID, userID, team } if preference.JSONData != nil { - dto.Locale = preference.JSONData.Locale + dto.Language = preference.JSONData.Language dto.Navbar = preference.JSONData.Navbar dto.QueryHistory = preference.JSONData.QueryHistory } @@ -149,7 +149,7 @@ func (hs *HTTPServer) updatePreferencesFor(ctx context.Context, orgID, userID, t OrgID: orgID, TeamID: teamId, Theme: dtoCmd.Theme, - Locale: dtoCmd.Locale, + Language: dtoCmd.Language, Timezone: dtoCmd.Timezone, WeekStart: dtoCmd.WeekStart, HomeDashboardID: dtoCmd.HomeDashboardID, @@ -212,7 +212,7 @@ func (hs *HTTPServer) patchPreferencesFor(ctx context.Context, orgID, userID, te Timezone: dtoCmd.Timezone, WeekStart: dtoCmd.WeekStart, HomeDashboardID: dtoCmd.HomeDashboardID, - Locale: dtoCmd.Locale, + Language: dtoCmd.Language, Navbar: dtoCmd.Navbar, QueryHistory: dtoCmd.QueryHistory, } diff --git a/pkg/services/preference/model.go b/pkg/services/preference/model.go index 3f09da21d92..9bb6a2ef22f 100644 --- a/pkg/services/preference/model.go +++ b/pkg/services/preference/model.go @@ -49,7 +49,7 @@ type SavePreferenceCommand struct { Timezone string `json:"timezone,omitempty"` WeekStart string `json:"weekStart,omitempty"` Theme string `json:"theme,omitempty"` - Locale string `json:"locale,omitempty"` + Language string `json:"language,omitempty"` Navbar *NavbarPreference `json:"navbar,omitempty"` QueryHistory *QueryHistoryPreference `json:"queryHistory,omitempty"` } @@ -64,7 +64,7 @@ type PatchPreferenceCommand struct { Timezone *string `json:"timezone,omitempty"` WeekStart *string `json:"weekStart,omitempty"` Theme *string `json:"theme,omitempty"` - Locale *string `json:"locale,omitempty"` + Language *string `json:"language,omitempty"` Navbar *NavbarPreference `json:"navbar,omitempty"` QueryHistory *QueryHistoryPreference `json:"queryHistory,omitempty"` } @@ -81,7 +81,7 @@ type NavbarPreference struct { } type PreferenceJSONData struct { - Locale string `json:"locale"` + Language string `json:"language"` Navbar NavbarPreference `json:"navbar"` QueryHistory QueryHistoryPreference `json:"queryHistory"` } diff --git a/pkg/services/preference/prefimpl/pref.go b/pkg/services/preference/prefimpl/pref.go index 7b9d0c5d10a..feadcbfa06e 100644 --- a/pkg/services/preference/prefimpl/pref.go +++ b/pkg/services/preference/prefimpl/pref.go @@ -61,8 +61,8 @@ func (s *Service) GetWithDefaults(ctx context.Context, query *pref.GetPreference res.HomeDashboardID = p.HomeDashboardID } if p.JSONData != nil { - if p.JSONData.Locale != "" { - res.JSONData.Locale = p.JSONData.Locale + if p.JSONData.Language != "" { + res.JSONData.Language = p.JSONData.Language } if len(p.JSONData.Navbar.SavedItems) > 0 { @@ -113,7 +113,7 @@ func (s *Service) Save(ctx context.Context, cmd *pref.SavePreferenceCommand) err Created: time.Now(), Updated: time.Now(), JSONData: &pref.PreferenceJSONData{ - Locale: cmd.Locale, + Language: cmd.Language, }, } _, err = s.store.Insert(ctx, preference) @@ -131,7 +131,7 @@ func (s *Service) Save(ctx context.Context, cmd *pref.SavePreferenceCommand) err preference.Version += 1 preference.HomeDashboardID = cmd.HomeDashboardID preference.JSONData = &pref.PreferenceJSONData{ - Locale: cmd.Locale, + Language: cmd.Language, } if cmd.Navbar != nil { @@ -166,11 +166,11 @@ func (s *Service) Patch(ctx context.Context, cmd *pref.PatchPreferenceCommand) e exists = true } - if cmd.Locale != nil { + if cmd.Language != nil { if preference.JSONData == nil { preference.JSONData = &pref.PreferenceJSONData{} } - preference.JSONData.Locale = *cmd.Locale + preference.JSONData.Language = *cmd.Language } if cmd.Navbar != nil { @@ -238,7 +238,7 @@ func (s *Service) GetDefaults() *pref.Preference { } if s.features.IsEnabled(featuremgmt.FlagInternationalization) { - defaults.JSONData.Locale = s.cfg.DefaultLocale + defaults.JSONData.Language = s.cfg.DefaultLanguage } return defaults diff --git a/pkg/services/preference/prefimpl/pref_test.go b/pkg/services/preference/prefimpl/pref_test.go index 6aa09fdf1f4..0f5868b0117 100644 --- a/pkg/services/preference/prefimpl/pref_test.go +++ b/pkg/services/preference/prefimpl/pref_test.go @@ -33,7 +33,7 @@ func TestGetDefaults(t *testing.T) { cfg: setting.NewCfg(), features: featuremgmt.WithFeatures(), } - prefService.cfg.DefaultLocale = "en-US" + prefService.cfg.DefaultLanguage = "en-US" prefService.cfg.DefaultTheme = "light" prefService.cfg.DateFormats.DefaultTimezone = "UTC" weekStart := "" @@ -76,7 +76,7 @@ func TestGetDefaultsWithI18nFeatureFlag(t *testing.T) { features: featuremgmt.WithFeatures(featuremgmt.FlagInternationalization), } weekStart := "" - prefService.cfg.DefaultLocale = "en-US" + prefService.cfg.DefaultLanguage = "en-US" prefService.cfg.DefaultTheme = "light" prefService.cfg.DateFormats.DefaultTimezone = "UTC" @@ -88,7 +88,7 @@ func TestGetDefaultsWithI18nFeatureFlag(t *testing.T) { Timezone: "UTC", HomeDashboardID: 0, JSONData: &pref.PreferenceJSONData{ - Locale: "en-US", + Language: "en-US", }, } if diff := cmp.Diff(expected, preference); diff != "" { @@ -103,7 +103,7 @@ func TestGetWithDefaults_withUserAndOrgPrefs(t *testing.T) { cfg: setting.NewCfg(), features: featuremgmt.WithFeatures(), } - prefService.cfg.DefaultLocale = "en-US" + prefService.cfg.DefaultLanguage = "en-US" weekStartOne := "1" weekStartTwo := "2" @@ -115,7 +115,7 @@ func TestGetWithDefaults_withUserAndOrgPrefs(t *testing.T) { Timezone: "UTC", WeekStart: &weekStartOne, JSONData: &pref.PreferenceJSONData{ - Locale: "en-GB", + Language: "en-GB", }, }, pref.Preference{ @@ -126,7 +126,7 @@ func TestGetWithDefaults_withUserAndOrgPrefs(t *testing.T) { Timezone: "browser", WeekStart: &weekStartTwo, JSONData: &pref.PreferenceJSONData{ - Locale: "en-AU", + Language: "en-AU", }, }, ) @@ -141,7 +141,7 @@ func TestGetWithDefaults_withUserAndOrgPrefs(t *testing.T) { WeekStart: &weekStartTwo, HomeDashboardID: 4, JSONData: &pref.PreferenceJSONData{ - Locale: "en-AU", + Language: "en-AU", }, } if diff := cmp.Diff(expected, preference); diff != "" { @@ -160,7 +160,7 @@ func TestGetWithDefaults_withUserAndOrgPrefs(t *testing.T) { WeekStart: &weekStartOne, HomeDashboardID: 1, JSONData: &pref.PreferenceJSONData{ - Locale: "en-GB", + Language: "en-GB", }, } if diff := cmp.Diff(expected, preference); diff != "" { @@ -209,9 +209,9 @@ func TestGetDefaults_JSONData(t *testing.T) { orgPreferencesJsonData := pref.PreferenceJSONData{ Navbar: orgNavbarPreferences, } - orgPreferencesWithLocaleJsonData := pref.PreferenceJSONData{ - Navbar: orgNavbarPreferences, - Locale: "en-GB", + orgPreferencesWithLanguageJsonData := pref.PreferenceJSONData{ + Navbar: orgNavbarPreferences, + Language: "en-GB", } team2PreferencesJsonData := pref.PreferenceJSONData{ Navbar: team2NavbarPreferences, @@ -248,7 +248,7 @@ func TestGetDefaults_JSONData(t *testing.T) { }, preference) }) - t.Run("user JSONData with missing locale does not override org preference", func(t *testing.T) { + t.Run("user JSONData with missing language does not override org preference", func(t *testing.T) { prefService := &Service{ store: newFake(), cfg: setting.NewCfg(), @@ -258,7 +258,7 @@ func TestGetDefaults_JSONData(t *testing.T) { insertPrefs(t, prefService.store, pref.Preference{ OrgID: 1, - JSONData: &orgPreferencesWithLocaleJsonData, + JSONData: &orgPreferencesWithLanguageJsonData, }, pref.Preference{ OrgID: 1, @@ -273,7 +273,7 @@ func TestGetDefaults_JSONData(t *testing.T) { require.Equal(t, &pref.Preference{ WeekStart: &weekStart, JSONData: &pref.PreferenceJSONData{ - Locale: "en-GB", + Language: "en-GB", Navbar: userNavbarPreferences, QueryHistory: queryPreference, }, diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go index dc874143e40..4754d5c028e 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -427,9 +427,9 @@ type Cfg struct { LDAPSkipOrgRoleSync bool LDAPAllowSignup bool - DefaultTheme string - DefaultLocale string - HomePage string + DefaultTheme string + DefaultLanguage string + HomePage string Quota QuotaSettings @@ -1455,7 +1455,7 @@ func readUserSettings(iniFile *ini.File, cfg *Cfg) error { LoginHint = valueAsString(users, "login_hint", "") PasswordHint = valueAsString(users, "password_hint", "") cfg.DefaultTheme = valueAsString(users, "default_theme", "") - cfg.DefaultLocale = valueAsString(users, "default_locale", "") + cfg.DefaultLanguage = valueAsString(users, "default_language", "") cfg.HomePage = valueAsString(users, "home_page", "") ExternalUserMngLinkUrl = valueAsString(users, "external_manage_link_url", "") ExternalUserMngLinkName = valueAsString(users, "external_manage_link_name", "") diff --git a/public/app/app.ts b/public/app/app.ts index 466e6ba6b55..cdf836281f2 100644 --- a/public/app/app.ts +++ b/public/app/app.ts @@ -105,7 +105,7 @@ export class GrafanaApp { // Let iframe container know grafana has started loading parent.postMessage('GrafanaAppInit', '*'); - const loadLocalePromise = initializeI18n(config.bootData.user.locale); + const initI18nPromise = initializeI18n(config.bootData.user.language); setBackendSrv(backendSrv); initEchoSrv(); @@ -160,7 +160,7 @@ export class GrafanaApp { modalManager.init(); await Promise.all([ - loadLocalePromise, + initI18nPromise, // Preload selected app plugins await preloadPlugins(config.pluginsToPreload), diff --git a/public/app/core/components/SharedPreferences/SharedPreferences.test.tsx b/public/app/core/components/SharedPreferences/SharedPreferences.test.tsx index 4e0cd8dff93..7daa5ab05c4 100644 --- a/public/app/core/components/SharedPreferences/SharedPreferences.test.tsx +++ b/public/app/core/components/SharedPreferences/SharedPreferences.test.tsx @@ -83,7 +83,7 @@ const mockPreferences: UserPreferencesDTO = { queryHistory: { homeTab: '', }, - locale: '', + language: '', }; const mockPrefsPatch = jest.fn(); @@ -152,7 +152,7 @@ describe('SharedPreferences', () => { expect(weekSelect).toHaveTextContent('Monday'); }); - it('renders the locale preference', async () => { + it('renders the language preference', async () => { const weekSelect = getSelectParent(screen.getByLabelText(/language/i)); expect(weekSelect).toHaveTextContent('Default'); }); @@ -174,7 +174,7 @@ describe('SharedPreferences', () => { queryHistory: { homeTab: '', }, - locale: 'fr-FR', + language: 'fr-FR', }); }); @@ -196,7 +196,7 @@ describe('SharedPreferences', () => { queryHistory: { homeTab: '', }, - locale: '', + language: '', }); }); diff --git a/public/app/core/components/SharedPreferences/SharedPreferences.tsx b/public/app/core/components/SharedPreferences/SharedPreferences.tsx index 5254a210938..e9ab93f9867 100644 --- a/public/app/core/components/SharedPreferences/SharedPreferences.tsx +++ b/public/app/core/components/SharedPreferences/SharedPreferences.tsx @@ -19,7 +19,7 @@ import { } from '@grafana/ui'; import { DashboardPicker } from 'app/core/components/Select/DashboardPicker'; import { t, Trans } from 'app/core/internationalization'; -import { LOCALES } from 'app/core/internationalization/constants'; +import { LANGUAGES } from 'app/core/internationalization/constants'; import { PreferencesService } from 'app/core/services/PreferencesService'; import { UserPreferencesDTO } from 'app/types'; @@ -37,7 +37,7 @@ const themes: SelectableValue[] = [ ]; function getLanguageOptions(): Array> { - const languageOptions = LOCALES.map((v) => ({ + const languageOptions = LANGUAGES.map((v) => ({ value: v.code, label: v.name, })); @@ -66,7 +66,7 @@ export class SharedPreferences extends PureComponent { theme: '', timezone: '', weekStart: '', - locale: '', + language: '', queryHistory: { homeTab: '' }, }; } @@ -79,14 +79,14 @@ export class SharedPreferences extends PureComponent { theme: prefs.theme, timezone: prefs.timezone, weekStart: prefs.weekStart, - locale: prefs.locale, + language: prefs.language, queryHistory: prefs.queryHistory, }); } onSubmitForm = async () => { - const { homeDashboardUID, theme, timezone, weekStart, locale, queryHistory } = this.state; - await this.service.update({ homeDashboardUID, theme, timezone, weekStart, locale, queryHistory }); + const { homeDashboardUID, theme, timezone, weekStart, language, queryHistory } = this.state; + await this.service.update({ homeDashboardUID, theme, timezone, weekStart, language, queryHistory }); window.location.reload(); }; @@ -109,12 +109,12 @@ export class SharedPreferences extends PureComponent { this.setState({ homeDashboardUID: dashboardUID }); }; - onLocaleChanged = (locale: string) => { - this.setState({ locale }); + onLanguageChanged = (language: string) => { + this.setState({ language }); }; render() { - const { theme, timezone, weekStart, homeDashboardUID, locale } = this.state; + const { theme, timezone, weekStart, homeDashboardUID, language } = this.state; const { disabled } = this.props; const styles = getStyles(); const languages = getLanguageOptions(); @@ -188,8 +188,8 @@ export class SharedPreferences extends PureComponent { data-testid="User preferences language drop down" >