Merge pull request #6645 from panda01/fix/moveAppendNavControls

Fix/move append nav controls
This commit is contained in:
Joe Fleming 2016-03-29 13:50:58 -07:00
commit 9a80ee524c
19 changed files with 121 additions and 78 deletions

View file

@ -52,6 +52,7 @@
<span>Options</span>
</button>
</div>
<kbn-global-timepicker></kbn-global-timepicker>
<div class="chrome-actions" kbn-chrome-append-nav-controls></div>
</navbar>
<config config-template="configTemplate" config-object="opts"></config>

View file

@ -40,6 +40,7 @@
<span>Share</span>
</button>
</div>
<kbn-global-timepicker></kbn-global-timepicker>
<div class="chrome-actions" kbn-chrome-append-nav-controls></div>
</navbar>
<config

View file

@ -47,6 +47,7 @@
<span>Refresh</span>
</button>
</div>
<kbn-global-timepicker></kbn-global-timepicker>
<div class="chrome-actions" kbn-chrome-append-nav-controls></div>
</navbar>
<config

View file

@ -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';

View file

@ -0,0 +1,36 @@
import ngMock from 'ng_mock';
import expect from 'expect.js';
import uiModules from 'ui/modules';
import $ from 'jquery';
import '../directives/kbn_loading_indicator';
describe('kbnLoadingIndicator', function () {
let compile;
beforeEach(() => {
ngMock.module('kibana');
ngMock.inject(function ($compile, $rootScope) {
compile = function (hasActiveConnections) {
$rootScope.chrome = {
httpActive: (hasActiveConnections ? [1] : [])
};
const $el = $('<kbn-loading-indicator></kbn-loading-indicator>');
$rootScope.$apply();
$compile($el)($rootScope);
return $el;
};
});
});
it('injects a loading .spinner into the element', function () {
const $el = compile();
expect($el.find('.spinner')).to.have.length(1);
});
it('applies removes ng-hide class when there are connections', function () {
const $el = compile(true);
expect($el.find('.spinner.ng-hide')).to.have.length(0);
});
});

View file

@ -1,6 +1,6 @@
<div class="content" chrome-context >
<!-- TODO: These config dropdowns shouldn't be hard coded -->
<nav class="app-links-wrapper">
<nav class="app-links-wrapper" ng-show="chrome.getVisible()">
<li
ng-if="!chrome.getBrand('logo') && !chrome.getBrand('smallLogo')"
aria-label="{{ chrome.getAppTitle() }} Logo"
@ -21,28 +21,12 @@
<app-switcher>
</app-switcher>
<div class="bottom-apps hide app-links">
<div class="app-link">
<a href="http://elastic.co">
<div class="app-icon">
<i class="fa fa-gear"></i>
</div>
<div class="app-title">settings</div>
</a>
</div>
<div class="app-link">
<a href="http://elastic.co">
<div class="app-icon">
<i class="fa fa-user"></i>
</div>
<div class="app-title">Jon Doe</div>
<div class="app-title">Logout</div>
</a>
</div>
<div class="bottom-apps">
<div class="chrome-actions app-links" kbn-chrome-append-nav-controls></div>
</div>
</nav>
<div class="app-wrapper">
<div class="app-wrapper" ng-class="{ 'hidden-chrome': !chrome.getVisible() }">
<div class="app-wrapper-panel">
<kbn-notifications list="notifList"></kbn-notifications>
<nav
@ -80,6 +64,7 @@
</div>
<!-- /Full navbar -->
</nav>
<kbn-loading-indicator></kbn-loading-indicator>
<div class="application" ng-class="'tab-' + chrome.getFirstPathSegment() + ' ' + chrome.getApplicationClasses()" ng-view></div>
</div>
</div>

View file

@ -1,30 +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.toggleRefresh = function () {
timefilter.refreshInterval.pause = !timefilter.refreshInterval.pause;
};
}
};
});

View file

@ -1 +0,0 @@
<div class="spinner" ng-show="chrome.httpActive.length"></div>

View file

@ -54,6 +54,7 @@ body { overflow-x: hidden; }
margin: 0 auto;
background-color: #fff;
&.hidden-chrome { left: 0; }
&-panel {
.flex-parent(@shrink: 0);
box-shadow: -4px 0px 3px rgba(0,0,0,0.2);
@ -84,7 +85,6 @@ body { overflow-x: hidden; }
.app-icon {
float: left;
filter: invert(100%);
font-weight: bold;
text-align: center;
font-size: 1.7em;
@ -95,6 +95,11 @@ body { overflow-x: hidden; }
> img {
height: 18px;
margin-top: 8px;
filter: invert(100%);
}
> i {
color: #fff;
line-height: @app-icon-height
}
}
@ -128,7 +133,7 @@ body { overflow-x: hidden; }
text-decoration: none;
}
img {
filter: invert(100%);
filter: none;
}
}

View file

@ -2,12 +2,6 @@ import $ from 'jquery';
import chromeNavControlsRegistry from 'ui/registry/chrome_nav_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) {
@ -19,7 +13,7 @@ export default function (chrome, internals) {
const parts = [$element.html()];
const controls = Private(chromeNavControlsRegistry);
for (const control of [spinner, ...controls.inOrder]) {
for (const control of controls.inOrder) {
parts.unshift(
`<!-- nav control ${control.name} -->`,
control.template

View file

@ -3,6 +3,7 @@ import 'ui/directives/config';
import './app_switcher';
import kbnChromeProv from './kbn_chrome';
import kbnChromeNavControlsProv from './append_nav_controls';
import './kbn_loading_indicator';
export default function (chrome, internals) {
kbnChromeProv(chrome, internals);

View file

@ -0,0 +1,13 @@
import UiModules from 'ui/modules';
import angular from 'angular';
const spinnerTemplate = '<div class="spinner" ng-show="chrome.httpActive.length"></div>';
UiModules
.get('ui/kibana')
.directive('kbnLoadingIndicator', function ($compile) {
return {
restrict: 'E',
template: spinnerTemplate,
};
});

View file

@ -146,6 +146,7 @@ a {
.kibana-nav-actions {
margin-left: auto;
line-height: 20px;
.button-group > :last-child {
border-radius: 0;

View file

@ -17,6 +17,7 @@
right: 0;
height: 2px;
position: absolute;
z-index: 10;
visibility: visible;
display: block;
animation: move 2s linear infinite;

View file

@ -0,0 +1,23 @@
import expect from 'expect.js';
import ngMock from 'ng_mock';
import uiModules from 'ui/modules';
import $ from 'jquery';
describe('kbnGlobalTimepicker', function () {
let compile;
beforeEach(() => {
ngMock.module('kibana');
ngMock.inject(($compile, $rootScope) => {
compile = () => {
const $el = $('<kbn-global-timepicker></kbn-global-timepicker>');
$rootScope.$apply();
$compile($el)($rootScope);
return $el;
};
});
});
it('injects the timepicker into the DOM', () => {
const $el = compile();
expect($el.find('button[ng-click]')).to.have.length(3);
});
});

View file

@ -0,0 +1,29 @@
import UiModules from 'ui/modules';
import chromeNavControlsRegistry from 'ui/registry/chrome_nav_controls';
import { once, clone } from 'lodash';
import toggleHtml from './kbn_global_timepicker.html';
UiModules
.get('kibana')
.directive('kbnGlobalTimepicker', (timefilter, globalState, $rootScope) => {
const listenForUpdates = once($scope => {
$scope.$listen(timefilter, 'update', (newVal, oldVal) => {
globalState.time = clone(timefilter.time);
globalState.refreshInterval = clone(timefilter.refreshInterval);
globalState.save();
});
});
return {
template: toggleHtml,
link: ($scope, $el, attrs) => {
listenForUpdates($rootScope);
$rootScope.timefilter = timefilter;
$rootScope.toggleRefresh = () => {
timefilter.refreshInterval.pause = !timefilter.refreshInterval.pause;
};
},
};
});

View file

@ -8,7 +8,7 @@ import 'ui/directives/inequality';
import 'ui/timepicker/quick_ranges';
import 'ui/timepicker/refresh_intervals';
import 'ui/timepicker/time_units';
import 'ui/timepicker/toggle';
import 'ui/timepicker/kbn_global_timepicker';
import uiModules from 'ui/modules';
var module = uiModules.get('ui/timepicker');
var notify = new Notifier({

View file

@ -1,16 +0,0 @@
import UiModules from 'ui/modules';
import chromeNavControlsRegistry from 'ui/registry/chrome_nav_controls';
import toggleHtml from './toggle.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
chromeNavControlsRegistry.register(function () {
return {
name: 'timepicker toggle',
order: 100,
template: toggleHtml
};
});