Skip to content

Conversation

@pmakode-akamai
Copy link
Contributor

@pmakode-akamai pmakode-akamai commented Jan 19, 2026

Description 📝

Add Marketplace filters to the Products landing page.

Below is the X-Filter header structure that will be sent to the API based on the filters selected by the user in the UI:

Details 1. Search by product name / description only When the user enters text in the search input without selecting category or type:
X-Filter
{
  "category_id": 1,
  "+or": [
    {
      "name": {
        "+contains": "Product ABC"
      }
    },
    {
      "short_description": {
        "+contains": "Product ABC"
      }
    }
  ]
}   
  1. Category and Type selected (no search input)
    When only category and type are selected from the dropdowns:
X-Filter
{
  "category_id": 3,
  "type_id": 4
}   
  1. Search by product name / description + Category + Type
    When the user enters search text and also selects category and type:
X-Filter
{
  "category_id": 3,
  "+or": [
    {
      "name": {
        "+contains": "Product ABC"
      }
    },
    {
      "short_description": {
        "+contains": "Product ABC"
      }
    }
  ],
  "type_id": 6
}   
  1. Search by Partner name + Category + Type
    When the search input matches partner names, matching partner IDs are resolved and included in the +or condition along with product name/description:
X-Filter
{
  "category_id": 3,
  "+or": [
    {
      "name": {
        "+contains": "partner"
      }
    },
    {
      "short_description": {
        "+contains": "partner"
      }
    },
    {
      "partner_id": 1
    },
    {
      "partner_id": 2
    },
    {
      "partner_id": 3
    }
  ],
  "type_id": 6
}   
  1. Search by Type name + Category
    When the search input matches type names and only category is selected, matching type IDs are included in the +or condition:
X-Filter
{
  "category_id": 3,
  "+or": [
    {
      "name": {
        "+contains": "type"
      }
    },
    {
      "short_description": {
        "+contains": "type"
      }
    },
    {
      "type_id": 1
    },
    {
      "type_id": 2
    }
  ]
}   

Note

The APIs are not available yet.

Changes 🔄

  • Add Marketplace filters to the Products landing page
  • Load 5 categories (with products) on initial load and load 5 more on scroll (and so on...)
  • Auto-fetch next batch of 5 if current batch has no results when filters are applied
  • Display an empty state when no categories with products are available
  • Add support for searching partners or types by text, with logic to find the corresponding searchDerivedTypeIds or searchDerivedPartnerIds to use in the X filter

Scope 🚢

Upon production release, changes in this PR will be visible to:

  • All customers
  • Some customers (e.g. in Beta or Limited Availability)
  • No customers / Not applicable

Target release date 🗓️

N/A

Preview 📷

Filters:
Screenshot 2026-01-19 at 6 02 51 PM

Empty States:

  • When filters are applied:
    Screenshot 2026-01-20 at 6 10 52 PM

  • When no categories with products are available:
    Screenshot 2026-01-20 at 6 14 49 PM

How to test 🧪

Prerequisites

  • Enable MSW and MarketplaceV2 feature flag

Verification steps

  • Verify Filtering:
    • Ensure the correct X filters are passed (check that the format is correct) when using search input only, dropdown values only, or both
    • Verify searching partners by name or types by name, and ensure the corresponding searchDerivedPartnerIds or searchDerivedTypeIds are passed in the X filter in the correct format
    • Select a type from the dropdown, then try searching for a type name in the input. Verify that searchDerivedTypeIds are not passed when the type is already selected from the dropdown
  • When no filters are applied
    • Verify that the next batch of 5 items is fetched only on scroll (and so on...), and no auto-fetch happens
  • When filters are applied
    • Verify that the next batch is only auto-fetched if the current batch API calls has no results
      • If all batches are auto-fetched and no results are found, verify that the empty state is displayed
    • Once results appear in any batch, verify that subsequent next batches are fetched via normal waypoint (scroll-based) lazy loading behavior
  • Verify empty states:
    • When no categories with products are available
    • When no results appear after applying filters
    • Ensure the Reset Filters link button works as expected from the empty state
  • Ensure there are no regressions
  • Ensure all checks pass
Author Checklists

As an Author, to speed up the review process, I considered 🤔

👀 Doing a self review
❔ Our contribution guidelines
🤏 Splitting feature into small PRs
➕ Adding a changeset
🧪 Providing/improving test coverage
🔐 Removing all sensitive information from the code and PR description
🚩 Using a feature flag to protect the release
👣 Providing comprehensive reproduction steps
📑 Providing or updating our documentation
🕛 Scheduling a pair reviewing session
📱 Providing mobile support
♿ Providing accessibility support

  • I have read and considered all applicable items listed above.

As an Author, before moving this PR from Draft to Open, I confirmed ✅

  • All tests and CI checks are passing
  • TypeScript compilation succeeded without errors
  • Code passes all linting rules

@pmakode-akamai pmakode-akamai marked this pull request as ready for review January 19, 2026 13:08
@pmakode-akamai pmakode-akamai requested a review from a team as a code owner January 19, 2026 13:08
if (value && value !== textFieldValue) {
if (value !== textFieldValue) {
setTextFieldValue(value);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This change ensures that the internal state correctly synchronizes with the value prop even when it is an empty string. Previously, the condition value && value !== textFieldValue prevented updates when value was "", so clearing the search field would not update the internal state or reflect in the UI. By changing the condition to value !== textFieldValue, the field now correctly resets, and the UI and internal state stay in sync when the search field is cleared.

We can test this by resetting the filters from the Filters empty state to ensure the field clears/resets correctly in the UI.

Copy link
Contributor

Choose a reason for hiding this comment

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

This component is used throughout the app, have you tested other areas to confirm there have been no regressions/behavior changes? I spot checked a few places and didn't notice any.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did check and didn't notice any issues either

Copy link
Contributor

@dwiley-akamai dwiley-akamai left a comment

Choose a reason for hiding this comment

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

Verification steps ✅
Code review ✅

if (value && value !== textFieldValue) {
if (value !== textFieldValue) {
setTextFieldValue(value);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This component is used throughout the app, have you tested other areas to confirm there have been no regressions/behavior changes? I spot checked a few places and didn't notice any.

@tvijay-akamai
Copy link
Contributor

As discussed, When filtering also let's make use of waypoint and handle empty state by making api call in batches if no products are found.

!isLoading &&
(totalCategories === 0 ||
(hasFiltersApplied &&
allCategoriesLoaded &&
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for making this change to use allCategoriesLoaded here.

@pmakode-akamai
Copy link
Contributor Author

pmakode-akamai commented Jan 22, 2026

As discussed, When filtering also let's make use of waypoint and handle empty state by making api call in batches if no products are found.

This logic is already handled in the current implementation of MarketplaceLanding.tsx‎ at L199-L222

@linode-gh-bot
Copy link
Collaborator

Cloud Manager UI test results

🔺 1 failing test on test run #12 ↗︎

❌ Failing✅ Passing↪️ Skipped🕐 Duration
1 Failing864 Passing11 Skipped42m 7s

Details

Failing Tests
SpecTest
clone-linode.spec.tsCloud Manager Cypress Tests→clone linode » can clone a Linode from Linode details page

Troubleshooting

Use this command to re-run the failing tests:

pnpm cy:run -s "cypress/e2e/core/linodes/clone-linode.spec.ts"

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

Projects

Status: Review

Development

Successfully merging this pull request may close these issues.

4 participants