Browse Source

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.
Marcus Efraimsson 8 years ago
parent
commit
92a0171a9b

+ 1 - 0
pkg/services/search/models.go

@@ -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"`

+ 1 - 0
pkg/services/sqlstore/dashboard.go

@@ -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,

+ 1 - 1
pkg/services/sqlstore/dashboard_test.go

@@ -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() {

+ 3 - 3
public/app/core/components/manage_dashboards/manage_dashboards.ts

@@ -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;

+ 11 - 11
public/app/core/services/backend_srv.ts

@@ -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.delete(`/api/dashboards/db/${slug}`)
+    this.getDashboardByUid(uid).then(fullDash => {
+      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) {
-      tasks.push(this.createTask(this.deleteDashboard.bind(this), true, slug));
+    for (let uid of dashboardUids) {
+      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) {
-      tasks.push(this.createTask(this.moveDashboard.bind(this), true, slug, toFolder));
+    for (let uid of dashboardUids) {
+      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) {

+ 4 - 2
public/app/core/services/search_srv.ts

@@ -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',

+ 8 - 8
public/app/core/specs/manage_dashboards.jest.ts

@@ -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,
         },
         },
       ];
       ];

+ 1 - 3
public/app/features/dashboard/create_folder_ctrl.ts

@@ -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']);
-
-      var folderUrl = `dashboards/folder/${result.dashboard.id}/${result.meta.slug}`;
-      this.$location.url(folderUrl);
+      this.$location.url(result.meta.url);
     });
     });
   }
   }
 
 

+ 5 - 4
public/app/features/dashboard/folder_dashboards_ctrl.ts

@@ -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) {
-      this.folderId = $routeParams.folderId;
+    if (this.$routeParams.uid) {
+      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');
     }
     }
   }
   }
 }
 }

+ 5 - 8
public/app/features/dashboard/folder_page_loader.ts

@@ -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}`;
-  }
 }
 }

+ 4 - 3
public/app/features/dashboard/folder_permissions_ctrl.ts

@@ -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) {
-      this.folderId = $routeParams.folderId;
+    if (this.$routeParams.uid) {
+      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');
     }
     }
   }
   }
 }
 }

+ 8 - 8
public/app/features/dashboard/folder_settings_ctrl.ts

@@ -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) {
-      this.folderId = $routeParams.folderId;
+    if (this.$routeParams.uid) {
+      this.uid = $routeParams.uid;
 
 
-      this.folderPageLoader = new FolderPageLoader(this.backendSrv, this.$routeParams);
-      this.folderPageLoader.load(this, this.folderId, 'manage-folder-settings').then(result => {
+      this.folderPageLoader = new FolderPageLoader(this.backendSrv);
+      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 (folderUrl !== this.$location.path()) {
-          this.$location.url(folderUrl + '/settings');
+        if (result.url !== this.$location.path()) {
+          this.$location.url(result.url + '/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');
         });
         });

+ 1 - 1
public/app/features/dashboard/settings/settings.ts

@@ -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('/');
     });
     });

+ 3 - 3
public/app/routes/routes.ts

@@ -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',