Commit 37b3b1fc by Torkel Ödegaard

Merge remote-tracking branch 'origin/master' into pro

parents 1bc277fd d8656180
......@@ -6,6 +6,7 @@ dist
# locally required config files
web.config
config.js
src/css/*.min.css
# Editor junk
*.sublime-workspace
......
language: node_js
node_js:
- "0.10"
git:
depth: 1
before_script:
- npm install -g grunt-cli
after_script:
......
# 1.7.0 (unreleased)
# 1.8.0 (unreleased)
**New features and improvements**
- [Issue #578](https://github.com/grafana/grafana/issues/578). Dashboard: Row option to display row title even when the row is visible
**Tech**
- Upgraded from angularjs 1.1.5 to 1.3 beta 17;
- Switch from underscore to lodash
- helpers to easily unit test angularjs controllers and services
- Test coverage through coveralls
# 1.7.0 (2014-08-11)
**Fixes**
- [Issue #655](https://github.com/grafana/grafana/issues/655). General: Auto refresh not initiated / started after dashboard loading
- [Issue #652](https://github.com/grafana/grafana/issues/652). Timepicker: Entering custom date range impossible when refresh is low (now is constantly reset)
- [Issue #450](https://github.com/grafana/grafana/issues/450). Graph: Tooltip does not disappear sometimes and would get stuck
- [Issue #655](https://github.com/grafana/grafana/issues/655). General: Auto refresh not initiated / started after dashboard loading
- [Issue #657](https://github.com/grafana/grafana/issues/657). General: Fix for refresh icon in IE browsers
- [Issue #661](https://github.com/grafana/grafana/issues/661). Annotations: Elasticsearch querystring with filter template replacements was not interpolated
- [Issue #660](https://github.com/grafana/grafana/issues/660). OpenTSDB: fix opentsdb queries that returned more than one series
**Change**
- [Issue #681](https://github.com/grafana/grafana/issues/681). Dashboard: The panel error bar has been replaced with a small error indicator, this indicator does not change panel height and is a lot less intrusive. Hover over it for short details, click on it for more details.
# 1.7.0-rc1 (2014-08-05)
......
[Grafana](http://grafana.org) [![Build Status](https://api.travis-ci.org/grafana/grafana.png)](https://travis-ci.org/grafana/grafana) [![Gittip](http://img.shields.io/gittip/torkelo.svg)](https://www.gittip.com/torkelo)
[Grafana](http://grafana.org) [![Build Status](https://api.travis-ci.org/grafana/grafana.svg)](https://travis-ci.org/grafana/grafana) [![Coverage Status](https://coveralls.io/repos/grafana/grafana/badge.png?branch=develop)](https://coveralls.io/r/grafana/grafana?branch=develop)
================
[Website](http://grafana.org) |
[Twitter](http://twitter.com/grafana) |
......
{
"version": "1.7.0-rc1",
"url": "http://grafanarel.s3.amazonaws.com/grafana-1.7.0-rc1.tar.gz"
}
\ No newline at end of file
"version": "1.7.0",
"url": "http://grafanarel.s3.amazonaws.com/grafana-1.7.0"
}
......@@ -4,7 +4,7 @@
"company": "Coding Instinct AB"
},
"name": "grafana",
"version": "1.7.0-rc1",
"version": "1.7.0",
"repository": {
"type": "git",
"url": "http://github.com/torkelo/grafana.git"
......@@ -26,6 +26,7 @@
"grunt-contrib-less": "~0.7.0",
"grunt-contrib-requirejs": "~0.4.1",
"grunt-contrib-uglify": "~0.2.4",
"grunt-contrib-watch": "^0.6.1",
"grunt-filerev": "^0.2.1",
"grunt-git-describe": "~2.3.2",
"grunt-karma": "~0.8.3",
......
......@@ -51,13 +51,13 @@ function (angular, $, _, appLevelRequire, config) {
app.config(function ($routeProvider, $controllerProvider, $compileProvider, $filterProvider, $provide) {
$routeProvider.otherwise({ redirectTo: config.default_route });
// this is how the internet told me to dynamically add modules :/
register_fns.controller = $controllerProvider.register;
register_fns.directive = $compileProvider.directive;
register_fns.factory = $provide.factory;
register_fns.service = $provide.service;
register_fns.filter = $filterProvider.register;
});
var apps_deps = [
......
......@@ -13,4 +13,5 @@ define([
'./playlistCtrl',
'./inspectCtrl',
'./opentsdbTargetCtrl',
'./console-ctrl',
], function () {});
define([
'angular',
'lodash',
'moment',
],
function (angular, _, moment) {
'use strict';
var module = angular.module('grafana.controllers');
var consoleEnabled = window.localStorage && window.localStorage.grafanaConsole === 'true';
if (!consoleEnabled) {
return;
}
var events = [];
var oldLog = console.log;
console.log = function (message) {
try {
if (_.isObject(message)) {
message = angular.toJson(message);
if (message.length > 50) {
message = message.substring(0, 50);
}
}
events.push(new ConsoleEvent('log', message, {}));
oldLog.apply(console, arguments);
} catch (e) { }
};
function ConsoleEvent(type, title, data) {
this.type = type;
this.title = title;
this.data = data;
this.time = moment().format('hh:mm:ss');
if (data.config) {
this.method = data.config.method;
this.elapsed = (new Date().getTime() - data.config.$grafana_timestamp) + ' ms';
if (data.config.params && data.config.params.q) {
this.field2 = data.config.params.q;
}
if (_.isString(data.config.data)) {
this.field2 = data.config.data;
}
if (data.status !== 200) {
this.error = true;
this.field3 = data.data;
}
if (_.isArray(data.data)) {
this.extractTimeseriesInfo(data.data);
}
}
}
ConsoleEvent.prototype.extractTimeseriesInfo = function(series) {
if (series.length === 0) {
return;
}
var points = 0;
var ok = false;
if (series[0].datapoints) {
points = _.reduce(series, function(memo, val) {
return memo + val.datapoints.length;
}, 0);
ok = true;
}
if (series[0].columns) {
points = _.reduce(series, function(memo, val) {
return memo + val.points.length;
}, 0);
ok = true;
}
if (ok) {
this.field1 = '(' + series.length + ' series';
this.field1 += ', ' + points + ' points)';
}
};
module.config(function($provide, $httpProvider) {
$provide.factory('mupp', function($q) {
return {
'request': function(config) {
if (config.inspect) {
config.$grafana_timestamp = new Date().getTime();
}
return config;
},
'response': function(response) {
if (response.config.inspect) {
events.push(new ConsoleEvent(response.config.inspect.type, response.config.url, response));
}
return response;
},
'requestError': function(rejection) {
console.log('requestError', rejection);
return $q.reject(rejection);
},
'responseError': function (rejection) {
var inspect = rejection.config.inspect || { type: 'error' };
events.push(new ConsoleEvent(inspect.type, rejection.config.url, rejection));
return $q.reject(rejection);
}
};
});
$httpProvider.interceptors.push('mupp');
});
module.controller('ConsoleCtrl', function($scope) {
$scope.events = events;
});
});
......@@ -18,6 +18,13 @@ function (angular, config, _) {
$scope.grafana = {
style: 'dark'
};
$scope.consoleEnabled = (window.localStorage && window.localStorage.grafanaConsole === 'true');
};
$scope.toggleConsole = function() {
$scope.consoleEnabled = !$scope.consoleEnabled;
window.localStorage.grafanaConsole = $scope.consoleEnabled ? 'true' : 'false';
};
$rootScope.onAppEvent = function(name, callback) {
......
define([
'angular'
'angular',
'lodash'
],
function (angular) {
function (angular, _) {
'use strict';
var module = angular.module('grafana.controllers');
......@@ -28,6 +29,16 @@ function (angular) {
return;
}
if (_.isString(model.error.data)) {
$scope.response = model.error.data;
}
if (model.error.config && model.error.config.params) {
$scope.request_parameters = _.map(model.error.config.params, function(value, key) {
return { key: key, value: value};
});
}
if (model.error.stack) {
$scope.editor.index = 2;
$scope.stack_trace = model.error.stack;
......@@ -72,4 +83,4 @@ function (angular) {
};
});
});
\ No newline at end of file
});
......@@ -33,11 +33,8 @@ function (angular, app, _) {
};
$scope.rowSpan = function(row) {
var panels = _.filter(row.panels, function(p) {
return $scope.isPanel(p);
});
return _.reduce(_.pluck(panels,'span'), function(p,v) {
return p+v;
return _.reduce(row.panels, function(p,v) {
return p + v.span;
},0);
};
......
......@@ -15,16 +15,12 @@ function (angular, $) {
var panelHeader =
'<div class="panel-header">'+
'<div class="row-fluid">' +
'<div class="span12 alert-error panel-error small" ng-show="panel.error">' +
'<a class="close" ng-click="panel.error=false">&times;</a>' +
'<span><i class="icon-exclamation-sign"></i> <strong>Oops!</strong> {{panel.error}} </span>' +
'<span class="pointer panel-error-inspector-link" config-modal="app/partials/inspector.html">View details</span>' +
'</div>' +
'</div>\n' +
'<div class="row-fluid panel-extra">' +
'<div class="row-fluid panel-extra">' +
'<div class="panel-extra-container">' +
'<span class="alert-error panel-error small pointer"' +
'config-modal="app/partials/inspector.html" ng-show="panel.error" data-placement="right" bs-tooltip="panel.error">' +
'<i class="icon-exclamation-sign"></i><span class="panel-error-arrow"></span>' +
'</span>' +
'<span class="panel-loading" ng-show="panelMeta.loading == true">' +
'<i class="icon-spinner icon-spin icon-large"></i>' +
......
......@@ -13,20 +13,15 @@
{{series.alias}}
</a>
</div>
<div class="graph-legend-value small" ng-show="panel.legend.values && panel.legend.current">
Current: {{series.current}}
<div class="graph-legend-value current small" ng-show="panel.legend.values && panel.legend.current" ng-bind="series.current">
</div>
<div class="graph-legend-value small" ng-show="panel.legend.values && panel.legend.min">
Min: {{series.min}}
<div class="graph-legend-value min small" ng-show="panel.legend.values && panel.legend.min" ng-bind="series.min">
</div>
<div class="graph-legend-value small" ng-show="panel.legend.values && panel.legend.max">
Max: {{series.max}}
<div class="graph-legend-value max small" ng-show="panel.legend.values && panel.legend.max" ng-bind="series.max">
</div>
<div class="graph-legend-value small" ng-show="panel.legend.values && panel.legend.total">
Total: {{series.total}}
<div class="graph-legend-value total small" ng-show="panel.legend.values && panel.legend.total" ng-bind="series.total">
</div>
<div class="graph-legend-value small" ng-show="panel.legend.values && panel.legend.avg">
Avg: {{series.avg}}
<div class="graph-legend-value avg small" ng-show="panel.legend.values && panel.legend.avg" ng-bind="series.avg">
</div>
</div>
......
......@@ -82,11 +82,13 @@ function (angular, app, _, require) {
$scope.updateContent = function(html) {
try {
$scope.content = $sce.trustAsHtml(filterSrv.applyTemplateToTarget(html));
if(!$scope.$$phase) {
$scope.$apply();
}
} catch(e) {
console.log('Text panel error: ', e);
$scope.content = $sce.trustAsHtml(html);
}
if(!$scope.$$phase) {
$scope.$apply();
}
};
......
......@@ -52,7 +52,7 @@
</li>
<li ng-show="!dashboard.refresh" class="grafana-menu-refresh">
<a class="icon-refresh" ng-click="dashboard.emit_refresh()"></a>
<a ng-click="dashboard.emit_refresh()"><i class="icon-refresh"></i></a>
</li>
</ul>
......
<div class="grafana-console" ng-controller="ConsoleCtrl">
<div class="grafana-console-header">
<span class="grafana-console-title large"><i class="icon-terminal"></i></span>
</div>
<div class="grafana-console-body">
<div class="grafana-console-item" ng-repeat="item in events" ng-class="{'grafana-console-error': item.error}">
<span class="grafana-console-time gfc-col" ng-bind="item.time"></span>
<span class="grafana-console-type gfc-col">
<span class="label label-info" ng-bind="item.type"></span>
</span>
<span class="gfc-col grafana-console-method" ng-bind="item.method"></span>
<span class="gfc-col grafana-console-title" ng-bind="item.title"></span>
<span class="gfc-col grafana-console-elapsed" ng-bind="item.elapsed"></span>
<span class="gfc-col grafana-console-field1" ng-bind="item.field1"></span>
<span class="gfc-col grafana-console-field2" ng-bind="item.field2"></span>
<span class="gfc-col grafana-console-field3" ng-bind="item.field3"></span>
</div>
</div>
</div>
......@@ -31,13 +31,15 @@
<div class="row-control">
<div class="row-control-inner" style="padding:0px;margin:0px;position:relative;">
<div class="row-close" ng-show="row.collapse" data-placement="bottom" >
<span class="row-button bgWarning" config-modal="app/partials/roweditor.html" class="pointer">
<i bs-tooltip="'Configure row'" data-placement="right" ng-show="row.editable" class="icon-cog pointer"></i>
</span>
<span class="row-button bgPrimary" ng-click="toggle_row(row)">
<i bs-tooltip="'Expand row'" data-placement="right" class="icon-caret-left pointer" ></i>
</span>
<span class="row-button row-text" ng-click="toggle_row(row)">{{row.title || 'Row '+$index}}</span>
<div class="row-close-buttons">
<span class="row-button bgWarning" config-modal="app/partials/roweditor.html" class="pointer">
<i bs-tooltip="'Configure row'" data-placement="right" ng-show="row.editable" class="icon-cog pointer"></i>
</span>
<span class="row-button bgPrimary" ng-click="toggle_row(row)">
<i bs-tooltip="'Expand row'" data-placement="right" class="icon-caret-left pointer" ></i>
</span>
</div>
<span class="row-text pointer" ng-click="toggle_row(row)" ng-bind="row.title"></span>
</div>
<div class="row-open" ng-show="!row.collapse">
<div class='row-tab bgPrimary' ng-click="toggle_row(row)">
......@@ -92,6 +94,8 @@
</div>
<div style="padding-top:0px" ng-if="!row.collapse">
<div class="row-text pointer" ng-click="toggle_row(row)" ng-if="row.showTitle" ng-bind="row.title">
</div>
<!-- Panels -->
<div ng-repeat="(name, panel) in row.panels|filter:isPanel" ng-hide="panel.hide" class="panel nospace" ng-style="{'width':(panel.span/1.2)*10+'%'}" data-drop="true" ng-model="row.panels" data-jqyoui-options jqyoui-droppable="{index:$index,mutate:false,onDrop:'panelMoveDrop',onOver:'panelMoveOver(true)',onOut:'panelMoveOut'}" ng-class="{'dragInProgress':dashboard.$$panelDragging}">
......@@ -121,4 +125,7 @@
</div>
</div>
<div ng-include="'app/partials/console.html'" ng-if="consoleEnabled">
</div>
</div>
......@@ -25,7 +25,7 @@
<label class="small">Hide controls (CTRL+H)</label>
<input type="checkbox" ng-model="dashboard.hideControls" ng-checked="dashboard.hideControls">
</div>
</div>
</div>
</div>
<div class="editor-row">
<div class="section">
......@@ -98,6 +98,7 @@
<span class="editor-option small">
Grafana version: {{grafanaVersion}}
</span>
<span> | <a ng-click="toggleConsole()" ng-show="!consoleEnabled">enable console</a> <a ng-click="toggleConsole()" ng-show="consoleEnabled">disable console</a></span>
<div class="small" grafana-version-check>
</div>
</div>
......
......@@ -41,6 +41,7 @@
</div>
<div ng-if="editor.index == 1">
<h5 ng-if="response" ng-bind="response"></h5>
<div ng-if="response_html">
<div iframe-content="response_html"></div>
......@@ -65,4 +66,4 @@
</div>
<div class="modal-footer">
<button type="button" class="btn btn-info" ng-click="dismiss()">Close</button>
</div>
\ No newline at end of file
</div>
......@@ -17,9 +17,9 @@
<label class="small"> Editable </label><input type="checkbox" ng-model="row.editable" ng-checked="row.editable" />
</div>
<div class="editor-option">
<label class="small"> Collapsable </label><input type="checkbox" ng-model="row.collapsable" ng-checked="row.collapsable" />
<label class="small"> Show title </label><input type="checkbox" ng-model="row.showTitle" ng-checked="row.showTitle" />
</div>
</div>
</div>
<div class="row-fluid" ng-if="editor.index == 1">
<div class="span12">
<h4>Panels</h4>
......
......@@ -7,7 +7,7 @@ function (angular, _) {
var module = angular.module('grafana.services');
module.service('alertSrv', function($timeout) {
module.service('alertSrv', function($timeout, $sce) {
var self = this;
// List of all alert objects
......@@ -17,7 +17,7 @@ function (angular, _) {
var
_a = {
title: title || '',
text: text || '',
text: $sce.trustAsHtml(text || ''),
severity: severity || 'info',
},
_ca = angular.toJson(_a),
......@@ -46,4 +46,4 @@ function (angular, _) {
self.list = [];
};
});
});
\ No newline at end of file
});
......@@ -73,8 +73,9 @@ function (angular, _, $, config, kbn, moment) {
to: rangeUnparsed.to,
};
var queryInterpolated = filterSrv.applyTemplateToTarget(queryString);
var filter = { "bool": { "must": [{ "range": range }] } };
var query = { "bool": { "should": [{ "query_string": { "query": queryString } }] } };
var query = { "bool": { "should": [{ "query_string": { "query": queryInterpolated } }] } };
var data = { "query" : { "filtered": { "query" : query, "filter": filter } }, "size": 100 };
return this._request('POST', '/_search', annotation.index, data).then(function(results) {
......
......@@ -205,6 +205,7 @@ function (angular, _, $, config, kbn, moment) {
}
options.url = this.url + options.url;
options.inspect = { type: 'graphite' };
return $http(options);
};
......
......@@ -132,8 +132,8 @@ function (angular, _, kbn, InfluxSeries) {
return new InfluxSeries({ seriesList: results, annotation: annotation }).getAnnotations();
});
};
InfluxDatasource.prototype.listColumns = function(seriesName) {
return this._seriesQuery('select * from /' + seriesName + '/ limit 1').then(function(data) {
if (!data) {
return [];
......@@ -184,6 +184,7 @@ function (angular, _, kbn, InfluxSeries) {
function retry(deferred, callback, delay) {
return callback().then(undefined, function(reason) {
if (reason.status !== 0 || reason.status >= 300) {
reason.message = 'InfluxDB Error: <br/>' + reason.data;
deferred.reject(reason);
}
else {
......@@ -223,7 +224,8 @@ function (angular, _, kbn, InfluxSeries) {
method: method,
url: currentUrl + url,
params: params,
data: data
data: data,
inspect: { type: 'influxdb' },
};
return $http(options).success(function (data) {
......
......@@ -106,7 +106,7 @@ function (angular, _, kbn) {
}
function createMetricLabel(metric, tagData, options) {
if (options.alias) {
if (!_.isUndefined(options) && options.alias) {
return options.alias;
}
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -12,22 +12,6 @@ body {
//url('../img/light.png') repeat right top;
}
h1 {
font-size: 50px;
}
h2, h3 {
font-size: 26px;
}
h4 {
font-size: 14px;
}
h5, h6 {
font-size: 11px;
}
blockquote {
padding: 10px 15px;
......@@ -527,11 +511,6 @@ a:hover {
.box-shadow(none);
}
[class^="icon-"], [class*=" icon-"] {
margin: 0 2px;
vertical-align: -2px;
}
a.thumbnail {
background-color: @grayLight;
......
.grafana-console {
position: fixed;
width: 100%;
bottom: 0px;
height: 300px;
background: @grafanaPanelBackground;
border-top: 1px solid @fullEditBorder;
}
.grafana-console-header {
background: @fullEditTabsBackground;
border-top: @fullEditTabsBorder;
padding: 2px 5px;
}
.grafana-console-item {
.icon-caret-right {
font-size: 14px;
color: @blue;
}
margin: 2px 0;
display: table-row;
}
.grafana-console-body {
overflow-y: auto;
display: table;
width: 100%;
}
.gfc-col {
display: table-cell;
padding: 2px 4px;
white-space: nowrap;
overflow: hidden;
vertical-align: middle;
}
.grafana-console-method {
text-align: center;
}
.grafana-console-error {
.grafana-console-method {
color: red;
}
}
.grafana-console-field2 {
width: 90%;
}
.grafana-console-time:before {
content: '(';
color: rgb(106, 253, 81);
}
.grafana-console-time:after {
content: ')';
color: rgb(106, 253, 81);
}
.grafana-console-time {
color: rgb(162, 196, 253);
}
.grafana-console-elapsed {
text-align: right;
color: rgb(162, 196, 253);
}
@import "submenu.less";
@import "graph.less";
@import "console.less";
@import "bootstrap-tagsinput.less";
.hide-controls {
......@@ -494,3 +495,11 @@ select.grafana-target-segment-input {
border-radius: 5px;
z-index: 9999;
}
.tooltip.in {
.opacity(100);
}
.tooltip-inner {
max-width: 400px;
}
......@@ -25,6 +25,21 @@
.graph-legend-value {
float: left;
white-space: nowrap;
&.current:before {
content: "Current: "
}
&.max:before {
content: "Max: "
}
&.min:before {
content: "Min: "
}
&.total:before {
content: "Total: "
}
&.avg:before {
content: "Avg: "
}
}
.graph-legend-series {
......
......@@ -112,15 +112,27 @@ code, pre {
.panel-error {
color: @white;
padding: 5px 10px 0px 10px;
//padding: 5px 10px 0px 10px;
position: absolute;
left: 5px;
padding: 0px 17px 6px 5px;
top: 0;
i {
position: relative;
top: -2px;
}
}
.panel-error-inspector-link {
float: right;
margin-right: 10px;
.panel-error-arrow {
width: 0;
height: 0;
position: absolute;
border-left: 31px solid transparent;
border-right: 30px solid transparent;
border-bottom: 27px solid @grafanaPanelBackground;
left: 0;
bottom: 0;
}
div.editor-row {
vertical-align: top;
}
......@@ -223,9 +235,9 @@ form input.ng-invalid {
.row-button {
width: 30px;
text-align: center;
float: left;
cursor: pointer;
line-height: 31px;
}
.row-text {
......@@ -233,15 +245,20 @@ form input.ng-invalid {
text-transform: uppercase;
font-weight: bold;
font-size: 0.9em;
margin: 0px 10px;
text-align: center;
line-height: 31px;
}
.row-close {
padding: 0px;
margin: 0px;
min-height: 30px !important;
line-height: 30px;
background: @grafanaPanelBackground;
text-align: center;
}
.row-close-buttons {
position: absolute;
left: 0;
}
.row-open {
......@@ -614,4 +631,4 @@ div.flot-text {
code, pre {
background-color: @grafanaPanelBackground;
color: @textColor;
}
\ No newline at end of file
}
......@@ -19,7 +19,7 @@
@blue: #33B5E5;
@blueDark: #0099CC;
@green: #669900;
@red: #CC0000;
@red: #CC3900;
@yellow: #ECBB13;
@orange: #FF8800;
@pink: #FF4444;
......
......@@ -7,7 +7,7 @@
<meta name="viewport" content="width=device-width">
<title>Grafana</title>
<link rel="stylesheet" href="css/default.min.css" title="Dark">
<link rel="stylesheet" href="css/grafana.dark.min.css" title="Dark">
<!-- build:js app/app.js -->
<script src="vendor/require/require.js"></script>
......@@ -20,9 +20,7 @@
<body ng-cloak ng-controller="GrafanaCtrl">
<link rel="stylesheet" href="css/bootstrap.light.min.css" ng-if="grafana.style === 'light'">
<link rel="stylesheet" href="css/bootstrap-responsive.min.css">
<link rel="stylesheet" href="css/font-awesome.min.css">
<link rel="stylesheet" href="css/grafana.light.min.css" ng-if="grafana.style === 'light'">
<div ng-repeat='alert in dashAlerts.list' class="alert-{{alert.severity}} dashboard-notice" ng-show="$last">
<button type="button" class="close" ng-click="dashAlerts.clear(alert)" style="padding-right:50px">&times;</button>
......
......@@ -797,7 +797,8 @@ angular.module('$strap.directives').directive('bsTooltip', [
title: function () {
return angular.isFunction(value) ? value.apply(null, arguments) : value;
},
html: true
html: true,
container: 'body', // Grafana change
});
var tooltip = element.data('tooltip');
tooltip.show = function () {
......@@ -875,4 +876,4 @@ angular.module('$strap.directives').directive('bsTypeahead', [
}
};
}
]);
\ No newline at end of file
]);
......@@ -6,7 +6,8 @@ module.exports = function(grunt) {
'jshint:tests',
'clean:on_start',
'less:src',
'concat:css',
'concat:cssDark',
'concat:cssLight',
'copy:everything_but_less_to_temp',
'htmlmin:build',
'ngtemplates',
......
// Lint and build CSS
module.exports = function(grunt) {
grunt.registerTask('default', ['jscs', 'jshint', 'less:src', 'concat:css']);
grunt.registerTask('css', ['less:src', 'concat:cssDark', 'concat:cssLight']);
grunt.registerTask('default', ['jscs', 'jshint', 'css']);
grunt.registerTask('test', ['default', 'karma:test']);
};
module.exports = function(config) {
return {
css: {
cssDark: {
src: [
'<%= srcDir %>/css/normalize.min.css',
'<%= srcDir %>/css/timepicker.css',
'<%= srcDir %>/css/spectrum.css',
'<%= srcDir %>/css/animate.min.css',
'<%= srcDir %>/css/bootstrap.dark.min.css'
'<%= srcDir %>/vendor/css/normalize.min.css',
'<%= srcDir %>/vendor/css/timepicker.css',
'<%= srcDir %>/vendor/css/spectrum.css',
'<%= srcDir %>/vendor/css/animate.min.css',
'<%= srcDir %>/css/bootstrap.dark.min.css',
'<%= srcDir %>/css/bootstrap-responsive.min.css',
'<%= srcDir %>/vendor/css/font-awesome.min.css'
],
dest: '<%= srcDir %>/css/default.min.css'
dest: '<%= srcDir %>/css/grafana.dark.min.css'
},
cssLight: {
src: [
'<%= srcDir %>/vendor/css/normalize.min.css',
'<%= srcDir %>/vendor/css/timepicker.css',
'<%= srcDir %>/vendor/css/spectrum.css',
'<%= srcDir %>/vendor/css/animate.min.css',
'<%= srcDir %>/css/bootstrap.light.min.css',
'<%= srcDir %>/css/bootstrap-responsive.min.css',
'<%= srcDir %>/vendor/css/font-awesome.min.css'
],
dest: '<%= srcDir %>/css/grafana.light.min.css'
},
js: {
src: [
'<%= destDir %>/vendor/require/require.js',
......
......@@ -5,8 +5,12 @@ module.exports = function(config) {
algorithm: 'md5',
length: 8,
},
css: {
src: '<%= destDir %>/css/default.min.css',
cssDark: {
src: '<%= destDir %>/css/grafana.dark.min.css',
dest: '<%= destDir %>/css'
},
cssLight: {
src: '<%= destDir %>/css/grafana.light.min.css',
dest: '<%= destDir %>/css'
},
js: {
......
......@@ -51,7 +51,7 @@ module.exports = function(config,grunt) {
'modernizr',
'timepicker',
'datepicker',
'underscore',
'lodash',
'filters/all',
'jquery.flot',
'services/all',
......
module.exports = function(config) {
return {
css: {
files: [ '<%= srcDir %>/css/**/*.less' ],
tasks: ['css'],
options: {
spawn: false
}
}
};
};
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