Skip to content

Comments

Fix product export with 'Current search' filter option#6254

Merged
witoszekdev merged 14 commits intosaleor:mainfrom
iharshyadav:fix/product-export-missing-filter-5985
Feb 12, 2026
Merged

Fix product export with 'Current search' filter option#6254
witoszekdev merged 14 commits intosaleor:mainfrom
iharshyadav:fix/product-export-missing-filter-5985

Conversation

@iharshyadav
Copy link
Contributor

@iharshyadav iharshyadav commented Jan 13, 2026

Description

Fixes #5985 - The export mutation was failing with "You must provide filter input" error when using the "Current search" export scope without active filters.

Root Cause

The backend's exportProducts mutation requires either:

  • A non-empty filter when scope: FILTER
  • ids array when scope: IDS
  • Just scope: ALL (no filter needed)

The dashboard was sending scope: FILTER with an empty filter {}, causing the backend to reject it with a REQUIRED validation error.

Changes

  • Created getExportProductFilter() function in src/products/views/ProductList/filters.ts to build proper export filter from current view's search, channel, and other active filters
  • Updated export submission logic in src/products/views/ProductList/ProductList.tsx to intelligently fall back to scope: ALL when no filters are active
  • Filter parameters now correctly included in GraphQL mutation when scope is FILTER

Screenshots

Before (Bug)

before-fix

After (Fixed)

after-fix

What Didn't Work

  • Exporting with "Current search" scope without any active filters → error: "You must provide filter input"
  • Export wasn't capturing search terms or channel context

What Works Now

  • Export succeeds for both filtered and unfiltered product lists
  • Search terms and channel are now included in export filters
  • Falls back to ALL scope when "Current search" has no active criteria
  • All export scopes (ALL, FILTER, IDS) work correctly

Scope of the change

  • I confirm my feature doesn't contain any user-facing changes that require ripples (no new product features added)
  • This is a bug fix - no analytics tracking needed

Testing

  • Exported products with no filters applied → falls back to ALL scope ✓
  • Exported with search term active → includes search in filter ✓
  • Exported with category/collection filters → includes filters ✓
  • Exported with channel selected → includes channel in filter ✓
  • Verified filter parameter structure in GraphQL request payload ✓
  • Confirmed no regressions to product list view or other export scopes ✓

Checklist

  • Code follows project style
  • Tested locally in development
  • Ran pnpm run lint and pnpm run check-types
  • Added changeset for user-facing changes
  • No new warnings generated

- Add search and channel to export filter builder
- Fall back to ALL scope when no filters are active
- Resolves REQUIRED filter error on export

Closes saleor#5985
Copilot AI review requested due to automatic review settings January 13, 2026 15:10
@iharshyadav iharshyadav requested a review from a team as a code owner January 13, 2026 15:10
@changeset-bot
Copy link

changeset-bot bot commented Jan 13, 2026

🦋 Changeset detected

Latest commit: b54b91f

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@CLAassistant
Copy link

CLAassistant commented Jan 13, 2026

CLA assistant check
All committers have signed the CLA.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a bug where exporting products with the "Current search" filter option failed when no active filters were present. The backend's exportProducts mutation requires either a non-empty filter when using scope: FILTER, ids array when using scope: IDS, or just scope: ALL without filters. The dashboard was incorrectly sending an empty filter object {} with scope: FILTER, causing validation errors.

Changes:

  • Added getExportProductFilter() function to build proper export filters from query parameters
  • Modified export submission logic to intelligently fall back to scope: ALL when no filters are active
  • Ensured search terms, channel, and other active filters are properly included in export mutations

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.

File Description
src/products/views/ProductList/filters.ts Implements new getExportProductFilter() function to construct ProductFilterInput from URL query parameters
src/products/views/ProductList/ProductList.tsx Updates export submission logic to use the new filter function and fall back to ALL scope when appropriate
.changeset/fuzzy-coins-arrive.md Adds changeset documenting the bug fix

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…' scope

- Add getExportProductFilter() to extract active filters from URL params
- Fall back to ALL scope when FILTER scope has no active criteria
- Use ExportScope enum for type safety
- Reduce code duplication, improve TypeScript typing
- Add 21 comprehensive test cases (27 total tests passing)

Fixes saleor#5985
Copy link
Member

@witoszekdev witoszekdev left a comment

Choose a reason for hiding this comment

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

Thanks @iharshyadav for your contribution!

I think we can merge this PR, but I would like us to check if we can re-use existing logic for building query variables. This will make maintenance easier for us, since we will need to update our logic in only once place :)

Copy link
Member

Choose a reason for hiding this comment

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

issue: We're duplicating here logic to create ProductFilterInput which our codebase already has in ConditionalFilter. This is problematic because we already have quite extensive logic for building query variables based on filter selection. It also supports building both FILTER and WHERE APIs (export still uses legacy FILTER API).

We could replace this method with:

export const createProductQueryVariablesLegacyInput = (filterContainer: FilterContainer): ProductFilterInput => {
  const builder = new FiltersQueryBuilder<ProductQueryVars, "channel">({
    apiType: QueryApiType.FILTER,
    filterContainer,
  });
  const { filters } = builder.build();

  return { ...filters };
};

We would need to get data from filter container though, not query variables (should be somewhere on product list page).

This should work, but if it doesn't please let me know since it might mean we have bug somewhere else 🙏🏻

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the suggestion! Refactored to use FiltersQueryBuilder with FILTER API type as you recommended.

I added a normalization step to handle field name conversions (singular to plural) and price format handling, since the FILTER API output differs slightly from what the export endpoint expects. All tests are passing now.

Let me know if this approach looks good or if there's a better way to handle the normalization!🙏🏻

Copilot AI review requested due to automatic review settings January 13, 2026 18:51
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 12 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Fix type safety by replacing 'any' with Partial<ProductFilterInput>
- Handle price = 0 edge case with strict equality checks
- Add null type guard in ProductList.tsx
- Return null instead of {} for consistency with InputMaybe type
- Strengthen test assertions and add edge case coverage (18 tests total)
- Improve JSDoc documentation for FILTER vs WHERE API differences
Copilot AI review requested due to automatic review settings February 4, 2026 15:01
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Comment on lines 1 to 3
import { ApolloClient } from "@apollo/client";
import * as Sentry from "@sentry/react";

Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

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

This file reports mapping errors via @sentry/react directly, while other ConditionalFilter code reports errors through the errorTracker abstraction (e.g. src/components/ConditionalFilter/FilterElement/Condition.ts:1,119). To keep error reporting consistent and configurable, prefer using errorTracker.captureException(...) here as well and avoid importing Sentry directly in new code.

Copilot uses AI. Check for mistakes.

let filterValue: string[];

if (typeof value === "object" && value !== null) {
Copy link
Member

Choose a reason for hiding this comment

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

we need to do this because export input has special type

witoszekdev
witoszekdev previously approved these changes Feb 4, 2026
Copy link
Member

@witoszekdev witoszekdev left a comment

Choose a reason for hiding this comment

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

I did some changes from my side, so that we re-use existing queryVariables logic; @lkostrowski please take a look as well :)

@codecov
Copy link

codecov bot commented Feb 4, 2026

Codecov Report

❌ Patch coverage is 76.28866% with 23 lines in your changes missing coverage. Please review.
✅ Project coverage is 42.76%. Comparing base (4f81c86) to head (b54b91f).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/products/views/ProductList/export.ts 7.14% 12 Missing and 1 partial ⚠️
...lder/queryVarsBuilders/ProductExportFieldMapper.ts 81.08% 7 Missing ⚠️
...er/queryVarsBuilders/PriceRangeQueryVarsBuilder.ts 94.28% 2 Missing ⚠️
src/products/views/ProductList/ProductList.tsx 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6254      +/-   ##
==========================================
+ Coverage   42.68%   42.76%   +0.07%     
==========================================
  Files        2505     2507       +2     
  Lines       43411    43508      +97     
  Branches    10247    10277      +30     
==========================================
+ Hits        18532    18607      +75     
- Misses      23562    23583      +21     
- Partials     1317     1318       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI review requested due to automatic review settings February 4, 2026 17:01
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Comment on lines +81 to +89
const builder = new FiltersQueryBuilder<ProductFilterInput>({
apiType: QUERY_API_TYPES.PRODUCT_EXPORT,
filterContainer,
filterDefinitionResolver: productExportFilterResolver,
});
const { filters } = builder.build();

// Return null if no filters remain (backend requirement)
return Object.keys(filters).length === 0 ? null : filters;
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

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

createProductExportQueryVariables relies on the default query-var builders for most fields. For the product price expression filter, the default mapping produces string values (UI number inputs emit strings) and for the is operator it yields a primitive (e.g. price: "200") rather than a PriceRangeInput ({ gte?: Float; lte?: Float }) required by ProductFilterInput. This will likely make exportProducts fail with GraphQL variable coercion errors when a price filter is active. Consider adding a dedicated query vars builder for product-export price that (1) parses values to numbers and (2) maps the is operator to { gte: value, lte: value }, and register it in productExportFilterResolver before the default builders.

Copilot uses AI. Check for mistakes.
@witoszekdev witoszekdev added the test deployment Deploy Pull Request to *.saleor.rocks environment label Feb 5, 2026
Copilot AI review requested due to automatic review settings February 10, 2026 09:52
@witoszekdev witoszekdev enabled auto-merge (squash) February 10, 2026 09:52
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copilot AI review requested due to automatic review settings February 12, 2026 14:14
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@witoszekdev witoszekdev merged commit a0011cc into saleor:main Feb 12, 2026
14 checks passed
This was referenced Feb 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test deployment Deploy Pull Request to *.saleor.rocks environment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Export with current search is not working

4 participants