diff --git a/cypress/e2e/products/productsVariants.js b/cypress/e2e/products/productsVariants.js index ec304039a..0e86d8c79 100644 --- a/cypress/e2e/products/productsVariants.js +++ b/cypress/e2e/products/productsVariants.js @@ -13,7 +13,6 @@ import { import * as productUtils from "../../support/api/utils/products/productsUtils"; import { getProductVariants } from "../../support/api/utils/storeFront/storeFrontProductUtils"; import { - createFirstVariant, createVariant, variantsShouldBeVisible, } from "../../support/pages/catalog/products/VariantsPage"; @@ -81,10 +80,11 @@ describe("As an admin I should be able to create variant", () => { channelId: newChannel.id, }); cy.visit(`${urlList.products}${createdProduct.id}`); - createFirstVariant({ + createVariant({ + channelName: [defaultChannel.name, newChannel.name], sku: name, price, - attribute: attributeValues[0], + attributeName: attributeValues[0], }); selectChannelInHeader(defaultChannel.name); variantsShouldBeVisible({ name, price }); diff --git a/cypress/e2e/products/productsWithoutSku/createProductWithoutSku.js b/cypress/e2e/products/productsWithoutSku/createProductWithoutSku.js index a5a720a8e..a82a35f9c 100644 --- a/cypress/e2e/products/productsWithoutSku/createProductWithoutSku.js +++ b/cypress/e2e/products/productsWithoutSku/createProductWithoutSku.js @@ -120,9 +120,9 @@ describe("Creating variants", () => { }); cy.visit(`${urlList.products}${createdProduct.id}`); cy.waitForProgressBarToNotBeVisible(); - createFirstVariant({ + createVariant({ price, - attribute: attributeValues[0], + attributeName: attributeValues[0], }); getProductVariants(createdProduct.id, defaultChannel.slug); }) diff --git a/cypress/elements/catalog/products/product-details.js b/cypress/elements/catalog/products/product-details.js index cbe0ff7e9..b69971dfc 100644 --- a/cypress/elements/catalog/products/product-details.js +++ b/cypress/elements/catalog/products/product-details.js @@ -8,11 +8,7 @@ export const PRODUCT_DETAILS = { firstCategoryItem: "#downshift-0-item-0", visibleRadioBtn: "[name='isPublished']", channelAvailabilityItem: "[data-test-id*='channel-availability-item']", - addVariantsButton: "[data-test-id*='button-add-variant']", - addVariantsOptionDialog: { - optionMultiple: '[data-test-id="variant-create-option-multiple"]', - optionSingle: '[data-test-id="variant-create-option-single"]' - }, + addVariantButton: "[data-test-id*='button-add-variant']", descriptionInput: "[data-test-id='rich-text-editor-description']", ratingInput: "[name='rating']", skuInput: "[name='sku']", @@ -24,10 +20,9 @@ export const PRODUCT_DETAILS = { stockInput: '[data-test-id="stock-input"]', costPriceInput: '[name*="costPrice"]', sellingPriceInput: '[name*="channel-price"]', - createSingleVariantCheckbox: '[value="single"]', productImage: '[data-test-id="product-image"]', uploadImageButton: '[data-test-id="button-upload-image"]', uploadSavedImagesButton: '[data-test-id="upload-images"]', uploadMediaUrlButton: '[data-test-id="upload-media-url"]', - saveUploadUrlButton: '[data-test-id="upload-url-button"]' + saveUploadUrlButton: '[data-test-id="upload-url-button"]', }; diff --git a/cypress/elements/catalog/products/variants-selectors.js b/cypress/elements/catalog/products/variants-selectors.js index e490fd803..6082a6c8a 100644 --- a/cypress/elements/catalog/products/variants-selectors.js +++ b/cypress/elements/catalog/products/variants-selectors.js @@ -1,8 +1,4 @@ export const VARIANTS_SELECTORS = { - attributeCheckbox: "[name*='value:']", - valueContainer: "[data-test-id='value-container']", - nextButton: "[class*='MuiButton-containedPrimary']", - warehouseCheckboxes: "[name*='warehouse:']", skuInput: "[ name='sku']", attributeOption: "[data-test-type='option'], [data-test-id='multi-autocomplete-select-option']", @@ -20,5 +16,5 @@ export const VARIANTS_SELECTORS = { preorderEndTimeInput: "[name='preorderEndDateTime:time']", globalThresholdInput: "[name='globalThreshold']", stockInput: "[data-test-id='stock-input']", - selectOption: "[data-test-id='multi-autocomplete-select-option']" + selectOption: "[data-test-id='multi-autocomplete-select-option']", }; diff --git a/cypress/support/pages/catalog/products/VariantsPage.js b/cypress/support/pages/catalog/products/VariantsPage.js index 4a0568b0d..3d14de19f 100644 --- a/cypress/support/pages/catalog/products/VariantsPage.js +++ b/cypress/support/pages/catalog/products/VariantsPage.js @@ -3,56 +3,14 @@ import { PRODUCT_DETAILS } from "../../../../elements/catalog/products/product-d import { VARIANTS_SELECTORS } from "../../../../elements/catalog/products/variants-selectors"; import { AVAILABLE_CHANNELS_FORM } from "../../../../elements/channels/available-channels-form"; import { BUTTON_SELECTORS } from "../../../../elements/shared/button-selectors"; -import { SHARED_ELEMENTS } from "../../../../elements/shared/sharedElements"; import { formatDate } from "../../../formatData/formatDate"; import { selectChannelVariantInDetailsPage } from "../../channelsPage"; -import { fillUpPriceList } from "./priceListComponent"; export function variantsShouldBeVisible({ price }) { cy.get(PRODUCT_DETAILS.variantRow).should("be.visible"); cy.contains(PRODUCT_DETAILS.variantPrice, price); } -export function createFirstVariant({ - sku, - warehouseId, - price, - attribute, - quantity = 1 -}) { - cy.get(PRODUCT_DETAILS.addVariantsButton).click(); - cy.get(PRODUCT_DETAILS.addVariantsOptionDialog.optionMultiple).click(); - cy.get(BUTTON_SELECTORS.submit).click(); - cy.get(VARIANTS_SELECTORS.valueContainer).click(); - cy.contains(VARIANTS_SELECTORS.selectOption, attribute) - .click() - .get(VARIANTS_SELECTORS.nextButton) - .click(); - fillUpPriceList(price); - if (warehouseId) { - cy.get(`[name*='${warehouseId}']`).click(); - } else { - cy.get(VARIANTS_SELECTORS.warehouseCheckboxes) - .first() - .click(); - } - cy.get(VARIANTS_SELECTORS.stockInput) - .type(quantity) - .get(VARIANTS_SELECTORS.nextButton) - .click(); - if (sku) { - cy.get(VARIANTS_SELECTORS.skuInput).type(sku); - } - cy.addAliasToGraphRequest("ProductVariantBulkCreate") - .get(VARIANTS_SELECTORS.nextButton) - .click() - .confirmationMessageShouldAppear() - .waitForRequestAndCheckIfNoErrors("@ProductVariantBulkCreate") - .waitForProgressBarToNotBeVisible() - .get(AVAILABLE_CHANNELS_FORM.menageChannelsButton) - .should("be.visible"); -} - export function createVariant({ sku, warehouseName, @@ -60,9 +18,9 @@ export function createVariant({ price, costPrice = price, channelName, - quantity = 10 + quantity = 10, }) { - cy.get(PRODUCT_DETAILS.addVariantsButton).click(); + cy.get(PRODUCT_DETAILS.addVariantButton).click(); fillUpVariantDetails({ attributeName, sku, warehouseName, quantity }); cy.get(VARIANTS_SELECTORS.saveButton) .click() @@ -76,7 +34,7 @@ export function createVariant({ channelName, variantName: attributeName, price, - costPrice + costPrice, }); } @@ -84,13 +42,13 @@ export function fillUpGeneralVariantInputs({ attributeName, warehouseName, sku, - quantity + quantity, }) { fillUpVariantAttributeAndSku({ attributeName, sku }); cy.get(VARIANTS_SELECTORS.addWarehouseButton).click(); if (warehouseName) { cy.contains(VARIANTS_SELECTORS.warehouseOption, warehouseName).click({ - force: true + force: true, }); } else { cy.get(VARIANTS_SELECTORS.warehouseOption) @@ -105,7 +63,7 @@ export function fillUpVariantDetails({ attributeType = "DROPDOWN", sku, warehouseName, - quantity + quantity, }) { selectAttributeWithType({ attributeType, attributeName }); if (sku) { @@ -115,7 +73,7 @@ export function fillUpVariantDetails({ cy.get(VARIANTS_SELECTORS.addWarehouseButton).click(); cy.contains(VARIANTS_SELECTORS.warehouseOption, warehouseName) .click({ - force: true + force: true, }) .get(VARIANTS_SELECTORS.stockInput) .type(quantity); @@ -138,10 +96,10 @@ export function selectChannelForVariantAndFillUpPrices({ channelName, variantName, price, - costPrice = price + costPrice = price, }) { cy.waitForProgressBarToNotBeVisible().addAliasToGraphRequest( - "ProductChannelListingUpdate" + "ProductChannelListingUpdate", ); selectChannelVariantInDetailsPage(channelName, variantName); cy.get(BUTTON_SELECTORS.confirm) @@ -150,9 +108,13 @@ export function selectChannelForVariantAndFillUpPrices({ cy.contains(PRODUCT_DETAILS.variantRow, variantName) .click() .get(PRICE_LIST.priceInput) - .type(price) + .each(input => { + cy.wrap(input).type(price); + }) .get(PRICE_LIST.costPriceInput) - .type(costPrice) + .each(input => { + cy.wrap(input).type(costPrice); + }) .addAliasToGraphRequest("ProductVariantChannelListingUpdate") .get(VARIANTS_SELECTORS.saveButton) .click() diff --git a/cypress/support/pages/channelsPage.js b/cypress/support/pages/channelsPage.js index fc430bb08..387a0dc79 100644 --- a/cypress/support/pages/channelsPage.js +++ b/cypress/support/pages/channelsPage.js @@ -108,13 +108,18 @@ export function selectChannelInDetailsPages(channelName) { export function selectChannelVariantInDetailsPage(channelName, attributeName) { cy.get(AVAILABLE_CHANNELS_FORM.menageChannelsButton).click(); - cy.contains(SELECT_CHANNELS_TO_ASSIGN.expandChannelRow, channelName) - .find(BUTTON_SELECTORS.expandIcon) - .click(); - cy.contains(SELECT_CHANNELS_TO_ASSIGN.expandChannelRow, channelName) - .contains(SELECT_CHANNELS_TO_ASSIGN.channelVariantRow, attributeName) - .find(BUTTON_SELECTORS.checkbox) - .click(); + const channelsNames = Array.isArray(channelName) + ? channelName + : [channelName]; + channelsNames.forEach(name => { + cy.contains(SELECT_CHANNELS_TO_ASSIGN.expandChannelRow, name) + .find(BUTTON_SELECTORS.expandIcon) + .click(); + cy.contains(SELECT_CHANNELS_TO_ASSIGN.expandChannelRow, name) + .contains(SELECT_CHANNELS_TO_ASSIGN.channelVariantRow, attributeName) + .find(BUTTON_SELECTORS.checkbox) + .click(); + }); cy.get(SELECT_CHANNELS_TO_ASSIGN.selectChannelsForm) .find(BUTTON_SELECTORS.submit) .click({ force: true }); diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json index 2c5b1f8bc..4981c4c08 100644 --- a/locale/defaultMessages.json +++ b/locale/defaultMessages.json @@ -66,10 +66,6 @@ "+a+2ug": { "string": "Members" }, - "+bFHzi": { - "context": "button", - "string": "Next" - }, "+c/f61": { "context": "retry installation", "string": "Retry" @@ -185,9 +181,6 @@ "context": "section header", "string": "Media" }, - "/Qb92c": { - "string": "Based on your selections we will create {numberOfProducts} products. Use this step to customize price and stocks for your new products" - }, "/TF6BZ": { "string": "Search Products" }, @@ -1154,10 +1147,6 @@ "context": "checkbox gift cards label", "string": "Automatically fulfill non shippable gift cards" }, - "7WEC+G": { - "context": "page title", - "string": "Price and SKUs" - }, "7WzUxn": { "context": "staff member status", "string": "Inactive" @@ -1322,10 +1311,6 @@ "context": "modal button images upload", "string": "Upload Images" }, - "9EMudJ": { - "context": "option", - "string": "Create single variant" - }, "9IWg/f": { "context": "button", "string": "SETUP END DATE" @@ -1445,10 +1430,6 @@ "context": "area units type", "string": "Area" }, - "ABgQcF": { - "context": "variant stock, header", - "string": "Stock" - }, "ADTNND": { "context": "product type", "string": "Physical" @@ -1596,9 +1577,6 @@ "context": "number of subcategories", "string": "Subcategories" }, - "BIqhVQ": { - "string": "Skip stock for now" - }, "BL/Lbk": { "context": "install app permissions", "string": "Installing this app will give it following permissions:" @@ -1796,9 +1774,6 @@ "context": "button", "string": "Create Category" }, - "ClFzoD": { - "string": "Selected values will be used to create variants for the configurable product." - }, "ClKKID": { "context": "channel publication status", "string": "Not published" @@ -1806,10 +1781,6 @@ "Co2U4u": { "string": "No plugins found" }, - "CrbI/c": { - "context": "variant channel price", - "string": "{channel} Price" - }, "CxfKLC": { "string": "Pages" }, @@ -1970,9 +1941,6 @@ "EEW+ND": { "string": "Navigator" }, - "EGG8f+": { - "string": "Apply unique prices by attribute to each SKU" - }, "EHsnZX": { "context": "dialog description", "string": "Are you sure you want to approve this fullfillment?" @@ -2062,10 +2030,6 @@ "Ev6SEF": { "string": "New Password" }, - "EzU7KV": { - "context": "option description", - "string": "Create new variant using variant details view" - }, "F0AXNs": { "context": "invoice create date prefix", "string": "created" @@ -2279,10 +2243,6 @@ "GOdq5V": { "string": "Catalog" }, - "GQcp83": { - "context": "variant stock, header", - "string": "Stock and Warehousing" - }, "GUlwXU": { "context": "dialog header", "string": "Assign Attribute Value" @@ -2346,10 +2306,6 @@ "context": "link", "string": "Get Support" }, - "Gjo89T": { - "context": "header", - "string": "Warehouses" - }, "Gkip05": { "context": "button", "string": "Unassign" @@ -2469,10 +2425,6 @@ "context": "table column header, sold units preorder quantity", "string": "Sold units" }, - "HcjV6k": { - "context": "button", - "string": "Create variants" - }, "HedXnw": { "context": "plugin channel availability status title", "string": "{activeChannelsCount,plural, =0 {Deactivated} other {Active in {activeChannelsCount}}}" @@ -2659,9 +2611,6 @@ "J/QqOI": { "string": "This value already exists within this attribute" }, - "J0UdxG": { - "string": "Skip pricing for now" - }, "J0lNnk": { "context": "column label", "string": "Warehouse" @@ -2953,9 +2902,6 @@ "context": "returned products list title", "string": "Products returned" }, - "L5rthO": { - "string": "Apply unique stock by attribute to each SKU" - }, "L6+p8a": { "context": "dialog title", "string": "Delete permission group" @@ -3235,10 +3181,6 @@ "NWxomz": { "string": "Fulfillment status" }, - "NXpFlL": { - "context": "product attribute values, page title", - "string": "Choose Values" - }, "NZtcLb": { "context": "gift card bulk create success dialog content", "string": "We have issued all of your requested gift cards. You can download the list of new gift cards using the button below." @@ -3375,10 +3317,6 @@ "context": "Types", "string": "Page Types" }, - "OgFBAj": { - "context": "input label", - "string": "Price" - }, "OhFGpX": { "context": "button", "string": "Assign members" @@ -3566,10 +3504,6 @@ "context": "modal button url upload", "string": "Upload URL" }, - "Q3j++G": { - "context": "create multiple variants, button", - "string": "Create" - }, "Q47ovw": { "context": "activate app", "string": "Are you sure you want to activate this app? Activating will start gathering events." @@ -3846,10 +3780,6 @@ "context": "default gift card delete description", "string": "{selectedItemsCount,plural,one{Are you sure you want to delete this gift card?} other{Are you sure you want to delete {selectedItemsCount} giftCards?}}" }, - "S5PVx1": { - "context": "variant creator summary card header", - "string": "Created Variants" - }, "S7Rwl0": { "context": "stock exceeded action question label", "string": "Are you sure you want to fulfill those products anyway?" @@ -3900,9 +3830,6 @@ "context": "change button label", "string": "Change" }, - "STp3Hl": { - "string": "Apply single stock to all SKUs" - }, "SUbxSK": { "context": "product weight", "string": "Weight" @@ -3943,10 +3870,6 @@ "context": "checkbox label, fulfillment approval", "string": "Send shipment details to customer" }, - "Sx7QVu": { - "context": "variant creation step", - "string": "Prices and SKU" - }, "T/5OyA": { "string": "No translation yet" }, @@ -3988,10 +3911,6 @@ "context": "order history message", "string": "Payment failed" }, - "TDXskW": { - "context": "variant attribute", - "string": "Select Attribute" - }, "TDhHMi": { "string": "This needs to be unique" }, @@ -4016,10 +3935,6 @@ "context": "button", "string": "Reset" }, - "TPCRKr": { - "context": "variant price, header", - "string": "Price" - }, "TPW2tP": { "string": "You have reached your order limit, you will be billed extra for orders above limit. If you would like to up your limit, contact your administration staff about raising your limits." }, @@ -4266,10 +4181,6 @@ "context": "dialog content", "string": "Removed sale" }, - "V76IV7": { - "context": "variant name", - "string": "Variant" - }, "V8FhTt": { "context": "collection label", "string": "Hidden" @@ -4390,10 +4301,6 @@ "context": "staff member full name", "string": "Name" }, - "W3JbSQ": { - "context": "create product variants", - "string": "How would you like to create variants:" - }, "W5SK5c": { "string": "Select content type" }, @@ -4576,10 +4483,6 @@ "context": "discount type", "string": "Fixed amount" }, - "XDeh5D": { - "context": "dialog header", - "string": "Create Variants" - }, "XFtKV5": { "context": "input placeholder tag", "string": "Tag" @@ -4663,9 +4566,6 @@ "context": "product pricing, section header", "string": "Pricing" }, - "Xr5zxu": { - "string": "You choices will add {variantsNumber} SKUs to your catalog which will exceed your limit by {aboveLimitVariantsNumber}. If you would like to up your limit, contact your administration staff about raising your limits." - }, "Xtd0AT": { "string": "Original String" }, @@ -5447,10 +5347,6 @@ "context": "filters error messages dependencies missing", "string": "Filter requires other filters: {dependencies}" }, - "esg2wu": { - "context": "previous step, button", - "string": "Previous" - }, "etP0+D": { "string": "Vouchers" }, @@ -5591,10 +5487,6 @@ "g/BrOt": { "string": "Url has invalid format" }, - "g1WQlC": { - "context": "page title", - "string": "Summary" - }, "g3qjSf": { "context": "button", "string": "Assign categories" @@ -5863,9 +5755,6 @@ "context": "customer", "string": "Join Date" }, - "iigydN": { - "string": "Based on your selections we will create 8 products. Use this step to customize price and stocks for your new products." - }, "ij7olm": { "context": "error message", "string": "This fulfillment cannot be cancelled" @@ -6209,10 +6098,6 @@ "context": "dialog title", "string": "Unassign users" }, - "lVZ5n7": { - "context": "variant attribute", - "string": "Attribute" - }, "lVwmf5": { "context": "total price of ordered products", "string": "Total" @@ -6261,9 +6146,6 @@ "lqIzC8": { "string": "This field needs to be unique" }, - "lra7Ej": { - "string": "Apply single price to all SKUs" - }, "lrq8O6": { "context": "order refund amount, input label", "string": "Amount" @@ -6540,18 +6422,10 @@ "context": "order status", "string": "Unfulfilled" }, - "oChkS4": { - "context": "success message", - "string": "Successfully created variants" - }, "oHbgcK": { "context": "PageTypeDeleteWarningDialog title", "string": "Delete page {selectedTypesCount,plural,one{type} other{types}}" }, - "oIMMcO": { - "context": "no warehouses info", - "string": "There are no warehouses set up for your store. You can configure variants without providing stock quantities." - }, "oIvtua": { "context": "attribute's editor component", "string": "Catalog Input type for Store Owner" @@ -6864,9 +6738,6 @@ "context": "invalid date in expirydate field content", "string": "Gift Card with past expiration date cannot be created" }, - "rHXF43": { - "string": "Here is the summary of variants that will be created. You can change prices, stocks an SKU for each one created." - }, "rHoRbE": { "context": "Status label when object is unpublished in a channel", "string": "Unpublished" @@ -6898,10 +6769,6 @@ "context": "page header with order number", "string": "Order #{orderNumber}" }, - "rVaB7c": { - "context": "attribute values, variant creation step", - "string": "Select Values" - }, "rZMT44": { "context": "created channels counter", "string": "{count}/{max} channels used" @@ -7098,10 +6965,6 @@ "context": "button", "string": "Accept" }, - "slKV5G": { - "context": "variant creation step", - "string": "Summary" - }, "sn2awN": { "context": "ExitFormPrompt cancel button", "string": "Discard changes" @@ -7316,10 +7179,6 @@ "context": "order history message", "string": "Order was confirmed" }, - "ucYPtV": { - "context": "variant attribute", - "string": "Choose attribute" - }, "ud0w8h": { "context": "number of postal code ranges", "string": "{number} postal code ranges" @@ -7364,10 +7223,6 @@ "context": "button", "string": "Assign attribute" }, - "uxZZXx": { - "context": "option", - "string": "Create multiple variant via variant creator" - }, "uy+tB8": { "context": "voucher status", "string": "Status" @@ -7459,10 +7314,6 @@ "context": "card title", "string": "Order Weight" }, - "vXA5xU": { - "context": "option description", - "string": "Use variant creator to create matrix of selected attribute values to create variants" - }, "vXFPD6": { "context": "voucher discount type", "string": "Fixed Amount" @@ -7514,9 +7365,6 @@ "context": "button", "string": "Create category" }, - "vuKrlW": { - "string": "Stock" - }, "vwMO04": { "context": "draft order", "string": "Created" @@ -7860,10 +7708,6 @@ "context": "header, dialog", "string": "Create New Warehouse" }, - "z+wMgQ": { - "context": "window title", - "string": "Create Variants" - }, "z0gGP+": { "context": "number of attributes", "string": "{number} Attributes" diff --git a/src/components/Attributes/SwatchRow.tsx b/src/components/Attributes/SwatchRow.tsx index 1d7dd9c4a..af095fb6f 100644 --- a/src/components/Attributes/SwatchRow.tsx +++ b/src/components/Attributes/SwatchRow.tsx @@ -6,7 +6,7 @@ import { getSingleDisplayValue, } from "@saleor/components/Attributes/utils"; import SingleAutocompleteSelectField from "@saleor/components/SingleAutocompleteSelectField"; -import { getBySlug } from "@saleor/products/components/ProductVariantCreatorPage/utils"; +import { getBySlug } from "@saleor/misc"; import React from "react"; import { useIntl } from "react-intl"; diff --git a/src/giftCards/GiftCardUpdate/GiftCardResendCodeDialog/GiftCardResendCodeDialog.tsx b/src/giftCards/GiftCardUpdate/GiftCardResendCodeDialog/GiftCardResendCodeDialog.tsx index e629a19b9..b4d569e9c 100644 --- a/src/giftCards/GiftCardUpdate/GiftCardResendCodeDialog/GiftCardResendCodeDialog.tsx +++ b/src/giftCards/GiftCardUpdate/GiftCardResendCodeDialog/GiftCardResendCodeDialog.tsx @@ -8,7 +8,7 @@ import SingleAutocompleteSelectField from "@saleor/components/SingleAutocomplete import { useChannelsQuery, useGiftCardResendMutation } from "@saleor/graphql"; import useForm from "@saleor/hooks/useForm"; import useNotifier from "@saleor/hooks/useNotifier"; -import { getBySlug } from "@saleor/products/components/ProductVariantCreatorPage/utils"; +import { getBySlug } from "@saleor/misc"; import { DialogProps } from "@saleor/types"; import commonErrorMessages from "@saleor/utils/errors/common"; import { mapSlugNodeToChoice } from "@saleor/utils/maps"; diff --git a/src/graphql/hooks.generated.ts b/src/graphql/hooks.generated.ts index e5cd0d1a8..2b444da31 100644 --- a/src/graphql/hooks.generated.ts +++ b/src/graphql/hooks.generated.ts @@ -11758,42 +11758,6 @@ export function useProductBulkDeleteMutation(baseOptions?: ApolloReactHooks.Muta export type ProductBulkDeleteMutationHookResult = ReturnType; export type ProductBulkDeleteMutationResult = Apollo.MutationResult; export type ProductBulkDeleteMutationOptions = Apollo.BaseMutationOptions; -export const ProductVariantBulkCreateDocument = gql` - mutation ProductVariantBulkCreate($id: ID!, $inputs: [ProductVariantBulkCreateInput!]!) { - productVariantBulkCreate(product: $id, variants: $inputs) { - errors { - ...BulkProductError - } - } -} - ${BulkProductErrorFragmentDoc}`; -export type ProductVariantBulkCreateMutationFn = Apollo.MutationFunction; - -/** - * __useProductVariantBulkCreateMutation__ - * - * To run a mutation, you first call `useProductVariantBulkCreateMutation` within a React component and pass it any options that fit your needs. - * When your component renders, `useProductVariantBulkCreateMutation` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [productVariantBulkCreateMutation, { data, loading, error }] = useProductVariantBulkCreateMutation({ - * variables: { - * id: // value for 'id' - * inputs: // value for 'inputs' - * }, - * }); - */ -export function useProductVariantBulkCreateMutation(baseOptions?: ApolloReactHooks.MutationHookOptions) { - const options = {...defaultOptions, ...baseOptions} - return ApolloReactHooks.useMutation(ProductVariantBulkCreateDocument, options); - } -export type ProductVariantBulkCreateMutationHookResult = ReturnType; -export type ProductVariantBulkCreateMutationResult = Apollo.MutationResult; -export type ProductVariantBulkCreateMutationOptions = Apollo.BaseMutationOptions; export const ProductVariantBulkDeleteDocument = gql` mutation ProductVariantBulkDelete($ids: [ID!]!) { productVariantBulkDelete(ids: $ids) { @@ -12633,53 +12597,6 @@ export function useGridAttributesLazyQuery(baseOptions?: ApolloReactHooks.LazyQu export type GridAttributesQueryHookResult = ReturnType; export type GridAttributesLazyQueryHookResult = ReturnType; export type GridAttributesQueryResult = Apollo.QueryResult; -export const CreateMultipleVariantsDataDocument = gql` - query CreateMultipleVariantsData($id: ID!, $firstValues: Int, $afterValues: String, $lastValues: Int, $beforeValues: String) { - product(id: $id) { - ...ProductVariantAttributes - } - warehouses(first: 20) { - edges { - node { - ...Warehouse - } - } - } -} - ${ProductVariantAttributesFragmentDoc} -${WarehouseFragmentDoc}`; - -/** - * __useCreateMultipleVariantsDataQuery__ - * - * To run a query within a React component, call `useCreateMultipleVariantsDataQuery` and pass it any options that fit your needs. - * When your component renders, `useCreateMultipleVariantsDataQuery` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useCreateMultipleVariantsDataQuery({ - * variables: { - * id: // value for 'id' - * firstValues: // value for 'firstValues' - * afterValues: // value for 'afterValues' - * lastValues: // value for 'lastValues' - * beforeValues: // value for 'beforeValues' - * }, - * }); - */ -export function useCreateMultipleVariantsDataQuery(baseOptions: ApolloReactHooks.QueryHookOptions) { - const options = {...defaultOptions, ...baseOptions} - return ApolloReactHooks.useQuery(CreateMultipleVariantsDataDocument, options); - } -export function useCreateMultipleVariantsDataLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptions) { - const options = {...defaultOptions, ...baseOptions} - return ApolloReactHooks.useLazyQuery(CreateMultipleVariantsDataDocument, options); - } -export type CreateMultipleVariantsDataQueryHookResult = ReturnType; -export type CreateMultipleVariantsDataLazyQueryHookResult = ReturnType; -export type CreateMultipleVariantsDataQueryResult = Apollo.QueryResult; export const SearchAttributesDocument = gql` query SearchAttributes($after: String, $first: Int!, $query: String!) { search: attributes(after: $after, first: $first, filter: {search: $query}) { diff --git a/src/graphql/types.generated.ts b/src/graphql/types.generated.ts index 4b43a3d47..6d60cf9db 100644 --- a/src/graphql/types.generated.ts +++ b/src/graphql/types.generated.ts @@ -7690,14 +7690,6 @@ export type ProductBulkDeleteMutationVariables = Exact<{ export type ProductBulkDeleteMutation = { __typename: 'Mutation', productBulkDelete: { __typename: 'ProductBulkDelete', errors: Array<{ __typename: 'ProductError', code: ProductErrorCode, field: string | null, message: string | null }> } | null }; -export type ProductVariantBulkCreateMutationVariables = Exact<{ - id: Scalars['ID']; - inputs: Array | ProductVariantBulkCreateInput; -}>; - - -export type ProductVariantBulkCreateMutation = { __typename: 'Mutation', productVariantBulkCreate: { __typename: 'ProductVariantBulkCreate', errors: Array<{ __typename: 'BulkProductError', field: string | null, code: ProductErrorCode, index: number | null, channels: Array | null, message: string | null }> } | null }; - export type ProductVariantBulkDeleteMutationVariables = Exact<{ ids: Array | Scalars['ID']; }>; @@ -7852,17 +7844,6 @@ export type GridAttributesQueryVariables = Exact<{ export type GridAttributesQuery = { __typename: 'Query', grid: { __typename: 'AttributeCountableConnection', edges: Array<{ __typename: 'AttributeCountableEdge', node: { __typename: 'Attribute', id: string, name: string | null } }> } | null }; -export type CreateMultipleVariantsDataQueryVariables = Exact<{ - id: Scalars['ID']; - firstValues?: InputMaybe; - afterValues?: InputMaybe; - lastValues?: InputMaybe; - beforeValues?: InputMaybe; -}>; - - -export type CreateMultipleVariantsDataQuery = { __typename: 'Query', product: { __typename: 'Product', id: string, attributes: Array<{ __typename: 'SelectedAttribute', attribute: { __typename: 'Attribute', id: string, slug: string | null, name: string | null, inputType: AttributeInputTypeEnum | null, entityType: AttributeEntityTypeEnum | null, valueRequired: boolean, unit: MeasurementUnitsEnum | null, choices: { __typename: 'AttributeValueCountableConnection', pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null }, edges: Array<{ __typename: 'AttributeValueCountableEdge', cursor: string, node: { __typename: 'AttributeValue', plainText: string | null, richText: any | null, id: string, name: string | null, slug: string | null, reference: string | null, boolean: boolean | null, date: any | null, dateTime: any | null, value: string | null, file: { __typename: 'File', url: string, contentType: string | null } | null } }> } | null }, values: Array<{ __typename: 'AttributeValue', plainText: string | null, richText: any | null, id: string, name: string | null, slug: string | null, reference: string | null, boolean: boolean | null, date: any | null, dateTime: any | null, value: string | null, file: { __typename: 'File', url: string, contentType: string | null } | null }> }>, productType: { __typename: 'ProductType', id: string, variantAttributes: Array<{ __typename: 'Attribute', id: string, name: string | null, inputType: AttributeInputTypeEnum | null, valueRequired: boolean, unit: MeasurementUnitsEnum | null, choices: { __typename: 'AttributeValueCountableConnection', pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null }, edges: Array<{ __typename: 'AttributeValueCountableEdge', cursor: string, node: { __typename: 'AttributeValue', plainText: string | null, richText: any | null, id: string, name: string | null, slug: string | null, reference: string | null, boolean: boolean | null, date: any | null, dateTime: any | null, value: string | null, file: { __typename: 'File', url: string, contentType: string | null } | null } }> } | null }> | null }, channelListings: Array<{ __typename: 'ProductChannelListing', channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } | null, warehouses: { __typename: 'WarehouseCountableConnection', edges: Array<{ __typename: 'WarehouseCountableEdge', node: { __typename: 'Warehouse', id: string, name: string } }> } | null }; - export type SearchAttributesQueryVariables = Exact<{ after?: InputMaybe; first: Scalars['Int']; diff --git a/src/misc.ts b/src/misc.ts index 59d1dfd90..5cd4102f8 100644 --- a/src/misc.ts +++ b/src/misc.ts @@ -531,3 +531,6 @@ export const isInDevelopment = export type WithOptional = Omit & Partial>; + +export const getBySlug = (slugToCompare: string) => (obj: { slug: string }) => + obj.slug === slugToCompare; diff --git a/src/products/components/ProductUpdatePage/ProductUpdatePage.test.tsx b/src/products/components/ProductUpdatePage/ProductUpdatePage.test.tsx index f1581f9bd..8956cd83b 100644 --- a/src/products/components/ProductUpdatePage/ProductUpdatePage.test.tsx +++ b/src/products/components/ProductUpdatePage/ProductUpdatePage.test.tsx @@ -73,7 +73,6 @@ const props: ProductUpdatePageProps = { onSetDefaultVariant: () => undefined, onSubmit, onVariantReorder: () => undefined, - onVariantsAdd: () => undefined, onVariantEndPreorderDialogOpen: () => undefined, onWarehouseConfigure: () => undefined, openChannelsModal: () => undefined, diff --git a/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx b/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx index 721310300..893498684 100644 --- a/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx +++ b/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx @@ -114,7 +114,6 @@ export interface ProductUpdatePageProps extends ListActions, ChannelProps { fetchAttributeValues: (query: string, attributeId: string) => void; onAssignReferencesClick: (attribute: AttributeInput) => void; onCloseDialog: () => void; - onVariantsAdd: () => void; onVariantReorder: ReorderAction; onVariantEndPreorderDialogOpen: () => void; onImageDelete: (id: string) => () => void; @@ -177,7 +176,6 @@ export const ProductUpdatePage: React.FC = ({ onSeoClick, onSubmit, channelsData, - onVariantsAdd, onSetDefaultVariant, onVariantReorder, onVariantEndPreorderDialogOpen, @@ -389,7 +387,6 @@ export const ProductUpdatePage: React.FC = ({ limits={limits} variants={variants} product={product} - onVariantsAdd={onVariantsAdd} onVariantReorder={onVariantReorder} onSetDefaultVariant={onSetDefaultVariant} toolbar={toolbar} diff --git a/src/products/components/ProductVariantCreateDialog/ProductVariantCreateDialog.tsx b/src/products/components/ProductVariantCreateDialog/ProductVariantCreateDialog.tsx deleted file mode 100644 index f0229cb9a..000000000 --- a/src/products/components/ProductVariantCreateDialog/ProductVariantCreateDialog.tsx +++ /dev/null @@ -1,107 +0,0 @@ -import { - Dialog, - DialogActions, - DialogContent, - DialogTitle, - Typography, -} from "@material-ui/core"; -import ConfirmButton from "@saleor/components/ConfirmButton"; -import Form from "@saleor/components/Form"; -import FormSpacer from "@saleor/components/FormSpacer"; -import RadioGroupField from "@saleor/components/RadioGroupField"; -import { buttonMessages } from "@saleor/intl"; -import React from "react"; -import { FormattedMessage } from "react-intl"; - -import { messages } from "./messages"; -import { useStyles } from "./styles"; -import { ProductVariantCreateOptionEnum } from "./types"; - -interface ProductVariantCreateDialogForm { - option: ProductVariantCreateOptionEnum; -} - -export interface ProductVariantCreateDialogProps { - open: boolean; - onClose: () => void; - onConfirm: (option: ProductVariantCreateOptionEnum) => void; -} - -const ProductVariantCreateDialog: React.FC = props => { - const { open, onConfirm, onClose } = props; - - const classes = useStyles(props); - - const initialForm = { - option: ProductVariantCreateOptionEnum.MULTIPLE, - }; - - const handleSubmit = (form: ProductVariantCreateDialogForm) => { - onConfirm(form.option); - }; - - const options = [ - { - title: messages.optionMultipleTitle, - subtitle: messages.optionMultipleDescription, - type: ProductVariantCreateOptionEnum.MULTIPLE, - }, - { - title: messages.optionSingleTitle, - subtitle: messages.optionSingleDescription, - type: ProductVariantCreateOptionEnum.SINGLE, - }, - ]; - - return ( - -
- {({ change, data }) => ( - <> - - - - - - - - - ({ - label: ( -
- - - - - - -
- ), - value: option.type, - }))} - name="option" - value={data.option} - onChange={change} - /> -
- - - - - - - )} -
-
- ); -}; -ProductVariantCreateDialog.displayName = "ProductVariantCreateDialog"; -export default ProductVariantCreateDialog; diff --git a/src/products/components/ProductVariantCreateDialog/index.ts b/src/products/components/ProductVariantCreateDialog/index.ts deleted file mode 100644 index 6f4e84eb6..000000000 --- a/src/products/components/ProductVariantCreateDialog/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./ProductVariantCreateDialog"; -export * from "./ProductVariantCreateDialog"; diff --git a/src/products/components/ProductVariantCreateDialog/messages.ts b/src/products/components/ProductVariantCreateDialog/messages.ts deleted file mode 100644 index 180374458..000000000 --- a/src/products/components/ProductVariantCreateDialog/messages.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { defineMessages } from "react-intl"; - -export const messages = defineMessages({ - title: { - id: "XDeh5D", - defaultMessage: "Create Variants", - description: "dialog header", - }, - description: { - id: "W3JbSQ", - defaultMessage: "How would you like to create variants:", - description: "create product variants", - }, - optionMultipleTitle: { - id: "uxZZXx", - defaultMessage: "Create multiple variant via variant creator", - description: "option", - }, - optionMultipleDescription: { - id: "vXA5xU", - defaultMessage: - "Use variant creator to create matrix of selected attribute values to create variants", - description: "option description", - }, - optionSingleTitle: { - id: "9EMudJ", - defaultMessage: "Create single variant", - description: "option", - }, - optionSingleDescription: { - id: "EzU7KV", - defaultMessage: "Create new variant using variant details view", - description: "option description", - }, -}); diff --git a/src/products/components/ProductVariantCreateDialog/styles.ts b/src/products/components/ProductVariantCreateDialog/styles.ts deleted file mode 100644 index 15b7fdbb9..000000000 --- a/src/products/components/ProductVariantCreateDialog/styles.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { makeStyles } from "@saleor/macaw-ui"; - -export const useStyles = makeStyles( - theme => ({ - option: { - marginBottom: theme.spacing(2), - width: 400, - }, - dialogContent: { - padding: 0, - }, - }), - { name: "ProductVariantCreateDialog" }, -); diff --git a/src/products/components/ProductVariantCreateDialog/types.ts b/src/products/components/ProductVariantCreateDialog/types.ts deleted file mode 100644 index 11d98b17a..000000000 --- a/src/products/components/ProductVariantCreateDialog/types.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum ProductVariantCreateOptionEnum { - MULTIPLE = "multiple", - SINGLE = "single", -} diff --git a/src/products/components/ProductVariantCreatorPage/ProductVariantCreator.stories.tsx b/src/products/components/ProductVariantCreatorPage/ProductVariantCreator.stories.tsx deleted file mode 100644 index 4b8c7d81c..000000000 --- a/src/products/components/ProductVariantCreatorPage/ProductVariantCreator.stories.tsx +++ /dev/null @@ -1,216 +0,0 @@ -import { attributes } from "@saleor/attributes/fixtures"; -import { productChannels } from "@saleor/channels/fixtures"; -import Container from "@saleor/components/Container"; -import { fetchMoreProps, limitsReached } from "@saleor/fixtures"; -import { BulkProductErrorFragment, ProductErrorCode } from "@saleor/graphql"; -import { warehouseList } from "@saleor/warehouses/fixtures"; -import { storiesOf } from "@storybook/react"; -import React from "react"; - -import Decorator from "../../../storybook/Decorator"; -import { createVariants } from "./createVariants"; -import { - ChannelPrice, - Price, - ProductVariantCreateFormData, - Stock, -} from "./form"; -import ProductVariantCreatorContent, { - ProductVariantCreatorContentProps, -} from "./ProductVariantCreatorContent"; -import ProductVariantCreatorPage from "./ProductVariantCreatorPage"; -import { ProductVariantCreatorStep } from "./types"; - -const selectedAttributes = [1, 4, 5].map(index => attributes[index]); -const selectedWarehouses = [0, 1, 3].map(index => warehouseList[index]); - -const channels: ChannelPrice[] = productChannels.map(channel => ({ - channelId: channel.channel.id, - price: channel.pricing?.priceRange?.start?.net.amount.toString(), -})); - -const price: Price = { - attribute: selectedAttributes[0].id, - channels, - mode: "attribute", - values: selectedAttributes[0].choices.edges.map(attribute => ({ - slug: attribute.node.slug, - value: channels, - })), -}; - -const stock: Stock = { - attribute: selectedAttributes[0].id, - mode: "attribute", - value: selectedWarehouses.map( - (_, warehouseIndex) => (warehouseIndex + 2) * 3, - ), - values: selectedAttributes[0].choices.edges.map( - (attribute, attributeIndex) => ({ - slug: attribute.node.slug, - value: selectedWarehouses.map( - (_, warehouseIndex) => - selectedAttributes.length * 10 - attributeIndex - warehouseIndex * 3, - ), - }), - ), -}; - -const dataAttributes = selectedAttributes.map(attribute => ({ - id: attribute.id, - valueRequired: attribute.valueRequired, - values: attribute.choices.edges - .map(value => ({ - slug: value.node.slug, - value: value.node, - })) - .filter((_, valueIndex) => valueIndex % 2 !== 1), -})); - -const errors: BulkProductErrorFragment[] = [ - { - __typename: "BulkProductError", - channels: [channels[0].channelId], - code: ProductErrorCode.UNIQUE, - field: "sku", - index: 3, - message: "Uniwue bulk product error", - }, -]; - -const data: ProductVariantCreateFormData = { - attributes: dataAttributes, - price, - stock, - variants: createVariants({ - attributes: dataAttributes, - price, - stock, - variants: [], - warehouses: selectedWarehouses.map(warehouse => warehouse.id), - }), - warehouses: selectedWarehouses.map(warehouse => warehouse.id), -}; -const props: ProductVariantCreatorContentProps = { - attributes: [0, 1, 4, 6].map(index => attributes[index]), - attributeValues: [], - fetchAttributeValues: () => undefined, - fetchMoreAttributeValues: fetchMoreProps, - channelListings: productChannels.map(listing => ({ - currency: listing.pricing?.priceRange?.start?.net.currency, - id: listing.channel.id, - name: listing.channel.name, - price: listing.pricing?.priceRange?.start?.net?.amount.toString() || "", - })), - data: { - ...data, - variants: createVariants(data), - }, - dispatchFormDataAction: () => undefined, - errors: [], - variantsLeft: 6, - step: ProductVariantCreatorStep.values, - warehouses: warehouseList, - onAttributeSelectBlur: () => undefined, -}; - -storiesOf("Views / Products / Create multiple variants", module) - .addDecorator(storyFn => {storyFn()}) - .addDecorator(Decorator) - .add("choose values", () => ); - -storiesOf( - "Views / Products / Create multiple variants / prices and SKUs", - module, -) - .addDecorator(storyFn => {storyFn()}) - .addDecorator(Decorator) - .add("apply to all", () => ( - - )) - .add("apply to all when one warehouse", () => ( - - )) - .add("apply to attribute", () => ( - - )) - .add("apply to attribute when one warehouse", () => ( - - )) - .add("ship when no warehouses", () => ( - - )); - -storiesOf("Views / Products / Create multiple variants / summary", module) - .addDecorator(storyFn => {storyFn()}) - .addDecorator(Decorator) - .add("default", () => ( - - )) - .add("errors", () => ( - - )); - -storiesOf("Views / Products / Create multiple variants", module) - .addDecorator(Decorator) - .add("interactive", () => ( - undefined} - /> - )); diff --git a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorContent.tsx b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorContent.tsx deleted file mode 100644 index cd24ce612..000000000 --- a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorContent.tsx +++ /dev/null @@ -1,217 +0,0 @@ -import { ChannelPriceData } from "@saleor/channels/utils"; -import { - BulkProductErrorFragment, - ProductVariantAttributesFragment, - SearchAttributeValuesQuery, - WarehouseFragment, -} from "@saleor/graphql"; -import { FetchMoreProps, RelayToFlat } from "@saleor/types"; -import { isSelected } from "@saleor/utils/lists"; -import React from "react"; - -import { ProductVariantCreateFormData } from "./form"; -import ProductVariantCreatorPriceAndSku from "./ProductVariantCreatorPriceAndSku"; -import ProductVariantCreatorSummary from "./ProductVariantCreatorSummary"; -import ProductVariantCreatorValues from "./ProductVariantCreatorValues"; -import { - ProductVariantCreateReducerAction, - ProductVariantCreateReducerActionType, -} from "./reducer"; -import { ProductVariantCreatorStep } from "./types"; - -export interface ProductVariantCreatorContentProps { - attributes: ProductVariantAttributesFragment["productType"]["variantAttributes"]; - attributeValues: RelayToFlat< - SearchAttributeValuesQuery["attribute"]["choices"] - >; - channelListings: ChannelPriceData[]; - data: ProductVariantCreateFormData; - dispatchFormDataAction: React.Dispatch; - errors: BulkProductErrorFragment[]; - step: ProductVariantCreatorStep; - variantsLeft: number | null; - warehouses: WarehouseFragment[]; - fetchAttributeValues: (query: string, attributeId: string) => void; - fetchMoreAttributeValues?: FetchMoreProps; - onAttributeSelectBlur: () => void; -} - -const ProductVariantCreatorContent: React.FC = ({ - attributes, - attributeValues, - fetchAttributeValues, - fetchMoreAttributeValues, - channelListings, - data, - dispatchFormDataAction, - errors, - step, - variantsLeft, - warehouses, - onAttributeSelectBlur, -}) => { - const selectedAttributes = attributes.filter(attribute => - isSelected( - attribute.id, - data.attributes.map(dataAttribute => dataAttribute.id), - (a, b) => a === b, - ), - ); - - return ( - <> - {step === ProductVariantCreatorStep.values && ( - - dispatchFormDataAction({ - selectValue: { - attributeId, - value, - }, - type: ProductVariantCreateReducerActionType.selectValue, - }) - } - onValueBlur={onAttributeSelectBlur} - /> - )} - {step === ProductVariantCreatorStep.prices && ( - - dispatchFormDataAction({ - applyPriceOrStockToAll: { - mode, - }, - type: - type === "price" - ? ProductVariantCreateReducerActionType.applyPriceToAll - : ProductVariantCreateReducerActionType.applyStockToAll, - }) - } - onApplyToAllPriceChange={(channelId, price) => - dispatchFormDataAction({ - changeApplyPriceToAllValue: { - channelId, - price, - }, - type: - ProductVariantCreateReducerActionType.changeApplyPriceToAllValue, - }) - } - onApplyToAllStockChange={(quantity, warehouseIndex) => - dispatchFormDataAction({ - changeApplyStockToAllValue: { - quantity, - warehouseIndex, - }, - type: - ProductVariantCreateReducerActionType.changeApplyStockToAllValue, - }) - } - onAttributeSelect={(attributeId, type) => - dispatchFormDataAction({ - changeApplyPriceOrStockToAttributeId: { - attributeId, - }, - type: - type === "price" - ? ProductVariantCreateReducerActionType.changeApplyPriceToAttributeId - : ProductVariantCreateReducerActionType.changeApplyStockToAttributeId, - }) - } - onAttributePriceChange={(valueId, price, channelId) => - dispatchFormDataAction({ - changeAttributeValuePrice: { - channelId, - price, - valueId, - }, - type: - ProductVariantCreateReducerActionType.changeAttributeValuePrice, - }) - } - onAttributeStockChange={(valueId, quantity, warehouseIndex) => - dispatchFormDataAction({ - changeAttributeValueStock: { - quantity, - valueId, - warehouseIndex, - }, - type: - ProductVariantCreateReducerActionType.changeAttributeValueStock, - }) - } - onWarehouseToggle={warehouseId => - dispatchFormDataAction({ - changeWarehouses: { - warehouseId, - }, - type: ProductVariantCreateReducerActionType.changeWarehouses, - }) - } - /> - )} - {step === ProductVariantCreatorStep.summary && ( - - dispatchFormDataAction({ - changeVariantSku: { - value, - variantIndex, - }, - type: ProductVariantCreateReducerActionType.changeVariantSku, - }) - } - onVariantPriceDataChange={(variantIndex, value) => - dispatchFormDataAction({ - changeVariantPriceData: { - value, - variantIndex, - }, - type: - ProductVariantCreateReducerActionType.changeVariantPriceData, - }) - } - onVariantStockDataChange={(variantIndex, warehouse, value) => - dispatchFormDataAction({ - changeVariantStockData: { - stock: { - quantity: parseInt(value, 10), - warehouse, - }, - variantIndex, - }, - type: - ProductVariantCreateReducerActionType.changeVariantStockData, - }) - } - onVariantDelete={variantIndex => - dispatchFormDataAction({ - deleteVariant: { - variantIndex, - }, - type: ProductVariantCreateReducerActionType.deleteVariant, - }) - } - warehouses={warehouses} - /> - )} - - ); -}; - -ProductVariantCreatorContent.displayName = "ProductVariantCreatorContent"; -export default ProductVariantCreatorContent; diff --git a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorPage.tsx b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorPage.tsx deleted file mode 100644 index b7fc5c692..000000000 --- a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorPage.tsx +++ /dev/null @@ -1,270 +0,0 @@ -import { Typography } from "@material-ui/core"; -import { Button } from "@saleor/components/Button"; -import Container from "@saleor/components/Container"; -import Hr from "@saleor/components/Hr"; -import PageHeader from "@saleor/components/PageHeader"; -import { - ProductVariantBulkCreateInput, - RefreshLimitsQuery, -} from "@saleor/graphql"; -import { SubmitPromise } from "@saleor/hooks/useForm"; -import useWizard from "@saleor/hooks/useWizard"; -import { makeStyles } from "@saleor/macaw-ui"; -import { validatePrice } from "@saleor/products/utils/validation"; -import React from "react"; -import { FormattedMessage, IntlShape, useIntl } from "react-intl"; - -import { createInitialForm, ProductVariantCreateFormData } from "./form"; -import ProductVariantCreatorContent, { - ProductVariantCreatorContentProps, -} from "./ProductVariantCreatorContent"; -import ProductVariantCreateTabs from "./ProductVariantCreatorTabs"; -import { getVariantsNumber } from "./ProductVariantCreatorValues"; -import reduceProductVariantCreateFormData, { - ProductVariantCreateReducerActionType, -} from "./reducer"; -import { ProductVariantCreatorStep } from "./types"; -import { dedupeListings } from "./utils"; - -const useStyles = makeStyles( - theme => ({ - button: { - marginLeft: theme.spacing(2), - }, - content: { - overflowX: "visible", - }, - description: { - marginTop: theme.spacing(), - }, - hr: { - margin: theme.spacing(3, 0), - }, - }), - { name: "ProductVariantCreatePage" }, -); - -function canHitNext( - step: ProductVariantCreatorStep, - data: ProductVariantCreateFormData, - variantsLeft: number | null, -): boolean { - switch (step) { - case ProductVariantCreatorStep.values: - return ( - data.attributes.every( - attribute => !attribute.valueRequired || attribute.values.length > 0, - ) && - (variantsLeft === null || getVariantsNumber(data) <= variantsLeft) - ); - case ProductVariantCreatorStep.prices: - if (data.price.mode === "all") { - if (data.price.channels.some(channel => validatePrice(channel.price))) { - return false; - } - } else if (data.price.mode === "attribute") { - if ( - !data.price.attribute || - data.price.values.some( - attribute => - attribute.value.length < data.price.channels.length || - attribute.value.some(channel => validatePrice(channel.price)), - ) - ) { - return false; - } - } - - if (data.stock.mode === "attribute" && data.stock.attribute === "") { - return false; - } - - return true; - case ProductVariantCreatorStep.summary: - return !data.variants.some(variant => - variant.channelListings.some(channel => validatePrice(channel.price)), - ); - - default: - return false; - } -} - -export interface ProductVariantCreatePageProps - extends Omit< - ProductVariantCreatorContentProps, - "data" | "dispatchFormDataAction" | "step" | "variantsLeft" | "onStepClick" - > { - limits: RefreshLimitsQuery["shop"]["limits"]; - onSubmit: (data: ProductVariantBulkCreateInput[]) => SubmitPromise; -} - -function getTitle(step: ProductVariantCreatorStep, intl: IntlShape): string { - switch (step) { - case ProductVariantCreatorStep.values: - return intl.formatMessage({ - id: "NXpFlL", - defaultMessage: "Choose Values", - description: "product attribute values, page title", - }); - case ProductVariantCreatorStep.prices: - return intl.formatMessage({ - id: "7WEC+G", - defaultMessage: "Price and SKUs", - description: "page title", - }); - case ProductVariantCreatorStep.summary: - return intl.formatMessage({ - id: "g1WQlC", - defaultMessage: "Summary", - description: "page title", - }); - } -} - -function getDescription( - step: ProductVariantCreatorStep, - intl: IntlShape, -): string { - switch (step) { - case ProductVariantCreatorStep.values: - return intl.formatMessage({ - id: "ClFzoD", - defaultMessage: - "Selected values will be used to create variants for the configurable product.", - }); - case ProductVariantCreatorStep.prices: - return intl.formatMessage({ - id: "iigydN", - defaultMessage: - "Based on your selections we will create 8 products. Use this step to customize price and stocks for your new products.", - }); - case ProductVariantCreatorStep.summary: - return intl.formatMessage({ - id: "rHXF43", - defaultMessage: - "Here is the summary of variants that will be created. You can change prices, stocks an SKU for each one created.", - }); - } -} - -const ProductVariantCreatePage: React.FC = props => { - const { - attributes, - channelListings, - errors, - limits, - onSubmit, - warehouses, - ...contentProps - } = props; - const classes = useStyles(props); - const intl = useIntl(); - const [wizardData, dispatchFormDataAction] = React.useReducer( - reduceProductVariantCreateFormData, - createInitialForm(attributes, channelListings, warehouses), - ); - const [step, { next: nextStep, prev: prevStep, set: setStep }] = useWizard< - ProductVariantCreatorStep - >( - ProductVariantCreatorStep.values, - [ - ProductVariantCreatorStep.values, - ProductVariantCreatorStep.prices, - ProductVariantCreatorStep.summary, - ], - { - onTransition: (_, nextStep) => { - if (nextStep === ProductVariantCreatorStep.summary) { - dispatchFormDataAction({ - type: ProductVariantCreateReducerActionType.rebuild, - }); - } - }, - }, - ); - const reloadForm = () => - dispatchFormDataAction({ - reload: { - data: createInitialForm(attributes, channelListings, warehouses), - }, - type: ProductVariantCreateReducerActionType.reload, - }); - - React.useEffect(reloadForm, [attributes.length, warehouses.length]); - - const variantsLeft = limits?.allowedUsage.productVariants - ? limits.allowedUsage.productVariants - limits.currentUsage.productVariants - : null; - - return ( - - - - {getTitle(step, intl)} - - {getDescription(step, intl)} - - - } - > - {step !== ProductVariantCreatorStep.values && ( - - )} - {step !== ProductVariantCreatorStep.summary ? ( - - ) : ( - - )} - -
-
- -
-
- ); -}; - -ProductVariantCreatePage.displayName = "ProductVariantCreatePage"; -export default ProductVariantCreatePage; diff --git a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorPriceAndSku.tsx b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorPriceAndSku.tsx deleted file mode 100644 index c217f83c2..000000000 --- a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorPriceAndSku.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import { ChannelPriceData } from "@saleor/channels/utils"; -import CardSpacer from "@saleor/components/CardSpacer"; -import { - ProductVariantAttributesFragment, - WarehouseFragment, -} from "@saleor/graphql"; -import React from "react"; - -import { - ProductVariantCreateFormData, - VariantCreatorPricesAndSkuMode, -} from "./form"; -import ProductVariantCreatorPrices from "./ProductVariantCreatorPrices"; -import ProductVariantCreatorStock from "./ProductVariantCreatorStock"; - -export type PriceOrStock = "price" | "stock"; -export interface ProductVariantCreatorPriceAndSkuProps { - attributes: ProductVariantAttributesFragment["productType"]["variantAttributes"]; - channelListings: ChannelPriceData[]; - data: ProductVariantCreateFormData; - warehouses: WarehouseFragment[]; - onApplyToAllChange: ( - value: VariantCreatorPricesAndSkuMode, - type: PriceOrStock, - ) => void; - onApplyToAllPriceChange: (channelId: string, value: string) => void; - onApplyToAllStockChange: (quantity: number, warehouseIndex: number) => void; - onAttributeSelect: (id: string, type: PriceOrStock) => void; - onAttributePriceChange: ( - id: string, - value: string, - channelId: string, - ) => void; - onAttributeStockChange: ( - id: string, - quantity: number, - warehouseIndex: number, - ) => void; - onWarehouseToggle: (id: string) => void; -} - -const ProductVariantCreatorPriceAndSku: React.FC = ({ - attributes, - channelListings, - data, - warehouses, - onApplyToAllChange, - onApplyToAllPriceChange, - onApplyToAllStockChange, - onAttributeSelect, - onAttributePriceChange, - onAttributeStockChange, - onWarehouseToggle, -}) => ( - <> - onApplyToAllChange(value, "price")} - onApplyToAllPriceChange={onApplyToAllPriceChange} - onAttributeSelect={id => onAttributeSelect(id, "price")} - onAttributeValueChange={onAttributePriceChange} - /> - - onApplyToAllChange(value, "stock")} - onApplyToAllStockChange={onApplyToAllStockChange} - onAttributeSelect={id => onAttributeSelect(id, "stock")} - onAttributeValueChange={onAttributeStockChange} - onWarehouseToggle={onWarehouseToggle} - /> - -); - -ProductVariantCreatorPriceAndSku.displayName = - "ProductVariantCreatorPriceAndSku"; -export default ProductVariantCreatorPriceAndSku; diff --git a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorPrices.tsx b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorPrices.tsx deleted file mode 100644 index b4924eca7..000000000 --- a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorPrices.tsx +++ /dev/null @@ -1,250 +0,0 @@ -import { - Card, - CardContent, - FormControlLabel, - Radio, - RadioGroup, - Typography, -} from "@material-ui/core"; -import { ChannelPriceData } from "@saleor/channels/utils"; -import CardTitle from "@saleor/components/CardTitle"; -import FormSpacer from "@saleor/components/FormSpacer"; -import Grid from "@saleor/components/Grid"; -import Hr from "@saleor/components/Hr"; -import PriceField from "@saleor/components/PriceField"; -import SingleSelectField from "@saleor/components/SingleSelectField"; -import { ProductVariantAttributesFragment } from "@saleor/graphql"; -import { makeStyles } from "@saleor/macaw-ui"; -import React from "react"; -import { defineMessages, FormattedMessage, useIntl } from "react-intl"; - -import { - ProductVariantCreateFormData, - VariantCreatorPricesAndSkuMode, -} from "./form"; -import { getPriceAttributeValues } from "./utils"; - -const messages = defineMessages({ - price: { - id: "OgFBAj", - defaultMessage: "Price", - description: "input label", - }, -}); - -const useStyles = makeStyles( - theme => ({ - attrInputsContainer: { - display: "grid", - gap: theme.spacing(2), - gridTemplateColumns: - "minmax(80px, 150px) repeat(auto-fit, minmax(150px, 250px))", - }, - channelName: { - marginBottom: theme.spacing(1), - }, - container: { - display: "block", - }, - hr: { - marginBottom: theme.spacing(), - marginTop: theme.spacing(0.5), - }, - hrAttribute: { - marginTop: theme.spacing(2), - }, - inputsContainer: { - display: "grid", - gap: theme.spacing(2), - gridTemplateColumns: "repeat(auto-fit, minmax(150px, 250px))", - }, - label: { - alignSelf: "center", - }, - }), - { name: "ProductVariantCreatorPrices" }, -); - -export interface ProductVariantCreatorPricesProps { - attributes: ProductVariantAttributesFragment["productType"]["variantAttributes"]; - channelListings: ChannelPriceData[]; - data: ProductVariantCreateFormData; - onApplyToAllChange: (applyToAll: VariantCreatorPricesAndSkuMode) => void; - onApplyToAllPriceChange: (channelId: string, value: string) => void; - onAttributeSelect: (id: string) => void; - onAttributeValueChange: ( - id: string, - value: string, - channelId: string, - ) => void; -} - -const ProductVariantCreatorPrices: React.FC = props => { - const { - attributes, - channelListings, - data, - onApplyToAllChange, - onApplyToAllPriceChange, - onAttributeSelect, - onAttributeValueChange, - } = props; - const classes = useStyles(props); - const intl = useIntl(); - - const attributeChoices = attributes.map(attribute => ({ - label: attribute.name, - value: attribute.id, - })); - const priceAttributeValues = getPriceAttributeValues(data, attributes); - - return ( - - - - - } - label={intl.formatMessage({ - id: "lra7Ej", - defaultMessage: "Apply single price to all SKUs", - })} - onChange={() => onApplyToAllChange("all")} - /> - {data.price.mode === "all" && ( - <> - -
- {channelListings?.map(listing => ( -
- - {listing.name} - - channel.channelId === listing.id, - )?.price - } - label={intl.formatMessage(messages.price)} - currencySymbol={listing.currency} - onChange={event => - onApplyToAllPriceChange(listing.id, event.target.value) - } - /> -
- ))} -
- - )} - - } - label={intl.formatMessage({ - id: "EGG8f+", - defaultMessage: "Apply unique prices by attribute to each SKU", - })} - onChange={() => onApplyToAllChange("attribute")} - /> - {data.price.mode === "attribute" && ( - <> - - -
- - - -
-
- onAttributeSelect(event.target.value)} - /> -
-
- {priceAttributeValues && - priceAttributeValues.map(attributeValue => { - const attributesChannels = data.price.values.find( - value => value.slug === attributeValue.slug, - ).value; - return ( - -
- -
-
- {attributeValue.name} -
- {channelListings?.map(listing => ( -
- - {listing.name} - - - attrChannel.channelId === listing.id, - )?.price || "" - } - onChange={event => - onAttributeValueChange( - attributeValue.slug, - event.target.value, - listing.id, - ) - } - /> -
- ))} -
-
- ); - })} - - )} - - } - label={intl.formatMessage({ - id: "J0UdxG", - defaultMessage: "Skip pricing for now", - })} - onChange={() => onApplyToAllChange("skip")} - /> -
-
-
- ); -}; - -ProductVariantCreatorPrices.displayName = "ProductVariantCreatorPrices"; -export default ProductVariantCreatorPrices; diff --git a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorStock.tsx b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorStock.tsx deleted file mode 100644 index 174dadd64..000000000 --- a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorStock.tsx +++ /dev/null @@ -1,343 +0,0 @@ -import { - Card, - CardContent, - FormControlLabel, - Radio, - RadioGroup, - TextField, - Typography, -} from "@material-ui/core"; -import CardSpacer from "@saleor/components/CardSpacer"; -import CardTitle from "@saleor/components/CardTitle"; -import ControlledCheckbox from "@saleor/components/ControlledCheckbox"; -import FormSpacer from "@saleor/components/FormSpacer"; -import Hr from "@saleor/components/Hr"; -import SingleSelectField from "@saleor/components/SingleSelectField"; -import { - ProductVariantAttributesFragment, - WarehouseFragment, -} from "@saleor/graphql"; -import { makeStyles } from "@saleor/macaw-ui"; -import { isSelected } from "@saleor/utils/lists"; -import React from "react"; -import { defineMessages, FormattedMessage, useIntl } from "react-intl"; - -import { - ProductVariantCreateFormData, - VariantCreatorPricesAndSkuMode, -} from "./form"; -import { getStockAttributeValues } from "./utils"; - -const messages = defineMessages({ - stock: { - id: "vuKrlW", - defaultMessage: "Stock", - }, -}); - -const useStyles = makeStyles( - theme => ({ - attributeStockContainer: { - columnGap: theme.spacing(3), - display: "grid", - gridTemplateColumns: ({ data }: ProductVariantCreatorStockProps) => - `150px repeat(${data.warehouses.length}, 288px)`, - rowGap: theme.spacing(2), - }, - attributeStockScroll: { - overflowX: "scroll", - width: "100%", - }, - hr: { - marginBottom: theme.spacing(), - marginTop: theme.spacing(0.5), - }, - hrAttribute: { - marginTop: theme.spacing(2), - }, - label: { - alignSelf: "center", - }, - shortInput: { - width: "33%", - }, - stockContainer: { - columnGap: theme.spacing(3), - display: "grid", - gridTemplateColumns: "repeat(3, 288px)", - marginTop: theme.spacing(2), - rowGap: theme.spacing(2), - }, - stockHeader: { - marginBottom: theme.spacing(), - }, - warehouseContainer: { - columnGap: theme.spacing(3), - display: "grid", - gridTemplateColumns: "repeat(4, 1fr)", - rowGap: theme.spacing(2), - }, - warehouseHeader: { - marginBottom: theme.spacing(), - }, - warehouseName: { - marginBottom: theme.spacing(), - }, - warehouseSubheader: { - marginBottom: theme.spacing(2), - }, - }), - { name: "ProductVariantCreatorStock" }, -); - -export interface ProductVariantCreatorStockProps { - attributes: ProductVariantAttributesFragment["productType"]["variantAttributes"]; - data: ProductVariantCreateFormData; - warehouses: WarehouseFragment[]; - onApplyToAllChange: (mode: VariantCreatorPricesAndSkuMode) => void; - onApplyToAllStockChange: (quantity: number, warehouseIndex: number) => void; - onAttributeSelect: (id: string) => void; - onAttributeValueChange: ( - id: string, - quantity: number, - warehouseIndex: number, - ) => void; - onWarehouseToggle: (id: string) => void; -} - -const ProductVariantCreatorStock: React.FC = props => { - const { - attributes, - data, - warehouses, - onApplyToAllChange, - onApplyToAllStockChange, - onAttributeSelect, - onAttributeValueChange, - onWarehouseToggle, - } = props; - const classes = useStyles(props); - const intl = useIntl(); - - const attributeChoices = attributes.map(attribute => ({ - label: attribute.name, - value: attribute.id, - })); - const stockAttributeValues = getStockAttributeValues(data, attributes); - - return ( - - - - {!warehouses.length ? ( - - - - ) : ( - <> - {warehouses.length > 1 && ( - <> - - - - - acc + attr.values.length, - 0, - ), - }} - /> - -
- {warehouses.map(warehouse => ( - a === b, - )} - name={`warehouse:${warehouse.id}`} - label={warehouse.name} - onChange={() => onWarehouseToggle(warehouse.id)} - key={warehouse.id} - /> - ))} -
- -
- - - )} - - - - - } - label={intl.formatMessage({ - id: "STp3Hl", - defaultMessage: "Apply single stock to all SKUs", - })} - onChange={() => onApplyToAllChange("all")} - /> - {data.stock.mode === "all" && ( -
- {data.warehouses.map((warehouseId, warehouseIndex) => ( -
- - { - warehouses.find( - warehouse => warehouse.id === warehouseId, - ).name - } - - - onApplyToAllStockChange( - parseInt(event.target.value, 10), - warehouseIndex, - ) - } - /> -
- ))} -
- )} - - } - label={intl.formatMessage({ - id: "L5rthO", - defaultMessage: "Apply unique stock by attribute to each SKU", - })} - onChange={() => onApplyToAllChange("attribute")} - /> - {data.stock.mode === "attribute" && ( - <> - - onAttributeSelect(event.target.value)} - /> - {stockAttributeValues && ( - <> -
- -
-
-
- {data.stock.attribute && - data.warehouses.map(warehouseId => ( - - { - warehouses.find( - warehouse => warehouse.id === warehouseId, - ).name - } - - ))} - {stockAttributeValues.map(attributeValue => ( - - {attributeValue.name} - {data.warehouses.map( - (warehouseId, warehouseIndex) => ( - - value.slug === attributeValue.slug, - ).value[warehouseIndex] - } - onChange={event => - onAttributeValueChange( - attributeValue.slug, - parseInt(event.target.value, 10), - warehouseIndex, - ) - } - key={warehouseId} - /> - ), - )} - - ))} -
-
- - )} - - )} - {data.stock.mode === "attribute" && !!data.stock.attribute && ( - <> - -
- - )} - - } - label={intl.formatMessage({ - id: "BIqhVQ", - defaultMessage: "Skip stock for now", - })} - onChange={() => onApplyToAllChange("skip")} - /> - - - )} - - - ); -}; - -ProductVariantCreatorStock.displayName = "ProductVariantCreatorStock"; -export default ProductVariantCreatorStock; diff --git a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorSummary.tsx b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorSummary.tsx deleted file mode 100644 index 05c0112a3..000000000 --- a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorSummary.tsx +++ /dev/null @@ -1,346 +0,0 @@ -import { Card, TextField } from "@material-ui/core"; -import blue from "@material-ui/core/colors/blue"; -import cyan from "@material-ui/core/colors/cyan"; -import green from "@material-ui/core/colors/green"; -import purple from "@material-ui/core/colors/purple"; -import yellow from "@material-ui/core/colors/yellow"; -import { ChannelPriceData } from "@saleor/channels/utils"; -import CardTitle from "@saleor/components/CardTitle"; -import Hr from "@saleor/components/Hr"; -import PriceField from "@saleor/components/PriceField"; -import { - BulkProductErrorFragment, - ProductFragment, - ProductVariantBulkCreateInput, - WarehouseFragment, -} from "@saleor/graphql"; -import { DeleteIcon, IconButton, makeStyles } from "@saleor/macaw-ui"; -import { getFormErrors } from "@saleor/utils/errors"; -import { getBulkProductErrorMessage } from "@saleor/utils/errors/product"; -import classNames from "classnames"; -import React from "react"; -import { FormattedMessage, useIntl } from "react-intl"; - -import { Attribute, ChannelPrice, ProductVariantCreateFormData } from "./form"; - -export interface ProductVariantCreatorSummaryProps { - attributes: ProductFragment["productType"]["variantAttributes"]; - channelListings: ChannelPriceData[]; - data: ProductVariantCreateFormData; - errors: BulkProductErrorFragment[]; - warehouses: WarehouseFragment[]; - onVariantSkuChange: (variantIndex: number, value: string) => void; - onVariantStockDataChange: ( - variantIndex: number, - warehouseId: string, - value: string, - ) => void; - onVariantDelete: (variantIndex: number) => void; - onVariantPriceDataChange: (variantIndex: number, value: ChannelPrice) => void; -} -type ClassKey = - | "attributeValue" - | "card" - | "col" - | "colHeader" - | "colName" - | "colPrice" - | "colSku" - | "colStock" - | "delete" - | "hr" - | "input" - | "summary"; - -const colors = [blue, cyan, green, purple, yellow].map(color => color[800]); - -const useStyles = makeStyles( - theme => ({ - attributeValue: { - display: "inline-block", - marginRight: theme.spacing(1), - }, - card: { - paddingBottom: theme.spacing(), - }, - col: { - ...theme.typography.body1, - fontSize: 14, - }, - colHeader: { - ...theme.typography.body1, - fontSize: 14, - paddingTop: theme.spacing(3), - }, - colName: { - "&:not($colHeader)": { - paddingTop: theme.spacing(2), - }, - paddingLeft: theme.spacing(3), - }, - colPrice: {}, - colSku: {}, - colStock: {}, - delete: { - marginTop: theme.spacing(0.5), - }, - hr: { - gridColumn: props => - `span ${4 + - props.data.variants[0].stocks.length + - props.data.variants[0].channelListings.length}`, - }, - input: { - "& input": { - padding: "16px 12px 17px", - }, - }, - summary: { - columnGap: theme.spacing(3), - display: "grid", - gridTemplateColumns: props => - `minmax(180px, auto) repeat(${props.data.variants[0].channelListings - .length + - props.data.variants[0].stocks - .length}, minmax(180px, auto)) 220px 64px`, - overflowX: "scroll", - rowGap: theme.spacing(), - paddingBottom: 3, - }, - }), - { - name: "ProductVariantCreatorSummary", - }, -); - -function getVariantName( - variant: ProductVariantBulkCreateInput, - attributes: Attribute[], -): string[] { - return attributes.reduce( - (acc, attribute) => [ - ...acc, - attribute.values?.find(value => { - const variantAttributeValue = variant.attributes.find( - variantAttribute => variantAttribute.id === attribute.id, - ); - return ( - variantAttributeValue.values?.[0] === value?.slug || - variantAttributeValue.boolean === value.value.boolean - ); - })?.value?.name, - ], - [], - ); -} - -const ProductVariantCreatorSummary: React.FC = props => { - const { - channelListings, - data, - errors, - warehouses, - onVariantPriceDataChange, - onVariantSkuChange, - onVariantDelete, - onVariantStockDataChange, - } = props; - const classes = useStyles(props); - const intl = useIntl(); - - return ( - - -
-
- -
- - {channelListings.map(listing => ( -
- -
- ))} - - {data.warehouses.map(warehouseId => ( -
- {warehouses.find(warehouse => warehouse.id === warehouseId).name} -
- ))} -
- -
-
-
- {data.variants.map((variant, variantIndex) => { - const variantErrors = errors.filter( - error => error.index === variantIndex, - ); - const variantFormErrors = getFormErrors( - ["price", "quantity", "sku"], - variantErrors, - ); - return ( - attribute.values?.[0] ?? attribute.boolean) - .join(":")} - > -
- {getVariantName(variant, data.attributes).map( - (value, valueIndex) => ( - - {value} - - ), - )} -
- {channelListings.map(listing => { - const error = variantFormErrors.price?.channels?.find( - id => id === listing.id, - ); - return ( -
- channel.channelId === listing.id, - )?.price - } - required - onChange={event => - onVariantPriceDataChange(variantIndex, { - channelId: listing.id, - price: event.target.value, - }) - } - /> -
- ); - })} - {variant.stocks.map(stock => ( -
- - onVariantStockDataChange( - variantIndex, - stock.warehouse, - event.target.value, - ) - } - /> -
- ))} -
- - onVariantSkuChange(variantIndex, event.target.value) - } - /> -
-
- onVariantDelete(variantIndex)} - > - - -
- {variantIndex !== data.variants.length - 1 && ( -
- )} -
- ); - })} -
- - ); -}; - -ProductVariantCreatorSummary.displayName = "ProductVariantCreatorSummary"; -export default ProductVariantCreatorSummary; diff --git a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorTabs.tsx b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorTabs.tsx deleted file mode 100644 index 6e254efc9..000000000 --- a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorTabs.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import makeCreatorSteps, { Step } from "@saleor/components/CreatorSteps"; -import React from "react"; -import { useIntl } from "react-intl"; - -import { ProductVariantCreatorStep } from "./types"; - -function useSteps(): Array> { - const intl = useIntl(); - - return [ - { - label: intl.formatMessage({ - id: "rVaB7c", - defaultMessage: "Select Values", - description: "attribute values, variant creation step", - }), - value: ProductVariantCreatorStep.values, - }, - { - label: intl.formatMessage({ - id: "Sx7QVu", - defaultMessage: "Prices and SKU", - description: "variant creation step", - }), - value: ProductVariantCreatorStep.prices, - }, - { - label: intl.formatMessage({ - id: "slKV5G", - defaultMessage: "Summary", - description: "variant creation step", - }), - value: ProductVariantCreatorStep.summary, - }, - ]; -} - -const ProductVariantCreatorSteps = makeCreatorSteps< - ProductVariantCreatorStep ->(); - -export interface ProductVariantCreatorTabsProps { - step: ProductVariantCreatorStep; - onStepClick: (step: ProductVariantCreatorStep) => void; -} - -const ProductVariantCreatorTabs: React.FC = ({ - step: currentStep, - onStepClick, -}) => { - const steps = useSteps(); - - return ( - - ); -}; - -ProductVariantCreatorTabs.displayName = "ProductVariantCreatorTabs"; -export default ProductVariantCreatorTabs; diff --git a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorValues.tsx b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorValues.tsx deleted file mode 100644 index d232b44e2..000000000 --- a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorValues.tsx +++ /dev/null @@ -1,236 +0,0 @@ -import { Card, CardContent } from "@material-ui/core"; -import { getMeasurementUnitMessage } from "@saleor/attributes/components/AttributeDetails/utils"; -import { getMultiChoices } from "@saleor/components/Attributes/utils"; -import CardSpacer from "@saleor/components/CardSpacer"; -import CardTitle from "@saleor/components/CardTitle"; -import LimitReachedAlert from "@saleor/components/LimitReachedAlert"; -import MultiAutocompleteSelectField from "@saleor/components/MultiAutocompleteSelectField"; -import Skeleton from "@saleor/components/Skeleton"; -import { - AttributeInputTypeEnum, - AttributeValueFragment, - ProductVariantAttributesFragment, - SearchAttributeValuesQuery, -} from "@saleor/graphql"; -import { commonMessages } from "@saleor/intl"; -import { getById } from "@saleor/orders/components/OrderReturnPage/utils"; -import { - getBasicAttributeValue, - getBooleanAttributeValue, -} from "@saleor/products/components/ProductVariantCreatorPage/utils"; -import { FetchMoreProps, RelayToFlat } from "@saleor/types"; -import React from "react"; -import { - defineMessages, - FormattedMessage, - IntlShape, - useIntl, -} from "react-intl"; - -import { - Attribute, - AttributeValue, - ProductVariantCreateFormData, -} from "./form"; - -const messages = defineMessages({ - multipleValueLabel: { - id: "j8PV7E", - defaultMessage: "Values", - description: "attribute values", - }, -}); - -export function getVariantsNumber(data: ProductVariantCreateFormData): number { - return data.attributes.reduce( - (variants, attribute) => variants * attribute.values.length, - 1, - ); -} - -export function getMultiValues( - attributes: Attribute[], - attribute: ProductVariantAttributesFragment["productType"]["variantAttributes"][0], -) { - return attributes - .find(getById(attribute.id)) - ?.values?.map(value => value.slug); -} - -export function getMultiDisplayValues( - attributes: Attribute[], - attribute: ProductVariantAttributesFragment["productType"]["variantAttributes"][0], -) { - return attributes.find(getById(attribute.id))?.values.map(value => ({ - label: value.value?.name, - value: value.slug, - })); -} - -const getBooleanDisplayValues = ( - intl: IntlShape, - values: Array>>, -) => { - if (!values.length) { - return []; - } - - const choices = getBooleanChoices(intl); - return values.map(({ value: { boolean } }) => - choices.find(({ value }) => value === boolean), - ); -}; - -const getBooleanChoices = ( - intl: IntlShape, - values?: Array>>, -) => { - const selectedValues = values?.map(({ value }) => value.boolean) ?? []; - const choices = [ - { label: intl.formatMessage(commonMessages.yes), value: true }, - { label: intl.formatMessage(commonMessages.no), value: false }, - ]; - - return choices.filter(({ value }) => !selectedValues.includes(value)); -}; - -export interface ProductVariantCreatorValuesProps { - attributes: ProductVariantAttributesFragment["productType"]["variantAttributes"]; - attributeValues: RelayToFlat< - SearchAttributeValuesQuery["attribute"]["choices"] - >; - fetchAttributeValues: (query: string, attributeId: string) => void; - fetchMoreAttributeValues?: FetchMoreProps; - data: ProductVariantCreateFormData; - variantsLeft: number | null; - onValueClick: ( - attributeId: string, - value: AttributeValue>, - ) => void; - onValueBlur: () => void; -} - -const ProductVariantCreatorValues: React.FC = props => { - const { - attributes, - attributeValues, - fetchAttributeValues, - fetchMoreAttributeValues, - data, - variantsLeft, - onValueClick, - onValueBlur, - } = props; - const intl = useIntl(); - const variantsNumber = getVariantsNumber(data); - - const handleValueClick = ( - attributeId: string, - attributeName: string, - attributeValue: string | boolean, - ) => - onValueClick( - attributeId, - typeof attributeValue === "boolean" - ? getBooleanAttributeValue(attributeName, attributeValue) - : getBasicAttributeValue( - attributeId, - attributeValue, - attributeValues, - data, - ), - ); - - return ( - <> - {variantsLeft !== null && variantsNumber > variantsLeft && ( - - - - )} - {attributes.map(attribute => ( - - - } /> - - {attribute.inputType === AttributeInputTypeEnum.BOOLEAN ? ( - id === attribute.id) - .values, - )} - name={`attribute:${attribute.name}`} - label={intl.formatMessage(messages.multipleValueLabel)} - value={getMultiValues(data.attributes, attribute)} - onChange={event => - handleValueClick( - attribute.id, - attribute.name, - event.target.value, - ) - } - allowCustomValues={false} - choices={getBooleanChoices( - intl, - data.attributes.find(({ id }) => id === attribute.id) - .values, - )} - /> - ) : ( - - handleValueClick( - attribute.id, - attribute.name, - event.target.value, - ) - } - endAdornment={ - attribute.unit && - getMeasurementUnitMessage( - attribute.unit, - intl.formatMessage, - ) - } - fetchOnFocus={true} - allowCustomValues={true} - fetchChoices={value => - fetchAttributeValues(value, attribute.id) - } - onBlur={onValueBlur} - {...fetchMoreAttributeValues} - /> - )} - - - - - ))} - - ); -}; - -ProductVariantCreatorValues.displayName = "ProductVariantCreatorValues"; -export default ProductVariantCreatorValues; diff --git a/src/products/components/ProductVariantCreatorPage/__snapshots__/reducer.test.ts.snap b/src/products/components/ProductVariantCreatorPage/__snapshots__/reducer.test.ts.snap deleted file mode 100644 index e7f274770..000000000 --- a/src/products/components/ProductVariantCreatorPage/__snapshots__/reducer.test.ts.snap +++ /dev/null @@ -1,3867 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Reducer is able to modify individual variant price 1`] = ` -Object { - "attributes": Array [ - Object { - "id": "attr-1", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-1-1", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-1-1", - "name": "val-1-1", - "reference": null, - "richText": null, - "slug": "val-1-1", - "value": null, - }, - }, - Object { - "slug": "val-1-7", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-1-7", - "name": "val-1-7", - "reference": null, - "richText": null, - "slug": "val-1-7", - "value": null, - }, - }, - ], - }, - Object { - "id": "attr-2", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-2-2", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-2-2", - "name": "val-2-2", - "reference": null, - "richText": null, - "slug": "val-2-2", - "value": null, - }, - }, - Object { - "slug": "val-2-4", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-2-4", - "name": "val-2-4", - "reference": null, - "richText": null, - "slug": "val-2-4", - "value": null, - }, - }, - ], - }, - Object { - "id": "attr-4", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-4-1", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-4-1", - "name": "val-4-1", - "reference": null, - "richText": null, - "slug": "val-4-1", - "value": null, - }, - }, - Object { - "slug": "val-4-5", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-4-5", - "name": "val-4-5", - "reference": null, - "richText": null, - "slug": "val-4-5", - "value": null, - }, - }, - ], - }, - ], - "price": Object { - "attribute": "attr-2", - "channels": Array [ - Object { - "channelId": "channel-1", - "price": "0", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "2", - }, - ], - "mode": "attribute", - "values": Array [ - Object { - "slug": "val-2-2", - "value": Array [ - Object { - "channelId": "channel-1", - "price": "0", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "2", - }, - ], - }, - Object { - "slug": "val-2-4", - "value": Array [ - Object { - "channelId": "channel-1", - "price": "0", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "2", - }, - ], - }, - ], - }, - "stock": Object { - "attribute": "attr-4", - "mode": "attribute", - "value": Array [], - "values": Array [ - Object { - "slug": "val-4-1", - "value": Array [ - 50, - 20, - 45, - 75, - ], - }, - Object { - "slug": "val-4-5", - "value": Array [ - 80, - 50, - 85, - 105, - ], - }, - ], - }, - "variants": Array [ - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "0", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "2", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 50, - "warehouse": "wh-1", - }, - Object { - "quantity": 20, - "warehouse": "wh-2", - }, - Object { - "quantity": 45, - "warehouse": "wh-3", - }, - Object { - "quantity": 75, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "0", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "2", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 80, - "warehouse": "wh-1", - }, - Object { - "quantity": 50, - "warehouse": "wh-2", - }, - Object { - "quantity": 85, - "warehouse": "wh-3", - }, - Object { - "quantity": 105, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "0", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "2", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 50, - "warehouse": "wh-1", - }, - Object { - "quantity": 20, - "warehouse": "wh-2", - }, - Object { - "quantity": 45, - "warehouse": "wh-3", - }, - Object { - "quantity": 75, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "7", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "2", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 80, - "warehouse": "wh-1", - }, - Object { - "quantity": 50, - "warehouse": "wh-2", - }, - Object { - "quantity": 85, - "warehouse": "wh-3", - }, - Object { - "quantity": 105, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "0", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "2", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 50, - "warehouse": "wh-1", - }, - Object { - "quantity": 20, - "warehouse": "wh-2", - }, - Object { - "quantity": 45, - "warehouse": "wh-3", - }, - Object { - "quantity": 75, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "0", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "2", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 80, - "warehouse": "wh-1", - }, - Object { - "quantity": 50, - "warehouse": "wh-2", - }, - Object { - "quantity": 85, - "warehouse": "wh-3", - }, - Object { - "quantity": 105, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "0", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "2", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 50, - "warehouse": "wh-1", - }, - Object { - "quantity": 20, - "warehouse": "wh-2", - }, - Object { - "quantity": 45, - "warehouse": "wh-3", - }, - Object { - "quantity": 75, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "0", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "2", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 80, - "warehouse": "wh-1", - }, - Object { - "quantity": 50, - "warehouse": "wh-2", - }, - Object { - "quantity": 85, - "warehouse": "wh-3", - }, - Object { - "quantity": 105, - "warehouse": "wh-4", - }, - ], - }, - ], - "warehouses": Array [ - "wh-1", - "wh-2", - "wh-3", - "wh-4", - ], -} -`; - -exports[`Reducer is able to modify individual variant stock 1`] = ` -Object { - "attributes": Array [ - Object { - "id": "attr-1", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-1-1", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-1-1", - "name": "val-1-1", - "reference": null, - "richText": null, - "slug": "val-1-1", - "value": null, - }, - }, - Object { - "slug": "val-1-7", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-1-7", - "name": "val-1-7", - "reference": null, - "richText": null, - "slug": "val-1-7", - "value": null, - }, - }, - ], - }, - Object { - "id": "attr-2", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-2-2", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-2-2", - "name": "val-2-2", - "reference": null, - "richText": null, - "slug": "val-2-2", - "value": null, - }, - }, - Object { - "slug": "val-2-4", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-2-4", - "name": "val-2-4", - "reference": null, - "richText": null, - "slug": "val-2-4", - "value": null, - }, - }, - ], - }, - Object { - "id": "attr-4", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-4-1", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-4-1", - "name": "val-4-1", - "reference": null, - "richText": null, - "slug": "val-4-1", - "value": null, - }, - }, - Object { - "slug": "val-4-5", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-4-5", - "name": "val-4-5", - "reference": null, - "richText": null, - "slug": "val-4-5", - "value": null, - }, - }, - ], - }, - ], - "price": Object { - "attribute": "attr-2", - "channels": Array [ - Object { - "channelId": "channel-1", - "price": "0", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "2", - }, - ], - "mode": "attribute", - "values": Array [ - Object { - "slug": "val-2-2", - "value": Array [ - Object { - "channelId": "channel-1", - "price": "0", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "2", - }, - ], - }, - Object { - "slug": "val-2-4", - "value": Array [ - Object { - "channelId": "channel-1", - "price": "0", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "2", - }, - ], - }, - ], - }, - "stock": Object { - "attribute": "attr-4", - "mode": "attribute", - "value": Array [], - "values": Array [ - Object { - "slug": "val-4-1", - "value": Array [ - 50, - 20, - 45, - 75, - ], - }, - Object { - "slug": "val-4-5", - "value": Array [ - 80, - 50, - 85, - 105, - ], - }, - ], - }, - "variants": Array [ - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "0", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "2", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 50, - "warehouse": "wh-1", - }, - Object { - "quantity": 20, - "warehouse": "wh-2", - }, - Object { - "quantity": 45, - "warehouse": "wh-3", - }, - Object { - "quantity": 75, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "0", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "2", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 80, - "warehouse": "wh-1", - }, - Object { - "quantity": 50, - "warehouse": "wh-2", - }, - Object { - "quantity": 85, - "warehouse": "wh-3", - }, - Object { - "quantity": 105, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "0", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "2", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 50, - "warehouse": "wh-1", - }, - Object { - "quantity": 20, - "warehouse": "wh-2", - }, - Object { - "quantity": 45, - "warehouse": "wh-3", - }, - Object { - "quantity": 75, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "0", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "2", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 5, - "warehouse": "wh-1", - }, - Object { - "quantity": 50, - "warehouse": "wh-2", - }, - Object { - "quantity": 85, - "warehouse": "wh-3", - }, - Object { - "quantity": 105, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "0", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "2", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 50, - "warehouse": "wh-1", - }, - Object { - "quantity": 20, - "warehouse": "wh-2", - }, - Object { - "quantity": 45, - "warehouse": "wh-3", - }, - Object { - "quantity": 75, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "0", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "2", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 80, - "warehouse": "wh-1", - }, - Object { - "quantity": 50, - "warehouse": "wh-2", - }, - Object { - "quantity": 85, - "warehouse": "wh-3", - }, - Object { - "quantity": 105, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "0", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "2", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 50, - "warehouse": "wh-1", - }, - Object { - "quantity": 20, - "warehouse": "wh-2", - }, - Object { - "quantity": 45, - "warehouse": "wh-3", - }, - Object { - "quantity": 75, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "0", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "2", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 80, - "warehouse": "wh-1", - }, - Object { - "quantity": 50, - "warehouse": "wh-2", - }, - Object { - "quantity": 85, - "warehouse": "wh-3", - }, - Object { - "quantity": 105, - "warehouse": "wh-4", - }, - ], - }, - ], - "warehouses": Array [ - "wh-1", - "wh-2", - "wh-3", - "wh-4", - ], -} -`; - -exports[`Reducer is able to select attribute values 1`] = ` -Object { - "attributes": Array [ - Object { - "id": "attr-1", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-1-1", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-1-1", - "name": "val-1-1", - "reference": null, - "richText": null, - "slug": "val-1-1", - "value": null, - }, - }, - Object { - "slug": "val-1-7", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-1-7", - "name": "val-1-7", - "reference": null, - "richText": null, - "slug": "val-1-7", - "value": null, - }, - }, - ], - }, - Object { - "id": "attr-2", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-2-2", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-2-2", - "name": "val-2-2", - "reference": null, - "richText": null, - "slug": "val-2-2", - "value": null, - }, - }, - Object { - "slug": "val-2-4", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-2-4", - "name": "val-2-4", - "reference": null, - "richText": null, - "slug": "val-2-4", - "value": null, - }, - }, - ], - }, - Object { - "id": "attr-4", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-4-1", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-4-1", - "name": "val-4-1", - "reference": null, - "richText": null, - "slug": "val-4-1", - "value": null, - }, - }, - Object { - "slug": "val-4-5", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-4-5", - "name": "val-4-5", - "reference": null, - "richText": null, - "slug": "val-4-5", - "value": null, - }, - }, - ], - }, - ], - "price": Object { - "attribute": undefined, - "channels": Array [ - Object { - "channelId": "channel-1", - "price": "1", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "mode": "all", - "values": Array [], - }, - "stock": Object { - "attribute": undefined, - "mode": "all", - "value": Array [], - "values": Array [], - }, - "variants": Array [], - "warehouses": Array [], -} -`; - -exports[`Reducer is able to select price for all variants 1`] = ` -Object { - "attributes": Array [ - Object { - "id": "attr-1", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-1-1", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-1-1", - "name": "val-1-1", - "reference": null, - "richText": null, - "slug": "val-1-1", - "value": null, - }, - }, - Object { - "slug": "val-1-7", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-1-7", - "name": "val-1-7", - "reference": null, - "richText": null, - "slug": "val-1-7", - "value": null, - }, - }, - ], - }, - Object { - "id": "attr-2", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-2-2", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-2-2", - "name": "val-2-2", - "reference": null, - "richText": null, - "slug": "val-2-2", - "value": null, - }, - }, - Object { - "slug": "val-2-4", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-2-4", - "name": "val-2-4", - "reference": null, - "richText": null, - "slug": "val-2-4", - "value": null, - }, - }, - ], - }, - Object { - "id": "attr-4", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-4-1", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-4-1", - "name": "val-4-1", - "reference": null, - "richText": null, - "slug": "val-4-1", - "value": null, - }, - }, - Object { - "slug": "val-4-5", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-4-5", - "name": "val-4-5", - "reference": null, - "richText": null, - "slug": "val-4-5", - "value": null, - }, - }, - ], - }, - ], - "price": Object { - "attribute": undefined, - "channels": Array [ - Object { - "channelId": "channel-1", - "price": "22.99", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "mode": "all", - "values": Array [], - }, - "stock": Object { - "attribute": undefined, - "mode": "all", - "value": Array [ - 0, - 0, - 0, - 0, - ], - "values": Array [], - }, - "variants": Array [ - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "22.99", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 0, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "22.99", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 0, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "22.99", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 0, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "22.99", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 0, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "22.99", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 0, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "22.99", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 0, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "22.99", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 0, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "22.99", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 0, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - ], - "warehouses": Array [ - "wh-1", - "wh-2", - "wh-3", - "wh-4", - ], -} -`; - -exports[`Reducer is able to select price to each attribute value 1`] = ` -Object { - "attributes": Array [ - Object { - "id": "attr-1", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-1-1", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-1-1", - "name": "val-1-1", - "reference": null, - "richText": null, - "slug": "val-1-1", - "value": null, - }, - }, - Object { - "slug": "val-1-7", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-1-7", - "name": "val-1-7", - "reference": null, - "richText": null, - "slug": "val-1-7", - "value": null, - }, - }, - ], - }, - Object { - "id": "attr-2", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-2-2", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-2-2", - "name": "val-2-2", - "reference": null, - "richText": null, - "slug": "val-2-2", - "value": null, - }, - }, - Object { - "slug": "val-2-4", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-2-4", - "name": "val-2-4", - "reference": null, - "richText": null, - "slug": "val-2-4", - "value": null, - }, - }, - ], - }, - Object { - "id": "attr-4", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-4-1", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-4-1", - "name": "val-4-1", - "reference": null, - "richText": null, - "slug": "val-4-1", - "value": null, - }, - }, - Object { - "slug": "val-4-5", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-4-5", - "name": "val-4-5", - "reference": null, - "richText": null, - "slug": "val-4-5", - "value": null, - }, - }, - ], - }, - ], - "price": Object { - "attribute": "attr-1", - "channels": Array [ - Object { - "channelId": "channel-1", - "price": "1", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "mode": "attribute", - "values": Array [ - Object { - "slug": "val-1-1", - "value": Array [ - Object { - "channelId": "channel-1", - "price": "45.99", - }, - ], - }, - Object { - "slug": "val-1-7", - "value": Array [ - Object { - "channelId": "channel-2", - "price": "51.99", - }, - ], - }, - ], - }, - "stock": Object { - "attribute": undefined, - "mode": "all", - "value": Array [ - 0, - 0, - 0, - 0, - ], - "values": Array [], - }, - "variants": Array [ - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "45.99", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 0, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "45.99", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 0, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "45.99", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 0, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "45.99", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 0, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-2", - "price": "51.99", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 0, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-2", - "price": "51.99", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 0, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-2", - "price": "51.99", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 0, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-2", - "price": "51.99", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 0, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - ], - "warehouses": Array [ - "wh-1", - "wh-2", - "wh-3", - "wh-4", - ], -} -`; - -exports[`Reducer is able to select stock for all variants 1`] = ` -Object { - "attributes": Array [ - Object { - "id": "attr-1", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-1-1", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-1-1", - "name": "val-1-1", - "reference": null, - "richText": null, - "slug": "val-1-1", - "value": null, - }, - }, - Object { - "slug": "val-1-7", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-1-7", - "name": "val-1-7", - "reference": null, - "richText": null, - "slug": "val-1-7", - "value": null, - }, - }, - ], - }, - Object { - "id": "attr-2", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-2-2", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-2-2", - "name": "val-2-2", - "reference": null, - "richText": null, - "slug": "val-2-2", - "value": null, - }, - }, - Object { - "slug": "val-2-4", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-2-4", - "name": "val-2-4", - "reference": null, - "richText": null, - "slug": "val-2-4", - "value": null, - }, - }, - ], - }, - Object { - "id": "attr-4", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-4-1", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-4-1", - "name": "val-4-1", - "reference": null, - "richText": null, - "slug": "val-4-1", - "value": null, - }, - }, - Object { - "slug": "val-4-5", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-4-5", - "name": "val-4-5", - "reference": null, - "richText": null, - "slug": "val-4-5", - "value": null, - }, - }, - ], - }, - ], - "price": Object { - "attribute": undefined, - "channels": Array [ - Object { - "channelId": "channel-1", - "price": "1", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "mode": "all", - "values": Array [], - }, - "stock": Object { - "attribute": undefined, - "mode": "all", - "value": Array [ - 0, - 45, - 0, - 0, - ], - "values": Array [], - }, - "variants": Array [ - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "1", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 45, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "1", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 45, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "1", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 45, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "1", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 45, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "1", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 45, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "1", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 45, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "1", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 45, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "1", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 0, - "warehouse": "wh-1", - }, - Object { - "quantity": 45, - "warehouse": "wh-2", - }, - Object { - "quantity": 0, - "warehouse": "wh-3", - }, - Object { - "quantity": 0, - "warehouse": "wh-4", - }, - ], - }, - ], - "warehouses": Array [ - "wh-1", - "wh-2", - "wh-3", - "wh-4", - ], -} -`; - -exports[`Reducer is able to select stock to each attribute value 1`] = ` -Object { - "attributes": Array [ - Object { - "id": "attr-1", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-1-1", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-1-1", - "name": "val-1-1", - "reference": null, - "richText": null, - "slug": "val-1-1", - "value": null, - }, - }, - Object { - "slug": "val-1-7", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-1-7", - "name": "val-1-7", - "reference": null, - "richText": null, - "slug": "val-1-7", - "value": null, - }, - }, - ], - }, - Object { - "id": "attr-2", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-2-2", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-2-2", - "name": "val-2-2", - "reference": null, - "richText": null, - "slug": "val-2-2", - "value": null, - }, - }, - Object { - "slug": "val-2-4", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-2-4", - "name": "val-2-4", - "reference": null, - "richText": null, - "slug": "val-2-4", - "value": null, - }, - }, - ], - }, - Object { - "id": "attr-4", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-4-1", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-4-1", - "name": "val-4-1", - "reference": null, - "richText": null, - "slug": "val-4-1", - "value": null, - }, - }, - Object { - "slug": "val-4-5", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-4-5", - "name": "val-4-5", - "reference": null, - "richText": null, - "slug": "val-4-5", - "value": null, - }, - }, - ], - }, - ], - "price": Object { - "attribute": undefined, - "channels": Array [ - Object { - "channelId": "channel-1", - "price": "1", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "mode": "all", - "values": Array [], - }, - "stock": Object { - "attribute": "attr-1", - "mode": "attribute", - "value": Array [ - 0, - 0, - 0, - 0, - ], - "values": Array [ - Object { - "slug": "val-1-1", - "value": Array [ - 13, - ], - }, - Object { - "slug": "val-1-7", - "value": Array [ - 19, - ], - }, - ], - }, - "variants": Array [ - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "1", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 13, - "warehouse": "wh-1", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "1", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 13, - "warehouse": "wh-1", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "1", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 13, - "warehouse": "wh-1", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-1", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "1", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 13, - "warehouse": "wh-1", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "1", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 19, - "warehouse": "wh-1", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-2", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "1", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 19, - "warehouse": "wh-1", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-1", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "1", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 19, - "warehouse": "wh-1", - }, - ], - }, - Object { - "attributes": Array [ - Object { - "id": "attr-1", - "values": Array [ - "val-1-7", - ], - }, - Object { - "id": "attr-2", - "values": Array [ - "val-2-4", - ], - }, - Object { - "id": "attr-4", - "values": Array [ - "val-4-5", - ], - }, - ], - "channelListings": Array [ - Object { - "channelId": "channel-1", - "price": "1", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "sku": "", - "stocks": Array [ - Object { - "quantity": 19, - "warehouse": "wh-1", - }, - ], - }, - ], - "warehouses": Array [ - "wh-1", - "wh-2", - "wh-3", - "wh-4", - ], -} -`; - -exports[`Reducer is able to select warehouses in which stock will be created 1`] = ` -Object { - "attributes": Array [ - Object { - "id": "attr-1", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-1-1", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-1-1", - "name": "val-1-1", - "reference": null, - "richText": null, - "slug": "val-1-1", - "value": null, - }, - }, - Object { - "slug": "val-1-7", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-1-7", - "name": "val-1-7", - "reference": null, - "richText": null, - "slug": "val-1-7", - "value": null, - }, - }, - ], - }, - Object { - "id": "attr-2", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-2-2", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-2-2", - "name": "val-2-2", - "reference": null, - "richText": null, - "slug": "val-2-2", - "value": null, - }, - }, - Object { - "slug": "val-2-4", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-2-4", - "name": "val-2-4", - "reference": null, - "richText": null, - "slug": "val-2-4", - "value": null, - }, - }, - ], - }, - Object { - "id": "attr-4", - "valueRequired": false, - "values": Array [ - Object { - "slug": "val-4-1", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-4-1", - "name": "val-4-1", - "reference": null, - "richText": null, - "slug": "val-4-1", - "value": null, - }, - }, - Object { - "slug": "val-4-5", - "value": Object { - "__typename": "AttributeValue", - "boolean": null, - "date": null, - "dateTime": null, - "file": null, - "id": "val-4-5", - "name": "val-4-5", - "reference": null, - "richText": null, - "slug": "val-4-5", - "value": null, - }, - }, - ], - }, - ], - "price": Object { - "attribute": undefined, - "channels": Array [ - Object { - "channelId": "channel-1", - "price": "1", - }, - Object { - "channelId": "channel-2", - "price": "2", - }, - Object { - "channelId": "channel-3", - "price": "3", - }, - ], - "mode": "all", - "values": Array [], - }, - "stock": Object { - "attribute": undefined, - "mode": "all", - "value": Array [ - 0, - 0, - ], - "values": Array [], - }, - "variants": Array [], - "warehouses": Array [ - "wh-2", - "wh-4", - ], -} -`; diff --git a/src/products/components/ProductVariantCreatorPage/createVariants.test.ts b/src/products/components/ProductVariantCreatorPage/createVariants.test.ts deleted file mode 100644 index 351a373b3..000000000 --- a/src/products/components/ProductVariantCreatorPage/createVariants.test.ts +++ /dev/null @@ -1,244 +0,0 @@ -import { - createVariantFlatMatrixDimension, - createVariants, -} from "./createVariants"; -import { attributes, channels, thirdStep } from "./fixtures"; -import { ChannelPrice, ProductVariantCreateFormData } from "./form"; - -describe("Creates variant matrix", () => { - it("with proper size", () => { - const attributes = thirdStep.attributes; - - const matrix = createVariantFlatMatrixDimension([[]], attributes); - - expect(matrix).toHaveLength( - attributes.reduce((acc, attribute) => acc * attribute.values.length, 1), - ); - }); - - it("with constant price and stock", () => { - const channels: ChannelPrice[] = [{ channelId: "1", price: "2" }]; - const stock = [80, 40, 30]; - - const data: ProductVariantCreateFormData = { - ...thirdStep, - price: { - ...thirdStep.price, - channels, - mode: "all", - }, - stock: { - ...thirdStep.stock, - mode: "all", - value: stock, - }, - }; - - const variants = createVariants(data); - expect(variants).toHaveLength( - thirdStep.attributes.reduce( - (acc, attribute) => acc * attribute.values.length, - 1, - ), - ); - - variants.forEach(variant => { - expect(variant.channelListings[0].price).toBe(channels[0].price); - variant.stocks.forEach((_, stockIndex) => { - expect(variant.stocks[stockIndex].quantity).toBe(stock[stockIndex]); - }); - }); - }); - - it("with constant stock and attribute dependent price", () => { - const stock = [80, 40, 30]; - const attribute = attributes.find( - attribute => attribute.id === thirdStep.attributes[0].id, - ); - - const data: ProductVariantCreateFormData = { - ...thirdStep, - price: { - ...thirdStep.price, - attribute: attribute.id, - mode: "attribute", - values: attribute.values.map((attributeValue, index) => ({ - slug: attributeValue.slug, - value: channels.map(channel => ({ - channelId: channel.id, - price: (channel.price + index).toString(), - })), - })), - }, - stock: { - ...thirdStep.stock, - mode: "all", - value: stock, - }, - }; - - const variants = createVariants(data); - expect(variants).toHaveLength( - thirdStep.attributes.reduce( - (acc, attribute) => acc * attribute.values.length, - 1, - ), - ); - - variants.forEach(variant => { - variant.stocks.forEach((_, stockIndex) => { - expect(variant.stocks[stockIndex].quantity).toBe(stock[stockIndex]); - }); - }); - - attribute.values.forEach((attributeValue, attributeValueIndex) => { - variants - .filter( - variant => - variant.attributes.find( - variantAttribute => variantAttribute.id === attribute.id, - ).values[0] === attributeValue.slug, - ) - .forEach(variant => { - variant.channelListings.map((channel, index) => { - expect(channel.price).toBe( - (channels[index].price + attributeValueIndex).toString(), - ); - }); - }); - }); - }); - - it("with constant price and attribute dependent stock", () => { - const price: ChannelPrice[] = [{ channelId: "1", price: "2" }]; - const stock = [80, 40, 30]; - const attribute = attributes.find( - attribute => attribute.id === thirdStep.attributes[0].id, - ); - - const data: ProductVariantCreateFormData = { - ...thirdStep, - price: { - ...thirdStep.price, - channels: price, - mode: "all", - }, - stock: { - ...thirdStep.stock, - attribute: attribute.id, - mode: "attribute", - values: attribute.values.map((attributeValue, attributeValueIndex) => ({ - slug: attributeValue.slug, - value: stock.map( - (_, stockIndex) => stock[stockIndex] * (attributeValueIndex + 1), - ), - })), - }, - }; - - const variants = createVariants(data); - expect(variants).toHaveLength( - thirdStep.attributes.reduce( - (acc, attribute) => acc * attribute.values.length, - 1, - ), - ); - - variants.forEach(variant => { - expect(variant.channelListings).toBe(price); - }); - - attribute.values.forEach((attributeValue, attributeValueIndex) => { - variants - .filter( - variant => - variant.attributes.find( - variantAttribute => variantAttribute.id === attribute.id, - ).values[0] === attributeValue.slug, - ) - .forEach(variant => { - variant.stocks.forEach((_, stockIndex) => { - expect(variant.stocks[stockIndex].quantity).toBe( - stock[stockIndex] * (attributeValueIndex + 1), - ); - }); - }); - }); - }); - - it("with attribute dependent price and stock", () => { - const stock = [80, 40, 30]; - const attribute = attributes.find( - attribute => attribute.id === thirdStep.attributes[0].id, - ); - - const data: ProductVariantCreateFormData = { - ...thirdStep, - price: { - ...thirdStep.price, - attribute: attribute.id, - mode: "attribute", - values: attribute.values.map((attributeValue, index) => ({ - slug: attributeValue.slug, - value: channels.map(channel => ({ - channelId: channel.id, - price: (channel.price + index).toString(), - })), - })), - }, - stock: { - ...thirdStep.stock, - attribute: attribute.id, - mode: "attribute", - values: attribute.values.map((attributeValue, attributeValueIndex) => ({ - slug: attributeValue.slug, - value: stock.map( - (_, stockIndex) => stock[stockIndex] * (attributeValueIndex + 1), - ), - })), - }, - }; - - const variants = createVariants(data); - expect(variants).toHaveLength( - thirdStep.attributes.reduce( - (acc, attribute) => acc * attribute.values.length, - 1, - ), - ); - - attribute.values.forEach((attributeValue, attributeValueIndex) => { - variants - .filter( - variant => - variant.attributes.find( - variantAttribute => variantAttribute.id === attribute.id, - ).values[0] === attributeValue.slug, - ) - .forEach(variant => { - variant.channelListings.map((channel, index) => { - expect(channel.price).toBe( - (channels[index].price + attributeValueIndex).toString(), - ); - }); - }); - }); - - attribute.values.forEach((attributeValue, attributeValueIndex) => { - variants - .filter( - variant => - variant.attributes.find( - variantAttribute => variantAttribute.id === attribute.id, - ).values[0] === attributeValue.slug, - ) - .forEach(variant => { - variant.stocks.forEach((_, stockIndex) => { - expect(variant.stocks[stockIndex].quantity).toBe( - stock[stockIndex] * (attributeValueIndex + 1), - ); - }); - }); - }); - }); -}); diff --git a/src/products/components/ProductVariantCreatorPage/createVariants.ts b/src/products/components/ProductVariantCreatorPage/createVariants.ts deleted file mode 100644 index b65331840..000000000 --- a/src/products/components/ProductVariantCreatorPage/createVariants.ts +++ /dev/null @@ -1,187 +0,0 @@ -import { - BulkAttributeValueInput, - ProductVariantBulkCreateInput, -} from "@saleor/graphql"; - -import { - Attribute, - ChannelPrice, - Price, - ProductVariantCreateFormData, - Stock, -} from "./form"; - -interface CreateVariantAttributeValueInput { - attributeId: string; - attributeValueSlug: string | null; - attributeBooleanValue: boolean | null; -} - -type CreateVariantInput = CreateVariantAttributeValueInput[]; - -function findAttribute( - attributes: CreateVariantInput, - stockOrPrice: Stock | Price, -) { - return attributes.find( - attribute => attribute.attributeId === stockOrPrice.attribute, - ); -} - -function getAttributeValueStock( - attributes: CreateVariantInput, - stock: Stock, -): number[] { - const attribute = findAttribute(attributes, stock); - - const attributeValue = stock.values.find( - attributeValue => attribute.attributeValueSlug === attributeValue.slug, - ); - - return attributeValue.value; -} - -function getAttributeValuePrice( - attributes: CreateVariantInput, - price: Price, -): ChannelPrice[] { - const attribute = findAttribute(attributes, price); - - const attributeValue = price.values.find( - attributeValue => attribute.attributeValueSlug === attributeValue.slug, - ); - - return attributeValue.value; -} - -function getStockFromMode( - attributes: CreateVariantInput, - stock: Stock, - skipValue: number[], -): number[] { - switch (stock.mode) { - case "all": - return stock.value; - case "attribute": - return getAttributeValueStock(attributes, stock); - case "skip": - return skipValue; - } -} - -function getPriceFromMode( - attributes: CreateVariantInput, - price: Price, - skipValue: ChannelPrice[], -): ChannelPrice[] { - switch (price.mode) { - case "all": - return price.channels; - case "attribute": - return getAttributeValuePrice(attributes, price); - case "skip": - return skipValue; - } -} - -function getAttributeFromAttributeValueInput({ - attributeId, - attributeBooleanValue, - attributeValueSlug, -}: CreateVariantAttributeValueInput): BulkAttributeValueInput { - if (attributeBooleanValue === null) { - return { - id: attributeId, - values: attributeValueSlug === null ? [] : [attributeValueSlug], - }; - } - return { - id: attributeId, - boolean: attributeBooleanValue, - }; -} - -function createVariant( - data: ProductVariantCreateFormData, - attributes: CreateVariantInput, -): ProductVariantBulkCreateInput { - const price = getPriceFromMode( - attributes, - data.price, - data.price.channels.map(channel => ({ ...channel, price: "" })), - ); - const stocks = getStockFromMode( - attributes, - data.stock, - data.warehouses.map(() => 0), - ); - - return { - attributes: attributes.map(getAttributeFromAttributeValueInput), - channelListings: price, - sku: "", - stocks: stocks.map((quantity, stockIndex) => ({ - quantity, - warehouse: data.warehouses[stockIndex], - })), - }; -} - -function addAttributeToVariant( - attribute: Attribute, - variant: CreateVariantInput, -): CreateVariantInput[] { - if (attribute.values.length === 0) { - return [ - [ - ...variant, - { - attributeId: attribute.id, - attributeValueSlug: null, - attributeBooleanValue: null, - }, - ], - ]; - } - return attribute.values.map(attributeValue => [ - ...variant, - { - attributeId: attribute.id, - attributeValueSlug: attributeValue.slug, - attributeBooleanValue: attributeValue.value?.boolean ?? null, - }, - ]); -} - -export function createVariantFlatMatrixDimension( - variants: CreateVariantInput[], - attributes: Attribute[], -): CreateVariantInput[] { - if (attributes.length > 0) { - return createVariantFlatMatrixDimension( - variants.flatMap(variant => - addAttributeToVariant(attributes[0], variant), - ), - attributes.slice(1), - ); - } else { - return variants; - } -} - -export function createVariants( - data: ProductVariantCreateFormData, -): ProductVariantBulkCreateInput[] { - if ( - (data.price.mode === "attribute" && !data.price.attribute) || - (data.stock.mode === "attribute" && !data.stock.attribute) - ) { - return []; - } - const variants = createVariantFlatMatrixDimension( - [[]], - data.attributes, - ).map(variant => createVariant(data, variant)); - - return variants; -} diff --git a/src/products/components/ProductVariantCreatorPage/fixtures.ts b/src/products/components/ProductVariantCreatorPage/fixtures.ts deleted file mode 100644 index 658501c04..000000000 --- a/src/products/components/ProductVariantCreatorPage/fixtures.ts +++ /dev/null @@ -1,230 +0,0 @@ -import { ChannelPriceData } from "@saleor/channels/utils"; -import { WarehouseFragment } from "@saleor/graphql"; - -import { createVariants } from "./createVariants"; -import { - createInitialForm, - Price, - ProductVariantCreateFormData, - Stock, -} from "./form"; - -export const channels: ChannelPriceData[] = [ - { currency: "USD", id: "channel-1", name: "Channel1", price: "1" }, - { currency: "USD", id: "channel-2", name: "Channel2", price: "2" }, - { currency: "USD", id: "channel-3", name: "Channel3", price: "3" }, -]; - -export const attributes = [ - { - id: "attr-1", - valueRequired: false, - values: Array(9) - .fill(0) - .map((_, index) => ({ - slug: `val-1-${index + 1}`, - value: { - __typename: "AttributeValue" as "AttributeValue", - id: `val-1-${index + 1}`, - name: `val-1-${index + 1}`, - slug: `val-1-${index + 1}`, - file: null, - reference: null, - richText: null, - boolean: null, - date: null, - dateTime: null, - value: null, - }, - })), - }, - { - id: "attr-2", - valueRequired: false, - values: Array(6) - .fill(0) - .map((_, index) => ({ - slug: `val-2-${index + 1}`, - value: { - __typename: "AttributeValue" as "AttributeValue", - id: `val-2-${index + 1}`, - name: `val-2-${index + 1}`, - slug: `val-2-${index + 1}`, - file: null, - reference: null, - richText: null, - boolean: null, - date: null, - dateTime: null, - value: null, - }, - })), - }, - { - id: "attr-3", - valueRequired: false, - values: Array(4) - .fill(0) - .map((_, index) => ({ - slug: `val-3-${index + 1}`, - value: { - __typename: "AttributeValue" as "AttributeValue", - id: `val-3-${index + 1}`, - name: `val-3-${index + 1}`, - slug: `val-3-${index + 1}`, - file: null, - reference: null, - richText: null, - boolean: null, - date: null, - dateTime: null, - value: null, - }, - })), - }, - { - id: "attr-4", - valueRequired: false, - values: Array(11) - .fill(0) - .map((_, index) => ({ - slug: `val-4-${index + 1}`, - value: { - __typename: "AttributeValue" as "AttributeValue", - id: `val-4-${index + 1}`, - name: `val-4-${index + 1}`, - slug: `val-4-${index + 1}`, - file: null, - reference: null, - richText: null, - boolean: null, - date: null, - dateTime: null, - value: null, - }, - })), - }, -]; - -export const warehouses: WarehouseFragment[] = [ - { - __typename: "Warehouse", - id: "wh-1", - name: "Warehouse 1", - }, - { - __typename: "Warehouse", - id: "wh-2", - name: "Warehouse 2", - }, - { - __typename: "Warehouse", - id: "wh-3", - name: "Warehouse 3", - }, - { - __typename: "Warehouse", - id: "wh-4", - name: "Warehouse 4", - }, -]; - -export const secondStep: ProductVariantCreateFormData = { - ...createInitialForm([], channels, warehouses), - attributes: [ - { - id: attributes[0].id, - valueRequired: attributes[0].valueRequired, - values: [], - }, - { - id: attributes[1].id, - valueRequired: attributes[1].valueRequired, - values: [], - }, - { - id: attributes[3].id, - valueRequired: attributes[3].valueRequired, - values: [], - }, - ], -}; - -export const thirdStep: ProductVariantCreateFormData = { - ...secondStep, - attributes: [ - { - id: attributes[0].id, - valueRequired: attributes[0].valueRequired, - values: [0, 6].map(index => attributes[0].values[index]), - }, - { - id: attributes[1].id, - valueRequired: attributes[1].valueRequired, - values: [1, 3].map(index => attributes[1].values[index]), - }, - { - id: attributes[3].id, - valueRequired: attributes[3].valueRequired, - values: [0, 4].map(index => attributes[3].values[index]), - }, - ], - stock: { - ...secondStep.stock, - value: warehouses.map(() => 0), - }, - warehouses: warehouses.map(warehouse => warehouse.id), -}; - -const price: Price = { - attribute: thirdStep.attributes[1].id, - channels: [ - { channelId: channels[0].id, price: "0" }, - { channelId: channels[1].id, price: "2" }, - { channelId: channels[2].id, price: "2" }, - ], - mode: "attribute", - values: [ - { - slug: thirdStep.attributes[1].values[0].slug, - value: [ - { channelId: channels[0].id, price: "0" }, - { channelId: channels[1].id, price: "2" }, - { channelId: channels[2].id, price: "2" }, - ], - }, - { - slug: thirdStep.attributes[1].values[1].slug, - value: [ - { channelId: channels[0].id, price: "0" }, - { channelId: channels[1].id, price: "2" }, - { channelId: channels[2].id, price: "2" }, - ], - }, - ], -}; -const stock: Stock = { - attribute: thirdStep.attributes[2].id, - mode: "attribute", - value: [], - values: [ - { - slug: thirdStep.attributes[2].values[0].slug, - value: [50, 20, 45, 75], - }, - { - slug: thirdStep.attributes[2].values[1].slug, - value: [80, 50, 85, 105], - }, - ], -}; -export const fourthStep: ProductVariantCreateFormData = { - ...thirdStep, - price, - stock, - variants: createVariants({ - ...thirdStep, - price, - stock, - }), -}; diff --git a/src/products/components/ProductVariantCreatorPage/form.ts b/src/products/components/ProductVariantCreatorPage/form.ts deleted file mode 100644 index 94fd75856..000000000 --- a/src/products/components/ProductVariantCreatorPage/form.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { ChannelPriceData } from "@saleor/channels/utils"; -import { - AttributeValueFragment, - ProductVariantAttributesFragment, - ProductVariantBulkCreateInput, - WarehouseFragment, -} from "@saleor/graphql"; - -export interface ChannelPrice { - channelId: string; - price: string; -} - -export interface AttributeValue { - slug: string; - value: T; -} -export type VariantCreatorPricesAndSkuMode = "all" | "attribute" | "skip"; -export interface Price { - mode: VariantCreatorPricesAndSkuMode; - attribute: string; - channels: ChannelPrice[]; - values: Array>; -} -export interface Stock { - mode: VariantCreatorPricesAndSkuMode; - attribute: string; - value: number[]; - values: Array>; -} -export interface Attribute { - id: string; - valueRequired: boolean; - values: Array>>; -} -export interface ProductVariantCreateFormData { - attributes: Attribute[]; - price: Price; - stock: Stock; - variants: ProductVariantBulkCreateInput[]; - warehouses: string[]; -} - -export const createInitialForm = ( - attributes: ProductVariantAttributesFragment["productType"]["variantAttributes"], - channels: ChannelPriceData[], - warehouses: WarehouseFragment[], -): ProductVariantCreateFormData => { - const channelListings = - channels?.map(channel => ({ - channelId: channel.id, - price: channel.price?.toString() || "", - })) || []; - return { - attributes: attributes.map(attribute => ({ - id: attribute.id, - valueRequired: attribute.valueRequired, - values: [], - })), - price: { - attribute: undefined, - channels: channelListings, - mode: "all", - values: [], - }, - stock: { - attribute: undefined, - mode: "all", - value: warehouses.length === 1 ? [0] : [], - values: [], - }, - variants: [], - warehouses: warehouses.length === 1 ? [warehouses[0].id] : [], - }; -}; diff --git a/src/products/components/ProductVariantCreatorPage/index.ts b/src/products/components/ProductVariantCreatorPage/index.ts deleted file mode 100644 index 5e4e6b074..000000000 --- a/src/products/components/ProductVariantCreatorPage/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./ProductVariantCreatorPage"; -export { default } from "./ProductVariantCreatorPage"; diff --git a/src/products/components/ProductVariantCreatorPage/reducer.test.ts b/src/products/components/ProductVariantCreatorPage/reducer.test.ts deleted file mode 100644 index 71ace0e19..000000000 --- a/src/products/components/ProductVariantCreatorPage/reducer.test.ts +++ /dev/null @@ -1,299 +0,0 @@ -import { - attributes, - channels, - fourthStep, - secondStep, - thirdStep, - warehouses, -} from "./fixtures"; -import { ChannelPrice } from "./form"; -import reducer, { ProductVariantCreateReducerActionType } from "./reducer"; - -function execActions( - initialState: TState, - reducer: (state: TState, action: TAction) => TState, - actions: TAction[], -): TState { - return actions.reduce((acc, action) => reducer(acc, action), initialState); -} - -describe("Reducer is able to", () => { - it("select attribute values", () => { - const state = execActions(secondStep, reducer, [ - { - selectValue: { - attributeId: attributes[0].id, - value: attributes[0].values[0], - }, - type: ProductVariantCreateReducerActionType.selectValue, - }, - { - selectValue: { - attributeId: attributes[0].id, - value: attributes[0].values[6], - }, - - type: ProductVariantCreateReducerActionType.selectValue, - }, - { - selectValue: { - attributeId: attributes[1].id, - value: attributes[1].values[1], - }, - type: ProductVariantCreateReducerActionType.selectValue, - }, - { - selectValue: { - attributeId: attributes[1].id, - value: attributes[1].values[3], - }, - type: ProductVariantCreateReducerActionType.selectValue, - }, - { - selectValue: { - attributeId: attributes[3].id, - value: attributes[3].values[0], - }, - type: ProductVariantCreateReducerActionType.selectValue, - }, - { - selectValue: { - attributeId: attributes[3].id, - value: attributes[3].values[4], - }, - type: ProductVariantCreateReducerActionType.selectValue, - }, - ]); - - expect(state.attributes[0].values).toHaveLength(2); - expect(state.attributes[1].values).toHaveLength(2); - expect(state.attributes[2].values).toHaveLength(2); - expect(state).toMatchSnapshot(); - }); - - it("select price for all variants", () => { - const price = "22.99"; - const state = execActions(thirdStep, reducer, [ - { - applyPriceOrStockToAll: { - mode: "all", - }, - type: ProductVariantCreateReducerActionType.applyPriceToAll, - }, - { - changeApplyPriceToAllValue: { - channelId: channels[0].id, - price, - }, - type: ProductVariantCreateReducerActionType.changeApplyPriceToAllValue, - }, - { - type: ProductVariantCreateReducerActionType.reload, - }, - ]); - expect(state.price.mode).toBe("all"); - expect(state.price.channels[0].price).toBe(price); - expect(state).toMatchSnapshot(); - }); - - it("select warehouses in which stock will be created", () => { - const state = execActions(thirdStep, reducer, [ - { - changeWarehouses: { - warehouseId: warehouses[0].id, - }, - type: ProductVariantCreateReducerActionType.changeWarehouses, - }, - { - changeWarehouses: { - warehouseId: warehouses[2].id, - }, - type: ProductVariantCreateReducerActionType.changeWarehouses, - }, - ]); - - expect(state.warehouses).toHaveLength(2); - expect(state).toMatchSnapshot(); - }); - - it("select stock for all variants", () => { - const quantity = 45; - const warehouseIndex = 1; - const state = execActions(thirdStep, reducer, [ - { - applyPriceOrStockToAll: { - mode: "all", - }, - type: ProductVariantCreateReducerActionType.applyStockToAll, - }, - { - changeApplyStockToAllValue: { - quantity, - warehouseIndex, - }, - type: ProductVariantCreateReducerActionType.changeApplyStockToAllValue, - }, - { - type: ProductVariantCreateReducerActionType.reload, - }, - ]); - - expect(state.stock.mode).toBe("all"); - expect(state.stock.value[warehouseIndex]).toBe(quantity); - expect(state).toMatchSnapshot(); - }); - - it("select price to each attribute value", () => { - const attribute = thirdStep.attributes[0]; - const value = 45.99; - const state = execActions(thirdStep, reducer, [ - { - applyPriceOrStockToAll: { - mode: "attribute", - }, - type: ProductVariantCreateReducerActionType.applyPriceToAll, - }, - { - changeApplyPriceOrStockToAttributeId: { - attributeId: attribute.id, - }, - type: - ProductVariantCreateReducerActionType.changeApplyPriceToAttributeId, - }, - { - changeAttributeValuePrice: { - channelId: channels[0].id, - price: value.toString(), - valueId: attribute.values[0].slug, - }, - type: ProductVariantCreateReducerActionType.changeAttributeValuePrice, - }, - { - changeAttributeValuePrice: { - channelId: channels[1].id, - price: (value + 6).toString(), - valueId: attribute.values[1].slug, - }, - type: ProductVariantCreateReducerActionType.changeAttributeValuePrice, - }, - { - type: ProductVariantCreateReducerActionType.reload, - }, - ]); - - expect(state.price.mode).toBe("attribute"); - expect(state.price.values).toHaveLength( - state.attributes.find(attribute => state.price.attribute === attribute.id) - .values.length, - ); - expect(state).toMatchSnapshot(); - }); - - it("select stock to each attribute value", () => { - const attribute = thirdStep.attributes[0]; - const quantity = 13; - const state = execActions(thirdStep, reducer, [ - { - applyPriceOrStockToAll: { - mode: "attribute", - }, - type: ProductVariantCreateReducerActionType.applyStockToAll, - }, - { - changeApplyPriceOrStockToAttributeId: { - attributeId: attribute.id, - }, - type: - ProductVariantCreateReducerActionType.changeApplyStockToAttributeId, - }, - { - changeAttributeValueStock: { - quantity, - valueId: attribute.values[0].slug, - warehouseIndex: 0, - }, - type: ProductVariantCreateReducerActionType.changeAttributeValueStock, - }, - { - changeAttributeValueStock: { - quantity: quantity + 6, - valueId: attribute.values[1].slug, - warehouseIndex: 0, - }, - type: ProductVariantCreateReducerActionType.changeAttributeValueStock, - }, - { - type: ProductVariantCreateReducerActionType.reload, - }, - ]); - - expect(state.stock.mode).toBe("attribute"); - expect(state.stock.values).toHaveLength( - state.attributes.find(attribute => state.stock.attribute === attribute.id) - .values.length, - ); - expect(state).toMatchSnapshot(); - }); - - it("modify individual variant price", () => { - const value: ChannelPrice = { channelId: channels[0].id, price: "7" }; - const variantIndex = 3; - - const state = execActions(fourthStep, reducer, [ - { - changeVariantPriceData: { - value, - variantIndex, - }, - type: ProductVariantCreateReducerActionType.changeVariantPriceData, - }, - ]); - - expect(state.variants[variantIndex].channelListings[0].price).toBe( - value.price, - ); - expect(state.variants[variantIndex - 1].channelListings).toBe( - fourthStep.variants[variantIndex - 1].channelListings, - ); - expect(state).toMatchSnapshot(); - }); - - it("modify individual variant stock", () => { - const quantity = 5; - const variantIndex = 3; - - const state = execActions(fourthStep, reducer, [ - { - changeVariantStockData: { - stock: { - quantity, - warehouse: warehouses[0].id, - }, - variantIndex, - }, - type: ProductVariantCreateReducerActionType.changeVariantStockData, - }, - ]); - - expect(state.variants[variantIndex].stocks[0].quantity).toBe(quantity); - expect(state.variants[variantIndex - 1].stocks[0].quantity).toBe( - fourthStep.variants[variantIndex - 1].stocks[0].quantity, - ); - expect(state).toMatchSnapshot(); - }); - - it("delete variant", () => { - const variantIndex = 3; - - const state = execActions(fourthStep, reducer, [ - { - deleteVariant: { - variantIndex, - }, - type: ProductVariantCreateReducerActionType.deleteVariant, - }, - ]); - - expect(state.variants.length).toBe(fourthStep.variants.length - 1); - }); -}); diff --git a/src/products/components/ProductVariantCreatorPage/reducer.ts b/src/products/components/ProductVariantCreatorPage/reducer.ts deleted file mode 100644 index 267f3cefa..000000000 --- a/src/products/components/ProductVariantCreatorPage/reducer.ts +++ /dev/null @@ -1,572 +0,0 @@ -import { - AttributeValueFragment, - ProductVariantBulkCreateInput, - StockInput, -} from "@saleor/graphql"; -import { - add, - remove, - removeAtIndex, - toggle, - update, - updateAtIndex, -} from "@saleor/utils/lists"; - -import { createVariants } from "./createVariants"; -import { - AttributeValue, - ProductVariantCreateFormData, - VariantCreatorPricesAndSkuMode, -} from "./form"; - -export enum ProductVariantCreateReducerActionType { - applyPriceToAll, - applyPriceToAttribute, - applyStockToAll, - applyStockToAttribute, - changeApplyPriceToAllValue, - changeApplyPriceToAttributeId, - changeApplyStockToAllValue, - changeApplyStockToAttributeId, - changeAttributeValuePrice, - changeAttributeValueStock, - changeVariantSku, - changeVariantPriceData, - changeVariantStockData, - changeWarehouses, - deleteVariant, - reload, - rebuild, - selectValue, -} -export interface ProductVariantCreateReducerAction { - applyPriceOrStockToAll?: { - mode: VariantCreatorPricesAndSkuMode; - }; - changeApplyPriceToAllValue?: { - channelId: string; - price: string; - }; - changeApplyPriceOrStockToAttributeId?: { - attributeId: string; - }; - changeApplyStockToAllValue?: Record<"quantity" | "warehouseIndex", number>; - changeAttributeValuePrice?: Record<"valueId" | "price" | "channelId", string>; - changeAttributeValueStock?: { - valueId: string; - quantity: number; - warehouseIndex: number; - }; - changeVariantSku?: { - value: string; - variantIndex: number; - }; - changeVariantPriceData?: { - value: { channelId: string; price: string }; - variantIndex: number; - }; - changeVariantStockData?: { - stock: StockInput; - variantIndex: number; - }; - changeWarehouses?: { - warehouseId: string; - }; - deleteVariant?: { - variantIndex: number; - }; - reload?: { - data?: ProductVariantCreateFormData; - }; - selectValue?: { - attributeId: string; - value: AttributeValue>; - }; - type: ProductVariantCreateReducerActionType; -} - -function getVariantId(variant: ProductVariantBulkCreateInput): string { - return variant.attributes - .map(attribute => attribute.values.join(":")) - .join("-"); -} - -function merge( - prev: ProductVariantBulkCreateInput[], - update: ProductVariantBulkCreateInput[], -): ProductVariantBulkCreateInput[] { - const prevIds = prev.map(getVariantId); - const updateIds = update.map(getVariantId); - return [ - ...prev - .filter(variant => updateIds.includes(getVariantId(variant))) - .map(variant => { - const updatedVariant = update.find( - v => getVariantId(v) === getVariantId(variant), - ); - - return { - ...updatedVariant, - sku: variant.sku, - }; - }), - ...update.filter(variant => !prevIds.includes(getVariantId(variant))), - ]; -} - -function rebuild( - state: ProductVariantCreateFormData, -): ProductVariantCreateFormData { - return { - ...state, - variants: merge(state.variants, createVariants(state)), - }; -} - -function selectValue( - prevState: ProductVariantCreateFormData, - attributeId: string, - value: AttributeValue>, -): ProductVariantCreateFormData { - const attribute = prevState.attributes.find( - attribute => attribute.id === attributeId, - ); - - const values = toggle(value, attribute.values, (a, b) => a.slug === b.slug); - const updatedAttributes = add( - { - id: attributeId, - valueRequired: attribute.valueRequired, - values, - }, - remove(attribute, prevState.attributes, (a, b) => a.id === b.id), - ); - - const priceValues = - prevState.price.attribute === attributeId - ? toggle( - { - slug: value.slug, - value: [], - }, - prevState.price.values, - (a, b) => a.slug === b.slug, - ) - : prevState.price.values; - - const stockValues = - prevState.stock.attribute === attributeId - ? toggle( - { - slug: value.slug, - value: [], - }, - prevState.stock.values, - (a, b) => a.slug === b.slug, - ) - : prevState.stock.values; - - return { - ...prevState, - attributes: updatedAttributes, - price: { - ...prevState.price, - values: priceValues, - }, - stock: { - ...prevState.stock, - values: stockValues, - }, - }; -} - -function applyPriceToAll( - state: ProductVariantCreateFormData, - mode: VariantCreatorPricesAndSkuMode, -): ProductVariantCreateFormData { - return { - ...state, - price: { - ...state.price, - mode, - }, - }; -} - -function applyStockToAll( - state: ProductVariantCreateFormData, - mode: VariantCreatorPricesAndSkuMode, -): ProductVariantCreateFormData { - return { - ...state, - stock: { - ...state.stock, - mode, - }, - }; -} - -function changeAttributeValuePrice( - state: ProductVariantCreateFormData, - attributeValueSlug: string, - price: string, - channelId: string, -): ProductVariantCreateFormData { - const index = state.price.values.findIndex( - value => value.slug === attributeValueSlug, - ); - - if (index === -1) { - throw new Error(`Value with id ${attributeValueSlug} not found`); - } - - const channels = state.price.values[index].value; - const channelIndex = channels.findIndex( - channel => channel.channelId === channelId, - ); - - const values = updateAtIndex( - { - slug: attributeValueSlug, - value: updateAtIndex({ channelId, price }, channels, channelIndex), - }, - state.price.values, - index, - ); - - return { - ...state, - price: { - ...state.price, - values, - }, - }; -} - -function changeAttributeValueStock( - state: ProductVariantCreateFormData, - attributeValueSlug: string, - quantity: number, - warehouseIndex: number, -): ProductVariantCreateFormData { - const index = state.stock.values.findIndex( - value => value.slug === attributeValueSlug, - ); - - if (index === -1) { - throw new Error(`Value with id ${attributeValueSlug} not found`); - } - - const values = updateAtIndex( - { - ...state.stock.values[index], - value: updateAtIndex( - quantity, - state.stock.values[index].value, - warehouseIndex, - ), - }, - state.stock.values, - index, - ); - - return { - ...state, - stock: { - ...state.stock, - values, - }, - }; -} - -function changeApplyPriceToAttributeId( - state: ProductVariantCreateFormData, - attributeId: string, -): ProductVariantCreateFormData { - const attribute = state.attributes.find( - attribute => attribute.id === attributeId, - ); - const values = attribute.values.map(value => ({ - slug: value.slug, - value: [], - })); - - return { - ...state, - price: { - ...state.price, - attribute: attributeId, - values, - }, - }; -} - -function changeApplyStockToAttributeId( - state: ProductVariantCreateFormData, - attributeId: string, -): ProductVariantCreateFormData { - const attribute = state.attributes.find( - attribute => attribute.id === attributeId, - ); - const values = attribute.values.map(value => ({ - slug: value.slug, - value: [], - })); - - return { - ...state, - stock: { - ...state.stock, - attribute: attributeId, - values, - }, - }; -} - -function changeApplyPriceToAllValue( - state: ProductVariantCreateFormData, - channelId: string, - price: string, -): ProductVariantCreateFormData { - const prevChannels = [...state.price.channels]; - const channelIndex = prevChannels?.findIndex( - channel => channelId === channel.channelId, - ); - prevChannels[channelIndex] = { channelId, price }; - return { - ...state, - price: { - ...state.price, - channels: prevChannels, - }, - }; -} - -function changeApplyStockToAllValue( - state: ProductVariantCreateFormData, - warehouseIndex: number, - quantity: number, -): ProductVariantCreateFormData { - return { - ...state, - stock: { - ...state.stock, - value: updateAtIndex(quantity, state.stock.value, warehouseIndex), - }, - }; -} - -function changeVariantSku( - state: ProductVariantCreateFormData, - value: string, - variantIndex: number, -): ProductVariantCreateFormData { - const variant = { - ...state.variants[variantIndex], - }; - variant.sku = value; - - return { - ...state, - variants: updateAtIndex(variant, state.variants, variantIndex), - }; -} - -function changeVariantStockData( - state: ProductVariantCreateFormData, - stock: StockInput, - variantIndex: number, -): ProductVariantCreateFormData { - const variant = { - ...state.variants[variantIndex], - }; - variant.stocks = update( - stock, - variant.stocks, - (a, b) => a.warehouse === b.warehouse, - ); - - return { - ...state, - variants: updateAtIndex(variant, state.variants, variantIndex), - }; -} - -function changeVariantPriceData( - state: ProductVariantCreateFormData, - value: { channelId: string; price: string }, - variantIndex: number, -): ProductVariantCreateFormData { - const { channelId, price } = value; - const variant = { - ...state.variants[variantIndex], - }; - const channelIndex = variant.channelListings.findIndex( - listing => listing.channelId === channelId, - ); - const updatedVariant = { - ...variant, - channelListings: updateAtIndex( - { channelId, price }, - [...variant.channelListings], - channelIndex, - ), - }; - return { - ...state, - variants: updateAtIndex(updatedVariant, [...state.variants], variantIndex), - }; -} - -function changeWarehouses( - state: ProductVariantCreateFormData, - warehouseId: string, -): ProductVariantCreateFormData { - const warehouses = toggle(warehouseId, state.warehouses, (a, b) => a === b); - const added = warehouses.length > state.warehouses.length; - - if (added) { - return { - ...state, - stock: { - ...state.stock, - value: [...state.stock.value, 0], - values: state.stock.values.map(stockValue => ({ - ...stockValue, - value: [...stockValue.value, 0], - })), - }, - warehouses, - }; - } - - const warehouseIndex = state.warehouses.indexOf(warehouseId); - - return { - ...state, - stock: { - ...state.stock, - value: removeAtIndex(state.stock.value, warehouseIndex), - values: state.stock.values.map(stockValue => ({ - ...stockValue, - value: removeAtIndex(stockValue.value, warehouseIndex), - })), - }, - warehouses, - }; -} - -function deleteVariant( - state: ProductVariantCreateFormData, - variantIndex: number, -): ProductVariantCreateFormData { - const variants = removeAtIndex(state.variants, variantIndex); - - return { - ...state, - variants: variants.length - ? variants - : createVariants({ - ...state, - attributes: state.attributes.map(attribute => ({ - id: attribute.id, - valueRequired: attribute.valueRequired, - values: [], - })), - variants, - }), - }; -} - -function createVariantMatrix( - state: ProductVariantCreateFormData, -): ProductVariantCreateFormData { - return { - ...state, - variants: createVariants(state), - }; -} - -function reduceProductVariantCreateFormData( - prevState: ProductVariantCreateFormData, - action: ProductVariantCreateReducerAction, -) { - switch (action.type) { - case ProductVariantCreateReducerActionType.selectValue: - return selectValue( - prevState, - action.selectValue.attributeId, - action.selectValue.value, - ); - case ProductVariantCreateReducerActionType.applyPriceToAll: - return applyPriceToAll(prevState, action.applyPriceOrStockToAll.mode); - case ProductVariantCreateReducerActionType.applyStockToAll: - return applyStockToAll(prevState, action.applyPriceOrStockToAll.mode); - case ProductVariantCreateReducerActionType.changeAttributeValuePrice: - return changeAttributeValuePrice( - prevState, - action.changeAttributeValuePrice.valueId, - action.changeAttributeValuePrice.price, - action.changeAttributeValuePrice.channelId, - ); - case ProductVariantCreateReducerActionType.changeAttributeValueStock: - return changeAttributeValueStock( - prevState, - action.changeAttributeValueStock.valueId, - action.changeAttributeValueStock.quantity, - action.changeAttributeValueStock.warehouseIndex, - ); - case ProductVariantCreateReducerActionType.changeApplyPriceToAttributeId: - return changeApplyPriceToAttributeId( - prevState, - action.changeApplyPriceOrStockToAttributeId.attributeId, - ); - case ProductVariantCreateReducerActionType.changeApplyStockToAttributeId: - return changeApplyStockToAttributeId( - prevState, - action.changeApplyPriceOrStockToAttributeId.attributeId, - ); - case ProductVariantCreateReducerActionType.changeApplyPriceToAllValue: - return changeApplyPriceToAllValue( - prevState, - action.changeApplyPriceToAllValue.channelId, - action.changeApplyPriceToAllValue.price, - ); - case ProductVariantCreateReducerActionType.changeApplyStockToAllValue: - return changeApplyStockToAllValue( - prevState, - action.changeApplyStockToAllValue.warehouseIndex, - action.changeApplyStockToAllValue.quantity, - ); - case ProductVariantCreateReducerActionType.changeVariantSku: - return changeVariantSku( - prevState, - action.changeVariantSku.value, - action.changeVariantSku.variantIndex, - ); - case ProductVariantCreateReducerActionType.changeVariantPriceData: - return changeVariantPriceData( - prevState, - action.changeVariantPriceData.value, - action.changeVariantPriceData.variantIndex, - ); - case ProductVariantCreateReducerActionType.changeVariantStockData: - return changeVariantStockData( - prevState, - action.changeVariantStockData.stock, - action.changeVariantStockData.variantIndex, - ); - case ProductVariantCreateReducerActionType.changeWarehouses: - return changeWarehouses(prevState, action.changeWarehouses.warehouseId); - case ProductVariantCreateReducerActionType.deleteVariant: - return deleteVariant(prevState, action.deleteVariant.variantIndex); - case ProductVariantCreateReducerActionType.reload: - return action.reload?.data || createVariantMatrix(prevState); - case ProductVariantCreateReducerActionType.rebuild: - return rebuild(prevState); - default: - return prevState; - } -} - -export default reduceProductVariantCreateFormData; diff --git a/src/products/components/ProductVariantCreatorPage/types.ts b/src/products/components/ProductVariantCreatorPage/types.ts deleted file mode 100644 index 865c79e64..000000000 --- a/src/products/components/ProductVariantCreatorPage/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -export enum ProductVariantCreatorStep { - values, - prices, - summary, -} diff --git a/src/products/components/ProductVariantCreatorPage/utils.ts b/src/products/components/ProductVariantCreatorPage/utils.ts deleted file mode 100644 index d50b5426b..000000000 --- a/src/products/components/ProductVariantCreatorPage/utils.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { - AttributeValueFragment, - ProductVariantAttributesFragment, - SearchAttributeValuesQuery, -} from "@saleor/graphql"; -import { getById } from "@saleor/orders/components/OrderReturnPage/utils"; -import { RelayToFlat } from "@saleor/types"; -import uniqBy from "lodash/uniqBy"; - -import { AttributeValue, ProductVariantCreateFormData } from "./form"; - -export function getPriceAttributeValues( - data: ProductVariantCreateFormData, - attributes: ProductVariantAttributesFragment["productType"]["variantAttributes"], -): AttributeValueFragment[] { - return data.price.mode === "all" - ? null - : data.price.attribute - ? attributes - .find(attribute => attribute.id === data.price.attribute) - .choices.edges.filter(value => - data.attributes - .find(attribute => attribute.id === data.price.attribute) - .values.some( - attributeValue => attributeValue.slug === value.node.slug, - ), - ) - .map(value => value.node) - : []; -} - -export function getStockAttributeValues( - data: ProductVariantCreateFormData, - attributes: ProductVariantAttributesFragment["productType"]["variantAttributes"], -): AttributeValueFragment[] { - return data.stock.mode === "all" - ? null - : data.stock.attribute - ? attributes - .find(attribute => attribute.id === data.stock.attribute) - .choices.edges.filter(value => - data.attributes - .find(attribute => attribute.id === data.stock.attribute) - .values.some( - attributeValue => attributeValue.slug === value.node.slug, - ), - ) - .map(value => value.node) - : []; -} - -export const getBySlug = (slugToCompare: string) => (obj: { slug: string }) => - obj.slug === slugToCompare; - -export const getBooleanAttributeValue = ( - attributeName: string, - attributeValue: boolean, -): AttributeValue> => ({ - slug: attributeValue.toString(), - value: { - boolean: attributeValue, - name: `${attributeName}: ${attributeValue ? "Yes" : "No"}`, - }, -}); - -export const getBasicAttributeValue = ( - attributeId: string, - attributeValue: string, - attributeValues: RelayToFlat< - SearchAttributeValuesQuery["attribute"]["choices"] - >, - data: ProductVariantCreateFormData, -): AttributeValue> => { - const dataAttribute = data.attributes.find(getById(attributeId)); - - return { - slug: attributeValue, - value: - dataAttribute?.values.find(getBySlug(attributeValue))?.value || - attributeValues.find(getBySlug(attributeValue)), - }; -}; - -export function dedupeListings( - data: ProductVariantCreateFormData, -): ProductVariantCreateFormData { - return { - ...data, - variants: data.variants.map(variant => ({ - ...variant, - channelListings: uniqBy(variant.channelListings, "channelId"), - })), - }; -} diff --git a/src/products/components/ProductVariants/ProductVariants.tsx b/src/products/components/ProductVariants/ProductVariants.tsx index 3899ed2b5..0935d1921 100644 --- a/src/products/components/ProductVariants/ProductVariants.tsx +++ b/src/products/components/ProductVariants/ProductVariants.tsx @@ -225,7 +225,6 @@ interface ProductVariantsProps extends ListActions, ChannelProps { variants: ProductDetailsVariantFragment[]; onVariantReorder: ReorderAction; onSetDefaultVariant(variant: ProductDetailsVariantFragment[][0]); - onVariantsAdd?(); } const numberOfColumns = 7; @@ -237,7 +236,6 @@ export const ProductVariants: React.FC = props => { limits, variants, product, - onVariantsAdd, onVariantReorder, onSetDefaultVariant, isChecked, @@ -263,33 +261,18 @@ export const ProductVariants: React.FC = props => { description: "section header", })} toolbar={ - hasVariants ? ( - - ) : ( - - ) + } /> diff --git a/src/products/index.tsx b/src/products/index.tsx index 041b8b519..b51d321d7 100644 --- a/src/products/index.tsx +++ b/src/products/index.tsx @@ -19,7 +19,6 @@ import { ProductUrlQueryParams, productVariantAddPath, ProductVariantAddUrlQueryParams, - productVariantCreatorPath, productVariantEditPath, ProductVariantEditUrlQueryParams, } from "./urls"; @@ -29,7 +28,6 @@ import ProductListComponent from "./views/ProductList"; import ProductUpdateComponent from "./views/ProductUpdate"; import ProductVariantComponent from "./views/ProductVariant"; import ProductVariantCreateComponent from "./views/ProductVariantCreate"; -import ProductVariantCreatorComponent from "./views/ProductVariantCreator"; const ProductList: React.FC> = ({ location }) => { const qs = parseQs(location.search.substr(1)); @@ -113,12 +111,6 @@ const ProductVariantCreate: React.FC> = ({ ); }; -const ProductVariantCreator: React.FC> = ({ match }) => ( - -); - const Component = () => { const intl = useIntl(); @@ -128,10 +120,6 @@ const Component = () => { - export const productPath = (id: string) => urlJoin(productSection + id); export type ProductUrlDialog = - | "add-variants" | "remove" | "remove-variants" | "assign-attribute-value" @@ -107,11 +106,6 @@ export const productVariantEditUrl = ( "?" + stringifyQs(params); -export const productVariantCreatorPath = (productId: string) => - urlJoin(productSection, productId, "variant-creator"); -export const productVariantCreatorUrl = (productId: string) => - productVariantCreatorPath(encodeURIComponent(productId)); - export type ProductVariantAddUrlDialog = "assign-attribute-value"; export type ProductVariantAddUrlQueryParams = Dialog< ProductVariantAddUrlDialog diff --git a/src/products/views/ProductUpdate/ProductUpdate.tsx b/src/products/views/ProductUpdate/ProductUpdate.tsx index 45ca5ffc7..006b34367 100644 --- a/src/products/views/ProductUpdate/ProductUpdate.tsx +++ b/src/products/views/ProductUpdate/ProductUpdate.tsx @@ -49,7 +49,6 @@ import useShop from "@saleor/hooks/useShop"; import useStateFromProps from "@saleor/hooks/useStateFromProps"; import { commonMessages, errorMessages } from "@saleor/intl"; import { DeleteIcon, IconButton } from "@saleor/macaw-ui"; -import ProductVariantCreateDialog from "@saleor/products/components/ProductVariantCreateDialog"; import ProductVariantEndPreorderDialog from "@saleor/products/components/ProductVariantEndPreorderDialog"; import useCategorySearch from "@saleor/searches/useCategorySearch"; import useCollectionSearch from "@saleor/searches/useCollectionSearch"; @@ -71,8 +70,6 @@ import { productUrl, ProductUrlDialog, ProductUrlQueryParams, - productVariantAddUrl, - productVariantCreatorUrl, } from "../../urls"; import { CHANNELS_AVAILIABILITY_MODAL_SELECTOR, @@ -401,9 +398,6 @@ export const ProductUpdate: React.FC = ({ id, params }) => { const handleBack = () => navigate(productListUrl()); - const handleVariantAdd = () => navigate(productVariantAddUrl(id)); - const handleVariantsAdd = () => navigate(productVariantCreatorUrl(id)); - const handleImageDelete = (id: string) => () => deleteProductImage({ variables: { id } }); @@ -598,7 +592,6 @@ export const ProductUpdate: React.FC = ({ id, params }) => { onMediaUrlUpload={handleMediaUrlUpload} onSubmit={handleSubmit} onWarehouseConfigure={() => navigate(warehouseAddPath)} - onVariantsAdd={() => openModal("add-variants")} onVariantReorder={handleVariantReorder} onVariantEndPreorderDialogOpen={() => setIsEndPreorderModalOpened(true)} onImageUpload={handleImageUpload} @@ -678,13 +671,6 @@ export const ProductUpdate: React.FC = ({ id, params }) => { /> - - option === "multiple" ? handleVariantsAdd() : handleVariantAdd() - } - /> {isSimpleProduct && !!product?.variants?.[0]?.preorder && ( = ({ - id, -}) => { - const navigate = useNavigator(); - const notify = useNotifier(); - const intl = useIntl(); - const { data } = useCreateMultipleVariantsDataQuery({ - displayLoader: true, - variables: { - id, - firstValues: 10, - }, - }); - const [ - bulkProductVariantCreate, - bulkProductVariantCreateOpts, - ] = useProductVariantBulkCreateMutation({ - onCompleted: data => { - if (data.productVariantBulkCreate.errors.length === 0) { - notify({ - status: "success", - text: intl.formatMessage({ - id: "oChkS4", - defaultMessage: "Successfully created variants", - description: "success message", - }), - }); - navigate(productUrl(id)); - } - }, - }); - const limitOpts = useShopLimitsQuery({ - variables: { - productVariants: true, - }, - }); - - const { - loadMore: loadMoreAttributeValues, - search: searchAttributeValues, - reset: searchAttributeReset, - result: searchAttributeValuesOpts, - } = useAttributeValueSearchHandler(DEFAULT_INITIAL_SEARCH_DATA); - - const fetchMoreAttributeValues = { - hasMore: !!searchAttributeValuesOpts.data?.attribute?.choices?.pageInfo - ?.hasNextPage, - loading: !!searchAttributeValuesOpts.loading, - onFetchMore: loadMoreAttributeValues, - }; - - const attributeValues = - mapEdgesToItems(searchAttributeValuesOpts?.data?.attribute.choices) || []; - - return ( - <> - - ({ - currency: listing.channel.currencyCode, - id: listing.channel.id, - name: listing.channel.name, - price: "", - }))} - attributes={data?.product?.productType?.variantAttributes || []} - attributeValues={attributeValues} - fetchAttributeValues={searchAttributeValues} - fetchMoreAttributeValues={fetchMoreAttributeValues} - limits={limitOpts.data?.shop?.limits} - onSubmit={inputs => - bulkProductVariantCreate({ - variables: { id, inputs }, - }) - } - onAttributeSelectBlur={searchAttributeReset} - warehouses={mapEdgesToItems(data?.warehouses) || []} - /> - - ); -}; -ProductVariantCreator.displayName = "ProductVariantCreator"; -export default ProductVariantCreator; diff --git a/src/products/views/ProductVariantCreator/index.ts b/src/products/views/ProductVariantCreator/index.ts deleted file mode 100644 index 033e63894..000000000 --- a/src/products/views/ProductVariantCreator/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./ProductVariantCreator"; -export { default } from "./ProductVariantCreator"; diff --git a/src/storybook/__snapshots__/Stories.test.ts.snap b/src/storybook/__snapshots__/Stories.test.ts.snap index ddb885c68..3d9639a14 100644 --- a/src/storybook/__snapshots__/Stories.test.ts.snap +++ b/src/storybook/__snapshots__/Stories.test.ts.snap @@ -4247,7 +4247,7 @@ exports[`Storyshots Generics / AddressEdit default 1`] = `