unified-storage: fix modes 1/2 pagination in dashboard list view (#115511)

* unified-storage: fix modes 1/2 pagination in dashboard list view
This commit is contained in:
Will Assis
2025-12-17 14:51:07 -05:00
committed by GitHub
parent fbd5fe4bd2
commit 5861b6c0d5
3 changed files with 109 additions and 7 deletions
@@ -360,7 +360,17 @@ func (c *DashboardSearchClient) Search(ctx context.Context, req *resourcepb.Reso
})
}
list.TotalHits = int64(len(list.Results.Rows))
// the UI expects us to populate "TotalHits" with the total search hits, not however many we are returning.
// this is a dumb workaround due to the fact that legacy doesn't expose a way of "counting search hits"
// it fixes a bug that only happens in mode 1-2 that prevents pagination from working in the dashboard list view
// we only have a handful of instances running in this mode and moving towards 0 instances fast, so this is fine
query.Limit = 0
query.Page = 1
res, err = c.dashboardStore.FindDashboards(ctx, query)
if err != nil {
return nil, err
}
list.TotalHits = int64(len(res))
return list, nil
}
@@ -48,6 +48,18 @@ func TestDashboardSearchClient_Search(t *testing.T) {
{ID: 2, UID: "uid2", Title: "Test Dashboard2", FolderUID: "folder2", Tags: []string{}},
}, nil).Once()
// Second call for total count with Page: 1, Limit: 0
mockStore.On("FindDashboards", mock.Anything, &dashboards.FindPersistedDashboardsQuery{
SignedInUser: user,
Type: "dash-db",
Sort: sorter,
Limit: 0,
Page: 1,
}).Return([]dashboards.DashboardSearchProjection{
{ID: 1, UID: "uid", Title: "Test Dashboard", FolderUID: "folder1", Tags: []string{"term"}},
{ID: 2, UID: "uid2", Title: "Test Dashboard2", FolderUID: "folder2", Tags: []string{}},
}, nil).Once()
req := &resourcepb.ResourceSearchRequest{
Options: &resourcepb.ListOptions{
Key: dashboardKey,
@@ -124,6 +136,17 @@ func TestDashboardSearchClient_Search(t *testing.T) {
{ID: 1, UID: "uid", Title: "Test Dashboard", FolderUID: "folder", SortMeta: int64(50), Tags: []string{}},
}, nil).Once()
// Second call for total count with Page: 1, Limit: 0
mockStore.On("FindDashboards", mock.Anything, &dashboards.FindPersistedDashboardsQuery{
SignedInUser: user,
Type: "dash-db",
Sort: sortOptionAsc,
Limit: 0,
Page: 1,
}).Return([]dashboards.DashboardSearchProjection{
{ID: 1, UID: "uid", Title: "Test Dashboard", FolderUID: "folder", SortMeta: int64(50), Tags: []string{}},
}, nil).Once()
req := &resourcepb.ResourceSearchRequest{
Options: &resourcepb.ListOptions{
Key: dashboardKey,
@@ -189,6 +212,17 @@ func TestDashboardSearchClient_Search(t *testing.T) {
{ID: 1, UID: "uid", Title: "Test Dashboard", FolderUID: "folder", SortMeta: int64(2), Tags: []string{}},
}, nil).Once()
// Second call for total count with Page: 1, Limit: 0
mockStore.On("FindDashboards", mock.Anything, &dashboards.FindPersistedDashboardsQuery{
SignedInUser: user,
Type: "dash-db",
Sort: sortOptionAsc,
Limit: 0,
Page: 1,
}).Return([]dashboards.DashboardSearchProjection{
{ID: 1, UID: "uid", Title: "Test Dashboard", FolderUID: "folder", SortMeta: int64(2), Tags: []string{}},
}, nil).Once()
req := &resourcepb.ResourceSearchRequest{
Options: &resourcepb.ListOptions{
Key: dashboardKey,
@@ -293,6 +327,17 @@ func TestDashboardSearchClient_Search(t *testing.T) {
{UID: "uid", Title: "Test Dashboard", FolderUID: "folder1"},
}, nil).Once()
// Second call for total count with Page: 1, Limit: 0
mockStore.On("FindDashboards", mock.Anything, &dashboards.FindPersistedDashboardsQuery{
Title: "test",
SignedInUser: user,
Type: "dash-db",
Limit: 0,
Page: 1,
}).Return([]dashboards.DashboardSearchProjection{
{UID: "uid", Title: "Test Dashboard", FolderUID: "folder1"},
}, nil).Once()
req := &resourcepb.ResourceSearchRequest{
Options: &resourcepb.ListOptions{
Key: dashboardKey,
@@ -319,6 +364,18 @@ func TestDashboardSearchClient_Search(t *testing.T) {
{UID: "uid", Title: "Test Dashboard", FolderUID: "folder1"},
}, nil).Once()
// Second call for total count with Page: 1, Limit: 0
mockStore.On("FindDashboards", mock.Anything, &dashboards.FindPersistedDashboardsQuery{
Title: "test",
TitleExactMatch: true,
SignedInUser: user,
Type: "dash-db",
Limit: 0,
Page: 1,
}).Return([]dashboards.DashboardSearchProjection{
{UID: "uid", Title: "Test Dashboard", FolderUID: "folder1"},
}, nil).Once()
req := &resourcepb.ResourceSearchRequest{
Options: &resourcepb.ListOptions{
Key: dashboardKey,
@@ -350,6 +407,17 @@ func TestDashboardSearchClient_Search(t *testing.T) {
{UID: "uid", Title: "Test Dashboard", FolderUID: "folder1"},
}, nil).Once()
// Second call for total count with Page: 1, Limit: 0
mockStore.On("FindDashboards", mock.Anything, &dashboards.FindPersistedDashboardsQuery{
DashboardIds: []int64{1, 2},
SignedInUser: user,
Type: "dash-db",
Limit: 0,
Page: 1,
}).Return([]dashboards.DashboardSearchProjection{
{UID: "uid", Title: "Test Dashboard", FolderUID: "folder1"},
}, nil).Once()
req := &resourcepb.ResourceSearchRequest{
Options: &resourcepb.ListOptions{
Key: dashboardKey,
@@ -383,6 +451,19 @@ func TestDashboardSearchClient_Search(t *testing.T) {
{UID: "uid", Title: "Test Dashboard", FolderUID: "folder1"},
}, nil).Once()
// Second call for total count with Page: 1, Limit: 0
mockStore.On("FindDashboards", mock.Anything, &dashboards.FindPersistedDashboardsQuery{
DashboardUIDs: []string{"uid1", "uid2"},
Tags: []string{"tag1", "tag2"},
FolderUIDs: []string{"general", "folder1"},
SignedInUser: user,
Type: "dash-db",
Limit: 0,
Page: 1,
}).Return([]dashboards.DashboardSearchProjection{
{UID: "uid", Title: "Test Dashboard", FolderUID: "folder1"},
}, nil).Once()
req := &resourcepb.ResourceSearchRequest{
Options: &resourcepb.ListOptions{
Key: dashboardKey,
@@ -532,6 +613,17 @@ func TestDashboardSearchClient_Search(t *testing.T) {
{ID: 1, UID: "uid", Title: "Test Dashboard", FolderUID: "folder1"},
}, nil).Once()
// Second call for total count with Page: 1, Limit: 0
mockStore.On("FindDashboards", mock.Anything, &dashboards.FindPersistedDashboardsQuery{
SignedInUser: user,
Sort: sort.SortAlphaAsc,
Type: "dash-db",
Limit: 0,
Page: 1,
}).Return([]dashboards.DashboardSearchProjection{
{ID: 1, UID: "uid", Title: "Test Dashboard", FolderUID: "folder1"},
}, nil).Once()
req := &resourcepb.ResourceSearchRequest{
Options: &resourcepb.ListOptions{
Key: dashboardKey,
@@ -552,7 +644,7 @@ func TestDashboardSearchClient_Search(t *testing.T) {
t.Run("Should set correct sort field when sorting by views", func(t *testing.T) {
mockStore.On("FindDashboards", mock.Anything, mock.Anything).Return([]dashboards.DashboardSearchProjection{
{ID: 1, UID: "uid", Title: "Test Dashboard", FolderUID: "folder1", SortMeta: 100},
}, nil).Once()
}, nil).Twice() // Will be called twice due to the total count call
req := &resourcepb.ResourceSearchRequest{
Options: &resourcepb.ListOptions{
@@ -584,7 +676,7 @@ func TestDashboardSearchClient_Search(t *testing.T) {
mockStore.On("FindDashboards", mock.Anything, mock.Anything).Return([]dashboards.DashboardSearchProjection{
{UID: "dashboard1", FolderUID: "folder1", ID: 1},
{UID: "dashboard2", FolderUID: "folder2", ID: 2},
}, nil).Once()
}, nil).Twice() // Will be called twice due to the total count call
req := &resourcepb.ResourceSearchRequest{
Options: &resourcepb.ListOptions{
@@ -439,7 +439,7 @@ func TestIntegrationFolderServiceViaUnifiedStorage(t *testing.T) {
ID: fooFolder.ID, // nolint:staticcheck
UID: fooFolder.UID,
},
}, nil).Once()
}, nil).Twice() // Called twice due to total count call
id := int64(123)
emptyString := ""
query := &folder.GetFolderQuery{
@@ -455,7 +455,7 @@ func TestIntegrationFolderServiceViaUnifiedStorage(t *testing.T) {
})
t.Run("When get folder by non existing ID should return not found error", func(t *testing.T) {
dashboardStore.On("FindDashboards", mock.Anything, mock.Anything).Return([]dashboards.DashboardSearchProjection{}, nil).Once()
dashboardStore.On("FindDashboards", mock.Anything, mock.Anything).Return([]dashboards.DashboardSearchProjection{}, nil).Twice() // Called twice due to total count call
id := int64(111111)
query := &folder.GetFolderQuery{
ID: &id,
@@ -475,7 +475,7 @@ func TestIntegrationFolderServiceViaUnifiedStorage(t *testing.T) {
ID: fooFolder.ID, // nolint:staticcheck
UID: fooFolder.UID,
},
}, nil).Once()
}, nil).Twice() // Called twice due to total count call
title := "foo"
query := &folder.GetFolderQuery{
Title: &title,
@@ -489,7 +489,7 @@ func TestIntegrationFolderServiceViaUnifiedStorage(t *testing.T) {
})
t.Run("When get folder by non existing Title should return not found error", func(t *testing.T) {
dashboardStore.On("FindDashboards", mock.Anything, mock.Anything).Return([]dashboards.DashboardSearchProjection{}, nil).Once()
dashboardStore.On("FindDashboards", mock.Anything, mock.Anything).Return([]dashboards.DashboardSearchProjection{}, nil).Twice() // Called twice due to total count call
title := "does not exists"
query := &folder.GetFolderQuery{
Title: &title,