mirror of
https://github.com/grafana/grafana.git
synced 2024-11-29 12:14:08 -06:00
folders: change the front end route for browsing folders
Change the front end route for folders to /dashboards/f/<uid>/<slug of folder title>. Use new route for deleting dashboard/folder by uid. Retrieve dashboard/folder by uid when moving or deleting dashboards/folders.
This commit is contained in:
parent
b23560ed5a
commit
92a0171a9b
@ -13,6 +13,7 @@ const (
|
|||||||
|
|
||||||
type Hit struct {
|
type Hit struct {
|
||||||
Id int64 `json:"id"`
|
Id int64 `json:"id"`
|
||||||
|
Uid string `json:"uid"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Uri string `json:"uri"`
|
Uri string `json:"uri"`
|
||||||
Url string `json:"url"`
|
Url string `json:"url"`
|
||||||
|
@ -266,6 +266,7 @@ func makeQueryResult(query *search.FindPersistedDashboardsQuery, res []Dashboard
|
|||||||
}
|
}
|
||||||
hit = &search.Hit{
|
hit = &search.Hit{
|
||||||
Id: item.Id,
|
Id: item.Id,
|
||||||
|
Uid: item.Uid,
|
||||||
Title: item.Title,
|
Title: item.Title,
|
||||||
Uri: "db/" + item.Slug,
|
Uri: "db/" + item.Slug,
|
||||||
Url: url,
|
Url: url,
|
||||||
|
@ -146,7 +146,7 @@ func TestDashboardDataAccess(t *testing.T) {
|
|||||||
So(len(query.Result), ShouldEqual, 1)
|
So(len(query.Result), ShouldEqual, 1)
|
||||||
hit := query.Result[0]
|
hit := query.Result[0]
|
||||||
So(hit.Type, ShouldEqual, search.DashHitFolder)
|
So(hit.Type, ShouldEqual, search.DashHitFolder)
|
||||||
So(hit.Url, ShouldEqual, fmt.Sprintf("/f/%s/%s", savedFolder.Uid, savedFolder.Slug))
|
So(hit.Url, ShouldEqual, fmt.Sprintf("/dashboards/f/%s/%s", savedFolder.Uid, savedFolder.Slug))
|
||||||
})
|
})
|
||||||
|
|
||||||
Convey("Should be able to search for a dashboard folder's children", func() {
|
Convey("Should be able to search for a dashboard folder's children", func() {
|
||||||
|
@ -91,10 +91,10 @@ export class ManageDashboardsCtrl {
|
|||||||
|
|
||||||
for (const section of this.sections) {
|
for (const section of this.sections) {
|
||||||
if (section.checked && section.id !== 0) {
|
if (section.checked && section.id !== 0) {
|
||||||
selectedDashboards.folders.push(section.slug);
|
selectedDashboards.folders.push(section.uid);
|
||||||
} else {
|
} else {
|
||||||
const selected = _.filter(section.items, { checked: true });
|
const selected = _.filter(section.items, { checked: true });
|
||||||
selectedDashboards.dashboards.push(..._.map(selected, 'slug'));
|
selectedDashboards.dashboards.push(..._.map(selected, 'uid'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,7 +185,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, 'slug'));
|
selectedDashboards.push(..._.map(selected, 'uid'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return selectedDashboards;
|
return selectedDashboards;
|
||||||
|
@ -257,11 +257,11 @@ export class BackendSrv {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteDashboard(slug) {
|
deleteDashboard(uid) {
|
||||||
let deferred = this.$q.defer();
|
let deferred = this.$q.defer();
|
||||||
|
|
||||||
this.getDashboard('db', slug).then(fullDash => {
|
this.getDashboardByUid(uid).then(fullDash => {
|
||||||
this.delete(`/api/dashboards/db/${slug}`)
|
this.delete(`/api/dashboards/uid/${uid}`)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
deferred.resolve(fullDash);
|
deferred.resolve(fullDash);
|
||||||
})
|
})
|
||||||
@ -273,21 +273,21 @@ export class BackendSrv {
|
|||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteDashboards(dashboardSlugs) {
|
deleteDashboards(dashboardUids) {
|
||||||
const tasks = [];
|
const tasks = [];
|
||||||
|
|
||||||
for (let slug of dashboardSlugs) {
|
for (let uid of dashboardUids) {
|
||||||
tasks.push(this.createTask(this.deleteDashboard.bind(this), true, slug));
|
tasks.push(this.createTask(this.deleteDashboard.bind(this), true, uid));
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.executeInOrder(tasks, []);
|
return this.executeInOrder(tasks, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
moveDashboards(dashboardSlugs, toFolder) {
|
moveDashboards(dashboardUids, toFolder) {
|
||||||
const tasks = [];
|
const tasks = [];
|
||||||
|
|
||||||
for (let slug of dashboardSlugs) {
|
for (let uid of dashboardUids) {
|
||||||
tasks.push(this.createTask(this.moveDashboard.bind(this), true, slug, toFolder));
|
tasks.push(this.createTask(this.moveDashboard.bind(this), true, uid, toFolder));
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.executeInOrder(tasks, []).then(result => {
|
return this.executeInOrder(tasks, []).then(result => {
|
||||||
@ -299,10 +299,10 @@ export class BackendSrv {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private moveDashboard(slug, toFolder) {
|
private moveDashboard(uid, toFolder) {
|
||||||
let deferred = this.$q.defer();
|
let deferred = this.$q.defer();
|
||||||
|
|
||||||
this.getDashboard('db', slug).then(fullDash => {
|
this.getDashboardByUid(uid).then(fullDash => {
|
||||||
const model = new DashboardModel(fullDash.dashboard, fullDash.meta);
|
const model = new DashboardModel(fullDash.dashboard, fullDash.meta);
|
||||||
|
|
||||||
if ((!fullDash.meta.folderId && toFolder.id === 0) || fullDash.meta.folderId === toFolder.id) {
|
if ((!fullDash.meta.folderId && toFolder.id === 0) || fullDash.meta.folderId === toFolder.id) {
|
||||||
|
@ -128,11 +128,12 @@ export class SearchSrv {
|
|||||||
if (hit.type === 'dash-folder') {
|
if (hit.type === 'dash-folder') {
|
||||||
sections[hit.id] = {
|
sections[hit.id] = {
|
||||||
id: hit.id,
|
id: hit.id,
|
||||||
|
uid: hit.uid,
|
||||||
title: hit.title,
|
title: hit.title,
|
||||||
expanded: false,
|
expanded: false,
|
||||||
items: [],
|
items: [],
|
||||||
toggle: this.toggleFolder.bind(this),
|
toggle: this.toggleFolder.bind(this),
|
||||||
url: `dashboards/folder/${hit.id}/${hit.slug}`,
|
url: hit.url,
|
||||||
slug: hit.slug,
|
slug: hit.slug,
|
||||||
icon: 'fa fa-folder',
|
icon: 'fa fa-folder',
|
||||||
score: _.keys(sections).length,
|
score: _.keys(sections).length,
|
||||||
@ -150,8 +151,9 @@ export class SearchSrv {
|
|||||||
if (hit.folderId) {
|
if (hit.folderId) {
|
||||||
section = {
|
section = {
|
||||||
id: hit.folderId,
|
id: hit.folderId,
|
||||||
|
uid: hit.uid,
|
||||||
title: hit.folderTitle,
|
title: hit.folderTitle,
|
||||||
url: `dashboards/folder/${hit.folderId}/${hit.folderSlug}`,
|
url: hit.url,
|
||||||
slug: hit.slug,
|
slug: hit.slug,
|
||||||
items: [],
|
items: [],
|
||||||
icon: 'fa fa-folder-open',
|
icon: 'fa fa-folder-open',
|
||||||
|
@ -483,22 +483,22 @@ describe('ManageDashboards', () => {
|
|||||||
ctrl.sections = [
|
ctrl.sections = [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
|
uid: 'folder',
|
||||||
title: 'folder',
|
title: 'folder',
|
||||||
items: [{ id: 2, checked: true, slug: 'folder-dash' }],
|
items: [{ id: 2, checked: true, uid: 'folder-dash' }],
|
||||||
checked: true,
|
checked: true,
|
||||||
slug: 'folder',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 3,
|
id: 3,
|
||||||
title: 'folder-2',
|
title: 'folder-2',
|
||||||
items: [{ id: 3, checked: true, slug: 'folder-2-dash' }],
|
items: [{ id: 3, checked: true, uid: 'folder-2-dash' }],
|
||||||
checked: false,
|
checked: false,
|
||||||
slug: 'folder-2',
|
uid: 'folder-2',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 0,
|
id: 0,
|
||||||
title: 'Root',
|
title: 'Root',
|
||||||
items: [{ id: 3, checked: true, slug: 'root-dash' }],
|
items: [{ id: 3, checked: true, uid: 'root-dash' }],
|
||||||
checked: true,
|
checked: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -535,14 +535,14 @@ describe('ManageDashboards', () => {
|
|||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
title: 'folder',
|
title: 'folder',
|
||||||
items: [{ id: 2, checked: true, slug: 'dash' }],
|
items: [{ id: 2, checked: true, uid: 'dash' }],
|
||||||
checked: false,
|
checked: false,
|
||||||
slug: 'folder',
|
uid: 'folder',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 0,
|
id: 0,
|
||||||
title: 'Root',
|
title: 'Root',
|
||||||
items: [{ id: 3, checked: true, slug: 'dash-2' }],
|
items: [{ id: 3, checked: true, uid: 'dash-2' }],
|
||||||
checked: false,
|
checked: false,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -19,9 +19,7 @@ export class CreateFolderCtrl {
|
|||||||
|
|
||||||
return this.backendSrv.createDashboardFolder(this.title).then(result => {
|
return this.backendSrv.createDashboardFolder(this.title).then(result => {
|
||||||
appEvents.emit('alert-success', ['Folder Created', 'OK']);
|
appEvents.emit('alert-success', ['Folder Created', 'OK']);
|
||||||
|
this.$location.url(result.meta.url);
|
||||||
var folderUrl = `dashboards/folder/${result.dashboard.id}/${result.meta.slug}`;
|
|
||||||
this.$location.url(folderUrl);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,15 +3,16 @@ import { FolderPageLoader } from './folder_page_loader';
|
|||||||
export class FolderDashboardsCtrl {
|
export class FolderDashboardsCtrl {
|
||||||
navModel: any;
|
navModel: any;
|
||||||
folderId: number;
|
folderId: number;
|
||||||
|
uid: string;
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
constructor(private backendSrv, navModelSrv, private $routeParams) {
|
constructor(private backendSrv, navModelSrv, private $routeParams) {
|
||||||
if (this.$routeParams.folderId && this.$routeParams.slug) {
|
if (this.$routeParams.uid) {
|
||||||
this.folderId = $routeParams.folderId;
|
this.uid = $routeParams.uid;
|
||||||
|
|
||||||
const loader = new FolderPageLoader(this.backendSrv, this.$routeParams);
|
const loader = new FolderPageLoader(this.backendSrv);
|
||||||
|
|
||||||
loader.load(this, this.folderId, 'manage-folder-dashboards');
|
loader.load(this, this.uid, 'manage-folder-dashboards');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
export class FolderPageLoader {
|
export class FolderPageLoader {
|
||||||
constructor(private backendSrv, private $routeParams) {}
|
constructor(private backendSrv) {}
|
||||||
|
|
||||||
load(ctrl, folderId, activeChildId) {
|
load(ctrl, uid, activeChildId) {
|
||||||
ctrl.navModel = {
|
ctrl.navModel = {
|
||||||
main: {
|
main: {
|
||||||
icon: 'fa fa-folder-open',
|
icon: 'fa fa-folder-open',
|
||||||
@ -38,12 +38,13 @@ export class FolderPageLoader {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return this.backendSrv.getDashboard('db', this.$routeParams.slug).then(result => {
|
return this.backendSrv.getDashboardByUid(uid).then(result => {
|
||||||
|
ctrl.folderId = result.dashboard.id;
|
||||||
const folderTitle = result.dashboard.title;
|
const folderTitle = result.dashboard.title;
|
||||||
ctrl.navModel.main.text = '';
|
ctrl.navModel.main.text = '';
|
||||||
ctrl.navModel.main.breadcrumbs = [{ title: 'Dashboards', url: 'dashboards' }, { title: folderTitle }];
|
ctrl.navModel.main.breadcrumbs = [{ title: 'Dashboards', url: 'dashboards' }, { title: folderTitle }];
|
||||||
|
|
||||||
const folderUrl = this.createFolderUrl(folderId, result.meta.type, result.meta.slug);
|
const folderUrl = result.meta.url;
|
||||||
|
|
||||||
const dashTab = _.find(ctrl.navModel.main.children, {
|
const dashTab = _.find(ctrl.navModel.main.children, {
|
||||||
id: 'manage-folder-dashboards',
|
id: 'manage-folder-dashboards',
|
||||||
@ -63,8 +64,4 @@ export class FolderPageLoader {
|
|||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
createFolderUrl(folderId: number, type: string, slug: string) {
|
|
||||||
return `dashboards/folder/${folderId}/${slug}`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,14 @@ import { FolderPageLoader } from './folder_page_loader';
|
|||||||
export class FolderPermissionsCtrl {
|
export class FolderPermissionsCtrl {
|
||||||
navModel: any;
|
navModel: any;
|
||||||
folderId: number;
|
folderId: number;
|
||||||
|
uid: string;
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
constructor(private backendSrv, navModelSrv, private $routeParams) {
|
constructor(private backendSrv, navModelSrv, private $routeParams) {
|
||||||
if (this.$routeParams.folderId && this.$routeParams.slug) {
|
if (this.$routeParams.uid) {
|
||||||
this.folderId = $routeParams.folderId;
|
this.uid = $routeParams.uid;
|
||||||
|
|
||||||
new FolderPageLoader(this.backendSrv, this.$routeParams).load(this, this.folderId, 'manage-folder-permissions');
|
new FolderPageLoader(this.backendSrv).load(this, this.uid, 'manage-folder-permissions');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ export class FolderSettingsCtrl {
|
|||||||
folderPageLoader: FolderPageLoader;
|
folderPageLoader: FolderPageLoader;
|
||||||
navModel: any;
|
navModel: any;
|
||||||
folderId: number;
|
folderId: number;
|
||||||
|
uid: string;
|
||||||
canSave = false;
|
canSave = false;
|
||||||
dashboard: any;
|
dashboard: any;
|
||||||
meta: any;
|
meta: any;
|
||||||
@ -13,11 +14,11 @@ export class FolderSettingsCtrl {
|
|||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
constructor(private backendSrv, navModelSrv, private $routeParams, private $location) {
|
constructor(private backendSrv, navModelSrv, private $routeParams, private $location) {
|
||||||
if (this.$routeParams.folderId && this.$routeParams.slug) {
|
if (this.$routeParams.uid) {
|
||||||
this.folderId = $routeParams.folderId;
|
this.uid = $routeParams.uid;
|
||||||
|
|
||||||
this.folderPageLoader = new FolderPageLoader(this.backendSrv, this.$routeParams);
|
this.folderPageLoader = new FolderPageLoader(this.backendSrv);
|
||||||
this.folderPageLoader.load(this, this.folderId, 'manage-folder-settings').then(result => {
|
this.folderPageLoader.load(this, this.uid, 'manage-folder-settings').then(result => {
|
||||||
this.dashboard = result.dashboard;
|
this.dashboard = result.dashboard;
|
||||||
this.meta = result.meta;
|
this.meta = result.meta;
|
||||||
this.canSave = result.meta.canSave;
|
this.canSave = result.meta.canSave;
|
||||||
@ -38,9 +39,8 @@ export class FolderSettingsCtrl {
|
|||||||
return this.backendSrv
|
return this.backendSrv
|
||||||
.saveDashboard(this.dashboard, { overwrite: false })
|
.saveDashboard(this.dashboard, { overwrite: false })
|
||||||
.then(result => {
|
.then(result => {
|
||||||
var folderUrl = this.folderPageLoader.createFolderUrl(this.folderId, this.meta.type, result.slug);
|
if (result.url !== this.$location.path()) {
|
||||||
if (folderUrl !== this.$location.path()) {
|
this.$location.url(result.url + '/settings');
|
||||||
this.$location.url(folderUrl + '/settings');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
appEvents.emit('dashboard-saved');
|
appEvents.emit('dashboard-saved');
|
||||||
@ -65,7 +65,7 @@ export class FolderSettingsCtrl {
|
|||||||
icon: 'fa-trash',
|
icon: 'fa-trash',
|
||||||
yesText: 'Delete',
|
yesText: 'Delete',
|
||||||
onConfirm: () => {
|
onConfirm: () => {
|
||||||
return this.backendSrv.deleteDashboard(this.meta.slug).then(() => {
|
return this.backendSrv.deleteDashboard(this.dashboard.uid).then(() => {
|
||||||
appEvents.emit('alert-success', ['Folder Deleted', `${this.dashboard.title} has been deleted`]);
|
appEvents.emit('alert-success', ['Folder Deleted', `${this.dashboard.title} has been deleted`]);
|
||||||
this.$location.url('dashboards');
|
this.$location.url('dashboards');
|
||||||
});
|
});
|
||||||
|
@ -174,7 +174,7 @@ export class SettingsCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deleteDashboardConfirmed() {
|
deleteDashboardConfirmed() {
|
||||||
this.backendSrv.deleteDashboard(this.dashboard.meta.slug).then(() => {
|
this.backendSrv.deleteDashboard(this.dashboard.uid).then(() => {
|
||||||
appEvents.emit('alert-success', ['Dashboard Deleted', this.dashboard.title + ' has been deleted']);
|
appEvents.emit('alert-success', ['Dashboard Deleted', this.dashboard.title + ' has been deleted']);
|
||||||
this.$location.url('/');
|
this.$location.url('/');
|
||||||
});
|
});
|
||||||
|
@ -74,17 +74,17 @@ export function setupAngularRoutes($routeProvider, $locationProvider) {
|
|||||||
controller: 'CreateFolderCtrl',
|
controller: 'CreateFolderCtrl',
|
||||||
controllerAs: 'ctrl',
|
controllerAs: 'ctrl',
|
||||||
})
|
})
|
||||||
.when('/dashboards/folder/:folderId/:slug/permissions', {
|
.when('/dashboards/f/:uid/:slug/permissions', {
|
||||||
templateUrl: 'public/app/features/dashboard/partials/folder_permissions.html',
|
templateUrl: 'public/app/features/dashboard/partials/folder_permissions.html',
|
||||||
controller: 'FolderPermissionsCtrl',
|
controller: 'FolderPermissionsCtrl',
|
||||||
controllerAs: 'ctrl',
|
controllerAs: 'ctrl',
|
||||||
})
|
})
|
||||||
.when('/dashboards/folder/:folderId/:slug/settings', {
|
.when('/dashboards/f/:uid/:slug/settings', {
|
||||||
templateUrl: 'public/app/features/dashboard/partials/folder_settings.html',
|
templateUrl: 'public/app/features/dashboard/partials/folder_settings.html',
|
||||||
controller: 'FolderSettingsCtrl',
|
controller: 'FolderSettingsCtrl',
|
||||||
controllerAs: 'ctrl',
|
controllerAs: 'ctrl',
|
||||||
})
|
})
|
||||||
.when('/dashboards/folder/:folderId/:slug', {
|
.when('/dashboards/f/:uid/:slug', {
|
||||||
templateUrl: 'public/app/features/dashboard/partials/folder_dashboards.html',
|
templateUrl: 'public/app/features/dashboard/partials/folder_dashboards.html',
|
||||||
controller: 'FolderDashboardsCtrl',
|
controller: 'FolderDashboardsCtrl',
|
||||||
controllerAs: 'ctrl',
|
controllerAs: 'ctrl',
|
||||||
|
Loading…
Reference in New Issue
Block a user