diff --git a/src/ui/public/autoload/modules.js b/src/ui/public/autoload/modules.js
index 5919a14605474..32aef92c482e3 100644
--- a/src/ui/public/autoload/modules.js
+++ b/src/ui/public/autoload/modules.js
@@ -1,6 +1,5 @@
import 'angular';
import 'ui/chrome';
-import 'ui/chrome/context';
import 'ui/bind';
import 'ui/bound_to_config_obj';
import 'ui/config';
diff --git a/src/ui/public/chrome/__tests__/config_controls.js b/src/ui/public/chrome/__tests__/config_controls.js
new file mode 100644
index 0000000000000..d9d2c29af1c94
--- /dev/null
+++ b/src/ui/public/chrome/__tests__/config_controls.js
@@ -0,0 +1,54 @@
+import ngMock from 'ngMock';
+import $ from 'jquery';
+import expect from 'expect.js';
+
+import uiModules from 'ui/modules';
+import chromeConfigControlsRegistry from 'ui/registry/chrome_config_controls';
+import Registry from 'ui/registry/_registry';
+import 'ui/chrome/directives/config_controls';
+import 'ui/directives/config';
+
+describe('chrome config controls', function () {
+ let compile;
+ let stubRegistry;
+
+ beforeEach(ngMock.module('kibana', function (PrivateProvider) {
+ stubRegistry = new Registry({
+ order: ['order']
+ });
+
+ PrivateProvider.swap(chromeConfigControlsRegistry, stubRegistry);
+ }));
+
+ beforeEach(ngMock.inject(function ($compile, $rootScope) {
+ compile = function () {
+ const $el = $('');
+ let $scope = $rootScope.$new();
+ $compile($el)($scope);
+ $scope.$digest();
+ return $el;
+ };
+ }));
+
+ it('injects configs from the ui/registry/chrome_config_controls registry', function () {
+ stubRegistry.register(function () {
+ return {
+ name: 'control1',
+ order: 1,
+ config: {
+ }
+ };
+ });
+ stubRegistry.register(function () {
+ return {
+ name: 'control2',
+ order: 2,
+ config: {
+ }
+ };
+ });
+
+ var $el = compile();
+ expect($el.find('config')).to.have.length(2);
+ });
+});
diff --git a/src/ui/public/chrome/__tests__/nav_controls.js b/src/ui/public/chrome/__tests__/nav_controls.js
index 64b3d54ef9d88..2194f6168f94b 100644
--- a/src/ui/public/chrome/__tests__/nav_controls.js
+++ b/src/ui/public/chrome/__tests__/nav_controls.js
@@ -4,18 +4,26 @@ import expect from 'expect.js';
import uiModules from 'ui/modules';
import chromeNavControlsRegistry from 'ui/registry/chrome_nav_controls';
+import chromeConfigControlsRegistry from 'ui/registry/chrome_config_controls';
import Registry from 'ui/registry/_registry';
describe('chrome nav controls', function () {
let compile;
- let stubRegistry;
+ let stubNavRegistry;
+ let stubConfigRegistry;
beforeEach(ngMock.module('kibana', function (PrivateProvider) {
- stubRegistry = new Registry({
+ stubNavRegistry = new Registry({
order: ['order']
});
- PrivateProvider.swap(chromeNavControlsRegistry, stubRegistry);
+ PrivateProvider.swap(chromeNavControlsRegistry, stubNavRegistry);
+
+ stubConfigRegistry = new Registry({
+ order: ['order']
+ });
+
+ PrivateProvider.swap(chromeConfigControlsRegistry, stubConfigRegistry);
}));
beforeEach(ngMock.inject(function ($compile, $rootScope) {
@@ -28,7 +36,7 @@ describe('chrome nav controls', function () {
}));
it('injects templates from the ui/registry/chrome_nav_controls registry', function () {
- stubRegistry.register(function () {
+ stubNavRegistry.register(function () {
return {
name: 'control',
order: 100,
@@ -40,22 +48,39 @@ describe('chrome nav controls', function () {
expect($el.find('#testTemplateEl')).to.have.length(1);
});
+ it('injects templates from the ui/registry/chrome_config_controls registry', function () {
+ stubConfigRegistry.register(function () {
+ return {
+ name: 'control',
+ order: 100,
+ navbar: {
+ template: ``
+ }
+ };
+ });
+
+ var $el = compile();
+ expect($el.find('#testTemplateEl')).to.have.length(1);
+ });
+
it('renders controls in reverse order, assuming that each control will float:right', function () {
- stubRegistry.register(function () {
+ stubConfigRegistry.register(function () {
return {
name: 'control2',
order: 2,
- template: ``
+ navbar: {
+ template: ``
+ }
};
});
- stubRegistry.register(function () {
+ stubNavRegistry.register(function () {
return {
name: 'control1',
order: 1,
template: ``
};
});
- stubRegistry.register(function () {
+ stubNavRegistry.register(function () {
return {
name: 'control3',
order: 3,
diff --git a/src/ui/public/chrome/chrome.html b/src/ui/public/chrome/chrome.html
index 6e5cccbfdd497..65a67b2008fea 100644
--- a/src/ui/public/chrome/chrome.html
+++ b/src/ui/public/chrome/chrome.html
@@ -1,5 +1,5 @@
-
+
diff --git a/src/ui/public/chrome/config/filter.html b/src/ui/public/chrome/config/filter.html
deleted file mode 100644
index 71a3dd32645ef..0000000000000
--- a/src/ui/public/chrome/config/filter.html
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
diff --git a/src/ui/public/chrome/config/interval.html b/src/ui/public/chrome/config/interval.html
deleted file mode 100644
index d41a601709709..0000000000000
--- a/src/ui/public/chrome/config/interval.html
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
diff --git a/src/ui/public/chrome/context.js b/src/ui/public/chrome/context.js
deleted file mode 100644
index 092ea422dcdff..0000000000000
--- a/src/ui/public/chrome/context.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import _ from 'lodash';
-import ConfigTemplate from 'ui/config_template';
-import uiModules from 'ui/modules';
-
-uiModules
-.get('kibana')
-// TODO: all of this really belongs in the timepicker
-.directive('chromeContext', function (timefilter, globalState) {
-
- var listenForUpdates = _.once(function ($scope) {
- $scope.$listen(timefilter, 'update', function (newVal, oldVal) {
- globalState.time = _.clone(timefilter.time);
- globalState.refreshInterval = _.clone(timefilter.refreshInterval);
- globalState.save();
- });
- });
-
- return {
- link: function ($scope) {
- listenForUpdates($scope);
-
- // chrome is responsible for timepicker ui and state transfer...
- $scope.timefilter = timefilter;
- $scope.pickerTemplate = new ConfigTemplate({
- filter: require('ui/chrome/config/filter.html'),
- interval: require('ui/chrome/config/interval.html')
- });
-
- $scope.toggleRefresh = function () {
- timefilter.refreshInterval.pause = !timefilter.refreshInterval.pause;
- };
- }
- };
-});
-
diff --git a/src/ui/public/chrome/directives/append_nav_controls.js b/src/ui/public/chrome/directives/append_nav_controls.js
index d37b9c6fe0a74..2fd90a7a2d247 100644
--- a/src/ui/public/chrome/directives/append_nav_controls.js
+++ b/src/ui/public/chrome/directives/append_nav_controls.js
@@ -1,14 +1,11 @@
+import _ from 'lodash';
import $ from 'jquery';
import chromeNavControlsRegistry from 'ui/registry/chrome_nav_controls';
+import chromeConfigControlsRegistry from 'ui/registry/chrome_config_controls';
import UiModules from 'ui/modules';
import spinnerHtml from './active_http_spinner.html';
-const spinner = {
- name: 'active http requests',
- template: spinnerHtml
-};
-
export default function (chrome, internals) {
UiModules
@@ -17,16 +14,43 @@ export default function (chrome, internals) {
return {
template: function ($element) {
const parts = [$element.html()];
- const controls = Private(chromeNavControlsRegistry);
+ const navs = Private(chromeNavControlsRegistry);
+ const configs = Private(chromeConfigControlsRegistry);
+
+ const controls = [
+ {
+ name: 'active http requests',
+ order: -100,
+ template: spinnerHtml
+ },
+
+ ...navs.map(function (nav) {
+ return {
+ template: `${nav.template}`,
+ order: nav.order
+ };
+ }),
+
+ ...configs.map(function (config) {
+ let $wrapper = $('
');
+ let $directive = $(`
`);
+ $directive.html(config.navbar.template);
+ $wrapper.append($directive);
+ return {
+ template: `${$wrapper.html()}`,
+ order: config.order
+ };
+ }),
+ ];
- for (const control of [spinner, ...controls.inOrder]) {
- parts.unshift(
- ``,
- control.template
- );
- }
+ _.sortBy(controls, 'order').forEach(function (control) {
+ parts.unshift(control.template);
+ });
return parts.join('\n');
+ },
+ controller: function ($scope) {
+ $scope.configs = Private(chromeConfigControlsRegistry).byName;
}
};
});
diff --git a/src/ui/public/chrome/directives/config_controls.html b/src/ui/public/chrome/directives/config_controls.html
new file mode 100644
index 0000000000000..115346011c154
--- /dev/null
+++ b/src/ui/public/chrome/directives/config_controls.html
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/src/ui/public/chrome/directives/config_controls.js b/src/ui/public/chrome/directives/config_controls.js
new file mode 100644
index 0000000000000..fbe4676747ee6
--- /dev/null
+++ b/src/ui/public/chrome/directives/config_controls.js
@@ -0,0 +1,22 @@
+import $ from 'jquery';
+
+import chromeConfigControlsRegistry from 'ui/registry/chrome_config_controls';
+import UiModules from 'ui/modules';
+import configControlsHtml from './config_controls.html';
+
+export default function (chrome, internals) {
+
+ UiModules
+ .get('kibana')
+ .directive('kbnChromeConfigControls', function (Private) {
+ const controls = Private(chromeConfigControlsRegistry);
+ return {
+ restrict: 'E',
+ template: configControlsHtml,
+ controller: function ($scope) {
+ $scope.controls = controls.inOrder;
+ }
+ };
+ });
+
+}
diff --git a/src/ui/public/chrome/directives/index.js b/src/ui/public/chrome/directives/index.js
index 530646292d388..1d38db2acb222 100644
--- a/src/ui/public/chrome/directives/index.js
+++ b/src/ui/public/chrome/directives/index.js
@@ -3,8 +3,10 @@ import 'ui/directives/config';
import './app_switcher';
import kbnChromeProv from './kbn_chrome';
import kbnChromeNavControlsProv from './append_nav_controls';
+import kbnChromeConfigControlsProv from './config_controls';
export default function (chrome, internals) {
kbnChromeProv(chrome, internals);
kbnChromeNavControlsProv(chrome, internals);
+ kbnChromeConfigControlsProv(chrome, internals);
}
diff --git a/src/ui/public/courier/courier.js b/src/ui/public/courier/courier.js
index 486d5bcb20e88..b48b7f9d5b2b6 100644
--- a/src/ui/public/courier/courier.js
+++ b/src/ui/public/courier/courier.js
@@ -22,7 +22,7 @@ import RedirectWhenMissingProvider from './_redirect_when_missing';
uiModules.get('kibana/courier')
-.service('courier', function ($rootScope, Private, Promise, indexPatterns) {
+.service('courier', function ($rootScope, Private, Promise, indexPatterns, timefilter) {
function Courier() {
var self = this;
@@ -134,9 +134,11 @@ uiModules.get('kibana/courier')
};
// Listen for refreshInterval changes
- $rootScope.$watchCollection('timefilter.refreshInterval', function () {
- var refreshValue = _.get($rootScope, 'timefilter.refreshInterval.value');
- var refreshPause = _.get($rootScope, 'timefilter.refreshInterval.pause');
+ $rootScope.$watchCollection(function () {
+ return timefilter.refreshInterval;
+ }, function (interval) {
+ var refreshValue = _.get(interval, 'value');
+ var refreshPause = _.get(interval, 'pause');
if (_.isNumber(refreshValue) && !refreshPause) {
self.fetchInterval(refreshValue);
} else {
diff --git a/src/ui/public/directives/__tests__/timepicker.js b/src/ui/public/directives/__tests__/timepicker.js
index bd8f9f6fe7be6..53b63f6996a19 100644
--- a/src/ui/public/directives/__tests__/timepicker.js
+++ b/src/ui/public/directives/__tests__/timepicker.js
@@ -28,23 +28,18 @@ var init = function () {
clock = sinon.useFakeTimers(moment(anchor).valueOf());
// Create the scope
- ngMock.inject(function ($rootScope, $compile) {
+ ngMock.inject(function ($rootScope, $compile, timefilter) {
// Give us a scope
$parentScope = $rootScope;
// Add some parameters to it
- var timefilter = {
- time : {
- from: moment().subtract(15, 'minutes'),
- to: moment(),
- mode: undefined
- },
- refreshInterval : {
- value : 0,
- display : 'Off'
- }
- };
+ timefilter.time.from = moment().subtract(15, 'minutes');
+ timefilter.time.to = moment();
+ timefilter.time.mode = undefined;
+ timefilter.refreshInterval.value = 0;
+ timefilter.refreshInterval.display = 'Off';
+
$parentScope.timefilter = timefilter;
// Create the element
diff --git a/src/ui/public/registry/chrome_config_controls.js b/src/ui/public/registry/chrome_config_controls.js
new file mode 100644
index 0000000000000..3e0b32c4dc0ac
--- /dev/null
+++ b/src/ui/public/registry/chrome_config_controls.js
@@ -0,0 +1,12 @@
+import _ from 'lodash';
+import uiRegistry from 'ui/registry/_registry';
+export default uiRegistry({
+ name: 'chromeConfigControls',
+ order: ['order'],
+ index: ['name'],
+ constructor() {
+ this.forEach(configControl => {
+ configControl.name = configControl.name.replace(/[^a-zA-Z0-9]/g, '_');
+ });
+ }
+});
diff --git a/src/ui/public/timepicker/config/filter.html b/src/ui/public/timepicker/config/filter.html
new file mode 100644
index 0000000000000..7dcf535fcc5b1
--- /dev/null
+++ b/src/ui/public/timepicker/config/filter.html
@@ -0,0 +1,7 @@
+
+
diff --git a/src/ui/public/timepicker/config/interval.html b/src/ui/public/timepicker/config/interval.html
new file mode 100644
index 0000000000000..529af7868b639
--- /dev/null
+++ b/src/ui/public/timepicker/config/interval.html
@@ -0,0 +1,7 @@
+
+
diff --git a/src/ui/public/timepicker/toggle.js b/src/ui/public/timepicker/toggle.js
index 2b9bf03fdc6be..76eb8f9594d65 100644
--- a/src/ui/public/timepicker/toggle.js
+++ b/src/ui/public/timepicker/toggle.js
@@ -1,16 +1,45 @@
+import _ from 'lodash';
import UiModules from 'ui/modules';
-import chromeNavControlsRegistry from 'ui/registry/chrome_nav_controls';
+import chromeConfigControlsRegistry from 'ui/registry/chrome_config_controls';
+import ConfigTemplate from 'ui/ConfigTemplate';
import toggleHtml from './toggle.html';
+import filterConfig from './config/filter.html';
+import intervalConfig from './config/interval.html';
-// TODO: the chrome-context directive is currently responsible for several variables
-// on scope used by this template. We need to get rid of that directive and move that
-// logic here
+chromeConfigControlsRegistry.register(function (timefilter, globalState) {
+ let pickerTemplate = new ConfigTemplate({
+ filter: filterConfig,
+ interval: intervalConfig
+ });
+
+ var listenForUpdates = _.once(function ($scope) {
+ $scope.$listen(timefilter, 'update', function (newVal, oldVal) {
+ globalState.time = _.clone(timefilter.time);
+ globalState.refreshInterval = _.clone(timefilter.refreshInterval);
+ globalState.save();
+ });
+ });
-chromeNavControlsRegistry.register(function () {
return {
name: 'timepicker toggle',
order: 100,
- template: toggleHtml
+ navbar: {
+ template: toggleHtml,
+ controller: function ($scope) {
+ listenForUpdates($scope);
+ $scope.pickerTemplate = pickerTemplate;
+ $scope.timefilter = timefilter;
+
+ $scope.toggleRefresh = function () {
+ timefilter.refreshInterval.pause = !timefilter.refreshInterval.pause;
+ };
+ }
+ },
+ config: {
+ template: pickerTemplate,
+ close: pickerTemplate.close,
+ object: timefilter
+ }
};
});
diff --git a/src/ui/ui_app.js b/src/ui/ui_app.js
index a14d01e5d9846..4b15f8d771a5b 100644
--- a/src/ui/ui_app.js
+++ b/src/ui/ui_app.js
@@ -36,7 +36,7 @@ class UiApp {
getModules() {
return _.chain([
this.uiExports.find(_.get(this, 'spec.uses', [])),
- this.uiExports.find(['chromeNavControls', 'hacks']),
+ this.uiExports.find(['chromeNavControls', 'hacks', 'chromeConfigControls']),
])
.flatten()
.uniq()
diff --git a/src/ui/ui_exports.js b/src/ui/ui_exports.js
index da5edef1a8f03..b35467849384f 100644
--- a/src/ui/ui_exports.js
+++ b/src/ui/ui_exports.js
@@ -65,6 +65,7 @@ class UiExports {
case 'settingsSections':
case 'docViews':
case 'hacks':
+ case 'chromeConfigControls':
return (plugin, spec) => {
this.aliases[type] = _.union(this.aliases[type] || [], spec);
};