diff --git a/public/app/core/components/manage_dashboards/manage_dashboards.ts b/public/app/core/components/manage_dashboards/manage_dashboards.ts index 3f6dacd311d..5b5e299b1af 100644 --- a/public/app/core/components/manage_dashboards/manage_dashboards.ts +++ b/public/app/core/components/manage_dashboards/manage_dashboards.ts @@ -11,7 +11,8 @@ export interface Section { id: number; uid: string; title: string; - expanded: false; + expanded: boolean; + removable: boolean; items: any[]; url: string; icon: string; diff --git a/public/app/core/services/backend_srv.ts b/public/app/core/services/backend_srv.ts index c73cc7661f5..53ab3ab6ce7 100644 --- a/public/app/core/services/backend_srv.ts +++ b/public/app/core/services/backend_srv.ts @@ -4,6 +4,28 @@ import appEvents from 'app/core/app_events'; import config from 'app/core/config'; import { DashboardModel } from 'app/features/dashboard/state/DashboardModel'; +export enum HitType { + DashHitDB = 'dash-db', + DashHitHome = 'dash-home', + DashHitFolder = 'dash-folder', +} + +export interface Hit { + id: number; + uid: string; + title: string; + uri: string; + url: string; + slug: string; + type: HitType; + tags: string[]; + isStarred: boolean; + folderId: number; + folderUid: string; + folderTitle: string; + folderUrl: string; +} + export class BackendSrv { private inFlightRequests = {}; private HTTP_REQUEST_CANCELED = -1; @@ -237,7 +259,7 @@ export class BackendSrv { return this.request({ url: '/api/login/ping', method: 'GET', retry: 1 }); } - search(query) { + search(query): Promise { return this.get('/api/search', query); } diff --git a/public/app/core/services/search_srv.ts b/public/app/core/services/search_srv.ts index 22d33921ebd..4a605d3fc50 100644 --- a/public/app/core/services/search_srv.ts +++ b/public/app/core/services/search_srv.ts @@ -1,21 +1,31 @@ +// @ts-ignore import _ from 'lodash'; +// @ts-ignore +import { IQService } from 'angular'; + import coreModule from 'app/core/core_module'; import impressionSrv from 'app/core/services/impression_srv'; import store from 'app/core/store'; import { contextSrv } from 'app/core/services/context_srv'; +import { BackendSrv, Hit } from './backend_srv'; +import { Section } from '../components/manage_dashboards/manage_dashboards'; + +interface Sections { + [key: string]: Partial
; +} export class SearchSrv { recentIsOpen: boolean; starredIsOpen: boolean; /** @ngInject */ - constructor(private backendSrv, private $q) { + constructor(private backendSrv: BackendSrv, private $q: IQService) { this.recentIsOpen = store.getBool('search.sections.recent', true); this.starredIsOpen = store.getBool('search.sections.starred', true); } - private getRecentDashboards(sections) { - return this.queryForRecentDashboards().then(result => { + private getRecentDashboards(sections: Sections) { + return this.queryForRecentDashboards().then((result: any[]) => { if (result.length > 0) { sections['recent'] = { title: 'Recent', @@ -30,8 +40,8 @@ export class SearchSrv { }); } - private queryForRecentDashboards() { - const dashIds = _.take(impressionSrv.getDashboardOpened(), 30); + private queryForRecentDashboards(): Promise { + const dashIds: number[] = _.take(impressionSrv.getDashboardOpened(), 30); if (dashIds.length === 0) { return Promise.resolve([]); } @@ -45,7 +55,7 @@ export class SearchSrv { }); } - private toggleRecent(section) { + private toggleRecent(section: Section) { this.recentIsOpen = section.expanded = !section.expanded; store.set('search.sections.recent', this.recentIsOpen); @@ -59,13 +69,13 @@ export class SearchSrv { }); } - private toggleStarred(section) { + private toggleStarred(section: Section) { this.starredIsOpen = section.expanded = !section.expanded; store.set('search.sections.starred', this.starredIsOpen); return Promise.resolve(section); } - private getStarred(sections) { + private getStarred(sections: Sections) { if (!contextSrv.isSignedIn) { return Promise.resolve(); } @@ -84,7 +94,7 @@ export class SearchSrv { }); } - search(options) { + search(options: any) { const sections: any = {}; const promises = []; const query = _.clone(options); @@ -118,7 +128,7 @@ export class SearchSrv { }); } - private handleSearchResult(sections, results) { + private handleSearchResult(sections: Sections, results: Hit[]): any { if (results.length === 0) { return sections; } @@ -177,7 +187,7 @@ export class SearchSrv { } } - private toggleFolder(section) { + private toggleFolder(section: Section) { section.expanded = !section.expanded; section.icon = section.expanded ? 'fa fa-folder-open' : 'fa fa-folder'; diff --git a/public/app/core/specs/manage_dashboards.test.ts b/public/app/core/specs/manage_dashboards.test.ts index ef5e240fd36..5e94d26ea89 100644 --- a/public/app/core/specs/manage_dashboards.test.ts +++ b/public/app/core/specs/manage_dashboards.test.ts @@ -16,6 +16,7 @@ const mockSection = (overides?: object): Section => { items: [], checked: false, expanded: false, + removable: false, hideHeader: false, icon: '', score: 0, diff --git a/public/app/core/specs/search_srv.test.ts b/public/app/core/specs/search_srv.test.ts index 550d11bbf9e..6566224c613 100644 --- a/public/app/core/specs/search_srv.test.ts +++ b/public/app/core/specs/search_srv.test.ts @@ -1,8 +1,12 @@ +// @ts-ignore +import { IQService } from 'angular'; + import { SearchSrv } from 'app/core/services/search_srv'; import { BackendSrvMock } from 'test/mocks/backend_srv'; import impressionSrv from 'app/core/services/impression_srv'; import { contextSrv } from 'app/core/services/context_srv'; import { beforeEach } from 'test/lib/common'; +import { BackendSrv } from '../services/backend_srv'; jest.mock('app/core/store', () => { return { @@ -18,18 +22,18 @@ jest.mock('app/core/services/impression_srv', () => { }); describe('SearchSrv', () => { - let searchSrv, backendSrvMock; + let searchSrv: SearchSrv, backendSrvMock: BackendSrvMock; beforeEach(() => { backendSrvMock = new BackendSrvMock(); - searchSrv = new SearchSrv(backendSrvMock, Promise); + searchSrv = new SearchSrv(backendSrvMock as BackendSrv, (Promise as any) as IQService); contextSrv.isSignedIn = true; impressionSrv.getDashboardOpened = jest.fn().mockReturnValue([]); }); describe('With recent dashboards', () => { - let results; + let results: any; beforeEach(() => { backendSrvMock.search = jest @@ -56,7 +60,7 @@ describe('SearchSrv', () => { }); describe('and 3 recent dashboards removed in backend', () => { - let results; + let results: any; beforeEach(() => { backendSrvMock.search = jest @@ -80,7 +84,7 @@ describe('SearchSrv', () => { }); describe('With starred dashboards', () => { - let results; + let results: any; beforeEach(() => { backendSrvMock.search = jest.fn().mockReturnValue(Promise.resolve([{ id: 1, title: 'starred' }])); @@ -97,7 +101,7 @@ describe('SearchSrv', () => { }); describe('With starred dashboards and recent', () => { - let results; + let results: any; beforeEach(() => { backendSrvMock.search = jest @@ -125,7 +129,7 @@ describe('SearchSrv', () => { }); describe('with no query string and dashboards with folders returned', () => { - let results; + let results: any; beforeEach(() => { backendSrvMock.search = jest @@ -173,12 +177,10 @@ describe('SearchSrv', () => { }); describe('with query string and dashboards with folders returned', () => { - let results; + let results: any; beforeEach(() => { - backendSrvMock.search = jest.fn(); - - backendSrvMock.search.mockReturnValue( + backendSrvMock.search = jest.fn().mockReturnValue( Promise.resolve([ { id: 2, @@ -249,8 +251,9 @@ describe('SearchSrv', () => { backendSrvMock.search = jest.fn(); backendSrvMock.search.mockReturnValue(Promise.resolve([])); - searchSrv.getRecentDashboards = () => { + searchSrv['getRecentDashboards'] = () => { getRecentDashboardsCalled = true; + return Promise.resolve(); }; return searchSrv.search({ skipRecent: true }).then(() => {}); @@ -269,8 +272,9 @@ describe('SearchSrv', () => { backendSrvMock.search.mockReturnValue(Promise.resolve([])); impressionSrv.getDashboardOpened = jest.fn().mockReturnValue([]); - searchSrv.getStarred = () => { + searchSrv['getStarred'] = () => { getStarredCalled = true; + return Promise.resolve(); }; return searchSrv.search({ skipStarred: true }).then(() => {});