diff --git a/public/app/core/components/dashboard_selector.ts b/public/app/core/components/dashboard_selector.ts index 7ec9f681520..ac8b30e7733 100644 --- a/public/app/core/components/dashboard_selector.ts +++ b/public/app/core/components/dashboard_selector.ts @@ -1,5 +1,3 @@ -/// - import coreModule from 'app/core/core_module'; var template = ` diff --git a/public/app/features/dashboard/all.ts b/public/app/features/dashboard/all.ts index eb61ca6aa11..4c7e6058984 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 './dashboard_save_as'; +import './save_as_modal'; 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 deleted file mode 100644 index 5ce487587e4..00000000000 --- a/public/app/features/dashboard/dashboard_save_as.ts +++ /dev/null @@ -1,81 +0,0 @@ -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/save_as_modal.ts b/public/app/features/dashboard/save_as_modal.ts new file mode 100644 index 00000000000..d69b64f1960 --- /dev/null +++ b/public/app/features/dashboard/save_as_modal.ts @@ -0,0 +1,93 @@ +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 76a297c50ee..7de5e2dbcd1 100644 --- a/public/app/features/dashboard/settings/settings.html +++ b/public/app/features/dashboard/settings/settings.html @@ -8,53 +8,65 @@ {{::section.title}} + +
+ + + +
-

- General -

+

+ General +

-
-
- - -
-
- - -
-
- - - -
- - - - -
+
+
+ + +
+
+ + +
+
+ + + +
+ + + + +
- + -
Panel Options
-
- -
- -
-
+
Panel Options
+
+ +
+ +
+
@@ -72,29 +84,11 @@
-

View JSON

+

View JSON

-
- -
-
- -
- -
- -
-

Delete dashboard

- -
-
This dashboard contains {{ctrl.alertCount}} alerts. Deleting this dashboard will also delete those alerts
- -
- - +
+ +
diff --git a/public/app/features/dashboard/settings/settings.ts b/public/app/features/dashboard/settings/settings.ts index d19165e832f..87ac91d568b 100644 --- a/public/app/features/dashboard/settings/settings.ts +++ b/public/app/features/dashboard/settings/settings.ts @@ -9,8 +9,8 @@ export class SettingsCtrl { viewId: string; json: string; alertCount: number; - confirmValid: boolean; - confirmText: string; + canSaveAs: boolean; + canDelete: boolean; sections: any[]; /** @ngInject */ @@ -24,13 +24,11 @@ export class SettingsCtrl { this.$rootScope.$broadcast('refresh'); }); - this.alertCount = _.sumBy(this.dashboard.panels, panel => { - return panel.alert ? 1 : 0; - }); + this.canSaveAs = contextSrv.isEditor; + this.canDelete = this.dashboard.meta.canSave; - this.confirmValid = this.alertCount === 0; - this.onRouteUpdated(); this.buildSectionList(); + this.onRouteUpdated(); $rootScope.onAppEvent('$routeUpdate', this.onRouteUpdated.bind(this), $scope); } @@ -55,14 +53,6 @@ export class SettingsCtrl { this.sections.push({ title: 'View JSON', id: 'view_json', icon: 'fa fa-fw fa-code' }); - if (contextSrv.isEditor) { - this.sections.push({ title: 'Save As', id: 'save_as', icon: 'fa fa-fw fa-copy' }); - } - - if (this.dashboard.meta.canSave) { - this.sections.push({ title: 'Delete', id: 'delete', icon: 'fa fa-fw fa-trash' }); - } - const params = this.$location.search(); const url = this.$location.path(); @@ -70,6 +60,14 @@ export class SettingsCtrl { const sectionParams = _.defaults({ editview: section.id }, params); section.url = url + '?' + $.param(sectionParams); } + } + + onRouteUpdated() { + this.viewId = this.$location.search().editview; + + if (this.viewId) { + this.json = JSON.stringify(this.dashboard.getSaveModelClone(), null, 2); + } const currentSection = _.find(this.sections, { id: this.viewId }); if (!currentSection) { @@ -79,12 +77,8 @@ export class SettingsCtrl { } } - onRouteUpdated() { - this.viewId = this.$location.search().editview; - - if (this.viewId) { - this.json = JSON.stringify(this.dashboard.getSaveModelClone(), null, 2); - } + openSaveAsModal() { + this.dashboardSrv.showSaveAsModal(); } hideSettings() { @@ -106,11 +100,34 @@ export class SettingsCtrl { }); } - confirmTextChanged() { - this.confirmValid = this.confirmText === 'DELETE'; + 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(); + } + }); } - deleteDashboard() { + 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('/'); diff --git a/public/app/features/dashboard/specs/dashboard_save_as.jest.ts b/public/app/features/dashboard/specs/save_as_modal.jest.ts similarity index 92% rename from public/app/features/dashboard/specs/dashboard_save_as.jest.ts rename to public/app/features/dashboard/specs/save_as_modal.jest.ts index 21d0fafd6ae..9155f59ca70 100644 --- a/public/app/features/dashboard/specs/dashboard_save_as.jest.ts +++ b/public/app/features/dashboard/specs/save_as_modal.jest.ts @@ -1,4 +1,4 @@ -import { SaveDashboardAsCtrl } from '../dashboard_save_as'; +import { SaveDashboardAsModalCtrl } from '../save_as_modal; import { describe, it, expect } from 'test/lib/common'; describe('saving dashboard as', () => { @@ -21,7 +21,7 @@ describe('saving dashboard as', () => { }, }; - var ctrl = new SaveDashboardAsCtrl(mockDashboardSrv); + var ctrl = new SaveDashboardAsModalCtrl(mockDashboardSrv); var ctx: any = { clone: ctrl.clone, ctrl: ctrl, diff --git a/public/sass/components/_dashboard_settings.scss b/public/sass/components/_dashboard_settings.scss index bb22e6af89e..9e307c07231 100644 --- a/public/sass/components/_dashboard_settings.scss +++ b/public/sass/components/_dashboard_settings.scss @@ -67,3 +67,15 @@ padding-right: 5px; } } + +.dashboard-settings__aside-actions { + display: flex; + flex-direction: column; + height: 100%; + flex-grow: 1; + margin: $spacer*3 $spacer*2 0 0; + + button { + margin-bottom: 10px; + } +}