|
@@ -7,6 +7,13 @@ import { DashboardMeta } from 'app/types';
|
|
|
import { BackendSrv } from 'app/core/services/backend_srv';
|
|
import { BackendSrv } from 'app/core/services/backend_srv';
|
|
|
import { ILocationService } from 'angular';
|
|
import { ILocationService } from 'angular';
|
|
|
|
|
|
|
|
|
|
+interface DashboardSaveOptions {
|
|
|
|
|
+ folderId?: number;
|
|
|
|
|
+ overwrite?: boolean;
|
|
|
|
|
+ message?: string;
|
|
|
|
|
+ makeEditable?: boolean;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
export class DashboardSrv {
|
|
export class DashboardSrv {
|
|
|
dashboard: DashboardModel;
|
|
dashboard: DashboardModel;
|
|
|
|
|
|
|
@@ -37,54 +44,53 @@ export class DashboardSrv {
|
|
|
removePanel(dashboard, dashboard.getPanelById(panelId), true);
|
|
removePanel(dashboard, dashboard.getPanelById(panelId), true);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- onPanelChangeView = (options: any) => {
|
|
|
|
|
|
|
+ onPanelChangeView = ({
|
|
|
|
|
+ fullscreen = false,
|
|
|
|
|
+ edit = false,
|
|
|
|
|
+ panelId,
|
|
|
|
|
+ }: {
|
|
|
|
|
+ fullscreen?: boolean;
|
|
|
|
|
+ edit?: boolean;
|
|
|
|
|
+ panelId?: number;
|
|
|
|
|
+ }) => {
|
|
|
const urlParams = this.$location.search();
|
|
const urlParams = this.$location.search();
|
|
|
|
|
|
|
|
// handle toggle logic
|
|
// handle toggle logic
|
|
|
- if (options.fullscreen === urlParams.fullscreen) {
|
|
|
|
|
- // I hate using these truthy converters (!!) but in this case
|
|
|
|
|
- // I think it's appropriate. edit can be null/false/undefined and
|
|
|
|
|
- // here i want all of those to compare the same
|
|
|
|
|
- if (!!options.edit === !!urlParams.edit) {
|
|
|
|
|
- delete urlParams.fullscreen;
|
|
|
|
|
- delete urlParams.edit;
|
|
|
|
|
- delete urlParams.panelId;
|
|
|
|
|
- delete urlParams.tab;
|
|
|
|
|
- this.$location.search(urlParams);
|
|
|
|
|
- return;
|
|
|
|
|
|
|
+ // I hate using these truthy converters (!!) but in this case
|
|
|
|
|
+ // I think it's appropriate. edit can be null/false/undefined and
|
|
|
|
|
+ // here i want all of those to compare the same
|
|
|
|
|
+ if (fullscreen === urlParams.fullscreen && edit === !!urlParams.edit) {
|
|
|
|
|
+ const paramsToRemove = ['fullscreen', 'edit', 'panelId', 'tab'];
|
|
|
|
|
+ for (const key of paramsToRemove) {
|
|
|
|
|
+ delete urlParams[key];
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- if (options.fullscreen) {
|
|
|
|
|
- urlParams.fullscreen = true;
|
|
|
|
|
- } else {
|
|
|
|
|
- delete urlParams.fullscreen;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (options.edit) {
|
|
|
|
|
- urlParams.edit = true;
|
|
|
|
|
- } else {
|
|
|
|
|
- delete urlParams.edit;
|
|
|
|
|
- delete urlParams.tab;
|
|
|
|
|
|
|
+ this.$location.search(urlParams);
|
|
|
|
|
+ return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (options.panelId || options.panelId === 0) {
|
|
|
|
|
- urlParams.panelId = options.panelId;
|
|
|
|
|
- } else {
|
|
|
|
|
- delete urlParams.panelId;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ const newUrlParams = {
|
|
|
|
|
+ ...urlParams,
|
|
|
|
|
+ fullscreen: fullscreen || undefined,
|
|
|
|
|
+ edit: edit || undefined,
|
|
|
|
|
+ tab: edit ? urlParams.tab : undefined,
|
|
|
|
|
+ panelId,
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ Object.keys(newUrlParams).forEach(key => {
|
|
|
|
|
+ if (newUrlParams[key] === undefined) {
|
|
|
|
|
+ delete newUrlParams[key];
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
- this.$location.search(urlParams);
|
|
|
|
|
|
|
+ this.$location.search(newUrlParams);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
handleSaveDashboardError(
|
|
handleSaveDashboardError(
|
|
|
clone: any,
|
|
clone: any,
|
|
|
- options: { overwrite?: any },
|
|
|
|
|
|
|
+ options: DashboardSaveOptions,
|
|
|
err: { data: { status: string; message: any }; isHandled: boolean }
|
|
err: { data: { status: string; message: any }; isHandled: boolean }
|
|
|
) {
|
|
) {
|
|
|
- options = options || {};
|
|
|
|
|
- options.overwrite = true;
|
|
|
|
|
-
|
|
|
|
|
if (err.data && err.data.status === 'version-mismatch') {
|
|
if (err.data && err.data.status === 'version-mismatch') {
|
|
|
err.isHandled = true;
|
|
err.isHandled = true;
|
|
|
|
|
|
|
@@ -129,16 +135,16 @@ export class DashboardSrv {
|
|
|
this.showSaveAsModal();
|
|
this.showSaveAsModal();
|
|
|
},
|
|
},
|
|
|
onConfirm: () => {
|
|
onConfirm: () => {
|
|
|
- this.save(clone, { overwrite: true });
|
|
|
|
|
|
|
+ this.save(clone, { ...options, overwrite: true });
|
|
|
},
|
|
},
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- postSave(clone: DashboardModel, data: { version: number; url: string }) {
|
|
|
|
|
|
|
+ postSave(data: { version: number; url: string }) {
|
|
|
this.dashboard.version = data.version;
|
|
this.dashboard.version = data.version;
|
|
|
|
|
|
|
|
- // important that these happens before location redirect below
|
|
|
|
|
|
|
+ // important that these happen before location redirect below
|
|
|
this.$rootScope.appEvent('dashboard-saved', this.dashboard);
|
|
this.$rootScope.appEvent('dashboard-saved', this.dashboard);
|
|
|
this.$rootScope.appEvent('alert-success', ['Dashboard saved']);
|
|
this.$rootScope.appEvent('alert-success', ['Dashboard saved']);
|
|
|
|
|
|
|
@@ -152,17 +158,19 @@ export class DashboardSrv {
|
|
|
return this.dashboard;
|
|
return this.dashboard;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- save(clone: any, options: { overwrite?: any; folderId?: any }) {
|
|
|
|
|
- options = options || {};
|
|
|
|
|
|
|
+ save(clone: any, options?: DashboardSaveOptions) {
|
|
|
options.folderId = options.folderId >= 0 ? options.folderId : this.dashboard.meta.folderId || clone.folderId;
|
|
options.folderId = options.folderId >= 0 ? options.folderId : this.dashboard.meta.folderId || clone.folderId;
|
|
|
|
|
|
|
|
return this.backendSrv
|
|
return this.backendSrv
|
|
|
.saveDashboard(clone, options)
|
|
.saveDashboard(clone, options)
|
|
|
- .then(this.postSave.bind(this, clone))
|
|
|
|
|
- .catch(this.handleSaveDashboardError.bind(this, clone, options));
|
|
|
|
|
|
|
+ .then((data: any) => this.postSave(data))
|
|
|
|
|
+ .catch(this.handleSaveDashboardError.bind(this, clone, { folderId: options.folderId }));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- saveDashboard(options?: { overwrite?: any; folderId?: any; makeEditable?: any }, clone?: DashboardModel) {
|
|
|
|
|
|
|
+ saveDashboard(
|
|
|
|
|
+ clone?: DashboardModel,
|
|
|
|
|
+ { makeEditable = false, folderId, overwrite = false, message }: DashboardSaveOptions = {}
|
|
|
|
|
+ ) {
|
|
|
if (clone) {
|
|
if (clone) {
|
|
|
this.setCurrent(this.create(clone, this.dashboard.meta));
|
|
this.setCurrent(this.create(clone, this.dashboard.meta));
|
|
|
}
|
|
}
|
|
@@ -171,7 +179,7 @@ export class DashboardSrv {
|
|
|
return this.showDashboardProvisionedModal();
|
|
return this.showDashboardProvisionedModal();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (!this.dashboard.meta.canSave && options.makeEditable !== true) {
|
|
|
|
|
|
|
+ if (!(this.dashboard.meta.canSave || makeEditable)) {
|
|
|
return Promise.resolve();
|
|
return Promise.resolve();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -183,7 +191,7 @@ export class DashboardSrv {
|
|
|
return this.showSaveModal();
|
|
return this.showSaveModal();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return this.save(this.dashboard.getSaveModelClone(), options);
|
|
|
|
|
|
|
+ return this.save(this.dashboard.getSaveModelClone(), { folderId, overwrite, message });
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
saveJSONDashboard(json: string) {
|
|
saveJSONDashboard(json: string) {
|