UNPKG

kibana-123

Version:

Kibana is an open source (Apache Licensed), browser based analytics and search dashboard for Elasticsearch. Kibana is a snap to setup and start using. Kibana strives to be easy to get started with, while also being flexible and powerful, just like Elastic

180 lines (150 loc) 6.41 kB
import 'ui/field_format_editor'; import 'angular-bootstrap-colorpicker'; import 'angular-bootstrap-colorpicker/css/colorpicker.css'; import _ from 'lodash'; import RegistryFieldFormatsProvider from 'ui/registry/field_formats'; import IndexPatternsFieldProvider from 'ui/index_patterns/_field'; import uiModules from 'ui/modules'; import fieldEditorTemplate from 'ui/field_editor/field_editor.html'; import chrome from 'ui/chrome'; import IndexPatternsCastMappingTypeProvider from 'ui/index_patterns/_cast_mapping_type'; import { scriptedFields as docLinks } from '../documentation_links/documentation_links'; import './field_editor.less'; import { GetEnabledScriptingLangsProvider, getSupportedScriptingLangs } from '../scripting_langs'; uiModules .get('kibana', ['colorpicker.module']) .directive('fieldEditor', function (Private, $sce) { let fieldFormats = Private(RegistryFieldFormatsProvider); let Field = Private(IndexPatternsFieldProvider); let getEnabledScriptingLangs = Private(GetEnabledScriptingLangsProvider); const fieldTypesByLang = { painless: ['number', 'string', 'date', 'boolean'], expression: ['number'], default: _.keys(Private(IndexPatternsCastMappingTypeProvider).types.byType) }; return { restrict: 'E', template: fieldEditorTemplate, scope: { getIndexPattern: '&indexPattern', getField: '&field' }, controllerAs: 'editor', controller: function ($scope, Notifier, kbnUrl, $http, $q) { let self = this; let notify = new Notifier({ location: 'Field Editor' }); self.docLinks = docLinks; getEnabledScriptingLangs().then((langs) => { self.scriptingLangs = langs; if (!_.includes(self.scriptingLangs, self.field.lang)) { self.field.lang = undefined; } }); self.indexPattern = $scope.getIndexPattern(); self.field = shadowCopy($scope.getField()); self.formatParams = self.field.format.params(); self.conflictDescriptionsLength = (self.field.conflictDescriptions) ? Object.keys(self.field.conflictDescriptions).length : 0; // only init on first create self.creating = !self.indexPattern.fields.byName[self.field.name]; self.selectedFormatId = _.get(self.indexPattern, ['fieldFormatMap', self.field.name, 'type', 'id']); self.defFormatType = initDefaultFormat(); self.cancel = redirectAway; self.save = function () { let indexPattern = self.indexPattern; let fields = indexPattern.fields; let field = self.field.toActualField(); fields.remove({ name: field.name }); fields.push(field); if (!self.selectedFormatId) { delete indexPattern.fieldFormatMap[field.name]; } else { indexPattern.fieldFormatMap[field.name] = self.field.format; } return indexPattern.save() .then(function () { notify.info('Saved Field "' + self.field.name + '"'); redirectAway(); }); }; self.delete = function () { let indexPattern = self.indexPattern; let field = self.field; indexPattern.fields.remove({ name: field.name }); return indexPattern.save() .then(function () { notify.info('Deleted Field "' + field.name + '"'); redirectAway(); }); }; self.isSupportedLang = function (lang) { return _.contains(getSupportedScriptingLangs(), lang); }; $scope.$watch('editor.selectedFormatId', function (cur, prev) { let format = self.field.format; let changedFormat = cur !== prev; let missingFormat = cur && (!format || format.type.id !== cur); if (!changedFormat || !missingFormat) return; // reset to the defaults, but make sure it's an object self.formatParams = _.assign({}, _.cloneDeep(getFieldFormatType().paramDefaults)); }); $scope.$watch('editor.formatParams', function () { let FieldFormat = getFieldFormatType(); self.field.format = new FieldFormat(self.formatParams); }, true); $scope.$watch('editor.field.type', function (newValue) { self.defFormatType = initDefaultFormat(); self.fieldFormatTypes = [self.defFormatType].concat(fieldFormats.byFieldType[newValue] || []); if (_.isUndefined(_.find(self.fieldFormatTypes, {id: self.selectedFormatId}))) { delete self.selectedFormatId; } }); $scope.$watch('editor.field.lang', function (newValue) { self.fieldTypes = _.get(fieldTypesByLang, newValue, fieldTypesByLang.default); if (!_.contains(self.fieldTypes, self.field.type)) { self.field.type = _.first(self.fieldTypes); } }); // copy the defined properties of the field to a plain object // which is mutable, and capture the changed seperately. function shadowCopy(field) { let changes = {}; let shadowProps = { toActualField: { // bring the shadow copy out of the shadows value: function toActualField() { return new Field(self.indexPattern, _.defaults({}, changes, field.$$spec)); } } }; Object.getOwnPropertyNames(field).forEach(function (prop) { let desc = Object.getOwnPropertyDescriptor(field, prop); shadowProps[prop] = { enumerable: desc.enumerable, get: function () { return _.has(changes, prop) ? changes[prop] : field[prop]; }, set: function (v) { changes[prop] = v; } }; }); return Object.create(null, shadowProps); } function redirectAway() { kbnUrl.changeToRoute(self.indexPattern, self.field.scripted ? 'scriptedFields' : 'indexedFields'); } function getFieldFormatType() { if (self.selectedFormatId) return fieldFormats.getType(self.selectedFormatId); else return fieldFormats.getDefaultType(self.field.type); } function initDefaultFormat() { let def = Object.create(fieldFormats.getDefaultType(self.field.type)); // explicitly set to undefined to prevent inheritting the prototypes id def.id = undefined; def.resolvedTitle = def.title; def.title = '- default - '; return def; } } }; });