diff --git a/public/app/core/services/backend_srv.ts b/public/app/core/services/backend_srv.ts index 0d7d098dcea..31db2a4bdee 100644 --- a/public/app/core/services/backend_srv.ts +++ b/public/app/core/services/backend_srv.ts @@ -1,46 +1,55 @@ +// @ts-ignore import _ from 'lodash'; +import angular from 'angular'; import coreModule from 'app/core/core_module'; import appEvents from 'app/core/app_events'; import config from 'app/core/config'; import { DashboardModel } from 'app/features/dashboard/state/DashboardModel'; import { DashboardSearchHit } from 'app/types/search'; +import { ContextSrv } from './context_srv'; +import { FolderInfo, DashboardDTO } from 'app/types'; export class BackendSrv { - private inFlightRequests = {}; + private inFlightRequests: { [key: string]: Array> } = {}; private HTTP_REQUEST_CANCELED = -1; private noBackendCache: boolean; /** @ngInject */ - constructor(private $http, private $q, private $timeout, private contextSrv) {} + constructor( + private $http: any, + private $q: angular.IQService, + private $timeout: angular.ITimeoutService, + private contextSrv: ContextSrv + ) {} - get(url, params?) { - return this.request({ method: 'GET', url: url, params: params }); + get(url: string, params?: any) { + return this.request({ method: 'GET', url, params }); } - delete(url) { - return this.request({ method: 'DELETE', url: url }); + delete(url: string) { + return this.request({ method: 'DELETE', url }); } - post(url, data) { - return this.request({ method: 'POST', url: url, data: data }); + post(url: string, data: any) { + return this.request({ method: 'POST', url, data }); } - patch(url, data) { - return this.request({ method: 'PATCH', url: url, data: data }); + patch(url: string, data: any) { + return this.request({ method: 'PATCH', url, data }); } - put(url, data) { - return this.request({ method: 'PUT', url: url, data: data }); + put(url: string, data: any) { + return this.request({ method: 'PUT', url, data }); } - withNoBackendCache(callback) { + withNoBackendCache(callback: any) { this.noBackendCache = true; return callback().finally(() => { this.noBackendCache = false; }); } - requestErrorHandler(err) { + requestErrorHandler(err: any) { if (err.isHandled) { return; } @@ -75,7 +84,7 @@ export class BackendSrv { throw data; } - request(options) { + request(options: any) { options.retry = options.retry || 0; const requestIsLocal = !options.url.match(/^http/); const firstAttempt = options.retry === 0; @@ -92,7 +101,7 @@ export class BackendSrv { } return this.$http(options).then( - results => { + (results: any) => { if (options.method !== 'GET') { if (results && results.data.message) { if (options.showSuccessAlert !== false) { @@ -102,7 +111,7 @@ export class BackendSrv { } return results.data; }, - err => { + (err: any) => { // handle unauthorized if (err.status === 401 && this.contextSrv.user.isSignedIn && firstAttempt) { return this.loginPing() @@ -110,7 +119,7 @@ export class BackendSrv { options.retry = 1; return this.request(options); }) - .catch(err => { + .catch((err: any) => { if (err.status === 401) { window.location.href = config.appSubUrl + '/logout'; throw err; @@ -124,7 +133,7 @@ export class BackendSrv { ); } - addCanceler(requestId, canceler) { + addCanceler(requestId: string, canceler: angular.IDeferred) { if (requestId in this.inFlightRequests) { this.inFlightRequests[requestId].push(canceler); } else { @@ -132,15 +141,15 @@ export class BackendSrv { } } - resolveCancelerIfExists(requestId) { + resolveCancelerIfExists(requestId: string) { const cancelers = this.inFlightRequests[requestId]; if (!_.isUndefined(cancelers) && cancelers.length) { cancelers[0].resolve(); } } - datasourceRequest(options) { - let canceler = null; + datasourceRequest(options: any) { + let canceler: angular.IDeferred = null; options.retry = options.retry || 0; // A requestID is provided by the datasource as a unique identifier for a @@ -180,13 +189,13 @@ export class BackendSrv { } return this.$http(options) - .then(response => { + .then((response: any) => { if (!options.silent) { appEvents.emit('ds-request-response', response); } return response; }) - .catch(err => { + .catch((err: any) => { if (err.status === this.HTTP_REQUEST_CANCELED) { throw { err, cancelled: true }; } @@ -201,7 +210,7 @@ export class BackendSrv { } return this.datasourceRequest(options); }) - .catch(err => { + .catch((err: any) => { if (err.status === 401) { window.location.href = config.appSubUrl + '/logout'; throw err; @@ -238,11 +247,11 @@ export class BackendSrv { return this.request({ url: '/api/login/ping', method: 'GET', retry: 1 }); } - search(query): Promise { + search(query: any): Promise { return this.get('/api/search', query); } - getDashboardBySlug(slug) { + getDashboardBySlug(slug: string) { return this.get(`/api/dashboards/db/${slug}`); } @@ -254,7 +263,7 @@ export class BackendSrv { return this.get(`/api/folders/${uid}`); } - saveDashboard(dash, options) { + saveDashboard(dash: DashboardModel, options: any) { options = options || {}; return this.post('/api/dashboards/db/', { @@ -269,11 +278,11 @@ export class BackendSrv { return this.post('/api/folders', payload); } - deleteFolder(uid: string, showSuccessAlert) { + deleteFolder(uid: string, showSuccessAlert: boolean) { return this.request({ method: 'DELETE', url: `/api/folders/${uid}`, showSuccessAlert: showSuccessAlert === true }); } - deleteDashboard(uid, showSuccessAlert) { + deleteDashboard(uid: string, showSuccessAlert: boolean) { return this.request({ method: 'DELETE', url: `/api/dashboards/uid/${uid}`, @@ -281,7 +290,7 @@ export class BackendSrv { }); } - deleteFoldersAndDashboards(folderUids, dashboardUids) { + deleteFoldersAndDashboards(folderUids: string[], dashboardUids: string[]) { const tasks = []; for (const folderUid of folderUids) { @@ -295,14 +304,14 @@ export class BackendSrv { return this.executeInOrder(tasks, []); } - moveDashboards(dashboardUids, toFolder) { + moveDashboards(dashboardUids: string[], toFolder: FolderInfo) { const tasks = []; for (const uid of dashboardUids) { tasks.push(this.createTask(this.moveDashboard.bind(this), true, uid, toFolder)); } - return this.executeInOrder(tasks, []).then(result => { + return this.executeInOrder(tasks, []).then((result: any) => { return { totalCount: result.length, successCount: _.filter(result, { succeeded: true }).length, @@ -311,10 +320,10 @@ export class BackendSrv { }); } - private moveDashboard(uid, toFolder) { + private moveDashboard(uid: string, toFolder: FolderInfo) { const deferred = this.$q.defer(); - this.getDashboardByUid(uid).then(fullDash => { + this.getDashboardByUid(uid).then((fullDash: DashboardDTO) => { const model = new DashboardModel(fullDash.dashboard, fullDash.meta); if ((!fullDash.meta.folderId && toFolder.id === 0) || fullDash.meta.folderId === toFolder.id) { @@ -332,7 +341,7 @@ export class BackendSrv { .then(() => { deferred.resolve({ succeeded: true }); }) - .catch(err => { + .catch((err: any) => { if (err.data && err.data.status === 'plugin-dashboard') { err.isHandled = true; options.overwrite = true; @@ -341,7 +350,7 @@ export class BackendSrv { .then(() => { deferred.resolve({ succeeded: true }); }) - .catch(err => { + .catch((err: any) => { deferred.resolve({ succeeded: false }); }); } else { @@ -353,14 +362,14 @@ export class BackendSrv { return deferred.promise; } - private createTask(fn, ignoreRejections, ...args: any[]) { - return result => { + private createTask(fn: Function, ignoreRejections: boolean, ...args: any[]) { + return (result: any) => { return fn .apply(null, args) - .then(res => { + .then((res: any) => { return Array.prototype.concat(result, [res]); }) - .catch(err => { + .catch((err: any) => { if (ignoreRejections) { return result; } @@ -370,7 +379,7 @@ export class BackendSrv { }; } - private executeInOrder(tasks, initialValue) { + private executeInOrder(tasks: any[], initialValue: any[]) { return tasks.reduce(this.$q.when, initialValue); } } diff --git a/public/app/core/specs/backend_srv.test.ts b/public/app/core/specs/backend_srv.test.ts index a6cb5a7d331..f7af6c89e32 100644 --- a/public/app/core/specs/backend_srv.test.ts +++ b/public/app/core/specs/backend_srv.test.ts @@ -1,4 +1,6 @@ +import angular from 'angular'; import { BackendSrv } from 'app/core/services/backend_srv'; +import { ContextSrv } from '../services/context_srv'; jest.mock('app/core/store'); describe('backend_srv', () => { @@ -9,7 +11,12 @@ describe('backend_srv', () => { return Promise.resolve({}); }; - const _backendSrv = new BackendSrv(_httpBackend, {}, {}, {}); + const _backendSrv = new BackendSrv( + _httpBackend, + {} as angular.IQService, + {} as angular.ITimeoutService, + {} as ContextSrv + ); describe('when handling errors', () => { it('should return the http status code', async () => {