Skip to content

Commit

Permalink
Merge pull request elastic#4924 from epixa/4684-unknown-settings
Browse files Browse the repository at this point in the history
Allow modifying unknown/custom advanced settings
  • Loading branch information
w33ble committed Sep 14, 2015
2 parents e0100b1 + 075a18e commit 89d0b16
Show file tree
Hide file tree
Showing 9 changed files with 200 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
<tr ng-class="conf.value === undefined ? 'default' : 'custom'">
<td class="name">
<b>{{conf.name}}</b>
<span class="smaller" ng-show="conf.value !== undefined">
<span class="smaller" ng-show="!conf.isCustom && conf.value !== undefined">
(Default: <i>{{conf.defVal == undefined ? 'null' : conf.defVal}}</i>)
</span>
<span class="smaller" ng-show="conf.isCustom">
(Custom setting)
</span>
<br>
<span class="smaller" ng-bind-html="conf.description | trustAsHtml"></span>
</td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
<kbn-settings-advanced class="container">
<div class="bs-callout bs-callout-warning">
<h4>Caution: You can break stuff here</h4>
Be careful in here, these settings are for very advanced users only. Tweaks you make here can break large portions of Kibana.
Some of these settings may be undocumented, unsupported or experimental. Blanking a field will cause Kibana to use its internal
defaults which may be unacceptable given other configuration directives.
Be careful in here, these settings are for very advanced users only.
Tweaks you make here can break large portionsof Kibana. Some of these
settings may be undocumented, unsupported or experimental. If a field has
a default value, blanking the field will reset it to its default which
may be unacceptable given other configuration directives. Deleting a
custom setting will permanently remove it from Kibana's config.
</div>
<form role="form">
<input aria-label="Filter" ng-model="advancedFilter" class="form-control span12" type="text" placeholder="Filter"/>
Expand Down
48 changes: 18 additions & 30 deletions src/plugins/kibana/public/settings/sections/advanced/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
define(function (require) {
var _ = require('lodash');
var getValType = require('plugins/kibana/settings/sections/advanced/lib/get_val_type');
var toEditableConfig = require('plugins/kibana/settings/sections/advanced/lib/to_editable_config');


require('plugins/kibana/settings/sections/advanced/advanced_row');
Expand All @@ -20,46 +20,34 @@ define(function (require) {
ESC: 27
};

var NAMED_EDITORS = ['json', 'array', 'boolean', 'select'];
var NORMAL_EDITOR = ['number', 'string', 'null', 'undefined'];

function getEditorType(conf) {
if (_.contains(NAMED_EDITORS, conf.type)) return conf.type;
if (_.contains(NORMAL_EDITOR, conf.type)) return 'normal';
}

function isTypeComplex(conf) {
return !(conf.json || conf.array || conf.bool || conf.normal);
}

function notDefaultConfig(configName) {
return !(configName in configDefaults);
}

function readConfigVals() {
var configVals = config._vals();

$scope.configs = _.map(configDefaults, function (def, name) {
var val = configVals[name];
var conf = {
name: name,
defVal: def.value,
type: getValType(def, val),
description: def.description,
options: def.options,
value: val,
};

var editor = getEditorType(conf);
conf.json = editor === 'json';
conf.select = editor === 'select';
conf.bool = editor === 'boolean';
conf.array = editor === 'array';
conf.normal = editor === 'normal';
conf.tooComplex = !editor;
var customConfig = Object.keys(configVals)
.filter(notDefaultConfig)
.map(name => toEditableConfig(false, name, configVals[name]));

return conf;
});
$scope.configs = _(configDefaults)
.map((def, name) => toEditableConfig(def, name, configVals[name]))
.reject('readonly')
.concat(customConfig)
.value();
}

// react to changes of the config values
var unhook = $rootScope.$on('change:config', readConfigVals);
$scope.$on('$destroy', unhook);

// initial config setup
readConfigVals();
$rootScope.$on('change:config', readConfigVals);
}
};
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

var getEditorType = require('plugins/kibana/settings/sections/advanced/lib/get_editor_type');
var expect = require('expect.js');

describe('Settings', function () {
describe('Advanced', function () {
describe('getEditorType(conf)', function () {
context('when given type has a named editor', function () {
it('returns that named editor', function () {
expect(getEditorType({ type: 'json' })).to.equal('json');
expect(getEditorType({ type: 'array' })).to.equal('array');
expect(getEditorType({ type: 'boolean' })).to.equal('boolean');
expect(getEditorType({ type: 'select' })).to.equal('select');
});
});

context('when given a type of number, string, null, or undefined', function () {
it('returns "normal"', function () {
expect(getEditorType({ type: 'number' })).to.equal('normal');
expect(getEditorType({ type: 'string' })).to.equal('normal');
expect(getEditorType({ type: 'null' })).to.equal('normal');
expect(getEditorType({ type: 'undefined' })).to.equal('normal');
});
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@

var toEditableConfig = require('plugins/kibana/settings/sections/advanced/lib/to_editable_config');
var expect = require('expect.js');

describe('Settings', function () {
describe('Advanced', function () {
describe('toEditableConfig(def, name, value)', function () {
it('sets name', function () {
expect(invoke({ name: 'who' }).name).to.equal('who');
});

it('sets value', function () {
expect(invoke({ value: 'what' }).value).to.equal('what');
});

it('sets type', function () {
expect(invoke({ value: 'what' }).type).to.be('string');
expect(invoke({ value: 0 }).type).to.be('number');
expect(invoke({ value: [] }).type).to.be('array');
});

context('when given a setting definition object', function () {
var def;
beforeEach(function () {
def = {
value: 'the original',
description: 'the one and only',
options: 'all the options'
};
});

it('is not marked as custom', function () {
expect(invoke({ def }).isCustom).to.be.false;
});

it('sets a default value', function () {
expect(invoke({ def }).defVal).to.equal(def.value);
});

it('sets a description', function () {
expect(invoke({ def }).description).to.equal(def.description);
});

it('sets options', function () {
expect(invoke({ def }).options).to.equal(def.options);
});

context('that contains a type', function () {
it('sets that type', function () {
def.type = 'something';
expect(invoke({ def }).type).to.equal(def.type);
});
});

context('that contains a value of type array', function () {
it('sets type to array', function () {
def.value = [];
expect(invoke({ def }).type).to.equal('array');
});
});
});

context('when not given a setting definition object', function () {
it('is marked as custom', function () {
expect(invoke().isCustom).to.be.true;
});

it('sets defVal to undefined', function () {
expect(invoke().defVal).to.be.undefined;
});

it('sets description to undefined', function () {
expect(invoke().description).to.be.undefined;
});

it('sets options to undefined', function () {
expect(invoke().options).to.be.undefined;
});
});
});
});
});

function invoke({ def = false, name = 'woah', value = 'forreal' } = {}) {
return toEditableConfig(def, name, value);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
define(function (require) {
var _ = require('lodash');

var NAMED_EDITORS = ['json', 'array', 'boolean', 'select'];
var NORMAL_EDITOR = ['number', 'string', 'null', 'undefined'];

/**
* @param {object} advanced setting configuration object
* @returns {string} the editor type to use when editing value
*/
function getEditorType(conf) {
if (_.contains(NAMED_EDITORS, conf.type)) return conf.type;
if (_.contains(NORMAL_EDITOR, conf.type)) return 'normal';
}

return getEditorType;
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
define(function (require) {
var _ = require('lodash');
var getValType = require('./get_val_type');
var getEditorType = require('./get_editor_type');

/**
* @param {object} advanced setting definition object
* @param {object} name of setting
* @param {object} current value of setting
* @returns {object} the editable config object
*/
function toEditableConfig(def, name, value) {
var isCustom = !def;
if (isCustom) def = {};

var conf = {
name,
value,
isCustom,
readonly: !!def.readonly,
defVal: def.value,
type: getValType(def, value),
description: def.description,
options: def.options
};

var editor = getEditorType(conf);
conf.json = editor === 'json';
conf.select = editor === 'select';
conf.bool = editor === 'boolean';
conf.array = editor === 'array';
conf.normal = editor === 'normal';
conf.tooComplex = !editor;

return conf;
}

return toEditableConfig;
});
3 changes: 3 additions & 0 deletions src/ui/public/config/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ define(function () {
// wraped in provider so that a new instance is given to each app/test

return {
'buildNum': {
readonly: true
},
'query:queryString:options': {
value: '{ "analyze_wildcard": true }',
description: 'Options for the lucene query string parser',
Expand Down

0 comments on commit 89d0b16

Please sign in to comment.