Simplify website search and listing controls#1553
Conversation
… there are two searches, but the overall site search is a lot more powerful
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove per-page text search, trim page-specific controls, and move remaining sort/filter controls into compact flyouts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR refactors the Learning Hub website’s browsing UX by removing per-page fuzzy text search, relying on the global Pagefind search (now prefiltered by the current resource page), and consolidating remaining listing controls into compact flyout panels.
Changes:
- Replace per-page fuzzy text search with lightweight page-specific sort/filter controls and updated result counts.
- Introduce a reusable
<details>-based “Sort & Filter” flyout pattern (CSS + JS to manage open/close behavior). - Remove skills categorization (and category UI) from the generated data + skills listing UI.
Show a summary per file
| File | Description |
|---|---|
| website/src/styles/global.css | Adds shared styling for the new listing toolbar + flyout controls. |
| website/src/scripts/pages/workflows.ts | Removes per-page search; keeps trigger filter + sort + URL sync. |
| website/src/scripts/pages/workflows-render.ts | Removes query highlighting support from workflow rendering. |
| website/src/scripts/pages/tools.ts | Removes per-page search; adds sort + category filter + URL sync. |
| website/src/scripts/pages/tools-render.ts | Adds tool sorting helper and removes query highlighting support. |
| website/src/scripts/pages/skills.ts | Removes per-page search/filters; keeps only sorting and rendering. |
| website/src/scripts/pages/skills-render.ts | Removes query highlighting and category tag rendering. |
| website/src/scripts/pages/plugins.ts | Removes per-page search; adds sort + tag filter + URL sync. |
| website/src/scripts/pages/plugins-render.ts | Adds plugin sorting helper and removes query highlighting support. |
| website/src/scripts/pages/instructions.ts | Removes per-page search; keeps extension filter + sort + URL sync. |
| website/src/scripts/pages/instructions-render.ts | Removes query highlighting support from instruction rendering. |
| website/src/scripts/pages/index.ts | Removes homepage fuzzy search implementation (now relying on Pagefind UI). |
| website/src/scripts/pages/hooks.ts | Removes per-page search + hook-event filter; keeps tag filter + sort + download actions. |
| website/src/scripts/pages/hooks-render.ts | Removes query highlighting support from hook rendering. |
| website/src/scripts/pages/agents.ts | Removes per-page search and filters; keeps only sorting + rendering. |
| website/src/scripts/pages/agents-render.ts | Removes query highlighting support from agent rendering. |
| website/src/scripts/listing-flyouts.ts | Adds shared behavior to close flyouts on outside click / Escape / when another opens. |
| website/src/pages/workflows.astro | Updates workflows page toolbar into flyout panel and loads flyout script. |
| website/src/pages/tools.astro | Updates tools page toolbar into flyout panel, adds sort select, loads flyout script. |
| website/src/pages/skills.astro | Simplifies skills toolbar to a sort-only flyout and loads flyout script. |
| website/src/pages/plugins.astro | Updates plugins page toolbar into flyout panel with sort+filter, loads flyout script. |
| website/src/pages/instructions.astro | Updates instructions page toolbar into flyout panel and loads flyout script. |
| website/src/pages/hooks.astro | Updates hooks page toolbar into flyout panel and loads flyout script. |
| website/src/pages/agents.astro | Updates agents page toolbar to a sort-only flyout and loads flyout script. |
| website/src/pages/index.astro | Removes homepage hero search markup. |
| website/src/integrations/pagefind-resources.ts | Improves Pagefind indexing robustness/log formatting. |
| website/src/components/Search.astro | Adds custom Search component that applies route-based Pagefind filtering. |
| website/astro.config.mjs | Registers the custom Search component override for Starlight. |
| eng/generate-website-data.mjs | Removes skill categorization and category filter generation for skills. |
Copilot's findings
- Files reviewed: 29/29 changed files
- Comments generated: 4
| // Map items to include title for FuzzySearch | ||
| allItems = data.items.map((item) => ({ | ||
| ...item, | ||
| title: item.name, // FuzzySearch uses title | ||
| })); |
There was a problem hiding this comment.
The comment says these fields are being added for FuzzySearch, but per-page fuzzy search was removed in this refactor. Please update/remove the outdated comment so it matches the current reason title is being set (e.g., sorting / rendering expectations), to avoid confusion during future maintenance.
See below for a potential fix:
// Normalize items so they always include a `title` field used by sorting/rendering.
allItems = data.items.map((item) => ({
...item,
title: item.name, // Mirror `name` to satisfy title-based UI expectations.
| ...item, | ||
| title: item.name, | ||
| })), | ||
| "title" |
There was a problem hiding this comment.
initialItems are server-rendered sorted by "title", but the hydrated page defaults to currentSort = "featured" (and the sort select defaults to “Featured First”). This will reorder the list on load and can cause layout shift. Consider sorting initialItems using the same default sort ("featured") so SSR and client rendering are consistent.
| "title" | |
| "featured" |
| const isLink = 'href' in (event.target || {}); | ||
| if ( | ||
| isLink || | ||
| (document.body.contains(event.target as Node) && | ||
| !dialogFrame.contains(event.target as Node)) |
There was a problem hiding this comment.
The link-click detection uses const isLink = 'href' in (event.target || {}), which will miss clicks on nested elements inside links (e.g., a <mark> inside an <a> in Pagefind results). That can prevent the dialog from closing when a result is selected. Consider checking event.target with closest('a[href]') (or event.composedPath()) instead of only testing the direct target for an href property.
| const isLink = 'href' in (event.target || {}); | |
| if ( | |
| isLink || | |
| (document.body.contains(event.target as Node) && | |
| !dialogFrame.contains(event.target as Node)) | |
| const target = event.target; | |
| const isLink = target instanceof Element && target.closest('a[href]') !== null; | |
| if ( | |
| isLink || | |
| (document.body.contains(target as Node) && !dialogFrame.contains(target as Node)) |
| } | ||
|
|
||
| interface Skill extends SearchItem, Omit<RenderableSkill, "files"> { | ||
| interface Skill extends Omit<RenderableSkill, "files"> { |
There was a problem hiding this comment.
Skill is typed as Omit<RenderableSkill, "files">, but RenderableSkill still requires a category field. This PR also removes skill categories from the generated website data, so skills.json items likely no longer include category. To keep types accurate (and avoid future runtime assumptions), either re-add category to the generated data or make category optional / remove it from the renderable types used here.
| interface Skill extends Omit<RenderableSkill, "files"> { | |
| interface Skill extends Omit<RenderableSkill, "files" | "category"> { | |
| category?: RenderableSkill["category"]; |
* Removing search from the home pageThis was a little confusing because there are two searches, but the overall site search is a lot more powerful * Prefilter website search by resource page Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * small error handling and formatting * Simplify website listing controls Remove per-page text search, trim page-specific controls, and move remaining sort/filter controls into compact flyouts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
Testing