mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
use dash-db type when searching for dashboard (#53607)
This commit is contained in:
parent
dc8eb0b777
commit
0ce89dbcb6
@ -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;
|
||||
|
121
public/app/features/search/service/sql.test.ts
Normal file
121
public/app/features/search/service/sql.test.ts
Normal 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,
|
||||
});
|
||||
});
|
||||
});
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user