From f6bcf198eed67ffde52dee8b73ff8eb2c2737e26 Mon Sep 17 00:00:00 2001 From: Justin Paul Date: Sat, 6 Jun 2026 22:54:08 -0400 Subject: [PATCH] Make the people index a scalable scrollable directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A flat wrap of every person didn't scale to imported trees. Replace it with a bounded (max-height, scrollable) searchable directory: clean name + birth–death-year rows, focus highlight, a result count, and a 200-row cap with a 'refine your search' notice so a thousand-person tree stays fast and usable. Co-Authored-By: Claude Opus 4.8 (1M context) Signed-off-by: Justin Paul --- frontend/app/trees/[id]/page.tsx | 53 ++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/frontend/app/trees/[id]/page.tsx b/frontend/app/trees/[id]/page.tsx index e533e59..ba31b7f 100644 --- a/frontend/app/trees/[id]/page.tsx +++ b/frontend/app/trees/[id]/page.tsx @@ -268,6 +268,7 @@ export default function FamilyViewPage() { const matches = search ? sorted.filter((p) => (p.primary_name ?? "").toLowerCase().includes(search.toLowerCase())) : sorted; + const shown = matches.slice(0, 200); // cap DOM nodes; refine search to narrow return (
@@ -325,32 +326,44 @@ export default function FamilyViewPage() {
- {/* Searchable index of everyone in the tree */} + {/* Scrollable, searchable people directory (scales to large trees) */}
-
-

All people ({people.length})

+
+

People ({people.length})

setSearch(e.target.value)} />
-
- {matches.map((p) => ( - - ))} -
+ +
+ {shown.length === 0 ? ( +
No matches.
+ ) : ( + shown.map((p, i) => ( + + )) + )} +
+ {matches.length > shown.length && ( +
+ Showing {shown.length} of {matches.length} — refine your search to narrow. +
+ )} +
); -- 2.52.0