[stringify] replace field formats with stringify component

This commit is contained in:
Spencer Alger 2015-01-22 20:32:27 -07:00
parent 5c3847668d
commit 792059d69a
19 changed files with 187 additions and 60 deletions

View file

@ -2,6 +2,7 @@ define(function (require) {
return function MetricAggTypeProvider(Private, indexPatterns) {
var _ = require('lodash');
var AggType = Private(require('components/agg_types/_agg_type'));
var fieldFormats = Private(require('registry/field_formats'));
_(MetricAggType).inherits(AggType);
function MetricAggType(config) {
@ -26,10 +27,10 @@ define(function (require) {
if (field && field.type === 'date' && field.format) {
return field.format;
} else {
return indexPatterns.fieldFormats.byName.number;
return fieldFormats.converterFor('number');
}
};
return MetricAggType;
};
});
});

View file

@ -80,39 +80,39 @@ define(function (require) {
value: 115,
description: 'The maximum height that a cell in a table should occupy. Set to 0 to disable truncation.'
},
'deafultFormat:ip': {
value: 'string',
'defaultFormat:ip': {
value: 'ip',
description: 'The default format to be used for fields of type ip.'
},
'deafultFormat:date': {
value: 'string',
'defaultFormat:date': {
value: 'date',
description: 'The default format to be used for fields of type date.'
},
'deafultFormat:string': {
'defaultFormat:string': {
value: 'string',
description: 'The default format to be used for fields of type string.'
},
'deafultFormat:number': {
value: 'string',
'defaultFormat:number': {
value: 'number',
description: 'The default format to be used for fields of type number.'
},
'deafultFormat:boolean': {
'defaultFormat:boolean': {
value: 'string',
description: 'The default format to be used for fields of type boolean.'
},
'deafultFormat:conflict': {
'defaultFormat:conflict': {
value: 'string',
description: 'The default format to be used for fields of type conflict.'
},
'deafultFormat:geo_point': {
'defaultFormat:geo_point': {
value: 'string',
description: 'The default format to be used for fields of type geo_point.'
},
'deafultFormat:geo_shape': {
'defaultFormat:geo_shape': {
value: 'string',
description: 'The default format to be used for fields of type geo_shape.'
},
'deafultFormat:attachment': {
'defaultFormat:attachment': {
value: 'string',
description: 'The default format to be used for fields of type attachment.'
}

View file

@ -1,13 +1,13 @@
<dl class="source truncate-by-height">
<% _.each(highlight, function (value, field) { /* show fields that match the query first */ %>
<dt><%= shortDotsFilter(field) %>:</dt>
<dd><%= source[field] %></dd>
<dt><%- shortDotsFilter(field) %>:</dt>
<dd><%- source[field] %></dd>
<%= ' ' %>
<% }); %>
<% _.each(source, function (value, field) { %>
<% if (_.has(highlight, field)) return; %>
<dt><%= shortDotsFilter(field) %>:</dt>
<dd><%= value %></dd>
<dt><%- shortDotsFilter(field) %>:</dt>
<dd><%- value %></dd>
<%= ' ' %>
<% }); %>
</dl>

View file

@ -25,6 +25,7 @@ define(function (require) {
// assign the meta fields
_.each(indexPattern.metaFields, function (meta) {
if (meta === '_source') return;
flat[meta] = hit[meta];
});

View file

@ -6,7 +6,7 @@ define(function (require) {
var getIds = Private(require('components/index_patterns/_get_ids'));
var mapper = Private(require('components/index_patterns/_mapper'));
var fieldFormats = Private(require('components/index_patterns/_field_formats'));
var fieldFormats = Private(require('registry/field_formats'));
var intervals = Private(require('components/index_patterns/_intervals'));
var fieldTypes = Private(require('components/index_patterns/_field_types'));
var flattenHit = require('components/index_patterns/_flatten_hit');
@ -109,7 +109,12 @@ define(function (require) {
format: {
get: function () {
var formatName = self.customFormats && self.customFormats[field.name];
return formatName ? fieldFormats.byName[formatName] : fieldFormats.defaultByType[field.type];
return formatName ? fieldFormats.byName[formatName] : fieldFormats.defaultFor(field.type);
}
},
formatter: {
get: function () {
return field.format.convert;
}
},
sortable: {

View file

@ -0,0 +1,4 @@
{
"extends": "../../../.jshintrc",
"unused": true
}

View file

@ -0,0 +1,14 @@
define(function (require) {
var _ = require('lodash');
var angular = require('angular');
return function format(fn) {
return function (value) {
if (_.isArray(value)) {
return angular.toJson(_.map(value, fn));
} else {
return fn(value);
}
};
};
});

View file

@ -0,0 +1,8 @@
define(function (require) {
var fieldFormats = require('registry/field_formats');
fieldFormats.register(require('components/stringify/bytes'));
fieldFormats.register(require('components/stringify/date'));
fieldFormats.register(require('components/stringify/ip'));
fieldFormats.register(require('components/stringify/number'));
fieldFormats.register(require('components/stringify/string'));
});

View file

@ -0,0 +1,13 @@
define(function (require) {
return function BytesFormatProvider(config) {
var format = require('components/stringify/_format');
return {
name: 'bytes',
fieldTypes: 'number',
convert: format(function (val) {
return (val / 1024).toFixed(config.get('format:numberPrecision')) + ' kb';
})
};
};
});

View file

@ -0,0 +1,35 @@
define(function (require) {
return function DateFormatProvider(config, $rootScope) {
var _ = require('lodash');
var format = require('components/stringify/_format');
var moment = require('moment');
function converter(val) {
if (_.isNumber(val) || _.isDate(val)) {
return moment(val).format(config.get('dateFormat'));
} else {
return val;
}
}
var memoizedConverter;
function memoizeDateFormat() {
memoizedConverter = _.memoize(converter);
}
// memoize now, once config is ready, and every time the date format changes
memoizeDateFormat();
$rootScope.$on('init:config', memoizeDateFormat);
$rootScope.$on('change:config.dateFormat', memoizeDateFormat);
return {
name: 'date',
fieldTypes: 'date',
convert: format(function (val) {
// don't give away our ref to memoizedConverter so
// we can hot-swap when config changes
return memoizedConverter(val);
})
};
};
});

View file

@ -0,0 +1,17 @@
define(function (require) {
return function IpFormatProvider() {
var format = require('components/stringify/_format');
return {
name: 'ip',
fieldType: [
'ip'
],
convert: format(function (val) {
if (!isFinite(val)) return val;
// shazzam!
return [val >>> 24, val >>> 16 & 0xFF, val >>> 8 & 0xFF, val & 0xFF].join('.');
})
};
};
});

View file

@ -0,0 +1,18 @@
define(function (require) {
return function NumberFormatProvider(config) {
var _ = require('lodash');
var format = require('components/stringify/_format');
return {
name: 'number',
fieldType: 'number',
convert: format(function (val) {
if (_.isNumber(val)) {
return +val.toFixed(config.get('format:numberPrecision'));
} else {
return _.asString(val);
}
})
};
};
});

View file

@ -0,0 +1,22 @@
define(function (require) {
return function StringFormatProvider() {
var _ = require('lodash');
var format = require('components/stringify/_format');
return {
name: 'string',
fieldType: [
'number',
'boolean',
'date',
'ip',
'attachment',
'geo_point',
'geo_shape',
'string',
'conflict'
],
convert: format(_.asString)
};
};
});

View file

@ -358,11 +358,11 @@ define(function (require) {
}
var rows = $scope.rows;
var counts = rows.fieldCounts;
var counts = rows.fieldCounts || (rows.fieldCounts = {});
var indexPattern = $scope.searchSource.get('index');
// merge the rows and the hits, use a new array to help watchers
rows = $scope.rows = rows.concat(resp.hits.hits);
rows.fieldCounts = counts;
if (sortFn) {
rows.sort(sortFn);
@ -375,21 +375,16 @@ define(function (require) {
// ---
// when we are sorting results, we need to redo the counts each time because the
// "top 500" may change with each response
if (hit.$$_formatted && !sortFn) return;
if (hit.$$_counted && !sortFn) return;
hit.$$_counted = true;
var formatAndCount = function (value, name) {
// add up the counts for each field name
counts[name] = counts[name] ? counts[name] + 1 : 1;
var defaultFormat = courier.indexPatterns.fieldFormats.defaultByType.string;
var field = $scope.indexPattern.fields.byName[name];
var formatter = (field && field.format) ? field.format : defaultFormat;
return formatter.convert(value);
};
var flatHit = $scope.indexPattern.flattenHit(hit);
hit.$$_formatted = _.mapValues(flatHit, formatAndCount);
var fields = _.keys(indexPattern.formatHit(hit));
var n = fields.length;
var field;
while (field = fields[--n]) {
if (counts[field]) counts[field] += 1;
else counts[field] = 1;
}
});
// apply the field counts to the field list

View file

@ -17,6 +17,7 @@ define(function (require) {
require('components/bind');
require('components/listen');
require('components/fancy_forms/fancy_forms');
require('components/stringify/_register');
require('directives/click_focus');
require('directives/info');
require('directives/spinner');

View file

@ -1,15 +1,26 @@
define(function (require) {
var _ = require('lodash');
// when the registry is empty or the default for a
// field type is not set, we will provide this
// as the "default" format.
var fallbackFormat = { convert: _.asString };
return require('registry/_registry')({
name: 'fieldFormats',
index: ['name'],
group: ['compatability'],
constructor: function (config) {
this.defaultForType = function (type) {
var name = config.get('deafultFormat:' + type);
return this.byName[name] || _.asString;
this.defaultFor = function (type) {
var name = config.get('defaultFormat:' + type);
return this.byName[name] || fallbackFormat;
};
this.converterFor = function (type) {
return this.defaultFor(type).convert;
};
}
});

View file

@ -192,7 +192,7 @@ define(function (require) {
return '';
}
else {
return _.escape('' + val);
return '' + val;
}
}
};

View file

@ -1,17 +0,0 @@
define(function (require) {
var _ = require('lodash');
var map = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'\'': '&#39;',
'"': '&quot;',
};
var regex = new RegExp('[' + _.keys(map).join('') + ']', 'g');
return function htmlEscape(text) {
return text.replace(regex, function (c) {
return map[c];
});
};
});

View file

@ -3,11 +3,10 @@ define(function (require) {
var _ = require('lodash');
var sinon = require('sinon/sinon');
var IndexedArray = require('utils/indexed_array/index');
var fieldFormats = Private(require('components/index_patterns/_field_formats'));
var fieldFormats = Private(require('registry/field_formats'));
var flattenHit = require('components/index_patterns/_flatten_hit');
var getComputedFields = require('components/index_patterns/_get_computed_fields');
function StubIndexPattern(pattern, timeField, fields) {
this.popularizeField = sinon.spy();
this.timeFieldName = timeField;
@ -21,7 +20,7 @@ define(function (require) {
Object.defineProperty(field, 'format', {
enumerable: false,
get: function () {
return fieldFormats.defaultByType[field.type];
return fieldFormats.defaultFor(field.type);
}
});