mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
TimePicker: will display the correct dates when selecting range in calendar with tz. (#35829)
* fixing calendar issue. * reset yarn.lock. * added boilerplate for test. * added tests to verify bugfix.
This commit is contained in:
@@ -4,6 +4,7 @@ export const Components = {
|
||||
fromField: 'TimePicker from field',
|
||||
toField: 'TimePicker to field',
|
||||
applyTimeRange: 'TimePicker submit button',
|
||||
calendar: 'TimePicker calendar',
|
||||
},
|
||||
DataSource: {
|
||||
TestData: {
|
||||
|
||||
@@ -8,6 +8,7 @@ import { Button } from '../../Button';
|
||||
import { Icon } from '../../Icon/Icon';
|
||||
import { Portal } from '../../Portal/Portal';
|
||||
import { ClickOutsideWrapper } from '../../ClickOutsideWrapper/ClickOutsideWrapper';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
|
||||
export const getStyles = stylesFactory((theme: GrafanaTheme2, isReversed = false) => {
|
||||
return {
|
||||
@@ -208,7 +209,11 @@ export const TimePickerCalendar = memo<Props>((props) => {
|
||||
if (isFullscreen) {
|
||||
return (
|
||||
<ClickOutsideWrapper onClick={props.onClose}>
|
||||
<div className={styles.container} onClick={stopPropagation}>
|
||||
<div
|
||||
className={styles.container}
|
||||
onClick={stopPropagation}
|
||||
aria-label={selectors.components.TimePicker.calendar}
|
||||
>
|
||||
<Body {...props} />
|
||||
</div>
|
||||
</ClickOutsideWrapper>
|
||||
@@ -218,7 +223,7 @@ export const TimePickerCalendar = memo<Props>((props) => {
|
||||
return (
|
||||
<Portal>
|
||||
<div className={styles.modal} onClick={stopPropagation}>
|
||||
<div className={styles.content}>
|
||||
<div className={styles.content} aria-label={selectors.components.TimePicker.calendar}>
|
||||
<Header {...props} />
|
||||
<Body {...props} />
|
||||
<Footer {...props} />
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
import React from 'react';
|
||||
import { fireEvent, render, RenderResult } from '@testing-library/react';
|
||||
import { dateTimeParse, TimeRange } from '@grafana/data';
|
||||
import { TimeRangeForm } from './TimeRangeForm';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
|
||||
type TimeRangeFormRenderResult = RenderResult & {
|
||||
getCalendarDayByLabelText(label: string): HTMLButtonElement;
|
||||
};
|
||||
|
||||
const defaultTimeRange: TimeRange = {
|
||||
from: dateTimeParse('2021-06-17 00:00:00', { timeZone: 'utc' }),
|
||||
to: dateTimeParse('2021-06-19 23:59:00', { timeZone: 'utc' }),
|
||||
raw: {
|
||||
from: '2021-06-17 00:00:00',
|
||||
to: '2021-06-19 23:59:00',
|
||||
},
|
||||
};
|
||||
|
||||
function setup(initial: TimeRange = defaultTimeRange, timeZone = 'utc'): TimeRangeFormRenderResult {
|
||||
const result = render(<TimeRangeForm isFullscreen={true} value={initial} onApply={() => {}} timeZone={timeZone} />);
|
||||
|
||||
return {
|
||||
...result,
|
||||
getCalendarDayByLabelText: (label: string) => {
|
||||
const item = result.getByLabelText(label);
|
||||
return item?.parentElement as HTMLButtonElement;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe('TimeRangeForm', () => {
|
||||
it('should render form correcty', () => {
|
||||
const { getByLabelText } = setup();
|
||||
const { TimePicker } = selectors.components;
|
||||
|
||||
expect(getByLabelText(TimePicker.applyTimeRange)).toBeInTheDocument();
|
||||
expect(getByLabelText(TimePicker.fromField)).toBeInTheDocument();
|
||||
expect(getByLabelText(TimePicker.toField)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should display calendar when clicking the from input field', () => {
|
||||
const { getByLabelText } = setup();
|
||||
const { TimePicker } = selectors.components;
|
||||
|
||||
fireEvent.focus(getByLabelText(TimePicker.fromField));
|
||||
expect(getByLabelText(TimePicker.calendar)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should have passed time range entered in form', () => {
|
||||
const { getByLabelText } = setup();
|
||||
const { TimePicker } = selectors.components;
|
||||
|
||||
const fromValue = defaultTimeRange.raw.from as string;
|
||||
const toValue = defaultTimeRange.raw.to as string;
|
||||
|
||||
expect(getByLabelText(TimePicker.fromField)).toHaveValue(fromValue);
|
||||
expect(getByLabelText(TimePicker.toField)).toHaveValue(toValue);
|
||||
});
|
||||
|
||||
it('should display calendar when clicking the to input field', () => {
|
||||
const { getByLabelText } = setup();
|
||||
const { TimePicker } = selectors.components;
|
||||
|
||||
fireEvent.focus(getByLabelText(TimePicker.toField));
|
||||
expect(getByLabelText(TimePicker.calendar)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not display calendar without clicking any input field', () => {
|
||||
const { queryByLabelText } = setup();
|
||||
const { TimePicker } = selectors.components;
|
||||
|
||||
expect(queryByLabelText(TimePicker.calendar)).toBeNull();
|
||||
});
|
||||
|
||||
it('should have passed time range selected in calendar', () => {
|
||||
const { getByLabelText, getCalendarDayByLabelText } = setup();
|
||||
const { TimePicker } = selectors.components;
|
||||
|
||||
fireEvent.focus(getByLabelText(TimePicker.toField));
|
||||
const from = getCalendarDayByLabelText('June 17, 2021');
|
||||
const to = getCalendarDayByLabelText('June 19, 2021');
|
||||
|
||||
expect(from).toHaveClass('react-calendar__tile--rangeStart');
|
||||
expect(to).toHaveClass('react-calendar__tile--rangeEnd');
|
||||
});
|
||||
|
||||
it('should select correct time range in calendar when having a custom time zone', () => {
|
||||
const { getByLabelText, getCalendarDayByLabelText } = setup(defaultTimeRange, 'Asia/Tokyo');
|
||||
const { TimePicker } = selectors.components;
|
||||
|
||||
fireEvent.focus(getByLabelText(TimePicker.toField));
|
||||
const from = getCalendarDayByLabelText('June 17, 2021');
|
||||
const to = getCalendarDayByLabelText('June 19, 2021');
|
||||
|
||||
expect(from).toHaveClass('react-calendar__tile--rangeStart');
|
||||
expect(to).toHaveClass('react-calendar__tile--rangeEnd');
|
||||
});
|
||||
});
|
||||
@@ -117,8 +117,8 @@ export const TimeRangeForm: React.FC<Props> = (props) => {
|
||||
<TimePickerCalendar
|
||||
isFullscreen={isFullscreen}
|
||||
isOpen={isOpen}
|
||||
from={dateTimeParse(from.value, { timeZone })}
|
||||
to={dateTimeParse(to.value, { timeZone })}
|
||||
from={dateTimeParse(from.value)}
|
||||
to={dateTimeParse(to.value)}
|
||||
onApply={onApply}
|
||||
onClose={() => setOpen(false)}
|
||||
onChange={onChange}
|
||||
|
||||
Reference in New Issue
Block a user