diff --git a/public/app/core/components/sidemenu/SideMenu.test.tsx b/public/app/core/components/sidemenu/SideMenu.test.tsx index 2a262adca5a..2286787d777 100644 --- a/public/app/core/components/sidemenu/SideMenu.test.tsx +++ b/public/app/core/components/sidemenu/SideMenu.test.tsx @@ -8,6 +8,16 @@ jest.mock('../../app_events', () => ({ emit: jest.fn(), })); +jest.mock('app/store/store', () => ({ + store: { + getState: jest.fn().mockReturnValue({ + location: { + lastUpdated: 0, + } + }) + } +})); + jest.mock('app/core/services/context_srv', () => ({ contextSrv: { sidemenu: true, diff --git a/public/app/core/components/sidemenu/SideMenu.tsx b/public/app/core/components/sidemenu/SideMenu.tsx index fd3e0d95564..29ef0fed069 100644 --- a/public/app/core/components/sidemenu/SideMenu.tsx +++ b/public/app/core/components/sidemenu/SideMenu.tsx @@ -3,9 +3,16 @@ import appEvents from '../../app_events'; import { contextSrv } from 'app/core/services/context_srv'; import TopSection from './TopSection'; import BottomSection from './BottomSection'; +import { store } from 'app/store/store'; export class SideMenu extends PureComponent { 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(); appEvents.emit('toggle-sidemenu'); }; diff --git a/public/app/core/reducers/location.ts b/public/app/core/reducers/location.ts index c038ab53c9f..dff1ac8f5c1 100644 --- a/public/app/core/reducers/location.ts +++ b/public/app/core/reducers/location.ts @@ -9,6 +9,7 @@ export const initialState: LocationState = { query: {}, routeParams: {}, replace: false, + lastUpdated: 0, }; export const locationReducer = (state = initialState, action: Action): LocationState => { @@ -28,6 +29,7 @@ export const locationReducer = (state = initialState, action: Action): LocationS query: { ...query }, routeParams: routeParams || state.routeParams, replace: replace === true, + lastUpdated: new Date().getTime(), }; } } diff --git a/public/app/features/dashboard/components/DashNav/DashNav.tsx b/public/app/features/dashboard/components/DashNav/DashNav.tsx index 297d7ca7ea7..6db07b5d42e 100644 --- a/public/app/features/dashboard/components/DashNav/DashNav.tsx +++ b/public/app/features/dashboard/components/DashNav/DashNav.tsx @@ -9,12 +9,13 @@ import { PlaylistSrv } from 'app/features/playlist/playlist_srv'; // Components import { DashNavButton } from './DashNavButton'; +import { Tooltip } from '@grafana/ui'; // State import { updateLocation } from 'app/core/actions'; // Types -import { DashboardModel } from '../../state/DashboardModel'; +import { DashboardModel } from '../../state'; export interface Props { dashboard: DashboardModel; @@ -33,7 +34,6 @@ export class DashNav extends PureComponent { constructor(props: Props) { super(props); - this.playlistSrv = this.props.$injector.get('playlistSrv'); } @@ -123,26 +123,54 @@ export class DashNav extends PureComponent { }); }; - render() { - const { dashboard, isFullscreen, editview, onAddPanel } = this.props; - const { canStar, canSave, canShare, folderTitle, showSettings, isStarred } = dashboard.meta; - const { snapshot } = dashboard; + renderDashboardTitleSearchButton() { + const { dashboard } = this.props; + const folderTitle = dashboard.meta.folderTitle; const haveFolder = dashboard.meta.folderId > 0; - const snapshotUrl = snapshot && snapshot.originalUrl; return ( -
+ <>
- + {!this.isInFullscreenOrSettings && } {haveFolder && {folderTitle} / } {dashboard.title}
-
+ + ); + } + + get isInFullscreenOrSettings() { + return this.props.editview || this.props.isFullscreen; + } + + renderBackButton() { + return ( +
+ + + +
+ ); + } + + render() { + const { dashboard, onAddPanel } = this.props; + const { canStar, canSave, canShare, showSettings, isStarred } = dashboard.meta; + const { snapshot } = dashboard; + + const snapshotUrl = snapshot && snapshot.originalUrl; + + return ( +
+ {this.isInFullscreenOrSettings && this.renderBackButton()} + {this.renderDashboardTitleSearchButton()} {this.playlistSrv.isPlaying && (
@@ -228,17 +256,6 @@ export class DashNav extends PureComponent {
(this.timePickerEl = element)} /> - - {(isFullscreen || editview) && ( -
- -
- )}
); } diff --git a/public/app/store/configureStore.ts b/public/app/store/configureStore.ts index e2c33523271..2638587e96d 100644 --- a/public/app/store/configureStore.ts +++ b/public/app/store/configureStore.ts @@ -1,6 +1,6 @@ import { createStore, applyMiddleware, compose, combineReducers } from 'redux'; import thunk from 'redux-thunk'; -import { createLogger } from 'redux-logger'; +// import { createLogger } from 'redux-logger'; import sharedReducers from 'app/core/reducers'; import alertingReducers from 'app/features/alerting/state/reducers'; import teamsReducers from 'app/features/teams/state/reducers'; @@ -41,7 +41,7 @@ export function configureStore() { if (process.env.NODE_ENV !== 'production') { // DEV builds we had the logger middleware - setStore(createStore(rootReducer, {}, composeEnhancers(applyMiddleware(thunk, createLogger())))); + setStore(createStore(rootReducer, {}, composeEnhancers(applyMiddleware(thunk)))); } else { setStore(createStore(rootReducer, {}, composeEnhancers(applyMiddleware(thunk)))); } diff --git a/public/app/types/location.ts b/public/app/types/location.ts index a47ef05d2be..4730f9d6ed7 100644 --- a/public/app/types/location.ts +++ b/public/app/types/location.ts @@ -15,6 +15,7 @@ export interface LocationState { query: UrlQueryMap; routeParams: UrlQueryMap; replace: boolean; + lastUpdated: number; } export type UrlQueryValue = string | number | boolean | string[] | number[] | boolean[]; diff --git a/public/sass/components/_navbar.scss b/public/sass/components/_navbar.scss index 0cfa314a985..ce0fb45051e 100644 --- a/public/sass/components/_navbar.scss +++ b/public/sass/components/_navbar.scss @@ -1,6 +1,6 @@ .navbar { position: relative; - padding-left: 40px; + padding-left: 20px; z-index: $zindex-navbar-fixed; height: $navbarHeight; padding-right: 20px; @@ -41,15 +41,12 @@ .panel-in-fullscreen { .navbar { - padding-left: 15px; + padding-left: 20px; } .navbar-button--add-panel, .navbar-button--star, .navbar-button--tv, - .navbar-page-btn .fa-caret-down { - display: none; - } .navbar-buttons--close { 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; + } +} + + diff --git a/public/sass/components/_panel_editor.scss b/public/sass/components/_panel_editor.scss index 1de136c09f1..475d7444b03 100644 --- a/public/sass/components/_panel_editor.scss +++ b/public/sass/components/_panel_editor.scss @@ -86,6 +86,10 @@ .panel-editor-container__panel { margin: 0 $dashboard-padding; } + + .search-container { + left: 0 !important; + } } .panel-editor-container__resizer { diff --git a/public/sass/components/_search.scss b/public/sass/components/_search.scss index daad8fd10da..eba03283510 100644 --- a/public/sass/components/_search.scss +++ b/public/sass/components/_search.scss @@ -21,9 +21,9 @@ // Search .search-field-wrapper { width: 100%; + height: $navbarHeight; display: flex; background-color: $navbarBackground; - box-shadow: $navbarShadow; position: relative; & > input {