dashlist: starred filter search

This commit is contained in:
Daniel Lee 2017-11-22 18:44:18 +01:00
parent 2d2015d3dd
commit 41a3431c4e
5 changed files with 112 additions and 34 deletions

View File

@ -8,8 +8,10 @@ export class SearchSrv {
} }
browse() { browse() {
const rootFolderId = 0;
let query = { let query = {
folderIds: [0] folderIds: [rootFolderId]
}; };
return this.backendSrv.search(query).then(results => { return this.backendSrv.search(query).then(results => {
@ -52,7 +54,9 @@ export class SearchSrv {
} }
search(options) { search(options) {
if (!options.query && !options.tag) { if (!options.query &&
(!options.tag || options.tag.length === 0) &&
!options.starred) {
return this.browse(); return this.browse();
} }

View File

@ -90,4 +90,30 @@ describe('SearchSrv', () => {
}); });
describe("with tags", () => {
beforeEach(() => {
backendSrvMock.search = jest.fn();
backendSrvMock.search.mockReturnValue(Promise.resolve([]));
return searchSrv.search({tag: ['atag']}).then(() => {});
});
it("should send tags query to backend search", () => {
expect(backendSrvMock.search.mock.calls[0][0].tag).toHaveLength(1);
});
});
describe("with starred", () => {
beforeEach(() => {
backendSrvMock.search = jest.fn();
backendSrvMock.search.mockReturnValue(Promise.resolve([]));
return searchSrv.search({starred: true}).then(() => {});
});
it("should send starred query to backend search", () => {
expect(backendSrvMock.search.mock.calls[0][0].starred).toEqual(true);
});
});
}); });

View File

@ -4,17 +4,20 @@ import { SearchSrv } from 'app/core/services/search_srv';
export class DashboardListCtrl { export class DashboardListCtrl {
public sections: any []; public sections: any [];
tags: any []; tagFilterOptions: any [];
selectedTagFilter: any; selectedTagFilter: any;
query: any; query: any;
navModel: any; navModel: any;
canDelete = false; canDelete = false;
canMove = false; canMove = false;
starredFilterOptions = [{text: 'Filter by Starred', disabled: true}, {text: 'Yes'}, {text: 'No'}];
selectedStarredFilter: any;
/** @ngInject */ /** @ngInject */
constructor(private backendSrv, navModelSrv, private $q, private searchSrv: SearchSrv) { constructor(private backendSrv, navModelSrv, private $q, private searchSrv: SearchSrv) {
this.navModel = navModelSrv.getNav('dashboards', 'dashboards'); this.navModel = navModelSrv.getNav('dashboards', 'dashboards');
this.query = {query: '', mode: 'tree', tag: []}; this.query = {query: '', mode: 'tree', tag: []};
this.selectedStarredFilter = this.starredFilterOptions[0];
this.getDashboards().then(() => { this.getDashboards().then(() => {
this.getTags(); this.getTags();
@ -22,7 +25,9 @@ export class DashboardListCtrl {
} }
getDashboards() { getDashboards() {
if (this.query.query.length === 0 && this.query.tag.length === 0) { if (this.query.query.length === 0 &&
this.query.tag.length === 0 &&
!this.query.starred) {
return this.searchSrv.browse().then((result) => { return this.searchSrv.browse().then((result) => {
return this.initDashboardList(result); return this.initDashboardList(result);
}); });
@ -139,24 +144,25 @@ export class DashboardListCtrl {
getTags() { getTags() {
return this.searchSrv.getDashboardTags().then((results) => { return this.searchSrv.getDashboardTags().then((results) => {
this.tags = [{ term: 'Filter By Tag', disabled: true }].concat(results); this.tagFilterOptions = [{ term: 'Filter By Tag', disabled: true }].concat(results);
this.selectedTagFilter = this.tags[0]; this.selectedTagFilter = this.tagFilterOptions[0];
}); });
} }
filterByTag(tag, evt) { filterByTag(tag, evt) {
this.query.tag.push(tag); this.query.tag.push(tag);
this.getDashboards();
if (evt) { if (evt) {
evt.stopPropagation(); evt.stopPropagation();
evt.preventDefault(); evt.preventDefault();
} }
return this.getDashboards();
} }
filterChange() { onTagFilterChange() {
this.query.tag.push(this.selectedTagFilter.term); this.query.tag.push(this.selectedTagFilter.term);
this.selectedTagFilter = this.tags[0]; this.selectedTagFilter = this.tagFilterOptions[0];
this.getDashboards(); return this.getDashboards();
} }
removeTag(tag, evt) { removeTag(tag, evt) {
@ -167,4 +173,9 @@ export class DashboardListCtrl {
evt.preventDefault(); evt.preventDefault();
} }
} }
onStarredFilterChange() {
this.query.starred = this.selectedStarredFilter.text === 'Yes';
return this.getDashboards();
}
} }

View File

@ -52,16 +52,22 @@
</div> </div>
<div class="admin-list-table" style="height: 80%"> <div class="admin-list-table" style="height: 80%">
<div gemini-scrollbar>
<div ng-show="ctrl.sections.length > 0">
<div> <div>
<select
class="gf-form-input"
ng-model="ctrl.selectedStarredFilter"
ng-options="t.text disable when t.disabled for t in ctrl.starredFilterOptions"
ng-change="ctrl.onStarredFilterChange()"
/>
<select <select
class="gf-form-input" class="gf-form-input"
ng-model="ctrl.selectedTagFilter" ng-model="ctrl.selectedTagFilter"
ng-options="t.term disable when t.disabled for t in ctrl.tags" ng-options="t.term disable when t.disabled for t in ctrl.tagFilterOptions"
ng-change="ctrl.filterChange(tag, $index)" ng-change="ctrl.onTagFilterChange()"
/> />
</div> </div>
<div gemini-scrollbar>
<div ng-show="ctrl.sections.length > 0">
<div ng-repeat="section in ctrl.sections" class="search-section"> <div ng-repeat="section in ctrl.sections" class="search-section">
<div class="search-section__header pointer" ng-show="::section.title"> <div class="search-section__header pointer" ng-show="::section.title">

View File

@ -1,4 +1,4 @@
import {DashboardListCtrl} from '../dashboard_list_ctrl'; import { DashboardListCtrl } from '../dashboard_list_ctrl';
import { SearchSrv } from 'app/core/services/search_srv'; import { SearchSrv } from 'app/core/services/search_srv';
import q from 'q'; import q from 'q';
@ -104,7 +104,11 @@ describe('DashboardListCtrl', () => {
isStarred: false, isStarred: false,
} }
]; ];
ctrl = createCtrlWithStubs(response); ctrl = createCtrlWithStubs([], response);
});
describe('with no filter', () => {
beforeEach(() => {
ctrl.query.query = 'd'; ctrl.query.query = 'd';
return ctrl.getDashboards(); return ctrl.getDashboards();
}); });
@ -118,6 +122,33 @@ describe('DashboardListCtrl', () => {
}); });
}); });
describe('with tag filter', () => {
beforeEach(() => {
return ctrl.filterByTag('test');
});
it('should set tag filter', () => {
expect(ctrl.sections.length).toEqual(2);
expect(ctrl.query.tag[0]).toEqual('test');
});
});
describe('with starred filter', () => {
beforeEach(() => {
const yesOption: any = ctrl.starredFilterOptions[1];
ctrl.selectedStarredFilter = yesOption;
return ctrl.onStarredFilterChange();
});
it('should set starred filter', () => {
expect(ctrl.sections.length).toEqual(2);
expect(ctrl.query.starred).toEqual(true);
});
});
});
describe('when selecting dashboards', () => { describe('when selecting dashboards', () => {
let ctrl; let ctrl;
@ -362,21 +393,21 @@ describe('DashboardListCtrl', () => {
}); });
}); });
function createCtrlWithStubs(response: any) { function createCtrlWithStubs(browseResponse: any, searchResponse?: any, tags?: any) {
const searchSrvStub = { const searchSrvStub = {
browse: () => { browse: () => {
return q.resolve(response); return q.resolve(browseResponse);
}, },
search: (options: any) => { search: (options: any) => {
return q.resolve(response); return q.resolve(searchResponse);
}, },
toggleFolder: (section) => { toggleFolder: (section) => {
return q.resolve(response); return;
}, },
getDashboardTags: () => { getDashboardTags: () => {
return q.resolve([]); return q.resolve(tags || []);
} }
}; };
return new DashboardListCtrl({}, {getNav: () => {}}, q, <SearchSrv>searchSrvStub); return new DashboardListCtrl({}, { getNav: () => { } }, q, <SearchSrv>searchSrvStub);
} }