From 11bddd3d1b6eb6ba33b31b704bc106341d732bb5 Mon Sep 17 00:00:00 2001 From: Dawid Tarasiuk Date: Wed, 20 Jan 2021 17:37:36 +0100 Subject: [PATCH] Product reference attributes (#948) * Update changelog with product reference attributes * 2068 - Add product reference type to attributes (#949) * 2069 - Add product reference attribute search implementation (#951) --- CHANGELOG.md | 1 + locale/defaultMessages.json | 4 + schema.graphql | 25 ++--- .../AttributeDetails/AttributeDetails.tsx | 8 ++ src/attributes/utils/data.ts | 95 ++++++++++++++++++- src/attributes/utils/handlers.ts | 53 ++++++++++- .../AssignAttributeValueDialog.tsx | 8 +- src/components/Attributes/Attributes.tsx | 17 ++-- src/components/Attributes/fixtures.ts | 21 ++-- src/fragments/pages.ts | 2 + src/fragments/products.ts | 2 + src/fragments/types/MetadataFragment.ts | 2 +- src/fragments/types/PageAttributesFragment.ts | 4 +- src/fragments/types/PageDetailsFragment.ts | 4 +- src/fragments/types/Product.ts | 3 +- src/fragments/types/ProductVariant.ts | 4 +- .../types/ProductVariantAttributesFragment.ts | 3 +- .../types/SelectedVariantAttributeFragment.ts | 3 +- .../types/VariantAttributeFragment.ts | 3 +- .../PageDetailsPage/PageDetailsPage.tsx | 34 +++++-- src/pages/components/PageDetailsPage/form.tsx | 52 +++++++--- src/pages/fixtures.ts | 4 + src/pages/types/PageCreate.ts | 4 +- src/pages/types/PageDetails.ts | 4 +- src/pages/types/PageUpdate.ts | 4 +- src/pages/utils/data.ts | 18 +--- src/pages/views/PageCreate.tsx | 24 ++++- src/pages/views/PageDetails.tsx | 22 ++++- src/productTypes/fixtures.ts | 12 +++ .../ProductCreatePage/ProductCreatePage.tsx | 34 +++++-- .../components/ProductCreatePage/form.tsx | 32 ++++++- .../ProductUpdatePage.test.tsx | 1 + .../ProductUpdatePage/ProductUpdatePage.tsx | 34 +++++-- .../components/ProductUpdatePage/form.tsx | 32 ++++++- .../ProductVariantCreatePage.tsx | 34 +++++-- .../ProductVariantCreatePage/form.tsx | 32 ++++++- .../ProductVariantPage/ProductVariantPage.tsx | 34 +++++-- .../components/ProductVariantPage/form.tsx | 32 ++++++- src/products/fixtures.ts | 7 ++ .../types/CreateMultipleVariantsData.ts | 3 +- .../types/ProductChannelListingUpdate.ts | 3 +- src/products/types/ProductCreate.ts | 3 +- src/products/types/ProductDetails.ts | 3 +- src/products/types/ProductImageCreate.ts | 3 +- src/products/types/ProductImageUpdate.ts | 3 +- src/products/types/ProductUpdate.ts | 3 +- .../ProductVariantChannelListingUpdate.ts | 4 +- .../types/ProductVariantCreateData.ts | 4 +- src/products/types/ProductVariantDetails.ts | 4 +- src/products/types/ProductVariantReorder.ts | 3 +- .../types/ProductVariantSetDefault.ts | 3 +- src/products/types/SimpleProductUpdate.ts | 11 ++- src/products/types/VariantCreate.ts | 4 +- src/products/types/VariantImageAssign.ts | 4 +- src/products/types/VariantImageUnassign.ts | 4 +- src/products/types/VariantUpdate.ts | 6 +- src/products/utils/data.ts | 4 + .../views/ProductCreate/ProductCreate.tsx | 26 ++++- .../views/ProductUpdate/ProductUpdate.tsx | 24 ++++- src/products/views/ProductVariant.tsx | 20 +++- src/products/views/ProductVariantCreate.tsx | 20 +++- src/searches/types/SearchPageTypes.ts | 3 +- src/searches/types/SearchProductTypes.ts | 3 +- src/searches/usePageTypeSearch.ts | 1 + src/searches/useProductTypeSearch.ts | 1 + .../stories/pages/PageDetailsPage.tsx | 1 + .../stories/products/ProductCreatePage.tsx | 3 + .../stories/products/ProductUpdatePage.tsx | 1 + .../products/ProductVariantCreatePage.tsx | 5 + .../stories/products/ProductVariantPage.tsx | 4 + src/types/globalTypes.ts | 2 + src/utils/maps.ts | 10 ++ src/utils/metadata/types/UpdateMetadata.ts | 2 +- .../metadata/types/UpdatePrivateMetadata.ts | 2 +- 74 files changed, 740 insertions(+), 172 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe0127347..404849087 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ All notable, unreleased changes to this project will be documented in this file. - Add shipping delivery days - #914 by @orzechdev - Guard against non-staff users logging in - #947 by @jwm0 - Add reference attributes - #917 by @orzechdev +- Add product reference attributes - #948 by @orzechdev # 2.11.1 diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json index a328c8454..c876de88e 100644 --- a/locale/defaultMessages.json +++ b/locale/defaultMessages.json @@ -813,6 +813,10 @@ "context": "page attribute entity type", "string": "Pages" }, + "src_dot_attributes_dot_components_dot_AttributeDetails_dot_product": { + "context": "product attribute entity type", + "string": "Products" + }, "src_dot_attributes_dot_components_dot_AttributeDetails_dot_references": { "context": "references attribute type", "string": "References" diff --git a/schema.graphql b/schema.graphql index e3f8eb49f..1ef686df7 100644 --- a/schema.graphql +++ b/schema.graphql @@ -454,6 +454,7 @@ type AttributeDelete { enum AttributeEntityTypeEnum { PAGE + PRODUCT } type AttributeError { @@ -570,7 +571,6 @@ type AttributeValue implements Node { id: ID! name: String slug: String - type: AttributeValueType @deprecated(reason: "Use the `inputType` field to determine the type of attribute's value. This field will be removed after 2020-07-31.") translation(languageCode: LanguageCodeEnum!): AttributeValueTranslation inputType: AttributeInputTypeEnum reference: ID @@ -628,13 +628,6 @@ type AttributeValueTranslation implements Node { language: LanguageDisplay! } -enum AttributeValueType { - COLOR - GRADIENT - URL - STRING -} - type AttributeValueUpdate { errors: [Error!]! @deprecated(reason: "Use typed errors with error codes. This field will be removed after 2020-07-31.") attribute: Attribute @@ -2319,10 +2312,12 @@ type Margin { stop: Int } -type Menu implements Node { +type Menu implements Node & ObjectWithMetadata { id: ID! name: String! slug: String! + privateMetadata: [MetadataItem]! + metadata: [MetadataItem]! items: [MenuItem] } @@ -2389,7 +2384,7 @@ input MenuInput { slug: String } -type MenuItem implements Node { +type MenuItem implements Node & ObjectWithMetadata { id: ID! name: String! menu: Menu! @@ -2398,6 +2393,8 @@ type MenuItem implements Node { collection: Collection page: Page level: Int! + privateMetadata: [MetadataItem]! + metadata: [MetadataItem]! children: [MenuItem] url: String translation(languageCode: LanguageCodeEnum!): MenuItemTranslation @@ -2841,6 +2838,7 @@ type Order implements Node & ObjectWithMetadata { shippingMethodName: String channel: Channel! shippingPrice: TaxedMoney + shippingTaxRate: Float! token: String! voucher: Voucher giftCards: [GiftCard] @@ -2937,6 +2935,7 @@ input OrderDraftFilterInput { customer: String created: DateRangeInput search: String + channels: [ID] } type OrderError { @@ -4241,12 +4240,8 @@ type ProductVariant implements Node & ObjectWithMetadata { weight: Weight privateMetadata: [MetadataItem]! metadata: [MetadataItem]! - quantity: Int! @deprecated(reason: "Use the stock field instead. This field will be removed after 2020-07-31.") - quantityAllocated: Int @deprecated(reason: "Use the stock field instead. This field will be removed after 2020-07-31.") - stockQuantity: Int! @deprecated(reason: "Use the quantityAvailable field instead. This field will be removed after 2020-07-31.") channelListings: [ProductVariantChannelListing!] pricing: VariantPricingInfo - isAvailable: Boolean @deprecated(reason: "Use the stock field instead. This field will be removed after 2020-07-31.") attributes(variantSelection: VariantAttributeScope): [SelectedAttribute!]! costPrice: Money margin: Int @@ -4484,7 +4479,7 @@ type Query { permissionGroup(id: ID!): Group me: User staffUsers(filter: StaffUserInput, sortBy: UserSortingInput, before: String, after: String, first: Int, last: Int): UserCountableConnection - user(id: ID!): User + user(id: ID, email: String): User _entities(representations: [_Any]): [_Entity] _service: _Service } diff --git a/src/attributes/components/AttributeDetails/AttributeDetails.tsx b/src/attributes/components/AttributeDetails/AttributeDetails.tsx index 1138547ff..83f204f0e 100644 --- a/src/attributes/components/AttributeDetails/AttributeDetails.tsx +++ b/src/attributes/components/AttributeDetails/AttributeDetails.tsx @@ -71,6 +71,10 @@ const entityTypeMessages = defineMessages({ page: { defaultMessage: "Pages", description: "page attribute entity type" + }, + product: { + defaultMessage: "Products", + description: "product attribute entity type" } }); @@ -122,6 +126,10 @@ const AttributeDetails: React.FC = props => { { label: intl.formatMessage(entityTypeMessages.page), value: AttributeEntityTypeEnum.PAGE + }, + { + label: intl.formatMessage(entityTypeMessages.product), + value: AttributeEntityTypeEnum.PRODUCT } ]; diff --git a/src/attributes/utils/data.ts b/src/attributes/utils/data.ts index 718fe479c..8d53dd5ff 100644 --- a/src/attributes/utils/data.ts +++ b/src/attributes/utils/data.ts @@ -10,10 +10,13 @@ import { FormsetData } from "@saleor/hooks/useFormset"; import { PageDetails_page_attributes } from "@saleor/pages/types/PageDetails"; import { ProductDetails_product_attributes } from "@saleor/products/types/ProductDetails"; import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages"; +import { SearchProducts_search_edges_node } from "@saleor/searches/types/SearchProducts"; import { + AttributeEntityTypeEnum, AttributeInputTypeEnum, AttributeValueInput } from "@saleor/types/globalTypes"; +import { mapNodeToChoice, mapPagesToChoices } from "@saleor/utils/maps"; import { MutationFetchResult } from "react-apollo"; import { AttributePageFormData } from "../components/AttributePage"; @@ -25,6 +28,11 @@ export const ATTRIBUTE_TYPES_WITH_DEDICATED_VALUES = [ AttributeInputTypeEnum.MULTISELECT ]; +export interface AttributeReference { + label: string; + value: string; +} + function getSimpleAttributeData( data: AttributePageFormData, values: AttributeValueEditDialogFormData[] @@ -199,7 +207,7 @@ export const getFileAttributeDisplayData = ( return attribute; }; -export const getReferenceAttributeDisplayData = ( +export const getPageReferenceAttributeDisplayData = ( attribute: AttributeInput, referencePages: SearchPages_search_edges_node[] ) => ({ @@ -208,21 +216,67 @@ export const getReferenceAttributeDisplayData = ( ...attribute.data, references: referencePages?.length > 0 && attribute.value?.length > 0 - ? attribute.value.map(value => - referencePages.find(reference => reference.id === value) + ? mapPagesToChoices( + attribute.value.map(value => { + const reference = referencePages.find( + reference => reference.id === value + ); + return { ...reference }; + }) ) : [] } }); +export const getProductReferenceAttributeDisplayData = ( + attribute: AttributeInput, + referenceProducts: SearchProducts_search_edges_node[] +) => ({ + ...attribute, + data: { + ...attribute.data, + references: + referenceProducts?.length > 0 && attribute.value?.length > 0 + ? mapNodeToChoice( + attribute.value.map(value => { + const reference = referenceProducts.find( + reference => reference.id === value + ); + return { ...reference }; + }) + ) + : [] + } +}); + +export const getReferenceAttributeDisplayData = ( + attribute: AttributeInput, + referencePages: SearchPages_search_edges_node[], + referenceProducts: SearchProducts_search_edges_node[] +) => { + if (attribute.data.entityType === AttributeEntityTypeEnum.PAGE) { + return getPageReferenceAttributeDisplayData(attribute, referencePages); + } else if (attribute.data.entityType === AttributeEntityTypeEnum.PRODUCT) { + return getProductReferenceAttributeDisplayData( + attribute, + referenceProducts + ); + } +}; + export const getAttributesDisplayData = ( attributes: AttributeInput[], attributesWithNewFileValue: FormsetData, - referencePages: SearchPages_search_edges_node[] + referencePages: SearchPages_search_edges_node[], + referenceProducts: SearchProducts_search_edges_node[] ) => attributes.map(attribute => { if (attribute.data.inputType === AttributeInputTypeEnum.REFERENCE) { - return getReferenceAttributeDisplayData(attribute, referencePages); + return getReferenceAttributeDisplayData( + attribute, + referencePages, + referenceProducts + ); } if (attribute.data.inputType === AttributeInputTypeEnum.FILE) { return getFileAttributeDisplayData(attribute, attributesWithNewFileValue); @@ -230,3 +284,34 @@ export const getAttributesDisplayData = ( return attribute; }); + +export const getSelectedReferencesFromAttribute = < + Node extends SearchPages_search_edges_node | SearchProducts_search_edges_node +>( + attribute?: AttributeInput, + references?: Node[] +) => + references?.filter( + value => + !attribute?.value?.some(selectedValue => selectedValue === value.id) + ) || []; + +export const getAttributeValuesFromReferences = ( + attributeId: string, + attributes?: AttributeInput[], + referencePages?: SearchPages_search_edges_node[], + referenceProducts?: SearchProducts_search_edges_node[] +) => { + const attribute = attributes?.find(attribute => attribute.id === attributeId); + + if (attribute?.data?.entityType === AttributeEntityTypeEnum.PAGE) { + return mapPagesToChoices( + getSelectedReferencesFromAttribute(attribute, referencePages) + ); + } else if (attribute?.data?.entityType === AttributeEntityTypeEnum.PRODUCT) { + return mapNodeToChoice( + getSelectedReferencesFromAttribute(attribute, referenceProducts) + ); + } + return []; +}; diff --git a/src/attributes/utils/handlers.ts b/src/attributes/utils/handlers.ts index afddebd11..28110b2db 100644 --- a/src/attributes/utils/handlers.ts +++ b/src/attributes/utils/handlers.ts @@ -12,8 +12,9 @@ import { FormsetData } from "@saleor/hooks/useFormset"; import { PageDetails_page_attributes } from "@saleor/pages/types/PageDetails"; -import { ReorderEvent } from "@saleor/types"; +import { FetchMoreProps, ReorderEvent } from "@saleor/types"; import { + AttributeEntityTypeEnum, AttributeInputTypeEnum, AttributeValueInput } from "@saleor/types/globalTypes"; @@ -67,6 +68,56 @@ export function createAttributeReferenceChangeHandler( }; } +export function createFetchReferencesHandler( + attributes: FormsetData, + assignReferencesAttributeId: string, + fetchReferencePages?: (data: string) => void, + fetchReferenceProducts?: (data: string) => void +) { + return (value: string) => { + const attribute = attributes?.find( + attribute => attribute.id === assignReferencesAttributeId + ); + + if (!attribute) { + return; + } + + if ( + attribute.data.entityType === AttributeEntityTypeEnum.PAGE && + fetchReferencePages + ) { + fetchReferencePages(value); + } else if ( + attribute.data.entityType === AttributeEntityTypeEnum.PRODUCT && + fetchReferenceProducts + ) { + fetchReferenceProducts(value); + } + }; +} + +export function createFetchMoreReferencesHandler( + attributes: FormsetData, + assignReferencesAttributeId: string, + fetchMoreReferencePages?: FetchMoreProps, + fetchMoreReferenceProducts?: FetchMoreProps +) { + const attribute = attributes?.find( + attribute => attribute.id === assignReferencesAttributeId + ); + + if (!attribute) { + return; + } + + if (attribute.data.entityType === AttributeEntityTypeEnum.PAGE) { + return fetchMoreReferencePages; + } else if (attribute.data.entityType === AttributeEntityTypeEnum.PRODUCT) { + return fetchMoreReferenceProducts; + } +} + export function createAttributeFileChangeHandler( changeAttributeData: FormsetChange, attributesWithNewFileValue: FormsetData>, diff --git a/src/components/AssignAttributeValueDialog/AssignAttributeValueDialog.tsx b/src/components/AssignAttributeValueDialog/AssignAttributeValueDialog.tsx index ff2711eeb..0a8d4523b 100644 --- a/src/components/AssignAttributeValueDialog/AssignAttributeValueDialog.tsx +++ b/src/components/AssignAttributeValueDialog/AssignAttributeValueDialog.tsx @@ -1,4 +1,4 @@ -import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages"; +import { AttributeReference } from "@saleor/attributes/utils/data"; import React from "react"; import { defineMessages, useIntl } from "react-intl"; @@ -26,7 +26,7 @@ interface AssignAttributeValueDialogProps AssignContainerDialogProps, "containers" | "title" | "search" | "confirmButtonState" > { - attributeValues: SearchPages_search_edges_node[]; + attributeValues: AttributeReference[]; } const AssignAttributeValueDialog: React.FC = ({ @@ -38,8 +38,8 @@ const AssignAttributeValueDialog: React.FC = ({ return ( ({ - id: value.id, - name: value.title + id: value.value, + name: value.label }))} search={{ label: intl.formatMessage(messages.searchLabel), diff --git a/src/components/Attributes/Attributes.tsx b/src/components/Attributes/Attributes.tsx index 95de1fb5b..aada001ec 100644 --- a/src/components/Attributes/Attributes.tsx +++ b/src/components/Attributes/Attributes.tsx @@ -4,6 +4,7 @@ import IconButton from "@material-ui/core/IconButton"; import makeStyles from "@material-ui/core/styles/makeStyles"; import Typography from "@material-ui/core/Typography"; import ArrowDropDownIcon from "@material-ui/icons/ArrowDropDown"; +import { AttributeReference } from "@saleor/attributes/utils/data"; import CardTitle from "@saleor/components/CardTitle"; import Hr from "@saleor/components/Hr"; import MultiAutocompleteSelectField, { @@ -16,9 +17,11 @@ import { AttributeValueFragment } from "@saleor/fragments/types/AttributeValueFr import { PageErrorWithAttributesFragment } from "@saleor/fragments/types/PageErrorWithAttributesFragment"; import { ProductErrorWithAttributesFragment } from "@saleor/fragments/types/ProductErrorWithAttributesFragment"; import { FormsetAtomicData, FormsetChange } from "@saleor/hooks/useFormset"; -import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages"; import { ReorderEvent } from "@saleor/types"; -import { AttributeInputTypeEnum } from "@saleor/types/globalTypes"; +import { + AttributeEntityTypeEnum, + AttributeInputTypeEnum +} from "@saleor/types/globalTypes"; import { getProductErrorMessage } from "@saleor/utils/errors"; import getPageErrorMessage from "@saleor/utils/errors/page"; import classNames from "classnames"; @@ -40,11 +43,12 @@ import { VariantAttributeScope } from "./types"; export interface AttributeInputData { inputType: AttributeInputTypeEnum; + entityType?: AttributeEntityTypeEnum; variantAttributeScope?: VariantAttributeScope; isRequired: boolean; values: AttributeValueFragment[]; selectedValues?: AttributeValueFragment[]; - references?: SearchPages_search_edges_node[]; + references?: AttributeReference[]; } export type AttributeInput = FormsetAtomicData; export type AttributeFileInput = FormsetAtomicData; @@ -175,14 +179,11 @@ function getReferenceDisplayValue( } const definedAttributeReference = attribute.data.references?.find( - reference => reference.id === attributeValue + reference => reference.value === attributeValue ); // If value has not been yet assigned, use data of reference if (!!definedAttributeReference) { - return { - label: definedAttributeReference.title, - value: definedAttributeReference.id - }; + return definedAttributeReference; } return { diff --git a/src/components/Attributes/fixtures.ts b/src/components/Attributes/fixtures.ts index 205bdd74c..6fb778150 100644 --- a/src/components/Attributes/fixtures.ts +++ b/src/components/Attributes/fixtures.ts @@ -1,4 +1,7 @@ -import { AttributeInputTypeEnum } from "@saleor/types/globalTypes"; +import { + AttributeEntityTypeEnum, + AttributeInputTypeEnum +} from "@saleor/types/globalTypes"; import { AttributeInput } from "./Attributes"; @@ -92,23 +95,21 @@ const FILE_ATTRIBUTE: AttributeInput = { const REFERENCE_ATTRIBUTE: AttributeInput = { data: { + entityType: AttributeEntityTypeEnum.PAGE, inputType: AttributeInputTypeEnum.REFERENCE, isRequired: true, references: [ { - __typename: "Page", - id: "vbnhgcvjhbvhj", - title: "References First Value" + label: "References First Value", + value: "vbnhgcvjhbvhj" }, { - __typename: "Page", - id: "gucngdfdfvdvd", - title: "References Second Value" + label: "References Second Value", + value: "gucngdfdfvdvd" }, { - __typename: "Page", - id: "dfdfdsfdsfdse", - title: "References Third Value" + label: "References Third Value", + value: "dfdfdsfdsfdse" } ], values: [ diff --git a/src/fragments/pages.ts b/src/fragments/pages.ts index f757f0459..d91a1a43d 100644 --- a/src/fragments/pages.ts +++ b/src/fragments/pages.ts @@ -21,6 +21,7 @@ export const pageAttributesFragment = gql` slug name inputType + entityType valueRequired values { ...AttributeValueFragment @@ -37,6 +38,7 @@ export const pageAttributesFragment = gql` id name inputType + entityType valueRequired values { ...AttributeValueFragment diff --git a/src/fragments/products.ts b/src/fragments/products.ts index a1fce235f..9cec7123b 100644 --- a/src/fragments/products.ts +++ b/src/fragments/products.ts @@ -123,6 +123,7 @@ export const productVariantAttributesFragment = gql` slug name inputType + entityType valueRequired values { ...AttributeValueFragment @@ -231,6 +232,7 @@ export const variantAttributeFragment = gql` name slug inputType + entityType valueRequired values { ...AttributeValueFragment diff --git a/src/fragments/types/MetadataFragment.ts b/src/fragments/types/MetadataFragment.ts index 4c6128e0b..53ae1cb06 100644 --- a/src/fragments/types/MetadataFragment.ts +++ b/src/fragments/types/MetadataFragment.ts @@ -19,7 +19,7 @@ export interface MetadataFragment_privateMetadata { } export interface MetadataFragment { - __typename: "App" | "ShippingZone" | "ShippingMethod" | "Product" | "ProductType" | "Attribute" | "Category" | "ProductVariant" | "DigitalContent" | "Collection" | "Page" | "PageType" | "User" | "Checkout" | "Order" | "Fulfillment" | "Invoice"; + __typename: "App" | "ShippingZone" | "ShippingMethod" | "Product" | "ProductType" | "Attribute" | "Category" | "ProductVariant" | "DigitalContent" | "Collection" | "Page" | "PageType" | "MenuItem" | "Menu" | "User" | "Checkout" | "Order" | "Fulfillment" | "Invoice"; metadata: (MetadataFragment_metadata | null)[]; privateMetadata: (MetadataFragment_privateMetadata | null)[]; } diff --git a/src/fragments/types/PageAttributesFragment.ts b/src/fragments/types/PageAttributesFragment.ts index 693850779..62c2b6697 100644 --- a/src/fragments/types/PageAttributesFragment.ts +++ b/src/fragments/types/PageAttributesFragment.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { AttributeInputTypeEnum } from "./../../types/globalTypes"; +import { AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL fragment: PageAttributesFragment @@ -29,6 +29,7 @@ export interface PageAttributesFragment_attributes_attribute { slug: string | null; name: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (PageAttributesFragment_attributes_attribute_values | null)[] | null; } @@ -74,6 +75,7 @@ export interface PageAttributesFragment_pageType_attributes { id: string; name: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (PageAttributesFragment_pageType_attributes_values | null)[] | null; } diff --git a/src/fragments/types/PageDetailsFragment.ts b/src/fragments/types/PageDetailsFragment.ts index d05db0d3a..2ba241f78 100644 --- a/src/fragments/types/PageDetailsFragment.ts +++ b/src/fragments/types/PageDetailsFragment.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { AttributeInputTypeEnum } from "./../../types/globalTypes"; +import { AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL fragment: PageDetailsFragment @@ -29,6 +29,7 @@ export interface PageDetailsFragment_attributes_attribute { slug: string | null; name: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (PageDetailsFragment_attributes_attribute_values | null)[] | null; } @@ -74,6 +75,7 @@ export interface PageDetailsFragment_pageType_attributes { id: string; name: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (PageDetailsFragment_pageType_attributes_values | null)[] | null; } diff --git a/src/fragments/types/Product.ts b/src/fragments/types/Product.ts index c5b5195d7..f9ba2f490 100644 --- a/src/fragments/types/Product.ts +++ b/src/fragments/types/Product.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { AttributeInputTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; +import { AttributeInputTypeEnum, AttributeEntityTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL fragment: Product @@ -29,6 +29,7 @@ export interface Product_attributes_attribute { slug: string | null; name: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (Product_attributes_attribute_values | null)[] | null; } diff --git a/src/fragments/types/ProductVariant.ts b/src/fragments/types/ProductVariant.ts index 78eded821..371bc43cc 100644 --- a/src/fragments/types/ProductVariant.ts +++ b/src/fragments/types/ProductVariant.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { AttributeInputTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; +import { AttributeInputTypeEnum, AttributeEntityTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL fragment: ProductVariant @@ -41,6 +41,7 @@ export interface ProductVariant_selectionAttributes_attribute { name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (ProductVariant_selectionAttributes_attribute_values | null)[] | null; } @@ -87,6 +88,7 @@ export interface ProductVariant_nonSelectionAttributes_attribute { name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (ProductVariant_nonSelectionAttributes_attribute_values | null)[] | null; } diff --git a/src/fragments/types/ProductVariantAttributesFragment.ts b/src/fragments/types/ProductVariantAttributesFragment.ts index 71f35d484..f2dae3282 100644 --- a/src/fragments/types/ProductVariantAttributesFragment.ts +++ b/src/fragments/types/ProductVariantAttributesFragment.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { AttributeInputTypeEnum } from "./../../types/globalTypes"; +import { AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL fragment: ProductVariantAttributesFragment @@ -29,6 +29,7 @@ export interface ProductVariantAttributesFragment_attributes_attribute { slug: string | null; name: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (ProductVariantAttributesFragment_attributes_attribute_values | null)[] | null; } diff --git a/src/fragments/types/SelectedVariantAttributeFragment.ts b/src/fragments/types/SelectedVariantAttributeFragment.ts index 9b5a69592..bc91e9574 100644 --- a/src/fragments/types/SelectedVariantAttributeFragment.ts +++ b/src/fragments/types/SelectedVariantAttributeFragment.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { AttributeInputTypeEnum } from "./../../types/globalTypes"; +import { AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL fragment: SelectedVariantAttributeFragment @@ -29,6 +29,7 @@ export interface SelectedVariantAttributeFragment_attribute { name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (SelectedVariantAttributeFragment_attribute_values | null)[] | null; } diff --git a/src/fragments/types/VariantAttributeFragment.ts b/src/fragments/types/VariantAttributeFragment.ts index bfaeecc1b..9bbf7316e 100644 --- a/src/fragments/types/VariantAttributeFragment.ts +++ b/src/fragments/types/VariantAttributeFragment.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { AttributeInputTypeEnum } from "./../../types/globalTypes"; +import { AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL fragment: VariantAttributeFragment @@ -29,6 +29,7 @@ export interface VariantAttributeFragment { name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (VariantAttributeFragment_values | null)[] | null; } diff --git a/src/pages/components/PageDetailsPage/PageDetailsPage.tsx b/src/pages/components/PageDetailsPage/PageDetailsPage.tsx index edfeb5841..e35e9a17f 100644 --- a/src/pages/components/PageDetailsPage/PageDetailsPage.tsx +++ b/src/pages/components/PageDetailsPage/PageDetailsPage.tsx @@ -1,4 +1,7 @@ -import { mergeAttributeValues } from "@saleor/attributes/utils/data"; +import { + getAttributeValuesFromReferences, + mergeAttributeValues +} from "@saleor/attributes/utils/data"; import AppHeader from "@saleor/components/AppHeader"; import AssignAttributeValueDialog from "@saleor/components/AssignAttributeValueDialog"; import Attributes, { AttributeInput } from "@saleor/components/Attributes"; @@ -15,9 +18,9 @@ import { PageErrorWithAttributesFragment } from "@saleor/fragments/types/PageErr import useDateLocalize from "@saleor/hooks/useDateLocalize"; import { SubmitPromise } from "@saleor/hooks/useForm"; import { sectionNames } from "@saleor/intl"; -import { getAttributeValuesFromReferences } from "@saleor/pages/utils/data"; import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages"; import { SearchPageTypes_search_edges_node } from "@saleor/searches/types/SearchPageTypes"; +import { SearchProducts_search_edges_node } from "@saleor/searches/types/SearchProducts"; import { FetchMoreProps } from "@saleor/types"; import React from "react"; import { useIntl } from "react-intl"; @@ -32,7 +35,8 @@ export interface PageDetailsPageProps { errors: PageErrorWithAttributesFragment[]; page: PageDetails_page; pageTypes?: SearchPageTypes_search_edges_node[]; - referencePages: SearchPages_search_edges_node[]; + referencePages?: SearchPages_search_edges_node[]; + referenceProducts?: SearchProducts_search_edges_node[]; allowEmptySlug?: boolean; saveButtonBarState: ConfirmButtonTransitionState; onBack: () => void; @@ -44,6 +48,8 @@ export interface PageDetailsPageProps { onAssignReferencesClick: (attribute: AttributeInput) => void; fetchReferencePages?: (data: string) => void; fetchMoreReferencePages?: FetchMoreProps; + fetchReferenceProducts?: (data: string) => void; + fetchMoreReferenceProducts?: FetchMoreProps; onCloseDialog: () => void; } @@ -52,7 +58,8 @@ const PageDetailsPage: React.FC = ({ errors, page, pageTypes, - referencePages, + referencePages = [], + referenceProducts = [], saveButtonBarState, onBack, onRemove, @@ -63,6 +70,8 @@ const PageDetailsPage: React.FC = ({ onAssignReferencesClick, fetchReferencePages, fetchMoreReferencePages, + fetchReferenceProducts, + fetchMoreReferenceProducts, onCloseDialog }) => { const intl = useIntl(); @@ -93,6 +102,12 @@ const PageDetailsPage: React.FC = ({ page={page} pageTypes={pageTypes} referencePages={referencePages} + referenceProducts={referenceProducts} + fetchReferencePages={fetchReferencePages} + fetchMoreReferencePages={fetchMoreReferencePages} + fetchReferenceProducts={fetchReferenceProducts} + fetchMoreReferenceProducts={fetchMoreReferenceProducts} + assignReferencesAttributeId={assignReferencesAttributeId} onSubmit={onSubmit} > {({ change, data, pageType, handlers, hasChanged, submit }) => ( @@ -208,13 +223,14 @@ const PageDetailsPage: React.FC = ({ attributeValues={getAttributeValuesFromReferences( assignReferencesAttributeId, data.attributes, - referencePages + referencePages, + referenceProducts )} - hasMore={fetchMoreReferencePages?.hasMore} + hasMore={handlers.fetchMoreReferences?.hasMore} open={canOpenAssignReferencesAttributeDialog} - onFetch={fetchReferencePages} - onFetchMore={fetchMoreReferencePages?.onFetchMore} - loading={fetchMoreReferencePages?.loading} + onFetch={handlers.fetchReferences} + onFetchMore={handlers.fetchMoreReferences?.onFetchMore} + loading={handlers.fetchMoreReferences?.loading} onClose={onCloseDialog} onSubmit={attributeValues => handleAssignReferenceAttribute(attributeValues, data, handlers) diff --git a/src/pages/components/PageDetailsPage/form.tsx b/src/pages/components/PageDetailsPage/form.tsx index cec3a130e..758c7d598 100644 --- a/src/pages/components/PageDetailsPage/form.tsx +++ b/src/pages/components/PageDetailsPage/form.tsx @@ -5,7 +5,9 @@ import { createAttributeFileChangeHandler, createAttributeMultiChangeHandler, createAttributeReferenceChangeHandler, - createAttributeValueReorderHandler + createAttributeValueReorderHandler, + createFetchMoreReferencesHandler, + createFetchReferencesHandler } from "@saleor/attributes/utils/handlers"; import { AttributeInput } from "@saleor/components/Attributes"; import { MetadataFormData } from "@saleor/components/Metadata"; @@ -24,7 +26,8 @@ import { import { getAttributeInputFromPage } from "@saleor/pages/utils/data"; import { createPageTypeSelectHandler } from "@saleor/pages/utils/handlers"; import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages"; -import { ReorderEvent } from "@saleor/types"; +import { SearchProducts_search_edges_node } from "@saleor/searches/types/SearchProducts"; +import { FetchMoreProps, ReorderEvent } from "@saleor/types"; import getPublicationData from "@saleor/utils/data/getPublicationData"; import handleFormSubmit from "@saleor/utils/handlers/handleFormSubmit"; import { mapMetadataItemToInput } from "@saleor/utils/maps"; @@ -62,6 +65,8 @@ export interface PageUpdateHandlers { selectAttributeReference: FormsetChange; selectAttributeFile: FormsetChange; reorderAttributeValue: FormsetChange; + fetchReferences: (value: string) => void; + fetchMoreReferences: FetchMoreProps; } export interface UsePageUpdateFormResult { change: FormChange; @@ -72,19 +77,28 @@ export interface UsePageUpdateFormResult { submit: () => void; } -export interface PageFormProps { +export interface UsePageFormOpts { + pageTypes?: PageDetails_page_pageType[]; + referencePages: SearchPages_search_edges_node[]; + referenceProducts: SearchProducts_search_edges_node[]; + fetchReferencePages?: (data: string) => void; + fetchMoreReferencePages?: FetchMoreProps; + fetchReferenceProducts?: (data: string) => void; + fetchMoreReferenceProducts?: FetchMoreProps; + assignReferencesAttributeId?: string; +} + +export interface PageFormProps extends UsePageFormOpts { children: (props: UsePageUpdateFormResult) => React.ReactNode; page: PageDetails_page; pageTypes?: PageDetails_page_pageType[]; - referencePages: SearchPages_search_edges_node[]; onSubmit: (data: PageData) => SubmitPromise; } function usePageForm( page: PageDetails_page, onSubmit: (data: PageData) => SubmitPromise, - referencePages: SearchPages_search_edges_node[], - pageTypes?: PageDetails_page_pageType[] + opts: UsePageFormOpts ): UsePageUpdateFormResult { const [changed, setChanged] = React.useState(false); const triggerChange = () => setChanged(true); @@ -131,7 +145,7 @@ function usePageForm( handleChange, attributes.set, setPageType, - pageTypes + opts.pageTypes ); const handleAttributeChange = createAttributeChangeHandler( attributes.change, @@ -146,6 +160,18 @@ function usePageForm( attributes.change, triggerChange ); + const handleFetchReferences = createFetchReferencesHandler( + attributes.data, + opts.assignReferencesAttributeId, + opts.fetchReferencePages, + opts.fetchReferenceProducts + ); + const handleFetchMoreReferences = createFetchMoreReferencesHandler( + attributes.data, + opts.assignReferencesAttributeId, + opts.fetchMoreReferencePages, + opts.fetchMoreReferenceProducts + ); const handleAttributeFileChange = createAttributeFileChangeHandler( attributes.change, attributesWithNewFileValue.data, @@ -165,7 +191,8 @@ function usePageForm( attributes: getAttributesDisplayData( attributes.data, attributesWithNewFileValue.data, - referencePages + opts.referencePages, + opts.referenceProducts ), content: content.current }); @@ -198,6 +225,8 @@ function usePageForm( handlers: { changeContent, changeMetadata, + fetchMoreReferences: handleFetchMoreReferences, + fetchReferences: handleFetchReferences, reorderAttributeValue: handleAttributeValueReorder, selectAttribute: handleAttributeChange, selectAttributeFile: handleAttributeFileChange, @@ -214,11 +243,10 @@ function usePageForm( const PageForm: React.FC = ({ children, page, - referencePages, - pageTypes, - onSubmit + onSubmit, + ...rest }) => { - const props = usePageForm(page, onSubmit, referencePages, pageTypes); + const props = usePageForm(page, onSubmit, rest); return
{children(props)}
; }; diff --git a/src/pages/fixtures.ts b/src/pages/fixtures.ts index 7e1938c15..0d1cd2e0b 100644 --- a/src/pages/fixtures.ts +++ b/src/pages/fixtures.ts @@ -45,6 +45,7 @@ export const page: PageDetails_page = { id: "QXR0cmlidXRlOjI3", slug: "author", name: "Author", + entityType: null, inputType: AttributeInputTypeEnum.DROPDOWN, valueRequired: false, values: [ @@ -92,6 +93,7 @@ export const page: PageDetails_page = { id: "QXR0cmlidXRlOjI5", slug: "tag", name: "Tag", + entityType: null, inputType: AttributeInputTypeEnum.MULTISELECT, valueRequired: false, values: [ @@ -161,6 +163,7 @@ export const page: PageDetails_page = { { id: "QXR0cmlidXRlOjI3", name: "Author", + entityType: null, inputType: AttributeInputTypeEnum.DROPDOWN, valueRequired: false, values: [ @@ -194,6 +197,7 @@ export const page: PageDetails_page = { { id: "QXR0cmlidXRlOjI5", name: "Tag", + entityType: null, inputType: AttributeInputTypeEnum.MULTISELECT, valueRequired: false, values: [ diff --git a/src/pages/types/PageCreate.ts b/src/pages/types/PageCreate.ts index bf67a2907..8499600b3 100644 --- a/src/pages/types/PageCreate.ts +++ b/src/pages/types/PageCreate.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { PageCreateInput, PageErrorCode, AttributeInputTypeEnum } from "./../../types/globalTypes"; +import { PageCreateInput, PageErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: PageCreate @@ -37,6 +37,7 @@ export interface PageCreate_pageCreate_page_attributes_attribute { slug: string | null; name: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (PageCreate_pageCreate_page_attributes_attribute_values | null)[] | null; } @@ -82,6 +83,7 @@ export interface PageCreate_pageCreate_page_pageType_attributes { id: string; name: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (PageCreate_pageCreate_page_pageType_attributes_values | null)[] | null; } diff --git a/src/pages/types/PageDetails.ts b/src/pages/types/PageDetails.ts index a891bd408..3526d05ac 100644 --- a/src/pages/types/PageDetails.ts +++ b/src/pages/types/PageDetails.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { AttributeInputTypeEnum } from "./../../types/globalTypes"; +import { AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL query operation: PageDetails @@ -29,6 +29,7 @@ export interface PageDetails_page_attributes_attribute { slug: string | null; name: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (PageDetails_page_attributes_attribute_values | null)[] | null; } @@ -74,6 +75,7 @@ export interface PageDetails_page_pageType_attributes { id: string; name: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (PageDetails_page_pageType_attributes_values | null)[] | null; } diff --git a/src/pages/types/PageUpdate.ts b/src/pages/types/PageUpdate.ts index 4d4cc1b26..8b78848f1 100644 --- a/src/pages/types/PageUpdate.ts +++ b/src/pages/types/PageUpdate.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { PageInput, PageErrorCode, AttributeInputTypeEnum } from "./../../types/globalTypes"; +import { PageInput, PageErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: PageUpdate @@ -36,6 +36,7 @@ export interface PageUpdate_pageUpdate_page_attributes_attribute { slug: string | null; name: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (PageUpdate_pageUpdate_page_attributes_attribute_values | null)[] | null; } @@ -81,6 +82,7 @@ export interface PageUpdate_pageUpdate_page_pageType_attributes { id: string; name: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (PageUpdate_pageUpdate_page_pageType_attributes_values | null)[] | null; } diff --git a/src/pages/utils/data.ts b/src/pages/utils/data.ts index db9116f38..083383dfe 100644 --- a/src/pages/utils/data.ts +++ b/src/pages/utils/data.ts @@ -1,6 +1,5 @@ import { getSelectedAttributeValues } from "@saleor/attributes/utils/data"; import { AttributeInput } from "@saleor/components/Attributes"; -import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages"; import { PageDetails_page, @@ -12,6 +11,7 @@ export function getAttributeInputFromPage( ): AttributeInput[] { return page?.attributes.map(attribute => ({ data: { + entityType: attribute.attribute.entityType, inputType: attribute.attribute.inputType, isRequired: attribute.attribute.valueRequired, selectedValues: attribute.values, @@ -28,6 +28,7 @@ export function getAttributeInputFromPageType( ): AttributeInput[] { return pageType?.attributes.map(attribute => ({ data: { + entityType: attribute.entityType, inputType: attribute.inputType, isRequired: attribute.valueRequired, values: attribute.values @@ -37,18 +38,3 @@ export function getAttributeInputFromPageType( value: [] })); } - -export const getAttributeValuesFromReferences = ( - attributeId: string, - attributes: AttributeInput[], - referencePages: SearchPages_search_edges_node[] -) => { - const attribute = attributes?.find(attribute => attribute.id === attributeId); - - return ( - referencePages?.filter( - value => - !attribute?.value?.some(selectedValue => selectedValue === value.id) - ) || [] - ); -}; diff --git a/src/pages/views/PageCreate.tsx b/src/pages/views/PageCreate.tsx index a77a11edc..2ee83d15b 100644 --- a/src/pages/views/PageCreate.tsx +++ b/src/pages/views/PageCreate.tsx @@ -11,6 +11,7 @@ import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import usePageSearch from "@saleor/searches/usePageSearch"; import usePageTypeSearch from "@saleor/searches/usePageTypeSearch"; +import useProductSearch from "@saleor/searches/useProductSearch"; import createMetadataCreateHandler from "@saleor/utils/handlers/metadataCreateHandler"; import { useMetadataUpdate, @@ -58,6 +59,14 @@ export const PageCreate: React.FC = ({ params }) => { variables: DEFAULT_INITIAL_SEARCH_DATA }); + const { + loadMore: loadMoreProducts, + search: searchProducts, + result: searchProductsOpts + } = useProductSearch({ + variables: DEFAULT_INITIAL_SEARCH_DATA + }); + const [uploadFile, uploadFileOpts] = useFileUploadMutation({}); const handlePageCreate = (data: PageCreateData) => { @@ -81,17 +90,23 @@ export const PageCreate: React.FC = ({ params }) => { ); const fetchMorePageTypes = { - hasMore: searchPageTypesOpts.data?.search.pageInfo.hasNextPage, + hasMore: searchPageTypesOpts.data?.search?.pageInfo?.hasNextPage, loading: searchPageTypesOpts.loading, onFetchMore: loadMorePageTypes }; const fetchMoreReferencePages = { - hasMore: searchPagesOpts.data?.search.pageInfo.hasNextPage, + hasMore: searchPagesOpts.data?.search?.pageInfo?.hasNextPage, loading: searchPagesOpts.loading, onFetchMore: loadMorePages }; + const fetchMoreReferenceProducts = { + hasMore: searchProductsOpts.data?.search?.pageInfo?.hasNextPage, + loading: searchProductsOpts.loading, + onFetchMore: loadMoreProducts + }; + return ( {(pageCreate, pageCreateOpts) => { @@ -163,8 +178,13 @@ export const PageCreate: React.FC = ({ params }) => { referencePages={searchPagesOpts.data?.search.edges.map( edge => edge.node )} + referenceProducts={searchProductsOpts.data?.search.edges.map( + edge => edge.node + )} fetchReferencePages={searchPages} fetchMoreReferencePages={fetchMoreReferencePages} + fetchReferenceProducts={searchProducts} + fetchMoreReferenceProducts={fetchMoreReferenceProducts} onCloseDialog={() => navigate(pageCreateUrl())} /> diff --git a/src/pages/views/PageDetails.tsx b/src/pages/views/PageDetails.tsx index 2b3174c64..687ddaf6f 100644 --- a/src/pages/views/PageDetails.tsx +++ b/src/pages/views/PageDetails.tsx @@ -22,6 +22,7 @@ import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import { commonMessages } from "@saleor/intl"; import usePageSearch from "@saleor/searches/usePageSearch"; +import useProductSearch from "@saleor/searches/useProductSearch"; import createMetadataUpdateHandler from "@saleor/utils/handlers/metadataUpdateHandler"; import { useMetadataUpdate, @@ -158,12 +159,26 @@ export const PageDetails: React.FC = ({ id, params }) => { variables: DEFAULT_INITIAL_SEARCH_DATA }); + const { + loadMore: loadMoreProducts, + search: searchProducts, + result: searchProductsOpts + } = useProductSearch({ + variables: DEFAULT_INITIAL_SEARCH_DATA + }); + const fetchMoreReferencePages = { - hasMore: searchPagesOpts.data?.search.pageInfo.hasNextPage, + hasMore: searchPagesOpts.data?.search?.pageInfo?.hasNextPage, loading: searchPagesOpts.loading, onFetchMore: loadMorePages }; + const fetchMoreReferenceProducts = { + hasMore: searchProductsOpts.data?.search?.pageInfo?.hasNextPage, + loading: searchProductsOpts.loading, + onFetchMore: loadMoreProducts + }; + return ( <> pageDetails.data.page.title)} /> @@ -193,8 +208,13 @@ export const PageDetails: React.FC = ({ id, params }) => { referencePages={searchPagesOpts.data?.search.edges.map( edge => edge.node )} + referenceProducts={searchProductsOpts.data?.search.edges.map( + edge => edge.node + )} fetchReferencePages={searchPages} fetchMoreReferencePages={fetchMoreReferencePages} + fetchReferenceProducts={searchProducts} + fetchMoreReferenceProducts={fetchMoreReferenceProducts} onCloseDialog={() => navigate(pageUrl(id))} /> ; productTypes?: SearchProductTypes_search_edges_node[]; - referencePages: SearchPages_search_edges_node[]; + referencePages?: SearchPages_search_edges_node[]; + referenceProducts?: SearchProducts_search_edges_node[]; header: string; saveButtonBarState: ConfirmButtonTransitionState; weightUnit: string; @@ -69,7 +73,9 @@ interface ProductCreatePageProps { assignReferencesAttributeId?: string; onAssignReferencesClick: (attribute: AttributeInput) => void; fetchReferencePages?: (data: string) => void; + fetchReferenceProducts?: (data: string) => void; fetchMoreReferencePages?: FetchMoreProps; + fetchMoreReferenceProducts?: FetchMoreProps; onCloseDialog: () => void; onBack?(); onSubmit?(data: ProductCreateData); @@ -91,7 +97,8 @@ export const ProductCreatePage: React.FC = ({ header, initial, productTypes: productTypeChoiceList, - referencePages, + referencePages = [], + referenceProducts = [], saveButtonBarState, warehouses, taxTypes, @@ -106,6 +113,8 @@ export const ProductCreatePage: React.FC = ({ onAssignReferencesClick, fetchReferencePages, fetchMoreReferencePages, + fetchReferenceProducts, + fetchMoreReferenceProducts, onCloseDialog }: ProductCreatePageProps) => { const intl = useIntl(); @@ -158,6 +167,7 @@ export const ProductCreatePage: React.FC = ({ collections={collections} productTypes={productTypeChoiceList} referencePages={referencePages} + referenceProducts={referenceProducts} selectedCollections={selectedCollections} setSelectedCategory={setSelectedCategory} setSelectedCollections={setSelectedCollections} @@ -167,6 +177,11 @@ export const ProductCreatePage: React.FC = ({ warehouses={warehouses} currentChannels={currentChannels} productTypeChoiceList={productTypeChoiceList} + fetchReferencePages={fetchReferencePages} + fetchMoreReferencePages={fetchMoreReferencePages} + fetchReferenceProducts={fetchReferenceProducts} + fetchMoreReferenceProducts={fetchMoreReferenceProducts} + assignReferencesAttributeId={assignReferencesAttributeId} > {({ change, @@ -327,13 +342,14 @@ export const ProductCreatePage: React.FC = ({ attributeValues={getAttributeValuesFromReferences( assignReferencesAttributeId, data.attributes, - referencePages + referencePages, + referenceProducts )} - hasMore={fetchMoreReferencePages?.hasMore} + hasMore={handlers.fetchMoreReferences?.hasMore} open={canOpenAssignReferencesAttributeDialog} - onFetch={fetchReferencePages} - onFetchMore={fetchMoreReferencePages?.onFetchMore} - loading={fetchMoreReferencePages?.loading} + onFetch={handlers.fetchReferences} + onFetchMore={handlers.fetchMoreReferences?.onFetchMore} + loading={handlers.fetchMoreReferences?.loading} onClose={onCloseDialog} onSubmit={attributeValues => handleAssignReferenceAttribute( diff --git a/src/products/components/ProductCreatePage/form.tsx b/src/products/components/ProductCreatePage/form.tsx index 4e534659d..3cf000d12 100644 --- a/src/products/components/ProductCreatePage/form.tsx +++ b/src/products/components/ProductCreatePage/form.tsx @@ -5,7 +5,9 @@ import { createAttributeFileChangeHandler, createAttributeMultiChangeHandler, createAttributeReferenceChangeHandler, - createAttributeValueReorderHandler + createAttributeValueReorderHandler, + createFetchMoreReferencesHandler, + createFetchReferencesHandler } from "@saleor/attributes/utils/handlers"; import { ChannelData, ChannelPriceArgs } from "@saleor/channels/utils"; import { @@ -36,9 +38,10 @@ import { validatePrice } from "@saleor/products/utils/validation"; import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages"; +import { SearchProducts_search_edges_node } from "@saleor/searches/types/SearchProducts"; import { SearchProductTypes_search_edges_node } from "@saleor/searches/types/SearchProductTypes"; import { SearchWarehouses_search_edges_node } from "@saleor/searches/types/SearchWarehouses"; -import { ReorderEvent } from "@saleor/types"; +import { FetchMoreProps, ReorderEvent } from "@saleor/types"; import createMultiAutocompleteSelectHandler from "@saleor/utils/handlers/multiAutocompleteSelectChangeHandler"; import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler"; import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger"; @@ -99,6 +102,8 @@ export interface ProductCreateHandlers Record<"reorderAttributeValue", FormsetChange>, Record<"addStock" | "deleteStock", (id: string) => void> { changeDescription: RichTextEditorChange; + fetchReferences: (value: string) => void; + fetchMoreReferences: FetchMoreProps; } export interface UseProductCreateFormResult { change: FormChange; @@ -126,6 +131,12 @@ export interface UseProductCreateFormOpts currentChannels: ChannelData[]; productTypeChoiceList: SearchProductTypes_search_edges_node[]; referencePages: SearchPages_search_edges_node[]; + referenceProducts: SearchProducts_search_edges_node[]; + fetchReferencePages?: (data: string) => void; + fetchMoreReferencePages?: FetchMoreProps; + fetchReferenceProducts?: (data: string) => void; + fetchMoreReferenceProducts?: FetchMoreProps; + assignReferencesAttributeId?: string; } export interface ProductCreateFormProps extends UseProductCreateFormOpts { @@ -222,6 +233,18 @@ function useProductCreateForm( attributes.change, triggerChange ); + const handleFetchReferences = createFetchReferencesHandler( + attributes.data, + opts.assignReferencesAttributeId, + opts.fetchReferencePages, + opts.fetchReferenceProducts + ); + const handleFetchMoreReferences = createFetchMoreReferencesHandler( + attributes.data, + opts.assignReferencesAttributeId, + opts.fetchMoreReferencePages, + opts.fetchMoreReferenceProducts + ); const handleAttributeFileChange = createAttributeFileChangeHandler( attributes.change, attributesWithNewFileValue.data, @@ -281,7 +304,8 @@ function useProductCreateForm( attributes: getAttributesDisplayData( attributes.data, attributesWithNewFileValue.data, - opts.referencePages + opts.referencePages, + opts.referenceProducts ), attributesWithNewFileValue: attributesWithNewFileValue.data, description: description.current, @@ -315,6 +339,8 @@ function useProductCreateForm( changeMetadata, changeStock: handleStockChange, deleteStock: handleStockDelete, + fetchMoreReferences: handleFetchMoreReferences, + fetchReferences: handleFetchReferences, reorderAttributeValue: handleAttributeValueReorder, selectAttribute: handleAttributeChange, selectAttributeFile: handleAttributeFileChange, diff --git a/src/products/components/ProductUpdatePage/ProductUpdatePage.test.tsx b/src/products/components/ProductUpdatePage/ProductUpdatePage.test.tsx index 09913fbfb..b96bbaf00 100644 --- a/src/products/components/ProductUpdatePage/ProductUpdatePage.test.tsx +++ b/src/products/components/ProductUpdatePage/ProductUpdatePage.test.tsx @@ -60,6 +60,7 @@ const props: ProductUpdatePageProps = { placeholderImage, product, referencePages: [], + referenceProducts: [], saveButtonBarState: "default", selectedChannelId: "123", taxTypes, diff --git a/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx b/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx index 87c00d0fd..e50d8ed1c 100644 --- a/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx +++ b/src/products/components/ProductUpdatePage/ProductUpdatePage.tsx @@ -1,5 +1,8 @@ import { OutputData } from "@editorjs/editorjs"; -import { mergeAttributeValues } from "@saleor/attributes/utils/data"; +import { + getAttributeValuesFromReferences, + mergeAttributeValues +} from "@saleor/attributes/utils/data"; import { ChannelData } from "@saleor/channels/utils"; import AppHeader from "@saleor/components/AppHeader"; import AssignAttributeValueDialog from "@saleor/components/AssignAttributeValueDialog"; @@ -23,11 +26,11 @@ import { FormsetData } from "@saleor/hooks/useFormset"; import useStateFromProps from "@saleor/hooks/useStateFromProps"; import { sectionNames } from "@saleor/intl"; import { maybe } from "@saleor/misc"; -import { getAttributeValuesFromReferences } from "@saleor/pages/utils/data"; import ProductVariantPrice from "@saleor/products/components/ProductVariantPrice"; import { SearchCategories_search_edges_node } from "@saleor/searches/types/SearchCategories"; import { SearchCollections_search_edges_node } from "@saleor/searches/types/SearchCollections"; import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages"; +import { SearchProducts_search_edges_node } from "@saleor/searches/types/SearchProducts"; import { ChannelProps, FetchMoreProps, @@ -76,12 +79,15 @@ export interface ProductUpdatePageProps extends ListActions, ChannelProps { saveButtonBarState: ConfirmButtonTransitionState; warehouses: WarehouseFragment[]; taxTypes: TaxTypeFragment[]; - referencePages: SearchPages_search_edges_node[]; + referencePages?: SearchPages_search_edges_node[]; + referenceProducts?: SearchProducts_search_edges_node[]; assignReferencesAttributeId?: string; fetchMoreReferencePages?: FetchMoreProps; + fetchMoreReferenceProducts?: FetchMoreProps; fetchCategories: (query: string) => void; fetchCollections: (query: string) => void; fetchReferencePages?: (data: string) => void; + fetchReferenceProducts?: (data: string) => void; onAssignReferencesClick: (attribute: AttributeInput) => void; onCloseDialog: () => void; onVariantsAdd: () => void; @@ -136,7 +142,8 @@ export const ProductUpdatePage: React.FC = ({ variants, warehouses, taxTypes, - referencePages, + referencePages = [], + referenceProducts = [], onBack, onDelete, onImageDelete, @@ -163,6 +170,8 @@ export const ProductUpdatePage: React.FC = ({ onAssignReferencesClick, fetchReferencePages, fetchMoreReferencePages, + fetchReferenceProducts, + fetchMoreReferenceProducts, onCloseDialog }) => { const intl = useIntl(); @@ -222,6 +231,12 @@ export const ProductUpdatePage: React.FC = ({ currentChannels={currentChannels} hasVariants={hasVariants} referencePages={referencePages} + referenceProducts={referenceProducts} + fetchReferencePages={fetchReferencePages} + fetchMoreReferencePages={fetchMoreReferencePages} + fetchReferenceProducts={fetchReferenceProducts} + fetchMoreReferenceProducts={fetchMoreReferenceProducts} + assignReferencesAttributeId={assignReferencesAttributeId} > {({ change, @@ -408,13 +423,14 @@ export const ProductUpdatePage: React.FC = ({ attributeValues={getAttributeValuesFromReferences( assignReferencesAttributeId, data.attributes, - referencePages + referencePages, + referenceProducts )} - hasMore={fetchMoreReferencePages?.hasMore} + hasMore={handlers.fetchMoreReferences?.hasMore} open={canOpenAssignReferencesAttributeDialog} - onFetch={fetchReferencePages} - onFetchMore={fetchMoreReferencePages?.onFetchMore} - loading={fetchMoreReferencePages?.loading} + onFetch={handlers.fetchReferences} + onFetchMore={handlers.fetchMoreReferences?.onFetchMore} + loading={handlers.fetchMoreReferences?.loading} onClose={onCloseDialog} onSubmit={attributeValues => handleAssignReferenceAttribute( diff --git a/src/products/components/ProductUpdatePage/form.tsx b/src/products/components/ProductUpdatePage/form.tsx index c49f2c7f1..8873c597e 100644 --- a/src/products/components/ProductUpdatePage/form.tsx +++ b/src/products/components/ProductUpdatePage/form.tsx @@ -5,7 +5,9 @@ import { createAttributeFileChangeHandler, createAttributeMultiChangeHandler, createAttributeReferenceChangeHandler, - createAttributeValueReorderHandler + createAttributeValueReorderHandler, + createFetchMoreReferencesHandler, + createFetchReferencesHandler } from "@saleor/attributes/utils/handlers"; import { ChannelData, ChannelPriceArgs } from "@saleor/channels/utils"; import { AttributeInput } from "@saleor/components/Attributes"; @@ -34,8 +36,9 @@ import { validatePrice } from "@saleor/products/utils/validation"; import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages"; +import { SearchProducts_search_edges_node } from "@saleor/searches/types/SearchProducts"; import { SearchWarehouses_search_edges_node } from "@saleor/searches/types/SearchWarehouses"; -import { ReorderEvent } from "@saleor/types"; +import { FetchMoreProps, ReorderEvent } from "@saleor/types"; import handleFormSubmit from "@saleor/utils/handlers/handleFormSubmit"; import createMultiAutocompleteSelectHandler from "@saleor/utils/handlers/multiAutocompleteSelectChangeHandler"; import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler"; @@ -116,6 +119,8 @@ export interface ProductUpdateHandlers Record<"reorderAttributeValue", FormsetChange>, Record<"addStock" | "deleteStock", (id: string) => void> { changeDescription: RichTextEditorChange; + fetchReferences: (value: string) => void; + fetchMoreReferences: FetchMoreProps; } export interface UseProductUpdateFormResult { change: FormChange; @@ -143,6 +148,12 @@ export interface UseProductUpdateFormOpts currentChannels: ChannelData[]; hasVariants: boolean; referencePages: SearchPages_search_edges_node[]; + referenceProducts: SearchProducts_search_edges_node[]; + fetchReferencePages?: (data: string) => void; + fetchMoreReferencePages?: FetchMoreProps; + fetchReferenceProducts?: (data: string) => void; + fetchMoreReferenceProducts?: FetchMoreProps; + assignReferencesAttributeId?: string; } export interface ProductUpdateFormProps extends UseProductUpdateFormOpts { @@ -232,6 +243,18 @@ function useProductUpdateForm( attributes.change, triggerChange ); + const handleFetchReferences = createFetchReferencesHandler( + attributes.data, + opts.assignReferencesAttributeId, + opts.fetchReferencePages, + opts.fetchReferenceProducts + ); + const handleFetchMoreReferences = createFetchMoreReferencesHandler( + attributes.data, + opts.assignReferencesAttributeId, + opts.fetchMoreReferencePages, + opts.fetchMoreReferenceProducts + ); const handleAttributeFileChange = createAttributeFileChangeHandler( attributes.change, attributesWithNewFileValue.data, @@ -283,7 +306,8 @@ function useProductUpdateForm( attributes: getAttributesDisplayData( attributes.data, attributesWithNewFileValue.data, - opts.referencePages + opts.referencePages, + opts.referenceProducts ), description: description.current, stocks: stocks.data @@ -332,6 +356,8 @@ function useProductUpdateForm( changeMetadata, changeStock: handleStockChange, deleteStock: handleStockDelete, + fetchMoreReferences: handleFetchMoreReferences, + fetchReferences: handleFetchReferences, reorderAttributeValue: handleAttributeValueReorder, selectAttribute: handleAttributeChange, selectAttributeFile: handleAttributeFileChange, diff --git a/src/products/components/ProductVariantCreatePage/ProductVariantCreatePage.tsx b/src/products/components/ProductVariantCreatePage/ProductVariantCreatePage.tsx index b0caf9591..b8bb91f67 100644 --- a/src/products/components/ProductVariantCreatePage/ProductVariantCreatePage.tsx +++ b/src/products/components/ProductVariantCreatePage/ProductVariantCreatePage.tsx @@ -1,4 +1,7 @@ -import { mergeAttributeValues } from "@saleor/attributes/utils/data"; +import { + getAttributeValuesFromReferences, + mergeAttributeValues +} from "@saleor/attributes/utils/data"; import { ChannelPriceData } from "@saleor/channels/utils"; import AppHeader from "@saleor/components/AppHeader"; import AssignAttributeValueDialog from "@saleor/components/AssignAttributeValueDialog"; @@ -15,8 +18,8 @@ import PageHeader from "@saleor/components/PageHeader"; import SaveButtonBar from "@saleor/components/SaveButtonBar"; import { ProductChannelListingErrorFragment } from "@saleor/fragments/types/ProductChannelListingErrorFragment"; import { ProductErrorWithAttributesFragment } from "@saleor/fragments/types/ProductErrorWithAttributesFragment"; -import { getAttributeValuesFromReferences } from "@saleor/pages/utils/data"; import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages"; +import { SearchProducts_search_edges_node } from "@saleor/searches/types/SearchProducts"; import { SearchWarehouses_search_edges_node } from "@saleor/searches/types/SearchWarehouses"; import { FetchMoreProps, ReorderAction } from "@saleor/types"; import React from "react"; @@ -61,7 +64,8 @@ interface ProductVariantCreatePageProps { saveButtonBarState: ConfirmButtonTransitionState; warehouses: SearchWarehouses_search_edges_node[]; weightUnit: string; - referencePages: SearchPages_search_edges_node[]; + referencePages?: SearchPages_search_edges_node[]; + referenceProducts?: SearchProducts_search_edges_node[]; onBack: () => void; onSubmit: (data: ProductVariantCreateData) => void; onVariantClick: (variantId: string) => void; @@ -70,7 +74,9 @@ interface ProductVariantCreatePageProps { assignReferencesAttributeId?: string; onAssignReferencesClick: (attribute: AttributeInput) => void; fetchReferencePages?: (data: string) => void; + fetchReferenceProducts?: (data: string) => void; fetchMoreReferencePages?: FetchMoreProps; + fetchMoreReferenceProducts?: FetchMoreProps; onCloseDialog: () => void; } @@ -84,7 +90,8 @@ const ProductVariantCreatePage: React.FC = ({ saveButtonBarState, warehouses, weightUnit, - referencePages, + referencePages = [], + referenceProducts = [], onBack, onSubmit, onVariantClick, @@ -93,7 +100,9 @@ const ProductVariantCreatePage: React.FC = ({ assignReferencesAttributeId, onAssignReferencesClick, fetchReferencePages, + fetchReferenceProducts, fetchMoreReferencePages, + fetchMoreReferenceProducts, onCloseDialog }) => { const intl = useIntl(); @@ -123,6 +132,12 @@ const ProductVariantCreatePage: React.FC = ({ warehouses={warehouses} currentChannels={channels} referencePages={referencePages} + referenceProducts={referenceProducts} + fetchReferencePages={fetchReferencePages} + fetchMoreReferencePages={fetchMoreReferencePages} + fetchReferenceProducts={fetchReferenceProducts} + fetchMoreReferenceProducts={fetchMoreReferenceProducts} + assignReferencesAttributeId={assignReferencesAttributeId} > {({ change, @@ -237,13 +252,14 @@ const ProductVariantCreatePage: React.FC = ({ attributeValues={getAttributeValuesFromReferences( assignReferencesAttributeId, data.attributes, - referencePages + referencePages, + referenceProducts )} - hasMore={fetchMoreReferencePages?.hasMore} + hasMore={handlers.fetchMoreReferences?.hasMore} open={canOpenAssignReferencesAttributeDialog} - onFetch={fetchReferencePages} - onFetchMore={fetchMoreReferencePages?.onFetchMore} - loading={fetchMoreReferencePages?.loading} + onFetch={handlers.fetchReferences} + onFetchMore={handlers.fetchMoreReferences?.onFetchMore} + loading={handlers.fetchMoreReferences?.loading} onClose={onCloseDialog} onSubmit={attributeValues => handleAssignReferenceAttribute(attributeValues, data, handlers) diff --git a/src/products/components/ProductVariantCreatePage/form.tsx b/src/products/components/ProductVariantCreatePage/form.tsx index 3febccb3c..bad8c22a9 100644 --- a/src/products/components/ProductVariantCreatePage/form.tsx +++ b/src/products/components/ProductVariantCreatePage/form.tsx @@ -4,7 +4,9 @@ import { createAttributeFileChangeHandler, createAttributeMultiChangeHandler, createAttributeReferenceChangeHandler, - createAttributeValueReorderHandler + createAttributeValueReorderHandler, + createFetchMoreReferencesHandler, + createFetchReferencesHandler } from "@saleor/attributes/utils/handlers"; import { ChannelPriceData, IChannelPriceArgs } from "@saleor/channels/utils"; import { AttributeInput } from "@saleor/components/Attributes"; @@ -22,8 +24,9 @@ import { validatePrice } from "@saleor/products/utils/validation"; import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages"; +import { SearchProducts_search_edges_node } from "@saleor/searches/types/SearchProducts"; import { SearchWarehouses_search_edges_node } from "@saleor/searches/types/SearchWarehouses"; -import { ReorderEvent } from "@saleor/types"; +import { FetchMoreProps, ReorderEvent } from "@saleor/types"; import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger"; import React from "react"; @@ -45,6 +48,12 @@ export interface UseProductVariantCreateFormOpts { warehouses: SearchWarehouses_search_edges_node[]; currentChannels: ChannelPriceData[]; referencePages: SearchPages_search_edges_node[]; + referenceProducts: SearchProducts_search_edges_node[]; + fetchReferencePages?: (data: string) => void; + fetchMoreReferencePages?: FetchMoreProps; + fetchReferenceProducts?: (data: string) => void; + fetchMoreReferenceProducts?: FetchMoreProps; + assignReferencesAttributeId?: string; } export interface ProductVariantCreateHandlers @@ -60,6 +69,8 @@ export interface ProductVariantCreateHandlers Record<"reorderAttributeValue", FormsetChange>, Record<"addStock" | "deleteStock", (id: string) => void> { changeMetadata: FormChange; + fetchReferences: (value: string) => void; + fetchMoreReferences: FetchMoreProps; } export interface UseProductVariantCreateFormResult { @@ -125,6 +136,18 @@ function useProductVariantCreateForm( attributes.change, triggerChange ); + const handleFetchReferences = createFetchReferencesHandler( + attributes.data, + opts.assignReferencesAttributeId, + opts.fetchReferencePages, + opts.fetchReferenceProducts + ); + const handleFetchMoreReferences = createFetchMoreReferencesHandler( + attributes.data, + opts.assignReferencesAttributeId, + opts.fetchMoreReferencePages, + opts.fetchMoreReferenceProducts + ); const handleAttributeFileChange = createAttributeFileChangeHandler( attributes.change, attributesWithNewFileValue.data, @@ -170,7 +193,8 @@ function useProductVariantCreateForm( attributes: getAttributesDisplayData( attributes.data, attributesWithNewFileValue.data, - opts.referencePages + opts.referencePages, + opts.referenceProducts ), attributesWithNewFileValue: attributesWithNewFileValue.data, channelListings: channels.data, @@ -189,6 +213,8 @@ function useProductVariantCreateForm( changeMetadata, changeStock: handleStockChange, deleteStock: handleStockDelete, + fetchMoreReferences: handleFetchMoreReferences, + fetchReferences: handleFetchReferences, reorderAttributeValue: handleAttributeValueReorder, selectAttribute: handleAttributeChange, selectAttributeFile: handleAttributeFileChange, diff --git a/src/products/components/ProductVariantPage/ProductVariantPage.tsx b/src/products/components/ProductVariantPage/ProductVariantPage.tsx index 6e88471a5..0c86e51f1 100644 --- a/src/products/components/ProductVariantPage/ProductVariantPage.tsx +++ b/src/products/components/ProductVariantPage/ProductVariantPage.tsx @@ -1,4 +1,7 @@ -import { mergeAttributeValues } from "@saleor/attributes/utils/data"; +import { + getAttributeValuesFromReferences, + mergeAttributeValues +} from "@saleor/attributes/utils/data"; import { ChannelPriceData } from "@saleor/channels/utils"; import AppHeader from "@saleor/components/AppHeader"; import AssignAttributeValueDialog from "@saleor/components/AssignAttributeValueDialog"; @@ -18,9 +21,9 @@ import { ProductChannelListingErrorFragment } from "@saleor/fragments/types/Prod import { ProductErrorWithAttributesFragment } from "@saleor/fragments/types/ProductErrorWithAttributesFragment"; import { ProductVariant } from "@saleor/fragments/types/ProductVariant"; import { WarehouseFragment } from "@saleor/fragments/types/WarehouseFragment"; -import { getAttributeValuesFromReferences } from "@saleor/pages/utils/data"; import { VariantUpdate_productVariantUpdate_errors } from "@saleor/products/types/VariantUpdate"; import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages"; +import { SearchProducts_search_edges_node } from "@saleor/searches/types/SearchProducts"; import { FetchMoreProps, ReorderAction } from "@saleor/types"; import React from "react"; import { defineMessages, useIntl } from "react-intl"; @@ -81,9 +84,12 @@ interface ProductVariantPageProps { saveButtonBarState: ConfirmButtonTransitionState; variant?: ProductVariant; warehouses: WarehouseFragment[]; - referencePages: SearchPages_search_edges_node[]; + referencePages?: SearchPages_search_edges_node[]; + referenceProducts?: SearchProducts_search_edges_node[]; fetchMoreReferencePages?: FetchMoreProps; + fetchMoreReferenceProducts?: FetchMoreProps; fetchReferencePages?: (data: string) => void; + fetchReferenceProducts?: (data: string) => void; onAssignReferencesClick: (attribute: AttributeInput) => void; onCloseDialog: () => void; onVariantReorder: ReorderAction; @@ -109,7 +115,8 @@ const ProductVariantPage: React.FC = ({ saveButtonBarState, variant, warehouses, - referencePages, + referencePages = [], + referenceProducts = [], onAdd, onBack, onDelete, @@ -122,7 +129,9 @@ const ProductVariantPage: React.FC = ({ assignReferencesAttributeId, onAssignReferencesClick, fetchReferencePages, + fetchReferenceProducts, fetchMoreReferencePages, + fetchMoreReferenceProducts, onCloseDialog }) => { const intl = useIntl(); @@ -173,6 +182,12 @@ const ProductVariantPage: React.FC = ({ warehouses={warehouses} currentChannels={channels} referencePages={referencePages} + referenceProducts={referenceProducts} + fetchReferencePages={fetchReferencePages} + fetchMoreReferencePages={fetchMoreReferencePages} + fetchReferenceProducts={fetchReferenceProducts} + fetchMoreReferenceProducts={fetchMoreReferenceProducts} + assignReferencesAttributeId={assignReferencesAttributeId} > {({ change, @@ -296,13 +311,14 @@ const ProductVariantPage: React.FC = ({ attributeValues={getAttributeValuesFromReferences( assignReferencesAttributeId, data.attributes, - referencePages + referencePages, + referenceProducts )} - hasMore={fetchMoreReferencePages?.hasMore} + hasMore={handlers.fetchMoreReferences?.hasMore} open={canOpenAssignReferencesAttributeDialog} - onFetch={fetchReferencePages} - onFetchMore={fetchMoreReferencePages?.onFetchMore} - loading={fetchMoreReferencePages?.loading} + onFetch={handlers.fetchReferences} + onFetchMore={handlers.fetchMoreReferences?.onFetchMore} + loading={handlers.fetchMoreReferences?.loading} onClose={onCloseDialog} onSubmit={attributeValues => handleAssignReferenceAttribute( diff --git a/src/products/components/ProductVariantPage/form.tsx b/src/products/components/ProductVariantPage/form.tsx index d257d4306..44b859390 100644 --- a/src/products/components/ProductVariantPage/form.tsx +++ b/src/products/components/ProductVariantPage/form.tsx @@ -4,7 +4,9 @@ import { createAttributeFileChangeHandler, createAttributeMultiChangeHandler, createAttributeReferenceChangeHandler, - createAttributeValueReorderHandler + createAttributeValueReorderHandler, + createFetchMoreReferencesHandler, + createFetchReferencesHandler } from "@saleor/attributes/utils/handlers"; import { ChannelPriceData, IChannelPriceArgs } from "@saleor/channels/utils"; import { AttributeInput } from "@saleor/components/Attributes"; @@ -25,8 +27,9 @@ import { validatePrice } from "@saleor/products/utils/validation"; import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages"; +import { SearchProducts_search_edges_node } from "@saleor/searches/types/SearchProducts"; import { SearchWarehouses_search_edges_node } from "@saleor/searches/types/SearchWarehouses"; -import { ReorderEvent } from "@saleor/types"; +import { FetchMoreProps, ReorderEvent } from "@saleor/types"; import { mapMetadataItemToInput } from "@saleor/utils/maps"; import getMetadata from "@saleor/utils/metadata/getMetadata"; import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger"; @@ -60,6 +63,12 @@ export interface UseProductVariantUpdateFormOpts { warehouses: SearchWarehouses_search_edges_node[]; currentChannels: ChannelPriceData[]; referencePages: SearchPages_search_edges_node[]; + referenceProducts: SearchProducts_search_edges_node[]; + fetchReferencePages?: (data: string) => void; + fetchMoreReferencePages?: FetchMoreProps; + fetchReferenceProducts?: (data: string) => void; + fetchMoreReferenceProducts?: FetchMoreProps; + assignReferencesAttributeId?: string; } export interface ProductVariantUpdateHandlers @@ -75,6 +84,8 @@ export interface ProductVariantUpdateHandlers Record<"reorderAttributeValue", FormsetChange>, Record<"addStock" | "deleteStock", (id: string) => void> { changeMetadata: FormChange; + fetchReferences: (value: string) => void; + fetchMoreReferences: FetchMoreProps; } export interface UseProductVariantUpdateFormResult { @@ -142,6 +153,18 @@ function useProductVariantUpdateForm( attributes.change, triggerChange ); + const handleFetchReferences = createFetchReferencesHandler( + attributes.data, + opts.assignReferencesAttributeId, + opts.fetchReferencePages, + opts.fetchReferenceProducts + ); + const handleFetchMoreReferences = createFetchMoreReferencesHandler( + attributes.data, + opts.assignReferencesAttributeId, + opts.fetchMoreReferencePages, + opts.fetchMoreReferenceProducts + ); const handleAttributeFileChange = createAttributeFileChangeHandler( attributes.change, attributesWithNewFileValue.data, @@ -201,7 +224,8 @@ function useProductVariantUpdateForm( attributes: getAttributesDisplayData( attributes.data, attributesWithNewFileValue.data, - opts.referencePages + opts.referencePages, + opts.referenceProducts ), channelListings: channels.data, stocks: stocks.data @@ -239,6 +263,8 @@ function useProductVariantUpdateForm( changeMetadata, changeStock: handleStockChange, deleteStock: handleStockDelete, + fetchMoreReferences: handleFetchMoreReferences, + fetchReferences: handleFetchReferences, reorderAttributeValue: handleAttributeValueReorder, selectAttribute: handleAttributeChange, selectAttributeFile: handleAttributeFileChange, diff --git a/src/products/fixtures.ts b/src/products/fixtures.ts index e12aa85f9..602232486 100644 --- a/src/products/fixtures.ts +++ b/src/products/fixtures.ts @@ -22,6 +22,7 @@ export const product: ( __typename: "SelectedAttribute", attribute: { __typename: "Attribute" as "Attribute", + entityType: null, id: "pta18161", inputType: AttributeInputTypeEnum.DROPDOWN, name: "Borders", @@ -61,6 +62,7 @@ export const product: ( __typename: "SelectedAttribute", attribute: { __typename: "Attribute" as "Attribute", + entityType: null, id: "pta22785", inputType: AttributeInputTypeEnum.MULTISELECT, name: "Legacy", @@ -262,6 +264,7 @@ export const product: ( nonSelectionVariantAttributes: [ { __typename: "Attribute", + entityType: null, id: "isdugfhud", inputType: AttributeInputTypeEnum.FILE, name: "Attachment", @@ -286,6 +289,7 @@ export const product: ( selectionVariantAttributes: [ { __typename: "Attribute", + entityType: null, id: "pta18161", inputType: AttributeInputTypeEnum.DROPDOWN, name: "Color", @@ -2710,6 +2714,7 @@ export const variant = (placeholderImage: string): ProductVariant => ({ __typename: "SelectedAttribute", attribute: { __typename: "Attribute", + entityType: null, id: "nfnyffcf8eyfm", inputType: AttributeInputTypeEnum.FILE, name: "Attachment", @@ -2945,6 +2950,7 @@ export const variant = (placeholderImage: string): ProductVariant => ({ __typename: "SelectedAttribute", attribute: { __typename: "Attribute" as "Attribute", + entityType: null, id: "pta18161", inputType: AttributeInputTypeEnum.DROPDOWN, name: "Borders", @@ -2984,6 +2990,7 @@ export const variant = (placeholderImage: string): ProductVariant => ({ __typename: "SelectedAttribute", attribute: { __typename: "Attribute" as "Attribute", + entityType: null, id: "pta22785", inputType: AttributeInputTypeEnum.DROPDOWN, name: "Legacy", diff --git a/src/products/types/CreateMultipleVariantsData.ts b/src/products/types/CreateMultipleVariantsData.ts index 5d7621d9d..4dc515a03 100644 --- a/src/products/types/CreateMultipleVariantsData.ts +++ b/src/products/types/CreateMultipleVariantsData.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { AttributeInputTypeEnum } from "./../../types/globalTypes"; +import { AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL query operation: CreateMultipleVariantsData @@ -29,6 +29,7 @@ export interface CreateMultipleVariantsData_product_attributes_attribute { slug: string | null; name: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (CreateMultipleVariantsData_product_attributes_attribute_values | null)[] | null; } diff --git a/src/products/types/ProductChannelListingUpdate.ts b/src/products/types/ProductChannelListingUpdate.ts index c7e8495e4..d12f9953d 100644 --- a/src/products/types/ProductChannelListingUpdate.ts +++ b/src/products/types/ProductChannelListingUpdate.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { ProductChannelListingUpdateInput, AttributeInputTypeEnum, WeightUnitsEnum, ProductErrorCode } from "./../../types/globalTypes"; +import { ProductChannelListingUpdateInput, AttributeInputTypeEnum, AttributeEntityTypeEnum, WeightUnitsEnum, ProductErrorCode } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: ProductChannelListingUpdate @@ -29,6 +29,7 @@ export interface ProductChannelListingUpdate_productChannelListingUpdate_product slug: string | null; name: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (ProductChannelListingUpdate_productChannelListingUpdate_product_attributes_attribute_values | null)[] | null; } diff --git a/src/products/types/ProductCreate.ts b/src/products/types/ProductCreate.ts index c44492a14..174158d4b 100644 --- a/src/products/types/ProductCreate.ts +++ b/src/products/types/ProductCreate.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { ProductCreateInput, ProductErrorCode, AttributeInputTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; +import { ProductCreateInput, ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: ProductCreate @@ -36,6 +36,7 @@ export interface ProductCreate_productCreate_product_attributes_attribute { slug: string | null; name: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (ProductCreate_productCreate_product_attributes_attribute_values | null)[] | null; } diff --git a/src/products/types/ProductDetails.ts b/src/products/types/ProductDetails.ts index 1dd8b0bcc..a8ed59463 100644 --- a/src/products/types/ProductDetails.ts +++ b/src/products/types/ProductDetails.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { AttributeInputTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; +import { AttributeInputTypeEnum, AttributeEntityTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL query operation: ProductDetails @@ -29,6 +29,7 @@ export interface ProductDetails_product_attributes_attribute { slug: string | null; name: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (ProductDetails_product_attributes_attribute_values | null)[] | null; } diff --git a/src/products/types/ProductImageCreate.ts b/src/products/types/ProductImageCreate.ts index 3ef7a7253..704823003 100644 --- a/src/products/types/ProductImageCreate.ts +++ b/src/products/types/ProductImageCreate.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { ProductErrorCode, AttributeInputTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; +import { ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: ProductImageCreate @@ -35,6 +35,7 @@ export interface ProductImageCreate_productImageCreate_product_attributes_attrib slug: string | null; name: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (ProductImageCreate_productImageCreate_product_attributes_attribute_values | null)[] | null; } diff --git a/src/products/types/ProductImageUpdate.ts b/src/products/types/ProductImageUpdate.ts index c6fa243f0..219de6624 100644 --- a/src/products/types/ProductImageUpdate.ts +++ b/src/products/types/ProductImageUpdate.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { ProductErrorCode, AttributeInputTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; +import { ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: ProductImageUpdate @@ -35,6 +35,7 @@ export interface ProductImageUpdate_productImageUpdate_product_attributes_attrib slug: string | null; name: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (ProductImageUpdate_productImageUpdate_product_attributes_attribute_values | null)[] | null; } diff --git a/src/products/types/ProductUpdate.ts b/src/products/types/ProductUpdate.ts index 75d41461e..661a7a0cf 100644 --- a/src/products/types/ProductUpdate.ts +++ b/src/products/types/ProductUpdate.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { ProductInput, ProductErrorCode, AttributeInputTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; +import { ProductInput, ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: ProductUpdate @@ -36,6 +36,7 @@ export interface ProductUpdate_productUpdate_product_attributes_attribute { slug: string | null; name: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (ProductUpdate_productUpdate_product_attributes_attribute_values | null)[] | null; } diff --git a/src/products/types/ProductVariantChannelListingUpdate.ts b/src/products/types/ProductVariantChannelListingUpdate.ts index b8c6d66bc..30220e6c0 100644 --- a/src/products/types/ProductVariantChannelListingUpdate.ts +++ b/src/products/types/ProductVariantChannelListingUpdate.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { ProductVariantChannelListingAddInput, AttributeInputTypeEnum, WeightUnitsEnum, ProductErrorCode } from "./../../types/globalTypes"; +import { ProductVariantChannelListingAddInput, AttributeInputTypeEnum, AttributeEntityTypeEnum, WeightUnitsEnum, ProductErrorCode } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: ProductVariantChannelListingUpdate @@ -41,6 +41,7 @@ export interface ProductVariantChannelListingUpdate_productVariantChannelListing name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (ProductVariantChannelListingUpdate_productVariantChannelListingUpdate_variant_selectionAttributes_attribute_values | null)[] | null; } @@ -87,6 +88,7 @@ export interface ProductVariantChannelListingUpdate_productVariantChannelListing name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (ProductVariantChannelListingUpdate_productVariantChannelListingUpdate_variant_nonSelectionAttributes_attribute_values | null)[] | null; } diff --git a/src/products/types/ProductVariantCreateData.ts b/src/products/types/ProductVariantCreateData.ts index 7cb5f0e4c..042a9d2af 100644 --- a/src/products/types/ProductVariantCreateData.ts +++ b/src/products/types/ProductVariantCreateData.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { AttributeInputTypeEnum } from "./../../types/globalTypes"; +import { AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL query operation: ProductVariantCreateData @@ -48,6 +48,7 @@ export interface ProductVariantCreateData_product_productType_selectionVariantAt name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (ProductVariantCreateData_product_productType_selectionVariantAttributes_values | null)[] | null; } @@ -73,6 +74,7 @@ export interface ProductVariantCreateData_product_productType_nonSelectionVarian name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (ProductVariantCreateData_product_productType_nonSelectionVariantAttributes_values | null)[] | null; } diff --git a/src/products/types/ProductVariantDetails.ts b/src/products/types/ProductVariantDetails.ts index a7a4ebc9d..c4853e724 100644 --- a/src/products/types/ProductVariantDetails.ts +++ b/src/products/types/ProductVariantDetails.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { AttributeInputTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; +import { AttributeInputTypeEnum, AttributeEntityTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL query operation: ProductVariantDetails @@ -41,6 +41,7 @@ export interface ProductVariantDetails_productVariant_selectionAttributes_attrib name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (ProductVariantDetails_productVariant_selectionAttributes_attribute_values | null)[] | null; } @@ -87,6 +88,7 @@ export interface ProductVariantDetails_productVariant_nonSelectionAttributes_att name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (ProductVariantDetails_productVariant_nonSelectionAttributes_attribute_values | null)[] | null; } diff --git a/src/products/types/ProductVariantReorder.ts b/src/products/types/ProductVariantReorder.ts index 652d1a2c8..68fb0c764 100644 --- a/src/products/types/ProductVariantReorder.ts +++ b/src/products/types/ProductVariantReorder.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { ReorderInput, ProductErrorCode, AttributeInputTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; +import { ReorderInput, ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: ProductVariantReorder @@ -35,6 +35,7 @@ export interface ProductVariantReorder_productVariantReorder_product_attributes_ slug: string | null; name: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (ProductVariantReorder_productVariantReorder_product_attributes_attribute_values | null)[] | null; } diff --git a/src/products/types/ProductVariantSetDefault.ts b/src/products/types/ProductVariantSetDefault.ts index 8a9c2ecb3..ed095108d 100644 --- a/src/products/types/ProductVariantSetDefault.ts +++ b/src/products/types/ProductVariantSetDefault.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { ProductErrorCode, AttributeInputTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; +import { ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: ProductVariantSetDefault @@ -35,6 +35,7 @@ export interface ProductVariantSetDefault_productVariantSetDefault_product_attri slug: string | null; name: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (ProductVariantSetDefault_productVariantSetDefault_product_attributes_attribute_values | null)[] | null; } diff --git a/src/products/types/SimpleProductUpdate.ts b/src/products/types/SimpleProductUpdate.ts index 9be3b83bf..2703b3ed8 100644 --- a/src/products/types/SimpleProductUpdate.ts +++ b/src/products/types/SimpleProductUpdate.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { ProductInput, ProductVariantInput, StockInput, ProductErrorCode, AttributeInputTypeEnum, WeightUnitsEnum, StockErrorCode } from "./../../types/globalTypes"; +import { ProductInput, ProductVariantInput, StockInput, ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, WeightUnitsEnum, StockErrorCode } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: SimpleProductUpdate @@ -36,6 +36,7 @@ export interface SimpleProductUpdate_productUpdate_product_attributes_attribute slug: string | null; name: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (SimpleProductUpdate_productUpdate_product_attributes_attribute_values | null)[] | null; } @@ -320,6 +321,7 @@ export interface SimpleProductUpdate_productVariantUpdate_productVariant_selecti name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (SimpleProductUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_values | null)[] | null; } @@ -366,6 +368,7 @@ export interface SimpleProductUpdate_productVariantUpdate_productVariant_nonSele name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (SimpleProductUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_values | null)[] | null; } @@ -595,6 +598,7 @@ export interface SimpleProductUpdate_productVariantStocksCreate_productVariant_s name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (SimpleProductUpdate_productVariantStocksCreate_productVariant_selectionAttributes_attribute_values | null)[] | null; } @@ -641,6 +645,7 @@ export interface SimpleProductUpdate_productVariantStocksCreate_productVariant_n name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (SimpleProductUpdate_productVariantStocksCreate_productVariant_nonSelectionAttributes_attribute_values | null)[] | null; } @@ -869,6 +874,7 @@ export interface SimpleProductUpdate_productVariantStocksDelete_productVariant_s name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (SimpleProductUpdate_productVariantStocksDelete_productVariant_selectionAttributes_attribute_values | null)[] | null; } @@ -915,6 +921,7 @@ export interface SimpleProductUpdate_productVariantStocksDelete_productVariant_n name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (SimpleProductUpdate_productVariantStocksDelete_productVariant_nonSelectionAttributes_attribute_values | null)[] | null; } @@ -1144,6 +1151,7 @@ export interface SimpleProductUpdate_productVariantStocksUpdate_productVariant_s name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (SimpleProductUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_values | null)[] | null; } @@ -1190,6 +1198,7 @@ export interface SimpleProductUpdate_productVariantStocksUpdate_productVariant_n name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (SimpleProductUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_values | null)[] | null; } diff --git a/src/products/types/VariantCreate.ts b/src/products/types/VariantCreate.ts index f31d5b352..a805f7dd2 100644 --- a/src/products/types/VariantCreate.ts +++ b/src/products/types/VariantCreate.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { ProductVariantCreateInput, ProductErrorCode, AttributeInputTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; +import { ProductVariantCreateInput, ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: VariantCreate @@ -48,6 +48,7 @@ export interface VariantCreate_productVariantCreate_productVariant_selectionAttr name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (VariantCreate_productVariantCreate_productVariant_selectionAttributes_attribute_values | null)[] | null; } @@ -94,6 +95,7 @@ export interface VariantCreate_productVariantCreate_productVariant_nonSelectionA name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (VariantCreate_productVariantCreate_productVariant_nonSelectionAttributes_attribute_values | null)[] | null; } diff --git a/src/products/types/VariantImageAssign.ts b/src/products/types/VariantImageAssign.ts index c6058315f..1b5a70a03 100644 --- a/src/products/types/VariantImageAssign.ts +++ b/src/products/types/VariantImageAssign.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { ProductErrorCode, AttributeInputTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; +import { ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: VariantImageAssign @@ -47,6 +47,7 @@ export interface VariantImageAssign_variantImageAssign_productVariant_selectionA name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (VariantImageAssign_variantImageAssign_productVariant_selectionAttributes_attribute_values | null)[] | null; } @@ -93,6 +94,7 @@ export interface VariantImageAssign_variantImageAssign_productVariant_nonSelecti name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (VariantImageAssign_variantImageAssign_productVariant_nonSelectionAttributes_attribute_values | null)[] | null; } diff --git a/src/products/types/VariantImageUnassign.ts b/src/products/types/VariantImageUnassign.ts index be0df6e40..a9cd3818c 100644 --- a/src/products/types/VariantImageUnassign.ts +++ b/src/products/types/VariantImageUnassign.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { ProductErrorCode, AttributeInputTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; +import { ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: VariantImageUnassign @@ -47,6 +47,7 @@ export interface VariantImageUnassign_variantImageUnassign_productVariant_select name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (VariantImageUnassign_variantImageUnassign_productVariant_selectionAttributes_attribute_values | null)[] | null; } @@ -93,6 +94,7 @@ export interface VariantImageUnassign_variantImageUnassign_productVariant_nonSel name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (VariantImageUnassign_variantImageUnassign_productVariant_nonSelectionAttributes_attribute_values | null)[] | null; } diff --git a/src/products/types/VariantUpdate.ts b/src/products/types/VariantUpdate.ts index 519334bc8..0b2c430de 100644 --- a/src/products/types/VariantUpdate.ts +++ b/src/products/types/VariantUpdate.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { StockInput, AttributeValueInput, ProductErrorCode, AttributeInputTypeEnum, WeightUnitsEnum, StockErrorCode } from "./../../types/globalTypes"; +import { StockInput, AttributeValueInput, ProductErrorCode, AttributeInputTypeEnum, AttributeEntityTypeEnum, WeightUnitsEnum, StockErrorCode } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: VariantUpdate @@ -48,6 +48,7 @@ export interface VariantUpdate_productVariantUpdate_productVariant_selectionAttr name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (VariantUpdate_productVariantUpdate_productVariant_selectionAttributes_attribute_values | null)[] | null; } @@ -94,6 +95,7 @@ export interface VariantUpdate_productVariantUpdate_productVariant_nonSelectionA name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (VariantUpdate_productVariantUpdate_productVariant_nonSelectionAttributes_attribute_values | null)[] | null; } @@ -323,6 +325,7 @@ export interface VariantUpdate_productVariantStocksUpdate_productVariant_selecti name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (VariantUpdate_productVariantStocksUpdate_productVariant_selectionAttributes_attribute_values | null)[] | null; } @@ -369,6 +372,7 @@ export interface VariantUpdate_productVariantStocksUpdate_productVariant_nonSele name: string | null; slug: string | null; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; valueRequired: boolean; values: (VariantUpdate_productVariantStocksUpdate_productVariant_nonSelectionAttributes_attribute_values | null)[] | null; } diff --git a/src/products/utils/data.ts b/src/products/utils/data.ts index 8ee4a6d6c..e6f8525e9 100644 --- a/src/products/utils/data.ts +++ b/src/products/utils/data.ts @@ -47,6 +47,7 @@ export function getAttributeInputFromProduct( (): AttributeInput[] => product.attributes.map(attribute => ({ data: { + entityType: attribute.attribute.entityType, inputType: attribute.attribute.inputType, isRequired: attribute.attribute.valueRequired, selectedValues: attribute.values, @@ -65,6 +66,7 @@ export function getAttributeInputFromProductType( ): AttributeInput[] { return productType.productAttributes.map(attribute => ({ data: { + entityType: attribute.entityType, inputType: attribute.inputType, isRequired: attribute.valueRequired, values: attribute.values @@ -81,6 +83,7 @@ export function getAttributeInputFromAttributes( ): AttributeInput[] { return variantAttributes?.map(attribute => ({ data: { + entityType: attribute.entityType, inputType: attribute.inputType, isRequired: attribute.valueRequired, values: attribute.values, @@ -98,6 +101,7 @@ export function getAttributeInputFromSelectedAttributes( ): AttributeInput[] { return variantAttributes?.map(attribute => ({ data: { + entityType: attribute.attribute.entityType, inputType: attribute.attribute.inputType, isRequired: attribute.attribute.valueRequired, selectedValues: attribute.values, diff --git a/src/products/views/ProductCreate/ProductCreate.tsx b/src/products/views/ProductCreate/ProductCreate.tsx index 03150579e..7f10487d9 100644 --- a/src/products/views/ProductCreate/ProductCreate.tsx +++ b/src/products/views/ProductCreate/ProductCreate.tsx @@ -27,6 +27,7 @@ import { import useCategorySearch from "@saleor/searches/useCategorySearch"; import useCollectionSearch from "@saleor/searches/useCollectionSearch"; import usePageSearch from "@saleor/searches/usePageSearch"; +import useProductSearch from "@saleor/searches/useProductSearch"; import useProductTypeSearch from "@saleor/searches/useProductTypeSearch"; import { useTaxTypeList } from "@saleor/taxes/queries"; import { getProductErrorMessage } from "@saleor/utils/errors"; @@ -89,6 +90,13 @@ export const ProductCreateView: React.FC = ({ params }) => { } = usePageSearch({ variables: DEFAULT_INITIAL_SEARCH_DATA }); + const { + loadMore: loadMoreProducts, + search: searchProducts, + result: searchProductsOpts + } = useProductSearch({ + variables: DEFAULT_INITIAL_SEARCH_DATA + }); const warehouses = useWarehouseList({ displayLoader: true, variables: { @@ -202,25 +210,30 @@ export const ProductCreateView: React.FC = ({ params }) => { }, [productCreateComplete]); const fetchMoreProductTypes = { - hasMore: searchProductTypesOpts.data?.search.pageInfo.hasNextPage, + hasMore: searchProductTypesOpts.data?.search?.pageInfo?.hasNextPage, loading: searchProductTypesOpts.loading, onFetchMore: loadMoreProductTypes }; const fetchMoreCollections = { - hasMore: searchCollectionOpts.data?.search.pageInfo.hasNextPage, + hasMore: searchCollectionOpts.data?.search?.pageInfo?.hasNextPage, loading: searchCollectionOpts.loading, onFetchMore: loadMoreCollections }; const fetchMoreCategories = { - hasMore: searchCategoryOpts.data?.search.pageInfo.hasNextPage, + hasMore: searchCategoryOpts.data?.search?.pageInfo?.hasNextPage, loading: searchCategoryOpts.loading, onFetchMore: loadMoreCategories }; const fetchMoreReferencePages = { - hasMore: searchPagesOpts.data?.search.pageInfo.hasNextPage, + hasMore: searchPagesOpts.data?.search?.pageInfo?.hasNextPage, loading: searchPagesOpts.loading, onFetchMore: loadMorePages }; + const fetchMoreReferenceProducts = { + hasMore: searchProductsOpts.data?.search?.pageInfo?.hasNextPage, + loading: searchProductsOpts.loading, + onFetchMore: loadMoreProducts + }; const loading = uploadFileOpts.loading || @@ -301,8 +314,13 @@ export const ProductCreateView: React.FC = ({ params }) => { referencePages={searchPagesOpts.data?.search.edges.map( edge => edge.node )} + referenceProducts={searchProductsOpts.data?.search.edges.map( + edge => edge.node + )} fetchReferencePages={searchPages} fetchMoreReferencePages={fetchMoreReferencePages} + fetchReferenceProducts={searchProducts} + fetchMoreReferenceProducts={fetchMoreReferenceProducts} onCloseDialog={() => navigate(productAddUrl())} /> diff --git a/src/products/views/ProductUpdate/ProductUpdate.tsx b/src/products/views/ProductUpdate/ProductUpdate.tsx index 9bca2a110..dc6621c02 100644 --- a/src/products/views/ProductUpdate/ProductUpdate.tsx +++ b/src/products/views/ProductUpdate/ProductUpdate.tsx @@ -40,6 +40,7 @@ import { import useCategorySearch from "@saleor/searches/useCategorySearch"; import useCollectionSearch from "@saleor/searches/useCollectionSearch"; import usePageSearch from "@saleor/searches/usePageSearch"; +import useProductSearch from "@saleor/searches/useProductSearch"; import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers"; import createMetadataUpdateHandler from "@saleor/utils/handlers/metadataUpdateHandler"; import { @@ -106,6 +107,13 @@ export const ProductUpdate: React.FC = ({ id, params }) => { } = usePageSearch({ variables: DEFAULT_INITIAL_SEARCH_DATA }); + const { + loadMore: loadMoreProducts, + search: searchProducts, + result: searchProductsOpts + } = useProductSearch({ + variables: DEFAULT_INITIAL_SEARCH_DATA + }); const warehouses = useWarehouseList({ displayLoader: true, variables: { @@ -356,20 +364,25 @@ export const ProductUpdate: React.FC = ({ id, params }) => { ]; const fetchMoreCollections = { - hasMore: searchCollectionsOpts.data?.search.pageInfo.hasNextPage, + hasMore: searchCollectionsOpts.data?.search?.pageInfo?.hasNextPage, loading: searchCollectionsOpts.loading, onFetchMore: loadMoreCollections }; const fetchMoreCategories = { - hasMore: searchCategoriesOpts.data?.search.pageInfo.hasNextPage, + hasMore: searchCategoriesOpts.data?.search?.pageInfo?.hasNextPage, loading: searchCategoriesOpts.loading, onFetchMore: loadMoreCategories }; const fetchMoreReferencePages = { - hasMore: searchPagesOpts.data?.search.pageInfo.hasNextPage, + hasMore: searchPagesOpts.data?.search?.pageInfo?.hasNextPage, loading: searchPagesOpts.loading, onFetchMore: loadMorePages }; + const fetchMoreReferenceProducts = { + hasMore: searchProductsOpts.data?.search?.pageInfo?.hasNextPage, + loading: searchProductsOpts.loading, + onFetchMore: loadMoreProducts + }; return ( <> @@ -458,8 +471,13 @@ export const ProductUpdate: React.FC = ({ id, params }) => { referencePages={searchPagesOpts.data?.search.edges.map( edge => edge.node )} + referenceProducts={searchProductsOpts.data?.search.edges.map( + edge => edge.node + )} fetchReferencePages={searchPages} fetchMoreReferencePages={fetchMoreReferencePages} + fetchReferenceProducts={searchProducts} + fetchMoreReferenceProducts={fetchMoreReferenceProducts} onCloseDialog={() => navigate(productUrl(id))} /> = ({ } = usePageSearch({ variables: DEFAULT_INITIAL_SEARCH_DATA }); + const { + loadMore: loadMoreProducts, + search: searchProducts, + result: searchProductsOpts + } = useProductSearch({ + variables: DEFAULT_INITIAL_SEARCH_DATA + }); const fetchMoreReferencePages = { - hasMore: searchPagesOpts.data?.search.pageInfo.hasNextPage, + hasMore: searchPagesOpts.data?.search?.pageInfo?.hasNextPage, loading: searchPagesOpts.loading, onFetchMore: loadMorePages }; + const fetchMoreReferenceProducts = { + hasMore: searchProductsOpts.data?.search?.pageInfo?.hasNextPage, + loading: searchProductsOpts.loading, + onFetchMore: loadMoreProducts + }; return ( <> @@ -335,8 +348,13 @@ export const ProductVariant: React.FC = ({ referencePages={searchPagesOpts.data?.search.edges.map( edge => edge.node )} + referenceProducts={searchProductsOpts.data?.search.edges.map( + edge => edge.node + )} fetchReferencePages={searchPages} fetchMoreReferencePages={fetchMoreReferencePages} + fetchReferenceProducts={searchProducts} + fetchMoreReferenceProducts={fetchMoreReferenceProducts} onCloseDialog={() => navigate(productVariantEditUrl(productId, variantId)) } diff --git a/src/products/views/ProductVariantCreate.tsx b/src/products/views/ProductVariantCreate.tsx index e5db0d460..25a273629 100644 --- a/src/products/views/ProductVariantCreate.tsx +++ b/src/products/views/ProductVariantCreate.tsx @@ -16,6 +16,7 @@ import { commonMessages } from "@saleor/intl"; import { useProductVariantChannelListingUpdate } from "@saleor/products/mutations"; import { ProductVariantChannelListingUpdate } from "@saleor/products/types/ProductVariantChannelListingUpdate"; import usePageSearch from "@saleor/searches/usePageSearch"; +import useProductSearch from "@saleor/searches/useProductSearch"; import createMetadataCreateHandler from "@saleor/utils/handlers/metadataCreateHandler"; import { useMetadataUpdate, @@ -198,12 +199,24 @@ export const ProductVariant: React.FC = ({ } = usePageSearch({ variables: DEFAULT_INITIAL_SEARCH_DATA }); + const { + loadMore: loadMoreProducts, + search: searchProducts, + result: searchProductsOpts + } = useProductSearch({ + variables: DEFAULT_INITIAL_SEARCH_DATA + }); const fetchMoreReferencePages = { - hasMore: searchPagesOpts.data?.search.pageInfo.hasNextPage, + hasMore: searchPagesOpts.data?.search?.pageInfo?.hasNextPage, loading: searchPagesOpts.loading, onFetchMore: loadMorePages }; + const fetchMoreReferenceProducts = { + hasMore: searchProductsOpts.data?.search?.pageInfo?.hasNextPage, + loading: searchProductsOpts.loading, + onFetchMore: loadMoreProducts + }; const disableForm = productLoading || @@ -248,8 +261,13 @@ export const ProductVariant: React.FC = ({ referencePages={searchPagesOpts.data?.search.edges.map( edge => edge.node )} + referenceProducts={searchProductsOpts.data?.search.edges.map( + edge => edge.node + )} fetchReferencePages={searchPages} fetchMoreReferencePages={fetchMoreReferencePages} + fetchReferenceProducts={searchProducts} + fetchMoreReferenceProducts={fetchMoreReferenceProducts} onCloseDialog={() => navigate(productVariantAddUrl(productId))} /> diff --git a/src/searches/types/SearchPageTypes.ts b/src/searches/types/SearchPageTypes.ts index 9fc09393d..faab63336 100644 --- a/src/searches/types/SearchPageTypes.ts +++ b/src/searches/types/SearchPageTypes.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { AttributeInputTypeEnum } from "./../../types/globalTypes"; +import { AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL query operation: SearchPageTypes @@ -27,6 +27,7 @@ export interface SearchPageTypes_search_edges_node_attributes { __typename: "Attribute"; id: string; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; slug: string | null; name: string | null; valueRequired: boolean; diff --git a/src/searches/types/SearchProductTypes.ts b/src/searches/types/SearchProductTypes.ts index 91ef9d89a..01a45d57b 100644 --- a/src/searches/types/SearchProductTypes.ts +++ b/src/searches/types/SearchProductTypes.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { AttributeInputTypeEnum } from "./../../types/globalTypes"; +import { AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL query operation: SearchProductTypes @@ -27,6 +27,7 @@ export interface SearchProductTypes_search_edges_node_productAttributes { __typename: "Attribute"; id: string; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; slug: string | null; name: string | null; valueRequired: boolean; diff --git a/src/searches/usePageTypeSearch.ts b/src/searches/usePageTypeSearch.ts index aef550016..30010a0bc 100644 --- a/src/searches/usePageTypeSearch.ts +++ b/src/searches/usePageTypeSearch.ts @@ -24,6 +24,7 @@ export const searchPageTypes = gql` attributes { id inputType + entityType slug name valueRequired diff --git a/src/searches/useProductTypeSearch.ts b/src/searches/useProductTypeSearch.ts index b25c8784b..bced1e221 100644 --- a/src/searches/useProductTypeSearch.ts +++ b/src/searches/useProductTypeSearch.ts @@ -27,6 +27,7 @@ export const searchProductTypes = gql` productAttributes { id inputType + entityType slug name valueRequired diff --git a/src/storybook/stories/pages/PageDetailsPage.tsx b/src/storybook/stories/pages/PageDetailsPage.tsx index 8e70f05ab..e68fdfd14 100644 --- a/src/storybook/stories/pages/PageDetailsPage.tsx +++ b/src/storybook/stories/pages/PageDetailsPage.tsx @@ -19,6 +19,7 @@ const props: PageDetailsPageProps = { onSubmit: () => undefined, page, referencePages: [], + referenceProducts: [], saveButtonBarState: "default" }; diff --git a/src/storybook/stories/products/ProductCreatePage.tsx b/src/storybook/stories/products/ProductCreatePage.tsx index ba6b9cc4b..6208fa4f6 100644 --- a/src/storybook/stories/products/ProductCreatePage.tsx +++ b/src/storybook/stories/products/ProductCreatePage.tsx @@ -46,6 +46,7 @@ storiesOf("Views / Products / Create product", module) taxTypes={taxTypes} weightUnit="kg" referencePages={[]} + referenceProducts={[]} onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} /> @@ -77,6 +78,7 @@ storiesOf("Views / Products / Create product", module) taxTypes={taxTypes} weightUnit="kg" referencePages={[]} + referenceProducts={[]} onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} /> @@ -125,6 +127,7 @@ storiesOf("Views / Products / Create product", module) taxTypes={taxTypes} weightUnit="kg" referencePages={[]} + referenceProducts={[]} onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} /> diff --git a/src/storybook/stories/products/ProductUpdatePage.tsx b/src/storybook/stories/products/ProductUpdatePage.tsx index da6134cb2..76e5d8421 100644 --- a/src/storybook/stories/products/ProductUpdatePage.tsx +++ b/src/storybook/stories/products/ProductUpdatePage.tsx @@ -60,6 +60,7 @@ const props: ProductUpdatePageProps = { placeholderImage, product, referencePages: [], + referenceProducts: [], saveButtonBarState: "default", selectedChannelId: "123", taxTypes, diff --git a/src/storybook/stories/products/ProductVariantCreatePage.tsx b/src/storybook/stories/products/ProductVariantCreatePage.tsx index e75232693..518f9722e 100644 --- a/src/storybook/stories/products/ProductVariantCreatePage.tsx +++ b/src/storybook/stories/products/ProductVariantCreatePage.tsx @@ -36,6 +36,7 @@ storiesOf("Views / Products / Create product variant", module) warehouses={warehouseList} onWarehouseConfigure={() => undefined} referencePages={[]} + referenceProducts={[]} onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} /> @@ -76,6 +77,7 @@ storiesOf("Views / Products / Create product variant", module) warehouses={warehouseList} onWarehouseConfigure={() => undefined} referencePages={[]} + referenceProducts={[]} onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} /> @@ -97,6 +99,7 @@ storiesOf("Views / Products / Create product variant", module) warehouses={warehouseList} onWarehouseConfigure={() => undefined} referencePages={[]} + referenceProducts={[]} onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} /> @@ -121,6 +124,7 @@ storiesOf("Views / Products / Create product variant", module) warehouses={warehouseList} onWarehouseConfigure={() => undefined} referencePages={[]} + referenceProducts={[]} onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} /> @@ -142,6 +146,7 @@ storiesOf("Views / Products / Create product variant", module) warehouses={[]} onWarehouseConfigure={() => undefined} referencePages={[]} + referenceProducts={[]} onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} /> diff --git a/src/storybook/stories/products/ProductVariantPage.tsx b/src/storybook/stories/products/ProductVariantPage.tsx index 0b0f50086..39ea8d700 100644 --- a/src/storybook/stories/products/ProductVariantPage.tsx +++ b/src/storybook/stories/products/ProductVariantPage.tsx @@ -34,6 +34,7 @@ storiesOf("Views / Products / Product variant details", module) warehouses={warehouseList} onWarehouseConfigure={() => undefined} referencePages={[]} + referenceProducts={[]} onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} /> @@ -59,6 +60,7 @@ storiesOf("Views / Products / Product variant details", module) warehouses={warehouseList} onWarehouseConfigure={() => undefined} referencePages={[]} + referenceProducts={[]} onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} /> @@ -83,6 +85,7 @@ storiesOf("Views / Products / Product variant details", module) warehouses={[]} onWarehouseConfigure={() => undefined} referencePages={[]} + referenceProducts={[]} onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} /> @@ -135,6 +138,7 @@ storiesOf("Views / Products / Product variant details", module) warehouses={warehouseList} onWarehouseConfigure={() => undefined} referencePages={[]} + referenceProducts={[]} onAssignReferencesClick={() => undefined} onCloseDialog={() => undefined} /> diff --git a/src/types/globalTypes.ts b/src/types/globalTypes.ts index ca344b83b..9e2f51f7d 100644 --- a/src/types/globalTypes.ts +++ b/src/types/globalTypes.ts @@ -72,6 +72,7 @@ export enum AppTypeEnum { export enum AttributeEntityTypeEnum { PAGE = "PAGE", + PRODUCT = "PRODUCT", } export enum AttributeErrorCode { @@ -1333,6 +1334,7 @@ export interface OrderDraftFilterInput { customer?: string | null; created?: DateRangeInput | null; search?: string | null; + channels?: (string | null)[] | null; } export interface OrderFilterInput { diff --git a/src/utils/maps.ts b/src/utils/maps.ts index 5fe3bad3e..0367e8599 100644 --- a/src/utils/maps.ts +++ b/src/utils/maps.ts @@ -2,6 +2,7 @@ import { MultiAutocompleteChoiceType } from "@saleor/components/MultiAutocomplet import { ShopInfo_shop_countries } from "@saleor/components/Shop/types/ShopInfo"; import { SingleAutocompleteChoiceType } from "@saleor/components/SingleAutocompleteSelectField"; import { MetadataItem } from "@saleor/fragments/types/MetadataItem"; +import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages"; import { Node } from "@saleor/types"; import { MetadataInput } from "@saleor/types/globalTypes"; @@ -14,6 +15,15 @@ export function mapCountriesToChoices( })); } +export function mapPagesToChoices( + pages: SearchPages_search_edges_node[] +): Array { + return pages.map(page => ({ + label: page.title, + value: page.id + })); +} + export function mapNodeToChoice( nodes: Array> ): Array { diff --git a/src/utils/metadata/types/UpdateMetadata.ts b/src/utils/metadata/types/UpdateMetadata.ts index cd763ddc6..40628865d 100644 --- a/src/utils/metadata/types/UpdateMetadata.ts +++ b/src/utils/metadata/types/UpdateMetadata.ts @@ -38,7 +38,7 @@ export interface UpdateMetadata_deleteMetadata_item_privateMetadata { } export interface UpdateMetadata_deleteMetadata_item { - __typename: "App" | "ShippingZone" | "ShippingMethod" | "Product" | "ProductType" | "Attribute" | "Category" | "ProductVariant" | "DigitalContent" | "Collection" | "Page" | "PageType" | "User" | "Checkout" | "Order" | "Fulfillment" | "Invoice"; + __typename: "App" | "ShippingZone" | "ShippingMethod" | "Product" | "ProductType" | "Attribute" | "Category" | "ProductVariant" | "DigitalContent" | "Collection" | "Page" | "PageType" | "MenuItem" | "Menu" | "User" | "Checkout" | "Order" | "Fulfillment" | "Invoice"; metadata: (UpdateMetadata_deleteMetadata_item_metadata | null)[]; privateMetadata: (UpdateMetadata_deleteMetadata_item_privateMetadata | null)[]; id: string; diff --git a/src/utils/metadata/types/UpdatePrivateMetadata.ts b/src/utils/metadata/types/UpdatePrivateMetadata.ts index db0b72fbe..173568570 100644 --- a/src/utils/metadata/types/UpdatePrivateMetadata.ts +++ b/src/utils/metadata/types/UpdatePrivateMetadata.ts @@ -38,7 +38,7 @@ export interface UpdatePrivateMetadata_deletePrivateMetadata_item_privateMetadat } export interface UpdatePrivateMetadata_deletePrivateMetadata_item { - __typename: "App" | "ShippingZone" | "ShippingMethod" | "Product" | "ProductType" | "Attribute" | "Category" | "ProductVariant" | "DigitalContent" | "Collection" | "Page" | "PageType" | "User" | "Checkout" | "Order" | "Fulfillment" | "Invoice"; + __typename: "App" | "ShippingZone" | "ShippingMethod" | "Product" | "ProductType" | "Attribute" | "Category" | "ProductVariant" | "DigitalContent" | "Collection" | "Page" | "PageType" | "MenuItem" | "Menu" | "User" | "Checkout" | "Order" | "Fulfillment" | "Invoice"; metadata: (UpdatePrivateMetadata_deletePrivateMetadata_item_metadata | null)[]; privateMetadata: (UpdatePrivateMetadata_deletePrivateMetadata_item_privateMetadata | null)[]; id: string;