StateTimeline: Add unit tests for usePagination hook, reorganize/rename some files (#112532)
* StateTimeline: Add unit tests for usePagination hook * reorganize styles * StateTimelineTooltip2 -> StateTimelineTooltip
This commit is contained in:
@@ -22,9 +22,10 @@ import { AnnotationsPlugin2 } from '../timeseries/plugins/AnnotationsPlugin2';
|
||||
import { OutsideRangePlugin } from '../timeseries/plugins/OutsideRangePlugin';
|
||||
import { getTimezones } from '../timeseries/utils';
|
||||
|
||||
import { StateTimelineTooltip2 } from './StateTimelineTooltip2';
|
||||
import { StateTimelineTooltip } from './StateTimelineTooltip';
|
||||
import { usePagination } from './hooks';
|
||||
import { Options } from './panelcfg.gen';
|
||||
import { containerStyles, usePagination } from './utils';
|
||||
import { containerStyles } from './styles';
|
||||
|
||||
interface TimelinePanelProps extends PanelProps<Options> {}
|
||||
|
||||
@@ -78,7 +79,7 @@ export const StateTimelinePanel = ({
|
||||
const enableAnnotationCreation = Boolean(canAddAnnotations && canAddAnnotations());
|
||||
|
||||
return (
|
||||
<div className={containerStyles.container}>
|
||||
<div className={containerStyles}>
|
||||
<TimelineChart
|
||||
theme={theme}
|
||||
frames={paginatedFrames}
|
||||
@@ -128,7 +129,7 @@ export const StateTimelinePanel = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<StateTimelineTooltip2
|
||||
<StateTimelineTooltip
|
||||
series={alignedFrame}
|
||||
dataIdxs={dataIdxs}
|
||||
seriesIdx={seriesIdx}
|
||||
|
||||
+3
-3
@@ -17,12 +17,12 @@ import { getFieldActions } from '../status-history/utils';
|
||||
import { TimeSeriesTooltipProps } from '../timeseries/TimeSeriesTooltip';
|
||||
import { isTooltipScrollable } from '../timeseries/utils';
|
||||
|
||||
interface StateTimelineTooltip2Props extends TimeSeriesTooltipProps {
|
||||
interface StateTimelineTooltipProps extends TimeSeriesTooltipProps {
|
||||
timeRange: TimeRange;
|
||||
withDuration: boolean;
|
||||
}
|
||||
|
||||
export const StateTimelineTooltip2 = ({
|
||||
export const StateTimelineTooltip = ({
|
||||
series,
|
||||
dataIdxs,
|
||||
seriesIdx,
|
||||
@@ -35,7 +35,7 @@ export const StateTimelineTooltip2 = ({
|
||||
maxHeight,
|
||||
replaceVariables,
|
||||
dataLinks,
|
||||
}: StateTimelineTooltip2Props) => {
|
||||
}: StateTimelineTooltipProps) => {
|
||||
const xField = series.fields[0];
|
||||
|
||||
const dataIdx = seriesIdx != null ? dataIdxs[seriesIdx] : dataIdxs.find((idx) => idx != null);
|
||||
@@ -0,0 +1,62 @@
|
||||
import { render, renderHook, screen } from '@testing-library/react';
|
||||
|
||||
import { createDataFrame, FieldType } from '@grafana/data';
|
||||
|
||||
import { usePagination } from './hooks';
|
||||
|
||||
describe('StateTimelinePanel hooks', () => {
|
||||
describe('usePagination', () => {
|
||||
describe('empty value', () => {
|
||||
it('returns the empty value if perPage is not set', () => {
|
||||
const { result } = renderHook(() => usePagination([]));
|
||||
expect(result.current).toEqual({
|
||||
paginatedFrames: [],
|
||||
paginationRev: 'disabled',
|
||||
paginationElement: undefined,
|
||||
paginationHeight: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it('returns the empty value if frames are not set', () => {
|
||||
const { result } = renderHook(() => usePagination(undefined, 5));
|
||||
expect(result.current).toEqual({
|
||||
paginatedFrames: undefined,
|
||||
paginationRev: 'disabled',
|
||||
paginationElement: undefined,
|
||||
paginationHeight: 0,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('returns the React element to be rendered for pagination', () => {
|
||||
const frames = createDataFrame({
|
||||
fields: [
|
||||
{ name: 'time', type: FieldType.time, values: [100, 200, 300] },
|
||||
{ name: 'value-A', type: FieldType.number, values: [4, 5, 6] },
|
||||
{ name: 'value-B', type: FieldType.number, values: [4, 5, 6] },
|
||||
{ name: 'value-C', type: FieldType.number, values: [4, 5, 6] },
|
||||
],
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => usePagination([frames], 2));
|
||||
|
||||
expect(result.current.paginatedFrames?.length).toBe(2);
|
||||
});
|
||||
|
||||
const frame = createDataFrame({
|
||||
fields: [
|
||||
{ name: 'time', type: FieldType.time, values: [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000] },
|
||||
{ name: 'value-A', type: FieldType.number, values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] },
|
||||
{ name: 'value-B', type: FieldType.number, values: [11, 12, 13, 14, 15, 16, 17, 18, 19, 20] },
|
||||
{ name: 'value-C', type: FieldType.number, values: [21, 22, 23, 24, 25, 26, 27, 28, 29, 30] },
|
||||
],
|
||||
});
|
||||
const { result } = renderHook(() => usePagination([frame], 2));
|
||||
|
||||
render(result.current.paginationElement);
|
||||
|
||||
expect(screen.getByText('1')).toBeInTheDocument(); // current page
|
||||
expect(screen.getByText('2')).toBeInTheDocument(); // last page
|
||||
expect(screen.getByLabelText('next page')).not.toBeDisabled();
|
||||
});
|
||||
});
|
||||
+3
-14
@@ -6,16 +6,7 @@ import { DataFrame } from '@grafana/data';
|
||||
import { Pagination } from '@grafana/ui';
|
||||
import { makeFramePerSeries } from 'app/core/components/TimelineChart/utils';
|
||||
|
||||
import { defaultOptions } from './panelcfg.gen';
|
||||
|
||||
export const containerStyles = {
|
||||
container: css({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
}),
|
||||
};
|
||||
|
||||
const styles = {
|
||||
const paginationStyles = {
|
||||
paginationContainer: css({
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
@@ -45,8 +36,6 @@ export function usePagination(frames?: DataFrame[], perPage?: number) {
|
||||
};
|
||||
}
|
||||
|
||||
perPage ||= defaultOptions.perPage!;
|
||||
|
||||
const numberOfPages = Math.ceil(pagedFrames.length / perPage);
|
||||
// `perPage` changing might lead to temporarily too large values of `currentPage`.
|
||||
const currentPageCapped = Math.min(currentPage, numberOfPages);
|
||||
@@ -60,9 +49,9 @@ export function usePagination(frames?: DataFrame[], perPage?: number) {
|
||||
|
||||
const showSmallVersion = paginationWidth < 550;
|
||||
const paginationElement = (
|
||||
<div className={styles.paginationContainer} ref={paginationWrapperRef}>
|
||||
<div className={paginationStyles.paginationContainer} ref={paginationWrapperRef}>
|
||||
<Pagination
|
||||
className={styles.paginationElement}
|
||||
className={paginationStyles.paginationElement}
|
||||
currentPage={currentPageCapped}
|
||||
numberOfPages={numberOfPages}
|
||||
showSmallVersion={showSmallVersion}
|
||||
@@ -0,0 +1,6 @@
|
||||
import { css } from '@emotion/css';
|
||||
|
||||
export const containerStyles = css({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
});
|
||||
@@ -19,8 +19,9 @@ import {
|
||||
TimelineMode,
|
||||
} from 'app/core/components/TimelineChart/utils';
|
||||
|
||||
import { StateTimelineTooltip2 } from '../state-timeline/StateTimelineTooltip2';
|
||||
import { containerStyles, usePagination } from '../state-timeline/utils';
|
||||
import { StateTimelineTooltip } from '../state-timeline/StateTimelineTooltip';
|
||||
import { usePagination } from '../state-timeline/hooks';
|
||||
import { containerStyles } from '../state-timeline/styles';
|
||||
import { AnnotationsPlugin2 } from '../timeseries/plugins/AnnotationsPlugin2';
|
||||
import { OutsideRangePlugin } from '../timeseries/plugins/OutsideRangePlugin';
|
||||
import { getTimezones } from '../timeseries/utils';
|
||||
@@ -91,7 +92,7 @@ export const StatusHistoryPanel = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={containerStyles.container}>
|
||||
<div className={containerStyles}>
|
||||
<TimelineChart
|
||||
theme={theme}
|
||||
frames={paginatedFrames}
|
||||
@@ -141,7 +142,7 @@ export const StatusHistoryPanel = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<StateTimelineTooltip2
|
||||
<StateTimelineTooltip
|
||||
series={alignedFrame}
|
||||
dataIdxs={dataIdxs}
|
||||
seriesIdx={seriesIdx}
|
||||
|
||||
Reference in New Issue
Block a user