Skip to content

Cluster page: reading list, voting, performance, and build pipeline#747

Open
LukasWallrich wants to merge 24 commits intomasterfrom
feature/featured-resources
Open

Cluster page: reading list, voting, performance, and build pipeline#747
LukasWallrich wants to merge 24 commits intomasterfrom
feature/featured-resources

Conversation

@LukasWallrich
Copy link
Copy Markdown
Contributor

Summary

Overhaul of the cluster/curated resources pages — new features, performance improvements, and a simplified build pipeline. Featured/recommended resources are disabled by default (enable_featured_resources: false) until real community recommendations are collected; all other improvements are active.

New features

  • Expandable reading list panel — saved items now show APA reference (with copy button), abstract preview with show more/less, DOI link, and Open Access indicator
  • PDF export for reading list (loads jsPDF from CDN on first use)
  • Vote submission — thumbs-up votes are now submitted to a Google Form via hidden iframe, and existing vote counts from the response sheet are shown as the starting count (vote_base)
  • pub_cards.json added to CI pipeline — enriched publication card data is now persisted and deployed alongside featured_resources.json

Performance

  • Cached card data at init — search text, focus/type/specificity attributes are extracted once and stored in a JS array; filtering loops over plain objects instead of querying the DOM on every keystroke
  • Two-pass filtering — pass 1 computes visibility from cached data (zero DOM reads), pass 2 batches all DOM writes, eliminating layout thrashing
  • maxHeight: 'none' replaces scrollHeight + 'px' for open accordion sections during filtering, avoiding forced reflows

Build pipeline (build_featured_data.py)

  • Replaced gws CLI dependency with direct published CSV URLs — no credentials needed
  • Parallelized 5 CSV fetches with ThreadPoolExecutor (~3× faster)
  • Added vote count fetching from Google Sheets response CSV
  • Added display exclusion column support (column 16)

Featured resources toggle

  • enable_featured_resources set to false in params.toml
  • Both the "Recommended" accordion section and the special recommendation card layout (with testimonial carousel) are gated on this flag
  • Flip to true when real recommendations are ready — no code changes needed

Test plan

  • Open /clusters/ — verify no "Recommended" sections or recommendation card layouts appear
  • Type in the search box — confirm filtering feels responsive with many resources
  • Click filter tags (Focus, Resource Type) — cards filter correctly
  • Save resources to reading list — expand items, verify APA copy, abstract toggle, DOI/OA links
  • Click "Download PDF" in reading list — verify PDF generates with correct content
  • Click thumbs-up vote on a card — verify count increments and persists across reload
  • Run python3 scripts/build_featured_data.py — verify it completes without errors and outputs correct JSON
  • Set enable_featured_resources = true in params.toml — verify recommended section and card layout reappear

🤖 Generated with Claude Code

LukasWallrich and others added 24 commits April 8, 2026 11:24
…tching

The search was capped at 30 results (now 500), hiding most matches.
Also, search terms required exact whole-word matches — e.g. "registra"
wouldn't find "registration". Now the last word in a query uses prefix
matching while earlier words still require full-word matches, keeping
results relevant without noise.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previously each query word matched independently (OR), so "pre-registration"
returned more results than "registration" because "pre" matched extra items.
Now every query word must appear in an item for it to be included. Multi-word
phrases and prefix matching still contribute to ranking/weight.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Content normalization produces both forms (split and joined) for
hyphenated words. Query normalization strips hyphens so both
"pre-registration" and "preregistration" search identically.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Instead of loading index.json and rendering a separate results list,
the search input now filters the existing resource cards in-place via
isotope. Supports AND logic (all words must match), prefix matching,
and works alongside the category filter buttons. Shows a count of
matching resources.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Card text contains original hyphens, so searching "preregistration"
wouldn't find cards with "pre-registration". Now hyphens are stripped
from both the query (split to words) and card text (before matching).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fetches recommendation form responses and matches DOIs against the
Publications sheet to build data/featured_resources.json, grouped by
cluster number.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Create featured_cards.html partial with filter bar, search, compact cards
- Create featured_global.html with reference popup and reading list HTML
- Inject conditional "Recommended" tab as first tab in cluster_section.html
- Add "Recommended" nav link in sidebar_nav.html
- Include featured_global.html in both cluster layout templates
- Add featured-resources.js script tag to custom_js.html
- Add enable_featured_resources site param (default true)
- Add all featured resource CSS (cards, filters, popups, reading list)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reference popup: shows APA/BibTeX with copy, abstract, DOI/OA status.
Reading list: localStorage save/remove, pill indicator, panel drawer,
BibTeX export. Voting: one-way thumbs up persisted in localStorage.
Filtering: focus/type tag buttons, specificity toggle, live text search.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Hash navigation now handles #c{N}-featured in addition to #c{N}-sc{M}
- Inline search indexes featured card titles/summaries
- Featured results shown with star icon, sorted between clusters and
  sub-clusters
- Click-to-scroll handles featured pane type

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Runs the featured resources pipeline in data-processing workflow and
commits data/featured_resources.json to the build-resources branch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Pipeline extracts recommender name, title, bio, photo, and text from
  form responses; downloads photos at build time with content-type
  validation, falls back to initials avatar on failure
- Cards render as side-by-side fr-card (resource + testimonial) when
  recommendations exist, compact fc-card otherwise
- Testimonial carousel with dot nav and arrow controls for multiple
  recommendations
- CSS for fr-card grid, testimonial panel, carousel, and avatars
- Filtering updated to handle both card types

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Pipeline now outputs pub_cards.json with card data (title, summary,
  focus, type, etc.) for all 822 publications
- Sub-cluster tabs render publications as fc-cards with tags, title,
  summary, and reference/save buttons instead of plain APA lists
- Falls back to APA text in a card for publications without enriched data
- Pub cards data injected as FORRT_PUB_CARDS for reference popups on
  all publications, not just featured ones
- JS and global HTML now load unconditionally on cluster pages

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fetch focus/type tag values from the "tags" sheet and output
  data/filter_tags.json
- Replace search bar in clusters_controls.html with unified filter bar:
  search input, Focus tags, Type tags, specificity toggle
- Remove per-cluster filter bar from featured_cards.html
- Rewrite JS filtering to apply globally across all tab panes
- Add no-results message to sub-cluster panes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All sub-clusters are now visible simultaneously instead of hidden
behind tabs. A compact inline jump-nav with dashed-underline links
replaces the 3-column tab grid, saving vertical space and making
filtered views useful across sections.

- cluster_section.html: tabs → stacked .cluster-sc-section divs
  with .cluster-jump-nav anchor links
- CSS: remove .cluster-tabs grid styles, add jump-nav and section
  separator styles, clean up responsive tab overrides
- clusters-page.js: remove showBootstrapTab calls, update hash nav
  and sidebar/search click handlers to scroll to sections directly,
  add jump-link click handler

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…espace

- Jump-nav: middot-separated inline links instead of boxed pills
- Section headings: smaller (0.82rem), muted color, less margin
- Section spacing: reduced padding, thinner separators
- Description text: smaller and more compact
- Featured heading: subtle accent color distinction

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Clean minimal accordion: each sub-cluster section has a collapsible
header with chevron and x/y match count showing how many cards pass
the current filter.

- Sections with 0 filter matches are disabled (greyed out, cannot
  expand) but their open/closed state is tracked and restored when
  matches return
- "Expand all / Collapse all" toggle in the cluster header
- Sidebar nav and hash nav auto-expand targeted sections
- Smooth max-height transitions on expand/collapse
- Removed old jump-nav CSS

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Only the Recommended accordion section starts expanded. Sub-cluster
sections start collapsed, showing their match counts in the header.
Also regenerates featured_resources.json with latest form responses
(13 resources across clusters 1, 2, 11).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Merge recommendation data into pub_cards.json so sub-cluster
  sections render fr-card (with testimonial) for recommended pubs
- Add sortCardsByFocus() to reorder cards in every section by the
  focus tag order from the sheet (overview, evidence, advocacy, ...)
- Inject FORRT_FOCUS_ORDER for client-side sorting
- Featured resources also sorted by focus order in the pipeline
- Regenerate data with updated tags sheet order

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Hugo's jsonify without safeJS was producing quoted strings instead of
JS objects/arrays for FORRT_FEATURED, FORRT_PUB_CARDS, and
FORRT_FOCUS_ORDER. This caused a TypeError in buildResourceIndex()
that killed execution before initAccordion() ran — explaining why
accordion clicks and card sorting weren't working.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Match fr-title (0.82→0.78rem) and fr-summary (0.75→0.7rem) to their
fc-card counterparts so recommended and regular cards have consistent
text sizing within sections.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Include references checkbox was removed from the UI but the JS
defaulted to false when the element was absent. Change fallback to
true so the search always covers publication text.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When any filter or search is active, sections with matching cards
auto-expand and 0-match sections collapse. When filters are cleared
(all back to defaults), sections restore to their pre-filter
open/closed state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Cache card data at init and use two-pass filtering (compute then
  write) to eliminate DOM thrashing during search/filter
- Replace scrollHeight reads with maxHeight:none for open sections
- Add expandable reading list items with APA copy, abstract preview,
  DOI/OA links, and PDF export via jsPDF
- Switch build_featured_data.py from gws CLI to published CSV URLs
  (no credentials needed) and parallelize fetches with ThreadPoolExecutor
- Add vote submission to Google Form via hidden iframe
- Include vote_base counts from vote response sheet
- Add pub_cards.json to CI pipeline
- Disable featured resources tab (enable_featured_resources: false)
  until real recommendations are in place; gate recommendation card
  layout on the same flag

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@LukasWallrich LukasWallrich requested a review from a team as a code owner April 15, 2026 16:39
@github-actions
Copy link
Copy Markdown
Contributor

👍 All image files/references (if any) are in webp format, in line with our policy.

@github-actions
Copy link
Copy Markdown
Contributor

📝 Spell Check Results

Found 4 potential spelling issue(s) when checking 16 changed file(s):

📄 static/js/clusters-page.js

Line Issue
80 tabEl ==> table
81 tabEl ==> table
83 tabEl ==> table
85 tabEl ==> table

ℹ️ How to address these issues:

  1. Fix the typo: If it's a genuine typo, please correct it.
  2. Add to whitelist: If it's a valid word (e.g., a name, technical term), add it to .codespell-ignore.txt
  3. False positive: If this is a false positive, please report it in the PR comments.

🤖 This check was performed by codespell

@LukasWallrich
Copy link
Copy Markdown
Contributor Author

LukasWallrich commented Apr 15, 2026

Staging Deployment Status

This PR has been successfully deployed to staging as part of an aggregated deployment.

Deployed at: 2026-04-15 21:21:15 UTC
Staging URL: https://staging.forrt.org

The staging site shows the combined state of all compatible open PRs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant