| 
									
										
										
										
											2017-12-20 19:33:33 +08:00
										 |  |  | import _ from 'lodash'; | 
					
						
							|  |  |  | import coreModule from 'app/core/core_module'; | 
					
						
							|  |  |  | import appEvents from 'app/core/app_events'; | 
					
						
							|  |  |  | import { DashboardModel } from 'app/features/dashboard/dashboard_model'; | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | export class BackendSrv { | 
					
						
							| 
									
										
										
										
											2017-08-23 19:31:26 +08:00
										 |  |  |   private inFlightRequests = {}; | 
					
						
							|  |  |  |   private HTTP_REQUEST_CANCELLED = -1; | 
					
						
							|  |  |  |   private noBackendCache: boolean; | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-14 21:47:39 +08:00
										 |  |  |   /** @ngInject */ | 
					
						
							| 
									
										
										
										
											2018-10-25 23:05:17 +08:00
										 |  |  |   constructor(private $http, private $q, private $timeout, private contextSrv) {} | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   get(url, params?) { | 
					
						
							| 
									
										
										
										
											2017-12-20 19:33:33 +08:00
										 |  |  |     return this.request({ method: 'GET', url: url, params: params }); | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   delete(url) { | 
					
						
							| 
									
										
										
										
											2017-12-20 19:33:33 +08:00
										 |  |  |     return this.request({ method: 'DELETE', url: url }); | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   post(url, data) { | 
					
						
							| 
									
										
										
										
											2017-12-20 19:33:33 +08:00
										 |  |  |     return this.request({ method: 'POST', url: url, data: data }); | 
					
						
							| 
									
										
										
										
											2017-04-20 17:16:37 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   patch(url, data) { | 
					
						
							| 
									
										
										
										
											2017-12-20 19:33:33 +08:00
										 |  |  |     return this.request({ method: 'PATCH', url: url, data: data }); | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   put(url, data) { | 
					
						
							| 
									
										
										
										
											2017-12-20 19:33:33 +08:00
										 |  |  |     return this.request({ method: 'PUT', url: url, data: data }); | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-23 19:31:26 +08:00
										 |  |  |   withNoBackendCache(callback) { | 
					
						
							|  |  |  |     this.noBackendCache = true; | 
					
						
							|  |  |  |     return callback().finally(() => { | 
					
						
							|  |  |  |       this.noBackendCache = false; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  |   requestErrorHandler(err) { | 
					
						
							|  |  |  |     if (err.isHandled) { | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-30 15:03:11 +08:00
										 |  |  |     let data = err.data || { message: 'Unexpected error' }; | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  |     if (_.isString(data)) { | 
					
						
							|  |  |  |       data = { message: data }; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (err.status === 422) { | 
					
						
							| 
									
										
										
										
											2018-10-25 23:05:17 +08:00
										 |  |  |       appEvents.emit('alert-warning', ['Validation failed', data.message]); | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  |       throw data; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-25 23:05:17 +08:00
										 |  |  |     let severity = 'error'; | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (err.status < 500) { | 
					
						
							| 
									
										
										
										
											2018-10-25 23:05:17 +08:00
										 |  |  |       severity = 'warning'; | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (data.message) { | 
					
						
							| 
									
										
										
										
											2017-12-20 19:33:33 +08:00
										 |  |  |       let description = ''; | 
					
						
							| 
									
										
										
										
											2017-09-12 15:05:32 +08:00
										 |  |  |       let message = data.message; | 
					
						
							|  |  |  |       if (message.length > 80) { | 
					
						
							|  |  |  |         description = message; | 
					
						
							| 
									
										
										
										
											2017-12-20 19:33:33 +08:00
										 |  |  |         message = 'Error'; | 
					
						
							| 
									
										
										
										
											2017-09-12 15:05:32 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-10-25 23:05:17 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       appEvents.emit('alert-' + severity, [message, description]); | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     throw data; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   request(options) { | 
					
						
							|  |  |  |     options.retry = options.retry || 0; | 
					
						
							| 
									
										
										
										
											2018-08-29 20:27:29 +08:00
										 |  |  |     const requestIsLocal = !options.url.match(/^http/); | 
					
						
							|  |  |  |     const firstAttempt = options.retry === 0; | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-14 22:00:52 +08:00
										 |  |  |     if (requestIsLocal) { | 
					
						
							|  |  |  |       if (this.contextSrv.user && this.contextSrv.user.orgId) { | 
					
						
							|  |  |  |         options.headers = options.headers || {}; | 
					
						
							| 
									
										
										
										
											2017-12-20 19:33:33 +08:00
										 |  |  |         options.headers['X-Grafana-Org-Id'] = this.contextSrv.user.orgId; | 
					
						
							| 
									
										
										
										
											2017-04-14 22:00:52 +08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 19:33:33 +08:00
										 |  |  |       if (options.url.indexOf('/') === 0) { | 
					
						
							| 
									
										
										
										
											2017-04-15 01:01:08 +08:00
										 |  |  |         options.url = options.url.substring(1); | 
					
						
							| 
									
										
										
										
											2017-04-14 22:00:52 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-19 23:06:54 +08:00
										 |  |  |     return this.$http(options).then( | 
					
						
							|  |  |  |       results => { | 
					
						
							| 
									
										
										
										
											2017-12-20 19:33:33 +08:00
										 |  |  |         if (options.method !== 'GET') { | 
					
						
							| 
									
										
										
										
											2017-12-19 23:06:54 +08:00
										 |  |  |           if (results && results.data.message) { | 
					
						
							|  |  |  |             if (options.showSuccessAlert !== false) { | 
					
						
							| 
									
										
										
										
											2018-10-25 23:05:17 +08:00
										 |  |  |               appEvents.emit('alert-success', [results.data.message]); | 
					
						
							| 
									
										
										
										
											2017-12-19 23:06:54 +08:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2016-11-09 17:41:39 +08:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-12-19 23:06:54 +08:00
										 |  |  |         return results.data; | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       err => { | 
					
						
							|  |  |  |         // handle unauthorized
 | 
					
						
							| 
									
										
										
										
											2017-12-21 15:39:31 +08:00
										 |  |  |         if (err.status === 401 && this.contextSrv.user.isSignedIn && firstAttempt) { | 
					
						
							| 
									
										
										
										
											2017-12-19 23:06:54 +08:00
										 |  |  |           return this.loginPing().then(() => { | 
					
						
							|  |  |  |             options.retry = 1; | 
					
						
							|  |  |  |             return this.request(options); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-19 23:06:54 +08:00
										 |  |  |         this.$timeout(this.requestErrorHandler.bind(this, err), 50); | 
					
						
							|  |  |  |         throw err; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2017-04-20 17:16:37 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-06 13:42:26 +08:00
										 |  |  |   addCanceler(requestId, canceler) { | 
					
						
							|  |  |  |     if (requestId in this.inFlightRequests) { | 
					
						
							|  |  |  |       this.inFlightRequests[requestId].push(canceler); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       this.inFlightRequests[requestId] = [canceler]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   resolveCancelerIfExists(requestId) { | 
					
						
							| 
									
										
										
										
											2018-08-29 20:27:29 +08:00
										 |  |  |     const cancelers = this.inFlightRequests[requestId]; | 
					
						
							| 
									
										
										
										
											2017-02-06 13:42:26 +08:00
										 |  |  |     if (!_.isUndefined(cancelers) && cancelers.length) { | 
					
						
							|  |  |  |       cancelers[0].resolve(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  |   datasourceRequest(options) { | 
					
						
							| 
									
										
										
										
											2018-08-29 20:27:29 +08:00
										 |  |  |     let canceler = null; | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  |     options.retry = options.retry || 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // A requestID is provided by the datasource as a unique identifier for a
 | 
					
						
							|  |  |  |     // particular query. If the requestID exists, the promise it is keyed to
 | 
					
						
							|  |  |  |     // is canceled, canceling the previous datasource request if it is still
 | 
					
						
							|  |  |  |     // in-flight.
 | 
					
						
							| 
									
										
										
										
											2018-08-29 20:27:29 +08:00
										 |  |  |     const requestId = options.requestId; | 
					
						
							| 
									
										
										
										
											2017-02-06 13:42:26 +08:00
										 |  |  |     if (requestId) { | 
					
						
							|  |  |  |       this.resolveCancelerIfExists(requestId); | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  |       // create new canceler
 | 
					
						
							| 
									
										
										
										
											2018-08-29 20:27:29 +08:00
										 |  |  |       canceler = this.$q.defer(); | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  |       options.timeout = canceler.promise; | 
					
						
							| 
									
										
										
										
											2017-02-06 13:42:26 +08:00
										 |  |  |       this.addCanceler(requestId, canceler); | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-29 20:27:29 +08:00
										 |  |  |     const requestIsLocal = !options.url.match(/^http/); | 
					
						
							|  |  |  |     const firstAttempt = options.retry === 0; | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-14 22:00:52 +08:00
										 |  |  |     if (requestIsLocal) { | 
					
						
							|  |  |  |       if (this.contextSrv.user && this.contextSrv.user.orgId) { | 
					
						
							|  |  |  |         options.headers = options.headers || {}; | 
					
						
							| 
									
										
										
										
											2017-12-20 19:33:33 +08:00
										 |  |  |         options.headers['X-Grafana-Org-Id'] = this.contextSrv.user.orgId; | 
					
						
							| 
									
										
										
										
											2017-04-14 22:00:52 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-04-14 21:47:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 19:33:33 +08:00
										 |  |  |       if (options.url.indexOf('/') === 0) { | 
					
						
							| 
									
										
										
										
											2017-04-15 01:01:08 +08:00
										 |  |  |         options.url = options.url.substring(1); | 
					
						
							| 
									
										
										
										
											2017-04-14 22:00:52 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2016-09-23 18:29:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-14 22:00:52 +08:00
										 |  |  |       if (options.headers && options.headers.Authorization) { | 
					
						
							| 
									
										
										
										
											2017-12-20 19:33:33 +08:00
										 |  |  |         options.headers['X-DS-Authorization'] = options.headers.Authorization; | 
					
						
							| 
									
										
										
										
											2017-04-14 22:00:52 +08:00
										 |  |  |         delete options.headers.Authorization; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2017-08-23 19:31:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       if (this.noBackendCache) { | 
					
						
							| 
									
										
										
										
											2017-12-20 19:33:33 +08:00
										 |  |  |         options.headers['X-Grafana-NoCache'] = 'true'; | 
					
						
							| 
									
										
										
										
											2017-08-23 19:31:26 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-19 23:06:54 +08:00
										 |  |  |     return this.$http(options) | 
					
						
							|  |  |  |       .then(response => { | 
					
						
							| 
									
										
										
										
											2018-04-20 21:28:04 +08:00
										 |  |  |         if (!options.silent) { | 
					
						
							|  |  |  |           appEvents.emit('ds-request-response', response); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-12-19 23:06:54 +08:00
										 |  |  |         return response; | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |       .catch(err => { | 
					
						
							|  |  |  |         if (err.status === this.HTTP_REQUEST_CANCELLED) { | 
					
						
							|  |  |  |           throw { err, cancelled: true }; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-19 23:06:54 +08:00
										 |  |  |         // handle unauthorized for backend requests
 | 
					
						
							|  |  |  |         if (requestIsLocal && firstAttempt && err.status === 401) { | 
					
						
							|  |  |  |           return this.loginPing().then(() => { | 
					
						
							|  |  |  |             options.retry = 1; | 
					
						
							|  |  |  |             if (canceler) { | 
					
						
							|  |  |  |               canceler.resolve(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return this.datasourceRequest(options); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-19 23:06:54 +08:00
										 |  |  |         // populate error obj on Internal Error
 | 
					
						
							|  |  |  |         if (_.isString(err.data) && err.status === 500) { | 
					
						
							|  |  |  |           err.data = { | 
					
						
							|  |  |  |             error: err.statusText, | 
					
						
							| 
									
										
										
										
											2017-12-20 19:33:33 +08:00
										 |  |  |             response: err.data, | 
					
						
							| 
									
										
										
										
											2017-12-19 23:06:54 +08:00
										 |  |  |           }; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-19 23:06:54 +08:00
										 |  |  |         // for Prometheus
 | 
					
						
							|  |  |  |         if (err.data && !err.data.message && _.isString(err.data.error)) { | 
					
						
							|  |  |  |           err.data.message = err.data.error; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-04-20 21:28:04 +08:00
										 |  |  |         if (!options.silent) { | 
					
						
							|  |  |  |           appEvents.emit('ds-request-error', err); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-12-19 23:06:54 +08:00
										 |  |  |         throw err; | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |       .finally(() => { | 
					
						
							|  |  |  |         // clean up
 | 
					
						
							|  |  |  |         if (options.requestId) { | 
					
						
							|  |  |  |           this.inFlightRequests[options.requestId].shift(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2017-04-20 17:16:37 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   loginPing() { | 
					
						
							| 
									
										
										
										
											2017-12-20 19:33:33 +08:00
										 |  |  |     return this.request({ url: '/api/login/ping', method: 'GET', retry: 1 }); | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   search(query) { | 
					
						
							| 
									
										
										
										
											2017-12-20 19:33:33 +08:00
										 |  |  |     return this.get('/api/search', query); | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 23:56:34 +08:00
										 |  |  |   getDashboardBySlug(slug) { | 
					
						
							|  |  |  |     return this.get(`/api/dashboards/db/${slug}`); | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-31 07:26:26 +08:00
										 |  |  |   getDashboardByUid(uid: string) { | 
					
						
							|  |  |  |     return this.get(`/api/dashboards/uid/${uid}`); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-02 05:32:26 +08:00
										 |  |  |   getFolderByUid(uid: string) { | 
					
						
							|  |  |  |     return this.get(`/api/folders/${uid}`); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  |   saveDashboard(dash, options) { | 
					
						
							| 
									
										
										
										
											2017-12-19 23:06:54 +08:00
										 |  |  |     options = options || {}; | 
					
						
							| 
									
										
										
										
											2017-06-05 20:56:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 19:33:33 +08:00
										 |  |  |     return this.post('/api/dashboards/db/', { | 
					
						
							| 
									
										
										
										
											2017-06-05 20:56:11 +08:00
										 |  |  |       dashboard: dash, | 
					
						
							| 
									
										
										
										
											2017-12-21 04:17:55 +08:00
										 |  |  |       folderId: options.folderId, | 
					
						
							| 
									
										
										
										
											2017-06-05 20:56:11 +08:00
										 |  |  |       overwrite: options.overwrite === true, | 
					
						
							| 
									
										
										
										
											2017-12-20 19:33:33 +08:00
										 |  |  |       message: options.message || '', | 
					
						
							| 
									
										
										
										
											2017-06-05 20:56:11 +08:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-05-26 23:17:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-02 05:32:26 +08:00
										 |  |  |   createFolder(payload: any) { | 
					
						
							|  |  |  |     return this.post('/api/folders', payload); | 
					
						
							| 
									
										
										
										
											2017-05-26 23:17:04 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-12-14 22:07:31 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 23:38:09 +08:00
										 |  |  |   deleteFolder(uid: string, showSuccessAlert) { | 
					
						
							|  |  |  |     return this.request({ method: 'DELETE', url: `/api/folders/${uid}`, showSuccessAlert: showSuccessAlert === true }); | 
					
						
							| 
									
										
										
										
											2018-02-02 05:32:26 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 23:38:09 +08:00
										 |  |  |   deleteDashboard(uid, showSuccessAlert) { | 
					
						
							|  |  |  |     return this.request({ | 
					
						
							|  |  |  |       method: 'DELETE', | 
					
						
							|  |  |  |       url: `/api/dashboards/uid/${uid}`, | 
					
						
							|  |  |  |       showSuccessAlert: showSuccessAlert === true, | 
					
						
							| 
									
										
										
										
											2017-12-19 23:06:54 +08:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2017-12-14 22:07:31 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-02 05:32:26 +08:00
										 |  |  |   deleteFoldersAndDashboards(folderUids, dashboardUids) { | 
					
						
							| 
									
										
										
										
											2017-12-14 22:07:31 +08:00
										 |  |  |     const tasks = []; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-26 23:14:40 +08:00
										 |  |  |     for (const folderUid of folderUids) { | 
					
						
							| 
									
										
										
										
											2018-02-21 23:38:09 +08:00
										 |  |  |       tasks.push(this.createTask(this.deleteFolder.bind(this), true, folderUid, true)); | 
					
						
							| 
									
										
										
										
											2018-02-02 05:32:26 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-26 23:14:40 +08:00
										 |  |  |     for (const dashboardUid of dashboardUids) { | 
					
						
							| 
									
										
										
										
											2018-02-21 23:38:09 +08:00
										 |  |  |       tasks.push(this.createTask(this.deleteDashboard.bind(this), true, dashboardUid, true)); | 
					
						
							| 
									
										
										
										
											2017-12-14 22:07:31 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return this.executeInOrder(tasks, []); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-01 00:15:00 +08:00
										 |  |  |   moveDashboards(dashboardUids, toFolder) { | 
					
						
							| 
									
										
										
										
											2017-12-14 22:07:31 +08:00
										 |  |  |     const tasks = []; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-26 23:14:40 +08:00
										 |  |  |     for (const uid of dashboardUids) { | 
					
						
							| 
									
										
										
										
											2018-02-01 00:15:00 +08:00
										 |  |  |       tasks.push(this.createTask(this.moveDashboard.bind(this), true, uid, toFolder)); | 
					
						
							| 
									
										
										
										
											2017-12-14 22:07:31 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-19 23:06:54 +08:00
										 |  |  |     return this.executeInOrder(tasks, []).then(result => { | 
					
						
							|  |  |  |       return { | 
					
						
							|  |  |  |         totalCount: result.length, | 
					
						
							|  |  |  |         successCount: _.filter(result, { succeeded: true }).length, | 
					
						
							| 
									
										
										
										
											2017-12-21 15:39:31 +08:00
										 |  |  |         alreadyInFolderCount: _.filter(result, { alreadyInFolder: true }).length, | 
					
						
							| 
									
										
										
										
											2017-12-19 23:06:54 +08:00
										 |  |  |       }; | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2017-12-14 22:07:31 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-01 00:15:00 +08:00
										 |  |  |   private moveDashboard(uid, toFolder) { | 
					
						
							| 
									
										
										
										
											2018-08-26 23:14:40 +08:00
										 |  |  |     const deferred = this.$q.defer(); | 
					
						
							| 
									
										
										
										
											2017-12-14 22:07:31 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-01 00:15:00 +08:00
										 |  |  |     this.getDashboardByUid(uid).then(fullDash => { | 
					
						
							| 
									
										
										
										
											2017-12-14 22:07:31 +08:00
										 |  |  |       const model = new DashboardModel(fullDash.dashboard, fullDash.meta); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-21 15:39:31 +08:00
										 |  |  |       if ((!fullDash.meta.folderId && toFolder.id === 0) || fullDash.meta.folderId === toFolder.id) { | 
					
						
							| 
									
										
										
										
											2017-12-19 23:06:54 +08:00
										 |  |  |         deferred.resolve({ alreadyInFolder: true }); | 
					
						
							| 
									
										
										
										
											2017-12-14 22:07:31 +08:00
										 |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const clone = model.getSaveModelClone(); | 
					
						
							| 
									
										
										
										
											2018-08-26 23:14:40 +08:00
										 |  |  |       const options = { | 
					
						
							| 
									
										
										
										
											2017-12-21 04:17:55 +08:00
										 |  |  |         folderId: toFolder.id, | 
					
						
							|  |  |  |         overwrite: false, | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2017-12-14 22:07:31 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-21 04:17:55 +08:00
										 |  |  |       this.saveDashboard(clone, options) | 
					
						
							| 
									
										
										
										
											2017-12-14 22:07:31 +08:00
										 |  |  |         .then(() => { | 
					
						
							| 
									
										
										
										
											2017-12-19 23:06:54 +08:00
										 |  |  |           deferred.resolve({ succeeded: true }); | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         .catch(err => { | 
					
						
							| 
									
										
										
										
											2017-12-20 19:33:33 +08:00
										 |  |  |           if (err.data && err.data.status === 'plugin-dashboard') { | 
					
						
							| 
									
										
										
										
											2017-12-14 23:51:23 +08:00
										 |  |  |             err.isHandled = true; | 
					
						
							| 
									
										
										
										
											2017-12-21 04:17:55 +08:00
										 |  |  |             options.overwrite = true; | 
					
						
							| 
									
										
										
										
											2017-12-14 23:51:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-21 04:17:55 +08:00
										 |  |  |             this.saveDashboard(clone, options) | 
					
						
							| 
									
										
										
										
											2017-12-14 23:51:23 +08:00
										 |  |  |               .then(() => { | 
					
						
							| 
									
										
										
										
											2017-12-19 23:06:54 +08:00
										 |  |  |                 deferred.resolve({ succeeded: true }); | 
					
						
							|  |  |  |               }) | 
					
						
							|  |  |  |               .catch(err => { | 
					
						
							|  |  |  |                 deferred.resolve({ succeeded: false }); | 
					
						
							| 
									
										
										
										
											2017-12-14 23:51:23 +08:00
										 |  |  |               }); | 
					
						
							|  |  |  |           } else { | 
					
						
							| 
									
										
										
										
											2017-12-19 23:06:54 +08:00
										 |  |  |             deferred.resolve({ succeeded: false }); | 
					
						
							| 
									
										
										
										
											2017-12-14 23:51:23 +08:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2017-12-14 22:07:31 +08:00
										 |  |  |         }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return deferred.promise; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   private createTask(fn, ignoreRejections, ...args: any[]) { | 
					
						
							| 
									
										
										
										
											2017-12-19 23:06:54 +08:00
										 |  |  |     return result => { | 
					
						
							|  |  |  |       return fn | 
					
						
							|  |  |  |         .apply(null, args) | 
					
						
							| 
									
										
										
										
											2017-12-14 22:07:31 +08:00
										 |  |  |         .then(res => { | 
					
						
							|  |  |  |           return Array.prototype.concat(result, [res]); | 
					
						
							| 
									
										
										
										
											2017-12-19 23:06:54 +08:00
										 |  |  |         }) | 
					
						
							|  |  |  |         .catch(err => { | 
					
						
							| 
									
										
										
										
											2017-12-14 22:07:31 +08:00
										 |  |  |           if (ignoreRejections) { | 
					
						
							|  |  |  |             return result; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           throw err; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   private executeInOrder(tasks, initialValue) { | 
					
						
							|  |  |  |     return tasks.reduce(this.$q.when, initialValue); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-06-16 16:48:26 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-20 19:33:33 +08:00
										 |  |  | coreModule.service('backendSrv', BackendSrv); | 
					
						
							| 
									
										
										
										
											2018-07-12 02:23:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Code below is to expore the service to react components
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | let singletonInstance: BackendSrv; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export function setBackendSrv(instance: BackendSrv) { | 
					
						
							|  |  |  |   singletonInstance = instance; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export function getBackendSrv(): BackendSrv { | 
					
						
							|  |  |  |   return singletonInstance; | 
					
						
							|  |  |  | } |