Skip to content

feat: move catalog filters into a dialog - #14

Merged
gcgoncalves merged 2 commits into
mainfrom
feat/6179-move-filters-into-dialog
Aug 13, 2026
Merged

feat: move catalog filters into a dialog#14
gcgoncalves merged 2 commits into
mainfrom
feat/6179-move-filters-into-dialog

Conversation

@gandhipratik203

@gandhipratik203 gandhipratik203 commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Moves the MCP server catalog filters out of the popover and into the Add filters dialog from the design, and removes the authentication type selector while the catalog only offers Open servers.

Implements IBM/mcp-context-forge#6179. Builds on #7.

Design: Refiring — filters - open only

Heads-up: this is more than a container swap

The issue text reads "move filters into dialog", but the linked frame specifies a different filter model, so the diff is larger than the title implies:

  • Providers, Categories and Tags are each an All / Select radio pair over a 4-column checkbox grid. Category and provider were single-select dropdowns; per the design they are now multi-select, read from repeatable query params like tags already was.
  • Filters are staged. The footer is Cancel + Add filters, so selections live as a draft inside the dialog and only reach the URL on apply. Previously every click wrote to the URL immediately.
  • No Clear button. The per-section All radios replace it.
  • Dialog is 696px wide, titled "Add filters", auth type omitted.

All filtering stays client-side over the fetched catalog, so there is no API or backend change — the multi-select that #5970 listed as needing backend work does not, given the existing client-side predicate.

Changes

File What
ServerCatalog.tsx category/providerstring[]; authType removed; setSingleFilter/toggleTag/clearFilters collapsed into one applyFilters(draft) issuing a single navigation; activeFilterCount sums array lengths
CatalogToolbar.tsx CatalogFiltersPopoverCatalogFiltersDialog; new CatalogFilterSectionFields; draft + per-section mode state seeded only on open
mcpServer.json ×3 Added addFilters, plural headings, per-section All/Select labels; removed clearFilters, allCategories, allProviders, allAuthTypes

Two details worth a reviewer's eye:

  • updateQuery now deletes auth_type unconditionally, not just on apply. Without it a stale ?auth_type=Open from an existing URL survives every later search keystroke. Marked transitional in a comment; remove when auth types ship.
  • Per-section mode is explicit state, not derived from selected.length > 0. Deriving it looked simpler but broke the radio: clicking "Select..." with nothing ticked would leave the section in All mode and never reveal the grid.

catalog.provider, catalog.category and catalog.authentication are deliberately kept — CatalogResults.tsx uses them as detail-row labels, unrelated to filtering.

Test results

  • Catalog tests: 22 passed, up from 15. Four reworked for staged apply, seven added.
  • Full suite: 2818 passed, 1 skipped, 0 failed (157 files), rebased onto current main.
  • npm run lint, npm run format:check: clean.

New coverage: draft discarded on Cancel and on close; URL and grid unchanged until apply; repeated-param URL restore including checked dialog state; multi-provider OR matching; All clearing only its own section; zero badge on a fresh page; single history entry per apply; stale auth_type dropped via both apply and a plain search keystroke.

Visual check

Rendered at 1512x1084 in both themes against the filters - open only frame:

  • Dialog measures exactly 696px wide with a 4-column option layout.
  • Fully expanded (all three sections open) the content is 780px tall, so DialogContent's max-h + overflow-y-auto only engages on short viewports. No nested provider scroll region is needed at this data size — flagging for @a-effort in case the design intends the header and footer to stay pinned regardless.
  • One deviation found and fixed in cf107e7: options were flowing across rows, but the design lists them alphabetically down each column. Switched the option lists from CSS grid to multi-column flow, which now matches the frame column for column.

Still to do before this leaves draft

Manual verification

Manual test steps

Setup

cd contextforge-web-ui
npm ci                 # if node_modules is missing
npm run generate       # if src/generated/ is missing
npm run dev            # :5173

The catalog needs an authenticated session and a GET /v1/catalog response, so it is driven through a Playwright-mocked browser window rather than a plain dev server. The mock seeds 24 Open servers, 6 categories, 7 tags, and one API Key server ("Secret Service MCP", provider "SecureCo") that must stay hidden throughout.

Everything below is done in the mocked window, in the tab it opens.

Steps

1. Dialog layout — click Filters on the catalog toolbar.

2. Column order — click Select... under Providers.

3. Cancel discards the draft — tick AWS and Astro, check the address bar, then click Cancel. Reopen the dialog.

4. Apply commits multi-select — tick AWS and Astro, click Add filters.

5. Per-section clearing — reopen, expand Tags, tick network, apply. Then reopen, set Providers back to All, apply.

6. Deep link filters the grid — load /app/server-catalog?category=Monitoring&category=Data&provider=AWS.

7. Deep link restores the dialog — on that URL, open Filters.

8. Legacy auth_type is dropped — load /app/server-catalog?auth_type=Open, then use the catalog toolbar's search box (not the global header search) and type aws. The param stays visible on load; it clears once the URL is rewritten.

9. Non-Open servers never leak — checked across every step above.

Manual test results

Checked in light and dark themes at 1512x1084.

# Step Expected Result
1 Click Filters Centred modal, 696px, titled "Add filters"; Providers, Categories, Tags sections; no Authentication section; no Clear button; Cancel + Add filters footer Pass
2 Expand Providers Four columns reading alphabetically down each column; SecureCo absent Pass
3 Tick AWS + Astro, Cancel URL unchanged, grid still 24 cards, badge still plain "Filters"; reopening shows Providers back on "All" with nothing ticked Pass
4 Tick AWS + Astro, Add filters URL ?provider=AWS&provider=Astro, grid down to 2 cards, badge shows 2 Pass
5 Add a tag and apply, then set Providers to All and apply Badge 3 then 1; provider params cleared, tags=network survives Pass
6 Deep link with two categories and a provider Grid filtered on load, badge shows 3 Pass
7 Open the dialog on that URL Monitoring and Data ticked, Productivity not; AWS ticked; Tags still on "All" Pass
8 ?auth_type=Open, then type in catalog search Legacy auth_type drops out of the URL Pass
9 Throughout API Key server never in the grid; SecureCo absent from provider options Pass

Defect found and fixed before merge: options initially flowed left-to-right across rows, but the design lists them alphabetically down each column. Switched from CSS grid to multi-column flow. Unit tests could not have caught this — jsdom sees DOM order, which was correct throughout; only rendering exposed it.

Alongside the manual pass: 22 unit tests on the catalog page, 2818 in the full suite, and 29 assertions driven through a real browser against the dev bundle.

@gandhipratik203
gandhipratik203 force-pushed the feat/6179-move-filters-into-dialog branch from 9b14a38 to be2b639 Compare August 12, 2026 16:01
@gandhipratik203
gandhipratik203 marked this pull request as ready for review August 12, 2026 16:35
Replace the server catalog filter popover with the "Add filters" dialog from
the design, and drop the authentication type selector while the catalog only
offers Open servers.

Providers, categories and tags each become an All / Select radio pair over a
checkbox grid, so category and provider are now multi-valued and read from
repeatable query params. Selections are held as a draft inside the dialog and
committed in a single navigation when Add filters is pressed; Cancel and the
close button discard them.

Implements IBM/mcp-context-forge#6179

Signed-off-by: Pratik Gandhi <gandhipratik203@gmail.com>
The design lists providers, categories and tags alphabetically down each
column. A CSS grid fills across rows instead, so switch the option lists to
multi-column flow.

Signed-off-by: Pratik Gandhi <gandhipratik203@gmail.com>
@gandhipratik203
gandhipratik203 force-pushed the feat/6179-move-filters-into-dialog branch from cf107e7 to 55eb5bc Compare August 13, 2026 06:56

@marekdano marekdano 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.

@gandhipratik203 - thanks for the contribution!

The PR implements a complete plugin catalog feature with excellent results across all review dimensions: Code Quality ✅, Security ✅, Accessibility ✅, Test Coverage ✅, Issue Implementation ✅

LGTM 🚀

@gcgoncalves gcgoncalves 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.

Good A11y approach. 👏

@gcgoncalves
gcgoncalves merged commit d25446a into main Aug 13, 2026
5 checks passed
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.

3 participants