diff --git a/public/app/features/dashboard/all.ts b/public/app/features/dashboard/all.ts
index 4c7e6058984..eb61ca6aa11 100644
--- a/public/app/features/dashboard/all.ts
+++ b/public/app/features/dashboard/all.ts
@@ -4,7 +4,7 @@ import './history/history';
import './dashboardLoaderSrv';
import './dashnav/dashnav';
import './submenu/submenu';
-import './save_as_modal';
+import './dashboard_save_as';
import './save_modal';
import './shareModalCtrl';
import './shareSnapshotCtrl';
diff --git a/public/app/features/dashboard/dashboard_save_as.ts b/public/app/features/dashboard/dashboard_save_as.ts
new file mode 100644
index 00000000000..5ce487587e4
--- /dev/null
+++ b/public/app/features/dashboard/dashboard_save_as.ts
@@ -0,0 +1,81 @@
+import coreModule from 'app/core/core_module';
+
+const template = `
+
+
+
+
+
+
+
+
This dashboard contains {{ctrl.alertCount}} alerts. Deleting this dashboard will also delete those alerts
+
+
+
+
+
+
+
+
You cannot delete this dashboard
+
+
+
diff --git a/public/app/features/dashboard/settings/settings.ts b/public/app/features/dashboard/settings/settings.ts
index 10dd857e255..96aadd0c690 100644
--- a/public/app/features/dashboard/settings/settings.ts
+++ b/public/app/features/dashboard/settings/settings.ts
@@ -1,4 +1,4 @@
-import {coreModule} from 'app/core/core';
+import {coreModule, appEvents} from 'app/core/core';
import {DashboardModel} from '../dashboard_model';
import $ from 'jquery';
import _ from 'lodash';
@@ -8,6 +8,9 @@ export class SettingsCtrl {
isOpen: boolean;
viewId: string;
json: string;
+ alertCount: number;
+ confirmValid: boolean;
+ confirmText: string;
sections: any[] = [
{title: 'General', id: 'settings', icon: "fa fa-fw fa-sliders"},
@@ -21,7 +24,7 @@ export class SettingsCtrl {
];
/** @ngInject */
- constructor(private $scope, private $location, private $rootScope) {
+ constructor(private $scope, private $location, private $rootScope, private backendSrv, private dashboardSrv) {
// temp hack for annotations and variables editors
// that rely on inherited scope
$scope.dashboard = this.dashboard;
@@ -39,6 +42,10 @@ export class SettingsCtrl {
this.$rootScope.$broadcast("refresh");
});
+ this.alertCount = _.sumBy(this.dashboard.panels, panel => {
+ return panel.alert ? 1 : 0;
+ });
+
this.onRouteUpdated();
$rootScope.onAppEvent("$routeUpdate", this.onRouteUpdated.bind(this), $scope);
}
@@ -61,6 +68,26 @@ export class SettingsCtrl {
});
}
+ makeEditable() {
+ this.dashboard.editable = true;
+
+ return this.dashboardSrv.saveDashboard({makeEditable: true, overwrite: false}).then(() => {
+ // force refresh whole page
+ window.location.href = window.location.href;
+ });
+ }
+
+ confirmTextChanged() {
+ this.confirmValid = this.confirmText === "DELETE";
+ }
+
+ deleteDashboard() {
+ this.backendSrv.delete('/api/dashboards/db/' + this.dashboard.meta.slug).then(() => {
+ appEvents.emit('alert-success', ['Dashboard Deleted', this.dashboard.title + ' has been deleted']);
+ this.$location.url('/');
+ });
+ }
+
onFolderChange(folder) {
this.dashboard.folderId = folder.id;
this.dashboard.meta.folderId = folder.id;
diff --git a/public/app/features/dashboard/specs/save_as_modal.jest.ts b/public/app/features/dashboard/specs/dashboard_save_as.jest.ts
similarity index 92%
rename from public/app/features/dashboard/specs/save_as_modal.jest.ts
rename to public/app/features/dashboard/specs/dashboard_save_as.jest.ts
index b2ab77f2255..21d0fafd6ae 100644
--- a/public/app/features/dashboard/specs/save_as_modal.jest.ts
+++ b/public/app/features/dashboard/specs/dashboard_save_as.jest.ts
@@ -1,4 +1,4 @@
-import { SaveDashboardAsModalCtrl } from '../save_as_modal';
+import { SaveDashboardAsCtrl } from '../dashboard_save_as';
import { describe, it, expect } from 'test/lib/common';
describe('saving dashboard as', () => {
@@ -21,7 +21,7 @@ describe('saving dashboard as', () => {
},
};
- var ctrl = new SaveDashboardAsModalCtrl(mockDashboardSrv);
+ var ctrl = new SaveDashboardAsCtrl(mockDashboardSrv);
var ctx: any = {
clone: ctrl.clone,
ctrl: ctrl,
diff --git a/public/app/features/panel/panel_ctrl.ts b/public/app/features/panel/panel_ctrl.ts
index ab74a006fce..4655ff19282 100644
--- a/public/app/features/panel/panel_ctrl.ts
+++ b/public/app/features/panel/panel_ctrl.ts
@@ -134,20 +134,27 @@ export class PanelCtrl {
getMenu() {
let menu = [];
menu.push({text: 'View', click: 'ctrl.viewPanel();', icon: "fa fa-fw fa-eye", shortcut: "v"});
- menu.push({text: 'Edit', click: 'ctrl.editPanel();', role: 'Editor', icon: "fa fa-fw fa-edit", shortcut: "e"});
+
+ if (this.dashboard.meta.canEdit) {
+ menu.push({text: 'Edit', click: 'ctrl.editPanel();', role: 'Editor', icon: "fa fa-fw fa-edit", shortcut: "e"});
+ }
+
menu.push({text: 'Share', click: 'ctrl.sharePanel();', icon: "fa fa-fw fa-share", shortcut: "p s"});
let extendedMenu = this.getExtendedMenu();
menu.push({text: 'More ...', click: 'ctrl.removePanel();', icon: "fa fa-fw fa-cube", submenu: extendedMenu});
- menu.push({divider: true, role: 'Editor'});
- menu.push({text: 'Remove', click: 'ctrl.removePanel();', role: 'Editor', icon: "fa fa-fw fa-trash", shortcut: "p r"});
+ if (this.dashboard.meta.canEdit) {
+ menu.push({divider: true, role: 'Editor'});
+ menu.push({text: 'Remove', click: 'ctrl.removePanel();', role: 'Editor', icon: "fa fa-fw fa-trash", shortcut: "p r"});
+ }
+
return menu;
}
getExtendedMenu() {
let menu = [];
- if (!this.fullscreen) {
+ if (!this.fullscreen && this.dashboard.meta.canEdit) {
menu.push({ text: 'Duplicate', click: 'ctrl.duplicate()', role: 'Editor' });
}
menu.push({text: 'Panel JSON', click: 'ctrl.editPanelJson(); dismiss();' });