Merge pull request #15339 from grafana/navbar-back-btn

Navbar back btn
This commit is contained in:
Torkel Ödegaard 2019-02-11 10:28:47 +01:00 committed by GitHub
commit a402a3713f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 97 additions and 29 deletions

View File

@ -8,6 +8,16 @@ jest.mock('../../app_events', () => ({
emit: jest.fn(), emit: jest.fn(),
})); }));
jest.mock('app/store/store', () => ({
store: {
getState: jest.fn().mockReturnValue({
location: {
lastUpdated: 0,
}
})
}
}));
jest.mock('app/core/services/context_srv', () => ({ jest.mock('app/core/services/context_srv', () => ({
contextSrv: { contextSrv: {
sidemenu: true, sidemenu: true,

View File

@ -3,9 +3,16 @@ import appEvents from '../../app_events';
import { contextSrv } from 'app/core/services/context_srv'; import { contextSrv } from 'app/core/services/context_srv';
import TopSection from './TopSection'; import TopSection from './TopSection';
import BottomSection from './BottomSection'; import BottomSection from './BottomSection';
import { store } from 'app/store/store';
export class SideMenu extends PureComponent { export class SideMenu extends PureComponent {
toggleSideMenu = () => { toggleSideMenu = () => {
// ignore if we just made a location change, stops hiding sidemenu on double clicks of back button
const timeSinceLocationChanged = new Date().getTime() - store.getState().location.lastUpdated;
if (timeSinceLocationChanged < 1000) {
return;
}
contextSrv.toggleSideMenu(); contextSrv.toggleSideMenu();
appEvents.emit('toggle-sidemenu'); appEvents.emit('toggle-sidemenu');
}; };

View File

@ -9,6 +9,7 @@ export const initialState: LocationState = {
query: {}, query: {},
routeParams: {}, routeParams: {},
replace: false, replace: false,
lastUpdated: 0,
}; };
export const locationReducer = (state = initialState, action: Action): LocationState => { export const locationReducer = (state = initialState, action: Action): LocationState => {
@ -28,6 +29,7 @@ export const locationReducer = (state = initialState, action: Action): LocationS
query: { ...query }, query: { ...query },
routeParams: routeParams || state.routeParams, routeParams: routeParams || state.routeParams,
replace: replace === true, replace: replace === true,
lastUpdated: new Date().getTime(),
}; };
} }
} }

View File

@ -9,12 +9,13 @@ import { PlaylistSrv } from 'app/features/playlist/playlist_srv';
// Components // Components
import { DashNavButton } from './DashNavButton'; import { DashNavButton } from './DashNavButton';
import { Tooltip } from '@grafana/ui';
// State // State
import { updateLocation } from 'app/core/actions'; import { updateLocation } from 'app/core/actions';
// Types // Types
import { DashboardModel } from '../../state/DashboardModel'; import { DashboardModel } from '../../state';
export interface Props { export interface Props {
dashboard: DashboardModel; dashboard: DashboardModel;
@ -33,7 +34,6 @@ export class DashNav extends PureComponent<Props> {
constructor(props: Props) { constructor(props: Props) {
super(props); super(props);
this.playlistSrv = this.props.$injector.get('playlistSrv'); this.playlistSrv = this.props.$injector.get('playlistSrv');
} }
@ -123,26 +123,54 @@ export class DashNav extends PureComponent<Props> {
}); });
}; };
render() { renderDashboardTitleSearchButton() {
const { dashboard, isFullscreen, editview, onAddPanel } = this.props; const { dashboard } = this.props;
const { canStar, canSave, canShare, folderTitle, showSettings, isStarred } = dashboard.meta;
const { snapshot } = dashboard;
const folderTitle = dashboard.meta.folderTitle;
const haveFolder = dashboard.meta.folderId > 0; const haveFolder = dashboard.meta.folderId > 0;
const snapshotUrl = snapshot && snapshot.originalUrl;
return ( return (
<div className="navbar"> <>
<div> <div>
<a className="navbar-page-btn" onClick={this.onOpenSearch}> <a className="navbar-page-btn" onClick={this.onOpenSearch}>
<i className="gicon gicon-dashboard" /> {!this.isInFullscreenOrSettings && <i className="gicon gicon-dashboard" />}
{haveFolder && <span className="navbar-page-btn--folder">{folderTitle} / </span>} {haveFolder && <span className="navbar-page-btn--folder">{folderTitle} / </span>}
{dashboard.title} {dashboard.title}
<i className="fa fa-caret-down" /> <i className="fa fa-caret-down" />
</a> </a>
</div> </div>
<div className="navbar__spacer" /> <div className="navbar__spacer" />
</>
);
}
get isInFullscreenOrSettings() {
return this.props.editview || this.props.isFullscreen;
}
renderBackButton() {
return (
<div className="navbar-edit">
<Tooltip content="Go back (Esc)">
<button className="navbar-edit__back-btn" onClick={this.onClose}>
<i className="fa fa-arrow-left" />
</button>
</Tooltip>
</div>
);
}
render() {
const { dashboard, onAddPanel } = this.props;
const { canStar, canSave, canShare, showSettings, isStarred } = dashboard.meta;
const { snapshot } = dashboard;
const snapshotUrl = snapshot && snapshot.originalUrl;
return (
<div className="navbar">
{this.isInFullscreenOrSettings && this.renderBackButton()}
{this.renderDashboardTitleSearchButton()}
{this.playlistSrv.isPlaying && ( {this.playlistSrv.isPlaying && (
<div className="navbar-buttons navbar-buttons--playlist"> <div className="navbar-buttons navbar-buttons--playlist">
@ -228,17 +256,6 @@ export class DashNav extends PureComponent<Props> {
</div> </div>
<div className="gf-timepicker-nav" ref={element => (this.timePickerEl = element)} /> <div className="gf-timepicker-nav" ref={element => (this.timePickerEl = element)} />
{(isFullscreen || editview) && (
<div className="navbar-buttons navbar-buttons--close">
<DashNavButton
tooltip="Back to dashboard"
classSuffix="primary"
icon="fa fa-reply"
onClick={this.onClose}
/>
</div>
)}
</div> </div>
); );
} }

View File

@ -1,6 +1,6 @@
import { createStore, applyMiddleware, compose, combineReducers } from 'redux'; import { createStore, applyMiddleware, compose, combineReducers } from 'redux';
import thunk from 'redux-thunk'; import thunk from 'redux-thunk';
import { createLogger } from 'redux-logger'; // import { createLogger } from 'redux-logger';
import sharedReducers from 'app/core/reducers'; import sharedReducers from 'app/core/reducers';
import alertingReducers from 'app/features/alerting/state/reducers'; import alertingReducers from 'app/features/alerting/state/reducers';
import teamsReducers from 'app/features/teams/state/reducers'; import teamsReducers from 'app/features/teams/state/reducers';
@ -41,7 +41,7 @@ export function configureStore() {
if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV !== 'production') {
// DEV builds we had the logger middleware // DEV builds we had the logger middleware
setStore(createStore(rootReducer, {}, composeEnhancers(applyMiddleware(thunk, createLogger())))); setStore(createStore(rootReducer, {}, composeEnhancers(applyMiddleware(thunk))));
} else { } else {
setStore(createStore(rootReducer, {}, composeEnhancers(applyMiddleware(thunk)))); setStore(createStore(rootReducer, {}, composeEnhancers(applyMiddleware(thunk))));
} }

View File

@ -15,6 +15,7 @@ export interface LocationState {
query: UrlQueryMap; query: UrlQueryMap;
routeParams: UrlQueryMap; routeParams: UrlQueryMap;
replace: boolean; replace: boolean;
lastUpdated: number;
} }
export type UrlQueryValue = string | number | boolean | string[] | number[] | boolean[]; export type UrlQueryValue = string | number | boolean | string[] | number[] | boolean[];

View File

@ -1,6 +1,6 @@
.navbar { .navbar {
position: relative; position: relative;
padding-left: 40px; padding-left: 20px;
z-index: $zindex-navbar-fixed; z-index: $zindex-navbar-fixed;
height: $navbarHeight; height: $navbarHeight;
padding-right: 20px; padding-right: 20px;
@ -41,15 +41,12 @@
.panel-in-fullscreen { .panel-in-fullscreen {
.navbar { .navbar {
padding-left: 15px; padding-left: 20px;
} }
.navbar-button--add-panel, .navbar-button--add-panel,
.navbar-button--star, .navbar-button--star,
.navbar-button--tv, .navbar-button--tv,
.navbar-page-btn .fa-caret-down {
display: none;
}
.navbar-buttons--close { .navbar-buttons--close {
display: flex; display: flex;
@ -179,3 +176,33 @@
} }
} }
} }
.navbar-edit {
display: flex;
height: $navbarHeight;
align-items: center;
padding-left: 7px;
}
.navbar-edit__back-btn {
background: transparent;
border: 2px solid $text-color;
border-radius: 50%;
width: 34px;
height: 34px;
transition: transform 0.1s ease 0.1s;
color: $text-color;
i {
font-size: $font-size-lg;
position: relative;
top: 2px;
}
&:hover {
color: $text-color-strong;
border-color: $text-color-strong;
}
}

View File

@ -86,6 +86,10 @@
.panel-editor-container__panel { .panel-editor-container__panel {
margin: 0 $dashboard-padding; margin: 0 $dashboard-padding;
} }
.search-container {
left: 0 !important;
}
} }
.panel-editor-container__resizer { .panel-editor-container__resizer {

View File

@ -21,9 +21,9 @@
// Search // Search
.search-field-wrapper { .search-field-wrapper {
width: 100%; width: 100%;
height: $navbarHeight;
display: flex; display: flex;
background-color: $navbarBackground; background-color: $navbarBackground;
box-shadow: $navbarShadow;
position: relative; position: relative;
& > input { & > input {