diff --git a/CHANGELOG.md b/CHANGELOG.md index 71ee9ce99..e55a790b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ All notable, unreleased changes to this project will be documented in this file. - Create channel filters in product, sales and voucher lists - #1187 by @jwm0 - Add generic filter validation - #1187 by @jwm0 - Fix duplicated labels in column picker - #1197 by @orzechdev +- Fix forbidden null sending as attribute value - #1201 by @orzechdev # 2.11.1 diff --git a/schema.graphql b/schema.graphql index d9ec858c8..3b5359811 100644 --- a/schema.graphql +++ b/schema.graphql @@ -558,7 +558,7 @@ type AttributeTranslatableContent implements Node { id: ID! name: String! translation(languageCode: LanguageCodeEnum!): AttributeTranslation - attribute: Attribute + attribute: Attribute @deprecated(reason: "Will be removed in Saleor 4.0. Get model fields from the root level.") } type AttributeTranslate { @@ -655,7 +655,7 @@ input AttributeValueFilterInput { input AttributeValueInput { id: ID - values: [String] + values: [String!] file: String contentType: String references: [ID!] @@ -667,7 +667,7 @@ type AttributeValueTranslatableContent implements Node { id: ID! name: String! translation(languageCode: LanguageCodeEnum!): AttributeValueTranslation - attributeValue: AttributeValue + attributeValue: AttributeValue @deprecated(reason: "Will be removed in Saleor 4.0. Get model fields from the root level.") } type AttributeValueTranslate { @@ -697,7 +697,7 @@ type AttributeValueUpdate { input BulkAttributeValueInput { id: ID - values: [String]! + values: [String!]! } type BulkProductError { @@ -808,7 +808,7 @@ type CategoryTranslatableContent implements Node { description: JSONString descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.") translation(languageCode: LanguageCodeEnum!): CategoryTranslation - category: Category + category: Category @deprecated(reason: "Will be removed in Saleor 4.0. Get model fields from the root level.") } type CategoryTranslate { @@ -1280,7 +1280,7 @@ type CollectionTranslatableContent implements Node { description: JSONString descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.") translation(languageCode: LanguageCodeEnum!): CollectionTranslation - collection: Collection + collection: Collection @deprecated(reason: "Will be removed in Saleor 4.0. Get model fields from the root level.") } type CollectionTranslate { @@ -2616,7 +2616,7 @@ type MenuItemTranslatableContent implements Node { id: ID! name: String! translation(languageCode: LanguageCodeEnum!): MenuItemTranslation - menuItem: MenuItem + menuItem: MenuItem @deprecated(reason: "Will be removed in Saleor 4.0. Get model fields from the root level.") } type MenuItemTranslate { @@ -2873,21 +2873,21 @@ type Mutation { voucherChannelListingUpdate(id: ID!, input: VoucherChannelListingInput!): VoucherChannelListingUpdate exportProducts(input: ExportProductsInput!): ExportProducts fileUpload(file: Upload!): FileUpload - checkoutAddPromoCode(checkoutId: ID!, promoCode: String!): CheckoutAddPromoCode - checkoutBillingAddressUpdate(billingAddress: AddressInput!, checkoutId: ID!): CheckoutBillingAddressUpdate - checkoutComplete(checkoutId: ID!, paymentData: JSONString, redirectUrl: String, storeSource: Boolean = false): CheckoutComplete + checkoutAddPromoCode(checkoutId: ID, promoCode: String!, token: UUID): CheckoutAddPromoCode + checkoutBillingAddressUpdate(billingAddress: AddressInput!, checkoutId: ID, token: UUID): CheckoutBillingAddressUpdate + checkoutComplete(checkoutId: ID, paymentData: JSONString, redirectUrl: String, storeSource: Boolean = false, token: UUID): CheckoutComplete checkoutCreate(input: CheckoutCreateInput!): CheckoutCreate - checkoutCustomerAttach(checkoutId: ID!): CheckoutCustomerAttach - checkoutCustomerDetach(checkoutId: ID!): CheckoutCustomerDetach - checkoutEmailUpdate(checkoutId: ID, email: String!): CheckoutEmailUpdate - checkoutLineDelete(checkoutId: ID!, lineId: ID): CheckoutLineDelete - checkoutLinesAdd(checkoutId: ID!, lines: [CheckoutLineInput]!): CheckoutLinesAdd - checkoutLinesUpdate(checkoutId: ID!, lines: [CheckoutLineInput]!): CheckoutLinesUpdate - checkoutRemovePromoCode(checkoutId: ID!, promoCode: String!): CheckoutRemovePromoCode - checkoutPaymentCreate(checkoutId: ID!, input: PaymentInput!): CheckoutPaymentCreate - checkoutShippingAddressUpdate(checkoutId: ID!, shippingAddress: AddressInput!): CheckoutShippingAddressUpdate - checkoutShippingMethodUpdate(checkoutId: ID, shippingMethodId: ID!): CheckoutShippingMethodUpdate - checkoutLanguageCodeUpdate(checkoutId: ID!, languageCode: LanguageCodeEnum!): CheckoutLanguageCodeUpdate + checkoutCustomerAttach(checkoutId: ID, token: UUID): CheckoutCustomerAttach + checkoutCustomerDetach(checkoutId: ID, token: UUID): CheckoutCustomerDetach + checkoutEmailUpdate(checkoutId: ID, email: String!, token: UUID): CheckoutEmailUpdate + checkoutLineDelete(checkoutId: ID, lineId: ID, token: UUID): CheckoutLineDelete + checkoutLinesAdd(checkoutId: ID, lines: [CheckoutLineInput]!, token: UUID): CheckoutLinesAdd + checkoutLinesUpdate(checkoutId: ID, lines: [CheckoutLineInput]!, token: UUID): CheckoutLinesUpdate + checkoutRemovePromoCode(checkoutId: ID, promoCode: String!, token: UUID): CheckoutRemovePromoCode + checkoutPaymentCreate(checkoutId: ID, input: PaymentInput!, token: UUID): CheckoutPaymentCreate + checkoutShippingAddressUpdate(checkoutId: ID, shippingAddress: AddressInput!, token: UUID): CheckoutShippingAddressUpdate + checkoutShippingMethodUpdate(checkoutId: ID, shippingMethodId: ID!, token: UUID): CheckoutShippingMethodUpdate + checkoutLanguageCodeUpdate(checkoutId: ID, languageCode: LanguageCodeEnum!, token: UUID): CheckoutLanguageCodeUpdate channelCreate(input: ChannelCreateInput!): ChannelCreate channelUpdate(id: ID!, input: ChannelUpdateInput!): ChannelUpdate channelDelete(id: ID!, input: ChannelDeleteInput): ChannelDelete @@ -3674,7 +3674,7 @@ type PageTranslatableContent implements Node { content: JSONString contentJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `content` field instead.") translation(languageCode: LanguageCodeEnum!): PageTranslation - page: Page + page: Page @deprecated(reason: "Will be removed in Saleor 4.0. Get model fields from the root level.") } type PageTranslate { @@ -4419,7 +4419,7 @@ type ProductTranslatableContent implements Node { description: JSONString descriptionJson: JSONString @deprecated(reason: "Will be removed in Saleor 4.0. Use the `description` field instead.") translation(languageCode: LanguageCodeEnum!): ProductTranslation - product: Product + product: Product @deprecated(reason: "Will be removed in Saleor 4.0. Get model fields from the root level.") } type ProductTranslate { @@ -4574,7 +4574,7 @@ type ProductVariantBulkCreate { } input ProductVariantBulkCreateInput { - attributes: [BulkAttributeValueInput]! + attributes: [BulkAttributeValueInput!]! sku: String! trackInventory: Boolean weight: WeightScalar @@ -4626,7 +4626,7 @@ type ProductVariantCreate { } input ProductVariantCreateInput { - attributes: [AttributeValueInput]! + attributes: [AttributeValueInput!]! sku: String trackInventory: Boolean weight: WeightScalar @@ -4647,7 +4647,7 @@ input ProductVariantFilterInput { } input ProductVariantInput { - attributes: [AttributeValueInput] + attributes: [AttributeValueInput!] sku: String trackInventory: Boolean weight: WeightScalar @@ -4693,7 +4693,7 @@ type ProductVariantTranslatableContent implements Node { id: ID! name: String! translation(languageCode: LanguageCodeEnum!): ProductVariantTranslation - productVariant: ProductVariant + productVariant: ProductVariant @deprecated(reason: "Will be removed in Saleor 4.0. Get model fields from the root level.") } type ProductVariantTranslate { @@ -4944,7 +4944,7 @@ type SaleTranslatableContent implements Node { id: ID! name: String! translation(languageCode: LanguageCodeEnum!): SaleTranslation - sale: Sale + sale: Sale @deprecated(reason: "Will be removed in Saleor 4.0. Get model fields from the root level.") } type SaleTranslate { @@ -5066,7 +5066,7 @@ type ShippingMethodTranslatableContent implements Node { name: String! description: JSONString translation(languageCode: LanguageCodeEnum!): ShippingMethodTranslation - shippingMethod: ShippingMethod + shippingMethod: ShippingMethod @deprecated(reason: "Will be removed in Saleor 4.0. Get model fields from the root level.") } type ShippingMethodTranslation implements Node { @@ -5890,7 +5890,7 @@ type VoucherTranslatableContent implements Node { id: ID! name: String translation(languageCode: LanguageCodeEnum!): VoucherTranslation - voucher: Voucher + voucher: Voucher @deprecated(reason: "Will be removed in Saleor 4.0. Get model fields from the root level.") } type VoucherTranslate { @@ -6169,4 +6169,4 @@ union _Entity = Address | User | Group | App | ProductVariant | Product | Produc type _Service { sdl: String -} \ No newline at end of file +} diff --git a/src/attributes/utils/handlers.ts b/src/attributes/utils/handlers.ts index b6800c05f..ff16730a6 100644 --- a/src/attributes/utils/handlers.ts +++ b/src/attributes/utils/handlers.ts @@ -221,7 +221,9 @@ function getBooleanInput(attribute: AttributeInput) { function getDefaultInput(attribute: AttributeInput) { return { id: attribute.id, - values: attribute.value[0] === "" ? [] : attribute.value + values: ["", undefined, null].includes(attribute.value[0]) + ? [] + : attribute.value }; } diff --git a/src/products/mutations.ts b/src/products/mutations.ts index ba3683944..5a48fe5be 100644 --- a/src/products/mutations.ts +++ b/src/products/mutations.ts @@ -330,7 +330,7 @@ export const variantUpdateMutation = gql` $addStocks: [StockInput!]! $removeStocks: [ID!]! $id: ID! - $attributes: [AttributeValueInput] + $attributes: [AttributeValueInput!] $sku: String $trackInventory: Boolean! $stocks: [StockInput!]! diff --git a/src/products/types/VariantUpdate.ts b/src/products/types/VariantUpdate.ts index fa6f8421b..4af9bfa82 100644 --- a/src/products/types/VariantUpdate.ts +++ b/src/products/types/VariantUpdate.ts @@ -755,7 +755,7 @@ export interface VariantUpdateVariables { addStocks: StockInput[]; removeStocks: string[]; id: string; - attributes?: (AttributeValueInput | null)[] | null; + attributes?: AttributeValueInput[] | null; sku?: string | null; trackInventory: boolean; stocks: StockInput[]; diff --git a/src/storybook/__snapshots__/Stories.test.ts.snap b/src/storybook/__snapshots__/Stories.test.ts.snap index 056110a80..ac33acbd1 100644 --- a/src/storybook/__snapshots__/Stories.test.ts.snap +++ b/src/storybook/__snapshots__/Stories.test.ts.snap @@ -10268,31 +10268,31 @@ exports[`Storyshots Generics / Multiple select with autocomplete can load more 1 Antigua and Barbuda -