mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Merge branch 'feature/3270/statusPage' of github.com:panda01/kibana into apps/home
This commit is contained in:
commit
22fb1e5a96
19 changed files with 328 additions and 195 deletions
|
@ -9,6 +9,7 @@
|
|||
"require": true,
|
||||
"console": false,
|
||||
"-event": true,
|
||||
"-name": true
|
||||
"-name": true,
|
||||
"module": true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
"url": "https://github.com/elastic/kibana.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"angular-nvd3": "krispo/angular-nvd3#7f04d396cb69cb0ed944555ffeb95e0d7457c952",
|
||||
"angular-nvd3": "panda01/angular-nvd3#kibana",
|
||||
"ansicolors": "^0.3.2",
|
||||
"autoprefixer-loader": "^2.0.0",
|
||||
"babel-jscs": "^1.0.3",
|
||||
|
@ -80,7 +80,7 @@
|
|||
"moment": "^2.10.3",
|
||||
"node-libs-browser": "spalger/node-libs-browser",
|
||||
"numeral": "^1.5.3",
|
||||
"nvd3": "novus/nvd3#679fe2ff96c194e442970cb9959ebccd79f6bd43",
|
||||
"nvd3": "panda01/nvd3#kibana",
|
||||
"raw-loader": "^0.5.1",
|
||||
"request": "^2.40.0",
|
||||
"requirefrom": "^0.2.0",
|
||||
|
|
|
@ -1,166 +0,0 @@
|
|||
var angular = require('angular');
|
||||
var $ = require('jquery');
|
||||
var _ = require('lodash');
|
||||
var moment = require('moment');
|
||||
var numeral = require('numeral');
|
||||
require('angular-nvd3');
|
||||
|
||||
// Turns thisIsASentence to
|
||||
// This Is A Sentence
|
||||
function niceName(name) {
|
||||
return name
|
||||
.split(/(?=[A-Z])/)
|
||||
.map(function (word) { return word[0].toUpperCase() + _.rest(word).join(''); })
|
||||
.join(' ');
|
||||
}
|
||||
|
||||
function formatNumber(num, which) {
|
||||
var format = '0.00';
|
||||
var postfix = '';
|
||||
switch (which) {
|
||||
case 'time':
|
||||
return moment(num).format('HH:mm:ss');
|
||||
case 'byte':
|
||||
format += 'b';
|
||||
break;
|
||||
case 'ms':
|
||||
postfix = 'ms';
|
||||
break;
|
||||
}
|
||||
return numeral(num).format(format) + postfix;
|
||||
}
|
||||
|
||||
function numberType(key) {
|
||||
var byteMetrics = ['heapTotal', 'heapUsed', 'rss'];
|
||||
var msMetrics = ['delay', 'responseTimeAvg', 'responseTimeMax'];
|
||||
var preciseMetric = ['requests', 'load'];
|
||||
if ( byteMetrics.indexOf(key) > -1 ) {
|
||||
return 'byte';
|
||||
} else if (msMetrics.indexOf(key) > -1 ) {
|
||||
return 'ms';
|
||||
} else {
|
||||
return 'precise';
|
||||
}
|
||||
}
|
||||
|
||||
var makeChartOptions = _.memoize(function (type) {
|
||||
return {
|
||||
chart: {
|
||||
type: 'lineChart',
|
||||
height: 200,
|
||||
showLegend: false,
|
||||
showXAxis: false,
|
||||
showYAxis: false,
|
||||
useInteractiveGuideline: true,
|
||||
tooltips: true,
|
||||
pointSize: 0,
|
||||
color: ['#444', '#777', '#aaa'],
|
||||
margin: {
|
||||
top: 10,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 20
|
||||
},
|
||||
xAxis: { tickFormat: function (d) { return formatNumber(d, 'time'); } },
|
||||
yAxis: { tickFormat: function (d) { return formatNumber(d, type); }, },
|
||||
y: function (d) { return d.y; },
|
||||
x: function (d) { return d.x; }
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// The Kibana App
|
||||
require('modules')
|
||||
.get('KibanaStatusApp', ['nvd3'])
|
||||
.controller('StatusPage', function ($scope, $http, $window, $timeout) {
|
||||
// the object representing all of the elements the ui touches
|
||||
$scope.ui = {
|
||||
overallStatus: null,
|
||||
statuses: null,
|
||||
loading: true,
|
||||
charts: {}
|
||||
};
|
||||
|
||||
var windowHasFocus = true;
|
||||
angular.element($window).bind({
|
||||
blur: function () { windowHasFocus = false; },
|
||||
focus: function () {
|
||||
windowHasFocus = true;
|
||||
getAppStatus();
|
||||
}
|
||||
});
|
||||
|
||||
function getAppStatus() {
|
||||
$scope.ui.loading = true;
|
||||
|
||||
// go ahead and get the info you want
|
||||
$http
|
||||
.get('/api/status')
|
||||
.success(function (data) {
|
||||
// Assign the propper variables to the scope and change them as necessary
|
||||
|
||||
// setup The charts
|
||||
// wrap the metrics data and append the average
|
||||
$scope.ui.charts = _.mapValues(data.metrics, function (metric, name) {
|
||||
|
||||
// Metric Values format
|
||||
// metric: [[xValue, yValue], ...]
|
||||
// LoadMetric:
|
||||
// metric: [[xValue, [yValue, yValue2, yValue3]], ...]
|
||||
// return [
|
||||
// {type: 'line', key: name, yAxis: 1, values: [{x: xValue, y: yValue}, ...]},
|
||||
// {type: 'line', key: name, yAxis: 1, values: [{x: xValue, y: yValue1}, ...]},
|
||||
// {type: 'line', key: name, yAxis: 1, values: [{x: xValue, y: yValue2}, ...]}]
|
||||
//
|
||||
// Go through all of the metric values and split the values out.
|
||||
// returns an array of all of the averages
|
||||
var metricList = [];
|
||||
var metricNumberType = numberType(name);
|
||||
|
||||
// convert the [x,y] into {x: x, y: y}
|
||||
metric.forEach(function (vector) {
|
||||
vector = _.flatten(vector);
|
||||
var x = vector.shift();
|
||||
vector.forEach(function (yValue, idx) {
|
||||
if (!metricList[idx]) {
|
||||
metricList[idx] = {
|
||||
key: name + idx,
|
||||
values: []
|
||||
};
|
||||
}
|
||||
// unshift to make sure they're in the correct order
|
||||
metricList[idx].values.unshift({x: x, y: yValue});
|
||||
});
|
||||
});
|
||||
|
||||
var average = metricList.map(function (data) {
|
||||
var uglySum = data.values.reduce(function (sumSoFar, vector) {
|
||||
return sumSoFar + vector.y;
|
||||
}, 0);
|
||||
return formatNumber(uglySum / data.values.length, metricNumberType);
|
||||
});
|
||||
var options = makeChartOptions(metricNumberType);
|
||||
|
||||
return { data: metricList, average: average, niceName: niceName(name), options: options };
|
||||
});
|
||||
|
||||
// give the plugins their proper name so CSS classes can be properply applied
|
||||
$scope.ui.overallStatus = data.status.overall;
|
||||
$scope.ui.statuses = data.status.statuses;
|
||||
|
||||
if (windowHasFocus) {
|
||||
// go ahead and get another status in 5 seconds
|
||||
$timeout(getAppStatus, 5000);
|
||||
}
|
||||
})
|
||||
.error(function () {
|
||||
window.alert('Something went terribly wrong while making the request!!! Perhaps your server is down?');
|
||||
})
|
||||
.finally(function () {
|
||||
$scope.ui.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
// Start it all up
|
||||
getAppStatus();
|
||||
});
|
19
src/plugins/serverStatus/public/lib/formatNumber.js
Normal file
19
src/plugins/serverStatus/public/lib/formatNumber.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
|
||||
var moment = require('moment');
|
||||
var numeral = require('numeral');
|
||||
|
||||
module.exports = function formatNumber(num, which) {
|
||||
var format = '0.00';
|
||||
var postfix = '';
|
||||
switch (which) {
|
||||
case 'time':
|
||||
return moment(num).format('HH:mm:ss');
|
||||
case 'byte':
|
||||
format += 'b';
|
||||
break;
|
||||
case 'ms':
|
||||
postfix = 'ms';
|
||||
break;
|
||||
}
|
||||
return numeral(num).format(format) + postfix;
|
||||
};
|
28
src/plugins/serverStatus/public/lib/makeChartOptions.js
Normal file
28
src/plugins/serverStatus/public/lib/makeChartOptions.js
Normal file
|
@ -0,0 +1,28 @@
|
|||
|
||||
var formatNumber = require('./formatNumber');
|
||||
|
||||
module.exports = function makeChartOptions(type) {
|
||||
return {
|
||||
chart: {
|
||||
type: 'lineChart',
|
||||
height: 200,
|
||||
showLegend: false,
|
||||
showXAxis: false,
|
||||
showYAxis: false,
|
||||
useInteractiveGuideline: true,
|
||||
tooltips: true,
|
||||
pointSize: 0,
|
||||
color: ['#444', '#777', '#aaa'],
|
||||
margin: {
|
||||
top: 10,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 20
|
||||
},
|
||||
xAxis: { tickFormat: function (d) { return formatNumber(d, 'time'); } },
|
||||
yAxis: { tickFormat: function (d) { return formatNumber(d, type); }, },
|
||||
y: function (d) { return d.y; },
|
||||
x: function (d) { return d.x; }
|
||||
}
|
||||
};
|
||||
};
|
39
src/plugins/serverStatus/public/lib/readStatData.js
Normal file
39
src/plugins/serverStatus/public/lib/readStatData.js
Normal file
|
@ -0,0 +1,39 @@
|
|||
var _ = require('lodash');
|
||||
|
||||
module.exports = function readStatData(data, seriesNames) {
|
||||
// Metric Values format
|
||||
// metric: [[xValue, yValue], ...]
|
||||
// LoadMetric:
|
||||
// metric: [[xValue, [yValue, yValue2, yValue3]], ...]
|
||||
// return [
|
||||
// {type: 'line', key: name, yAxis: 1, values: [{x: xValue, y: yValue}, ...]},
|
||||
// {type: 'line', key: name, yAxis: 1, values: [{x: xValue, y: yValue1}, ...]},
|
||||
// {type: 'line', key: name, yAxis: 1, values: [{x: xValue, y: yValue2}, ...]}]
|
||||
//
|
||||
// Go through all of the metric values and split the values out.
|
||||
// returns an array of all of the averages
|
||||
|
||||
var metricList = [];
|
||||
seriesNames = seriesNames || [];
|
||||
data.forEach(function (vector) {
|
||||
vector = _.flatten(vector);
|
||||
var x = vector.shift();
|
||||
vector.forEach(function (yValue, i) {
|
||||
var series = seriesNames[i] || '';
|
||||
|
||||
if (!metricList[i]) {
|
||||
metricList[i] = {
|
||||
key: series,
|
||||
values: []
|
||||
};
|
||||
}
|
||||
// unshift to make sure they're in the correct order
|
||||
metricList[i].values.unshift({
|
||||
x: x,
|
||||
y: yValue
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return metricList;
|
||||
};
|
10
src/plugins/serverStatus/public/lib/toTitleCase.js
Normal file
10
src/plugins/serverStatus/public/lib/toTitleCase.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
var _ = require('lodash');
|
||||
|
||||
// Turns thisIsASentence to
|
||||
// This Is A Sentence
|
||||
module.exports = function toTitleCase(name) {
|
||||
return name
|
||||
.split(/(?=[A-Z])/)
|
||||
.map(function (word) { return word[0].toUpperCase() + _.rest(word).join(''); })
|
||||
.join(' ');
|
||||
};
|
|
@ -11,13 +11,13 @@
|
|||
<p>Here is the status of your kibana instance and the plugins you have installed along with some, statistics to asses potential problems.</p>
|
||||
</section>
|
||||
|
||||
<div class="system_status_wrapper state_default state_{{ui.overallStatus.state}}">
|
||||
<div class="system_status_wrapper state_default state_{{ui.overall.state}}">
|
||||
|
||||
<h3 class="title">
|
||||
<b>
|
||||
System Status:
|
||||
</b>
|
||||
{{ui.overallStatus.nickname || ui.overallStatus.title}}
|
||||
{{ui.overall.nickname || ui.overall.title}}
|
||||
</h3>
|
||||
|
||||
<div ng-if="!ui.statuses && ui.loading" class="loading_statuses">
|
||||
|
@ -44,13 +44,8 @@
|
|||
<h2>Server Metrics</h2>
|
||||
<p>Interval of 5 seconds, with a max history of 5 minutes.</p>
|
||||
<div id="chart_cont" class="row">
|
||||
<div ng-repeat="(key, chart) in ui.charts" class="status_chart_wrapper col-md-4">
|
||||
<h3 class="title">{{chart.niceName}}</h2>
|
||||
<h4 class="average">
|
||||
<span ng-repeat="average in chart.average track by $index"><span ng-if="$index">, </span>{{average}}</span>
|
||||
</h4>
|
||||
<nvd3 options="chart.options" data="chart.data"></nvd3>
|
||||
<div ng-repeat="(name, data) in ui.metrics">
|
||||
<server-status-metric></server-status-metric>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
require('plugins/serverStatus/KibanaStatusApp');
|
||||
require('plugins/serverStatus/serverStatusController');
|
||||
require('plugins/serverStatus/serverStatusMetric');
|
||||
require('plugins/serverStatus/serverStatus.less');
|
||||
|
||||
require('chrome')
|
||||
|
@ -9,4 +10,4 @@ require('chrome')
|
|||
}
|
||||
])
|
||||
.setRootTemplate(require('plugins/serverStatus/serverStatus.html'))
|
||||
.setRootController('statusPage', 'StatusPage');
|
||||
.setRootController('ui', 'ServerStatusController');
|
||||
|
|
48
src/plugins/serverStatus/public/serverStatusController.js
Normal file
48
src/plugins/serverStatus/public/serverStatusController.js
Normal file
|
@ -0,0 +1,48 @@
|
|||
var angular = require('angular');
|
||||
var $ = require('jquery');
|
||||
var _ = require('lodash');
|
||||
var notify = require('components/notify');
|
||||
|
||||
// The Kibana App
|
||||
require('modules')
|
||||
.get('kibana')
|
||||
.controller('ServerStatusController', function ($http, $window, $timeout) {
|
||||
var ui = this;
|
||||
ui.loading = false;
|
||||
|
||||
ui.init = function () {
|
||||
$($window)
|
||||
.on('blur', ui.blur)
|
||||
.on('focus', ui.refresh);
|
||||
|
||||
return ui.refresh();
|
||||
};
|
||||
|
||||
ui.blur = function () {
|
||||
$timeout.cancel(ui.timeout);
|
||||
};
|
||||
|
||||
ui.refresh = function () {
|
||||
ui.loading = true;
|
||||
|
||||
// go ahead and get the info you want
|
||||
return $http
|
||||
.get('/api/status')
|
||||
.then(function (resp) {
|
||||
var data = resp.data;
|
||||
|
||||
ui.metrics = data.metrics;
|
||||
ui.overall = data.status.overall;
|
||||
ui.statuses = data.status.statuses;
|
||||
})
|
||||
.catch(function () {
|
||||
notify.error('Failed to request server ui. Perhaps your server is down?');
|
||||
})
|
||||
.then(function () {
|
||||
ui.loading = false;
|
||||
ui.timeout = $timeout(ui.refresh, 5000);
|
||||
});
|
||||
};
|
||||
|
||||
ui.init();
|
||||
});
|
8
src/plugins/serverStatus/public/serverStatusMetric.html
Normal file
8
src/plugins/serverStatus/public/serverStatusMetric.html
Normal file
|
@ -0,0 +1,8 @@
|
|||
<div class="status_chart_wrapper col-md-4">
|
||||
<h3 class="title">{{chart.niceName}}</h3>
|
||||
<h4 class="average">
|
||||
<span ng-repeat="average in chart.average track by $index"><span ng-if="$index">, </span>{{average}}</span>
|
||||
</h4>
|
||||
<nvd3 options="chart.options" data="chart.data"></nvd3>
|
||||
</h4>
|
||||
</div>
|
57
src/plugins/serverStatus/public/serverStatusMetric.js
Normal file
57
src/plugins/serverStatus/public/serverStatusMetric.js
Normal file
|
@ -0,0 +1,57 @@
|
|||
var _ = require('lodash');
|
||||
var moment = require('moment');
|
||||
var numeral = require('numeral');
|
||||
require('angular-nvd3');
|
||||
|
||||
var toTitleCase = require('./lib/toTitleCase');
|
||||
var formatNumber = require('./lib/formatNumber');
|
||||
var getChartOptions = _.memoize(require('./lib/makeChartOptions'));
|
||||
var readStatData = require('./lib/readStatData');
|
||||
|
||||
function metricToNumberType(stat) {
|
||||
switch (stat) {
|
||||
case 'heapTotal':
|
||||
case 'heapUsed':
|
||||
case 'rss':
|
||||
return 'byte';
|
||||
case 'delay':
|
||||
case 'responseTimeAvg':
|
||||
case 'responseTimeMax':
|
||||
return 'ms';
|
||||
default:
|
||||
return 'precise';
|
||||
}
|
||||
}
|
||||
|
||||
function calcAvg(metricList, metricNumberType) {
|
||||
return metricList.map(function (data) {
|
||||
var uglySum = data.values.reduce(function (sumSoFar, vector) {
|
||||
return sumSoFar + vector.y;
|
||||
}, 0);
|
||||
return formatNumber(uglySum / data.values.length, metricNumberType);
|
||||
});
|
||||
}
|
||||
|
||||
require('modules')
|
||||
.get('kibana', ['nvd3'])
|
||||
.directive('serverStatusMetric', function () {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: require('plugins/serverStatus/serverStatusMetric.html'),
|
||||
link: function ($scope, $el, attrs) {
|
||||
var metricNumberType = metricToNumberType($scope.name);
|
||||
|
||||
$scope.chart = {
|
||||
niceName: toTitleCase($scope.name),
|
||||
options: getChartOptions(metricNumberType)
|
||||
};
|
||||
|
||||
$scope.seriesNames = $scope.name === 'load' ? ['1min', '5min', '15min'] : null;
|
||||
|
||||
$scope.$watch('data', function () {
|
||||
$scope.chart.data = readStatData($scope.data, $scope.seriesNames);
|
||||
$scope.chart.average = calcAvg($scope.chart.data, metricNumberType);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
|
@ -11,6 +11,24 @@ module.exports = function (kbnServer, server, config) {
|
|||
|
||||
server.exposeStaticDir('/bundles/{path*}', bundleDir);
|
||||
|
||||
server.ext('onRequest', function (request, reply) {
|
||||
switch (status.state) {
|
||||
case 'yellow':
|
||||
return reply(`
|
||||
<html>
|
||||
<head><meta http-equiv="refresh" content="1"></head>
|
||||
<body>${status.message}</body>
|
||||
</html>
|
||||
`);
|
||||
case 'red':
|
||||
return reply(`
|
||||
<html><body>${status.message}, please wait.</body></html>
|
||||
`);
|
||||
default:
|
||||
return reply.continue();
|
||||
}
|
||||
});
|
||||
|
||||
function start() {
|
||||
kbnServer.optimizer = new Optimizer({
|
||||
watch: config.get('optimize.watch'),
|
||||
|
|
42
src/server/optimize/testBundler.js
Normal file
42
src/server/optimize/testBundler.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
'use strict';
|
||||
|
||||
let promify = require('bluebird').promisify;
|
||||
let glob = promify(require('glob'));
|
||||
let write = promify(require('fs').writeFile);
|
||||
let webpack = promify(require('webpack'));
|
||||
let basename = require('path').basename;
|
||||
|
||||
let fromRoot = require('../../utils/fromRoot');
|
||||
const TEST = fromRoot('test');
|
||||
const UNIT = fromRoot('test/unit');
|
||||
const ENTRY = fromRoot('test/unit.specs.entry.js');
|
||||
const BUNDLE = fromRoot('test/unit.specs.bundle.js');
|
||||
const SPECS = fromRoot('test/unit/specs/**/*.js');
|
||||
const NODE_MODULES = fromRoot('node_modules');
|
||||
|
||||
module.exports = function () {
|
||||
return glob(SPECS, { cwd: '/' })
|
||||
.filter(function (path) {
|
||||
return basename(path)[0] !== '_';
|
||||
})
|
||||
.reduce(function (memo, path) {
|
||||
return `${memo}\nrequire('${path}');`;
|
||||
}, '')
|
||||
.then(function (contents) {
|
||||
return write(ENTRY, contents, { encoding: 'utf8' });
|
||||
})
|
||||
.then(function () {
|
||||
return webpack({
|
||||
context: TEST,
|
||||
entry: ENTRY,
|
||||
output: {
|
||||
path: TEST,
|
||||
filename: 'unit.specs.bundle.js'
|
||||
}
|
||||
});
|
||||
})
|
||||
.then(function (stats) {
|
||||
console.log(stats.toString({ colors: true }));
|
||||
return BUNDLE;
|
||||
});
|
||||
};
|
|
@ -37,15 +37,6 @@ module.exports = function (kbnServer, server, config) {
|
|||
let app = apps.byId[id];
|
||||
if (!app) return reply(Boom.notFound('Unkown app ' + id));
|
||||
|
||||
if (kbnServer.status.getState('optimize') === 'yellow') {
|
||||
return reply(`
|
||||
<html>
|
||||
<head><meta http-equiv="refresh" content="1"></head>
|
||||
<body>Optimization in progress, please wait.</body>
|
||||
</html>
|
||||
`);
|
||||
}
|
||||
|
||||
if (kbnServer.status.isGreen()) {
|
||||
return reply.renderApp(app);
|
||||
} else {
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
ng-class="{ show: !chrome.embedded }"
|
||||
bindonce
|
||||
class="hide navbar navbar-inverse navbar-static-top">
|
||||
<div class="navbar-header">
|
||||
|
||||
<!-- Mobile navbar -->
|
||||
<div class=" -header">
|
||||
<button ng-click="showCollapsed = !showCollapsed" type="button" class="navbar-toggle">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
|
@ -18,6 +20,7 @@
|
|||
<span ng-show="chrome.httpActive.length" class="spinner"></span>
|
||||
</span>
|
||||
</div>
|
||||
<!-- /Mobile navbar -->
|
||||
|
||||
<!-- Full navbar -->
|
||||
<div collapse="!showCollapsed" class="navbar-collapse">
|
||||
|
@ -51,7 +54,10 @@
|
|||
|
||||
<ul ng-show="timefilter.enabled" class="nav navbar-nav navbar-right navbar-timepicker">
|
||||
<li>
|
||||
<a ng-click="toggleRefresh()" ng-show="timefilter.refreshInterval.value > 0">
|
||||
<a
|
||||
ng-click="toggleRefresh()"
|
||||
ng-show="timefilter.refreshInterval.value > 0">
|
||||
|
||||
<i class="fa" ng-class="timefilter.refreshInterval.pause ? 'fa-play' : 'fa-pause'"></i>
|
||||
</a>
|
||||
</li>
|
||||
|
@ -85,8 +91,8 @@
|
|||
<div class="spinner"></div>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- /Full navbar -->
|
||||
</div>
|
||||
<!-- /Full navbar -->
|
||||
</nav>
|
||||
|
||||
<config
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
max-height: <%= truncateMaxHeight %>;
|
||||
display: inline-block;
|
||||
}
|
||||
.truncate-by-height::before {
|
||||
.truncate-by-height:before {
|
||||
top: <%= truncateGradientTop %>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ define(function (require) {
|
|||
.get('kibana')
|
||||
.run(function ($rootScope, $compile, config) {
|
||||
var truncateGradientHeight = 15;
|
||||
var template = _.template(require('raw!components/style_compile/style_compile.css.tmpl'));
|
||||
var template = _.template(require('components/style_compile/style_compile.css.tmpl'));
|
||||
var locals = {};
|
||||
|
||||
$rootScope.$on('$destroy', function () {
|
||||
|
|
36
tasks/config/watch.js
Normal file
36
tasks/config/watch.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
module.exports = function (grunt) {
|
||||
var config = {
|
||||
less: {
|
||||
files: [
|
||||
'<%= app %>/**/styles/**/*.less',
|
||||
'<%= plugins %>/*/styles/**/*.less',
|
||||
'<%= plugins %>/*/*.less',
|
||||
'<%= app %>/**/components/**/*.less',
|
||||
'<%= app %>/**/components/vislib/components/styles/**/*.less',
|
||||
'<%= src %>/server/plugins/status/public/styles/main.less'
|
||||
],
|
||||
tasks: ['less:dev']
|
||||
},
|
||||
|
||||
jade: {
|
||||
files: [
|
||||
'<%= unitTestDir %>/index.jade'
|
||||
],
|
||||
tasks: ['jade:test']
|
||||
},
|
||||
|
||||
clientside_jade: {
|
||||
files: [
|
||||
'<%= testUtilsDir %>/istanbul_reporter/report.clientside.jade'
|
||||
],
|
||||
tasks: ['jade:clientside']
|
||||
}
|
||||
};
|
||||
|
||||
if (grunt.option('no-test-watcher')) {
|
||||
// unset the test watcher
|
||||
delete config.test;
|
||||
}
|
||||
|
||||
return config;
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue