i18n: Add locale to backend (#102233)
This commit is contained in:
@@ -222,6 +222,7 @@ Experimental features might be changed or removed without prior notice.
|
||||
| `newLogsPanel` | Enables the new logs panel in Explore |
|
||||
| `pluginsCDNSyncLoader` | Load plugins from CDN synchronously |
|
||||
| `assetSriChecks` | Enables SRI checks for Grafana JavaScript assets |
|
||||
| `localeFormatPreference` | Specify the locale so we can show the correct format for numbers and dates |
|
||||
| `localizationForPlugins` | Enables localization for plugins |
|
||||
|
||||
## Development feature toggles
|
||||
|
||||
@@ -27,6 +27,9 @@ lineage: schemas: [{
|
||||
// Selected language (beta)
|
||||
language?: string
|
||||
|
||||
// Selected locale (beta)
|
||||
locale?: string
|
||||
|
||||
// Explore query history preferences
|
||||
queryHistory?: #QueryHistoryPreference
|
||||
|
||||
|
||||
@@ -1047,6 +1047,10 @@ export interface FeatureToggles {
|
||||
*/
|
||||
unifiedStorageHistoryPruner?: boolean;
|
||||
/**
|
||||
* Specify the locale so we can show the correct format for numbers and dates
|
||||
*/
|
||||
localeFormatPreference?: boolean;
|
||||
/**
|
||||
* Enables the unified storage grpc connection pool
|
||||
*/
|
||||
unifiedStorageGrpcConnectionPool?: boolean;
|
||||
|
||||
@@ -46,6 +46,10 @@ export interface Preferences {
|
||||
* Selected language (beta)
|
||||
*/
|
||||
language?: string;
|
||||
/**
|
||||
* Selected locale (beta)
|
||||
*/
|
||||
locale?: string;
|
||||
/**
|
||||
* Navigation preferences
|
||||
*/
|
||||
|
||||
@@ -17,6 +17,7 @@ type UpdatePrefsCmd struct {
|
||||
WeekStart string `json:"weekStart"`
|
||||
QueryHistory *pref.QueryHistoryPreference `json:"queryHistory,omitempty"`
|
||||
Language string `json:"language"`
|
||||
Locale string `json:"locale"`
|
||||
Cookies []pref.CookieType `json:"cookies,omitempty"`
|
||||
Navbar *pref.NavbarPreference `json:"navbar,omitempty"`
|
||||
}
|
||||
@@ -32,6 +33,7 @@ type PatchPrefsCmd struct {
|
||||
Timezone *string `json:"timezone,omitempty"`
|
||||
WeekStart *string `json:"weekStart,omitempty"`
|
||||
Language *string `json:"language,omitempty"`
|
||||
Locale *string `json:"locale,omitempty"`
|
||||
QueryHistory *pref.QueryHistoryPreference `json:"queryHistory,omitempty"`
|
||||
HomeDashboardUID *string `json:"homeDashboardUID,omitempty"`
|
||||
Cookies []pref.CookieType `json:"cookies,omitempty"`
|
||||
|
||||
+8
-2
@@ -50,8 +50,8 @@ func (hs *HTTPServer) setIndexViewData(c *contextmodel.ReqContext) (*dtos.IndexV
|
||||
// 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
|
||||
locale := "en-US" // default to en-US formatting, but use the accept-lang header or user's preference
|
||||
language := "" // frontend will set the default language
|
||||
|
||||
if prefs.JSONData.Language != "" {
|
||||
language = prefs.JSONData.Language
|
||||
@@ -62,6 +62,12 @@ func (hs *HTTPServer) setIndexViewData(c *contextmodel.ReqContext) (*dtos.IndexV
|
||||
locale = parts[0]
|
||||
}
|
||||
|
||||
if hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagLocaleFormatPreference) {
|
||||
if prefs.JSONData.Locale != "" {
|
||||
locale = prefs.JSONData.Locale
|
||||
}
|
||||
}
|
||||
|
||||
appURL := hs.Cfg.AppURL
|
||||
appSubURL := hs.Cfg.AppSubURL
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ func (hs *HTTPServer) GetUserPreferences(c *contextmodel.ReqContext) response.Re
|
||||
return response.Error(http.StatusInternalServerError, "Failed to update user preferences", err)
|
||||
}
|
||||
|
||||
return prefapi.GetPreferencesFor(c.Req.Context(), hs.DashboardService, hs.preferenceService, c.SignedInUser.GetOrgID(), userID, 0)
|
||||
return prefapi.GetPreferencesFor(c.Req.Context(), hs.DashboardService, hs.preferenceService, hs.Features, c.SignedInUser.GetOrgID(), userID, 0)
|
||||
}
|
||||
|
||||
// swagger:route PUT /user/preferences user_preferences updateUserPreferences
|
||||
@@ -95,7 +95,7 @@ func (hs *HTTPServer) UpdateUserPreferences(c *contextmodel.ReqContext) response
|
||||
}
|
||||
|
||||
return prefapi.UpdatePreferencesFor(c.Req.Context(), hs.DashboardService,
|
||||
hs.preferenceService, c.SignedInUser.GetOrgID(), userID, 0, &dtoCmd)
|
||||
hs.preferenceService, hs.Features, c.SignedInUser.GetOrgID(), userID, 0, &dtoCmd)
|
||||
}
|
||||
|
||||
// swagger:route PATCH /user/preferences user_preferences patchUserPreferences
|
||||
@@ -153,6 +153,7 @@ func (hs *HTTPServer) patchPreferencesFor(ctx context.Context, orgID, userID, te
|
||||
WeekStart: dtoCmd.WeekStart,
|
||||
HomeDashboardID: dtoCmd.HomeDashboardID,
|
||||
Language: dtoCmd.Language,
|
||||
Locale: dtoCmd.Locale,
|
||||
QueryHistory: dtoCmd.QueryHistory,
|
||||
CookiePreferences: dtoCmd.Cookies,
|
||||
Navbar: dtoCmd.Navbar,
|
||||
@@ -175,7 +176,7 @@ func (hs *HTTPServer) patchPreferencesFor(ctx context.Context, orgID, userID, te
|
||||
// 403: forbiddenError
|
||||
// 500: internalServerError
|
||||
func (hs *HTTPServer) GetOrgPreferences(c *contextmodel.ReqContext) response.Response {
|
||||
return prefapi.GetPreferencesFor(c.Req.Context(), hs.DashboardService, hs.preferenceService, c.SignedInUser.GetOrgID(), 0, 0)
|
||||
return prefapi.GetPreferencesFor(c.Req.Context(), hs.DashboardService, hs.preferenceService, hs.Features, c.SignedInUser.GetOrgID(), 0, 0)
|
||||
}
|
||||
|
||||
// swagger:route PUT /org/preferences org_preferences updateOrgPreferences
|
||||
@@ -194,7 +195,7 @@ func (hs *HTTPServer) UpdateOrgPreferences(c *contextmodel.ReqContext) response.
|
||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||
}
|
||||
|
||||
return prefapi.UpdatePreferencesFor(c.Req.Context(), hs.DashboardService, hs.preferenceService, c.SignedInUser.GetOrgID(), 0, 0, &dtoCmd)
|
||||
return prefapi.UpdatePreferencesFor(c.Req.Context(), hs.DashboardService, hs.preferenceService, hs.Features, c.SignedInUser.GetOrgID(), 0, 0, &dtoCmd)
|
||||
}
|
||||
|
||||
// swagger:route PATCH /org/preferences org_preferences patchOrgPreferences
|
||||
|
||||
@@ -25,6 +25,8 @@ type Spec struct {
|
||||
Theme *string `json:"theme,omitempty"`
|
||||
// Selected language (beta)
|
||||
Language *string `json:"language,omitempty"`
|
||||
// Selected locale (beta)
|
||||
Locale *string `json:"locale,omitempty"`
|
||||
// Explore query history preferences
|
||||
QueryHistory *QueryHistoryPreference `json:"queryHistory,omitempty"`
|
||||
// Cookie preferences
|
||||
|
||||
@@ -1800,6 +1800,12 @@ var (
|
||||
HideFromAdminPage: true,
|
||||
HideFromDocs: true,
|
||||
},
|
||||
{
|
||||
Name: "localeFormatPreference",
|
||||
Description: "Specify the locale so we can show the correct format for numbers and dates",
|
||||
Stage: FeatureStageExperimental,
|
||||
Owner: grafanaFrontendPlatformSquad,
|
||||
},
|
||||
{
|
||||
Name: "unifiedStorageGrpcConnectionPool",
|
||||
Description: "Enables the unified storage grpc connection pool",
|
||||
|
||||
@@ -237,6 +237,7 @@ inviteUserExperimental,experimental,@grafana/sharing-squad,false,false,true
|
||||
noBackdropBlur,experimental,@grafana/grafana-frontend-platform,false,false,true
|
||||
alertingMigrationUI,experimental,@grafana/alerting-squad,false,false,true
|
||||
unifiedStorageHistoryPruner,experimental,@grafana/search-and-storage,false,false,false
|
||||
localeFormatPreference,experimental,@grafana/grafana-frontend-platform,false,false,false
|
||||
unifiedStorageGrpcConnectionPool,experimental,@grafana/search-and-storage,false,false,false
|
||||
alertingRuleRecoverDeleted,GA,@grafana/alerting-squad,false,false,true
|
||||
localizationForPlugins,experimental,@grafana/plugins-platform-backend,false,false,false
|
||||
|
||||
|
@@ -959,6 +959,10 @@ const (
|
||||
// Enables the unified storage history pruner
|
||||
FlagUnifiedStorageHistoryPruner = "unifiedStorageHistoryPruner"
|
||||
|
||||
// FlagLocaleFormatPreference
|
||||
// Specify the locale so we can show the correct format for numbers and dates
|
||||
FlagLocaleFormatPreference = "localeFormatPreference"
|
||||
|
||||
// FlagUnifiedStorageGrpcConnectionPool
|
||||
// Enables the unified storage grpc connection pool
|
||||
FlagUnifiedStorageGrpcConnectionPool = "unifiedStorageGrpcConnectionPool"
|
||||
|
||||
@@ -2469,6 +2469,18 @@
|
||||
"frontend": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"name": "localeFormatPreference",
|
||||
"resourceVersion": "1742397804851",
|
||||
"creationTimestamp": "2025-03-19T15:23:24Z"
|
||||
},
|
||||
"spec": {
|
||||
"description": "Specify the locale so we can show the correct format for numbers and dates",
|
||||
"stage": "experimental",
|
||||
"codeowner": "@grafana/grafana-frontend-platform"
|
||||
}
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"name": "localizationForPlugins",
|
||||
|
||||
@@ -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"`
|
||||
|
||||
@@ -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{},
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/middleware/requestmeta"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/licensing"
|
||||
pref "github.com/grafana/grafana/pkg/services/preference"
|
||||
"github.com/grafana/grafana/pkg/services/team"
|
||||
@@ -23,6 +24,7 @@ type TeamAPI struct {
|
||||
preferenceService pref.Service
|
||||
ds dashboards.DashboardService
|
||||
logger log.Logger
|
||||
features featuremgmt.FeatureToggles
|
||||
}
|
||||
|
||||
func ProvideTeamAPI(
|
||||
@@ -36,6 +38,7 @@ func ProvideTeamAPI(
|
||||
cfg *setting.Cfg,
|
||||
preferenceService pref.Service,
|
||||
ds dashboards.DashboardService,
|
||||
features featuremgmt.FeatureToggles,
|
||||
) *TeamAPI {
|
||||
tapi := &TeamAPI{
|
||||
teamService: teamService,
|
||||
@@ -47,6 +50,7 @@ func ProvideTeamAPI(
|
||||
preferenceService: preferenceService,
|
||||
ds: ds,
|
||||
logger: log.New("team-api"),
|
||||
features: features,
|
||||
}
|
||||
|
||||
tapi.registerRoutes(routeRegister, acEvaluator)
|
||||
|
||||
@@ -251,7 +251,7 @@ func (tapi *TeamAPI) getTeamPreferences(c *contextmodel.ReqContext) response.Res
|
||||
return response.Error(http.StatusBadRequest, "teamId is invalid", err)
|
||||
}
|
||||
|
||||
return prefapi.GetPreferencesFor(c.Req.Context(), tapi.ds, tapi.preferenceService, c.SignedInUser.GetOrgID(), 0, teamId)
|
||||
return prefapi.GetPreferencesFor(c.Req.Context(), tapi.ds, tapi.preferenceService, tapi.features, c.SignedInUser.GetOrgID(), 0, teamId)
|
||||
}
|
||||
|
||||
// swagger:route PUT /teams/{team_id}/preferences teams updateTeamPreferences
|
||||
@@ -274,7 +274,7 @@ func (tapi *TeamAPI) updateTeamPreferences(c *contextmodel.ReqContext) response.
|
||||
return response.Error(http.StatusBadRequest, "teamId is invalid", err)
|
||||
}
|
||||
|
||||
return prefapi.UpdatePreferencesFor(c.Req.Context(), tapi.ds, tapi.preferenceService, c.SignedInUser.GetOrgID(), 0, teamId, &dtoCmd)
|
||||
return prefapi.UpdatePreferencesFor(c.Req.Context(), tapi.ds, tapi.preferenceService, tapi.features, c.SignedInUser.GetOrgID(), 0, teamId, &dtoCmd)
|
||||
}
|
||||
|
||||
// swagger:parameters updateTeamPreferences
|
||||
|
||||
@@ -47,6 +47,7 @@ func SetupAPITestServer(t *testing.T, teamService team.Service, opts ...func(a *
|
||||
cfg,
|
||||
preftest.NewPreferenceServiceFake(),
|
||||
dashboards.NewFakeDashboardService(t),
|
||||
featuremgmt.WithFeatures(),
|
||||
)
|
||||
for _, o := range opts {
|
||||
o(a)
|
||||
@@ -302,6 +303,7 @@ func Test_getTeamMembershipUpdates(t *testing.T) {
|
||||
cfg,
|
||||
preftest.NewPreferenceServiceFake(),
|
||||
dashboards.NewFakeDashboardService(t),
|
||||
featuremgmt.WithFeatures(),
|
||||
)
|
||||
|
||||
user := &user.SignedInUser{UserID: 1, OrgID: 1, OrgRole: org.RoleAdmin, Permissions: map[int64]map[string][]string{1: {accesscontrol.ActionOrgUsersRead: {"users:id:*"}}}}
|
||||
|
||||
@@ -17990,6 +17990,9 @@
|
||||
"language": {
|
||||
"type": "string"
|
||||
},
|
||||
"locale": {
|
||||
"type": "string"
|
||||
},
|
||||
"navbar": {
|
||||
"$ref": "#/definitions/NavbarPreference"
|
||||
},
|
||||
@@ -18609,6 +18612,10 @@
|
||||
"description": "Selected language (beta)",
|
||||
"type": "string"
|
||||
},
|
||||
"locale": {
|
||||
"description": "Selected locale (beta)",
|
||||
"type": "string"
|
||||
},
|
||||
"navbar": {
|
||||
"$ref": "#/definitions/NavbarPreference"
|
||||
},
|
||||
@@ -22060,6 +22067,9 @@
|
||||
"language": {
|
||||
"type": "string"
|
||||
},
|
||||
"locale": {
|
||||
"type": "string"
|
||||
},
|
||||
"navbar": {
|
||||
"$ref": "#/definitions/NavbarPreference"
|
||||
},
|
||||
|
||||
@@ -7985,6 +7985,9 @@
|
||||
"language": {
|
||||
"type": "string"
|
||||
},
|
||||
"locale": {
|
||||
"type": "string"
|
||||
},
|
||||
"navbar": {
|
||||
"$ref": "#/components/schemas/NavbarPreference"
|
||||
},
|
||||
@@ -8604,6 +8607,10 @@
|
||||
"description": "Selected language (beta)",
|
||||
"type": "string"
|
||||
},
|
||||
"locale": {
|
||||
"description": "Selected locale (beta)",
|
||||
"type": "string"
|
||||
},
|
||||
"navbar": {
|
||||
"$ref": "#/components/schemas/NavbarPreference"
|
||||
},
|
||||
@@ -12054,6 +12061,9 @@
|
||||
"language": {
|
||||
"type": "string"
|
||||
},
|
||||
"locale": {
|
||||
"type": "string"
|
||||
},
|
||||
"navbar": {
|
||||
"$ref": "#/components/schemas/NavbarPreference"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user