Paginate migrated resources (#91055)

* E2C: Add snapshot table pagination

* Fix default page number

* Update defaults

* Reduce page size to 50, correctly calculate number of pages

---------

Co-authored-by: joshhunt <josh@trtr.co>
This commit is contained in:
Alex Khomenko 2024-07-29 12:21:04 +03:00 committed by GitHub
parent 8d98c9eba7
commit 47fb116989
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 39 additions and 20 deletions

View File

@ -58,20 +58,23 @@ const SHOULD_POLL_STATUSES: Array<SnapshotDto['status']> = [
];
const SNAPSHOT_REBUILD_STATUSES: Array<SnapshotDto['status']> = ['PENDING_PROCESSING', 'FINISHED', 'ERROR', 'UNKNOWN'];
const SNAPSHOT_BUILDING_STATUSES: Array<SnapshotDto['status']> = ['INITIALIZING', 'CREATING'];
const SNAPSHOT_UPLOADING_STATUSES: Array<SnapshotDto['status']> = ['UPLOADING', 'PENDING_PROCESSING', 'PROCESSING'];
const STATUS_POLL_INTERVAL = 5 * 1000;
function useGetLatestSnapshot(sessionUid?: string) {
const PAGE_SIZE = 50;
function useGetLatestSnapshot(sessionUid?: string, page = 1) {
const [shouldPoll, setShouldPoll] = useState(false);
const listResult = useGetShapshotListQuery(sessionUid ? { uid: sessionUid } : skipToken);
const lastItem = listResult.data?.snapshots?.at(0);
const getSnapshotQueryArgs = sessionUid && lastItem?.uid ? { uid: sessionUid, snapshotUid: lastItem.uid } : skipToken;
const getSnapshotQueryArgs =
sessionUid && lastItem?.uid
? { uid: sessionUid, snapshotUid: lastItem.uid, resultLimit: PAGE_SIZE, resultPage: page }
: skipToken;
const snapshotResult = useGetSnapshotQuery(getSnapshotQueryArgs, {
pollingInterval: shouldPoll ? STATUS_POLL_INTERVAL : 0,
@ -99,7 +102,8 @@ function useGetLatestSnapshot(sessionUid?: string) {
export const Page = () => {
const [disconnectModalOpen, setDisconnectModalOpen] = useState(false);
const session = useGetLatestSession();
const snapshot = useGetLatestSnapshot(session.data?.uid);
const [page, setPage] = useState(1);
const snapshot = useGetLatestSnapshot(session.data?.uid, page);
const [performCreateSnapshot, createSnapshotResult] = useCreateSnapshotMutation();
const [performUploadSnapshot, uploadSnapshotResult] = useUploadSnapshotMutation();
const [performCancelSnapshot, cancelSnapshotResult] = useCancelSnapshotMutation();
@ -228,7 +232,12 @@ export const Page = () => {
)}
{snapshot.data?.results && snapshot.data.results.length > 0 && (
<ResourcesTable resources={snapshot.data.results} />
<ResourcesTable
resources={snapshot.data.results}
onChangePage={setPage}
numberOfPages={Math.ceil((snapshot?.data?.stats?.total || 0) / PAGE_SIZE)}
page={page}
/>
)}
</Stack>

View File

@ -8,12 +8,16 @@ import { wellFormedDashboardMigrationItem, wellFormedDatasourceMigrationItem } f
import { registerMockAPI } from '../fixtures/mswAPI';
import { wellFormedDatasource } from '../fixtures/others';
import { ResourcesTable } from './ResourcesTable';
import { ResourcesTable, ResourcesTableProps } from './ResourcesTable';
setBackendSrv(backendSrv);
function render(...[ui, options]: Parameters<typeof rtlRender>) {
rtlRender(<TestProvider>{ui}</TestProvider>, options);
function render(props: Partial<ResourcesTableProps>) {
rtlRender(
<TestProvider>
<ResourcesTable onChangePage={() => {}} numberOfPages={10} page={0} resources={props.resources || []} />
</TestProvider>
);
}
describe('ResourcesTable', () => {
@ -46,7 +50,7 @@ describe('ResourcesTable', () => {
}),
];
render(<ResourcesTable resources={resources} />);
render({ resources });
expect(screen.getByText('Datasource A')).toBeInTheDocument();
});
@ -55,7 +59,7 @@ describe('ResourcesTable', () => {
const item = wellFormedDatasourceMigrationItem(2);
const resources = [item];
render(<ResourcesTable resources={resources} />);
render({ resources });
expect(screen.getByText(`Data source ${item.refId}`)).toBeInTheDocument();
expect(screen.getByText(`Unknown data source`)).toBeInTheDocument();
@ -64,7 +68,7 @@ describe('ResourcesTable', () => {
it('renders dashboards', async () => {
const resources = [wellFormedDashboardMigrationItem(1)];
render(<ResourcesTable resources={resources} />);
render({ resources });
expect(await screen.findByText('My Dashboard')).toBeInTheDocument();
});
@ -76,7 +80,7 @@ describe('ResourcesTable', () => {
}),
];
render(<ResourcesTable resources={resources} />);
render({ resources });
expect(await screen.findByText('Unable to load dashboard')).toBeInTheDocument();
expect(await screen.findByText('Dashboard dashboard-404')).toBeInTheDocument();
@ -90,7 +94,7 @@ describe('ResourcesTable', () => {
}),
];
render(<ResourcesTable resources={resources} />);
render({ resources });
expect(screen.getByText('Uploaded to cloud')).toBeInTheDocument();
});
@ -103,7 +107,7 @@ describe('ResourcesTable', () => {
}),
];
render(<ResourcesTable resources={resources} />);
render({ resources });
expect(screen.getByText('Error')).toBeInTheDocument();
});
@ -117,7 +121,7 @@ describe('ResourcesTable', () => {
}),
];
render(<ResourcesTable resources={resources} />);
render({ resources });
expect(
screen.getByRole('button', {

View File

@ -1,6 +1,6 @@
import { useCallback, useMemo, useState } from 'react';
import { InteractiveTable } from '@grafana/ui';
import { InteractiveTable, Pagination, Stack } from '@grafana/ui';
import { MigrateDataResponseItemDto } from '../api';
@ -10,8 +10,11 @@ import { StatusCell } from './StatusCell';
import { TypeCell } from './TypeCell';
import { ResourceTableItem } from './types';
interface ResourcesTableProps {
export interface ResourcesTableProps {
resources: MigrateDataResponseItemDto[];
page: number;
numberOfPages: number;
onChangePage: (page: number) => void;
}
const columns = [
@ -20,7 +23,7 @@ const columns = [
{ id: 'status', header: 'Status', cell: StatusCell },
];
export function ResourcesTable({ resources }: ResourcesTableProps) {
export function ResourcesTable({ resources, numberOfPages = 0, onChangePage, page = 1 }: ResourcesTableProps) {
const [erroredResource, setErroredResource] = useState<ResourceTableItem | undefined>();
const handleShowErrorModal = useCallback((resource: ResourceTableItem) => {
@ -33,7 +36,10 @@ export function ResourcesTable({ resources }: ResourcesTableProps) {
return (
<>
<InteractiveTable columns={columns} data={data} getRowId={(r) => r.refId} pageSize={15} />
<InteractiveTable columns={columns} data={data} getRowId={(r) => r.refId} />
<Stack justifyContent={'flex-end'}>
<Pagination numberOfPages={numberOfPages} currentPage={page} onNavigate={onChangePage} />
</Stack>
<ResourceErrorModal resource={erroredResource} onClose={() => setErroredResource(undefined)} />
</>