Skip to content

feat(ui): paginate glossary terms with cursor Prev/Next and paged expand-all (#32223) - #32473

Merged
anuj-kumary merged 2 commits into
2.0from
backport/32223-glossary-term-pagination-2.0
Sep 3, 2026
Merged

anuj-kumary merged 2 commits into
2.0from
backport/32223-glossary-term-pagination-2.0

Conversation

@anuj-kumary

@anuj-kumary anuj-kumary commented Sep 2, 2026

Copy link
Copy Markdown
Member

Summary

Backport of #32223 to 2.0.

Paginates the glossary terms table with cursor-based Prev/Next navigation and a paged expand-all, so large glossaries no longer load every nested term up front.

Backport notes

Cherry-picked from ba06d99e (squash merge of #32223) with -x. Resulting diff matches the original exactly: 27 files, +623/-349.

One conflict, in GlossaryTermTab.component.tsx — an import block. 2.0 has:

import { debounce, isEmpty, isUndefined, unionBy, uniqBy } from 'lodash';

whereas main additionally carries import { TFunction } from 'i18next'; (pre-existing on main from an earlier PR that was never backported — not part of #32223). Taking the incoming side wholesale would have pulled that import into 2.0, where nothing uses it, tripping no-unused-vars.

Resolved to 2.0's shape with only #32223's actual change applied — dropping unionBy, whose sole call site this PR removes:

import { debounce, isEmpty, isUndefined, uniqBy } from 'lodash';

Verified afterwards that neither unionBy nor TFunction has any remaining reference in the file.

Test plan

Run locally against 2.0 (a fresh yarn install --frozen-lockfile, since 2.0 pins different zustand/eslint/qs versions than main):

  • jest — 7 suites, 172 tests passing (GlossaryUtils, GlossaryTermTab, and all RichTextEditor suites)
  • eslint on all 6 changed source files — no findings
  • prettier --check on every changed file, locale JSON included — clean
  • yarn check-i18n — passes; the 4 new keys are present and sorted in all 24 locale files
  • Spot-checked ja-jp, de-de, ru-ru, zh-cn, fr-fr, he-he — genuine translations, {{count}} / {{total}} / {{current}} interpolations intact

Note 2.0 runs no ui-checkstyle in CI (it does not fire for any 2.0 PR), so the eslint/prettier/i18n gates above were run by hand rather than by a workflow.

🤖 Generated with Claude Code


skip-pr-checks applied per the 2.0 backport convention (#32444, #32416, #32395): a backport has no issue of its own to link — the original is tracked on #32223.

…and-all (#32223)

* feat(ui): paginate glossary terms with cursor Prev/Next and paged expand-all

* fix bot comments

* fix(ui): use singular term-count label for count=1 (i18next)

Addresses the gitar-bot review finding: a parent with one nested term
rendered '1 terms'. Pick label.count-term (singular) vs
label.count-term-plural based on the count. Adds count-term across locales.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test(ui): drive glossary pagination test via cursor Prev/Next

The large-glossary test asserted infinite-scroll behaviour (scroll to
bottom, expect the directChildrenOf+after fetch, then 100 appended rows).
Cursor pagination replaced infinite scroll, so that fetch never fires on
scroll and the test timed out. Rewrite it to click Next (which triggers
the directChildrenOf+after fetch), assert the page is replaced (still 50
rows, Previous now enabled), then Prev back to the first page.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(ui): keep glossary hierarchy intact across partial expand-all pages

Two defects flagged in review on the paginated glossary terms table:

1. buildTree promoted parentless descendants to roots. Progressive
   expand-all paginates all levels by name (backend orders by name,id),
   so a nested term can arrive on an earlier page than its parent term.
   buildTree then rendered that orphan as a top-level row, corrupting the
   hierarchy. Hold such orphans back until the page carrying their parent
   loads, at which point they attach correctly.

2. The Expand/Collapse-All control desynced on partial loads. The action
   was chosen by an expandedRowKeys === expandableKeys equality that a
   partially loaded tree never satisfies, and toggleExpandBtn was blindly
   flipped. So a second click (or one after a manual row collapse) re-ran
   the expand path, reset the accumulated pages, and hid the only Load
   More control. Drive the action, label, and icon off the explicit
   expand-all mode flag instead.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix checkstyle

* fix(ui): address gitar review on glossary expand-all hierarchy

- buildTree: push the live node into its parent's children instead of a
  shallow snapshot. With lazy child-array creation, a snapshot kept the
  node's original (undefined) children array, so a grandchild attached on
  a later page bound to the original node and vanished from the tree.
- buildTree: hold an orphan back based on the parent FQN's presence
  (excluding an explicit glossary parent) rather than a populated
  parent.type, which the API may omit and would otherwise let the orphan
  become a spurious root.
- toggleExpandAll: list the fetch helpers (and handlePagingChange) it
  actually calls in its dependency array so the memoized callback can't
  invoke a stale closure.

Adds regression tests for the missing-parent-type orphan and the
intermediate-with-no-inline-children grandchild cases.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(ui): don't hold back a term view's direct children in buildTree

The orphan guard treated any term whose parent term is absent from the
fetched data as an orphan. That is correct in the glossary view (top-level
terms have no term parent), but wrong when expanding a glossary term:
fetchExpadedTree loads that term's descendants, so the term itself is not
in the data and its direct children reference an absent parent — they were
wrongly held back, leaving the expanded table empty.

Pass the view's root FQN (the glossary or the term being viewed) to
buildTree so its direct children are recognised as genuine roots. Fixes
the 'Verify Expand All For Nested Glossary Terms' e2e regression.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix checkstyle

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
(cherry picked from commit ba06d99)
@anuj-kumary
anuj-kumary requested a review from a team as a code owner September 2, 2026 11:14
@anuj-kumary anuj-kumary added UI UI specific issues safe to test Add this label to run secure Github workflows on PRs skip-pr-checks Bypass PR metadata validation check labels Sep 2, 2026
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

❌ PR checklist incomplete

This PR cannot be merged until the following are addressed on its linked issue:

  • No GitHub issue is linked. Link an issue in the Development section of the PR (or add Fixes #12345 to the description). For a same-org cross-repo issue, add Fixes open-metadata/<repo>#123 to the description.

The fields live on the linked issue in the Shipping project (open the issue → right sidebar → Projects). After you set them, re-run this check (or push a commit) — issue/project changes do not re-trigger it automatically.

Maintainers can bypass this check by adding the skip-pr-checks label.

@gitar-bot

gitar-bot Bot commented Sep 2, 2026

Copy link
Copy Markdown
Code Review ✅ Approved 2 resolved / 2 findings

Paginates the glossary terms table with cursor-based Prev/Next navigation and a paged expand-all, so large glossaries no longer load every nested term up front. The backport cleanly applies to 2.0 with conflict resolution in the import block.

Consider guarding fetchExpandedTree against stale responses (like fetchAllTerms does with requestSeq) and clearing expand-all state when search/status filters change mid-flight, to prevent the header and load-more bar from staying visible after the results page resets. Also consider hiding the Prev/Next pager while in expand-all mode, since it renders redundantly beneath the expand-tree load-more bar with no navigation capability.

✅ 2 resolved
Quality: Both load-more bar and Prev/Next pager render in expand-all

📄 openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryTermTab/GlossaryTermTab.component.tsx:1656-1659 📄 openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryTermTab/GlossaryTermTab.component.tsx:1794-1805
In expand-all mode showPagination (glossaryTerms.length > 0) stays true while showExpandTreeLoadMore is also true, so the footer renders two stacked bars: the expand-tree "Load more / Showing X of Y" bar and a NextPrevious pager that is intentionally inert (after/before undefined, total set to 0). The redundant, non-navigable pager showing "Page 1" beneath the load-more control is visually confusing. Consider hiding NextPrevious while in expand-all mode, e.g. gate it as showPagination && !toggleExpandBtn.

Edge Case: Expand-all mode not reset when search/status changes mid-flight

📄 openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryTermTab/GlossaryTermTab.component.tsx:397-411 📄 openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryTermTab/GlossaryTermTab.component.tsx:1636-1650 📄 openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryTermTab/GlossaryTermTab.component.tsx:457-463
fetchExpadedTree runs with no stale-response guard (unlike fetchAllTerms, which uses requestSeq and re-checks searchTermRef/selectedStatusRef), and the search/status effect (line ~1636) does not clear toggleExpandBtn or expandTree. If a user types a search or changes the status filter while an expand-all fetch is in flight (the search box stays visible in expand-all mode), fetchAllTerms replaces the rows with a flat page while toggleExpandBtn remains true — the header still reads 'Collapse All' and a stale expand-tree-load-more bar can remain visible against flat results. Consider clearing expand-all state (setToggleExpandBtn(false), reset expandTree, clear expandedTreeFlatRef) in the search/status effect, and/or guarding fetchExpadedTree's apply with the active-context check.

Options

Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Jest test Coverage

UI tests summary

Lines Statements Branches Functions
Coverage: 67%
67.12% (80570/120025) 51.67% (49457/95710) 52.51% (14728/28044)

@anuj-kumary
anuj-kumary enabled auto-merge (squash) September 3, 2026 09:25
@anuj-kumary
anuj-kumary merged commit 58f21ec into 2.0 Sep 3, 2026
20 of 21 checks passed
@anuj-kumary
anuj-kumary deleted the backport/32223-glossary-term-pagination-2.0 branch September 3, 2026 09:28
@sonarqubecloud

sonarqubecloud Bot commented Sep 3, 2026

Copy link
Copy Markdown

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

Labels

safe to test Add this label to run secure Github workflows on PRs skip-pr-checks Bypass PR metadata validation check UI UI specific issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants