mirror of
https://github.com/grafana/grafana.git
synced 2025-09-18 05:13:01 +08:00
Explore: respect min_refresh_interval (#27988)
* Explore: respect min_refresh_interval Fixes #27494 * fixup! Explore: respect min_refresh_interval * fixup! Explore: respect min_refresh_interval * UI: export defaultIntervals from refresh picker * fixup! Explore: respect min_refresh_interval Co-authored-by: Zoltán Bedi <zoltan.bedi@gmail.com>
This commit is contained in:
@ -549,9 +549,11 @@ Number dashboard versions to keep (per dashboard). Default: `20`, Minimum: `1`.
|
|||||||
|
|
||||||
> Only available in Grafana v6.7+.
|
> Only available in Grafana v6.7+.
|
||||||
|
|
||||||
This prevents users from setting the dashboard refresh interval of a lower than given interval. Per default this is 5 seconds.
|
This feature prevents users from setting the dashboard refresh interval to a lower value than a given interval value. The default interval value is 5 seconds.
|
||||||
The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. `30s` or `1m`.
|
The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. `30s` or `1m`.
|
||||||
|
|
||||||
|
As of Grafana v7.3, this also limits the refresh interval options in Explore.
|
||||||
|
|
||||||
### default_home_dashboard_path
|
### default_home_dashboard_path
|
||||||
|
|
||||||
Path to the default home dashboard. If this value is empty, then Grafana uses StaticRootPath + "dashboards/home.json"
|
Path to the default home dashboard. If this value is empty, then Grafana uses StaticRootPath + "dashboards/home.json"
|
||||||
|
@ -9,6 +9,7 @@ import memoizeOne from 'memoize-one';
|
|||||||
import { GrafanaTheme } from '@grafana/data';
|
import { GrafanaTheme } from '@grafana/data';
|
||||||
import { withTheme } from '../../themes';
|
import { withTheme } from '../../themes';
|
||||||
|
|
||||||
|
// Default intervals used in the refresh picker component
|
||||||
export const defaultIntervals = ['5s', '10s', '30s', '1m', '5m', '15m', '30m', '1h', '2h', '1d'];
|
export const defaultIntervals = ['5s', '10s', '30s', '1m', '5m', '15m', '30m', '1h', '2h', '1d'];
|
||||||
|
|
||||||
const getStyles = memoizeOne((theme: GrafanaTheme) => {
|
const getStyles = memoizeOne((theme: GrafanaTheme) => {
|
||||||
|
@ -22,7 +22,7 @@ export { EmptySearchResult } from './EmptySearchResult/EmptySearchResult';
|
|||||||
export { PieChart, PieChartType } from './PieChart/PieChart';
|
export { PieChart, PieChartType } from './PieChart/PieChart';
|
||||||
export { UnitPicker } from './UnitPicker/UnitPicker';
|
export { UnitPicker } from './UnitPicker/UnitPicker';
|
||||||
export { StatsPicker } from './StatsPicker/StatsPicker';
|
export { StatsPicker } from './StatsPicker/StatsPicker';
|
||||||
export { RefreshPicker } from './RefreshPicker/RefreshPicker';
|
export { RefreshPicker, defaultIntervals } from './RefreshPicker/RefreshPicker';
|
||||||
export { TimeRangePicker } from './TimePicker/TimeRangePicker';
|
export { TimeRangePicker } from './TimePicker/TimeRangePicker';
|
||||||
export { TimeOfDayPicker } from './TimePicker/TimeOfDayPicker';
|
export { TimeOfDayPicker } from './TimePicker/TimeOfDayPicker';
|
||||||
export { TimeZonePicker } from './TimePicker/TimeZonePicker';
|
export { TimeZonePicker } from './TimePicker/TimeZonePicker';
|
||||||
|
@ -12,12 +12,11 @@ import { TimeRange } from '@grafana/data';
|
|||||||
import { updateTimeZoneForSession } from 'app/features/profile/state/reducers';
|
import { updateTimeZoneForSession } from 'app/features/profile/state/reducers';
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import { RefreshPicker, withTheme, stylesFactory, Themeable } from '@grafana/ui';
|
import { RefreshPicker, withTheme, stylesFactory, Themeable, defaultIntervals } from '@grafana/ui';
|
||||||
import { TimePickerWithHistory } from 'app/core/components/TimePicker/TimePickerWithHistory';
|
import { TimePickerWithHistory } from 'app/core/components/TimePicker/TimePickerWithHistory';
|
||||||
|
|
||||||
// Utils & Services
|
// Utils & Services
|
||||||
import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||||
import { defaultIntervals } from '@grafana/ui/src/components/RefreshPicker/RefreshPicker';
|
|
||||||
import { appEvents } from 'app/core/core';
|
import { appEvents } from 'app/core/core';
|
||||||
|
|
||||||
const getStyles = stylesFactory((theme: GrafanaTheme) => {
|
const getStyles = stylesFactory((theme: GrafanaTheme) => {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render, screen } from '@testing-library/react';
|
import { render, screen } from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import { defaultIntervals } from '@grafana/ui/src/components/RefreshPicker/RefreshPicker';
|
import { defaultIntervals } from '@grafana/ui';
|
||||||
|
|
||||||
import { AutoRefreshIntervals, getValidIntervals, Props, validateIntervals } from './AutoRefreshIntervals';
|
import { AutoRefreshIntervals, getValidIntervals, Props, validateIntervals } from './AutoRefreshIntervals';
|
||||||
import { TimeSrv } from '../../services/TimeSrv';
|
import { TimeSrv } from '../../services/TimeSrv';
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import React, { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
import React, { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { Input, Tooltip } from '@grafana/ui';
|
import { Input, Tooltip, defaultIntervals } from '@grafana/ui';
|
||||||
import { defaultIntervals } from '@grafana/ui/src/components/RefreshPicker/RefreshPicker';
|
|
||||||
|
|
||||||
import { getTimeSrv } from '../../services/TimeSrv';
|
import { getTimeSrv } from '../../services/TimeSrv';
|
||||||
|
|
||||||
|
47
public/app/features/explore/RunButton.test.tsx
Normal file
47
public/app/features/explore/RunButton.test.tsx
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { RunButton, Props } from './RunButton';
|
||||||
|
import { RefreshPicker } from '@grafana/ui';
|
||||||
|
import { shallow } from 'enzyme';
|
||||||
|
import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||||
|
|
||||||
|
const setup = (propOverrides?: object) => {
|
||||||
|
const props: Props = {
|
||||||
|
splitted: false,
|
||||||
|
loading: false,
|
||||||
|
isLive: false,
|
||||||
|
onRun: jest.fn(),
|
||||||
|
refreshInterval: '5m',
|
||||||
|
onChangeRefreshInterval: jest.fn(),
|
||||||
|
showDropdown: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.assign(props, propOverrides);
|
||||||
|
|
||||||
|
const wrapper = shallow(<RunButton {...props} />);
|
||||||
|
return wrapper;
|
||||||
|
};
|
||||||
|
|
||||||
|
const validIntervals = ['1d'];
|
||||||
|
jest.mock('app/features/dashboard/services/TimeSrv', () => ({
|
||||||
|
getTimeSrv: jest.fn().mockReturnValue({
|
||||||
|
getValidIntervals(intervals: string[]): string[] {
|
||||||
|
return validIntervals;
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
const getTimeSrvMock = (getTimeSrv as any) as jest.Mock<TimeSrv>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
getTimeSrvMock.mockClear();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('RunButton', () => {
|
||||||
|
describe('if showdropdown is set', () => {
|
||||||
|
it('should render a RefreshPicker with only valid intervals', () => {
|
||||||
|
const wrapper = setup({ showDropdown: true });
|
||||||
|
|
||||||
|
expect(wrapper.find(RefreshPicker)).toHaveLength(1);
|
||||||
|
expect(wrapper.find(RefreshPicker).props().intervals).toEqual(validIntervals);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { RefreshPicker } from '@grafana/ui';
|
import { RefreshPicker, defaultIntervals } from '@grafana/ui';
|
||||||
import { selectors } from '@grafana/e2e-selectors';
|
import { selectors } from '@grafana/e2e-selectors';
|
||||||
import memoizeOne from 'memoize-one';
|
import memoizeOne from 'memoize-one';
|
||||||
import { css } from 'emotion';
|
import { css } from 'emotion';
|
||||||
@ -7,6 +7,8 @@ import classNames from 'classnames';
|
|||||||
|
|
||||||
import { ResponsiveButton } from './ResponsiveButton';
|
import { ResponsiveButton } from './ResponsiveButton';
|
||||||
|
|
||||||
|
import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||||
|
|
||||||
const getStyles = memoizeOne(() => {
|
const getStyles = memoizeOne(() => {
|
||||||
return {
|
return {
|
||||||
selectButtonOverride: css`
|
selectButtonOverride: css`
|
||||||
@ -18,7 +20,7 @@ const getStyles = memoizeOne(() => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
type Props = {
|
export type Props = {
|
||||||
splitted: boolean;
|
splitted: boolean;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
isLive: boolean;
|
isLive: boolean;
|
||||||
@ -31,6 +33,7 @@ type Props = {
|
|||||||
export function RunButton(props: Props) {
|
export function RunButton(props: Props) {
|
||||||
const { splitted, loading, onRun, onChangeRefreshInterval, refreshInterval, showDropdown, isLive } = props;
|
const { splitted, loading, onRun, onChangeRefreshInterval, refreshInterval, showDropdown, isLive } = props;
|
||||||
const styles = getStyles();
|
const styles = getStyles();
|
||||||
|
const intervals = getTimeSrv().getValidIntervals(defaultIntervals);
|
||||||
|
|
||||||
const runButton = (
|
const runButton = (
|
||||||
<ResponsiveButton
|
<ResponsiveButton
|
||||||
@ -57,6 +60,7 @@ export function RunButton(props: Props) {
|
|||||||
styles.selectButtonOverride
|
styles.selectButtonOverride
|
||||||
}`}
|
}`}
|
||||||
refreshButton={runButton}
|
refreshButton={runButton}
|
||||||
|
intervals={intervals}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user