{!emptyResults && isTimeSeriesResults && (
- {series.map((frame, index) => (
-
+ {pageItems.map((frame, index) => (
+
))}
)}
{!emptyResults &&
!isTimeSeriesResults &&
- series.map((frame, index) => (
+ pageItems.map((frame, index) => (
// There's no way to uniquely identify a frame that doesn't cause render bugs :/ (Gilles)
-
+
))}
{emptyResults &&
No data
}
+ {shouldShowPagination && (
+
+
+
+
+
+ {pageStart} - {pageEnd} of {series.length}
+
+
+
+
+
+ )}
);
};
@@ -429,11 +474,8 @@ const getStyles = (theme: GrafanaTheme2) => ({
`,
timeseriesTableWrapper: css`
max-height: 500px;
- max-width: 300px;
overflow-y: scroll;
-
- padding: 0 !important; // not sure why but style override doesn't work otherwise :( (Gilles)
`,
timeseriesTable: css`
table-layout: auto;
@@ -462,4 +504,10 @@ const getStyles = (theme: GrafanaTheme2) => ({
}
}
`,
+ pagination: {
+ wrapper: css`
+ border-top: 1px solid ${theme.colors.border.medium};
+ padding: ${theme.spacing()};
+ `,
+ },
});
diff --git a/public/app/features/alerting/unified/hooks/usePagination.test.tsx b/public/app/features/alerting/unified/hooks/usePagination.test.tsx
new file mode 100644
index 00000000000..48793b0ec5c
--- /dev/null
+++ b/public/app/features/alerting/unified/hooks/usePagination.test.tsx
@@ -0,0 +1,67 @@
+import { act, renderHook } from '@testing-library/react-hooks';
+
+import { usePagination } from './usePagination';
+
+describe('usePagination()', () => {
+ it('should work with no items', () => {
+ const { result } = renderHook(() => {
+ return usePagination([], 1, 20);
+ });
+
+ const { pageItems, numberOfPages, page, pageStart, pageEnd } = result.current;
+
+ expect(pageItems).toStrictEqual([]);
+ expect(numberOfPages).toStrictEqual(0);
+ expect(page).toStrictEqual(1);
+ expect(pageStart).toStrictEqual(1);
+ expect(pageEnd).toStrictEqual(0);
+ });
+
+ it('should work with items < page size', () => {
+ const { result } = renderHook(() => {
+ return usePagination([1, 2, 3], 1, 10);
+ });
+
+ const { pageItems, numberOfPages, page, pageStart, pageEnd } = result.current;
+
+ expect(pageItems).toStrictEqual([1, 2, 3]);
+ expect(numberOfPages).toStrictEqual(1);
+ expect(page).toStrictEqual(1);
+ expect(pageStart).toStrictEqual(1);
+ expect(pageEnd).toStrictEqual(3);
+ });
+
+ it('should work with items > page size', () => {
+ const { result } = renderHook(() => {
+ return usePagination([1, 2, 3], 1, 1);
+ });
+
+ const { pageItems, numberOfPages, page, pageStart, pageEnd } = result.current;
+
+ expect(pageItems).toStrictEqual([1]);
+ expect(numberOfPages).toStrictEqual(3);
+ expect(page).toStrictEqual(1);
+ expect(pageStart).toStrictEqual(1);
+ expect(pageEnd).toStrictEqual(1);
+ });
+
+ it('should clamp pages', () => {
+ const { result } = renderHook(() => {
+ return usePagination([1, 2, 3], 1, 1);
+ });
+
+ expect(result.current.pageItems).toStrictEqual([1]);
+
+ act(() => result.current.previousPage());
+ expect(result.current.pageItems).toStrictEqual([1]);
+
+ act(() => result.current.nextPage());
+ expect(result.current.pageItems).toStrictEqual([2]);
+
+ act(() => result.current.nextPage());
+ expect(result.current.pageItems).toStrictEqual([3]);
+
+ act(() => result.current.nextPage());
+ expect(result.current.pageItems).toStrictEqual([3]);
+ });
+});
diff --git a/public/app/features/alerting/unified/hooks/usePagination.ts b/public/app/features/alerting/unified/hooks/usePagination.ts
index 1c7b1bfae6b..e95962d9a7a 100644
--- a/public/app/features/alerting/unified/hooks/usePagination.ts
+++ b/public/app/features/alerting/unified/hooks/usePagination.ts
@@ -1,25 +1,29 @@
-import { useCallback, useEffect, useMemo, useState } from 'react';
+import { chunk, clamp } from 'lodash';
+import { useCallback, useEffect, useState, useMemo } from 'react';
-export function usePagination