ProductDoctor: Add support for the new availability mode#6545
ProductDoctor: Add support for the new availability mode#6545
Conversation
🦋 Changeset detectedLatest commit: 599bcda 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 |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #6545 +/- ##
==========================================
+ Coverage 48.16% 48.63% +0.46%
==========================================
Files 2589 2591 +2
Lines 46051 46143 +92
Branches 10869 10892 +23
==========================================
+ Hits 22182 22441 +259
+ Misses 22624 22466 -158
+ Partials 1245 1236 -9
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Makes Product Doctor aware of Saleor’s stock-availability mode (Shop.useLegacyShippingZoneStockAvailability) so diagnostics avoid false positives in direct warehouse↔channel mode and provide clearer user context.
Changes:
- Extend the diagnostics GraphQL query + hook plumbing to read and expose
useLegacyShippingZoneStockAvailability. - Update availability checks to (a) adjust shipping-zone severity/copy by mode, (b) skip legacy-only checks in direct mode, and (c) add an info advisory for “stock outside channel warehouses”.
- Update UI to display the active availability mode and to treat
infoissues as non-blocking in channel headers; add/extend unit tests.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/products/queries.ts | Adds shop.useLegacyShippingZoneStockAvailability to diagnostics query. |
| src/products/components/ProductDoctor/utils/types.ts | Exposes the mode flag in DiagnosticsResult. |
| src/products/components/ProductDoctor/utils/availabilityChecks.ts | Makes checks mode-aware; adds “stock outside channel warehouses” info check. |
| src/products/components/ProductDoctor/utils/availabilityChecks.test.ts | Adds coverage for direct vs legacy behavior + new info check. |
| src/products/components/ProductDoctor/primitives.tsx | Adds test selectors/attributes for the channel issue badge. |
| src/products/components/ProductDoctor/messages.ts | Adds/updates i18n copy for direct-mode messaging and mode indicator. |
| src/products/components/ProductDoctor/hooks/useProductAvailabilityDiagnostics.ts | Plumbs the shop flag into check execution and hook result. |
| src/products/components/ProductDoctor/hooks/useProductAvailabilityDiagnostics.test.tsx | Adds tests ensuring the flag is forwarded/exposed with safe fallback. |
| src/products/components/ProductDoctor/AvailabilityChannelItem.tsx | Treats info as advisory (non-blocking) in header visuals; adds callout test selectors. |
| src/products/components/ProductDoctor/AvailabilityCard.tsx | Displays a stock-availability mode indicator with tooltip. |
| src/products/components/ProductDoctor/AvailabilityCard.test.tsx | Adds UI tests for the mode indicator and info-vs-blocking gating. |
| src/graphql/types.generated.ts | Regenerates types to include shop in ChannelDiagnosticsQuery. |
| src/graphql/hooks.generated.ts | Regenerates ChannelDiagnosticsDocument to include shop selection. |
| locale/defaultMessages.json | Adds new extracted messages and updates the shipping-zone description key. |
| .changeset/tender-impalas-tickle.md | Adds a patch changeset entry for the Product Doctor enhancement. |
| /** | ||
| * Defaults to `true` (legacy mode) when the shop fragment in the diagnostics | ||
| * query hasn't loaded yet so we don't downgrade legacy behaviors prematurely | ||
| * on a fresh page load. Once the query resolves, the real value takes over | ||
| * and re-renders the diagnostics. | ||
| */ | ||
| const LEGACY_MODE_FALLBACK = true; |
There was a problem hiding this comment.
you can read about optimistic rendering. Probably Apollo has it built-in. Instead of fallback on this level, you can provide default value to apollo so it will use it like it was cached
(non blocking, also not sure how its done in old apollo)
Renamed across the channel availability code so the name describes the UI role (these are the issues that are promoted into the channel header and surface a badge) rather than implying that warnings block: - `getBlockingIssueBadgeProps` → `getHeaderIssueBadgeProps` - `BlockingIssueType` → `HeaderIssueType` - `hasBlockingIssues` → `hasHeaderIssues`
| const accessibleName = intl.formatMessage(messages.channelHasIssues, { count }); | ||
| const iconLabel = intl.formatMessage( | ||
| type === "error" ? messages.issueBadgeIconError : messages.issueBadgeIconWarning, | ||
| ); | ||
|
|
||
| return ( | ||
| <Box display="flex" alignItems="center" title={title} position="relative"> | ||
| <Box | ||
| display="flex" | ||
| alignItems="center" | ||
| title={accessibleName} | ||
| aria-label={accessibleName} | ||
| position="relative" | ||
| data-test-id="channel-issue-badge" | ||
| > |
There was a problem hiding this comment.
IssueBadge sets aria-label on the wrapping Box, but since it renders as a non-focusable generic element, assistive tech is unlikely to announce that label. In the common count === 1 case (no visible number rendered), a screen reader will only get the icon’s label ("Error"/"Warning") and miss the issue count/context. Consider making the badge itself expose a meaningful accessible name (e.g., give the wrapper an appropriate role and label that includes count + severity, or ensure the count/context is always available via screen-reader-only text) and avoid duplicating/conflicting labels between wrapper and icon.
| const createMockChannelData = ( | ||
| overrides: { useLegacyShippingZoneStockAvailability?: boolean } = {}, | ||
| ) => ({ | ||
| shop: { | ||
| useLegacyShippingZoneStockAvailability: | ||
| overrides.useLegacyShippingZoneStockAvailability ?? LEGACY_MODE_FALLBACK, | ||
| }, | ||
| channels: [ |
There was a problem hiding this comment.
createMockChannelData's shop object doesn't include the id field, but the real ChannelDiagnostics query selects shop { id useLegacyShippingZoneStockAvailability }. Adding id to the mock keeps the fixture aligned with the production response shape and prevents future type-tightening of the useQuery mock from breaking these tests.
Saleor 3.23 introduced
Shop.useLegacyShippingZoneStockAvailability. New installations default to the new direct warehouse↔channel stock model (false); existing installations keep the legacy shipping-zone-intersection model (true). The Product Doctor was so far only supporting the legacy semantics, so on direct-mode shops it raised false positives ("warehouse not in shipping zone") and labelled shipping-zone misconfiguration as a purchase blocker - when in direct mode it only blocks shipping.This PR makes the doctor mode-aware and gives users explicit context about which mode is active.
Screen.Recording.2026-04-29.at.13.45.15.mov