use dash-db type when searching for dashboard (#53607)

This commit is contained in:
Leo 2022-08-12 16:14:04 +02:00 committed by GitHub
parent dc8eb0b777
commit 0ce89dbcb6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 168 additions and 43 deletions

View File

@ -1,3 +1,5 @@
import { DashboardSearchItemType } from './types';
export const NO_ID_SECTIONS = ['Recent', 'Starred'];
// Height of the search result item
export const SEARCH_ITEM_HEIGHT = 58;
@ -9,3 +11,10 @@ export const GENERAL_FOLDER_UID = 'general';
export const GENERAL_FOLDER_TITLE = 'General';
export const SEARCH_PANELS_LOCAL_STORAGE_KEY = 'grafana.search.include.panels';
export const SEARCH_SELECTED_LAYOUT = 'grafana.search.layout';
export const TYPE_KIND_MAP: { [key: string]: DashboardSearchItemType } = {
dashboard: DashboardSearchItemType.DashDB,
folder: DashboardSearchItemType.DashFolder,
home: DashboardSearchItemType.DashHome,
};
export const DEFAULT_MAX_VALUES = 1000;

View File

@ -0,0 +1,121 @@
import { backendSrv } from 'app/core/services/backend_srv';
import { DashboardSearchItemType } from '../types';
import { SQLSearcher } from './sql';
const searchMock = jest.spyOn(backendSrv, 'get');
jest.spyOn(backendSrv, 'fetch');
describe('SQLSearcher', () => {
beforeEach(() => {
searchMock.mockReset();
});
it('should call search api with correct query for general folder', async () => {
searchMock.mockResolvedValue([]);
const sqlSearcher = new SQLSearcher();
const query = {
query: '*',
kind: ['dashboard'],
location: 'General',
sort: 'name_sort',
};
await sqlSearcher.search(query);
expect(searchMock).toHaveBeenLastCalledWith('/api/search', {
limit: 1000,
sort: query.sort,
tag: undefined,
type: DashboardSearchItemType.DashDB,
folderIds: [0],
});
});
it('should call search api with correct query based on its kinds', async () => {
searchMock.mockResolvedValue([]);
const sqlSearcher = new SQLSearcher();
const query = {
query: '*',
kind: ['folder'],
location: 'any',
sort: 'name_sort',
};
await sqlSearcher.search(query);
expect(searchMock).toHaveBeenLastCalledWith('/api/search', {
limit: 1000,
sort: query.sort,
tag: undefined,
type: DashboardSearchItemType.DashFolder,
folderIds: [0],
});
searchMock.mockClear();
const query2 = {
query: 'test',
kind: ['folder'],
location: 'any',
sort: 'name_sort',
};
await sqlSearcher.search(query2);
expect(searchMock).toHaveBeenLastCalledWith('/api/search', {
limit: 1000,
sort: query2.sort,
query: query2.query,
tag: undefined,
folderIds: [0],
});
searchMock.mockClear();
const query3 = {
query: 'test',
kind: ['folder'],
location: 'any',
sort: 'name_sort',
uid: ['T202C0Tnk'],
};
await sqlSearcher.search(query3);
expect(searchMock).toHaveBeenLastCalledWith('/api/search', {
limit: 1000,
sort: query3.sort,
query: query3.query,
tag: undefined,
dashboardUID: query3.uid,
});
});
it('starred should call search api with correct query', async () => {
searchMock.mockResolvedValue([]);
const sqlSearcher = new SQLSearcher();
const query = {
query: 'test',
kind: ['folder'],
location: 'any',
sort: 'name_sort',
uid: ['T202C0Tnk'],
starred: true,
};
await sqlSearcher.starred(query);
expect(searchMock).toHaveBeenLastCalledWith('/api/search', {
limit: 1000,
sort: query.sort,
query: query.query,
tag: undefined,
dashboardUID: query.uid,
starred: true,
});
});
});

View File

@ -3,7 +3,8 @@ import { config } from '@grafana/runtime';
import { TermCount } from 'app/core/components/TagFilter/TagFilter';
import { backendSrv } from 'app/core/services/backend_srv';
import { DashboardSearchHit } from '../types';
import { DEFAULT_MAX_VALUES, TYPE_KIND_MAP } from '../constants';
import { DashboardSearchHit, DashboardSearchItemType } from '../types';
import { LocationInfo } from './types';
import { replaceCurrentFolderQuery } from './utils';
@ -15,7 +16,7 @@ interface APIQuery {
tag?: string[];
limit?: number;
page?: number;
type?: string;
type?: DashboardSearchItemType;
// DashboardIds []int64
dashboardUID?: string[];
folderIds?: number[];
@ -38,36 +39,46 @@ export class SQLSearcher implements GrafanaSearcher {
},
}; // share location info with everyone
async search(query: SearchQuery): Promise<QueryResponse> {
if (query.facet?.length) {
throw new Error('facets not supported!');
}
const q: APIQuery = {
limit: query.limit ?? 1000, // default 1k max values
tag: query.tags,
sort: query.sort,
};
private async composeQuery(apiQuery: APIQuery, searchOptions: SearchQuery): Promise<APIQuery> {
const query = await replaceCurrentFolderQuery(searchOptions);
query = await replaceCurrentFolderQuery(query);
if (query.query === '*') {
if (query.kind?.length === 1 && query.kind[0] === 'folder') {
q.type = 'dash-folder';
if (query.kind?.length === 1 && TYPE_KIND_MAP[query.kind[0]]) {
apiQuery.type = TYPE_KIND_MAP[query.kind[0]];
}
} else if (query.query?.length) {
q.query = query.query;
apiQuery.query = query.query;
}
if (query.uid) {
q.dashboardUID = query.uid;
apiQuery.dashboardUID = query.uid;
} else if (query.location?.length) {
let info = this.locationInfo[query.location];
if (!info) {
// This will load all folder folders
await this.doAPIQuery({ type: 'dash-folder', limit: 999 });
await this.doAPIQuery({ type: DashboardSearchItemType.DashFolder, limit: 999 });
info = this.locationInfo[query.location];
}
q.folderIds = [info.folderId ?? 0];
apiQuery.folderIds = [info?.folderId ?? 0];
}
return apiQuery;
}
async search(query: SearchQuery): Promise<QueryResponse> {
if (query.facet?.length) {
throw new Error('facets not supported!');
}
const q = await this.composeQuery(
{
limit: query.limit ?? DEFAULT_MAX_VALUES, // default 1k max values
tag: query.tags,
sort: query.sort,
},
query
);
return this.doAPIQuery(q);
}
@ -75,33 +86,17 @@ export class SQLSearcher implements GrafanaSearcher {
if (query.facet?.length) {
throw new Error('facets not supported!');
}
const q: APIQuery = {
limit: query.limit ?? 1000, // default 1k max values
tag: query.tags,
sort: query.sort,
starred: query.starred,
};
query = await replaceCurrentFolderQuery(query);
if (query.query === '*') {
if (query.kind?.length === 1 && query.kind[0] === 'folder') {
q.type = 'dash-folder';
}
} else if (query.query?.length) {
q.query = query.query;
}
const q = await this.composeQuery(
{
limit: query.limit ?? DEFAULT_MAX_VALUES, // default 1k max values
tag: query.tags,
sort: query.sort,
starred: query.starred,
},
query
);
if (query.uid) {
q.dashboardUID = query.uid;
} else if (query.location?.length) {
let info = this.locationInfo[query.location];
if (!info) {
// This will load all folder folders
await this.doAPIQuery({ type: 'dash-folder', limit: 999 });
info = this.locationInfo[query.location];
}
q.folderIds = [info.folderId ?? 0];
}
return this.doAPIQuery(q);
}