Merge branch 'master' of github.com:elastic/kibana into update/lodash

This commit is contained in:
Spencer Alger 2015-06-19 10:54:22 -07:00
commit dddfb802c2
9 changed files with 112 additions and 35 deletions

View file

@ -29,7 +29,7 @@ exported.
years.
* {k4pull}3273[Pull Request 3273]: Line smoothing for for line and area charts.
* {k4pull}3464[Pull Request 3464]: You can now specify the extent of the Y axis for charts.
* {k4pull}3526[Pull Request 3526]: You can add columns to Dicover's list of results directly from an entry's table of
* {k4pull}3526[Pull Request 3526]: You can add columns to Discover's list of results directly from an entry's table of
fields.
* {k4pull}3671[Pull Request 3671]: Tile maps now support latitude/longitude filtering.
* {k4pull}3800[Pull Request 3800]: You can now pause auto-refresh on a dashboard.

View file

@ -15,7 +15,7 @@ define(function (require) {
{
name: 'filters',
editor: require('text!components/agg_types/controls/filters.html'),
default: [ {input: {}} ],
default: [ {input: {}, label: ''} ],
write: function (aggConfig, output) {
var inFilters = aggConfig.params.filters;
if (!_.size(inFilters)) return;
@ -29,7 +29,7 @@ define(function (require) {
decorateQuery(query);
var label = _.get(query, 'query_string.query') || angular.toJson(query);
var label = filter.label || _.get(query, 'query_string.query') || angular.toJson(query);
filters[label] = input;
}, {});

View file

@ -1,19 +1,43 @@
<div class="form-group">
<div ng-repeat="filter in agg.params.filters">
<label>Filter {{$index + 1}}</label>
<div class="form-group vis-editor-agg-form-row">
<div class="vis-editor-agg-header">
<label>
Filter {{$index + 1}}
<span ng-if="filter.label">- {{ filter.label }}</span>
</label>
<div class="btn-group">
<button
ng-click="showConfig = !showConfig"
type="button"
class="btn btn-default btn-xs">
<i class="fa fa-tag"></i>
</button>
<button
type="button"
ng-click="agg.params.filters.splice($index, 1)"
class="btn btn-danger btn-xs">
<i class="fa fa-times"></i>
</button>
</div>
</div>
<div class="form-group">
<input validate-query
ng-model="filter.input.query"
type="text"
class="form-control"
name="filter{{$index}}">
</div>
<button
type="button"
ng-click="agg.params.filters.splice($index, 1)"
class="btn btn-danger btn-xs">
<i class="fa fa-times"></i>
</button>
<div class="form-group" ng-show="showConfig">
<label>Filter {{$index + 1}} label</label>
<input
ng-model="filter.label"
placeholder="Label"
type="text"
class="form-control"
name="label{{$index}}">
</div>
</div>
</div>

View file

@ -39,10 +39,40 @@ define(function (require) {
return;
}
_.assign(output.params, paramJSON);
function filteredCombine(srcA, srcB) {
function mergeObjs(a, b) {
return _(a)
.keys()
.union(_.keys(b))
.transform(function (dest, key) {
var val = compare(a[key], b[key]);
if (val !== undefined) dest[key] = val;
}, {})
.value();
}
function mergeArrays(a, b) {
// attempt to merge each value
return _.times(Math.max(a.length, b.length), function (i) {
return compare(a[i], b[i]);
});
}
function compare(a, b) {
if (_.isPlainObject(a) && _.isPlainObject(b)) return mergeObjs(a, b);
if (_.isArray(a) && _.isArray(b)) return mergeArrays(a, b);
if (b === null) return undefined;
if (b !== undefined) return b;
return a;
}
return compare(srcA, srcB);
}
output.params = filteredCombine(output.params, paramJSON);
return;
};
return RawJSONAggParam;
};
});
});

View file

@ -131,6 +131,14 @@
padding: @vis-editor-agg-editor-spacing;
margin-bottom: @vis-editor-agg-editor-spacing;
}
label {
.flex(2 0 0);
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
margin-bottom: 0;
}
}
.visualization-options {

View file

@ -1,20 +1,16 @@
module.exports = function (grunt) {
grunt.registerTask('kibana_server', function (keepalive) {
var done = this.async();
var Kibana = require('../');
var devStatics = require('./utils/dev_statics');
var quiet = !grunt.option('debug') && !grunt.option('verbose');
var port = grunt.option('port');
var settings = { 'logging.quiet': quiet };
if (grunt.option('port')) {
settings['kibana.server.port'] = grunt.option('port');
}
var kibana = new Kibana(settings, [devStatics]);
kibana.listen().then(function (server) {
require('./utils/dev_server')({
'logging.quiet': !grunt.option('debug') && !grunt.option('verbose'),
'kibana.server.port': grunt.option('port')
})
.then(function (server) {
grunt.log.ok('Server started: ' + server.info.uri);
if (keepalive !== 'keepalive') done();
}).catch(done);
})
.catch(done);
});
};

View file

@ -6,7 +6,7 @@ module.exports = function (grunt) {
var http = require('http');
var opts = {
method: 'HEAD',
path: '/',
path: '/status/health',
host: 'localhost',
port: options.port
};
@ -17,9 +17,7 @@ module.exports = function (grunt) {
function onResponse(res) {
grunt.log.debug('Server responded with', res.statusCode);
var app = res.headers['x-app-name'];
if (res.statusCode === 200 && app && app === 'kibana') {
if (res.statusCode === 200) {
grunt.log.ok('Kibana server already started on port', options.port);
} else {
grunt.log.error('Another server is already running on port', options.port);

12
tasks/utils/dev_server.js Normal file
View file

@ -0,0 +1,12 @@
var Kibana = require('../../');
var devStatics = require('./dev_statics');
module.exports = function (settings) {
var kibana = new Kibana(settings || {}, [devStatics]);
return kibana.listen();
};
if (require.main === module) {
module.exports();
}

View file

@ -29,18 +29,18 @@ define(function (require) {
BaseAggParam = Private(require('components/agg_types/param_types/base'));
JsonAggParam = Private(require('components/agg_types/param_types/raw_json'));
initAggParam();
}));
describe('constructor', function () {
it('it is an instance of BaseAggParam', function () {
initAggParam();
expect(aggParam).to.be.a(BaseAggParam);
});
});
describe('write', function () {
it('should do nothing when param is not defined', function () {
initAggParam();
expect(aggConfig.params).not.to.have.property(paramName);
aggParam.write(aggConfig, output);
@ -48,7 +48,6 @@ define(function (require) {
});
it('should not append param when invalid JSON', function () {
initAggParam();
aggConfig.params[paramName] = 'i am not json';
aggParam.write(aggConfig, output);
@ -57,8 +56,6 @@ define(function (require) {
});
it('should append param when valid JSON', function () {
initAggParam();
var jsonData = JSON.stringify({
new_param: 'should exist in output'
});
@ -75,8 +72,6 @@ define(function (require) {
});
it('should not overwrite existing params', function () {
initAggParam();
var jsonData = JSON.stringify({
new_param: 'should exist in output',
existing: 'should be used'
@ -88,6 +83,20 @@ define(function (require) {
aggParam.write(aggConfig, output);
expect(output.params).to.eql(JSON.parse(jsonData));
});
it('should drop nulled params', function () {
var jsonData = JSON.stringify({
new_param: 'should exist in output',
field: null
});
output.params.field = 'extensions';
aggConfig.params[paramName] = jsonData;
aggParam.write(aggConfig, output);
expect(Object.keys(output.params)).to.contain('new_param');
expect(Object.keys(output.params)).to.not.contain('field');
});
});
}];
});