Skip to content

Commit

Permalink
[Metrics UI] Setup commonly used time ranges in timepicker (#56701) (#…
Browse files Browse the repository at this point in the history
…57253)

* [Metrics UI] Setup commonly used time ranges in timepicker

* Fixing tests by mocking out useKibanaUISetting

* add definition override to useKibanaUISetting for timepicker:quickRanges; reduce duplicate code for mapping quick ranges

* Fixing types

Co-authored-by: Elastic Machine <[email protected]>

Co-authored-by: Elastic Machine <[email protected]>
  • Loading branch information
simianhacker and elasticmachine authored Feb 11, 2020
1 parent 8b3a323 commit a3ce273
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import { MetricsExplorerChartOptions as MetricsExplorerChartOptionsComponent } f
import { SavedViewsToolbarControls } from '../saved_views/toolbar_control';
import { MetricExplorerViewState } from '../../pages/infrastructure/metrics_explorer/use_metric_explorer_state';
import { metricsExplorerViewSavedObjectType } from '../../../common/saved_objects/metrics_explorer_view';
import { useKibanaUiSetting } from '../../utils/use_kibana_ui_setting';
import { mapKibanaQuickRangesToDatePickerRanges } from '../../utils/map_timepicker_quickranges_to_datepicker_ranges';

interface Props {
derivedIndexPattern: IIndexPattern;
Expand Down Expand Up @@ -59,6 +61,8 @@ export const MetricsExplorerToolbar = ({
onViewStateChange,
}: Props) => {
const isDefaultOptions = options.aggregation === 'avg' && options.metrics.length === 0;
const [timepickerQuickRanges] = useKibanaUiSetting('timepicker:quickRanges');
const commonlyUsedRanges = mapKibanaQuickRangesToDatePickerRanges(timepickerQuickRanges);
return (
<Toolbar>
<EuiFlexGroup alignItems="center">
Expand Down Expand Up @@ -134,6 +138,7 @@ export const MetricsExplorerToolbar = ({
end={timeRange.to}
onTimeChange={({ start, end }) => onTimeChange(start, end)}
onRefresh={onRefresh}
commonlyUsedRanges={commonlyUsedRanges}
/>
</EuiFlexItem>
</EuiFlexGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
jest.mock('../../../utils/use_kibana_ui_setting', () => ({
_esModule: true,
useKibanaUiSetting: jest.fn(() => [
[
{
from: 'now/d',
to: 'now/d',
display: 'Today',
},
],
]),
}));

import React from 'react';
import { MetricsTimeControls } from './time_controls';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
*/

import { EuiSuperDatePicker, OnRefreshChangeProps, OnTimeChangeProps } from '@elastic/eui';
import React from 'react';
import React, { useCallback } from 'react';
import euiStyled from '../../../../../../common/eui_styled_components';
import { MetricsTimeInput } from '../containers/with_metrics_time';
import { useKibanaUiSetting } from '../../../utils/use_kibana_ui_setting';
import { mapKibanaQuickRangesToDatePickerRanges } from '../../../utils/map_timepicker_quickranges_to_datepicker_ranges';

interface MetricsTimeControlsProps {
currentTimeRange: MetricsTimeInput;
Expand All @@ -19,41 +21,58 @@ interface MetricsTimeControlsProps {
onRefresh: () => void;
}

export class MetricsTimeControls extends React.Component<MetricsTimeControlsProps> {
public render() {
const { currentTimeRange, isLiveStreaming, refreshInterval } = this.props;
return (
<MetricsTimeControlsContainer>
<EuiSuperDatePicker
start={currentTimeRange.from}
end={currentTimeRange.to}
isPaused={!isLiveStreaming}
refreshInterval={refreshInterval ? refreshInterval : 0}
onTimeChange={this.handleTimeChange}
onRefreshChange={this.handleRefreshChange}
onRefresh={this.props.onRefresh}
/>
</MetricsTimeControlsContainer>
);
}

private handleTimeChange = ({ start, end }: OnTimeChangeProps) => {
this.props.onChangeTimeRange({
from: start,
to: end,
interval: '>=1m',
});
};

private handleRefreshChange = ({ isPaused, refreshInterval }: OnRefreshChangeProps) => {
if (isPaused) {
this.props.setAutoReload(false);
} else {
this.props.setRefreshInterval(refreshInterval);
this.props.setAutoReload(true);
}
};
}
export const MetricsTimeControls = (props: MetricsTimeControlsProps) => {
const [timepickerQuickRanges] = useKibanaUiSetting('timepicker:quickRanges');
const {
onChangeTimeRange,
onRefresh,
currentTimeRange,
isLiveStreaming,
refreshInterval,
setAutoReload,
setRefreshInterval,
} = props;

const commonlyUsedRanges = mapKibanaQuickRangesToDatePickerRanges(timepickerQuickRanges);

const handleTimeChange = useCallback(
({ start, end }: OnTimeChangeProps) => {
onChangeTimeRange({
from: start,
to: end,
interval: '>=1m',
});
},
[onChangeTimeRange]
);

const handleRefreshChange = useCallback(
({ isPaused, refreshInterval: _refreshInterval }: OnRefreshChangeProps) => {
if (isPaused) {
setAutoReload(false);
} else {
setRefreshInterval(_refreshInterval);
setAutoReload(true);
}
},
[setAutoReload, setRefreshInterval]
);

return (
<MetricsTimeControlsContainer>
<EuiSuperDatePicker
start={currentTimeRange.from}
end={currentTimeRange.to}
isPaused={!isLiveStreaming}
refreshInterval={refreshInterval ? refreshInterval : 0}
onTimeChange={handleTimeChange}
onRefreshChange={handleRefreshChange}
onRefresh={onRefresh}
commonlyUsedRanges={commonlyUsedRanges}
/>
</MetricsTimeControlsContainer>
);
};

const MetricsTimeControlsContainer = euiStyled.div`
max-width: 750px;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { EuiSuperDatePickerCommonRange } from '@elastic/eui';
import { TimePickerQuickRange } from './use_kibana_ui_setting';

export const mapKibanaQuickRangesToDatePickerRanges = (
timepickerQuickRanges: TimePickerQuickRange[] | undefined
): EuiSuperDatePickerCommonRange[] =>
timepickerQuickRanges
? timepickerQuickRanges.map(r => ({
start: r.from,
end: r.to,
label: r.display,
}))
: [];
24 changes: 22 additions & 2 deletions x-pack/legacy/plugins/infra/public/utils/use_kibana_ui_setting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,27 @@ import useObservable from 'react-use/lib/useObservable';
* Unlike the `useState`, it doesn't give type guarantees for the value,
* because the underlying `UiSettingsClient` doesn't support that.
*/
export const useKibanaUiSetting = (key: string, defaultValue?: any) => {

export interface TimePickerQuickRange {
from: string;
to: string;
display: string;
}

export function useKibanaUiSetting(
key: 'timepicker:quickRanges',
defaultValue?: TimePickerQuickRange[]
): [
TimePickerQuickRange[],
(key: 'timepicker:quickRanges', value: TimePickerQuickRange[]) => Promise<boolean>
];

export function useKibanaUiSetting(
key: string,
defaultValue?: any
): [any, (key: string, value: any) => Promise<boolean>];

export function useKibanaUiSetting(key: string, defaultValue?: any) {
const uiSettingsClient = npSetup.core.uiSettings;

const uiSetting$ = useMemo(() => uiSettingsClient.get$(key, defaultValue), [
Expand All @@ -41,4 +61,4 @@ export const useKibanaUiSetting = (key: string, defaultValue?: any) => {
]);

return [uiSetting, setUiSetting];
};
}

0 comments on commit a3ce273

Please sign in to comment.