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