Preferences: Use dashboard uid for the home dashboard (#106666)

This commit is contained in:
Stephanie Hingtgen
2025-06-13 07:10:44 -05:00
committed by GitHub
parent 4c2bfe8263
commit 352aac162c
16 changed files with 303 additions and 177 deletions
+4 -5
View File
@@ -580,16 +580,15 @@ func (hs *HTTPServer) GetHomeDashboard(c *contextmodel.ReqContext) response.Resp
return response.Error(http.StatusInternalServerError, "Failed to get preferences", err)
}
if preference.HomeDashboardID == 0 && len(homePage) > 0 {
if preference.HomeDashboardUID == "" && len(homePage) > 0 {
homePageRedirect := dtos.DashboardRedirect{RedirectUri: homePage}
return response.JSON(http.StatusOK, &homePageRedirect)
}
if preference.HomeDashboardID != 0 {
slugQuery := dashboards.GetDashboardRefByIDQuery{ID: preference.HomeDashboardID}
slugQueryResult, err := hs.DashboardService.GetDashboardUIDByID(c.Req.Context(), &slugQuery)
if preference.HomeDashboardUID != "" {
slugQueryResult, err := hs.DashboardService.GetDashboard(c.Req.Context(), &dashboards.GetDashboardQuery{UID: preference.HomeDashboardUID, OrgID: c.GetOrgID()})
if err == nil {
url := dashboards.GetDashboardURL(slugQueryResult.UID, slugQueryResult.Slug)
url := dashboards.GetDashboardURL(preference.HomeDashboardUID, slugQueryResult.Slug)
dashRedirect := dtos.DashboardRedirect{RedirectUri: url}
return response.JSON(http.StatusOK, &dashRedirect)
}
+2
View File
@@ -10,6 +10,7 @@ type UpdatePrefsCmd struct {
Theme string `json:"theme"`
// The numerical :id of a favorited dashboard
// Default:0
// Deprecated: Use HomeDashboardUID instead
HomeDashboardID int64 `json:"homeDashboardId"`
HomeDashboardUID *string `json:"homeDashboardUID,omitempty"`
// Enum: utc,browser
@@ -28,6 +29,7 @@ type PatchPrefsCmd struct {
Theme *string `json:"theme,omitempty"`
// The numerical :id of a favorited dashboard
// Default:0
// Deprecated: Use HomeDashboardUID instead
HomeDashboardID *int64 `json:"homeDashboardId,omitempty"`
// Enum: utc,browser
Timezone *string `json:"timezone,omitempty"`
+23 -4
View File
@@ -30,8 +30,8 @@ func (hs *HTTPServer) SetHomeDashboard(c *contextmodel.ReqContext) response.Resp
cmd.UserID = userID
cmd.OrgID = c.GetOrgID()
// the default value of HomeDashboardID is taken from input, when HomeDashboardID is set also,
// UID is used in preference to identify dashboard
// convert dashboard UID to ID in order to store internally if it exists in the query, otherwise take the id from query
// nolint:staticcheck
dashboardID := cmd.HomeDashboardID
if cmd.HomeDashboardUID != nil {
query := dashboards.GetDashboardQuery{UID: *cmd.HomeDashboardUID}
@@ -44,8 +44,16 @@ func (hs *HTTPServer) SetHomeDashboard(c *contextmodel.ReqContext) response.Resp
}
dashboardID = queryResult.ID
}
} else if cmd.HomeDashboardID != 0 { // nolint:staticcheck
// make sure uid is always set if id is set
queryResult, err := hs.DashboardService.GetDashboard(c.Req.Context(), &dashboards.GetDashboardQuery{ID: cmd.HomeDashboardID, OrgID: cmd.OrgID}) // nolint:staticcheck
if err != nil {
return response.Error(http.StatusNotFound, "Dashboard not found", err)
}
cmd.HomeDashboardUID = &queryResult.UID
}
// nolint:staticcheck
cmd.HomeDashboardID = dashboardID
if err := hs.preferenceService.Save(c.Req.Context(), &cmd); err != nil {
@@ -76,7 +84,7 @@ func (hs *HTTPServer) GetUserPreferences(c *contextmodel.ReqContext) response.Re
//
// Update user preferences.
//
// Omitting a key (`theme`, `homeDashboardId`, `timezone`) will cause the current value to be replaced with the system default value.
// Omitting a key (`theme`, `homeDashboardUID`, `timezone`) will cause the current value to be replaced with the system default value.
//
// Responses:
// 200: okResponse
@@ -127,6 +135,7 @@ func (hs *HTTPServer) patchPreferencesFor(ctx context.Context, orgID, userID, te
}
// convert dashboard UID to ID in order to store internally if it exists in the query, otherwise take the id from query
// nolint:staticcheck
dashboardID := dtoCmd.HomeDashboardID
if dtoCmd.HomeDashboardUID != nil {
query := dashboards.GetDashboardQuery{UID: *dtoCmd.HomeDashboardUID, OrgID: orgID}
@@ -141,7 +150,16 @@ func (hs *HTTPServer) patchPreferencesFor(ctx context.Context, orgID, userID, te
}
dashboardID = &queryResult.ID
}
} else if dtoCmd.HomeDashboardID != nil {
// make sure uid is always set if id is set
queryResult, err := hs.DashboardService.GetDashboard(ctx, &dashboards.GetDashboardQuery{ID: *dtoCmd.HomeDashboardID, OrgID: orgID}) // nolint:staticcheck
if err != nil {
return response.Error(http.StatusNotFound, "Dashboard not found", err)
}
dtoCmd.HomeDashboardUID = &queryResult.UID
}
// nolint:staticcheck
dtoCmd.HomeDashboardID = dashboardID
patchCmd := pref.PatchPreferenceCommand{
@@ -151,7 +169,8 @@ func (hs *HTTPServer) patchPreferencesFor(ctx context.Context, orgID, userID, te
Theme: dtoCmd.Theme,
Timezone: dtoCmd.Timezone,
WeekStart: dtoCmd.WeekStart,
HomeDashboardID: dtoCmd.HomeDashboardID,
HomeDashboardID: dtoCmd.HomeDashboardID, // nolint:staticcheck
HomeDashboardUID: dtoCmd.HomeDashboardUID,
Language: dtoCmd.Language,
Locale: dtoCmd.Locale,
QueryHistory: dtoCmd.QueryHistory,
+5 -5
View File
@@ -37,14 +37,9 @@ func TestAPIEndpoint_GetCurrentOrgPreferences(t *testing.T) {
prefService := preftest.NewPreferenceServiceFake()
prefService.ExpectedPreference = &pref.Preference{HomeDashboardID: 1, Theme: "dark"}
dashSvc := dashboards.NewFakeDashboardService(t)
qResult := &dashboards.Dashboard{UID: "home", ID: 1}
dashSvc.On("GetDashboard", mock.Anything, mock.AnythingOfType("*dashboards.GetDashboardQuery")).Return(qResult, nil)
server := SetupAPITestServer(t, func(hs *HTTPServer) {
hs.Cfg = setting.NewCfg()
hs.preferenceService = prefService
hs.DashboardService = dashSvc
})
t.Run("AccessControl allows getting org preferences with correct permissions", func(t *testing.T) {
@@ -78,9 +73,14 @@ func TestAPIEndpoint_PutCurrentOrgPreferences(t *testing.T) {
prefService := preftest.NewPreferenceServiceFake()
prefService.ExpectedPreference = &pref.Preference{HomeDashboardID: 1, Theme: "dark"}
dashSvc := dashboards.NewFakeDashboardService(t)
qResult := &dashboards.Dashboard{UID: "home", ID: 1}
dashSvc.On("GetDashboard", mock.Anything, mock.AnythingOfType("*dashboards.GetDashboardQuery")).Return(qResult, nil)
server := SetupAPITestServer(t, func(hs *HTTPServer) {
hs.Cfg = setting.NewCfg()
hs.preferenceService = prefService
hs.DashboardService = dashSvc
})
input := strings.NewReader(testUpdateOrgPreferencesCmd)