From 52f99e9e0b4dd56b88e790fc1c12e4b98fdb32cc Mon Sep 17 00:00:00 2001 From: "krshivam2505@gmail.com" Date: Sun, 11 Oct 2026 13:29:41 +0530 Subject: [PATCH] fix(markets): show legacy markets matching the switcher search Searching for a legacy market rendered "No markets found": the match landed in the legacy group, which only renders when the "Show legacy markets" switch is on, and noResults never counted that group. An active search now reveals matching legacy markets regardless of the switch, and noResults accounts for them. Closes #3127 --- src/components/MarketSwitcher.tsx | 27 +++++++--- .../__tests__/marketSwitcher.utils.test.ts | 50 +++++++++++++++++++ src/components/marketSwitcher.utils.ts | 28 +++++++++++ 3 files changed, 97 insertions(+), 8 deletions(-) create mode 100644 src/components/__tests__/marketSwitcher.utils.test.ts create mode 100644 src/components/marketSwitcher.utils.ts diff --git a/src/components/MarketSwitcher.tsx b/src/components/MarketSwitcher.tsx index ef291c6c33..0e5c7f0cca 100644 --- a/src/components/MarketSwitcher.tsx +++ b/src/components/MarketSwitcher.tsx @@ -19,6 +19,7 @@ import React, { useMemo, useRef, useState } from 'react'; import { ArrowUpRightIcon } from 'src/components/icons/ArrowUpRightIcon'; import { ChevronUpDownIcon } from 'src/components/icons/ChevronUpDownIcon'; import { FAVOURITE_STAR_COLOR, StarIcon } from 'src/components/icons/StarIcon'; +import { hasNoMarketResults, shouldShowLegacySection } from 'src/components/marketSwitcher.utils'; import { ShimmerText } from 'src/components/ShimmerText'; import { useRootStore } from 'src/store/root'; import { BaseNetworkConfig } from 'src/ui-config/networksConfig'; @@ -611,13 +612,23 @@ export const MarketSwitcher = ({ hideDescription }: MarketSwitcherProps) => { ); - const noResults = - pinned.length === 0 && - ethereum.length === 0 && - l2.length === 0 && - other.length === 0 && - v4Ethereum.length === 0 && - v4Other.length === 0; + // An active search reveals matching legacy markets even while the switch is off, so a searched + // market is never hidden from the person who just named it. + const showLegacySection = shouldShowLegacySection({ + showLegacy, + searchQuery, + legacyCount: legacy.length, + }); + + const noResults = hasNoMarketResults([ + pinned.length, + ethereum.length, + l2.length, + other.length, + legacy.length, + v4Ethereum.length, + v4Other.length, + ]); const renderSelectorContent = (mobile: boolean) => ( <> @@ -705,7 +716,7 @@ export const MarketSwitcher = ({ hideDescription }: MarketSwitcherProps) => { )} {/* Legacy */} - {showLegacy && + {showLegacySection && renderSection( Legacy, legacy.map((id) => renderGridItem(id, mobile)) diff --git a/src/components/__tests__/marketSwitcher.utils.test.ts b/src/components/__tests__/marketSwitcher.utils.test.ts new file mode 100644 index 0000000000..8ec7d38af0 --- /dev/null +++ b/src/components/__tests__/marketSwitcher.utils.test.ts @@ -0,0 +1,50 @@ +import { hasNoMarketResults, shouldShowLegacySection } from '../marketSwitcher.utils'; + +describe('shouldShowLegacySection', () => { + it('keeps legacy markets collapsed by default', () => { + expect(shouldShowLegacySection({ showLegacy: false, searchQuery: '', legacyCount: 3 })).toBe( + false + ); + }); + + it('shows legacy markets when the switch is on', () => { + expect(shouldShowLegacySection({ showLegacy: true, searchQuery: '', legacyCount: 3 })).toBe( + true + ); + }); + + // Regression guard for https://github.com/aave/interface/issues/3127: searching for a legacy + // market used to report "No markets found" because the match was never rendered. + it('shows a searched-for legacy market even while the switch is off', () => { + expect( + shouldShowLegacySection({ showLegacy: false, searchQuery: 'gnosis', legacyCount: 1 }) + ).toBe(true); + }); + + it('stays hidden when a search matches no legacy market', () => { + expect( + shouldShowLegacySection({ showLegacy: false, searchQuery: 'base', legacyCount: 0 }) + ).toBe(false); + }); + + it('treats a whitespace-only query as no search', () => { + expect(shouldShowLegacySection({ showLegacy: false, searchQuery: ' ', legacyCount: 3 })).toBe( + false + ); + }); +}); + +describe('hasNoMarketResults', () => { + it('reports no results when every group is empty', () => { + expect(hasNoMarketResults([0, 0, 0, 0, 0, 0, 0])).toBe(true); + }); + + // The other half of #3127: legacy has to count, or a legacy-only match renders the empty state. + it('does not report no results when only a legacy market matched', () => { + expect(hasNoMarketResults([0, 0, 0, 0, 1, 0, 0])).toBe(false); + }); + + it('does not report no results when a non-legacy group matched', () => { + expect(hasNoMarketResults([0, 2, 0, 0, 0, 0, 0])).toBe(false); + }); +}); diff --git a/src/components/marketSwitcher.utils.ts b/src/components/marketSwitcher.utils.ts new file mode 100644 index 0000000000..b0113d076c --- /dev/null +++ b/src/components/marketSwitcher.utils.ts @@ -0,0 +1,28 @@ +/** + * Pure helpers for the market switcher's legacy section. + * + * Legacy markets are collapsed behind a "Show legacy markets" switch. That also hid them from + * search, so searching for one reported "No markets found" while the match sat in the + * un-rendered legacy group (https://github.com/aave/interface/issues/3127). + */ + +/** + * Legacy markets stay collapsed by default, but an explicit search must never hide a match — + * typing a market name has already said which market the user wants. + */ +export const shouldShowLegacySection = ({ + showLegacy, + searchQuery, + legacyCount, +}: { + showLegacy: boolean; + searchQuery: string; + legacyCount: number; +}): boolean => legacyCount > 0 && (showLegacy || searchQuery.trim() !== ''); + +/** + * "No markets found" has to account for every group a match can land in, legacy included, + * otherwise a legacy-only match is reported as no match at all. + */ +export const hasNoMarketResults = (groupCounts: number[]): boolean => + groupCounts.every((count) => count === 0);