Explore: Synchronise time ranges in split mode (#19274)

* Explore: create connected sync button when screen is splitted

* Explore: create attachable button to TimePicker

* WIP/Explore: set up redux boilerplate for synced state

* WIP/Explore: add toggling functionality to sync buttons

* WIP/Explore: Fix styling issue

* First pass solution working

* Explore: Clean up, update comments

* Explore: refactore Timepicker, remove newly introduced class names

* Explore: refactore ExploreTimeControls

* Explore: more semantic variables naming

* Explore: run query on syncable item when synced times activated

* Explore: Add tooltip to sync times button

* Explore: Remove typo

* Explore: check exploreId

* Explore: refactor ExploreTimeControls

* Explore: refactor to include suggested changes

* Explore: Create TimeSyncButton component, update colors

* Explore: Toggle tooltip, use stylesFactory
This commit is contained in:
Ivana Huckova
2019-10-08 18:55:53 +02:00
committed by GitHub
parent 0f32e15a88
commit dabc848e11
11 changed files with 205 additions and 26 deletions

View File

@@ -1,5 +1,8 @@
// Libraries
import React, { PureComponent, createRef } from 'react';
import { css } from 'emotion';
import memoizeOne from 'memoize-one';
import classNames from 'classnames';
// Components
import { ButtonSelect } from '../Select/ButtonSelect';
@@ -11,15 +14,41 @@ import { ClickOutsideWrapper } from '../ClickOutsideWrapper/ClickOutsideWrapper'
import { isDateTime, DateTime } from '@grafana/data';
import { rangeUtil } from '@grafana/data';
import { rawToTimeRange } from './time';
import { withTheme } from '../../themes/ThemeContext';
// Types
import { TimeRange, TimeOption, TimeZone, TIME_FORMAT, SelectableValue } from '@grafana/data';
import { dateMath } from '@grafana/data';
import { TimeRange, TimeOption, TimeZone, TIME_FORMAT, SelectableValue, dateMath } from '@grafana/data';
import { GrafanaTheme } from '../../types/theme';
import { Themeable } from '../../types';
export interface Props {
const getStyles = memoizeOne((theme: GrafanaTheme) => {
return {
timePickerSynced: css`
label: timePickerSynced;
border-color: ${theme.colors.orangeDark};
background-image: none;
background-color: transparent;
color: ${theme.colors.orangeDark};
&:focus,
:hover {
color: ${theme.colors.orangeDark};
background-image: none;
background-color: transparent;
}
`,
noRightBorderStyle: css`
label: noRightBorderStyle;
border-right: 0;
`,
};
});
export interface Props extends Themeable {
value: TimeRange;
selectOptions: TimeOption[];
timeZone?: TimeZone;
timeSyncButton?: JSX.Element;
isSynced?: boolean;
onChange: (timeRange: TimeRange) => void;
onMoveBackward: () => void;
onMoveForward: () => void;
@@ -70,7 +99,7 @@ const defaultZoomOutTooltip = () => {
export interface State {
isCustomOpen: boolean;
}
export class TimePicker extends PureComponent<Props, State> {
class UnThemedTimePicker extends PureComponent<Props, State> {
pickerTriggerRef = createRef<HTMLDivElement>();
state: State = {
@@ -120,7 +149,19 @@ export class TimePicker extends PureComponent<Props, State> {
};
render() {
const { selectOptions: selectTimeOptions, value, onMoveBackward, onMoveForward, onZoom, timeZone } = this.props;
const {
selectOptions: selectTimeOptions,
value,
onMoveBackward,
onMoveForward,
onZoom,
timeZone,
timeSyncButton,
isSynced,
theme,
} = this.props;
const styles = getStyles(theme);
const { isCustomOpen } = this.state;
const options = this.mapTimeOptionsToSelectableValues(selectTimeOptions);
const currentOption = options.find(item => isTimeOptionEqualToTimeRange(item.value, value));
@@ -152,7 +193,10 @@ export class TimePicker extends PureComponent<Props, State> {
</button>
)}
<ButtonSelect
className="time-picker-button-select"
className={classNames('time-picker-button-select', {
[`btn--radius-right-0 ${styles.noRightBorderStyle}`]: timeSyncButton,
[styles.timePickerSynced]: timeSyncButton ? isSynced : null,
})}
value={currentOption}
label={label}
options={options}
@@ -161,6 +205,9 @@ export class TimePicker extends PureComponent<Props, State> {
iconClass={'fa fa-clock-o fa-fw'}
tooltipContent={<TimePickerTooltipContent timeRange={value} />}
/>
{timeSyncButton}
{isAbsolute && (
<button className="btn navbar-button navbar-button--tight" onClick={onMoveForward}>
<i className="fa fa-chevron-right" />
@@ -195,3 +242,5 @@ const TimePickerTooltipContent = ({ timeRange }: { timeRange: TimeRange }) => (
function isTimeOptionEqualToTimeRange(option: TimeOption, range: TimeRange): boolean {
return range.raw.from === option.from && range.raw.to === option.to;
}
export const TimePicker = withTheme(UnThemedTimePicker);