Commit 9b63a817 by Patrick O'Carroll

migrated files to ts + fixed specfile

parent af34f997
import './dashboard_ctrl';
import './alerting_srv';
import './history/history';
import './dashboardLoaderSrv';
import './dashboard_loader_srv';
import './dashnav/dashnav';
import './submenu/submenu';
import './save_as_modal';
import './save_modal';
import './shareModalCtrl';
import './shareSnapshotCtrl';
import './share_snapshot_ctrl';
import './dashboard_srv';
import './view_state_srv';
import './validation_srv';
import './time_srv';
import './unsavedChangesSrv';
import './unsaved_changes_srv';
import './unsaved_changes_modal';
import './timepicker/timepicker';
import './upload';
......
define([
'angular',
'moment',
'lodash',
'jquery',
'app/core/utils/kbn',
'app/core/utils/datemath',
'app/core/services/impression_srv'
],
function (angular, moment, _, $, kbn, dateMath, impressionSrv) {
'use strict';
kbn = kbn.default;
impressionSrv = impressionSrv.default;
var module = angular.module('grafana.services');
module.service('dashboardLoaderSrv', function(backendSrv,
dashboardSrv,
datasourceSrv,
$http, $q, $timeout,
contextSrv, $routeParams,
$rootScope) {
var self = this;
this._dashboardLoadFailed = function(title, snapshot) {
snapshot = snapshot || false;
return {
meta: { canStar: false, isSnapshot: snapshot, canDelete: false, canSave: false, canEdit: false, dashboardNotFound: true },
dashboard: {title: title }
};
};
this.loadDashboard = function(type, slug) {
var promise;
if (type === 'script') {
promise = this._loadScriptedDashboard(slug);
} else if (type === 'snapshot') {
promise = backendSrv.get('/api/snapshots/' + $routeParams.slug)
.catch(function() {
return self._dashboardLoadFailed("Snapshot not found", true);
});
} else {
promise = backendSrv.getDashboard($routeParams.type, $routeParams.slug)
.then(function(result) {
if (result.meta.isFolder) {
$rootScope.appEvent("alert-error", ['Dashboard not found']);
throw new Error("Dashboard not found");
}
return result;
})
.catch(function() {
return self._dashboardLoadFailed("Not found");
});
}
promise.then(function(result) {
if (result.meta.dashboardNotFound !== true) {
impressionSrv.addDashboardImpression(result.dashboard.id);
}
return result;
});
return promise;
};
this._loadScriptedDashboard = function(file) {
var url = 'public/dashboards/'+file.replace(/\.(?!js)/,"/") + '?' + new Date().getTime();
return $http({ url: url, method: "GET" })
.then(this._executeScript).then(function(result) {
return { meta: { fromScript: true, canDelete: false, canSave: false, canStar: false}, dashboard: result.data };
}, function(err) {
console.log('Script dashboard error '+ err);
$rootScope.appEvent('alert-error', ["Script Error", "Please make sure it exists and returns a valid dashboard"]);
return self._dashboardLoadFailed('Scripted dashboard');
});
};
this._executeScript = function(result) {
var services = {
dashboardSrv: dashboardSrv,
datasourceSrv: datasourceSrv,
$q: $q,
};
/*jshint -W054 */
var script_func = new Function('ARGS','kbn','dateMath','_','moment','window','document','$','jQuery', 'services', result.data);
var script_result = script_func($routeParams, kbn, dateMath, _ , moment, window, document, $, $, services);
// Handle async dashboard scripts
if (_.isFunction(script_result)) {
var deferred = $q.defer();
script_result(function(dashboard) {
$timeout(function() {
deferred.resolve({ data: dashboard });
});
});
return deferred.promise;
}
return { data: script_result };
};
});
});
import angular from 'angular';
import moment from 'moment';
import _ from 'lodash';
import $ from 'jquery';
import kbn from 'app/core/utils/kbn';
import * as dateMath from 'app/core/utils/datemath';
import impressionSrv from 'app/core/services/impression_srv';
export class DashboardLoaderSrv {
/** @ngInject */
constructor(
private backendSrv,
private dashboardSrv,
private datasourceSrv,
private $http,
private $q,
private $timeout,
contextSrv,
private $routeParams,
private $rootScope
) {}
_dashboardLoadFailed(title, snapshot) {
snapshot = snapshot || false;
return {
meta: {
canStar: false,
isSnapshot: snapshot,
canDelete: false,
canSave: false,
canEdit: false,
dashboardNotFound: true,
},
dashboard: { title: title },
};
}
loadDashboard(type, slug) {
var promise;
if (type === 'script') {
promise = this._loadScriptedDashboard(slug);
} else if (type === 'snapshot') {
promise = this.backendSrv
.get('/api/snapshots/' + this.$routeParams.slug)
.catch(() => {
return this._dashboardLoadFailed('Snapshot not found', true);
});
} else {
promise = this.backendSrv
.getDashboard(this.$routeParams.type, this.$routeParams.slug)
.then(result => {
if (result.meta.isFolder) {
this.$rootScope.appEvent('alert-error', ['Dashboard not found']);
throw new Error('Dashboard not found');
}
return result;
})
.catch(() => {
return this._dashboardLoadFailed('Not found', true);
});
}
promise.then(function(result) {
if (result.meta.dashboardNotFound !== true) {
impressionSrv.addDashboardImpression(result.dashboard.id);
}
return result;
});
return promise;
}
_loadScriptedDashboard(file) {
var url =
'public/dashboards/' +
file.replace(/\.(?!js)/, '/') +
'?' +
new Date().getTime();
return this.$http({ url: url, method: 'GET' })
.then(this._executeScript)
.then(
function(result) {
return {
meta: {
fromScript: true,
canDelete: false,
canSave: false,
canStar: false,
},
dashboard: result.data,
};
},
function(err) {
console.log('Script dashboard error ' + err);
this.$rootScope.appEvent('alert-error', [
'Script Error',
'Please make sure it exists and returns a valid dashboard',
]);
return this._dashboardLoadFailed('Scripted dashboard');
}
);
}
_executeScript(result) {
var services = {
dashboardSrv: this.dashboardSrv,
datasourceSrv: this.datasourceSrv,
$q: this.$q,
};
/*jshint -W054 */
var script_func = new Function(
'ARGS',
'kbn',
'dateMath',
'_',
'moment',
'window',
'document',
'$',
'jQuery',
'services',
result.data
);
var script_result = script_func(
this.$routeParams,
kbn,
dateMath,
_,
moment,
window,
document,
$,
$,
services
);
// Handle async dashboard scripts
if (_.isFunction(script_result)) {
var deferred = this.$q.defer();
script_result(dashboard => {
this.$timeout(() => {
deferred.resolve({ data: dashboard });
});
});
return deferred.promise;
}
return { data: script_result };
}
}
angular
.module('grafana.services')
.service('dashboardLoaderSrv', DashboardLoaderSrv);
define([
'angular',
'lodash',
],
function (angular, _) {
'use strict';
var module = angular.module('grafana.controllers');
module.controller('ShareSnapshotCtrl', function($scope, $rootScope, $location, backendSrv, $timeout, timeSrv) {
import angular from 'angular';
import _ from 'lodash';
export class ShareSnapshotCtrl {
constructor($scope, $rootScope, $location, backendSrv, $timeout, timeSrv) {
$scope.snapshot = {
name: $scope.dashboard.title,
expires: 0,
......@@ -18,16 +12,16 @@ function (angular, _) {
$scope.step = 1;
$scope.expireOptions = [
{text: '1 Hour', value: 60*60},
{text: '1 Day', value: 60*60*24},
{text: '7 Days', value: 60*60*24*7},
{text: 'Never', value: 0},
{ text: '1 Hour', value: 60 * 60 },
{ text: '1 Day', value: 60 * 60 * 24 },
{ text: '7 Days', value: 60 * 60 * 24 * 7 },
{ text: 'Never', value: 0 },
];
$scope.accessOptions = [
{text: 'Anyone with the link', value: 1},
{text: 'Organization users', value: 2},
{text: 'Public on the web', value: 3},
{ text: 'Anyone with the link', value: 1 },
{ text: 'Organization users', value: 2 },
{ text: 'Public on the web', value: 3 },
];
$scope.init = function() {
......@@ -42,7 +36,7 @@ function (angular, _) {
$scope.createSnapshot = function(external) {
$scope.dashboard.snapshot = {
timestamp: new Date()
timestamp: new Date(),
};
if (!external) {
......@@ -69,31 +63,37 @@ function (angular, _) {
expires: $scope.snapshot.expires,
};
var postUrl = external ? $scope.externalUrl + $scope.apiUrl : $scope.apiUrl;
backendSrv.post(postUrl, cmdData).then(function(results) {
$scope.loading = false;
if (external) {
$scope.deleteUrl = results.deleteUrl;
$scope.snapshotUrl = results.url;
$scope.saveExternalSnapshotRef(cmdData, results);
} else {
var url = $location.url();
var baseUrl = $location.absUrl();
if (url !== '/') {
baseUrl = baseUrl.replace(url, '') + '/';
var postUrl = external
? $scope.externalUrl + $scope.apiUrl
: $scope.apiUrl;
backendSrv.post(postUrl, cmdData).then(
function(results) {
$scope.loading = false;
if (external) {
$scope.deleteUrl = results.deleteUrl;
$scope.snapshotUrl = results.url;
$scope.saveExternalSnapshotRef(cmdData, results);
} else {
var url = $location.url();
var baseUrl = $location.absUrl();
if (url !== '/') {
baseUrl = baseUrl.replace(url, '') + '/';
}
$scope.snapshotUrl = baseUrl + 'dashboard/snapshot/' + results.key;
$scope.deleteUrl =
baseUrl + 'api/snapshots-delete/' + results.deleteKey;
}
$scope.snapshotUrl = baseUrl + 'dashboard/snapshot/' + results.key;
$scope.deleteUrl = baseUrl + 'api/snapshots-delete/' + results.deleteKey;
$scope.step = 2;
},
function() {
$scope.loading = false;
}
$scope.step = 2;
}, function() {
$scope.loading = false;
});
);
};
$scope.getSnapshotUrl = function() {
......@@ -116,21 +116,22 @@ function (angular, _) {
// remove annotation queries
dash.annotations.list = _.chain(dash.annotations.list)
.filter(function(annotation) {
return annotation.enable;
})
.map(function(annotation) {
return {
name: annotation.name,
enable: annotation.enable,
iconColor: annotation.iconColor,
snapshotData: annotation.snapshotData
};
}).value();
.filter(function(annotation) {
return annotation.enable;
})
.map(function(annotation) {
return {
name: annotation.name,
enable: annotation.enable,
iconColor: annotation.iconColor,
snapshotData: annotation.snapshotData,
};
})
.value();
// remove template queries
_.each(dash.templating.list, function(variable) {
variable.query = "";
variable.query = '';
variable.options = variable.current;
variable.refresh = false;
});
......@@ -168,7 +169,9 @@ function (angular, _) {
cmdData.deleteKey = results.deleteKey;
backendSrv.post('/api/snapshots/', cmdData);
};
}
}
});
});
angular
.module('grafana.controllers')
.controller('ShareSnapshotCtrl', ShareSnapshotCtrl);
......@@ -6,14 +6,17 @@ import {
sinon,
angularMocks,
} from 'test/lib/common';
import 'app/features/dashboard/unsavedChangesSrv';
import { Tracker } from 'app/features/dashboard/unsaved_changes_srv';
import 'app/features/dashboard/dashboard_srv';
import { contextSrv } from 'app/core/core';
describe('unsavedChangesSrv', function() {
var _unsavedChangesSrv;
var _dashboardSrv;
var _contextSrvStub = { isEditor: true };
var _rootScope;
var _location;
var _timeout;
var _window;
var tracker;
var dash;
var scope;
......@@ -32,11 +35,15 @@ describe('unsavedChangesSrv', function() {
unsavedChangesSrv,
$location,
$rootScope,
dashboardSrv
dashboardSrv,
$timeout,
$window
) {
_unsavedChangesSrv = unsavedChangesSrv;
_dashboardSrv = dashboardSrv;
_rootScope = $rootScope;
_location = $location;
_timeout = $timeout;
_window = $window;
})
);
......@@ -54,7 +61,16 @@ describe('unsavedChangesSrv', function() {
scope.appEvent = sinon.spy();
scope.onAppEvent = sinon.spy();
tracker = new _unsavedChangesSrv.Tracker(dash, scope);
tracker = new Tracker(
dash,
scope,
undefined,
_location,
_window,
_timeout,
contextSrv,
_rootScope
);
});
it('No changes should not have changes', function() {
......
define([
'angular',
'lodash',
],
function(angular, _) {
'use strict';
var module = angular.module('grafana.services');
module.service('unsavedChangesSrv', function($rootScope, $q, $location, $timeout, contextSrv, dashboardSrv, $window) {
function Tracker(dashboard, scope, originalCopyDelay) {
var self = this;
this.current = dashboard;
this.originalPath = $location.path();
this.scope = scope;
// register events
scope.onAppEvent('dashboard-saved', function() {
this.original = this.current.getSaveModelClone();
this.originalPath = $location.path();
}.bind(this));
$window.onbeforeunload = function() {
if (self.ignoreChanges()) { return; }
if (self.hasChanges()) {
return "There are unsaved changes to this dashboard";
}
};
scope.$on("$locationChangeStart", function(event, next) {
// check if we should look for changes
if (self.originalPath === $location.path()) { return true; }
if (self.ignoreChanges()) { return true; }
if (self.hasChanges()) {
event.preventDefault();
self.next = next;
$timeout(function() {
self.open_modal();
});
}
});
if (originalCopyDelay) {
$timeout(function() {
// wait for different services to patch the dashboard (missing properties)
self.original = dashboard.getSaveModelClone();
}, originalCopyDelay);
} else {
self.original = dashboard.getSaveModelClone();
}
}
var p = Tracker.prototype;
// for some dashboards and users
// changes should be ignored
p.ignoreChanges = function() {
if (!this.original) { return true; }
if (!contextSrv.isEditor) { return true; }
if (!this.current || !this.current.meta) { return true; }
var meta = this.current.meta;
return !meta.canSave || meta.fromScript || meta.fromFile;
};
// remove stuff that should not count in diff
p.cleanDashboardFromIgnoredChanges = function(dash) {
// ignore time and refresh
dash.time = 0;
dash.refresh = 0;
dash.schemaVersion = 0;
// filter row and panels properties that should be ignored
dash.rows = _.filter(dash.rows, function(row) {
if (row.repeatRowId) {
return false;
}
row.panels = _.filter(row.panels, function(panel) {
if (panel.repeatPanelId) {
return false;
}
// remove scopedVars
panel.scopedVars = null;
// ignore span changes
panel.span = null;
// ignore panel legend sort
if (panel.legend) {
delete panel.legend.sort;
delete panel.legend.sortDesc;
}
return true;
});
// ignore collapse state
row.collapse = false;
return true;
});
dash.panels = _.filter(dash.panels, function(panel) {
if (panel.repeatPanelId) {
return false;
}
// remove scopedVars
panel.scopedVars = null;
// ignore panel legend sort
if (panel.legend) {
delete panel.legend.sort;
delete panel.legend.sortDesc;
}
return true;
});
// ignore template variable values
_.each(dash.templating.list, function(value) {
value.current = null;
value.options = null;
value.filters = null;
});
};
p.hasChanges = function() {
var current = this.current.getSaveModelClone();
var original = this.original;
this.cleanDashboardFromIgnoredChanges(current);
this.cleanDashboardFromIgnoredChanges(original);
var currentTimepicker = _.find(current.nav, { type: 'timepicker' });
var originalTimepicker = _.find(original.nav, { type: 'timepicker' });
if (currentTimepicker && originalTimepicker) {
currentTimepicker.now = originalTimepicker.now;
}
var currentJson = angular.toJson(current);
var originalJson = angular.toJson(original);
return currentJson !== originalJson;
};
p.discardChanges = function() {
this.original = null;
this.gotoNext();
};
p.open_modal = function() {
$rootScope.appEvent('show-modal', {
templateHtml: '<unsaved-changes-modal dismiss="dismiss()"></unsaved-changes-modal>',
modalClass: 'modal--narrow confirm-modal'
});
};
p.saveChanges = function() {
var self = this;
var cancel = $rootScope.$on('dashboard-saved', function() {
cancel();
$timeout(function() {
self.gotoNext();
});
});
$rootScope.appEvent('save-dashboard');
};
p.gotoNext = function() {
var baseLen = $location.absUrl().length - $location.url().length;
var nextUrl = this.next.substring(baseLen);
$location.url(nextUrl);
};
this.Tracker = Tracker;
this.init = function(dashboard, scope) {
this.tracker = new Tracker(dashboard, scope, 1000);
return this.tracker;
};
});
});
import angular from 'angular';
import _ from 'lodash';
export class Tracker {
current: any;
originalPath: any;
scope: any;
original: any;
next: any;
$window: any;
/** @ngInject */
constructor(
dashboard,
scope,
originalCopyDelay,
private $location,
$window,
private $timeout,
private contextSrv,
private $rootScope
) {
this.$location = $location;
this.$window = $window;
this.current = dashboard;
this.originalPath = $location.path();
this.scope = scope;
// register events
scope.onAppEvent('dashboard-saved', () => {
this.original = this.current.getSaveModelClone();
this.originalPath = $location.path();
});
$window.onbeforeunload = () => {
if (this.ignoreChanges()) {
return '';
}
if (this.hasChanges()) {
return 'There are unsaved changes to this dashboard';
}
return '';
};
scope.$on('$locationChangeStart', (event, next) => {
// check if we should look for changes
if (this.originalPath === $location.path()) {
return true;
}
if (this.ignoreChanges()) {
return true;
}
if (this.hasChanges()) {
event.preventDefault();
this.next = next;
this.$timeout(() => {
this.open_modal();
});
}
return false;
});
if (originalCopyDelay) {
this.$timeout(() => {
// wait for different services to patch the dashboard (missing properties)
this.original = dashboard.getSaveModelClone();
}, originalCopyDelay);
} else {
this.original = dashboard.getSaveModelClone();
}
}
// for some dashboards and users
// changes should be ignored
ignoreChanges() {
if (!this.original) {
return true;
}
if (!this.contextSrv.isEditor) {
return true;
}
if (!this.current || !this.current.meta) {
return true;
}
var meta = this.current.meta;
return !meta.canSave || meta.fromScript || meta.fromFile;
}
// remove stuff that should not count in diff
cleanDashboardFromIgnoredChanges(dash) {
// ignore time and refresh
dash.time = 0;
dash.refresh = 0;
dash.schemaVersion = 0;
// filter row and panels properties that should be ignored
dash.rows = _.filter(dash.rows, function(row) {
if (row.repeatRowId) {
return false;
}
row.panels = _.filter(row.panels, function(panel) {
if (panel.repeatPanelId) {
return false;
}
// remove scopedVars
panel.scopedVars = null;
// ignore span changes
panel.span = null;
// ignore panel legend sort
if (panel.legend) {
delete panel.legend.sort;
delete panel.legend.sortDesc;
}
return true;
});
// ignore collapse state
row.collapse = false;
return true;
});
dash.panels = _.filter(dash.panels, panel => {
if (panel.repeatPanelId) {
return false;
}
// remove scopedVars
panel.scopedVars = null;
// ignore panel legend sort
if (panel.legend) {
delete panel.legend.sort;
delete panel.legend.sortDesc;
}
return true;
});
// ignore template variable values
_.each(dash.templating.list, function(value) {
value.current = null;
value.options = null;
value.filters = null;
});
}
hasChanges() {
var current = this.current.getSaveModelClone();
var original = this.original;
this.cleanDashboardFromIgnoredChanges(current);
this.cleanDashboardFromIgnoredChanges(original);
var currentTimepicker = _.find(current.nav, { type: 'timepicker' });
var originalTimepicker = _.find(original.nav, { type: 'timepicker' });
if (currentTimepicker && originalTimepicker) {
currentTimepicker.now = originalTimepicker.now;
}
var currentJson = angular.toJson(current);
var originalJson = angular.toJson(original);
return currentJson !== originalJson;
}
discardChanges() {
this.original = null;
this.gotoNext();
}
open_modal() {
this.$rootScope.appEvent('show-modal', {
templateHtml:
'<unsaved-changes-modal dismiss="dismiss()"></unsaved-changes-modal>',
modalClass: 'modal--narrow confirm-modal',
});
}
saveChanges() {
var self = this;
var cancel = this.$rootScope.$on('dashboard-saved', () => {
cancel();
this.$timeout(() => {
self.gotoNext();
});
});
this.$rootScope.appEvent('save-dashboard');
}
gotoNext() {
var baseLen = this.$location.absUrl().length - this.$location.url().length;
var nextUrl = this.next.substring(baseLen);
this.$location.url(nextUrl);
}
}
/** @ngInject */
export function unsavedChangesSrv(
$rootScope,
$q,
$location,
$timeout,
contextSrv,
dashboardSrv,
$window
) {
this.Tracker = Tracker;
this.init = function(dashboard, scope) {
this.tracker = new Tracker(
dashboard,
scope,
1000,
$location,
$window,
$timeout,
contextSrv,
$rootScope
);
return this.tracker;
};
}
angular
.module('grafana.services')
.service('unsavedChangesSrv', unsavedChangesSrv);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment