Skip to content

Commit 2dbca88

Browse files
committed
feat(sistent): optimize pagination with memoization and de-duplication
Signed-off-by: Rishi Raj <rishiraj438gt@gmail.com>
1 parent 51fe6f6 commit 2dbca88

File tree

1 file changed

+42
-28
lines changed

1 file changed

+42
-28
lines changed

src/components/SistentNavigation/pagination.js

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useEffect, useState } from "react";
1+
import React, { useEffect, useState, useMemo } from "react";
22
import { graphql, useStaticQuery } from "gatsby";
33

44
import Button from "../../reusecore/Button";
@@ -54,37 +54,51 @@ const SistentPagination = () => {
5454
}
5555
`);
5656

57-
// Compile set of published components based on overview pages
58-
const publishedComponents = new Set();
59-
data.allMdx.nodes.forEach((node) => {
60-
if (node.fields.pageType === "overview" && node.frontmatter.published === true) {
61-
publishedComponents.add(node.frontmatter.component);
62-
}
63-
});
64-
65-
// Map, filter out drafts, and group by tab order: overview -> guidance -> code
66-
const dynamicRoutes = data.allMdx.nodes
67-
.map((node) => ({
68-
componentSlug: node.frontmatter.component,
69-
name: node.frontmatter.name || node.frontmatter.component,
70-
link: node.fields.slug,
71-
pageType: node.fields.pageType,
72-
}))
73-
.filter((node) => publishedComponents.has(node.componentSlug))
74-
.sort((a, b) => {
75-
if (a.componentSlug !== b.componentSlug) {
76-
return (a.componentSlug || "").localeCompare(b.componentSlug || "");
57+
// Published components based on overview pages
58+
const publishedComponents = useMemo(() => {
59+
const published = new Set();
60+
data.allMdx.nodes.forEach((node) => {
61+
if (node.fields.pageType === "overview" && node.frontmatter.published === true) {
62+
published.add(node.frontmatter.component);
7763
}
78-
return (
79-
(PAGE_TYPE_ORDER[a.pageType] || 99) - (PAGE_TYPE_ORDER[b.pageType] || 99)
80-
);
8164
});
65+
return published;
66+
}, [data.allMdx.nodes]);
8267

83-
const fullContentArray = [...STABLE_ROUTES, ...dynamicRoutes];
68+
// Map, filter, and sort dynamic routes
69+
const dynamicRoutes = useMemo(() => {
70+
return data.allMdx.nodes
71+
.map((node) => ({
72+
componentSlug: node.frontmatter.component,
73+
text: node.frontmatter.name || node.frontmatter.component,
74+
link: node.fields.slug,
75+
pageType: node.fields.pageType,
76+
}))
77+
.filter((node) => publishedComponents.has(node.componentSlug))
78+
.sort((a, b) => {
79+
if (a.componentSlug !== b.componentSlug) {
80+
return (a.componentSlug || "").localeCompare(b.componentSlug || "");
81+
}
82+
return (
83+
(PAGE_TYPE_ORDER[a.pageType] || 99) - (PAGE_TYPE_ORDER[b.pageType] || 99)
84+
);
85+
});
86+
}, [data.allMdx.nodes, publishedComponents]);
87+
88+
// Combine and de-duplicate routes by link
89+
const fullContentArray = useMemo(() => {
90+
const combined = [...STABLE_ROUTES, ...dynamicRoutes];
91+
const seenLinks = new Set();
92+
return combined.filter((route) => {
93+
if (seenLinks.has(route.link)) return false;
94+
seenLinks.add(route.link);
95+
return true;
96+
});
97+
}, [dynamicRoutes]);
8498

8599
useEffect(() => {
86100
const path = window.location.pathname;
87-
// Handle trajectory slashes
101+
// Handle trailing slashes
88102
const cleanPath = path.endsWith("/") && path.length > 1 ? path.slice(0, -1) : path;
89103
const index = fullContentArray.findIndex((x) => x.link === cleanPath);
90104
setCurrentPage(index);
@@ -96,13 +110,13 @@ const SistentPagination = () => {
96110
<Button $secondary $url={fullContentArray[currentPage - 1]?.link}>
97111
&larr; Previous
98112
</Button>
99-
) : <div />}
113+
) : null}
100114

101115
{currentPage !== -1 && currentPage < fullContentArray.length - 1 ? (
102116
<Button $primary $url={fullContentArray[currentPage + 1]?.link}>
103117
Next &rarr;
104118
</Button>
105-
) : <div />}
119+
) : null}
106120
</PaginationWrapper>
107121
);
108122
};

0 commit comments

Comments
 (0)