TimeRangePicker: Fix recent ranges not showing all items (#59836)

* Fix not all recently used time ranges showing

* Refactor time picker history to store simpler json objects

* Don't store duplicate items

* update todo tests:

* Add tests for TimePickerWithHistory

* better fix for focus scope issues in test
This commit is contained in:
Josh Hunt
2022-12-09 11:28:57 +00:00
committed by GitHub
parent 0c9aed905a
commit 6280780e0c
5 changed files with 236 additions and 22 deletions

View File

@@ -122,8 +122,8 @@ export function TimeRangePicker(props: TimeRangePickerProps) {
</ToolbarButton>
</Tooltip>
{isOpen && (
<FocusScope contain autoFocus>
<section ref={ref} {...overlayProps} {...dialogProps}>
<section ref={ref} {...overlayProps} {...dialogProps}>
<FocusScope contain autoFocus>
<TimePickerContent
timeZone={timeZone}
fiscalYearStartMonth={fiscalYearStartMonth}
@@ -137,8 +137,8 @@ export function TimeRangePicker(props: TimeRangePickerProps) {
onChangeFiscalYearStartMonth={onChangeFiscalYearStartMonth}
hideQuickRanges={hideQuickRanges}
/>
</section>
</FocusScope>
</FocusScope>
</section>
)}
{timeSyncButton}

View File

@@ -160,7 +160,6 @@ const NarrowScreenForm = (props: FormProps) => {
<div className={styles.form}>
<TimeRangeContent value={value} onApply={onChange} timeZone={timeZone} isFullscreen={false} />
</div>
<p></p>
{showHistory && (
<TimeRangeList
title={t('time-picker.absolute.recent-title', 'Recently used absolute ranges')}
@@ -246,7 +245,8 @@ function mapToHistoryOptions(ranges?: TimeRange[], timeZone?: TimeZone): TimeOpt
if (!Array.isArray(ranges) || ranges.length === 0) {
return [];
}
return ranges.slice(ranges.length - 4).map((range) => mapRangeToTimeOption(range, timeZone));
return ranges.map((range) => mapRangeToTimeOption(range, timeZone));
}
EmptyRecentList.displayName = 'EmptyRecentList';

View File

@@ -0,0 +1,56 @@
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { SelectableValue } from '@grafana/data';
import { ButtonSelect } from './ButtonSelect';
const OPTIONS: SelectableValue[] = [
{
label: 'Hello',
value: 'a',
},
{
label: 'World',
value: 'b',
},
];
describe('ButtonSelect', () => {
it('initially renders the selected value with the menu closed', () => {
const selected = OPTIONS[0];
render(<ButtonSelect value={selected} options={OPTIONS} onChange={() => {}} />);
expect(screen.getByText('Hello')).toBeInTheDocument();
expect(screen.queryAllByRole('menuitemradio')).toHaveLength(0);
});
it('opens the menu when clicking the button', async () => {
const selected = OPTIONS[0];
render(<ButtonSelect value={selected} options={OPTIONS} onChange={() => {}} />);
const button = screen.getByText('Hello');
await userEvent.click(button);
expect(screen.queryAllByRole('menuitemradio')).toHaveLength(2);
});
it('closes the menu when clicking an option', async () => {
const selected = OPTIONS[0];
const onChange = jest.fn();
render(<ButtonSelect value={selected} options={OPTIONS} onChange={onChange} />);
const button = screen.getByText('Hello');
await userEvent.click(button);
const option = screen.getByText('World');
await userEvent.click(option);
expect(screen.queryAllByRole('menuitemradio')).toHaveLength(0);
expect(onChange).toHaveBeenCalledWith({
label: 'World',
value: 'b',
});
});
});