diff --git a/.gitignore b/.gitignore index b52ecff18b8..8abd0d17cbd 100644 --- a/.gitignore +++ b/.gitignore @@ -30,4 +30,3 @@ conf/custom.ini fig.yml profile.cov grafana -tsconfig.json diff --git a/public/test/karma.conf.js b/karma.conf.js similarity index 67% rename from public/test/karma.conf.js rename to karma.conf.js index 6b51d1a5a1e..569cf845b16 100644 --- a/public/test/karma.conf.js +++ b/karma.conf.js @@ -2,14 +2,16 @@ module.exports = function(config) { 'use strict'; config.set({ - basePath: '../../', + basePath: __dirname + '/public_gen', frameworks: ['mocha', 'requirejs', 'expect', 'sinon'], // list of files / patterns to load in the browser files: [ - 'public/test/test-main.js', - {pattern: 'public_gen/**/*.js', included: false} + 'test/test-main.js', + {pattern: 'app/**/*.js', included: false}, + {pattern: 'vendor/**/*.js', included: false}, + {pattern: 'test/**/*.js', included: false} ], // list of files to exclude diff --git a/public/app/app.js b/public/app/app.js index 022d972511a..01f79883e84 100644 --- a/public/app/app.js +++ b/public/app/app.js @@ -12,7 +12,7 @@ define([ 'angular-ui', 'extend-jquery', 'bindonce', - './core/core', + 'app/core/core', ], function (angular, $, _, appLevelRequire) { "use strict"; @@ -70,10 +70,10 @@ function (angular, $, _, appLevelRequire) { }); var preBootRequires = [ - 'services/all', - 'features/all', - 'controllers/all', - 'components/partials', + 'app/services/all', + 'app/features/all', + 'app/controllers/all', + 'app/components/partials', ]; app.boot = function() { diff --git a/public/app/components/extend-jquery.js b/public/app/components/extend-jquery.js index f44245103b5..449afcf2019 100644 --- a/public/app/components/extend-jquery.js +++ b/public/app/components/extend-jquery.js @@ -2,9 +2,6 @@ define(['jquery', 'angular', 'lodash'], function ($, angular, _) { 'use strict'; - /** - * jQuery extensions - */ var $win = $(window); $.fn.place_tt = (function () { diff --git a/public/app/components/require.config.js b/public/app/components/require.config.js index f255418414e..074df7cbefe 100644 --- a/public/app/components/require.config.js +++ b/public/app/components/require.config.js @@ -1,51 +1,50 @@ require.config({ urlArgs: 'bust=' + (new Date().getTime()), - baseUrl: 'public/app', + baseUrl: 'public', paths: { - config: 'components/config', - settings: 'components/settings', - kbn: 'components/kbn', - store: 'components/store', + config: 'app/components/config', + settings: 'app/components/settings', + kbn: 'app/components/kbn', + store: 'app/components/store', + 'extend-jquery': 'app/components/extend-jquery', + lodash: 'app/components/lodash.extended', - text: '../vendor/requirejs-text/text', - moment: '../vendor/moment', - filesaver: '../vendor/filesaver', - ZeroClipboard: '../vendor/ZeroClipboard', - angular: '../vendor/angular/angular', - 'angular-route': '../vendor/angular-route/angular-route', - 'angular-sanitize': '../vendor/angular-sanitize/angular-sanitize', - 'angular-dragdrop': '../vendor/angular-native-dragdrop/draganddrop', - 'angular-strap': '../vendor/angular-other/angular-strap', - 'angular-ui': '../vendor/angular-ui/angular-bootstrap', - timepicker: '../vendor/angular-other/timepicker', - datepicker: '../vendor/angular-other/datepicker', - bindonce: '../vendor/angular-bindonce/bindonce', - crypto: '../vendor/crypto.min', - spectrum: '../vendor/spectrum', + text: 'vendor/requirejs-text/text', + moment: 'vendor/moment', + filesaver: 'vendor/filesaver', + ZeroClipboard: 'vendor/ZeroClipboard', + angular: 'vendor/angular/angular', + 'angular-route': 'vendor/angular-route/angular-route', + 'angular-sanitize': 'vendor/angular-sanitize/angular-sanitize', + 'angular-dragdrop': 'vendor/angular-native-dragdrop/draganddrop', + 'angular-strap': 'vendor/angular-other/angular-strap', + 'angular-ui': 'vendor/angular-ui/tabs', + timepicker: 'vendor/angular-other/timepicker', + datepicker: 'vendor/angular-other/datepicker', + bindonce: 'vendor/angular-bindonce/bindonce', + crypto: 'vendor/crypto.min', + spectrum: 'vendor/spectrum', - lodash: 'components/lodash.extended', - 'lodash-src': '../vendor/lodash', - bootstrap: '../vendor/bootstrap/bootstrap', + 'lodash-src': 'vendor/lodash', + bootstrap: 'vendor/bootstrap/bootstrap', - jquery: '../vendor/jquery/dist/jquery', + jquery: 'vendor/jquery/dist/jquery', - 'extend-jquery': 'components/extend-jquery', + 'jquery.flot': 'vendor/flot/jquery.flot', + 'jquery.flot.pie': 'vendor/flot/jquery.flot.pie', + 'jquery.flot.events': 'vendor/flot/jquery.flot.events', + 'jquery.flot.selection': 'vendor/flot/jquery.flot.selection', + 'jquery.flot.stack': 'vendor/flot/jquery.flot.stack', + 'jquery.flot.stackpercent':'vendor/flot/jquery.flot.stackpercent', + 'jquery.flot.time': 'vendor/flot/jquery.flot.time', + 'jquery.flot.crosshair': 'vendor/flot/jquery.flot.crosshair', + 'jquery.flot.fillbelow': 'vendor/flot/jquery.flot.fillbelow', - 'jquery.flot': '../vendor/flot/jquery.flot', - 'jquery.flot.pie': '../vendor/flot/jquery.flot.pie', - 'jquery.flot.events': '../vendor/flot/jquery.flot.events', - 'jquery.flot.selection': '../vendor/flot/jquery.flot.selection', - 'jquery.flot.stack': '../vendor/flot/jquery.flot.stack', - 'jquery.flot.stackpercent':'../vendor/flot/jquery.flot.stackpercent', - 'jquery.flot.time': '../vendor/flot/jquery.flot.time', - 'jquery.flot.crosshair': '../vendor/flot/jquery.flot.crosshair', - 'jquery.flot.fillbelow': '../vendor/flot/jquery.flot.fillbelow', + modernizr: 'vendor/modernizr-2.6.1', - modernizr: '../vendor/modernizr-2.6.1', - - 'bootstrap-tagsinput': '../vendor/tagsinput/bootstrap-tagsinput', - 'aws-sdk': '../vendor/aws-sdk/dist/aws-sdk.min', + 'bootstrap-tagsinput': 'vendor/tagsinput/bootstrap-tagsinput', + 'aws-sdk': 'vendor/aws-sdk/dist/aws-sdk.min', }, shim: { diff --git a/public/app/components/settings.js b/public/app/components/settings.js index b3a04bb3eec..a9e1d382dd5 100644 --- a/public/app/components/settings.js +++ b/public/app/components/settings.js @@ -15,10 +15,10 @@ function (_) { datasources : {}, window_title_prefix : 'Grafana - ', panels : { - 'graph': { path: 'panels/graph', name: 'Graph' }, - 'singlestat': { path: 'panels/singlestat', name: 'Single stat' }, - 'text': { path: 'panels/text', name: 'Text' }, - 'dashlist': { path: 'panels/dashlist', name: 'Dashboard list' }, + 'graph': { path: 'app/panels/graph', name: 'Graph' }, + 'singlestat': { path: 'app/panels/singlestat', name: 'Single stat' }, + 'text': { path: 'app/panels/text', name: 'Text' }, + 'dashlist': { path: 'app/panels/dashlist', name: 'Dashboard list' }, }, new_panel_title: 'no title (click here)', plugins: {}, diff --git a/public/app/core/routes/all.js b/public/app/core/routes/all.js index a16af0836dd..a7e36a0e228 100644 --- a/public/app/core/routes/all.js +++ b/public/app/core/routes/all.js @@ -9,7 +9,7 @@ define([ coreModule.config(function($routeProvider, $locationProvider) { $locationProvider.html5Mode(true); - var loadOrgBundle = new BundleLoader.BundleLoader('features/org/all'); + var loadOrgBundle = new BundleLoader.BundleLoader('app/features/org/all'); $routeProvider .when('/', { diff --git a/public/app/core/utils/datemath.ts b/public/app/core/utils/datemath.ts new file mode 100644 index 00000000000..0bc572eeb8f --- /dev/null +++ b/public/app/core/utils/datemath.ts @@ -0,0 +1,109 @@ +/// + +import _ = require('lodash'); +import moment = require('moment'); + +var units = ['y', 'M', 'w', 'd', 'h', 'm', 's']; +var unitsAsc = _.sortBy(units, function (unit) { + return moment.duration(1, unit).valueOf(); +}); +var unitsDesc = unitsAsc.reverse(); + +export class DateMath { + + static parse(text, roundUp) { + if (!text) { return undefined; } + if (moment.isMoment(text)) { return text; } + if (_.isDate(text)) { return moment(text); } + + var time; + var mathString = ''; + var index; + var parseString; + + if (text.substring(0, 3) === 'now') { + time = moment(); + mathString = text.substring('now'.length); + } else { + index = text.indexOf('||'); + if (index === -1) { + parseString = text; + mathString = ''; // nothing else + } else { + parseString = text.substring(0, index); + mathString = text.substring(index + 2); + } + // We're going to just require ISO8601 timestamps, k? + time = moment(parseString); + } + + if (!mathString.length) { + return time; + } + + return DateMath.parseDateMath(mathString, time, roundUp); + } + + static parseDateMath(mathString, time, roundUp) { + var dateTime = time; + var i = 0; + var len = mathString.length; + + while (i < len) { + var c = mathString.charAt(i++); + var type; + var num; + var unit; + + if (c === '/') { + type = 0; + } else if (c === '+') { + type = 1; + } else if (c === '-') { + type = 2; + } else { + return undefined; + } + + if (isNaN(mathString.charAt(i))) { + num = 1; + } else if (mathString.length === 2) { + num = mathString.charAt(i); + } else { + var numFrom = i; + while (!isNaN(mathString.charAt(i))) { + i++; + if (i > 10) { return undefined; } + } + num = parseInt(mathString.substring(numFrom, i), 10); + } + + if (type === 0) { + // rounding is only allowed on whole, single, units (eg M or 1M, not 0.5M or 2M) + if (num !== 1) { + return undefined; + } + } + unit = mathString.charAt(i++); + + if (!_.contains(units, unit)) { + return undefined; + } else { + if (type === 0) { + if (roundUp) { + dateTime.endOf(unit); + } + else { + dateTime.startOf(unit); + } + } else if (type === 1) { + dateTime.add(num, unit); + } else if (type === 2) { + dateTime.subtract(num, unit); + } + } + } + return dateTime; + } +} + diff --git a/public/app/features/dashboard/graphiteImportCtrl.js b/public/app/features/dashboard/graphiteImportCtrl.js index 578d2981db1..2b6660c2a22 100644 --- a/public/app/features/dashboard/graphiteImportCtrl.js +++ b/public/app/features/dashboard/graphiteImportCtrl.js @@ -1,10 +1,9 @@ define([ 'angular', - 'app', 'lodash', 'kbn' ], -function (angular, app, _, kbn) { +function (angular, _, kbn) { 'use strict'; var module = angular.module('grafana.controllers'); diff --git a/public/app/features/dashboard/rowCtrl.js b/public/app/features/dashboard/rowCtrl.js index 6839feb8f3b..4270d7f97f6 100644 --- a/public/app/features/dashboard/rowCtrl.js +++ b/public/app/features/dashboard/rowCtrl.js @@ -1,10 +1,9 @@ define([ 'angular', - 'app', 'lodash', 'config' ], -function (angular, app, _, config) { +function (angular, _, config) { 'use strict'; var module = angular.module('grafana.controllers'); diff --git a/public/app/features/dashboard/timepicker/timepicker.html b/public/app/features/dashboard/timepicker/timepicker.html index cc916dc4a9d..900f4c9182e 100644 --- a/public/app/features/dashboard/timepicker/timepicker.html +++ b/public/app/features/dashboard/timepicker/timepicker.html @@ -27,9 +27,9 @@ -