From 008b9bb3e92df492928dec8150df72a2c86def9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 11 Dec 2017 16:28:57 +0100 Subject: [PATCH] ux: dashboard settings work progress --- public/app/features/dashboard/all.ts | 2 +- .../features/dashboard/dashboard_save_as.ts | 81 ++++++++++++++++ .../app/features/dashboard/dashnav/dashnav.ts | 54 ----------- .../features/dashboard/history/history.html | 26 +++-- .../app/features/dashboard/save_as_modal.ts | 95 ------------------- .../features/dashboard/settings/settings.html | 26 +++++ .../features/dashboard/settings/settings.ts | 31 +++++- ...odal.jest.ts => dashboard_save_as.jest.ts} | 4 +- public/app/features/panel/panel_ctrl.ts | 15 ++- 9 files changed, 161 insertions(+), 173 deletions(-) create mode 100644 public/app/features/dashboard/dashboard_save_as.ts delete mode 100644 public/app/features/dashboard/save_as_modal.ts rename public/app/features/dashboard/specs/{save_as_modal.jest.ts => dashboard_save_as.jest.ts} (92%) 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 = ` +

Save As

+ +
+
+
+ + +
+
+ + +
+
+ +
+ +
+
+`; + +export class SaveDashboardAsCtrl { + clone: any; + folderId: any; + dismiss: () => void; + + /** @ngInject */ + constructor(private dashboardSrv) { + var dashboard = this.dashboardSrv.getCurrent(); + this.clone = dashboard.getSaveModelClone(); + this.clone.id = null; + this.clone.title += ' Copy'; + this.clone.editable = true; + this.clone.hideControls = false; + this.folderId = dashboard.folderId; + + // remove alerts if source dashboard is already persisted + // do not want to create alert dupes + if (dashboard.id > 0) { + this.clone.panels.forEach(panel => { + if (panel.type === "graph" && panel.alert) { + delete panel.thresholds; + } + delete panel.alert; + }); + } + + delete this.clone.autoUpdate; + } + + save() { + return this.dashboardSrv.save(this.clone).then(this.dismiss); + } + + keyDown(evt) { + if (evt.keyCode === 13) { + this.save(); + } + } + + onFolderChange(folder) { + this.clone.folderId = folder.id; + } +} + +export function saveDashboardAsDirective() { + return { + restrict: 'E', + template: template, + controller: SaveDashboardAsCtrl, + bindToController: true, + controllerAs: 'ctrl', + scope: {} + }; +} + +coreModule.directive('saveDashboardAs', saveDashboardAsDirective); diff --git a/public/app/features/dashboard/dashnav/dashnav.ts b/public/app/features/dashboard/dashnav/dashnav.ts index 284a913401d..aed803efb9a 100644 --- a/public/app/features/dashboard/dashnav/dashnav.ts +++ b/public/app/features/dashboard/dashnav/dashnav.ts @@ -1,4 +1,3 @@ -import _ from 'lodash'; import moment from 'moment'; import angular from 'angular'; import {appEvents, NavModel} from 'app/core/core'; @@ -15,13 +14,11 @@ export class DashNavCtrl { private $rootScope, private dashboardSrv, private $location, - private backendSrv, public playlistSrv, navModelSrv) { this.navModel = navModelSrv.getDashboardNav(this.dashboard, this); appEvents.on('save-dashboard', this.saveDashboard.bind(this), $scope); - appEvents.on('delete-dashboard', this.deleteDashboard.bind(this), $scope); if (this.dashboard.meta.isSnapshot) { var meta = this.dashboard.meta; @@ -76,61 +73,10 @@ export class DashNavCtrl { angular.element(evt.currentTarget).tooltip('hide'); } - makeEditable() { - this.dashboard.editable = true; - - return this.dashboardSrv.saveDashboard({makeEditable: true, overwrite: false}).then(() => { - // force refresh whole page - window.location.href = window.location.href; - }); - } - - exitFullscreen() { - this.$rootScope.appEvent('panel-change-view', {fullscreen: false, edit: false}); - } - saveDashboard() { return this.dashboardSrv.saveDashboard(); } - deleteDashboard() { - var confirmText = ''; - var text2 = this.dashboard.title; - - const alerts = _.sumBy(this.dashboard.panels, panel => { - return panel.alert ? 1 : 0; - }); - - if (alerts > 0) { - confirmText = 'DELETE'; - text2 = `This dashboard contains ${alerts} alerts. Deleting this dashboard will also delete those alerts`; - } - - appEvents.emit('confirm-modal', { - title: 'Delete', - text: 'Do you want to delete this dashboard?', - text2: text2, - icon: 'fa-trash', - confirmText: confirmText, - yesText: 'Delete', - onConfirm: () => { - this.dashboard.meta.canSave = false; - this.deleteDashboardConfirmed(); - } - }); - } - - deleteDashboardConfirmed() { - 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('/'); - }); - } - - saveDashboardAs() { - return this.dashboardSrv.showSaveAsModal(); - } - showSearch() { this.$rootScope.appEvent('show-dash-search'); } diff --git a/public/app/features/dashboard/history/history.html b/public/app/features/dashboard/history/history.html index 8ccf6e5b695..c79853e5613 100644 --- a/public/app/features/dashboard/history/history.html +++ b/public/app/features/dashboard/history/history.html @@ -8,18 +8,6 @@ -
-
- -
-
@@ -75,6 +63,14 @@ ng-disabled="ctrl.isLastPage()"> Show more versions +
@@ -89,9 +85,9 @@
diff --git a/public/app/features/dashboard/save_as_modal.ts b/public/app/features/dashboard/save_as_modal.ts deleted file mode 100644 index 643d6a36f67..00000000000 --- a/public/app/features/dashboard/save_as_modal.ts +++ /dev/null @@ -1,95 +0,0 @@ -/// - -import coreModule from 'app/core/core_module'; - -const template = ` - -`; - -export class SaveDashboardAsModalCtrl { - clone: any; - folderId: any; - dismiss: () => void; - - /** @ngInject */ - constructor(private dashboardSrv) { - var dashboard = this.dashboardSrv.getCurrent(); - this.clone = dashboard.getSaveModelClone(); - this.clone.id = null; - this.clone.title += ' Copy'; - this.clone.editable = true; - this.clone.hideControls = false; - this.folderId = dashboard.folderId; - - // remove alerts if source dashboard is already persisted - // do not want to create alert dupes - if (dashboard.id > 0) { - this.clone.panels.forEach(panel => { - if (panel.type === "graph" && panel.alert) { - delete panel.thresholds; - } - delete panel.alert; - }); - } - - delete this.clone.autoUpdate; - } - - save() { - return this.dashboardSrv.save(this.clone).then(this.dismiss); - } - - keyDown(evt) { - if (evt.keyCode === 13) { - this.save(); - } - } - - onFolderChange(folder) { - this.clone.folderId = folder.id; - } -} - -export function saveDashboardAsDirective() { - return { - restrict: 'E', - template: template, - controller: SaveDashboardAsModalCtrl, - bindToController: true, - controllerAs: 'ctrl', - scope: {dismiss: "&"} - }; -} - -coreModule.directive('saveDashboardAsModal', saveDashboardAsDirective); diff --git a/public/app/features/dashboard/settings/settings.html b/public/app/features/dashboard/settings/settings.html index e594c7c7563..4727e424214 100644 --- a/public/app/features/dashboard/settings/settings.html +++ b/public/app/features/dashboard/settings/settings.html @@ -78,3 +78,29 @@
+ +
+ +
+ +
+

Delete dashboard

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