Merge branch 'master' into pinned-filters

This commit is contained in:
Joe Fleming 2015-05-06 10:05:20 -07:00
commit 2b03b1af6f
12 changed files with 187 additions and 31 deletions

View file

@ -38,7 +38,7 @@ define(function (require) {
if (source.history) {
source.history.push(this);
source.history = _.last(source.history, 20);
source.history = _.last(source.history, 1);
}
};

View file

@ -6,30 +6,29 @@ define(function (require) {
var types = {
html: function (format, convert) {
return function recurse(value, field, hit) {
var type = typeof value;
if (type === 'object' && typeof value.map === 'function') {
if (value.$$_formattedField) return value.$$_formattedField;
var subVals = value.map(recurse);
var useMultiLine = subVals.some(function (sub) {
return sub.indexOf('\n') > -1;
});
return value.$$_formattedField = subVals.join(',' + (useMultiLine ? '\n' : ' '));
if (!value || typeof value.map !== 'function') {
return convert.call(format, value, field, hit);
}
return convert.call(format, value, field, hit);
// format a list of values. Lists of values will have their formatted values cached
if (value.$$_formattedField) return value.$$_formattedField;
var subVals = value.map(recurse);
var useMultiLine = subVals.some(function (sub) {
return sub.indexOf('\n') > -1;
});
return value.$$_formattedField = subVals.join(',' + (useMultiLine ? '\n' : ' '));
};
},
text: function (format, convert) {
return function recurse(value) {
if (value && typeof value.map === 'function') {
return angular.toJson(value.map(recurse), true);
if (!value || typeof value.map !== 'function') {
return convert.call(format, value);
}
return convert.call(format, value);
// format a list of values. In text contexts we just use JSON encoding
return angular.toJson(value.map(recurse), true);
};
}
};

View file

@ -617,12 +617,16 @@ define(function (require) {
* @return {undefined}
*/
TileMap.prototype.destroy = function () {
// Cleanup hanging DOM nodes
$(this.chartEl).find('[class*=" leaflet"]').remove();
if (this.maps && this.maps.length) {
this.maps.forEach(function (map) {
// Cleanup hanging DOM nodes
// TODO: The correct way to handle this is to ensure all listeners are properly removed
var children = $(map._container).find('*');
map.remove();
children.remove();
});
}
this.maps.forEach(function (map) {
map.remove();
});
};
return TileMap;

View file

@ -1 +1 @@
<kbn-agg-table table="table" per-page="editableVis.params.spyPerPage"></kbn-agg-table>
<kbn-agg-table table="table" per-page="editableVis.params.spyPerPage"></kbn-agg-table>

View file

@ -20,7 +20,6 @@ define(function (require) {
$scope.modes = modes;
$scope.toggleDisplay = function () {
$scope.showPageToggle = !$scope.fullScreenSpy;
$scope.setSpyMode($scope.spy.mode ? null : defaultMode);
};
@ -63,4 +62,4 @@ define(function (require) {
}
};
});
});
});

View file

@ -17,6 +17,7 @@ define(function (require) {
self.vislibParams = self._getVislibParams();
self.vislibVis = new vislib.Vis(self.$el[0], self.vislibParams);
if (this.chartData) self.vislibVis.render(this.chartData);
_.each(self.vis.listeners, function (listener, event) {
self.vislibVis.on(event, listener);
@ -36,8 +37,8 @@ define(function (require) {
VislibRenderbot.prototype.buildChartData = buildChartData;
VislibRenderbot.prototype.render = function (esResponse) {
var chartData = this.buildChartData(esResponse);
this.vislibVis.render(chartData);
this.chartData = this.buildChartData(esResponse);
this.vislibVis.render(this.chartData);
};
VislibRenderbot.prototype.destroy = function () {

View file

@ -112,7 +112,8 @@ define(function (require) {
}
var attrs = {
'agg-param': 'agg.type.params[' + idx + ']'
'agg-param': 'agg.type.params[' + idx + ']',
'ng-hide': '!indexedFields.length && ' + idx + ' > 0' // if there are no fields, and this is one of the extra options
};
if (param.advanced) {

View file

@ -26,7 +26,6 @@
.flex(0 0 auto);
margin-right: @padding-base-horizontal;
font-size: 1.5em;
width: 1em;
text-align: center;
}

View file

@ -9,7 +9,7 @@
ng-repeat="type in visTypes.inTitleOrder"
ng-href="{{ visTypeUrl(type) }}">
<div class="wizard-vis-type-heading">
<i aria-hidden="true" class="fa" ng-class="type.icon"></i>
<i aria-hidden="true" class="fa fa-fw" ng-class="type.icon"></i>
<h4>{{type.title}}</h4>
</div>
<span class="wizard-vis-type-description">{{type.description}}</span>
@ -21,4 +21,4 @@
<saved-object-finder
title="Saved Visualizations"
type="visualizations">
</saved-object-finder>
</saved-object-finder>

View file

@ -1,7 +1,7 @@
var child_process = require('child_process');
var join = require('path').join;
module.exports = function (grunt) {
grunt.registerTask('npm_install_kibana', 'NPM isntall kibana server into dist', function () {
grunt.registerTask('npm_install_kibana', 'NPM install kibana server into dist', function () {
var done = this.async();
var cwd = join(grunt.config.get('build'), 'dist', 'kibana', 'src');
var command = 'npm install --production --no-optional';

View file

@ -0,0 +1,152 @@
define(function (require) {
return ['FieldFormat class', function () {
var _ = require('lodash');
var FieldFormat;
var TestFormat;
beforeEach(module('kibana'));
beforeEach(inject(function (Private) {
FieldFormat = Private(require('components/index_patterns/_field_format/FieldFormat'));
TestFormat = function (params) {
TestFormat.Super.call(this, params);
};
TestFormat.id = 'test-format';
TestFormat.title = 'Test Format';
TestFormat.prototype._convert = _.asPrettyString;
_(TestFormat).inherits(FieldFormat);
}));
describe('params', function () {
it('accepts its params via the constructor', function () {
var f = new TestFormat({ foo: 'bar' });
expect(f.param('foo')).to.be('bar');
});
it('allows reading a clone of the params', function () {
var params = { foo: 'bar' };
var f = new TestFormat(params);
var output = f.params();
expect(output).to.eql(params);
expect(output).to.not.be(params);
});
});
describe('type', function () {
it('links the constructor class to instances as the `type`', function () {
var f = new TestFormat();
expect(f.type).to.be(TestFormat);
});
});
describe('toJSON', function () {
it('serializes to a version a basic id and param pair', function () {
var f = new TestFormat({ foo: 'bar' });
var ser = JSON.parse(JSON.stringify(f));
expect(ser).to.eql({ id: 'test-format', params: { foo: 'bar' } });
});
it('removes param values that match the defaults', function () {
TestFormat.paramDefaults = { foo: 'bar' };
var f = new TestFormat({ foo: 'bar', baz: 'bar' });
var ser = JSON.parse(JSON.stringify(f));
expect(ser.params).to.eql({ baz: 'bar' });
});
it('removes the params entirely if they are empty', function () {
var f = new TestFormat();
var ser = JSON.parse(JSON.stringify(f));
expect(ser).to.not.have.property('params');
});
});
describe('converters', function () {
describe('#getConverterFor', function () {
it('returns a converter for a specific content type', function () {
var f = new TestFormat();
expect(f.getConverterFor('html')()).to.be.a('string');
expect(f.getConverterFor('text')()).to.be.a('string');
});
});
describe('#_convert, the instance method or methods used to format values', function () {
it('can be a function, which gets converted to a text and html converter', function () {
TestFormat.prototype._convert = function () {
return 'formatted';
};
var f = new TestFormat();
var text = f.getConverterFor('text');
var html = f.getConverterFor('html');
expect(text).to.not.be(html);
expect(text()).to.be('formatted');
expect(html()).to.be('formatted');
});
it('can be an object, with seperate text and html converter', function () {
TestFormat.prototype._convert = {
text: _.constant('formatted text'),
html: _.constant('formatted html'),
};
var f = new TestFormat();
var text = f.getConverterFor('text');
var html = f.getConverterFor('html');
expect(text).to.not.be(html);
expect(text()).to.be('formatted text');
expect(html()).to.be('formatted html');
});
it('does not escape the output of the text converter', function () {
TestFormat.prototype._convert = _.constant('<script>alert("xxs");</script>');
var f = new TestFormat();
expect(f.convert('', 'text')).to.contain('<');
});
it('does escape the output of the text converter if used in an html context', function () {
TestFormat.prototype._convert = _.constant('<script>alert("xxs");</script>');
var f = new TestFormat();
expect(f.convert('', 'html')).to.not.contain('<');
});
it('does not escape the output of an html specific converter', function () {
TestFormat.prototype._convert = {
text: _.constant('<img>'),
html: _.constant('<img>'),
};
var f = new TestFormat();
expect(f.convert('', 'text')).to.be('<img>');
expect(f.convert('', 'html')).to.be('<img>');
});
});
describe('#convert', function () {
it('formats a value, defaulting to text content type', function () {
TestFormat.prototype._convert = {
text: _.constant('text'),
html: _.constant('html'),
};
var f = new TestFormat();
expect(f.convert('val')).to.be('text');
});
it('formats a value as html, when specified via second param', function () {
TestFormat.prototype._convert = {
text: _.constant('text'),
html: _.constant('html'),
};
var f = new TestFormat();
expect(f.convert('val', 'html')).to.be('html');
});
});
});
}];
});

View file

@ -5,6 +5,7 @@ define(function (require) {
run(require('specs/components/index_pattern/_map_field'));
run(require('specs/components/index_pattern/_pattern_to_wildcard'));
run(require('specs/components/index_pattern/_get_computed_fields'));
run(require('specs/components/index_pattern/_FieldFormat'));
function run(mod) { describe(mod[0], mod[1]); }
});