Commit cb0dac11 by Marcus Efraimsson

Merge branch 'develop' of github.com:grafana/grafana into develop

parents f87b9aaa e8807f4b
import { react2AngularDirective } from 'app/core/utils/react2angular'; import { react2AngularDirective } from 'app/core/utils/react2angular';
import { PasswordStrength } from './components/PasswordStrength'; import { PasswordStrength } from './components/PasswordStrength';
import PageHeader from './components/PageHeader'; import PageHeader from './components/PageHeader/PageHeader';
import EmptyListCTA from './components/EmptyListCTA/EmptyListCTA'; import EmptyListCTA from './components/EmptyListCTA/EmptyListCTA';
export function registerAngularDirectives() { export function registerAngularDirectives() {
react2AngularDirective('passwordStrength', PasswordStrength, ['password']); react2AngularDirective('passwordStrength', PasswordStrength, ['password']);
react2AngularDirective('pageHeader', PageHeader, ['model', "noTabs"]); react2AngularDirective('pageHeader', PageHeader, ['model', 'noTabs']);
react2AngularDirective('emptyListCta', EmptyListCTA, ['model']); react2AngularDirective('emptyListCta', EmptyListCTA, ['model']);
} }
import React from 'react'; import React from 'react';
import { NavModel, NavModelItem } from '../nav_model_srv'; import { NavModel, NavModelItem } from '../../nav_model_srv';
import classNames from 'classnames'; import classNames from 'classnames';
import appEvents from 'app/core/app_events';
export interface IProps { export interface IProps {
model: NavModel; model: NavModel;
...@@ -26,8 +27,44 @@ function TabItem(tab: NavModelItem) { ...@@ -26,8 +27,44 @@ function TabItem(tab: NavModelItem) {
); );
} }
function Tabs({main}: {main: NavModelItem}) { function SelectOption(navItem: NavModelItem) {
return <ul className="gf-tabs">{main.children.map(TabItem)}</ul>; if (navItem.hideFromTabs) { // TODO: Rename hideFromTabs => hideFromNav
return (null);
}
return (
<option key={navItem.url} value={navItem.url}>
{navItem.text}
</option>
);
}
function Navigation({main}: {main: NavModelItem}) {
return (<nav>
<SelectNav customCss="page-header__select_nav" main={main} />
<Tabs customCss="page-header__tabs" main={main} />
</nav>);
}
function SelectNav({main, customCss}: {main: NavModelItem, customCss: string}) {
const defaultSelectedItem = main.children.find(navItem => {
return navItem.active === true;
});
const gotoUrl = evt => {
var element = evt.target;
var url = element.options[element.selectedIndex].value;
appEvents.emit('location-change', {href: url});
};
return (<select
className={`gf-select-nav ${customCss}`}
defaultValue={defaultSelectedItem.url}
onChange={gotoUrl}>{main.children.map(SelectOption)}</select>);
}
function Tabs({main, customCss}: {main: NavModelItem, customCss: string}) {
return <ul className={`gf-tabs ${customCss}`}>{main.children.map(TabItem)}</ul>;
} }
export default class PageHeader extends React.Component<IProps, any> { export default class PageHeader extends React.Component<IProps, any> {
...@@ -63,7 +100,7 @@ export default class PageHeader extends React.Component<IProps, any> { ...@@ -63,7 +100,7 @@ export default class PageHeader extends React.Component<IProps, any> {
<div className="page-container"> <div className="page-container">
<div className="page-header"> <div className="page-header">
{this.renderHeaderTitle(this.props.model.main)} {this.renderHeaderTitle(this.props.model.main)}
{this.props.model.main.children && <Tabs main={this.props.model.main} />} {this.props.model.main.children && <Navigation main={this.props.model.main} />}
</div> </div>
</div> </div>
</div> </div>
......
...@@ -12,7 +12,7 @@ import Drop from 'tether-drop'; ...@@ -12,7 +12,7 @@ import Drop from 'tether-drop';
export class GrafanaCtrl { export class GrafanaCtrl {
/** @ngInject */ /** @ngInject */
constructor($scope, alertSrv, utilSrv, $rootScope, $controller, contextSrv) { constructor($scope, alertSrv, utilSrv, $rootScope, $controller, contextSrv, globalEventSrv) {
$scope.init = function() { $scope.init = function() {
$scope.contextSrv = contextSrv; $scope.contextSrv = contextSrv;
...@@ -23,6 +23,7 @@ export class GrafanaCtrl { ...@@ -23,6 +23,7 @@ export class GrafanaCtrl {
profiler.init(config, $rootScope); profiler.init(config, $rootScope);
alertSrv.init(); alertSrv.init();
utilSrv.init(); utilSrv.init();
globalEventSrv.init();
$scope.dashAlerts = alertSrv; $scope.dashAlerts = alertSrv;
}; };
......
...@@ -8,5 +8,6 @@ define([ ...@@ -8,5 +8,6 @@ define([
'./segment_srv', './segment_srv',
'./backend_srv', './backend_srv',
'./dynamic_directive_srv', './dynamic_directive_srv',
'./global_event_srv'
], ],
function () {}); function () {});
import coreModule from 'app/core/core_module';
import appEvents from 'app/core/app_events';
// This service is for registering global events.
// Good for communication react > angular and vice verse
export class GlobalEventSrv {
/** @ngInject */
constructor(private $location, private $timeout) {
}
init() {
appEvents.on('location-change', payload => {
this.$timeout(() => { // A hack to use timeout when we're changing things (in this case the url) from outside of Angular.
this.$location.path(payload.href);
});
});
}
}
coreModule.service('globalEventSrv', GlobalEventSrv);
import coreModule from 'app/core/core_module'; import coreModule from 'app/core/core_module';
export function react2AngularDirective(name: string, component: any, options: any) { export function react2AngularDirective(name: string, component: any, options: any) {
coreModule.directive(name, ['reactDirective', reactDirective => { coreModule.directive(name, ['reactDirective', reactDirective => {
return reactDirective(component, options); return reactDirective(component, options);
}]); }]);
} }
///<reference path="../../headers/common.d.ts" /> ///<reference path="../../headers/common.d.ts" />
import coreModule from '../../core/core_module'; import coreModule from '../../core/core_module';
import {appEvents} from 'app/core/core';
export class DataSourcesCtrl { export class DataSourcesCtrl {
datasources: any; datasources: any;
...@@ -11,13 +12,24 @@ export class DataSourcesCtrl { ...@@ -11,13 +12,24 @@ export class DataSourcesCtrl {
private $scope, private $scope,
private backendSrv, private backendSrv,
private datasourceSrv, private datasourceSrv,
private $location,
private navModelSrv) { private navModelSrv) {
this.navModel = this.navModelSrv.getNav('cfg', 'datasources', 0); this.navModel = this.navModelSrv.getNav('cfg', 'datasources', 0);
this.navigateToUrl = this.navigateToUrl.bind(this);
backendSrv.get('/api/datasources').then(result => { backendSrv.get('/api/datasources').then(result => {
this.datasources = result; this.datasources = result;
}); });
appEvents.on('location-change', payload => {
this.navigateToUrl(payload.href);
});
}
navigateToUrl(url) {
// debugger;
this.$location.path(url);
this.$location.replace();
} }
removeDataSourceConfirmed(ds) { removeDataSourceConfirmed(ds) {
......
<navbar model="navModel"></navbar>
<div class="page-container"> <div class="page-container">
<div class="page-header"> <div class="page-header">
<h1> <div class="page-header__inner">
Page not found (404) <span class="page-header__logo">
<i class="page-header__icon fa fa-fw fa-exclamation-triangle"></i>
</span>
<div class="page-header__info-block">
<h1 class="page-header__title">
Page not found
</h1> </h1>
<div class="page-header__sub-title">
404 Error
</div> </div>
<div class="error-row"> </div>
<div class="dash-row-menu-grip"><i class="fa fa-ellipsis-v"></i></div> </div>
<div class="panel-container error-row"> </div>
<div class="panel-container error-container">
<div class="error-column graph-box"> <div class="error-column graph-box">
<div class="error-row"> <div class="error-row">
<div class="error-column error-space-between graph-percentage"> <div class="error-column error-space-between graph-percentage">
...@@ -35,21 +40,21 @@ ...@@ -35,21 +40,21 @@
</div> </div>
<div class="error-row" style="flex: 1"> <div class="error-row" style="flex: 1">
<i class="fa fa-minus error-minus"></i> <i class="fa fa-minus error-minus"></i>
<div class="error-column error-space-between"> <div class="error-column error-space-between error-full-width">
<div class="error-row error-space-between"> <div class="error-row error-space-between">
<p>Chances you are on the page you are looking for.</p> <p>Chances you are on the page you are looking for.</p>
<p class="left-margin">0%</p> <p class="left-margin">0%</p>
</div> </div>
<div> <div>
<h3>Sorry for the inconvenience</h3> <h3>Sorry for the inconvenience</h3>
<p>Please go back to your <a href="{{appSubUrl}}/" class="error-link">home dashboard</a> and try again.</p> <p>Please go back to your
<p>If the error persists, seek help on the <a href="https://community.grafana.com" target="_blank" class="error-link">community site</a>.</p> <a href="{{appSubUrl}}/" class="error-link">home dashboard</a> and try again.</p>
</div> <p>If the error persists, seek help on the
<a href="https://community.grafana.com" target="_blank" class="error-link">community site</a>.</p>
</div> </div>
</div> </div>
</div> </div>
<span class="resize-panel-handle icon-gf icon-gf-grabber" style="cursor: default"></span>
</div> </div>
<span class="react-resizable-handle" style="cursor: default"></span>
</div> </div>
</div> </div>
...@@ -235,5 +235,5 @@ $dashboard-padding: $panel-margin * 2; ...@@ -235,5 +235,5 @@ $dashboard-padding: $panel-margin * 2;
$panel-padding: 0px 10px 5px 10px; $panel-padding: 0px 10px 5px 10px;
// tabs // tabs
$tabs-padding: 9px 15px 9px; $tabs-padding: 10px 15px 9px;
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
} }
.react-grid-item { .react-grid-item {
display: none; display: none !important;
transition-property: none !important; transition-property: none !important;
} }
......
...@@ -72,6 +72,21 @@ ...@@ -72,6 +72,21 @@
text-transform: uppercase; text-transform: uppercase;
} }
.page-header__select_nav {
margin-bottom: 10px;
@include media-breakpoint-up(lg) {
display: none;
}
}
.page-header__tabs {
display: none;
@include media-breakpoint-up(lg) {
display: block;
}
}
.page-breadcrumbs { .page-breadcrumbs {
display: flex; display: flex;
padding: 10px 0; padding: 10px 0;
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
position: relative; position: relative;
display: block; display: block;
border: solid transparent; border: solid transparent;
border-width: 2px 1px 1px; border-width: 0 1px 1px;
border-radius: 3px 3px 0 0; border-radius: 3px 3px 0 0;
i { i {
...@@ -34,6 +34,18 @@ ...@@ -34,6 +34,18 @@
border-color: $orange $tab-border-color transparent; border-color: $orange $tab-border-color transparent;
background: $page-bg; background: $page-bg;
color: $link-color; color: $link-color;
overflow: hidden;
&::before {
display: block;
content: ' ';
position: absolute;
left: 0;
right: 0;
height: 2px;
top: 0;
background-image: linear-gradient(to right, #ffd500 0%, #ff4400 99%, #ff4400 100%);
}
} }
} }
...@@ -3,6 +3,11 @@ ...@@ -3,6 +3,11 @@
// Layout // Layout
// //
.error-container {
display: flex;
flex-direction: row;
}
.error-row { .error-row {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
...@@ -22,7 +27,7 @@ ...@@ -22,7 +27,7 @@
.info-box { .info-box {
width: 38%; width: 38%;
padding: 2rem 1rem 6rem; padding: 2rem 1rem 2rem;
} }
.graph-percentage {padding: 0 0 1.5rem;} .graph-percentage {padding: 0 0 1.5rem;}
...@@ -58,3 +63,31 @@ ...@@ -58,3 +63,31 @@
} }
.graph-text {margin: 0;} .graph-text {margin: 0;}
@include media-breakpoint-down(sm) {
.graph-box {
width: 50%;
}
.info-box {
width: 50%;
}
}
@include media-breakpoint-down(xs) {
.error-container {
flex-direction: column;
}
.graph-box {
width: 100%;
}
.info-box {
width: 100%;
}
.error-full-width {
width: 100%;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment