2021-04-21 02:38:00 -05:00
|
|
|
import { clone, keys, sortBy, take, values } from 'lodash';
|
2022-04-22 08:33:13 -05:00
|
|
|
|
|
|
|
import { contextSrv } from 'app/core/services/context_srv';
|
2017-12-20 05:33:33 -06:00
|
|
|
import impressionSrv from 'app/core/services/impression_srv';
|
|
|
|
import store from 'app/core/store';
|
2020-05-12 05:51:00 -05:00
|
|
|
import { SECTION_STORAGE_KEY } from 'app/features/search/constants';
|
2020-04-27 07:08:48 -05:00
|
|
|
import { DashboardSection, DashboardSearchItemType, DashboardSearchHit, SearchLayout } from 'app/features/search/types';
|
2022-04-22 08:33:13 -05:00
|
|
|
import { hasFilters } from 'app/features/search/utils';
|
|
|
|
|
2020-01-21 03:08:07 -06:00
|
|
|
import { backendSrv } from './backend_srv';
|
2019-03-19 08:48:35 -05:00
|
|
|
|
|
|
|
interface Sections {
|
2020-04-24 10:07:57 -05:00
|
|
|
[key: string]: Partial<DashboardSection>;
|
2019-03-19 08:48:35 -05:00
|
|
|
}
|
2017-11-02 10:54:33 -05:00
|
|
|
|
|
|
|
export class SearchSrv {
|
2020-04-24 10:07:57 -05:00
|
|
|
private getRecentDashboards(sections: DashboardSection[] | any) {
|
2019-03-19 08:48:35 -05:00
|
|
|
return this.queryForRecentDashboards().then((result: any[]) => {
|
2017-11-24 09:18:56 -06:00
|
|
|
if (result.length > 0) {
|
2017-12-20 05:33:33 -06:00
|
|
|
sections['recent'] = {
|
|
|
|
title: 'Recent',
|
2020-04-12 15:20:02 -05:00
|
|
|
icon: 'clock-nine',
|
2017-11-24 09:18:56 -06:00
|
|
|
score: -1,
|
2020-05-12 05:51:00 -05:00
|
|
|
expanded: store.getBool(`${SECTION_STORAGE_KEY}.recent`, true),
|
2017-12-20 05:33:33 -06:00
|
|
|
items: result,
|
2020-04-24 10:07:57 -05:00
|
|
|
type: DashboardSearchItemType.DashFolder,
|
2017-11-24 09:18:56 -06:00
|
|
|
};
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-04-15 05:11:52 -05:00
|
|
|
private queryForRecentDashboards(): Promise<DashboardSearchHit[]> {
|
2021-04-21 02:38:00 -05:00
|
|
|
const dashIds: number[] = take(impressionSrv.getDashboardOpened(), 30);
|
2017-11-24 09:18:56 -06:00
|
|
|
if (dashIds.length === 0) {
|
|
|
|
return Promise.resolve([]);
|
|
|
|
}
|
|
|
|
|
2021-01-20 00:59:48 -06:00
|
|
|
return backendSrv.search({ dashboardIds: dashIds }).then((result) => {
|
2017-12-19 09:06:54 -06:00
|
|
|
return dashIds
|
2021-01-20 00:59:48 -06:00
|
|
|
.map((orderId) => result.find((result) => result.id === orderId))
|
|
|
|
.filter((hit) => hit && !hit.isStarred) as DashboardSearchHit[];
|
2017-11-24 09:18:56 -06:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-04-27 07:08:48 -05:00
|
|
|
private getStarred(sections: DashboardSection): Promise<any> {
|
2017-11-24 09:54:55 -06:00
|
|
|
if (!contextSrv.isSignedIn) {
|
|
|
|
return Promise.resolve();
|
|
|
|
}
|
|
|
|
|
2021-01-20 00:59:48 -06:00
|
|
|
return backendSrv.search({ starred: true, limit: 30 }).then((result) => {
|
2017-11-24 09:18:56 -06:00
|
|
|
if (result.length > 0) {
|
2020-04-24 10:07:57 -05:00
|
|
|
(sections as any)['starred'] = {
|
2017-12-20 05:33:33 -06:00
|
|
|
title: 'Starred',
|
2020-04-12 15:20:02 -05:00
|
|
|
icon: 'star',
|
2017-11-24 09:18:56 -06:00
|
|
|
score: -2,
|
2020-05-12 05:51:00 -05:00
|
|
|
expanded: store.getBool(`${SECTION_STORAGE_KEY}.starred`, true),
|
2018-01-30 17:42:17 -06:00
|
|
|
items: result,
|
2020-04-24 10:07:57 -05:00
|
|
|
type: DashboardSearchItemType.DashFolder,
|
2017-11-24 09:18:56 -06:00
|
|
|
};
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-03-19 08:48:35 -05:00
|
|
|
search(options: any) {
|
2018-08-26 10:14:40 -05:00
|
|
|
const sections: any = {};
|
|
|
|
const promises = [];
|
2021-04-21 02:38:00 -05:00
|
|
|
const query = clone(options);
|
2020-04-23 00:18:53 -05:00
|
|
|
const filters = hasFilters(options) || query.folderIds?.length > 0;
|
2017-12-04 08:22:08 -06:00
|
|
|
|
2020-04-27 07:08:48 -05:00
|
|
|
query.folderIds = query.folderIds || [];
|
2020-04-27 11:16:03 -05:00
|
|
|
|
2020-04-27 07:08:48 -05:00
|
|
|
if (query.layout === SearchLayout.List) {
|
2020-04-29 11:18:37 -05:00
|
|
|
return backendSrv
|
|
|
|
.search({ ...query, type: DashboardSearchItemType.DashDB })
|
2021-01-20 00:59:48 -06:00
|
|
|
.then((results) => (results.length ? [{ title: '', items: results }] : []));
|
2020-04-27 07:08:48 -05:00
|
|
|
}
|
|
|
|
|
2020-04-27 11:16:03 -05:00
|
|
|
if (!filters) {
|
|
|
|
query.folderIds = [0];
|
|
|
|
}
|
|
|
|
|
2020-04-23 00:18:53 -05:00
|
|
|
if (!options.skipRecent && !filters) {
|
2017-12-04 08:22:08 -06:00
|
|
|
promises.push(this.getRecentDashboards(sections));
|
|
|
|
}
|
|
|
|
|
2020-04-23 00:18:53 -05:00
|
|
|
if (!options.skipStarred && !filters) {
|
2017-12-04 08:22:08 -06:00
|
|
|
promises.push(this.getStarred(sections));
|
|
|
|
}
|
|
|
|
|
2017-12-19 09:06:54 -06:00
|
|
|
promises.push(
|
2021-01-20 00:59:48 -06:00
|
|
|
backendSrv.search(query).then((results) => {
|
2017-12-19 09:06:54 -06:00
|
|
|
return this.handleSearchResult(sections, results);
|
|
|
|
})
|
|
|
|
);
|
2017-11-24 09:18:56 -06:00
|
|
|
|
2019-12-05 03:04:03 -06:00
|
|
|
return Promise.all(promises).then(() => {
|
2021-04-21 02:38:00 -05:00
|
|
|
return sortBy(values(sections), 'score');
|
2017-11-02 10:54:33 -05:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-03-19 11:44:58 -05:00
|
|
|
private handleSearchResult(sections: Sections, results: DashboardSearchHit[]): any {
|
2017-12-13 08:51:59 -06:00
|
|
|
if (results.length === 0) {
|
|
|
|
return sections;
|
2017-11-20 08:11:32 -06:00
|
|
|
}
|
|
|
|
|
2017-12-13 08:51:59 -06:00
|
|
|
// create folder index
|
2018-08-26 10:14:40 -05:00
|
|
|
for (const hit of results) {
|
2017-12-20 05:33:33 -06:00
|
|
|
if (hit.type === 'dash-folder') {
|
2017-12-13 08:51:59 -06:00
|
|
|
sections[hit.id] = {
|
|
|
|
id: hit.id,
|
2018-01-31 10:15:00 -06:00
|
|
|
uid: hit.uid,
|
2017-12-13 08:51:59 -06:00
|
|
|
title: hit.title,
|
|
|
|
expanded: false,
|
|
|
|
items: [],
|
2018-01-31 10:15:00 -06:00
|
|
|
url: hit.url,
|
2020-03-26 04:09:08 -05:00
|
|
|
icon: 'folder',
|
2021-04-21 02:38:00 -05:00
|
|
|
score: keys(sections).length,
|
2020-04-08 10:14:03 -05:00
|
|
|
type: hit.type,
|
2017-12-13 08:51:59 -06:00
|
|
|
};
|
2017-12-04 08:22:08 -06:00
|
|
|
}
|
2017-12-13 08:51:59 -06:00
|
|
|
}
|
2017-12-04 08:22:08 -06:00
|
|
|
|
2018-08-26 10:14:40 -05:00
|
|
|
for (const hit of results) {
|
2017-12-20 05:33:33 -06:00
|
|
|
if (hit.type === 'dash-folder') {
|
2017-12-13 08:51:59 -06:00
|
|
|
continue;
|
|
|
|
}
|
2017-11-20 08:11:32 -06:00
|
|
|
|
2017-12-13 08:51:59 -06:00
|
|
|
let section = sections[hit.folderId || 0];
|
|
|
|
if (!section) {
|
|
|
|
if (hit.folderId) {
|
|
|
|
section = {
|
|
|
|
id: hit.folderId,
|
2018-02-05 06:23:24 -06:00
|
|
|
uid: hit.folderUid,
|
2017-12-13 08:51:59 -06:00
|
|
|
title: hit.folderTitle,
|
2018-02-05 06:23:24 -06:00
|
|
|
url: hit.folderUrl,
|
2017-12-13 08:51:59 -06:00
|
|
|
items: [],
|
2020-03-26 04:09:08 -05:00
|
|
|
icon: 'folder-open',
|
2021-04-21 02:38:00 -05:00
|
|
|
score: keys(sections).length,
|
2020-04-24 10:07:57 -05:00
|
|
|
type: DashboardSearchItemType.DashFolder,
|
2017-12-13 08:51:59 -06:00
|
|
|
};
|
|
|
|
} else {
|
|
|
|
section = {
|
|
|
|
id: 0,
|
2018-02-02 03:33:31 -06:00
|
|
|
title: 'General',
|
2017-12-13 08:51:59 -06:00
|
|
|
items: [],
|
2020-03-26 04:09:08 -05:00
|
|
|
icon: 'folder-open',
|
2021-04-21 02:38:00 -05:00
|
|
|
score: keys(sections).length,
|
2020-04-24 10:07:57 -05:00
|
|
|
type: DashboardSearchItemType.DashFolder,
|
2017-12-13 08:51:59 -06:00
|
|
|
};
|
2017-11-20 08:11:32 -06:00
|
|
|
}
|
2017-12-13 08:51:59 -06:00
|
|
|
// add section
|
|
|
|
sections[hit.folderId || 0] = section;
|
2017-11-20 08:11:32 -06:00
|
|
|
}
|
|
|
|
|
2017-12-13 08:51:59 -06:00
|
|
|
section.expanded = true;
|
2020-04-24 10:07:57 -05:00
|
|
|
section.items && section.items.push(hit);
|
2017-12-13 08:51:59 -06:00
|
|
|
}
|
2017-11-20 08:11:32 -06:00
|
|
|
}
|
|
|
|
|
2017-11-02 10:54:33 -05:00
|
|
|
getDashboardTags() {
|
2020-01-21 03:08:07 -06:00
|
|
|
return backendSrv.get('/api/dashboards/tags');
|
2017-11-02 10:54:33 -05:00
|
|
|
}
|
2020-04-23 00:18:53 -05:00
|
|
|
|
|
|
|
getSortOptions() {
|
|
|
|
return backendSrv.get('/api/search/sorting');
|
|
|
|
}
|
2017-11-02 10:54:33 -05:00
|
|
|
}
|