mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Search: Improvements for starred dashboard search (#64758)
* improvements for starred dashboard search * fix workflows for the case when no dashboards are starred * PR feedback (don't query DB if starred dashboards and requested but no starred IDs are found) and linting * return empty list not null in case of no starred dashboards * return empty list not null in case of no starred dashboards pt 2 * return empty list not null in case of no starred dashboards pt 3
This commit is contained in:
@@ -58,10 +58,30 @@ type SearchService struct {
|
||||
}
|
||||
|
||||
func (s *SearchService) SearchHandler(ctx context.Context, query *Query) error {
|
||||
starredQuery := star.GetUserStarsQuery{
|
||||
UserID: query.SignedInUser.UserID,
|
||||
}
|
||||
staredDashIDs, err := s.starService.GetByUser(ctx, &starredQuery)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// No starred dashboards will be found
|
||||
if query.IsStarred && len(staredDashIDs.UserStars) == 0 {
|
||||
query.Result = model.HitList{}
|
||||
return nil
|
||||
}
|
||||
|
||||
// filter by starred dashboard IDs when starred dashboards are requested and no UID or ID filters are specified to improve query performance
|
||||
if query.IsStarred && len(query.DashboardIds) == 0 && len(query.DashboardUIDs) == 0 {
|
||||
for id := range staredDashIDs.UserStars {
|
||||
query.DashboardIds = append(query.DashboardIds, id)
|
||||
}
|
||||
}
|
||||
|
||||
dashboardQuery := dashboards.FindPersistedDashboardsQuery{
|
||||
Title: query.Title,
|
||||
SignedInUser: query.SignedInUser,
|
||||
IsStarred: query.IsStarred,
|
||||
DashboardUIDs: query.DashboardUIDs,
|
||||
DashboardIds: query.DashboardIds,
|
||||
Type: query.Type,
|
||||
@@ -85,11 +105,24 @@ func (s *SearchService) SearchHandler(ctx context.Context, query *Query) error {
|
||||
hits = sortedHits(hits)
|
||||
}
|
||||
|
||||
if err := s.setStarredDashboards(ctx, query.SignedInUser.UserID, hits); err != nil {
|
||||
return err
|
||||
// set starred dashboards
|
||||
for _, dashboard := range hits {
|
||||
if _, ok := staredDashIDs.UserStars[dashboard.ID]; ok {
|
||||
dashboard.IsStarred = true
|
||||
}
|
||||
}
|
||||
|
||||
query.Result = hits
|
||||
// filter for starred dashboards if requested
|
||||
if !query.IsStarred {
|
||||
query.Result = hits
|
||||
} else {
|
||||
query.Result = model.HitList{}
|
||||
for _, dashboard := range hits {
|
||||
if dashboard.IsStarred {
|
||||
query.Result = append(query.Result, dashboard)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -106,22 +139,3 @@ func sortedHits(unsorted model.HitList) model.HitList {
|
||||
|
||||
return hits
|
||||
}
|
||||
|
||||
func (s *SearchService) setStarredDashboards(ctx context.Context, userID int64, hits []*model.Hit) error {
|
||||
query := star.GetUserStarsQuery{
|
||||
UserID: userID,
|
||||
}
|
||||
|
||||
res, err := s.starService.GetByUser(ctx, &query)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
iuserstars := res.UserStars
|
||||
for _, dashboard := range hits {
|
||||
if _, ok := iuserstars[dashboard.ID]; ok {
|
||||
dashboard.IsStarred = true
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -62,3 +62,39 @@ func TestSearch_SortedResults(t *testing.T) {
|
||||
assert.Equal(t, "BB", query.Result[3].Tags[1])
|
||||
assert.Equal(t, "EE", query.Result[3].Tags[2])
|
||||
}
|
||||
|
||||
func TestSearch_StarredResults(t *testing.T) {
|
||||
ss := startest.NewStarServiceFake()
|
||||
db := dbtest.NewFakeDB()
|
||||
us := usertest.NewUserServiceFake()
|
||||
ds := dashboards.NewFakeDashboardService(t)
|
||||
ds.On("SearchDashboards", mock.Anything, mock.AnythingOfType("*dashboards.FindPersistedDashboardsQuery")).Run(func(args mock.Arguments) {
|
||||
q := args.Get(1).(*dashboards.FindPersistedDashboardsQuery)
|
||||
q.Result = model.HitList{
|
||||
&model.Hit{ID: 1, Title: "A", Type: "dash-db"},
|
||||
&model.Hit{ID: 2, Title: "B", Type: "dash-db"},
|
||||
&model.Hit{ID: 3, Title: "C", Type: "dash-db"},
|
||||
}
|
||||
}).Return(nil)
|
||||
us.ExpectedSignedInUser = &user.SignedInUser{}
|
||||
ss.ExpectedUserStars = &star.GetUserStarsResult{UserStars: map[int64]bool{1: true, 3: true, 4: true}}
|
||||
svc := &SearchService{
|
||||
sqlstore: db,
|
||||
starService: ss,
|
||||
dashboardService: ds,
|
||||
}
|
||||
|
||||
query := &Query{
|
||||
Limit: 2000,
|
||||
IsStarred: true,
|
||||
SignedInUser: &user.SignedInUser{},
|
||||
}
|
||||
|
||||
err := svc.SearchHandler(context.Background(), query)
|
||||
require.Nil(t, err)
|
||||
|
||||
// Assert only starred dashboards are returned
|
||||
assert.Equal(t, 2, query.Result.Len())
|
||||
assert.Equal(t, "A", query.Result[0].Title)
|
||||
assert.Equal(t, "C", query.Result[1].Title)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user