i18n: Add locale to backend (#102233)

This commit is contained in:
Laura Fernández
2025-03-31 15:59:07 +02:00
committed by GitHub
parent 7808cc960d
commit 4ad0492d3d
21 changed files with 145 additions and 12 deletions
+3
View File
@@ -65,6 +65,7 @@ type SavePreferenceCommand struct {
WeekStart string `json:"weekStart,omitempty"`
Theme string `json:"theme,omitempty"`
Language string `json:"language,omitempty"`
Locale string `json:"locale,omitempty"`
QueryHistory *QueryHistoryPreference `json:"queryHistory,omitempty"`
CookiePreferences []CookieType `json:"cookiePreferences,omitempty"`
Navbar *NavbarPreference `json:"navbar,omitempty"`
@@ -81,6 +82,7 @@ type PatchPreferenceCommand struct {
WeekStart *string `json:"weekStart,omitempty"`
Theme *string `json:"theme,omitempty"`
Language *string `json:"language,omitempty"`
Locale *string `json:"locale,omitempty"`
QueryHistory *QueryHistoryPreference `json:"queryHistory,omitempty"`
CookiePreferences []CookieType `json:"cookiePreferences,omitempty"`
Navbar *NavbarPreference `json:"navbar,omitempty"`
@@ -88,6 +90,7 @@ type PatchPreferenceCommand struct {
type PreferenceJSONData struct {
Language string `json:"language"`
Locale string `json:"locale"`
QueryHistory QueryHistoryPreference `json:"queryHistory"`
CookiePreferences map[string]struct{} `json:"cookiePreferences"`
Navbar NavbarPreference `json:"navbar"`
+13 -3
View File
@@ -9,11 +9,12 @@ import (
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/kinds/preferences"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/featuremgmt"
pref "github.com/grafana/grafana/pkg/services/preference"
)
func UpdatePreferencesFor(ctx context.Context,
dashboardService dashboards.DashboardService, preferenceService pref.Service,
dashboardService dashboards.DashboardService, preferenceService pref.Service, features featuremgmt.FeatureToggles,
orgID, userID, teamId int64, dtoCmd *dtos.UpdatePrefsCmd) response.Response {
if dtoCmd.Theme != "" && !pref.IsValidThemeID(dtoCmd.Theme) {
return response.Error(http.StatusBadRequest, "Invalid theme", nil)
@@ -49,6 +50,10 @@ func UpdatePreferencesFor(ctx context.Context,
Navbar: dtoCmd.Navbar,
}
if features.IsEnabled(ctx, featuremgmt.FlagLocaleFormatPreference) {
saveCmd.Locale = dtoCmd.Locale
}
if err := preferenceService.Save(ctx, &saveCmd); err != nil {
return response.ErrOrFallback(http.StatusInternalServerError, "Failed to save preferences", err)
}
@@ -58,7 +63,7 @@ func UpdatePreferencesFor(ctx context.Context,
func GetPreferencesFor(ctx context.Context,
dashboardService dashboards.DashboardService, preferenceService pref.Service,
orgID, userID, teamID int64) response.Response {
features featuremgmt.FeatureToggles, orgID, userID, teamID int64) response.Response {
prefsQuery := pref.GetPreferenceQuery{UserID: userID, OrgID: orgID, TeamID: teamID}
preference, err := preferenceService.Get(ctx, &prefsQuery)
@@ -67,7 +72,6 @@ func GetPreferencesFor(ctx context.Context,
}
var dashboardUID string
// when homedashboardID is 0, that means it is the default home dashboard, no UID would be returned in the response
if preference.HomeDashboardID != 0 {
query := dashboards.GetDashboardQuery{ID: preference.HomeDashboardID, OrgID: orgID}
@@ -97,6 +101,12 @@ func GetPreferencesFor(ctx context.Context,
dto.Language = &preference.JSONData.Language
}
if features.IsEnabled(ctx, featuremgmt.FlagLocaleFormatPreference) {
if preference.JSONData.Locale != "" {
dto.Locale = &preference.JSONData.Locale
}
}
if preference.JSONData.Navbar.BookmarkUrls != nil {
dto.Navbar = &preferences.NavbarPreference{
BookmarkUrls: []string{},
+12 -1
View File
@@ -67,6 +67,10 @@ func (s *Service) GetWithDefaults(ctx context.Context, query *pref.GetPreference
res.JSONData.Language = p.JSONData.Language
}
if p.JSONData.Locale != "" {
res.JSONData.Locale = p.JSONData.Locale
}
if p.JSONData.QueryHistory.HomeTab != "" {
res.JSONData.QueryHistory.HomeTab = p.JSONData.QueryHistory.HomeTab
}
@@ -174,6 +178,13 @@ func (s *Service) Patch(ctx context.Context, cmd *pref.PatchPreferenceCommand) e
preference.JSONData.Language = *cmd.Language
}
if cmd.Locale != nil {
if preference.JSONData == nil {
preference.JSONData = &pref.PreferenceJSONData{}
}
preference.JSONData.Locale = *cmd.Locale
}
if cmd.Navbar != nil && cmd.Navbar.BookmarkUrls != nil {
if preference.JSONData == nil {
preference.JSONData = &pref.PreferenceJSONData{}
@@ -266,8 +277,8 @@ func parseCookiePreferences(prefs []pref.CookieType) (map[string]struct{}, error
func preferenceData(cmd *pref.SavePreferenceCommand) (*pref.PreferenceJSONData, error) {
jsonData := &pref.PreferenceJSONData{
Language: cmd.Language,
Locale: cmd.Locale,
}
if cmd.Navbar != nil {
jsonData.Navbar = *cmd.Navbar
}
@@ -92,6 +92,7 @@ func TestGetWithDefaults_withUserAndOrgPrefs(t *testing.T) {
WeekStart: &weekStartOne,
JSONData: &pref.PreferenceJSONData{
Language: "en-GB",
Locale: "en-US",
},
},
pref.Preference{
@@ -103,6 +104,7 @@ func TestGetWithDefaults_withUserAndOrgPrefs(t *testing.T) {
WeekStart: &weekStartTwo,
JSONData: &pref.PreferenceJSONData{
Language: "en-AU",
Locale: "es-ES",
},
},
)
@@ -118,6 +120,7 @@ func TestGetWithDefaults_withUserAndOrgPrefs(t *testing.T) {
HomeDashboardID: 4,
JSONData: &pref.PreferenceJSONData{
Language: "en-AU",
Locale: "es-ES",
},
}
if diff := cmp.Diff(expected, preference); diff != "" {
@@ -137,6 +140,7 @@ func TestGetWithDefaults_withUserAndOrgPrefs(t *testing.T) {
HomeDashboardID: 1,
JSONData: &pref.PreferenceJSONData{
Language: "en-GB",
Locale: "en-US",
},
}
if diff := cmp.Diff(expected, preference); diff != "" {
@@ -157,6 +161,9 @@ func TestGetDefaults_JSONData(t *testing.T) {
orgPreferencesWithLanguageJsonData := pref.PreferenceJSONData{
Language: "en-GB",
}
orgPreferencesWithLocaleJsonData := pref.PreferenceJSONData{
Locale: "en-US",
}
team2PreferencesJsonData := pref.PreferenceJSONData{}
team1PreferencesJsonData := pref.PreferenceJSONData{}
@@ -217,6 +224,36 @@ func TestGetDefaults_JSONData(t *testing.T) {
}, preference)
})
t.Run("user JSONData with missing locale does not override org preference", func(t *testing.T) {
prefService := &Service{
store: newFake(),
defaults: prefsFromConfig(setting.NewCfg()),
}
insertPrefs(t, prefService.store,
pref.Preference{
OrgID: 1,
JSONData: &orgPreferencesWithLocaleJsonData,
},
pref.Preference{
OrgID: 1,
UserID: 1,
JSONData: &userPreferencesJsonData,
},
)
query := &pref.GetPreferenceWithDefaultsQuery{OrgID: 1, UserID: 1}
preference, err := prefService.GetWithDefaults(context.Background(), query)
require.NoError(t, err)
require.Equal(t, &pref.Preference{
WeekStart: &weekStart,
JSONData: &pref.PreferenceJSONData{
Locale: "en-US",
QueryHistory: queryPreference,
},
}, preference)
})
t.Run("teams have precedence over org and are read in ascending order", func(t *testing.T) {
prefService := &Service{
store: newFake(),