mirror of https://github.com/grafana/grafana
StatusHistory: Add pagination option (#99517)
* first pass * Add to docs * Move pagination hook and styles to a shared util * Update docs/sources/panels-visualizations/visualizations/status-history/index.md Co-authored-by: Isabel Matwawana <76437239+imatwawana@users.noreply.github.com> --------- Co-authored-by: Isabel Matwawana <76437239+imatwawana@users.noreply.github.com>pull/98710/head^2
parent
af663dadc7
commit
d409853683
@ -0,0 +1,75 @@ |
|||||||
|
import { css } from '@emotion/css'; |
||||||
|
import { useMemo, useState } from 'react'; |
||||||
|
import { useMeasure } from 'react-use'; |
||||||
|
|
||||||
|
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 = { |
||||||
|
paginationContainer: css({ |
||||||
|
display: 'flex', |
||||||
|
justifyContent: 'center', |
||||||
|
width: '100%', |
||||||
|
}), |
||||||
|
paginationElement: css({ |
||||||
|
marginTop: '8px', |
||||||
|
}), |
||||||
|
}; |
||||||
|
|
||||||
|
export function usePagination(frames?: DataFrame[], perPage?: number) { |
||||||
|
const [currentPage, setCurrentPage] = useState(1); |
||||||
|
|
||||||
|
const [paginationWrapperRef, { height: paginationHeight, width: paginationWidth }] = useMeasure<HTMLDivElement>(); |
||||||
|
|
||||||
|
const pagedFrames = useMemo( |
||||||
|
() => (!perPage || frames == null ? frames : makeFramePerSeries(frames)), |
||||||
|
[frames, perPage] |
||||||
|
); |
||||||
|
|
||||||
|
if (!perPage || pagedFrames == null) { |
||||||
|
return { |
||||||
|
paginatedFrames: pagedFrames, |
||||||
|
paginationRev: 'disabled', |
||||||
|
paginationElement: undefined, |
||||||
|
paginationHeight: 0, |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
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); |
||||||
|
const pageOffset = (currentPageCapped - 1) * perPage; |
||||||
|
const currentPageFrames = pagedFrames.slice(pageOffset, pageOffset + perPage); |
||||||
|
|
||||||
|
// `paginationRev` needs to change value whenever any of the pagination settings changes.
|
||||||
|
// It's used in to trigger a reconfiguration of the underlying graphs (which is cached,
|
||||||
|
// hence an explicit nudge is required).
|
||||||
|
const paginationRev = `${currentPageCapped}/${perPage}`; |
||||||
|
|
||||||
|
const showSmallVersion = paginationWidth < 550; |
||||||
|
const paginationElement = ( |
||||||
|
<div className={styles.paginationContainer} ref={paginationWrapperRef}> |
||||||
|
<Pagination |
||||||
|
className={styles.paginationElement} |
||||||
|
currentPage={currentPageCapped} |
||||||
|
numberOfPages={numberOfPages} |
||||||
|
showSmallVersion={showSmallVersion} |
||||||
|
onNavigate={setCurrentPage} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
); |
||||||
|
|
||||||
|
return { paginatedFrames: currentPageFrames, paginationRev, paginationElement, paginationHeight }; |
||||||
|
} |
Loading…
Reference in new issue