mirror of
https://github.com/grafana/grafana.git
synced 2025-02-20 11:48:34 -06:00
* feat: Add new picker to DashNavTimeControls * chore: noImplicitAny limit reached * chore: noImplicityAny fix * chore: Add momentUtc helper to avoid the isUtc conditionals * chore: Move getRaw from Explore's time picker to grafana/ui utils and rename to getRawRange * feat: Use helper functions to convert utc to browser time * fix: Dont Select current value when pressing tab when using Time Picker * fix: Add tabIndex to time range inputs so tab works smoothly and prevent mouseDown event to propagate to react-select * fix: Add spacing to custom range labels * fix: Updated snapshot * fix: Re-adding getRaw() temporary to fix the build * fix: Disable scroll event in Popper when we're using the TimePicker so the popup wont "follow" the menu * fix: Move all "Last xxxx" quick ranges to the menu and show a "UTC" text when applicable * fix: Add zoom functionality * feat: Add logic to mark selected option as active * fix: Add tooltip to zoom button * fix: lint fix after rebase * chore: Remove old time picker from DashNav * TimePicker: minor design update * chore: Move all time picker quick ranges to the menu * fix: Remove the popover border-right, since the quick ranges are gone * chore: Remove function not in use * Fix: Close time picker on resize event * Fix: Remove border bottom * Fix: Use fa icons on prev/next arrows * Fix: Pass ref from TimePicker to TimePickerOptionGroup so the popover will align as it should * Fix: time picker ui adjustments to get better touch area on buttons * Fix: Dont increase line height on large screens * TimePicker: style updates * Fix: Add more prominent colors for selected dates and fade out dates in previous/next month * TimePicker: style updates2 * TimePicker: Big refactorings and style changes * Removed use of Popper not sure we need that here? * Made active selected item in the list have the "selected" checkmark * Changed design of popover * Changed design of and implementation of the Custom selection in the dropdown it did not feel like a item you could select like the rest now the list is just a normal list * TimePicker: Refactoring & style changes * TimePicker: use same date format everywhere * TimePicker: Calendar style updates * TimePicker: fixed unit test * fixed unit test * TimeZone: refactoring time zone type * TimePicker: refactoring * TimePicker: finally to UTC to work * TimePicker: better way to handle calendar utc dates * TimePicker: Fixed tooltip issues * Updated snapshot * TimePicker: moved tooltip from DashNavControls into TimePicker
291 lines
7.5 KiB
TypeScript
291 lines
7.5 KiB
TypeScript
// Libaries
|
|
import React, { PureComponent } from 'react';
|
|
import { connect } from 'react-redux';
|
|
|
|
// Utils & Services
|
|
import { appEvents } from 'app/core/app_events';
|
|
import { PlaylistSrv } from 'app/features/playlist/playlist_srv';
|
|
|
|
// Components
|
|
import { DashNavButton } from './DashNavButton';
|
|
import { DashNavTimeControls } from './DashNavTimeControls';
|
|
import { Tooltip } from '@grafana/ui';
|
|
|
|
// State
|
|
import { updateLocation } from 'app/core/actions';
|
|
|
|
// Types
|
|
import { DashboardModel } from '../../state';
|
|
import { StoreState } from 'app/types';
|
|
|
|
export interface OwnProps {
|
|
dashboard: DashboardModel;
|
|
editview: string;
|
|
isEditing: boolean;
|
|
isFullscreen: boolean;
|
|
$injector: any;
|
|
updateLocation: typeof updateLocation;
|
|
onAddPanel: () => void;
|
|
}
|
|
|
|
export interface StateProps {
|
|
location: any;
|
|
}
|
|
|
|
type Props = StateProps & OwnProps;
|
|
|
|
export class DashNav extends PureComponent<Props> {
|
|
playlistSrv: PlaylistSrv;
|
|
|
|
constructor(props: Props) {
|
|
super(props);
|
|
this.playlistSrv = this.props.$injector.get('playlistSrv');
|
|
}
|
|
|
|
onDahboardNameClick = () => {
|
|
appEvents.emit('show-dash-search');
|
|
};
|
|
|
|
onFolderNameClick = () => {
|
|
appEvents.emit('show-dash-search', {
|
|
query: 'folder:current',
|
|
});
|
|
};
|
|
|
|
onClose = () => {
|
|
if (this.props.editview) {
|
|
this.props.updateLocation({
|
|
query: { editview: null },
|
|
partial: true,
|
|
});
|
|
} else {
|
|
this.props.updateLocation({
|
|
query: { panelId: null, edit: null, fullscreen: null, tab: null },
|
|
partial: true,
|
|
});
|
|
}
|
|
};
|
|
|
|
onToggleTVMode = () => {
|
|
appEvents.emit('toggle-kiosk-mode');
|
|
};
|
|
|
|
onSave = () => {
|
|
const { $injector } = this.props;
|
|
const dashboardSrv = $injector.get('dashboardSrv');
|
|
dashboardSrv.saveDashboard();
|
|
};
|
|
|
|
onOpenSettings = () => {
|
|
this.props.updateLocation({
|
|
query: { editview: 'settings' },
|
|
partial: true,
|
|
});
|
|
};
|
|
|
|
onStarDashboard = () => {
|
|
const { dashboard, $injector } = this.props;
|
|
const dashboardSrv = $injector.get('dashboardSrv');
|
|
|
|
dashboardSrv.starDashboard(dashboard.id, dashboard.meta.isStarred).then(newState => {
|
|
dashboard.meta.isStarred = newState;
|
|
this.forceUpdate();
|
|
});
|
|
};
|
|
|
|
onPlaylistPrev = () => {
|
|
this.playlistSrv.prev();
|
|
};
|
|
|
|
onPlaylistNext = () => {
|
|
this.playlistSrv.next();
|
|
};
|
|
|
|
onPlaylistStop = () => {
|
|
this.playlistSrv.stop();
|
|
this.forceUpdate();
|
|
};
|
|
|
|
onOpenShare = () => {
|
|
const $rootScope = this.props.$injector.get('$rootScope');
|
|
const modalScope = $rootScope.$new();
|
|
modalScope.tabIndex = 0;
|
|
modalScope.dashboard = this.props.dashboard;
|
|
|
|
appEvents.emit('show-modal', {
|
|
src: 'public/app/features/dashboard/components/ShareModal/template.html',
|
|
scope: modalScope,
|
|
});
|
|
};
|
|
|
|
renderDashboardTitleSearchButton() {
|
|
const { dashboard } = this.props;
|
|
|
|
const folderTitle = dashboard.meta.folderTitle;
|
|
const haveFolder = dashboard.meta.folderId > 0;
|
|
|
|
return (
|
|
<>
|
|
<div>
|
|
<div className="navbar-page-btn">
|
|
{!this.isInFullscreenOrSettings && <i className="gicon gicon-dashboard" />}
|
|
{haveFolder && (
|
|
<>
|
|
<a className="navbar-page-btn__folder" onClick={this.onFolderNameClick}>
|
|
{folderTitle}
|
|
</a>
|
|
<i className="fa fa-chevron-right navbar-page-btn__folder-icon" />
|
|
</>
|
|
)}
|
|
<a onClick={this.onDahboardNameClick}>
|
|
{dashboard.title} <i className="fa fa-caret-down navbar-page-btn__search" />
|
|
</a>
|
|
</div>
|
|
</div>
|
|
{this.isSettings && <span className="navbar-settings-title"> / Settings</span>}
|
|
<div className="navbar__spacer" />
|
|
</>
|
|
);
|
|
}
|
|
|
|
get isInFullscreenOrSettings() {
|
|
return this.props.editview || this.props.isFullscreen;
|
|
}
|
|
|
|
get isSettings() {
|
|
return this.props.editview;
|
|
}
|
|
|
|
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, location, $injector } = 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 && (
|
|
<div className="navbar-buttons navbar-buttons--playlist">
|
|
<DashNavButton
|
|
tooltip="Go to previous dashboard"
|
|
classSuffix="tight"
|
|
icon="fa fa-step-backward"
|
|
onClick={this.onPlaylistPrev}
|
|
/>
|
|
<DashNavButton
|
|
tooltip="Stop playlist"
|
|
classSuffix="tight"
|
|
icon="fa fa-stop"
|
|
onClick={this.onPlaylistStop}
|
|
/>
|
|
<DashNavButton
|
|
tooltip="Go to next dashboard"
|
|
classSuffix="tight"
|
|
icon="fa fa-forward"
|
|
onClick={this.onPlaylistNext}
|
|
/>
|
|
</div>
|
|
)}
|
|
|
|
<div className="navbar-buttons navbar-buttons--actions">
|
|
{canSave && (
|
|
<DashNavButton
|
|
tooltip="Add panel"
|
|
classSuffix="add-panel"
|
|
icon="gicon gicon-add-panel"
|
|
onClick={onAddPanel}
|
|
/>
|
|
)}
|
|
|
|
{canStar && (
|
|
<DashNavButton
|
|
tooltip="Mark as favorite"
|
|
classSuffix="star"
|
|
icon={`${isStarred ? 'fa fa-star' : 'fa fa-star-o'}`}
|
|
onClick={this.onStarDashboard}
|
|
/>
|
|
)}
|
|
|
|
{canShare && (
|
|
<DashNavButton
|
|
tooltip="Share dashboard"
|
|
classSuffix="share"
|
|
icon="fa fa-share-square-o"
|
|
onClick={this.onOpenShare}
|
|
/>
|
|
)}
|
|
|
|
{canSave && (
|
|
<DashNavButton tooltip="Save dashboard" classSuffix="save" icon="fa fa-save" onClick={this.onSave} />
|
|
)}
|
|
|
|
{snapshotUrl && (
|
|
<DashNavButton
|
|
tooltip="Open original dashboard"
|
|
classSuffix="snapshot-origin"
|
|
icon="gicon gicon-link"
|
|
href={snapshotUrl}
|
|
/>
|
|
)}
|
|
|
|
{showSettings && (
|
|
<DashNavButton
|
|
tooltip="Dashboard settings"
|
|
classSuffix="settings"
|
|
icon="gicon gicon-cog"
|
|
onClick={this.onOpenSettings}
|
|
/>
|
|
)}
|
|
</div>
|
|
|
|
<div className="navbar-buttons navbar-buttons--tv">
|
|
<DashNavButton
|
|
tooltip="Cycle view mode"
|
|
classSuffix="tv"
|
|
icon="fa fa-desktop"
|
|
onClick={this.onToggleTVMode}
|
|
/>
|
|
</div>
|
|
|
|
{!dashboard.timepicker.hidden && (
|
|
<div className="navbar-buttons">
|
|
<DashNavTimeControls
|
|
$injector={$injector}
|
|
dashboard={dashboard}
|
|
location={location}
|
|
updateLocation={updateLocation}
|
|
/>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
const mapStateToProps = (state: StoreState) => ({
|
|
location: state.location,
|
|
});
|
|
|
|
const mapDispatchToProps = {
|
|
updateLocation,
|
|
};
|
|
|
|
export default connect(
|
|
mapStateToProps,
|
|
mapDispatchToProps
|
|
)(DashNav);
|