Merge branch 'develop' of github.com:grafana/grafana into develop

This commit is contained in:
Torkel Ödegaard 2017-12-14 12:10:59 +01:00
commit 9007e26106
7 changed files with 118 additions and 35 deletions

View File

@ -64,6 +64,7 @@ func (hs *HttpServer) registerRoutes() {
r.Get("/dashboard-solo/snapshot/*", Index) r.Get("/dashboard-solo/snapshot/*", Index)
r.Get("/dashboard-solo/*", reqSignedIn, Index) r.Get("/dashboard-solo/*", reqSignedIn, Index)
r.Get("/import/dashboard", reqSignedIn, Index) r.Get("/import/dashboard", reqSignedIn, Index)
r.Get("/dashboards/", reqSignedIn, Index)
r.Get("/dashboards/*", reqSignedIn, Index) r.Get("/dashboards/*", reqSignedIn, Index)
r.Get("/playlists/", reqSignedIn, Index) r.Get("/playlists/", reqSignedIn, Index)

View File

@ -58,10 +58,13 @@ export class ManageDashboardsCtrl {
dashboard.checked = false; dashboard.checked = false;
} }
} }
if (this.folderId && this.sections.length > 0) {
this.sections[0].hideHeader = true;
}
} }
selectionChanged() { selectionChanged() {
let selectedDashboards = 0; let selectedDashboards = 0;
for (let section of this.sections) { for (let section of this.sections) {
@ -69,7 +72,7 @@ export class ManageDashboardsCtrl {
} }
const selectedFolders = _.filter(this.sections, { checked: true }).length; const selectedFolders = _.filter(this.sections, { checked: true }).length;
this.canMove = selectedDashboards > 0 && selectedFolders === 0; this.canMove = selectedDashboards > 0;
this.canDelete = selectedDashboards > 0 || selectedFolders > 0; this.canDelete = selectedDashboards > 0 || selectedFolders > 0;
} }
@ -77,11 +80,11 @@ export class ManageDashboardsCtrl {
let selectedDashboards = []; let selectedDashboards = [];
for (const section of this.sections) { for (const section of this.sections) {
if (section.checked) { if (section.checked && section.id !== 0) {
selectedDashboards.push(section.uri); selectedDashboards.push(section.slug);
} else { } else {
const selected = _.filter(section.items, { checked: true }); const selected = _.filter(section.items, { checked: true });
selectedDashboards.push(..._.map(selected, 'uri')); selectedDashboards.push(..._.map(selected, 'slug'));
} }
} }
@ -109,7 +112,7 @@ export class ManageDashboardsCtrl {
onConfirm: () => { onConfirm: () => {
const promises = []; const promises = [];
for (let dash of selectedDashboards) { for (let dash of selectedDashboards) {
promises.push(this.backendSrv.delete(`/api/dashboards/${dash}`)); promises.push(this.backendSrv.delete(`/api/dashboards/db/${dash}`));
} }
this.$q.all(promises).then(() => { this.$q.all(promises).then(() => {
@ -124,7 +127,7 @@ export class ManageDashboardsCtrl {
for (const section of this.sections) { for (const section of this.sections) {
const selected = _.filter(section.items, { checked: true }); const selected = _.filter(section.items, { checked: true });
selectedDashboards.push(..._.map(selected, 'uri')); selectedDashboards.push(..._.map(selected, 'slug'));
} }
return selectedDashboards; return selectedDashboards;

View File

@ -1,4 +1,4 @@
// import _ from 'lodash'; import _ from 'lodash';
import coreModule from '../../core_module'; import coreModule from '../../core_module';
export class SearchResultsCtrl { export class SearchResultsCtrl {
@ -6,10 +6,10 @@ export class SearchResultsCtrl {
onSelectionChanged: any; onSelectionChanged: any;
onTagSelected: any; onTagSelected: any;
onFolderExpanding: any; onFolderExpanding: any;
editable: boolean;
/** @ngInject */ /** @ngInject */
constructor(private $location) { constructor(private $location) {}
}
toggleFolderExpand(section) { toggleFolderExpand(section) {
if (section.toggle) { if (section.toggle) {
@ -17,12 +17,24 @@ export class SearchResultsCtrl {
this.onFolderExpanding(); this.onFolderExpanding();
} }
section.toggle(section); section.toggle(section).then(f => {
if (this.editable && f.expanded) {
if (f.items) {
_.each(f.items, i => {
i.checked = f.checked;
});
if (this.onSelectionChanged) {
this.onSelectionChanged();
}
}
}
});
} }
} }
navigateToFolder(section, evt) { navigateToFolder(section, evt) {
this.$location.path('/dashboards/folder/' + section.id + '/' + section.uri); this.$location.path(section.url);
if (evt) { if (evt) {
evt.stopPropagation(); evt.stopPropagation();
@ -33,6 +45,12 @@ export class SearchResultsCtrl {
toggleSelection(item, evt) { toggleSelection(item, evt) {
item.checked = !item.checked; item.checked = !item.checked;
if (item.items) {
_.each(item.items, i => {
i.checked = item.checked;
});
}
if (this.onSelectionChanged) { if (this.onSelectionChanged) {
this.onSelectionChanged(); this.onSelectionChanged();
} }

View File

@ -51,18 +51,19 @@ export class SearchSrv {
store.set('search.sections.recent', this.recentIsOpen); store.set('search.sections.recent', this.recentIsOpen);
if (!section.expanded || section.items.length) { if (!section.expanded || section.items.length) {
return Promise.resolve(); return Promise.resolve(section);
} }
return this.queryForRecentDashboards().then(result => { return this.queryForRecentDashboards().then(result => {
section.items = result; section.items = result;
return Promise.resolve(section);
}); });
} }
private toggleStarred(section) { private toggleStarred(section) {
this.starredIsOpen = section.expanded = !section.expanded; this.starredIsOpen = section.expanded = !section.expanded;
store.set('search.sections.starred', this.starredIsOpen); store.set('search.sections.starred', this.starredIsOpen);
return Promise.resolve(); return Promise.resolve(section);
} }
private getStarred(sections) { private getStarred(sections) {
@ -134,6 +135,7 @@ export class SearchSrv {
items: [], items: [],
toggle: this.toggleFolder.bind(this), toggle: this.toggleFolder.bind(this),
url: `dashboards/folder/${hit.id}/${hit.slug}`, url: `dashboards/folder/${hit.id}/${hit.slug}`,
slug: hit.slug,
icon: 'fa fa-folder', icon: 'fa fa-folder',
score: _.keys(sections).length, score: _.keys(sections).length,
}; };
@ -152,6 +154,7 @@ export class SearchSrv {
id: hit.folderId, id: hit.folderId,
title: hit.folderTitle, title: hit.folderTitle,
url: `dashboards/folder/${hit.folderId}/${hit.folderSlug}`, url: `dashboards/folder/${hit.folderId}/${hit.folderSlug}`,
slug: hit.slug,
items: [], items: [],
icon: 'fa fa-folder-open', icon: 'fa fa-folder-open',
toggle: this.toggleFolder.bind(this), toggle: this.toggleFolder.bind(this),
@ -181,7 +184,7 @@ export class SearchSrv {
section.icon = section.expanded ? 'fa fa-folder-open' : 'fa fa-folder'; section.icon = section.expanded ? 'fa fa-folder-open' : 'fa fa-folder';
if (section.items.length) { if (section.items.length) {
return Promise.resolve(); return Promise.resolve(section);
} }
let query = { let query = {
@ -190,6 +193,7 @@ export class SearchSrv {
return this.backendSrv.search(query).then(results => { return this.backendSrv.search(query).then(results => {
section.items = _.map(results, this.transformToViewModel); section.items = _.map(results, this.transformToViewModel);
return Promise.resolve(section);
}); });
} }

View File

@ -58,6 +58,41 @@ describe('ManageDashboards', () => {
expect(ctrl.sections[0].items[0].checked).toEqual(false); expect(ctrl.sections[0].items[0].checked).toEqual(false);
expect(ctrl.sections[1].checked).toEqual(false); expect(ctrl.sections[1].checked).toEqual(false);
expect(ctrl.sections[1].items[0].checked).toEqual(false); expect(ctrl.sections[1].items[0].checked).toEqual(false);
expect(ctrl.sections[0].hideHeader).toBeFalsy();
});
});
describe('when browsing dashboards for a folder', () => {
beforeEach(() => {
const response = [
{
id: 410,
title: "afolder",
type: "dash-folder",
items: [
{
id: 399,
title: "Dashboard Test",
url: "dashboard/db/dashboard-test",
icon: 'fa fa-folder',
tags: [],
isStarred: false,
folderId: 410,
folderTitle: "afolder",
folderSlug: "afolder"
}
],
tags: [],
isStarred: false
}
];
ctrl = createCtrlWithStubs(response);
ctrl.folderId = 410;
return ctrl.getDashboards();
});
it('should set hide header to true on section', () => {
expect(ctrl.sections[0].hideHeader).toBeTruthy();
}); });
}); });
@ -263,8 +298,8 @@ describe('ManageDashboards', () => {
expect(ctrl.sections[1].items[0].checked).toBeTruthy(); expect(ctrl.sections[1].items[0].checked).toBeTruthy();
}); });
it('should disable Move To button', () => { it('should enable Move To button', () => {
expect(ctrl.canMove).toBeFalsy(); expect(ctrl.canMove).toBeTruthy();
}); });
it('should enable delete button', () => { it('should enable delete button', () => {
@ -294,8 +329,8 @@ describe('ManageDashboards', () => {
ctrl.selectionChanged(); ctrl.selectionChanged();
}); });
it('should disable Move To button', () => { it('should enable Move To button', () => {
expect(ctrl.canMove).toBeFalsy(); expect(ctrl.canMove).toBeTruthy();
}); });
it('should enable delete button', () => { it('should enable delete button', () => {
@ -455,8 +490,8 @@ describe('ManageDashboards', () => {
ctrl.selectionChanged(); ctrl.selectionChanged();
}); });
it('should disable Move To button', () => { it('should enable Move To button', () => {
expect(ctrl.canMove).toBeFalsy(); expect(ctrl.canMove).toBeTruthy();
}); });
it('should enable delete button', () => { it('should enable delete button', () => {
@ -466,6 +501,8 @@ describe('ManageDashboards', () => {
}); });
describe('when deleting dashboards', () => { describe('when deleting dashboards', () => {
let toBeDeleted = [];
beforeEach(() => { beforeEach(() => {
ctrl = createCtrlWithStubs([]); ctrl = createCtrlWithStubs([]);
@ -474,27 +511,47 @@ describe('ManageDashboards', () => {
id: 1, id: 1,
title: 'folder', title: 'folder',
items: [ items: [
{ id: 2, checked: true, uri: 'dash' } { id: 2, checked: true, slug: 'folder-dash' }
], ],
checked: true, checked: true,
uri: 'folder' slug: 'folder'
},
{
id: 3,
title: 'folder-2',
items: [
{ id: 3, checked: true, slug: 'folder-2-dash' }
],
checked: false,
slug: 'folder-2'
}, },
{ {
id: 0, id: 0,
title: 'Root', title: 'Root',
items: [ items: [
{ id: 3, checked: true, uri: 'dash-2' } { id: 3, checked: true, slug: 'root-dash' }
], ],
checked: false checked: true
} }
]; ];
toBeDeleted = ctrl.getDashboardsToDelete();
}); });
it('should filter out children if parent is selected', () => { it('should return 3 items', () => {
const toBeDeleted = ctrl.getDashboardsToDelete(); expect(toBeDeleted.length).toEqual(3);
expect(toBeDeleted.length).toEqual(2); });
it('should filter out children if parent is checked', () => {
expect(toBeDeleted[0]).toEqual('folder'); expect(toBeDeleted[0]).toEqual('folder');
expect(toBeDeleted[1]).toEqual('dash-2'); });
it('should not filter out children if parent not is checked', () => {
expect(toBeDeleted[1]).toEqual('folder-2-dash');
});
it('should not filter out children if parent is checked and root', () => {
expect(toBeDeleted[2]).toEqual('root-dash');
}); });
}); });
@ -507,16 +564,16 @@ describe('ManageDashboards', () => {
id: 1, id: 1,
title: 'folder', title: 'folder',
items: [ items: [
{ id: 2, checked: true, uri: 'dash' } { id: 2, checked: true, slug: 'dash' }
], ],
checked: false, checked: false,
uri: 'folder' slug: 'folder'
}, },
{ {
id: 0, id: 0,
title: 'Root', title: 'Root',
items: [ items: [
{ id: 3, checked: true, uri: 'dash-2' } { id: 3, checked: true, slug: 'dash-2' }
], ],
checked: false checked: false
} }

View File

@ -64,7 +64,7 @@ describe('SearchResultsCtrl', () => {
let folder = { let folder = {
expanded: false, expanded: false,
toggle: () => {} toggle: () => Promise.resolve(folder)
}; };
ctrl.toggleFolderExpand(folder); ctrl.toggleFolderExpand(folder);
@ -84,7 +84,7 @@ describe('SearchResultsCtrl', () => {
let folder = { let folder = {
expanded: true, expanded: true,
toggle: () => {} toggle: () => Promise.resolve(folder)
}; };
ctrl.toggleFolderExpand(folder); ctrl.toggleFolderExpand(folder);

View File

@ -32,7 +32,7 @@ export class MoveToFolderCtrl {
private moveDashboard(dash) { private moveDashboard(dash) {
let deferred = this.$q.defer(); let deferred = this.$q.defer();
this.backendSrv.get('/api/dashboards/' + dash) this.backendSrv.get('/api/dashboards/db/' + dash)
.then(fullDash => { .then(fullDash => {
const model = new DashboardModel(fullDash.dashboard, fullDash.meta); const model = new DashboardModel(fullDash.dashboard, fullDash.meta);