diff --git a/CHANGELOG.md b/CHANGELOG.md index 153e357c9..0e80fa242 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ All notable, unreleased changes to this project will be documented in this file. ## [Unreleased] - Pass query params in `ORDER_DETAILS_MORE_ACTIONS` and `PRODUCT_DETAILS_MORE_ACTIONS` mounting points - #2100 by @witoszekdev +- Add product variant reference attribute - #2268 by @droniu ## 3.4 diff --git a/introspection.json b/introspection.json index 3adf5fbde..6ea8ee790 100644 --- a/introspection.json +++ b/introspection.json @@ -7065,6 +7065,12 @@ "description": null, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "PRODUCT_VARIANT", + "description": null, + "isDeprecated": false, + "deprecationReason": null } ], "possibleTypes": null @@ -9104,9 +9110,13 @@ "name": "id", "description": "ID of the selected attribute.", "type": { - "kind": "SCALAR", - "name": "ID", - "ofType": null + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } }, "defaultValue": null, "isDeprecated": false, @@ -10106,6 +10116,87 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "OBJECT", + "name": "CalculateTaxes", + "description": "Synchronous webhook for calculating checkout/order taxes.\n\nAdded in Saleor 3.7.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", + "fields": [ + { + "name": "issuedAt", + "description": "Time of the event.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "version", + "description": "Saleor version that triggered the event.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "issuingPrincipal", + "description": "The user or application that triggered the event.", + "args": [], + "type": { + "kind": "UNION", + "name": "IssuingPrincipal", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "recipient", + "description": "The application receiving the webhook.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "App", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "taxBase", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "TaxableObject", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Event", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, { "kind": "INPUT_OBJECT", "name": "CardInput", @@ -25088,6 +25179,11 @@ "name": "AttributeValueUpdated", "ofType": null }, + { + "kind": "OBJECT", + "name": "CalculateTaxes", + "ofType": null + }, { "kind": "OBJECT", "name": "CategoryCreated", @@ -56121,7 +56217,7 @@ }, { "name": "deliveryMethod", - "description": "The delivery method selected for this checkout.\n\nAdded in Saleor 3.1.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", + "description": "The delivery method selected for this order.\n\nAdded in Saleor 3.1.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.", "args": [], "type": { "kind": "UNION", @@ -94029,6 +94125,48 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "UNION", + "name": "TaxSourceLine", + "description": null, + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "CheckoutLine", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "OrderLine", + "ofType": null + } + ] + }, + { + "kind": "UNION", + "name": "TaxSourceObject", + "description": null, + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": [ + { + "kind": "OBJECT", + "name": "Checkout", + "ofType": null + }, + { + "kind": "OBJECT", + "name": "Order", + "ofType": null + } + ] + }, { "kind": "OBJECT", "name": "TaxType", @@ -94064,6 +94202,331 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "OBJECT", + "name": "TaxableObject", + "description": "Taxable object.", + "fields": [ + { + "name": "sourceObject", + "description": "The source object related to this tax object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "UNION", + "name": "TaxSourceObject", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "pricesEnteredWithTax", + "description": "Determines if prices contain entered tax..", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "currency", + "description": "The currency of the object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "shippingPrice", + "description": "The price of shipping method.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Money", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "address", + "description": "The address data.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "Address", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "discounts", + "description": "List of discounts.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "TaxableObjectDiscount", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "lines", + "description": "List of lines assigned to the object.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "TaxableObjectLine", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "channel", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Channel", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "TaxableObjectDiscount", + "description": "Taxable object discount.", + "fields": [ + { + "name": "name", + "description": "The name of the discount.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "amount", + "description": "The amount of the discount.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Money", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "TaxableObjectLine", + "description": null, + "fields": [ + { + "name": "sourceLine", + "description": "The source line related to this tax line.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "UNION", + "name": "TaxSourceLine", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "quantity", + "description": "Number of items.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "chargeTaxes", + "description": "Determines if taxes are being charged for the product.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "productName", + "description": "The product name.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "variantName", + "description": "The variant name.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "productSku", + "description": "The product sku.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unitPrice", + "description": "Price of the single item in the order line.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Money", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "totalPrice", + "description": "Price of the order line.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Money", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, { "kind": "OBJECT", "name": "TaxedMoney", diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json index eed47724e..069e84454 100644 --- a/locale/defaultMessages.json +++ b/locale/defaultMessages.json @@ -889,6 +889,10 @@ "context": "alert", "string": "Warehouse limit reached" }, + "5I7Lc2": { + "context": "dialog header", + "string": "Assign page" + }, "5JT4v2": { "context": "dialog header", "string": "Send Invoice" @@ -2265,10 +2269,6 @@ "GOdq5V": { "string": "Catalog" }, - "GUlwXU": { - "context": "dialog header", - "string": "Assign Attribute Value" - }, "GVM/fi": { "context": "order history message", "string": "Payment was authorized" @@ -3235,10 +3235,6 @@ "context": "navigator placeholder", "string": "Type Command" }, - "NsgWhZ": { - "context": "placeholder", - "string": "Search by value name, etc..." - }, "NtFVFS": { "context": "weight", "string": "{value} {unit}" @@ -3293,6 +3289,10 @@ "context": "WarehouseSettings disabled warehouse label", "string": "Disabled" }, + "OFW7nq": { + "context": "placeholder", + "string": "Search by page name, etc..." + }, "OGemtu": { "context": "payment status", "string": "Partially refunded" @@ -3757,10 +3757,6 @@ "RlfqSV": { "string": "No orders found" }, - "RoKOQJ": { - "context": "label", - "string": "Search Attribute Value" - }, "Rp/Okl": { "string": "Shipping Weight Unit" }, @@ -5284,10 +5280,6 @@ "context": "product", "string": "Digital" }, - "dTCDMn": { - "context": "dialog header", - "string": "Assign Product" - }, "dTCWqt": { "string": "You are about to end your products preorder. You have sold {variantGlobalSoldUnits} units of this variant. Sold units will be allocated at appropriate warehouses. Remember to add remaining threshold stock to warehouses." }, @@ -5790,6 +5782,10 @@ "context": "customer", "string": "Join Date" }, + "idr+JK": { + "context": "assign reference to a page, button", + "string": "Assign and save" + }, "ij7olm": { "context": "error message", "string": "This fulfillment cannot be cancelled" @@ -5820,6 +5816,10 @@ "ixjvkM": { "string": "We’ve created your default token. Make sure to copy your new personal access token now. You won’t be able to see it again." }, + "izJvcM": { + "context": "label", + "string": "Search pages" + }, "j/vV0n": { "context": "channel name", "string": "Channel Name" @@ -5918,6 +5918,10 @@ "juBV+h": { "string": "End Hour" }, + "juxCV3": { + "context": "dialog header", + "string": "Assign product" + }, "jvKNMP": { "string": "Discount Code" }, @@ -7262,6 +7266,9 @@ "umsU70": { "string": "Search Page Type" }, + "un+VWt": { + "string": "Search products" + }, "usSkzP": { "context": "navigator order mode description", "string": "Search Orders" @@ -7531,6 +7538,10 @@ "context": "WarehouseSettings private stock label", "string": "Private Stock" }, + "wsDF7X": { + "context": "product variant attribute entity type", + "string": "Product variants" + }, "wyvzh9": { "context": "dialog header", "string": "Publish Pages" @@ -7744,10 +7755,6 @@ "context": "voucher requirements, header", "string": "Minimum Requirements" }, - "ylobu9": { - "context": "assign reference to product, button", - "string": "Assign" - }, "ypW4Mi": { "context": "button refreshing page", "string": "Refresh page" diff --git a/schema.graphql b/schema.graphql index 171b31bbb..8f2d02178 100644 --- a/schema.graphql +++ b/schema.graphql @@ -1384,6 +1384,7 @@ type AttributeDeleted implements Event { enum AttributeEntityTypeEnum { PAGE PRODUCT + PRODUCT_VARIANT } type AttributeError { @@ -1823,7 +1824,7 @@ input AttributeValueFilterInput { input AttributeValueInput { """ID of the selected attribute.""" - id: ID + id: ID! """ The value or slug of an attribute to resolve. If the passed value is non-existent, it will be created. @@ -2052,6 +2053,28 @@ type BulkStockError { index: Int } +""" +Synchronous webhook for calculating checkout/order taxes. + +Added in Saleor 3.7. + +Note: this API is currently in Feature Preview and can be subject to changes at later point. +""" +type CalculateTaxes implements Event { + """Time of the event.""" + issuedAt: DateTime + + """Saleor version that triggered the event.""" + version: String + + """The user or application that triggered the event.""" + issuingPrincipal: IssuingPrincipal + + """The application receiving the webhook.""" + recipient: App + taxBase: TaxableObject! +} + input CardInput { """ Payment method nonce, a token returned by the appropriate provider's SDK. @@ -12540,7 +12563,7 @@ type Order implements Node & ObjectWithMetadata { isShippingRequired: Boolean! """ - The delivery method selected for this checkout. + The delivery method selected for this order. Added in Saleor 3.1. @@ -21189,6 +21212,10 @@ type Subscription { event: Event } +union TaxSourceLine = CheckoutLine | OrderLine + +union TaxSourceObject = Checkout | Order + """Representation of tax types fetched from tax gateway.""" type TaxType { """Description of the tax type.""" @@ -21198,6 +21225,66 @@ type TaxType { taxCode: String } +"""Taxable object.""" +type TaxableObject { + """The source object related to this tax object.""" + sourceObject: TaxSourceObject! + + """Determines if prices contain entered tax..""" + pricesEnteredWithTax: Boolean! + + """The currency of the object.""" + currency: String! + + """The price of shipping method.""" + shippingPrice: Money! + + """The address data.""" + address: Address + + """List of discounts.""" + discounts: [TaxableObjectDiscount!]! + + """List of lines assigned to the object.""" + lines: [TaxableObjectLine!]! + channel: Channel! +} + +"""Taxable object discount.""" +type TaxableObjectDiscount { + """The name of the discount.""" + name: String + + """The amount of the discount.""" + amount: Money! +} + +type TaxableObjectLine { + """The source line related to this tax line.""" + sourceLine: TaxSourceLine! + + """Number of items.""" + quantity: Int! + + """Determines if taxes are being charged for the product.""" + chargeTaxes: Boolean! + + """The product name.""" + productName: String! + + """The variant name.""" + variantName: String! + + """The product sku.""" + productSku: String + + """Price of the single item in the order line.""" + unitPrice: Money! + + """Price of the order line.""" + totalPrice: Money! +} + """ Represents a monetary value with taxes. In cases where taxes were not applied, net and gross values will be equal. """ diff --git a/src/attributes/components/AttributeDetails/AttributeDetails.tsx b/src/attributes/components/AttributeDetails/AttributeDetails.tsx index 5a99a5e76..12907531f 100644 --- a/src/attributes/components/AttributeDetails/AttributeDetails.tsx +++ b/src/attributes/components/AttributeDetails/AttributeDetails.tsx @@ -33,6 +33,11 @@ const entityTypeMessages = defineMessages({ defaultMessage: "Products", description: "product attribute entity type", }, + productVariant: { + id: "wsDF7X", + defaultMessage: "Product variants", + description: "product variant attribute entity type", + }, }); const useStyles = makeStyles( @@ -129,6 +134,10 @@ const AttributeDetails: React.FC = props => { label: intl.formatMessage(entityTypeMessages.product), value: AttributeEntityTypeEnum.PRODUCT, }, + { + label: intl.formatMessage(entityTypeMessages.productVariant), + value: AttributeEntityTypeEnum.PRODUCT_VARIANT, + }, ]; const formApiErrors = getFormErrors( diff --git a/src/attributes/utils/data.ts b/src/attributes/utils/data.ts index 02d1aef2e..afb6ca1ac 100644 --- a/src/attributes/utils/data.ts +++ b/src/attributes/utils/data.ts @@ -420,6 +420,27 @@ export const getProductReferenceAttributeDisplayData = ( }, }); +export const getProductVariantReferenceAttributeDisplayData = ( + attribute: AttributeInput, + referenceProducts: RelayToFlat, +) => ({ + ...attribute, + data: { + ...attribute.data, + references: + referenceProducts?.length > 0 && attribute.value?.length > 0 + ? mapNodeToChoice( + attribute.value.map(value => { + const reference = mapReferenceProductsToVariants( + referenceProducts, + ).find(reference => reference.id === value); + return { ...reference }; + }), + ) + : [], + }, +}); + export const getReferenceAttributeDisplayData = ( attribute: AttributeInput, referencePages: RelayToFlat, @@ -432,6 +453,13 @@ export const getReferenceAttributeDisplayData = ( attribute, referenceProducts, ); + } else if ( + attribute.data.entityType === AttributeEntityTypeEnum.PRODUCT_VARIANT + ) { + return getProductVariantReferenceAttributeDisplayData( + attribute, + referenceProducts, + ); } }; @@ -464,22 +492,18 @@ export const getSelectedReferencesFromAttribute = ( !attribute?.value?.some(selectedValue => selectedValue === value.id), ) || []; -export const getAttributeValuesFromReferences = ( +export const getReferenceAttributeEntityTypeFromAttribute = ( attributeId: string, attributes?: AttributeInput[], - referencePages?: RelayToFlat, - referenceProducts?: RelayToFlat, -) => { - const attribute = attributes?.find(attribute => attribute.id === attributeId); +): AttributeEntityTypeEnum | undefined => + attributes?.find(attribute => attribute.id === attributeId)?.data?.entityType; - if (attribute?.data?.entityType === AttributeEntityTypeEnum.PAGE) { - return mapPagesToChoices( - getSelectedReferencesFromAttribute(attribute, referencePages), - ); - } else if (attribute?.data?.entityType === AttributeEntityTypeEnum.PRODUCT) { - return mapNodeToChoice( - getSelectedReferencesFromAttribute(attribute, referenceProducts), - ); - } - return []; -}; +export const mapReferenceProductsToVariants = ( + referenceProducts: RelayToFlat, +) => + referenceProducts.flatMap(product => + product.variants.map(variant => ({ + ...variant, + name: product.name + " " + variant.name, + })), + ); diff --git a/src/attributes/utils/handlers.ts b/src/attributes/utils/handlers.ts index 5307db7b1..9cd676c87 100644 --- a/src/attributes/utils/handlers.ts +++ b/src/attributes/utils/handlers.ts @@ -88,7 +88,10 @@ export function createFetchReferencesHandler( ) { fetchReferencePages(value); } else if ( - attribute.data.entityType === AttributeEntityTypeEnum.PRODUCT && + [ + AttributeEntityTypeEnum.PRODUCT, + AttributeEntityTypeEnum.PRODUCT_VARIANT, + ].includes(attribute.data.entityType) && fetchReferenceProducts ) { fetchReferenceProducts(value); @@ -112,7 +115,12 @@ export function createFetchMoreReferencesHandler( if (attribute.data.entityType === AttributeEntityTypeEnum.PAGE) { return fetchMoreReferencePages; - } else if (attribute.data.entityType === AttributeEntityTypeEnum.PRODUCT) { + } else if ( + [ + AttributeEntityTypeEnum.PRODUCT, + AttributeEntityTypeEnum.PRODUCT_VARIANT, + ].includes(attribute.data.entityType) + ) { return fetchMoreReferenceProducts; } } diff --git a/src/components/AssignAttributeValueDialog/AssignAttributeValueDialog.tsx b/src/components/AssignAttributeValueDialog/AssignAttributeValueDialog.tsx index cc6de7cc2..73df76090 100644 --- a/src/components/AssignAttributeValueDialog/AssignAttributeValueDialog.tsx +++ b/src/components/AssignAttributeValueDialog/AssignAttributeValueDialog.tsx @@ -1,65 +1,69 @@ -import { AttributeReference } from "@saleor/attributes/utils/data"; +import { AttributeEntityTypeEnum, SearchPagesQuery } from "@saleor/graphql"; +import { RelayToFlat } from "@saleor/types"; import React from "react"; import { defineMessages, useIntl } from "react-intl"; -import AssignContainerDialog, { - AssignContainerDialogProps, -} from "../AssignContainerDialog"; +import AssignContainerDialog from "../AssignContainerDialog"; +import AssignProductDialog, { + AssignProductDialogProps, +} from "../AssignProductDialog"; +import AssignVariantDialog from "../AssignVariantDialog"; -const messages = defineMessages({ +const pagesMessages = defineMessages({ confirmBtn: { - id: "ylobu9", - defaultMessage: "Assign", - description: "assign reference to product, button", + id: "idr+JK", + defaultMessage: "Assign and save", + description: "assign reference to a page, button", }, header: { - id: "GUlwXU", - defaultMessage: "Assign Attribute Value", + id: "5I7Lc2", + defaultMessage: "Assign page", description: "dialog header", }, searchLabel: { - id: "RoKOQJ", - defaultMessage: "Search Attribute Value", + id: "izJvcM", + defaultMessage: "Search pages", description: "label", }, searchPlaceholder: { - id: "NsgWhZ", - defaultMessage: "Search by value name, etc...", + id: "OFW7nq", + defaultMessage: "Search by page name, etc...", description: "placeholder", }, }); -interface AssignAttributeValueDialogProps - extends Omit< - AssignContainerDialogProps, - "containers" | "title" | "search" | "confirmButtonState" | "labels" - > { - attributeValues: AttributeReference[]; -} +type AssignAttributeValueDialogProps = AssignProductDialogProps & { + entityType: AttributeEntityTypeEnum; + pages: RelayToFlat; +}; const AssignAttributeValueDialog: React.FC = ({ - attributeValues, + entityType, + pages, + products, ...rest }) => { const intl = useIntl(); - return ( - ({ - id: value.value, - name: value.label, - }))} - labels={{ - confirmBtn: intl.formatMessage(messages.confirmBtn), - label: intl.formatMessage(messages.searchLabel), - placeholder: intl.formatMessage(messages.searchPlaceholder), - title: intl.formatMessage(messages.header), - }} - confirmButtonState="default" - {...rest} - /> - ); + switch (entityType) { + case AttributeEntityTypeEnum.PAGE: + return ( + ({ id: page.id, name: page.title }))} + labels={{ + confirmBtn: intl.formatMessage(pagesMessages.confirmBtn), + label: intl.formatMessage(pagesMessages.searchLabel), + placeholder: intl.formatMessage(pagesMessages.searchPlaceholder), + title: intl.formatMessage(pagesMessages.header), + }} + {...rest} + /> + ); + case AttributeEntityTypeEnum.PRODUCT: + return ; + case AttributeEntityTypeEnum.PRODUCT_VARIANT: + return ; + } }; - AssignAttributeValueDialog.displayName = "AssignAttributeValueDialog"; export default AssignAttributeValueDialog; diff --git a/src/components/AssignProductDialog/messages.ts b/src/components/AssignProductDialog/messages.ts index c51f0502a..d7a1f9ea8 100644 --- a/src/components/AssignProductDialog/messages.ts +++ b/src/components/AssignProductDialog/messages.ts @@ -2,8 +2,8 @@ import { defineMessages } from "react-intl"; export const messages = defineMessages({ assignVariantDialogHeader: { - id: "dTCDMn", - defaultMessage: "Assign Product", + id: "juxCV3", + defaultMessage: "Assign product", description: "dialog header", }, assignProductDialogButton: { @@ -12,8 +12,8 @@ export const messages = defineMessages({ description: "button", }, assignProductDialogContent: { - id: "/TF6BZ", - defaultMessage: "Search Products", + id: "un+VWt", + defaultMessage: "Search products", }, assignProductDialogSearch: { id: "SHm7ee", diff --git a/src/components/AssignVariantDialog/AssignVariantDialog.tsx b/src/components/AssignVariantDialog/AssignVariantDialog.tsx index 451849eee..1ad54eb52 100644 --- a/src/components/AssignVariantDialog/AssignVariantDialog.tsx +++ b/src/components/AssignVariantDialog/AssignVariantDialog.tsx @@ -45,7 +45,7 @@ export interface AssignVariantDialogProps extends FetchMoreProps, DialogProps { products: RelayToFlat; loading: boolean; onFetch: (value: string) => void; - onSubmit: (data: SearchVariant[]) => void; + onSubmit: (data: string[]) => void; } const scrollableTargetId = "assignVariantScrollableDialog"; @@ -84,7 +84,7 @@ const AssignVariantDialog: React.FC = props => { ) : []; - const handleSubmit = () => onSubmit(variants); + const handleSubmit = () => onSubmit(variants.map(variant => variant.id)); return ( = ({ id, params }) => { ...paginationState, id, input: { - variants: variants.map(variant => variant.id), + variants, }, }, }) diff --git a/src/graphql/fragmentTypes.generated.ts b/src/graphql/fragmentTypes.generated.ts index d8fd244f0..aeb4cb5e5 100644 --- a/src/graphql/fragmentTypes.generated.ts +++ b/src/graphql/fragmentTypes.generated.ts @@ -25,6 +25,7 @@ "AttributeValueCreated", "AttributeValueDeleted", "AttributeValueUpdated", + "CalculateTaxes", "CategoryCreated", "CategoryDeleted", "CategoryUpdated", @@ -237,6 +238,14 @@ "Voucher", "Warehouse" ], + "TaxSourceLine": [ + "CheckoutLine", + "OrderLine" + ], + "TaxSourceObject": [ + "Checkout", + "Order" + ], "TranslatableItem": [ "ProductTranslatableContent", "CollectionTranslatableContent", diff --git a/src/graphql/typePolicies.generated.ts b/src/graphql/typePolicies.generated.ts index 44c05bf4e..e4a039a4e 100644 --- a/src/graphql/typePolicies.generated.ts +++ b/src/graphql/typePolicies.generated.ts @@ -607,6 +607,14 @@ export type BulkStockErrorFieldPolicy = { values?: FieldPolicy | FieldReadFunction, index?: FieldPolicy | FieldReadFunction }; +export type CalculateTaxesKeySpecifier = ('issuedAt' | 'version' | 'issuingPrincipal' | 'recipient' | 'taxBase' | CalculateTaxesKeySpecifier)[]; +export type CalculateTaxesFieldPolicy = { + issuedAt?: FieldPolicy | FieldReadFunction, + version?: FieldPolicy | FieldReadFunction, + issuingPrincipal?: FieldPolicy | FieldReadFunction, + recipient?: FieldPolicy | FieldReadFunction, + taxBase?: FieldPolicy | FieldReadFunction +}; export type CategoryKeySpecifier = ('id' | 'privateMetadata' | 'privateMetafield' | 'privateMetafields' | 'metadata' | 'metafield' | 'metafields' | 'seoTitle' | 'seoDescription' | 'name' | 'description' | 'slug' | 'parent' | 'level' | 'descriptionJson' | 'ancestors' | 'products' | 'children' | 'backgroundImage' | 'translation' | CategoryKeySpecifier)[]; export type CategoryFieldPolicy = { id?: FieldPolicy | FieldReadFunction, @@ -4634,6 +4642,33 @@ export type TaxTypeFieldPolicy = { description?: FieldPolicy | FieldReadFunction, taxCode?: FieldPolicy | FieldReadFunction }; +export type TaxableObjectKeySpecifier = ('sourceObject' | 'pricesEnteredWithTax' | 'currency' | 'shippingPrice' | 'address' | 'discounts' | 'lines' | 'channel' | TaxableObjectKeySpecifier)[]; +export type TaxableObjectFieldPolicy = { + sourceObject?: FieldPolicy | FieldReadFunction, + pricesEnteredWithTax?: FieldPolicy | FieldReadFunction, + currency?: FieldPolicy | FieldReadFunction, + shippingPrice?: FieldPolicy | FieldReadFunction, + address?: FieldPolicy | FieldReadFunction, + discounts?: FieldPolicy | FieldReadFunction, + lines?: FieldPolicy | FieldReadFunction, + channel?: FieldPolicy | FieldReadFunction +}; +export type TaxableObjectDiscountKeySpecifier = ('name' | 'amount' | TaxableObjectDiscountKeySpecifier)[]; +export type TaxableObjectDiscountFieldPolicy = { + name?: FieldPolicy | FieldReadFunction, + amount?: FieldPolicy | FieldReadFunction +}; +export type TaxableObjectLineKeySpecifier = ('sourceLine' | 'quantity' | 'chargeTaxes' | 'productName' | 'variantName' | 'productSku' | 'unitPrice' | 'totalPrice' | TaxableObjectLineKeySpecifier)[]; +export type TaxableObjectLineFieldPolicy = { + sourceLine?: FieldPolicy | FieldReadFunction, + quantity?: FieldPolicy | FieldReadFunction, + chargeTaxes?: FieldPolicy | FieldReadFunction, + productName?: FieldPolicy | FieldReadFunction, + variantName?: FieldPolicy | FieldReadFunction, + productSku?: FieldPolicy | FieldReadFunction, + unitPrice?: FieldPolicy | FieldReadFunction, + totalPrice?: FieldPolicy | FieldReadFunction +}; export type TaxedMoneyKeySpecifier = ('currency' | 'gross' | 'net' | 'tax' | TaxedMoneyKeySpecifier)[]; export type TaxedMoneyFieldPolicy = { currency?: FieldPolicy | FieldReadFunction, @@ -5498,6 +5533,10 @@ export type StrictTypedTypePolicies = { keyFields?: false | BulkStockErrorKeySpecifier | (() => undefined | BulkStockErrorKeySpecifier), fields?: BulkStockErrorFieldPolicy, }, + CalculateTaxes?: Omit & { + keyFields?: false | CalculateTaxesKeySpecifier | (() => undefined | CalculateTaxesKeySpecifier), + fields?: CalculateTaxesFieldPolicy, + }, Category?: Omit & { keyFields?: false | CategoryKeySpecifier | (() => undefined | CategoryKeySpecifier), fields?: CategoryFieldPolicy, @@ -7398,6 +7437,18 @@ export type StrictTypedTypePolicies = { keyFields?: false | TaxTypeKeySpecifier | (() => undefined | TaxTypeKeySpecifier), fields?: TaxTypeFieldPolicy, }, + TaxableObject?: Omit & { + keyFields?: false | TaxableObjectKeySpecifier | (() => undefined | TaxableObjectKeySpecifier), + fields?: TaxableObjectFieldPolicy, + }, + TaxableObjectDiscount?: Omit & { + keyFields?: false | TaxableObjectDiscountKeySpecifier | (() => undefined | TaxableObjectDiscountKeySpecifier), + fields?: TaxableObjectDiscountFieldPolicy, + }, + TaxableObjectLine?: Omit & { + keyFields?: false | TaxableObjectLineKeySpecifier | (() => undefined | TaxableObjectLineKeySpecifier), + fields?: TaxableObjectLineFieldPolicy, + }, TaxedMoney?: Omit & { keyFields?: false | TaxedMoneyKeySpecifier | (() => undefined | TaxedMoneyKeySpecifier), fields?: TaxedMoneyFieldPolicy, diff --git a/src/graphql/types.generated.ts b/src/graphql/types.generated.ts index 676dd2834..735c7ce8b 100644 --- a/src/graphql/types.generated.ts +++ b/src/graphql/types.generated.ts @@ -334,7 +334,8 @@ export type AttributeCreateInput = { /** An enumeration. */ export enum AttributeEntityTypeEnum { PAGE = 'PAGE', - PRODUCT = 'PRODUCT' + PRODUCT = 'PRODUCT', + PRODUCT_VARIANT = 'PRODUCT_VARIANT' } /** An enumeration. */ @@ -485,7 +486,7 @@ export type AttributeValueFilterInput = { export type AttributeValueInput = { /** ID of the selected attribute. */ - id?: InputMaybe; + id: Scalars['ID']; /** The value or slug of an attribute to resolve. If the passed value is non-existent, it will be created. */ values?: InputMaybe>; /** URL of the file attribute. Every time, a new value is created. */ diff --git a/src/pages/components/PageDetailsPage/PageDetailsPage.tsx b/src/pages/components/PageDetailsPage/PageDetailsPage.tsx index 99849380c..adf987adb 100644 --- a/src/pages/components/PageDetailsPage/PageDetailsPage.tsx +++ b/src/pages/components/PageDetailsPage/PageDetailsPage.tsx @@ -1,5 +1,5 @@ import { - getAttributeValuesFromReferences, + getReferenceAttributeEntityTypeFromAttribute, mergeAttributeValues, } from "@saleor/attributes/utils/data"; import AssignAttributeValueDialog from "@saleor/components/AssignAttributeValueDialog"; @@ -264,12 +264,13 @@ const PageDetailsPage: React.FC = ({ /> {canOpenAssignReferencesAttributeDialog && ( = ({ /> {canOpenAssignReferencesAttributeDialog && ( = ({ /> {canOpenAssignReferencesAttributeDialog && ( = ({ /> {canOpenAssignReferencesAttributeDialog && ( = ({ /> {canOpenAssignReferencesAttributeDialog && (