Skip to content

fix: sort catalog filter options by collation, not code point - #2016

Merged
mrbobbytables merged 2 commits into
cncf:mainfrom
mrbobbytables:fix/filter-option-sort
Oct 30, 2026
Merged

mrbobbytables merged 2 commits into
cncf:mainfrom
mrbobbytables:fix/filter-option-sort

Conversation

@mrbobbytables

Copy link
Copy Markdown
Member

Fixes #2013

Remit: the project, industry, organization and country filter dropdowns on /case-studies, /architectures and /members list every lowercase label (etcd, cert-manager, gRPC, tekton, gaming, iGaming) after every capitalised one, so a visitor scanning alphabetically does not find them.

What changes

  • src/components/shared/compareLabels.js (new): a.localeCompare(b, 'en'). ICU collation already orders letters before case, so the issue's sensitivity: 'base' plus fallback produces the same order as a single pinned-locale localeCompare; verified identical on the live case-study project set. Pinning en keeps the order the same on every runtime.
  • ArchitectureFilters/index.js, CaseStudies/index.js, MemberDirectory/hooks.js: the eight .sort() calls become .sort(compareLabels). The existing tag comparator is untouched.
  • Tests: one mixed-case fixture per suite (architecture-filters-ui, case-studies, member-directory) with literal expected order; the live-data assertions in case-studies, member-directory and reference-architectures now compute collation order (one visible effect on real data: Capital One now precedes CERN).

Verification

  • All six new or updated assertions fail with the src/ change stashed, pass with it
  • npm run test:unit:coverage:check: 3800 pass, gate green
  • Mutation on the four src/ files: 100% (251 mutants, 0 survived)
  • check:format, check:spelling, check:markdown, check:duplication, check:lint, check:unused: all clean

The project, industry, organization and country selects on
/case-studies, /architectures and /members were built with a bare
Array.prototype.sort, which orders by UTF-16 code point. CNCF project
names keep their published casing, so etcd, cert-manager, gRPC, tekton
and the lowercase industries were listed in a block after every
capitalised name, where a visitor scanning alphabetically does not look.

Add a shared compareLabels comparator that pins English collation, use
it at the eight option builders, and give each affected suite a
mixed-case fixture that fails under code-point order.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: mrbobbytables <mrbobbytables@users.noreply.github.com>
@netlify

netlify Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for endusers ready!

Name Link
🔨 Latest commit 54f93ea
🔍 Latest deploy log https://app.netlify.com/projects/endusers/deploys/6ae4bc9c39d6a551eee6600e
😎 Deploy Preview https://deploy-preview-2016--endusers.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@hivecommons-hive

Copy link
Copy Markdown
Contributor

Validate repository / End-to-end coverage fails on this head (1005cb06) with:

Error: 1 accepted region(s) in tests/e2e/fixtures/accepted-regions.json are stale; remove them:
  src/components/CaseStudies/index.js 52:38-52:44: not a region this run reports

Cause is PR-local, not a shared CI incident (baseline is green — merge-group runs for #2010/#2015 passed). The new project filter line in src/components/CaseStudies/index.js shifts const caseStudies = data.caseStudies || []; from line 52 to line 53, so the accepted span no longer lands on the || [] guard.

Fix: update the entry in tests/e2e/fixtures/accepted-regions.json:

-{"file": "src/components/CaseStudies/index.js", "span": "52:38-52:44", ...}
+{"file": "src/components/CaseStudies/index.js", "span": "53:38-53:44", ...}

The guard itself is unchanged — same reason string stays valid.


🐝 Hive Agent: ci-maintainer | Instance: hosted-available-lke648397-260827-5n31 | SHA: unknown

— hive: agent=ci-maintainer backend=copilot model=kimi-k3 copilot=1.0.88

@hivecommons-hive hivecommons-hive Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Read the diff against the tree at merge-base. The fix itself is correct and matches #2013: the eight .sort() sites in ArchitectureFilters/index.js, CaseStudies/index.js:23-25 and MemberDirectory/hooks.js:22-23 now use the shared comparator, the tag comparator is untouched, and localeCompare(b, 'en') (ICU orders letters before case) produces the order the issue asked for; the simplification from the issue's sensitivity:'base' + fallback is explained in the body and only changes tie order for case-only duplicate labels, which the data sets don't contain. The new tests fail without the src change, as claimed.

One blocking finding — the required "End-to-end coverage" check fails, and it is this diff's fault:

  • tests/e2e/fixtures/accepted-regions.json pins an accepted zero-count region at src/components/CaseStudies/index.js span 52:38-52:44 (the || [] fallback of data.caseStudies || []).
  • This PR adds import { compareLabels } ... at src/components/CaseStudies/index.js:7, shifting that statement from line 52 to line 53.
  • tests/tools/e2e-coverage-report.mjs:1277 then fails the lane: 1 accepted region(s) ... stale; remove them: src/components/CaseStudies/index.js 52:38-52:44: not a region this run reports (run 41080008758).

Fix: update that fixture entry's span to the line the run now reports — 53:38-53:44, same columns, since only the line shifted — and the lane should go green. Everything else (unit coverage, mutation, lint, e2e tests, CodeQL, DCO) is already green on this head.

With that one fixture line updated, this looks correct to me.

— hive: agent=reviewer backend=copilot model=claude-fable-5 copilot=1.0.88

The compareLabels import shifts the component by one line, so the
pinned span for the caseStudies fallback moves with it.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: mrbobbytables <mrbobbytables@users.noreply.github.com>
@hivecommons-hive

Copy link
Copy Markdown
Contributor

Follow-up on the requested change: verified at head 54f93ea9.

  • tests/e2e/fixtures/accepted-regions.json now carries span 53:38-53:44 for src/components/CaseStudies/index.js, and the guard const caseStudies = data.caseStudies || []; does sit on line 53 at this head — the stale-region failure from the 1005cb06 run is addressed.
  • Diff 1005cb06..54f93ea9 is exactly that one-line span update; nothing else moved, so the earlier review of the comparator and the eight .sort(compareLabels) sites still stands.

The current BLOCKED merge state is just the still-running required checks (Mutation testing, Validate repository), not a failure.


🐝 scanner agent re-verification


🐝 Hive Agent: scanner | Instance: hosted-available-lke648397-260827-5n31 | SHA: fab7565

— hive: agent=scanner backend=copilot model=kimi-k3 copilot=1.0.88

@mrbobbytables
mrbobbytables added this pull request to the merge queue Oct 30, 2026
Merged via the queue into cncf:main with commit a563482 Oct 30, 2026
15 checks passed
mrbobbytables added a commit to mrbobbytables/endusers that referenced this pull request Oct 31, 2026
…ncf#2033)

cncf#2016 pinned eight filter-option comparators to English collation and left
the tag dropdown and the alphabetical card order on the runtime default. A
visitor whose locale collates the digraph ch as one letter (Czech,
traditional Spanish) hydrates a different option order than the HTML served
to them, so React re-renders the tag select client-side. Route both through
compareLabels and pin the order with a child-process run under cs_CZ.

Refs cncf#2031

Signed-off-by: mrbobbytables <mrbobbytables@users.noreply.github.com>
Co-authored-by: mrbobbytables <mrbobbytables@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

[quality] Catalog filter dropdowns list lowercase project and industry names after every capitalised one

1 participant