Merge pull request #4594 from jbudz/issues/1726

Color field format
This commit is contained in:
Jonathan Budzenski 2015-10-12 13:58:41 -05:00
commit 935b3d9d0b
9 changed files with 174 additions and 2 deletions

View file

@ -62,6 +62,7 @@
"@spalger/ui-ace": "0.2.3",
"angular": "1.2.28",
"angular-bindonce": "0.3.1",
"angular-bootstrap-colorpicker": "3.0.19",
"angular-elastic": "2.5.0",
"angular-route": "1.2.28",
"ansicolors": "0.3.2",

View file

@ -1,9 +1,11 @@
define(function (require) {
require('ui/field_format_editor');
require('angular-bootstrap-colorpicker');
require('angular-bootstrap-colorpicker/css/colorpicker.css');
require('ui/modules')
.get('kibana')
.get('kibana', ['colorpicker.module'])
.directive('fieldEditor', function (Private, $sce) {
var _ = require('lodash');
var fieldFormats = Private(require('ui/registry/field_formats'));
@ -78,7 +80,7 @@ define(function (require) {
if (!changedFormat || !missingFormat) return;
// reset to the defaults, but make sure it's an object
self.formatParams = _.assign({}, getFieldFormatType().paramDefaults);
self.formatParams = _.assign({}, _.cloneDeep(getFieldFormatType().paramDefaults));
});
$scope.$watch('editor.formatParams', function () {

View file

@ -0,0 +1,38 @@
describe('Color Format', function () {
var fieldFormats;
var ColorFormat;
var expect = require('expect.js');
var ngMock = require('ngMock');
beforeEach(ngMock.module('kibana'));
beforeEach(ngMock.inject(function (Private) {
fieldFormats = Private(require('ui/registry/field_formats'));
ColorFormat = fieldFormats.getType('color');
}));
it('should add colors if the value is in range', function () {
var colorer = new ColorFormat({
colors: [{
range: '100:150',
text: 'blue',
background: 'yellow'
}]
});
expect(colorer.convert(99, 'html')).to.eql('99');
expect(colorer.convert(100, 'html')).to.eql('<span style="color: blue;background-color: yellow;">100</span>');
expect(colorer.convert(150, 'html')).to.eql('<span style="color: blue;background-color: yellow;">150</span>');
expect(colorer.convert(151, 'html')).to.eql('151');
});
it('should not convert invalid ranges', function () {
var colorer = new ColorFormat({
colors: [{
range: '100150',
text: 'blue',
background: 'yellow'
}]
});
expect(colorer.convert(99, 'html')).to.eql('99');
});
});

View file

@ -12,6 +12,7 @@ var formatIds = [
'ip',
'number',
'percent',
'color',
'string',
'url',
'_source'

View file

@ -4,5 +4,6 @@ describe('Stringify Component', function () {
require('./_source');
require('./_string');
require('./_url');
require('./_color');
require('./_date');
});

View file

@ -0,0 +1,51 @@
<div class="form-group">
<div ng-repeat="color in editor.formatParams.colors">
<div class="editor-color">
<button ng-if="editor.formatParams.colors.length > 1" aria-label="Remove Color" ng-click="removeColor($index)" tooltip="Remove Color" tooltip-append-to-body="true" type="button" class="btn btn-xs btn-danger editor-color-remove">
<i aria-hidden="true" class="fa fa-times"></i>
</button>
<div class="form-group">
<label>Range
<small>
(min:max)
</small>
</label>
<input
ng-model="color.range"
class="form-control">
</div>
<div class="form-group">
<label>Font Color</label>
<input
ng-model="color.text"
colorpicker
type="text"
class="form-control">
</div>
<div class="form-group">
<label>Background Color</label>
<input
ng-model="color.background"
colorpicker
type="text"
class="form-control">
</div>
<div class="form-group">
<label>Example</label>
<div class="form-control"
ng-style="{color: color.text, 'background-color': color.background}"
value="formatted">
123456
</div>
</div>
</div>
<hr>
</div>
<button aria-label="Add Color" ng-click="addColor()" tooltip="Add Color" tooltip-append-to-body="true" type="button" class="btn btn-primary btn-xs">
<span class="sr-only">Add Color</span>
<i aria-hidden="true" class="fa fa-plus"></i> Add Color
</button>
</div>

View file

@ -0,0 +1,17 @@
.editor-color {
display: flex;
position: relative;
> .form-group {
flex: 1 1 1%;
padding-right: 5px;
&:last-child {
padding-right: 0;
}
}
}
.editor-color-remove {
position: absolute;
right: 0;
top: -10px;
}

View file

@ -8,4 +8,5 @@ define(function (require) {
fieldFormats.register(require('ui/stringify/types/Percent'));
fieldFormats.register(require('ui/stringify/types/String'));
fieldFormats.register(require('ui/stringify/types/Source'));
fieldFormats.register(require('ui/stringify/types/Color'));
});

View file

@ -0,0 +1,60 @@
define(function (require) {
return function _StringProvider(Private) {
require('ui/stringify/editors/color.less');
const _ = require('lodash');
const FieldFormat = Private(require('ui/index_patterns/_field_format/FieldFormat'));
const DEFAULT_COLOR = {
range: `${Number.NEGATIVE_INFINITY}:${Number.POSITIVE_INFINITY}`,
text: '#000000',
background: '#ffffff'
};
_.class(_Color).inherits(FieldFormat);
function _Color(params) {
_Color.Super.call(this, params);
}
_Color.id = 'color';
_Color.title = 'Color';
_Color.fieldType = [
'number'
];
_Color.editor = {
template: require('ui/stringify/editors/color.html'),
controller($scope) {
$scope.addColor = function () {
$scope.editor.formatParams.colors.push(_.cloneDeep(DEFAULT_COLOR));
};
$scope.removeColor = function (index) {
$scope.editor.formatParams.colors.splice(index, 1);
};
}
};
_Color.paramDefaults = {
colors: [_.cloneDeep(DEFAULT_COLOR)]
};
_Color.prototype._convert = {
html(val) {
const color = _.findLast(this.param('colors'), ({ range }) => {
if (!range) return;
const [start, end] = range.split(':');
return val >= Number(start) && val <= Number(end);
});
if (!color) return _.asPrettyString(val);
const styleColor = color.text ? `color: ${color.text};` : '';
const styleBackgroundColor = color.background ? `background-color: ${color.background};` : '';
return `<span style="${styleColor}${styleBackgroundColor}">${_.escape(val)}</span>`;
}
};
return _Color;
};
});