From aba9108eef11ec9e4316601511bae95641f15bb2 Mon Sep 17 00:00:00 2001 From: Joe Fleming Date: Mon, 13 Jun 2016 15:08:20 -0700 Subject: [PATCH 1/4] create a navbar-extensions directive --- .../navbar_extensions/navbar_extensions.js | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/ui/public/navbar_extensions/navbar_extensions.js diff --git a/src/ui/public/navbar_extensions/navbar_extensions.js b/src/ui/public/navbar_extensions/navbar_extensions.js new file mode 100644 index 0000000000000..1b87a1790761a --- /dev/null +++ b/src/ui/public/navbar_extensions/navbar_extensions.js @@ -0,0 +1,47 @@ +const _ = require('lodash'); +const $ = require('jquery'); +const navbar = require('ui/modules').get('kibana'); + +require('ui/render_directive'); + +navbar.directive('navbarExtensions', function (Private, $compile) { + const navbarExtensionsRegistry = Private(require('ui/registry/navbar_extensions')); + const getExtensions = _.memoize(function (name) { + if (!name) throw new Error('navbar directive requires a name attribute'); + return _.sortBy(navbarExtensionsRegistry.byAppName[name], 'order'); + }); + + return { + scope: { + configTemplate: '=' + }, + restrict: 'E', + link: function ($scope, $el, $attr) { + if (!$scope.configTemplate) throw new Error('navbar extensions require a configTemplate'); + + const extensions = getExtensions($attr.name); + + extensions.forEach(function (extension) { + $scope.configTemplate.push(extension.name, extension.template); + + const extScope = $scope.$new(); + const $ext = $(` + + + + `); + const $ctrl = $compile($ext)(extScope); + $el.append($ctrl); + }); + }, + controllerAs: 'navbarExtensions', + controller: function ($attrs) { + this.extensions = getExtensions($attrs.name); + } + }; +}); From 844b95253e614e3385dbca868dfb0e414aad7cf3 Mon Sep 17 00:00:00 2001 From: Joe Fleming Date: Mon, 13 Jun 2016 15:08:52 -0700 Subject: [PATCH 2/4] use navbar-extensions in apps, remove navbar requires --- src/plugins/kibana/public/dashboard/index.html | 1 + src/plugins/kibana/public/dashboard/index.js | 2 +- src/plugins/kibana/public/discover/index.html | 1 + src/plugins/kibana/public/discover/index.js | 2 +- src/plugins/kibana/public/visualize/editor/editor.html | 1 + src/plugins/kibana/public/visualize/editor/editor.js | 2 +- 6 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/plugins/kibana/public/dashboard/index.html b/src/plugins/kibana/public/dashboard/index.html index 9a3f94fa3832e..cc9743157243f 100644 --- a/src/plugins/kibana/public/dashboard/index.html +++ b/src/plugins/kibana/public/dashboard/index.html @@ -84,6 +84,7 @@ + diff --git a/src/plugins/kibana/public/dashboard/index.js b/src/plugins/kibana/public/dashboard/index.js index d0f9da568a276..a14edf32e8601 100644 --- a/src/plugins/kibana/public/dashboard/index.js +++ b/src/plugins/kibana/public/dashboard/index.js @@ -10,7 +10,7 @@ define(function (require) { require('ui/config'); require('ui/notify'); require('ui/typeahead'); - require('ui/navbar'); + require('ui/navbar_extensions'); require('ui/share'); require('plugins/kibana/dashboard/directives/grid'); diff --git a/src/plugins/kibana/public/discover/index.html b/src/plugins/kibana/public/discover/index.html index 215bfe5ab0e9d..9f4b25b2d533c 100644 --- a/src/plugins/kibana/public/discover/index.html +++ b/src/plugins/kibana/public/discover/index.html @@ -60,6 +60,7 @@ + diff --git a/src/plugins/kibana/public/discover/index.js b/src/plugins/kibana/public/discover/index.js index 21b2e6a082945..47b0b2d6ebd8f 100644 --- a/src/plugins/kibana/public/discover/index.js +++ b/src/plugins/kibana/public/discover/index.js @@ -1,7 +1,7 @@ define(function (require, module, exports) { require('plugins/kibana/discover/saved_searches/saved_searches'); require('plugins/kibana/discover/directives/timechart'); - require('ui/navbar'); + require('ui/navbar_extensions'); require('ui/collapsible_sidebar'); require('plugins/kibana/discover/components/field_chooser/field_chooser'); require('plugins/kibana/discover/controllers/discover'); diff --git a/src/plugins/kibana/public/visualize/editor/editor.html b/src/plugins/kibana/public/visualize/editor/editor.html index c50e7f2ec3b92..d15c12f798080 100644 --- a/src/plugins/kibana/public/visualize/editor/editor.html +++ b/src/plugins/kibana/public/visualize/editor/editor.html @@ -112,6 +112,7 @@ + diff --git a/src/plugins/kibana/public/visualize/editor/editor.js b/src/plugins/kibana/public/visualize/editor/editor.js index 85466abe0fd70..9a8d1daf21cfc 100644 --- a/src/plugins/kibana/public/visualize/editor/editor.js +++ b/src/plugins/kibana/public/visualize/editor/editor.js @@ -4,7 +4,7 @@ define(function (require) { require('plugins/kibana/visualize/editor/sidebar'); require('plugins/kibana/visualize/editor/agg_filter'); - require('ui/navbar'); + require('ui/navbar_extensions'); require('ui/visualize'); require('ui/collapsible_sidebar'); require('ui/share'); From 3f99cb75a50e67b045a4342b3a34378ba51af6c4 Mon Sep 17 00:00:00 2001 From: Joe Fleming Date: Mon, 13 Jun 2016 15:09:07 -0700 Subject: [PATCH 3/4] remove navbar directive --- src/ui/public/ConfigTemplate.js | 4 + src/ui/public/navbar/__tests__/navbar.js | 140 ----------------------- src/ui/public/navbar/navbar.js | 56 --------- 3 files changed, 4 insertions(+), 196 deletions(-) delete mode 100644 src/ui/public/navbar/__tests__/navbar.js delete mode 100644 src/ui/public/navbar/navbar.js diff --git a/src/ui/public/ConfigTemplate.js b/src/ui/public/ConfigTemplate.js index 13026f55de5d3..efdeb27ba2465 100644 --- a/src/ui/public/ConfigTemplate.js +++ b/src/ui/public/ConfigTemplate.js @@ -22,6 +22,10 @@ define(function (require) { return newState; } + template.push = function (name, tpl) { + templates[name] = tpl; + }; + template.is = function (name) { return template.current === templates[name]; }; diff --git a/src/ui/public/navbar/__tests__/navbar.js b/src/ui/public/navbar/__tests__/navbar.js deleted file mode 100644 index 9f8c3e9910b60..0000000000000 --- a/src/ui/public/navbar/__tests__/navbar.js +++ /dev/null @@ -1,140 +0,0 @@ -const ngMock = require('ngMock'); -const sinon = require('sinon'); -const expect = require('expect.js'); -const angular = require('angular'); -const _ = require('lodash'); - -require('ui/navbar'); -const navbarExtensionsRegistry = require('ui/registry/navbar_extensions'); -const Registry = require('ui/registry/_registry'); - -const defaultMarkup = ` - - - `; - - -describe('navbar directive', function () { - let $rootScope; - let $compile; - let stubRegistry; - - beforeEach(function () { - ngMock.module('kibana', function (PrivateProvider) { - stubRegistry = new Registry({ - index: ['name'], - group: ['appName'], - order: ['order'] - }); - - PrivateProvider.swap(navbarExtensionsRegistry, stubRegistry); - }); - - ngMock.module('kibana/navbar'); - - // Create the scope - ngMock.inject(function ($injector) { - $rootScope = $injector.get('$rootScope'); - $compile = $injector.get('$compile'); - }); - }); - - function init(markup = defaultMarkup) { - // Give us a scope - const $el = angular.element(markup); - $compile($el)($rootScope); - $el.scope().$digest(); - return $el; - } - - describe('incorrect use', function () { - it('should throw if missing a name property', function () { - const markup = ``; - expect(() => init(markup)).to.throwException(/requires a name attribute/); - }); - - it('should throw if missing a button group', function () { - const markup = ``; - expect(() => init(markup)).to.throwException(/must have exactly 1 button group/); - }); - - it('should throw if multiple button groups', function () { - const markup = ` - - - `; - expect(() => init(markup)).to.throwException(/must have exactly 1 button group/); - }); - - it('should throw if button group not direct child', function () { - const markup = `
`; - expect(() => init(markup)).to.throwException(/must have exactly 1 button group/); - }); - }); - - describe('injecting extensions', function () { - function registerExtension(def = {}) { - stubRegistry.register(function () { - return _.defaults(def, { - name: 'exampleButton', - appName: 'testing', - order: 0, - template: ` - ` - }); - }); - } - - it('should use the default markup', function () { - var $el = init(); - expect($el.find('.button-group button').length).to.equal(3); - }); - - it('should append to end then order == 0', function () { - registerExtension({ order: 0 }); - var $el = init(); - - expect($el.find('.button-group button').length).to.equal(4); - expect($el.find('.button-group button').last().hasClass('test-button')).to.be.ok(); - }); - - it('should append to end then order > 0', function () { - registerExtension({ order: 1 }); - var $el = init(); - - expect($el.find('.button-group button').length).to.equal(4); - expect($el.find('.button-group button').last().hasClass('test-button')).to.be.ok(); - }); - - it('should append to end then order < 0', function () { - registerExtension({ order: -1 }); - var $el = init(); - - expect($el.find('.button-group button').length).to.equal(4); - expect($el.find('.button-group button').first().hasClass('test-button')).to.be.ok(); - }); - }); -}); diff --git a/src/ui/public/navbar/navbar.js b/src/ui/public/navbar/navbar.js deleted file mode 100644 index 2e49a760708be..0000000000000 --- a/src/ui/public/navbar/navbar.js +++ /dev/null @@ -1,56 +0,0 @@ -const _ = require('lodash'); -const $ = require('jquery'); -const navbar = require('ui/modules').get('kibana/navbar'); - -require('ui/render_directive'); - -navbar.directive('navbar', function (Private, $compile) { - const navbarExtensions = Private(require('ui/registry/navbar_extensions')); - const getExtensions = _.memoize(function (name) { - if (!name) throw new Error('navbar directive requires a name attribute'); - return _.sortBy(navbarExtensions.byAppName[name], 'order'); - }); - - return { - restrict: 'E', - template: function ($el, $attrs) { - const $buttonGroup = $el.children('.button-group'); - if ($buttonGroup.length !== 1) throw new Error('navbar must have exactly 1 button group'); - - const extensions = getExtensions($attrs.name); - const buttons = $buttonGroup.children().detach().toArray(); - const controls = [ - ...buttons.map(function (button) { - return { - order: 0, - $el: $(button), - }; - }), - ...extensions.map(function (extension, i) { - return { - order: extension.order, - index: i, - extension: extension, - }; - }), - ]; - - _.sortBy(controls, 'order').forEach(function (control) { - if (control.$el) { - return $buttonGroup.append(control.$el); - } - - const { extension, index } = control; - const $ext = $(``); - $ext.html(extension.template); - $buttonGroup.append($ext); - }); - - return $el.html(); - }, - controllerAs: 'navbar', - controller: function ($attrs) { - this.extensions = getExtensions($attrs.name); - } - }; -}); From c699992c3f458b56d52d81d46c333fbe65a369b3 Mon Sep 17 00:00:00 2001 From: Joe Fleming Date: Mon, 13 Jun 2016 15:29:46 -0700 Subject: [PATCH 4/4] remove render_directive --- .../navbar_extensions/navbar_extensions.js | 2 - .../__tests__/render_directive.js | 65 ------------------- .../render_directive/render_directive.js | 30 --------- 3 files changed, 97 deletions(-) delete mode 100644 src/ui/public/render_directive/__tests__/render_directive.js delete mode 100644 src/ui/public/render_directive/render_directive.js diff --git a/src/ui/public/navbar_extensions/navbar_extensions.js b/src/ui/public/navbar_extensions/navbar_extensions.js index 1b87a1790761a..e1185e355097d 100644 --- a/src/ui/public/navbar_extensions/navbar_extensions.js +++ b/src/ui/public/navbar_extensions/navbar_extensions.js @@ -2,8 +2,6 @@ const _ = require('lodash'); const $ = require('jquery'); const navbar = require('ui/modules').get('kibana'); -require('ui/render_directive'); - navbar.directive('navbarExtensions', function (Private, $compile) { const navbarExtensionsRegistry = Private(require('ui/registry/navbar_extensions')); const getExtensions = _.memoize(function (name) { diff --git a/src/ui/public/render_directive/__tests__/render_directive.js b/src/ui/public/render_directive/__tests__/render_directive.js deleted file mode 100644 index 1168bed286a4f..0000000000000 --- a/src/ui/public/render_directive/__tests__/render_directive.js +++ /dev/null @@ -1,65 +0,0 @@ -const angular = require('angular'); -const sinon = require('sinon'); -const expect = require('expect.js'); -const ngMock = require('ngMock'); - -require('ui/render_directive'); - -let $parentScope; -let $elem; -let $directiveScope; - -function init(markup = '', definition = {}) { - ngMock.module('kibana/render_directive'); - - // Create the scope - ngMock.inject(function ($rootScope, $compile) { - $parentScope = $rootScope; - - // create the markup - $elem = angular.element(''); - $elem.html(markup); - if (definition !== null) { - $parentScope.definition = definition; - $elem.attr('definition', 'definition'); - } - - // compile the directive - $compile($elem)($parentScope); - $parentScope.$apply(); - - $directiveScope = $elem.isolateScope(); - }); -} - -describe('render_directive', function () { - describe('directive requirements', function () { - it('should throw if not given a definition', function () { - expect(() => init('', null)).to.throwException(/must have a definition/); - }); - }); - - describe('rendering with definition', function () { - it('should call link method', function () { - const markup = '

hello world

'; - const definition = { - link: sinon.stub(), - }; - - init(markup, definition); - - sinon.assert.callCount(definition.link, 1); - }); - - it('should call controller method', function () { - const markup = '

hello world

'; - const definition = { - controller: sinon.stub(), - }; - - init(markup, definition); - - sinon.assert.callCount(definition.controller, 1); - }); - }); -}); diff --git a/src/ui/public/render_directive/render_directive.js b/src/ui/public/render_directive/render_directive.js deleted file mode 100644 index 21ee171e90e05..0000000000000 --- a/src/ui/public/render_directive/render_directive.js +++ /dev/null @@ -1,30 +0,0 @@ -const _ = require('lodash'); -const $ = require('jquery'); -const module = require('ui/modules').get('kibana/render_directive'); - -module.directive('renderDirective', function () { - return { - restrict: 'E', - scope: { - 'definition': '=' - }, - template: function ($el, $attrs) { - return $el.html(); - }, - controller: function ($scope, $element, $attrs, $transclude) { - if (!$scope.definition) throw new Error('render-directive must have a definition attribute'); - - const { controller, controllerAs } = $scope.definition; - if (controller) { - if (controllerAs) $scope[controllerAs] = this; - $scope.$eval(controller, { $scope, $element, $attrs, $transclude }); - } - }, - link: function ($scope, $el, $attrs) { - const { link } = $scope.definition; - if (link) { - link($scope, $el, $attrs); - } - } - }; -}); \ No newline at end of file