-
diff --git a/src/ui/public/chrome/appSwitcher/appSwitcher.js b/src/ui/public/chrome/appSwitcher/appSwitcher.js
new file mode 100644
index 0000000000000..61d2d6311381c
--- /dev/null
+++ b/src/ui/public/chrome/appSwitcher/appSwitcher.js
@@ -0,0 +1,51 @@
+var parse = require('url').parse;
+var bindKey = require('lodash').bindKey;
+
+require('../appSwitcher/appSwitcher.less');
+var DomLocationProvider = require('ui/domLocation');
+
+require('ui/modules')
+.get('kibana')
+.directive('appSwitcher', function () {
+ return {
+ restrict: 'E',
+ template: require('./appSwitcher.html'),
+ controllerAs: 'switcher',
+ controller: function ($scope, Private) {
+ var domLocation = Private(DomLocationProvider);
+
+ // since we render this in an isolate scope we can't "require: ^chrome", but
+ // rather than remove all helpfull checks we can just check here.
+ if (!$scope.chrome || !$scope.chrome.getNavLinks) {
+ throw new TypeError('appSwitcher directive requires the "chrome" config-object');
+ }
+
+ this.getNavLinks = bindKey($scope.chrome, 'getNavLinks');
+
+ // links don't cause full-navigation events in certain scenarios
+ // so we force them when needed
+ this.ensureNavigation = function (event, app) {
+ if (event.isDefaultPrevented() || event.altKey || event.metaKey || event.ctrlKey) {
+ return;
+ }
+
+ var toParsed = parse(event.delegateTarget.href);
+ var fromParsed = parse(domLocation.href);
+ var sameProto = toParsed.protocol === fromParsed.protocol;
+ var sameHost = toParsed.host === fromParsed.host;
+ var samePath = toParsed.path === fromParsed.path;
+
+ if (sameProto && sameHost && samePath) {
+ toParsed.hash && domLocation.reload();
+
+ // event.preventDefault() keeps the browser from seeing the new url as an update
+ // and even setting window.location does not mimic that behavior, so instead
+ // we use stopPropagation() to prevent angular from seeing the click and
+ // starting a digest cycle/attempting to handle it in the router.
+ event.stopPropagation();
+ }
+ };
+
+ }
+ };
+});
diff --git a/src/ui/public/chrome/appSwitcher/appSwitcher.less b/src/ui/public/chrome/appSwitcher/appSwitcher.less
index 8b888de07e4ef..95ac50baa310c 100644
--- a/src/ui/public/chrome/appSwitcher/appSwitcher.less
+++ b/src/ui/public/chrome/appSwitcher/appSwitcher.less
@@ -1,6 +1,7 @@
@import (reference) "~ui/styles/variables";
@app-icon-size: 48px;
+@app-icon-padding: 10px;
.app-links {
text-align: justify;
@@ -8,9 +9,11 @@
.app-link {
display: inline-block;
vertical-align: top;
- width: @app-icon-size;
- margin: 0px 10px;
text-align: left;
+ width: @app-icon-size + (@app-icon-padding * 2);
+ margin: 0px 10px;
+ padding: @app-icon-padding;
+ border-radius: @border-radius-base;
.app-icon {
display: block;
@@ -43,6 +46,13 @@
text-decoration: underline;
}
+ &.active {
+ background: @gray-lighter;
+ .app-title {
+ text-decoration: underline;
+ }
+ }
+
}
}
diff --git a/src/ui/public/domLocation.js b/src/ui/public/domLocation.js
new file mode 100644
index 0000000000000..f17926fd10a1a
--- /dev/null
+++ b/src/ui/public/domLocation.js
@@ -0,0 +1,15 @@
+module.exports = function DomLocationProvider($window) {
+ return {
+ reload: function (forceFetch) {
+ $window.location.reload(forceFetch);
+ },
+
+ get href() {
+ return $window.location.href;
+ },
+
+ set href(val) {
+ return ($window.location.href = val);
+ }
+ };
+};