Skip to content

fix(ui): filter team members modal to show only non-members#3610

Merged
crivetimihai merged 9 commits intoIBM:mainfrom
omorros:fix/team-members-modal-search-only-nonmembers
Mar 21, 2026
Merged

fix(ui): filter team members modal to show only non-members#3610
crivetimihai merged 9 commits intoIBM:mainfrom
omorros:fix/team-members-modal-search-only-nonmembers

Conversation

@omorros
Copy link
Copy Markdown
Contributor

@omorros omorros commented Mar 11, 2026

🔗 Related Issue Closes #3085

Supersedes #3209


📝 Summary

The Manage Members modal loaded all non-members eagerly via infinite scroll, which crashed browsers at 20K+ users due to DOM accumulation.
Changes:

  • Non-members section no longer loads on modal open — users must search by name/email first; results are capped at 50
  • Current members section gains its own search bar with server-side filtering via a new search parameter on get_team_members()
  • Replaced monolithic serverSideUserSearch with two focused server-side search functions (serverSideMemberSearch,
    serverSideNonMemberSearch) - Selection state is preserved across searches with a 2-char minimum enforced

🏷️ Type of Change

  • Bug fix
  • Feature / Enhancement
  • Documentation
  • Refactor
  • Chore (deps, CI, tooling)
  • Other (describe below)

🧪 Verification

Check Command Status
Lint suite make lint
Unit tests make test

✅ Checklist

  • Code formatted (make black isort pre-commit)
  • Tests added/updated for changes - [ ] Documentation updated (if applicable)
  • No secrets or credentials committed

📓 Notes (optional)

Re-opened from #3209 (which was itself re-created from #3103) since the branch lived on the upstream repo and I couldn't push conflict
resolution directly. Code and changes are identical — only the merge conflicts with upstream main have been resolved.
Files changed (4): - mcpgateway/admin.py — Split unified search into two per-section inputs; non-members container no longer auto-loads

  • mcpgateway/services/team_management_service.py — Added search param + _escape_like() to get_team_members()
  • mcpgateway/static/admin.js — Replaced serverSideUserSearch with serverSideMemberSearch and serverSideNonMemberSearch
  • tests/unit/mcpgateway/test_admin.py — Updated 13 tests for new search param, added test_admin_team_non_members_partial_html_empty_search

omorros and others added 5 commits February 24, 2026 10:14
Closes IBM#3085

Signed-off-by: Oriol Morros Vilaseca <OM368@student.aru.ac.uk>
…minimum in team members modal

Signed-off-by: Oriol Morros Vilaseca <OM368@student.aru.ac.uk>
Signed-off-by: Oriol Morros Vilaseca <OM368@student.aru.ac.uk>
@vishu-bh vishu-bh added bug Something isn't working ui User Interface labels Mar 11, 2026
@vishu-bh vishu-bh added this to the Release 1.0.0 milestone Mar 11, 2026
Copy link
Copy Markdown
Collaborator

@vishu-bh vishu-bh left a comment

Choose a reason for hiding this comment

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

Thanks @omorros for new PR and addressing the issue.

LGTM 🚀

Copy link
Copy Markdown
Collaborator

@vishu-bh vishu-bh left a comment

Choose a reason for hiding this comment

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

Thanks @omorros for new PR and addressing the issue.

LGTM 🚀

@vishu-bh vishu-bh added the release-fix Critical bugfix required for the release label Mar 11, 2026
@marekdano marekdano added release-fix Critical bugfix required for the release and removed release-fix Critical bugfix required for the release labels Mar 11, 2026
@crivetimihai
Copy link
Copy Markdown
Member

Maintainer Review & Rebase

Rebased onto current main (641d6a4) — resolved 6 merge conflicts across admin.py and test_admin.py.

Commits (4 on branch)

  1. f60d82ffix(ui): search-only non-members (original author)
  2. f2f9019fix(ui): preserve selection state + 2-char minimum (original author)
  3. 507f934test: paginated search path coverage — added test_get_team_members_with_search_paginated for the page-based pagination + search code path
  4. 23aa2b3fix(tests): stabilize flaky caplog tests — fixed 3 flaky test_get_prompt_* tests in test_streamablehttp_transport.py that failed when run after test_main_extended.py (root cause: intermediate mcpgateway logger left at ERROR level polluting caplog.at_level)

Verification

  • All 1172 Python tests pass (test_admin + test_team_management_service)
  • All 23 JS tests pass (admin-search.test.js)
  • Manual E2E testing on live server confirmed:
    • Members load on modal open, member search filters server-side
    • Non-members do NOT auto-load (placeholder shown)
    • 2-char minimum enforced client-side and server-side
    • SQL wildcards (%, _, \) properly escaped via _escape_like()
    • Selection state preserved across search changes
    • urllib.parse.quote / encodeURIComponent used at all URL boundaries

Security

  • No SQL injection vectors (parameterized ILIKE with escape clause)
  • No XSS (team_id UUID-validated, search params URL-encoded)
  • Auth/RBAC decorators preserved on both endpoints

@crivetimihai crivetimihai added the SHOULD P2: Important but not vital; high-value items that are not crucial for the immediate release label Mar 20, 2026
@crivetimihai crivetimihai changed the title Fix/team members modal search only nonmembers fix(ui): filter team members modal to show only non-members Mar 20, 2026
@crivetimihai
Copy link
Copy Markdown
Member

Review Summary

Rebased onto main (clean, no conflicts) and reviewed for correctness, security, consistency, and test coverage.

Original PR — Well Implemented

  • Server-side search guards are solid: 2-char minimum, 50-result cap, prefix-based ilike with proper _escape_like() escaping
  • Splitting serverSideUserSearch into serverSideMemberSearch/serverSideNonMemberSearch is cleaner than the old unified approach
  • Selection caching preserves checkbox/role state across searches
  • list_users_not_in_team already supported the search parameter — no unnecessary service-layer changes
  • Search param correctly propagated in pagination URLs via urllib.parse.quote()

Fixes Added During Review

1. Stale cache leakage across modal sessions (3e95826)
The nonMemberSelectionsCache and memberOverridesCache persisted in JS memory after the modal was closed (HTMX destroys DOM but not JS state). Reopening the modal and submitting could silently add users from a previous session. Fixed by adding clearTeamSearchCaches(teamId) called on modal render.

2. Hidden role-input encoding mismatch (3e95826)
restoreNonMemberSelections used encodeURIComponent(email) for hidden role input names, but the backend uses urllib.parse.quote(email, safe=""). These differ for !'*() characters. Added urlQuoteSafe() to match Python's encoding.

3. Member overrides lost when filtered out by search (3be8345)
If a user unchecked or re-roled a member, then searched so that member disappeared from view, the override was silently dropped on submit because loadedMembers was gone from the DOM. restoreMemberOverrides() now creates hidden loadedMembers/associatedUsers/role inputs for off-screen cached members.

4. Missing test assertion (b3a9d38)
test_admin_team_non_members_partial_html_success verified template rendering but didn't assert the search parameter was forwarded to list_users_not_in_team.

Test Results

  • Python: 86 related tests pass
  • JavaScript: 890 tests pass (7 new tests added for cache clearing, encoding, and off-screen member overrides)

Copy link
Copy Markdown
Member

@crivetimihai crivetimihai left a comment

Choose a reason for hiding this comment

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

Reviewed, rebased, and fixed three bugs found during review (stale cache leakage, encoding mismatch, off-screen member override loss). All tests pass. Approved.

@crivetimihai crivetimihai merged commit 43d9702 into IBM:main Mar 21, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working release-fix Critical bugfix required for the release SHOULD P2: Important but not vital; high-value items that are not crucial for the immediate release ui User Interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG][PERFORMANCE][UI]: The team members and non-members should not load in one go in Manage members modal.

4 participants