From 52c47612182f97f440ba2c3377420794a5cf16ce Mon Sep 17 00:00:00 2001 From: Josh Hunt Date: Tue, 6 Jun 2023 17:26:06 +0100 Subject: [PATCH] Fix: Fix dashboards not showing in folders with search v2 enabled (#69638) * Fix: Fix dashboards not showing in folders with search v2 enabled * tests --- .../browse-dashboards/api/services.test.ts | 49 +++++++++++++++++++ .../browse-dashboards/api/services.ts | 2 +- .../app/features/search/service/sql.test.ts | 27 ++++++++++ public/app/features/search/service/sql.ts | 6 ++- 4 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 public/app/features/browse-dashboards/api/services.test.ts diff --git a/public/app/features/browse-dashboards/api/services.test.ts b/public/app/features/browse-dashboards/api/services.test.ts new file mode 100644 index 00000000000..39675f0f582 --- /dev/null +++ b/public/app/features/browse-dashboards/api/services.test.ts @@ -0,0 +1,49 @@ +import { DataFrame, DataFrameView, FieldType } from '@grafana/data'; +import { DashboardQueryResult, getGrafanaSearcher, QueryResponse } from 'app/features/search/service'; + +import { listDashboards } from './services'; + +describe('browse-dashboards services', () => { + describe('listDashboards', () => { + const searchData: DataFrame = { + fields: [ + { name: 'kind', type: FieldType.string, config: {}, values: [] }, + { name: 'name', type: FieldType.string, config: {}, values: [] }, + { name: 'uid', type: FieldType.string, config: {}, values: [] }, + { name: 'url', type: FieldType.string, config: {}, values: [] }, + { name: 'tags', type: FieldType.other, config: {}, values: [] }, + { name: 'location', type: FieldType.string, config: {}, values: [] }, + ], + length: 0, + }; + + const mockSearchResult: QueryResponse = { + isItemLoaded: jest.fn(), + loadMoreItems: jest.fn(), + totalRows: searchData.length, + view: new DataFrameView(searchData), + }; + + const searchMock = jest.spyOn(getGrafanaSearcher(), 'search'); + searchMock.mockResolvedValue(mockSearchResult); + + const PAGE_SIZE = 50; + + it.each([ + { page: undefined, expectedFrom: 0 }, + { page: 1, expectedFrom: 0 }, + { page: 2, expectedFrom: 50 }, + { page: 4, expectedFrom: 150 }, + ])('skips first $expectedFrom when listing page $page', async ({ page, expectedFrom }) => { + await listDashboards('abc-123', page, PAGE_SIZE); + + expect(searchMock).toHaveBeenCalledWith({ + kind: ['dashboard'], + query: '*', + location: 'abc-123', + from: expectedFrom, + limit: PAGE_SIZE, + }); + }); + }); +}); diff --git a/public/app/features/browse-dashboards/api/services.ts b/public/app/features/browse-dashboards/api/services.ts index 3f3c8ef5754..417865d9eb4 100644 --- a/public/app/features/browse-dashboards/api/services.ts +++ b/public/app/features/browse-dashboards/api/services.ts @@ -38,7 +38,7 @@ export async function listDashboards(parentUID?: string, page = 1, pageSize = PA kind: ['dashboard'], query: '*', location: parentUID || 'general', - from: page * pageSize, + from: (page - 1) * pageSize, // our pages are 1-indexed, so we need to -1 to convert that to correct value to skip limit: pageSize, }); diff --git a/public/app/features/search/service/sql.test.ts b/public/app/features/search/service/sql.test.ts index 79b50ba3bdc..ae69757e94c 100644 --- a/public/app/features/search/service/sql.test.ts +++ b/public/app/features/search/service/sql.test.ts @@ -118,4 +118,31 @@ describe('SQLSearcher', () => { starred: true, }); }); + + describe('pagination', () => { + it.each([ + { from: undefined, expectedPage: undefined }, + { from: 0, expectedPage: 1 }, + { from: 50, expectedPage: 2 }, + { from: 150, expectedPage: 4 }, + ])('should search page $expectedPage when skipping $from results', async ({ from, expectedPage }) => { + searchMock.mockResolvedValue([]); + const sqlSearcher = new SQLSearcher(); + + await sqlSearcher.search({ + query: '*', + kind: ['dashboard'], + from, + limit: 50, + }); + + expect(searchMock).toHaveBeenLastCalledWith('/api/search', { + limit: 50, + page: expectedPage, + sort: undefined, + tag: undefined, + type: 'dash-db', + }); + }); + }); }); diff --git a/public/app/features/search/service/sql.ts b/public/app/features/search/service/sql.ts index 636e2882b34..a67992afe6a 100644 --- a/public/app/features/search/service/sql.ts +++ b/public/app/features/search/service/sql.ts @@ -81,7 +81,11 @@ export class SQLSearcher implements GrafanaSearcher { } const limit = query.limit ?? (query.from !== undefined ? 1 : DEFAULT_MAX_VALUES); - const page = query.from !== undefined ? query.from / limit : undefined; + const page = + query.from !== undefined + ? // prettier-ignore + (query.from / limit) + 1 // pages are 1-indexed, so need to +1 to get there + : undefined; const q = await this.composeQuery( {