mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Explore: avoid locking timepicker when range is inverted (#44790)
* Explore: avoid locking timepicker when range is inverted * Explore: prevent time picker to lock if from & to search parameters are present
This commit is contained in:
parent
bb88cf683c
commit
6415b9a54d
@ -11,6 +11,7 @@ import {
|
||||
getExploreUrl,
|
||||
GetExploreUrlArguments,
|
||||
getTimeRangeFromUrl,
|
||||
getTimeRange,
|
||||
} from './explore';
|
||||
import store from 'app/core/store';
|
||||
import { dateTime, ExploreUrlState, LogsSortOrder } from '@grafana/data';
|
||||
@ -361,6 +362,19 @@ describe('getTimeRangeFromUrl', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTimeRange', () => {
|
||||
describe('should flip from and to when from is after to', () => {
|
||||
const rawRange = {
|
||||
from: 'now',
|
||||
to: 'now-6h',
|
||||
};
|
||||
|
||||
const range = getTimeRange('utc', rawRange, 0);
|
||||
|
||||
expect(range.from.isBefore(range.to)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getRefIds', () => {
|
||||
describe('when called with a null value', () => {
|
||||
it('then it should return empty array', () => {
|
||||
|
@ -358,11 +358,13 @@ export const getQueryKeys = (queries: DataQuery[], datasourceInstance?: DataSour
|
||||
};
|
||||
|
||||
export const getTimeRange = (timeZone: TimeZone, rawRange: RawTimeRange, fiscalYearStartMonth: number): TimeRange => {
|
||||
return {
|
||||
from: dateMath.parse(rawRange.from, false, timeZone as any, fiscalYearStartMonth)!,
|
||||
to: dateMath.parse(rawRange.to, true, timeZone as any, fiscalYearStartMonth)!,
|
||||
raw: rawRange,
|
||||
};
|
||||
let range = rangeUtil.convertRawToRange(rawRange, timeZone, fiscalYearStartMonth);
|
||||
|
||||
if (range.to.isBefore(range.from)) {
|
||||
range = rangeUtil.convertRawToRange({ from: range.raw.to, to: range.raw.from }, timeZone, fiscalYearStartMonth);
|
||||
}
|
||||
|
||||
return range;
|
||||
};
|
||||
|
||||
const parseRawTime = (value: string | DateTime): TimeFragment | null => {
|
||||
|
@ -314,12 +314,20 @@ describe('Wrapper', () => {
|
||||
store.dispatch(splitOpen<any>({ datasourceUid: 'elastic', query: { expr: 'error' } }) as any);
|
||||
await waitFor(() => expect(document.title).toEqual('Explore - loki | elastic - Grafana'));
|
||||
});
|
||||
|
||||
it('removes `from` and `to` parameters from url when first mounted', () => {
|
||||
setup({ searchParams: 'from=1&to=2&orgId=1' });
|
||||
|
||||
expect(locationService.getSearchObject()).toEqual(expect.not.objectContaining({ from: '1', to: '2' }));
|
||||
expect(locationService.getSearchObject()).toEqual(expect.objectContaining({ orgId: '1' }));
|
||||
});
|
||||
});
|
||||
|
||||
type DatasourceSetup = { settings: DataSourceInstanceSettings; api: DataSourceApi };
|
||||
type SetupOptions = {
|
||||
datasources?: DatasourceSetup[];
|
||||
query?: any;
|
||||
searchParams?: string;
|
||||
};
|
||||
|
||||
function setup(options?: SetupOptions): { datasources: { [name: string]: DataSourceApi }; store: EnhancedStore } {
|
||||
@ -368,7 +376,7 @@ function setup(options?: SetupOptions): { datasources: { [name: string]: DataSou
|
||||
},
|
||||
};
|
||||
|
||||
locationService.push({ pathname: '/explore' });
|
||||
locationService.push({ pathname: '/explore', search: options?.searchParams });
|
||||
|
||||
if (options?.query) {
|
||||
locationService.partial(options.query);
|
||||
|
@ -10,6 +10,7 @@ import { Branding } from '../../core/components/Branding/Branding';
|
||||
|
||||
import { getNavModel } from '../../core/selectors/navModel';
|
||||
import { StoreState } from 'app/types';
|
||||
import { locationService } from '@grafana/runtime';
|
||||
|
||||
interface RouteProps extends GrafanaRouteComponentProps<{}, ExploreQueryParams> {}
|
||||
interface OwnProps {}
|
||||
@ -38,6 +39,20 @@ class WrapperUnconnected extends PureComponent<Props> {
|
||||
lastSavedUrl.left = undefined;
|
||||
lastSavedUrl.right = undefined;
|
||||
|
||||
// timeSrv (which is used internally) on init reads `from` and `to` param from the URL and updates itself
|
||||
// using those value regardless of what is passed to the init method.
|
||||
// The updated value is then used by Explore to get the range for each pane.
|
||||
// This means that if `from` and `to` parameters are present in the URL,
|
||||
// it would be impossible to change the time range in Explore.
|
||||
// We are only doing this on mount for 2 reasons:
|
||||
// 1: Doing it on update means we'll enter a render loop.
|
||||
// 2: when parsing time in Explore (before feeding it to timeSrv) we make sure `from` is before `to` inside
|
||||
// each pane state in order to not trigger un URL update from timeSrv.
|
||||
const searchParams = locationService.getSearchObject();
|
||||
if (searchParams.from || searchParams.to) {
|
||||
locationService.partial({ from: undefined, to: undefined }, true);
|
||||
}
|
||||
|
||||
const richHistory = getRichHistory();
|
||||
this.props.richHistoryUpdatedAction({ richHistory });
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user