diff --git a/pdl-live-react/src/view/masonry/Masonry.tsx b/pdl-live-react/src/view/masonry/Masonry.tsx
index 30cfbbcb5..aecca12e0 100644
--- a/pdl-live-react/src/view/masonry/Masonry.tsx
+++ b/pdl-live-react/src/view/masonry/Masonry.tsx
@@ -3,12 +3,21 @@ import MasonryTile from "./MasonryTile"
import "./Masonry.css"
type Props = import("react").PropsWithChildren<{
+ page: number
+ perPage: number
run: import("./MasonryCombo").Runner
sml: import("./Toolbar").SML
model: import("./Tile").default[]
}>
-export default function Masonry({ run, sml, model, children }: Props) {
+export default function Masonry({
+ run,
+ sml,
+ model,
+ children,
+ page,
+ perPage,
+}: Props) {
return (
{(!children ? [] : Array.isArray(children) ? children : [children])
@@ -23,11 +32,11 @@ export default function Masonry({ run, sml, model, children }: Props) {
{child}
))}
- {model.map((props, idx) => (
+ {model.slice((page - 1) * perPage, page * perPage).map((props, idx) => (
diff --git a/pdl-live-react/src/view/masonry/MasonryCombo.tsx b/pdl-live-react/src/view/masonry/MasonryCombo.tsx
index ebae9d5f6..5b873dd2c 100644
--- a/pdl-live-react/src/view/masonry/MasonryCombo.tsx
+++ b/pdl-live-react/src/view/masonry/MasonryCombo.tsx
@@ -39,6 +39,9 @@ import RunningIcon from "@patternfly/react-icons/dist/esm/icons/running-icon"
import "./Masonry.css"
+/** Initial number of masonry tiles to show per page */
+const initialPerPage = 20
+
export type Runner = (
block?: import("../../helpers").NonScalarPdlBlock,
async?: boolean,
@@ -76,6 +79,9 @@ export default function MasonryCombo({ value, setValue }: Props) {
const [sml, setSML] = useState(getSMLUserSetting())
useEffect(() => setSMLUserSetting(sml), [sml])
+ const [page, setPage] = useState(1)
+ const [perPage, setPerPage] = useState(initialPerPage)
+
const [modalIsDone, setModalIsDone] = useState(-1)
const [modalContent, setModalContent] = useState setModalIsDone(modalContent === null ? -1 : -2),
- [modalContent],
- )
+ useEffect(() => {
+ setModalIsDone(modalContent === null ? -1 : -2)
+ setPage(1)
+ setPerPage(initialPerPage)
+ }, [modalContent])
// special form of setModalContent for running a PDL program
const run = useCallback(
@@ -206,6 +213,11 @@ export default function MasonryCombo({ value, setValue }: Props) {
run={run}
isRunning={modalIsDone === -2}
block={block}
+ itemCount={masonry.length < initialPerPage ? -1 : masonry.length}
+ page={page}
+ perPage={perPage}
+ setPage={setPage}
+ setPerPage={setPerPage}
/>
-
+
diff --git a/pdl-live-react/src/view/masonry/Toolbar.tsx b/pdl-live-react/src/view/masonry/Toolbar.tsx
index 56cce2260..b6a68898e 100644
--- a/pdl-live-react/src/view/masonry/Toolbar.tsx
+++ b/pdl-live-react/src/view/masonry/Toolbar.tsx
@@ -1,6 +1,7 @@
import { Toolbar, ToolbarGroup, ToolbarContent } from "@patternfly/react-core"
import DarkModeToggle from "../../page/DarkModeToggle"
+import ToolbarPaginator from "./ToolbarPaginator"
import ToolbarSMLToggle from "./ToolbarSMLToggle"
import ToolbarReplayButton from "./ToolbarReplayButton"
import ToolbarShowSourceButton from "./ToolbarShowSourceButton"
@@ -11,7 +12,7 @@ const alignEnd = { default: "alignEnd" as const }
export type SML = "s" | "m" | "l" | "xl"
-export type Props = {
+export type Props = import("./ToolbarPaginator").Props & {
run: import("./MasonryCombo").Runner
isRunning: boolean
block: import("../../pdl_ast").PdlBlock
@@ -26,6 +27,12 @@ export default function MasonryToolbar({
isRunning,
sml,
setSML,
+
+ itemCount,
+ page,
+ perPage,
+ setPage,
+ setPerPage,
}: Props) {
return (
@@ -34,6 +41,14 @@ export default function MasonryToolbar({
+
+
{isNonScalarPdlBlock(block) && (
)}
diff --git a/pdl-live-react/src/view/masonry/ToolbarPaginator.tsx b/pdl-live-react/src/view/masonry/ToolbarPaginator.tsx
new file mode 100644
index 000000000..ed92a16e4
--- /dev/null
+++ b/pdl-live-react/src/view/masonry/ToolbarPaginator.tsx
@@ -0,0 +1,53 @@
+import { Pagination, type PaginationProps } from "@patternfly/react-core"
+
+export type Props = Pick<
+ Required,
+ "itemCount" | "perPage" | "page"
+> & {
+ setPage(n: number): void
+ setPerPage(n: number): void
+}
+
+export default function ToolbarPaginator({
+ itemCount,
+ perPage,
+ page,
+ setPage,
+ setPerPage,
+}: Props) {
+ const onPerPageSelect = (
+ _event:
+ | import("react").MouseEvent
+ | import("react").KeyboardEvent
+ | MouseEvent,
+ newPerPage: number,
+ newPage: number,
+ ) => {
+ setPerPage(newPerPage)
+ setPage(newPage)
+ }
+
+ const onSetPage = (
+ _event:
+ | import("react").MouseEvent
+ | import("react").KeyboardEvent
+ | MouseEvent,
+ newPage: number,
+ ) => {
+ setPage(newPage)
+ }
+
+ return (
+ itemCount > 1 && (
+
+ )
+ )
+}