Merge pull request #452 from mirumee/next/use-form-error-codes
Use translated error messages based on error codes
This commit is contained in:
commit
680dd8baa2
310 changed files with 8039 additions and 2247 deletions
|
@ -292,6 +292,12 @@
|
||||||
"context": "attributes section name",
|
"context": "attributes section name",
|
||||||
"string": "Attributes"
|
"string": "Attributes"
|
||||||
},
|
},
|
||||||
|
"src_dot_attributes_dot_attributeSlugUnique": {
|
||||||
|
"string": "Attribute with this slug already exists"
|
||||||
|
},
|
||||||
|
"src_dot_attributes_dot_attributeValueAlreadyExists": {
|
||||||
|
"string": "This value already exists within this attribute"
|
||||||
|
},
|
||||||
"src_dot_attributes_dot_components_dot_AttributeBulkDeleteDialog_dot_1184518529": {
|
"src_dot_attributes_dot_components_dot_AttributeBulkDeleteDialog_dot_1184518529": {
|
||||||
"context": "dialog content",
|
"context": "dialog content",
|
||||||
"string": "{counter,plural,one{Are you sure you want to delete this attribute?} other{Are you sure you want to delete {displayQuantity} attributes?}}"
|
"string": "{counter,plural,one{Are you sure you want to delete this attribute?} other{Are you sure you want to delete {displayQuantity} attributes?}}"
|
||||||
|
@ -477,10 +483,6 @@
|
||||||
"src_dot_attributes_dot_views_dot_AttributeCreate_dot_11941964": {
|
"src_dot_attributes_dot_views_dot_AttributeCreate_dot_11941964": {
|
||||||
"string": "Successfully created attribute"
|
"string": "Successfully created attribute"
|
||||||
},
|
},
|
||||||
"src_dot_attributes_dot_views_dot_AttributeCreate_dot_354316953": {
|
|
||||||
"context": "attribute value edit error",
|
|
||||||
"string": "A value named {name} already exists"
|
|
||||||
},
|
|
||||||
"src_dot_attributes_dot_views_dot_AttributeDetails_dot_423042761": {
|
"src_dot_attributes_dot_views_dot_AttributeDetails_dot_423042761": {
|
||||||
"context": "attribute value deleted",
|
"context": "attribute value deleted",
|
||||||
"string": "Value deleted"
|
"string": "Value deleted"
|
||||||
|
@ -836,9 +838,6 @@
|
||||||
"src_dot_collections_dot_views_dot_1152429477": {
|
"src_dot_collections_dot_views_dot_1152429477": {
|
||||||
"string": "Deleted collection"
|
"string": "Deleted collection"
|
||||||
},
|
},
|
||||||
"src_dot_collections_dot_views_dot_1597339737": {
|
|
||||||
"string": "Created collection"
|
|
||||||
},
|
|
||||||
"src_dot_collections_dot_views_dot_2001540731": {
|
"src_dot_collections_dot_views_dot_2001540731": {
|
||||||
"string": "Added product to collection"
|
"string": "Added product to collection"
|
||||||
},
|
},
|
||||||
|
@ -2722,9 +2721,6 @@
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_1056718390": {
|
"src_dot_orders_dot_views_dot_OrderDetails_dot_1056718390": {
|
||||||
"string": "Payment successfully captured"
|
"string": "Payment successfully captured"
|
||||||
},
|
},
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_1096896329": {
|
|
||||||
"string": "Could not fulfill items"
|
|
||||||
},
|
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_1435191432": {
|
"src_dot_orders_dot_views_dot_OrderDetails_dot_1435191432": {
|
||||||
"string": "Draft order successfully finalized"
|
"string": "Draft order successfully finalized"
|
||||||
},
|
},
|
||||||
|
@ -2734,30 +2730,15 @@
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_1475565380": {
|
"src_dot_orders_dot_views_dot_OrderDetails_dot_1475565380": {
|
||||||
"string": "Fulfillment successfully updated"
|
"string": "Fulfillment successfully updated"
|
||||||
},
|
},
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_149745214": {
|
|
||||||
"string": "Could not finalize draft"
|
|
||||||
},
|
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_1632861387": {
|
"src_dot_orders_dot_views_dot_OrderDetails_dot_1632861387": {
|
||||||
"string": "Order line updated"
|
"string": "Order line updated"
|
||||||
},
|
},
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_1636370257": {
|
"src_dot_orders_dot_views_dot_OrderDetails_dot_1636370257": {
|
||||||
"string": "Order marked as paid"
|
"string": "Order marked as paid"
|
||||||
},
|
},
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_1708579411": {
|
|
||||||
"string": "Could not update shipping method"
|
|
||||||
},
|
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_1852833563": {
|
|
||||||
"string": "Could not mark order as paid"
|
|
||||||
},
|
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_1999598492": {
|
"src_dot_orders_dot_views_dot_OrderDetails_dot_1999598492": {
|
||||||
"string": "Order line added"
|
"string": "Order line added"
|
||||||
},
|
},
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_2205960666": {
|
|
||||||
"string": "Could not delete order line"
|
|
||||||
},
|
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_2714957902": {
|
|
||||||
"string": "Could not add note"
|
|
||||||
},
|
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_2808777264": {
|
"src_dot_orders_dot_views_dot_OrderDetails_dot_2808777264": {
|
||||||
"string": "Order successfully cancelled"
|
"string": "Order successfully cancelled"
|
||||||
},
|
},
|
||||||
|
@ -2770,27 +2751,12 @@
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_3367579693": {
|
"src_dot_orders_dot_views_dot_OrderDetails_dot_3367579693": {
|
||||||
"string": "Order successfully updated"
|
"string": "Order successfully updated"
|
||||||
},
|
},
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_3991286734": {
|
|
||||||
"context": "notification",
|
|
||||||
"string": "Payment not refunded: {errorMessage}"
|
|
||||||
},
|
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_4199953867": {
|
|
||||||
"string": "Could not cancel fulfillment"
|
|
||||||
},
|
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_4245651107": {
|
"src_dot_orders_dot_views_dot_OrderDetails_dot_4245651107": {
|
||||||
"string": "Items successfully fulfilled"
|
"string": "Items successfully fulfilled"
|
||||||
},
|
},
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_487150696": {
|
"src_dot_orders_dot_views_dot_OrderDetails_dot_580490159": {
|
||||||
"string": "Could not update order line"
|
"context": "window title",
|
||||||
},
|
"string": "Order #{orderNumber}"
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_553600482": {
|
|
||||||
"string": "Could not update fulfillment"
|
|
||||||
},
|
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_557535634": {
|
|
||||||
"string": "Payment not captured: {errorMessage}"
|
|
||||||
},
|
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_562214451": {
|
|
||||||
"string": "Could not create order line"
|
|
||||||
},
|
},
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_617145655": {
|
"src_dot_orders_dot_views_dot_OrderDetails_dot_617145655": {
|
||||||
"string": "Shipping method successfully updated"
|
"string": "Shipping method successfully updated"
|
||||||
|
@ -2798,6 +2764,10 @@
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_667274681": {
|
"src_dot_orders_dot_views_dot_OrderDetails_dot_667274681": {
|
||||||
"string": "Payment successfully refunded"
|
"string": "Payment successfully refunded"
|
||||||
},
|
},
|
||||||
|
"src_dot_orders_dot_views_dot_OrderDetails_dot_694622335": {
|
||||||
|
"context": "window title",
|
||||||
|
"string": "Draft Order #{orderNumber}"
|
||||||
|
},
|
||||||
"src_dot_orders_dot_views_dot_OrderDetails_dot_927945225": {
|
"src_dot_orders_dot_views_dot_OrderDetails_dot_927945225": {
|
||||||
"string": "Fulfillment successfully cancelled"
|
"string": "Fulfillment successfully cancelled"
|
||||||
},
|
},
|
||||||
|
@ -2893,9 +2863,6 @@
|
||||||
"context": "header",
|
"context": "header",
|
||||||
"string": "Create Page"
|
"string": "Create Page"
|
||||||
},
|
},
|
||||||
"src_dot_pages_dot_views_dot_1457312643": {
|
|
||||||
"string": "Removed page"
|
|
||||||
},
|
|
||||||
"src_dot_pages_dot_views_dot_2680158037": {
|
"src_dot_pages_dot_views_dot_2680158037": {
|
||||||
"string": "Successfully created new page"
|
"string": "Successfully created new page"
|
||||||
},
|
},
|
||||||
|
@ -4009,6 +3976,14 @@
|
||||||
"context": "shipping method has no value limits",
|
"context": "shipping method has no value limits",
|
||||||
"string": "There are no value limits"
|
"string": "There are no value limits"
|
||||||
},
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZoneRateDialog_dot_price": {
|
||||||
|
"context": "error message",
|
||||||
|
"string": "Maximum price cannot be lower than minimum"
|
||||||
|
},
|
||||||
|
"src_dot_shipping_dot_components_dot_ShippingZoneRateDialog_dot_weight": {
|
||||||
|
"context": "error message",
|
||||||
|
"string": "Maximum weight cannot be lower than minimum"
|
||||||
|
},
|
||||||
"src_dot_shipping_dot_components_dot_ShippingZoneRates_dot_1134347598": {
|
"src_dot_shipping_dot_components_dot_ShippingZoneRates_dot_1134347598": {
|
||||||
"context": "shipping method price",
|
"context": "shipping method price",
|
||||||
"string": "Price"
|
"string": "Price"
|
||||||
|
@ -4236,9 +4211,6 @@
|
||||||
"src_dot_siteSettings_dot_components_dot_SiteSettingsPage_dot_866304242": {
|
"src_dot_siteSettings_dot_components_dot_SiteSettingsPage_dot_866304242": {
|
||||||
"string": "This where you will find all of the settings determining your stores e-mails. You can determine main email address and some of the contents of your emails."
|
"string": "This where you will find all of the settings determining your stores e-mails. You can determine main email address and some of the contents of your emails."
|
||||||
},
|
},
|
||||||
"src_dot_siteSettings_dot_views_dot_2276194921": {
|
|
||||||
"string": "Could not delete authorization key: {errorMessage}"
|
|
||||||
},
|
|
||||||
"src_dot_somethingWentWrong": {
|
"src_dot_somethingWentWrong": {
|
||||||
"string": "Saleor ran into an unexpected problem"
|
"string": "Saleor ran into an unexpected problem"
|
||||||
},
|
},
|
||||||
|
@ -4745,6 +4717,98 @@
|
||||||
"context": "button",
|
"context": "button",
|
||||||
"string": "Upload image"
|
"string": "Upload image"
|
||||||
},
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_alreadyExists": {
|
||||||
|
"context": "add authorization key error",
|
||||||
|
"string": "Authorization key with this type already exists"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_attributeAlreadyAssigned": {
|
||||||
|
"string": "This attribute has already been assigned to this product type"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_attributeCannotBeAssigned": {
|
||||||
|
"string": "This attribute cannot be assigned to this product type"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_attributeVariantsDisabled": {
|
||||||
|
"string": "Variants are disabled in this product type"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_billingNotSet": {
|
||||||
|
"context": "error message",
|
||||||
|
"string": "Billing address is not set"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_cannotCancelFulfillment": {
|
||||||
|
"context": "error message",
|
||||||
|
"string": "This fulfillment cannot be cancelled"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_cannotCancelOrder": {
|
||||||
|
"context": "error message",
|
||||||
|
"string": "This order cannot be cancelled"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_cannotFulfillLine": {
|
||||||
|
"context": "error message",
|
||||||
|
"string": "Not enough items to fulfill"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_cannotRefund": {
|
||||||
|
"context": "error message",
|
||||||
|
"string": "Manual payments can not be refunded"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_cannotVoid": {
|
||||||
|
"context": "error message",
|
||||||
|
"string": "Only pre-authorized payments can be voided"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_captureInactive": {
|
||||||
|
"context": "error message",
|
||||||
|
"string": "Only pre-authorized payments can be captured"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_graphqlError": {
|
||||||
|
"string": "API error"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_invalid": {
|
||||||
|
"string": "Invalid value"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_invalidPassword": {
|
||||||
|
"string": "Invalid password"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_noShippingAddress": {
|
||||||
|
"context": "error message",
|
||||||
|
"string": "Cannot choose a shipping method for an order without the shipping address"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_notEditable": {
|
||||||
|
"context": "error message",
|
||||||
|
"string": "Only draft orders can be edited"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_passwordNumeric": {
|
||||||
|
"string": "Password cannot be entirely numeric"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_paymentMissing": {
|
||||||
|
"context": "error message",
|
||||||
|
"string": "There's no payment associated with the order"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_shippingNotApplicable": {
|
||||||
|
"context": "error message",
|
||||||
|
"string": "Shipping method is not valid for chosen shipping address"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_shippingRequired": {
|
||||||
|
"context": "error message",
|
||||||
|
"string": "Shipping method is required for this order"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_skuUnique": {
|
||||||
|
"context": "bulk variant create error",
|
||||||
|
"string": "SKUs must be unique"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_tooCommon": {
|
||||||
|
"string": "This password is too commonly used"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_tooShort": {
|
||||||
|
"string": "This password is too short"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_tooSimilar": {
|
||||||
|
"string": "These passwords are too similar"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_unknownError": {
|
||||||
|
"string": "Unknown error"
|
||||||
|
},
|
||||||
|
"src_dot_utils_dot_errors_dot_variantNoDigitalContent": {
|
||||||
|
"string": "This variant does not have any digital content"
|
||||||
|
},
|
||||||
"src_dot_vouchers": {
|
"src_dot_vouchers": {
|
||||||
"context": "vouchers section name",
|
"context": "vouchers section name",
|
||||||
"string": "Vouchers"
|
"string": "Vouchers"
|
||||||
|
@ -4757,6 +4821,10 @@
|
||||||
"context": "header",
|
"context": "header",
|
||||||
"string": "Create Webhook"
|
"string": "Create Webhook"
|
||||||
},
|
},
|
||||||
|
"src_dot_webhooks_dot_components_dot_WebhookDeleteDialog_dot_216945727": {
|
||||||
|
"context": "delete webhook",
|
||||||
|
"string": "Are you sure you want to delete this webhook?"
|
||||||
|
},
|
||||||
"src_dot_webhooks_dot_components_dot_WebhookDeleteDialog_dot_2297471173": {
|
"src_dot_webhooks_dot_components_dot_WebhookDeleteDialog_dot_2297471173": {
|
||||||
"context": "delete webhook",
|
"context": "delete webhook",
|
||||||
"string": "Are you sure you want to delete {name}?"
|
"string": "Are you sure you want to delete {name}?"
|
||||||
|
@ -4856,6 +4924,10 @@
|
||||||
"context": "section header",
|
"context": "section header",
|
||||||
"string": "Webhook Status"
|
"string": "Webhook Status"
|
||||||
},
|
},
|
||||||
|
"src_dot_webhooks_dot_components_dot_WebhooksDetailsPage_dot_1595053355": {
|
||||||
|
"context": "header",
|
||||||
|
"string": "Unnamed Webhook Details"
|
||||||
|
},
|
||||||
"src_dot_webhooks_dot_components_dot_WebhooksDetailsPage_dot_408706360": {
|
"src_dot_webhooks_dot_components_dot_WebhooksDetailsPage_dot_408706360": {
|
||||||
"context": "header",
|
"context": "header",
|
||||||
"string": "{webhookName} Details"
|
"string": "{webhookName} Details"
|
||||||
|
@ -4890,6 +4962,9 @@
|
||||||
"context": "user action bar",
|
"context": "user action bar",
|
||||||
"string": "Action"
|
"string": "Action"
|
||||||
},
|
},
|
||||||
|
"src_dot_webhooks_dot_components_dot_WebhooksList_dot_618422799": {
|
||||||
|
"string": "Unnamed webhook"
|
||||||
|
},
|
||||||
"src_dot_webhooks_dot_components_dot_WebhooksList_dot_636461959": {
|
"src_dot_webhooks_dot_components_dot_WebhooksList_dot_636461959": {
|
||||||
"context": "webhook name",
|
"context": "webhook name",
|
||||||
"string": "Name"
|
"string": "Name"
|
||||||
|
|
110
schema.graphql
110
schema.graphql
|
@ -493,6 +493,13 @@ type BulkProductError {
|
||||||
index: Int
|
index: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BulkStockError {
|
||||||
|
field: String
|
||||||
|
message: String
|
||||||
|
code: ProductErrorCode!
|
||||||
|
index: Int
|
||||||
|
}
|
||||||
|
|
||||||
input CatalogueInput {
|
input CatalogueInput {
|
||||||
products: [ID]
|
products: [ID]
|
||||||
categories: [ID]
|
categories: [ID]
|
||||||
|
@ -1502,6 +1509,20 @@ input DigitalContentUrlCreateInput {
|
||||||
content: ID!
|
content: ID!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DiscountError {
|
||||||
|
field: String
|
||||||
|
message: String
|
||||||
|
code: DiscountErrorCode!
|
||||||
|
}
|
||||||
|
|
||||||
|
enum DiscountErrorCode {
|
||||||
|
ALREADY_EXISTS
|
||||||
|
INVALID
|
||||||
|
NOT_FOUND
|
||||||
|
REQUIRED
|
||||||
|
UNIQUE
|
||||||
|
}
|
||||||
|
|
||||||
enum DiscountStatusEnum {
|
enum DiscountStatusEnum {
|
||||||
ACTIVE
|
ACTIVE
|
||||||
EXPIRED
|
EXPIRED
|
||||||
|
@ -2158,10 +2179,6 @@ type Mutation {
|
||||||
deleteWarehouse(id: ID!): WarehouseDelete
|
deleteWarehouse(id: ID!): WarehouseDelete
|
||||||
assignWarehouseShippingZone(id: ID!, shippingZoneIds: [ID!]!): WarehouseShippingZoneAssign
|
assignWarehouseShippingZone(id: ID!, shippingZoneIds: [ID!]!): WarehouseShippingZoneAssign
|
||||||
unassignWarehouseShippingZone(id: ID!, shippingZoneIds: [ID!]!): WarehouseShippingZoneUnassign
|
unassignWarehouseShippingZone(id: ID!, shippingZoneIds: [ID!]!): WarehouseShippingZoneUnassign
|
||||||
createStock(input: StockInput!): StockCreate
|
|
||||||
updateStock(id: ID!, input: StockInput!): StockUpdate
|
|
||||||
deleteStock(id: ID!): StockDelete
|
|
||||||
bulkDeleteStock(ids: [ID]!): StockBulkDelete
|
|
||||||
authorizationKeyAdd(input: AuthorizationKeyInput!, keyType: AuthorizationKeyType!): AuthorizationKeyAdd
|
authorizationKeyAdd(input: AuthorizationKeyInput!, keyType: AuthorizationKeyType!): AuthorizationKeyAdd
|
||||||
authorizationKeyDelete(keyType: AuthorizationKeyType!): AuthorizationKeyDelete
|
authorizationKeyDelete(keyType: AuthorizationKeyType!): AuthorizationKeyDelete
|
||||||
staffNotificationRecipientCreate(input: StaffNotificationRecipientInput!): StaffNotificationRecipientCreate
|
staffNotificationRecipientCreate(input: StaffNotificationRecipientInput!): StaffNotificationRecipientCreate
|
||||||
|
@ -2253,6 +2270,9 @@ type Mutation {
|
||||||
productVariantDelete(id: ID!): ProductVariantDelete
|
productVariantDelete(id: ID!): ProductVariantDelete
|
||||||
productVariantBulkCreate(product: ID!, variants: [ProductVariantBulkCreateInput]!): ProductVariantBulkCreate
|
productVariantBulkCreate(product: ID!, variants: [ProductVariantBulkCreateInput]!): ProductVariantBulkCreate
|
||||||
productVariantBulkDelete(ids: [ID]!): ProductVariantBulkDelete
|
productVariantBulkDelete(ids: [ID]!): ProductVariantBulkDelete
|
||||||
|
productVariantStocksCreate(stocks: [StockInput!]!, variantId: ID!): ProductVariantStocksCreate
|
||||||
|
productVariantStocksDelete(variantId: ID!, warehouseIds: [ID!]): ProductVariantStocksDelete
|
||||||
|
productVariantStocksUpdate(stocks: [StockInput!]!, variantId: ID!): ProductVariantStocksUpdate
|
||||||
productVariantUpdate(id: ID!, input: ProductVariantInput!): ProductVariantUpdate
|
productVariantUpdate(id: ID!, input: ProductVariantInput!): ProductVariantUpdate
|
||||||
productVariantTranslate(id: ID!, input: NameTranslationInput!, languageCode: LanguageCodeEnum!): ProductVariantTranslate
|
productVariantTranslate(id: ID!, input: NameTranslationInput!, languageCode: LanguageCodeEnum!): ProductVariantTranslate
|
||||||
productVariantUpdateMetadata(id: ID!, input: MetaInput!): ProductVariantUpdateMeta @deprecated(reason: "Will be removed in Saleor 2.11. Use the `UpdateMetadata` mutation instead.")
|
productVariantUpdateMetadata(id: ID!, input: MetaInput!): ProductVariantUpdateMeta @deprecated(reason: "Will be removed in Saleor 2.11. Use the `UpdateMetadata` mutation instead.")
|
||||||
|
@ -2444,8 +2464,8 @@ type Order implements Node & ObjectWithMetadata {
|
||||||
voucher: Voucher
|
voucher: Voucher
|
||||||
giftCards: [GiftCard]
|
giftCards: [GiftCard]
|
||||||
discount: Money
|
discount: Money
|
||||||
discountName: String!
|
discountName: String
|
||||||
translatedDiscountName: String!
|
translatedDiscountName: String
|
||||||
displayGrossPrices: Boolean!
|
displayGrossPrices: Boolean!
|
||||||
customerNote: String!
|
customerNote: String!
|
||||||
weight: Weight
|
weight: Weight
|
||||||
|
@ -2489,7 +2509,7 @@ type OrderAddNote {
|
||||||
}
|
}
|
||||||
|
|
||||||
input OrderAddNoteInput {
|
input OrderAddNoteInput {
|
||||||
message: String
|
message: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
type OrderBulkCancel {
|
type OrderBulkCancel {
|
||||||
|
@ -3218,6 +3238,7 @@ input ProductCreateInput {
|
||||||
quantity: Int
|
quantity: Int
|
||||||
trackInventory: Boolean
|
trackInventory: Boolean
|
||||||
productType: ID!
|
productType: ID!
|
||||||
|
stocks: [StockInput!]
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProductDelete {
|
type ProductDelete {
|
||||||
|
@ -3255,6 +3276,7 @@ input ProductFilterInput {
|
||||||
attributes: [AttributeInput]
|
attributes: [AttributeInput]
|
||||||
stockAvailability: StockAvailability
|
stockAvailability: StockAvailability
|
||||||
productType: ID
|
productType: ID
|
||||||
|
stocks: ProductStockFilterInput
|
||||||
search: String
|
search: String
|
||||||
minimalPrice: PriceRangeInput
|
minimalPrice: PriceRangeInput
|
||||||
productTypes: [ID]
|
productTypes: [ID]
|
||||||
|
@ -3355,6 +3377,11 @@ type ProductPricingInfo {
|
||||||
priceRangeLocalCurrency: TaxedMoneyRange
|
priceRangeLocalCurrency: TaxedMoneyRange
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input ProductStockFilterInput {
|
||||||
|
warehouseIds: [ID!]
|
||||||
|
quantity: IntRangeInput
|
||||||
|
}
|
||||||
|
|
||||||
type ProductTranslatableContent implements Node {
|
type ProductTranslatableContent implements Node {
|
||||||
id: ID!
|
id: ID!
|
||||||
seoTitle: String
|
seoTitle: String
|
||||||
|
@ -3549,7 +3576,7 @@ type ProductVariant implements Node & ObjectWithMetadata {
|
||||||
images: [ProductImage]
|
images: [ProductImage]
|
||||||
translation(languageCode: LanguageCodeEnum!): ProductVariantTranslation
|
translation(languageCode: LanguageCodeEnum!): ProductVariantTranslation
|
||||||
digitalContent: DigitalContent
|
digitalContent: DigitalContent
|
||||||
stock(country: String): [Stock]
|
stocks(countryCode: CountryCode): [Stock]
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProductVariantBulkCreate {
|
type ProductVariantBulkCreate {
|
||||||
|
@ -3613,6 +3640,7 @@ input ProductVariantCreateInput {
|
||||||
trackInventory: Boolean
|
trackInventory: Boolean
|
||||||
weight: WeightScalar
|
weight: WeightScalar
|
||||||
product: ID!
|
product: ID!
|
||||||
|
stocks: [StockInput!]
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProductVariantDelete {
|
type ProductVariantDelete {
|
||||||
|
@ -3631,6 +3659,24 @@ input ProductVariantInput {
|
||||||
weight: WeightScalar
|
weight: WeightScalar
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ProductVariantStocksCreate {
|
||||||
|
errors: [Error!]!
|
||||||
|
productVariant: ProductVariant
|
||||||
|
bulkStockErrors: [BulkStockError!]!
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProductVariantStocksDelete {
|
||||||
|
errors: [Error!]!
|
||||||
|
productVariant: ProductVariant
|
||||||
|
stockErrors: [StockError!]!
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProductVariantStocksUpdate {
|
||||||
|
errors: [Error!]!
|
||||||
|
productVariant: ProductVariant
|
||||||
|
bulkStockErrors: [BulkStockError!]!
|
||||||
|
}
|
||||||
|
|
||||||
type ProductVariantTranslatableContent implements Node {
|
type ProductVariantTranslatableContent implements Node {
|
||||||
id: ID!
|
id: ID!
|
||||||
name: String!
|
name: String!
|
||||||
|
@ -3784,6 +3830,7 @@ type Sale implements Node {
|
||||||
type SaleAddCatalogues {
|
type SaleAddCatalogues {
|
||||||
errors: [Error!]!
|
errors: [Error!]!
|
||||||
sale: Sale
|
sale: Sale
|
||||||
|
discountErrors: [DiscountError!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
type SaleBulkDelete {
|
type SaleBulkDelete {
|
||||||
|
@ -3804,11 +3851,13 @@ type SaleCountableEdge {
|
||||||
|
|
||||||
type SaleCreate {
|
type SaleCreate {
|
||||||
errors: [Error!]!
|
errors: [Error!]!
|
||||||
|
discountErrors: [DiscountError!]!
|
||||||
sale: Sale
|
sale: Sale
|
||||||
}
|
}
|
||||||
|
|
||||||
type SaleDelete {
|
type SaleDelete {
|
||||||
errors: [Error!]!
|
errors: [Error!]!
|
||||||
|
discountErrors: [DiscountError!]!
|
||||||
sale: Sale
|
sale: Sale
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3833,6 +3882,7 @@ input SaleInput {
|
||||||
type SaleRemoveCatalogues {
|
type SaleRemoveCatalogues {
|
||||||
errors: [Error!]!
|
errors: [Error!]!
|
||||||
sale: Sale
|
sale: Sale
|
||||||
|
discountErrors: [DiscountError!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SaleSortField {
|
enum SaleSortField {
|
||||||
|
@ -3873,6 +3923,7 @@ enum SaleType {
|
||||||
|
|
||||||
type SaleUpdate {
|
type SaleUpdate {
|
||||||
errors: [Error!]!
|
errors: [Error!]!
|
||||||
|
discountErrors: [DiscountError!]!
|
||||||
sale: Sale
|
sale: Sale
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3888,15 +3939,15 @@ input SeoInput {
|
||||||
|
|
||||||
type ServiceAccount implements Node & ObjectWithMetadata {
|
type ServiceAccount implements Node & ObjectWithMetadata {
|
||||||
id: ID!
|
id: ID!
|
||||||
|
name: String
|
||||||
created: DateTime
|
created: DateTime
|
||||||
isActive: Boolean
|
isActive: Boolean
|
||||||
|
permissions: [PermissionDisplay]
|
||||||
tokens: [ServiceAccountToken]
|
tokens: [ServiceAccountToken]
|
||||||
privateMetadata: [MetadataItem]!
|
privateMetadata: [MetadataItem]!
|
||||||
metadata: [MetadataItem]!
|
metadata: [MetadataItem]!
|
||||||
privateMeta: [MetaStore]! @deprecated(reason: "DEPRECATED: Will be removed in Saleor 2.11. use the `privetaMetadata` field instead. ")
|
privateMeta: [MetaStore]! @deprecated(reason: "DEPRECATED: Will be removed in Saleor 2.11. use the `privetaMetadata` field instead. ")
|
||||||
meta: [MetaStore]! @deprecated(reason: "DEPRECATED: Will be removed in Saleor 2.11. use the `metadata` field instead. ")
|
meta: [MetaStore]! @deprecated(reason: "DEPRECATED: Will be removed in Saleor 2.11. use the `metadata` field instead. ")
|
||||||
permissions: [PermissionDisplay]
|
|
||||||
name: String
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServiceAccountClearPrivateMeta {
|
type ServiceAccountClearPrivateMeta {
|
||||||
|
@ -4341,12 +4392,6 @@ enum StockAvailability {
|
||||||
OUT_OF_STOCK
|
OUT_OF_STOCK
|
||||||
}
|
}
|
||||||
|
|
||||||
type StockBulkDelete {
|
|
||||||
errors: [Error!]!
|
|
||||||
count: Int!
|
|
||||||
stockError: [StockError!]!
|
|
||||||
}
|
|
||||||
|
|
||||||
type StockCountableConnection {
|
type StockCountableConnection {
|
||||||
pageInfo: PageInfo!
|
pageInfo: PageInfo!
|
||||||
edges: [StockCountableEdge!]!
|
edges: [StockCountableEdge!]!
|
||||||
|
@ -4358,18 +4403,13 @@ type StockCountableEdge {
|
||||||
cursor: String!
|
cursor: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
type StockCreate {
|
type StockError {
|
||||||
errors: [Error!]!
|
field: String
|
||||||
stockErrors: [StockError!]!
|
message: String
|
||||||
stock: Stock
|
code: StockErrorCode!
|
||||||
}
|
}
|
||||||
|
|
||||||
type StockDelete {
|
enum StockErrorCode {
|
||||||
errors: [Error!]!
|
|
||||||
stock: Stock
|
|
||||||
}
|
|
||||||
|
|
||||||
enum StockErorrCode {
|
|
||||||
ALREADY_EXISTS
|
ALREADY_EXISTS
|
||||||
GRAPHQL_ERROR
|
GRAPHQL_ERROR
|
||||||
INVALID
|
INVALID
|
||||||
|
@ -4378,12 +4418,6 @@ enum StockErorrCode {
|
||||||
UNIQUE
|
UNIQUE
|
||||||
}
|
}
|
||||||
|
|
||||||
type StockError {
|
|
||||||
field: String
|
|
||||||
message: String
|
|
||||||
code: StockErorrCode!
|
|
||||||
}
|
|
||||||
|
|
||||||
input StockFilterInput {
|
input StockFilterInput {
|
||||||
quantity: Float
|
quantity: Float
|
||||||
quantityAllocated: Float
|
quantityAllocated: Float
|
||||||
|
@ -4391,17 +4425,10 @@ input StockFilterInput {
|
||||||
}
|
}
|
||||||
|
|
||||||
input StockInput {
|
input StockInput {
|
||||||
productVariant: ID!
|
|
||||||
warehouse: ID!
|
warehouse: ID!
|
||||||
quantity: Int
|
quantity: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
type StockUpdate {
|
|
||||||
errors: [Error!]!
|
|
||||||
stockError: [StockError!]!
|
|
||||||
stock: Stock
|
|
||||||
}
|
|
||||||
|
|
||||||
enum TaxRateType {
|
enum TaxRateType {
|
||||||
ACCOMMODATION
|
ACCOMMODATION
|
||||||
ADMISSION_TO_CULTURAL_EVENTS
|
ADMISSION_TO_CULTURAL_EVENTS
|
||||||
|
@ -4693,6 +4720,7 @@ type Voucher implements Node {
|
||||||
type VoucherAddCatalogues {
|
type VoucherAddCatalogues {
|
||||||
errors: [Error!]!
|
errors: [Error!]!
|
||||||
voucher: Voucher
|
voucher: Voucher
|
||||||
|
discountErrors: [DiscountError!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
type VoucherBulkDelete {
|
type VoucherBulkDelete {
|
||||||
|
@ -4713,11 +4741,13 @@ type VoucherCountableEdge {
|
||||||
|
|
||||||
type VoucherCreate {
|
type VoucherCreate {
|
||||||
errors: [Error!]!
|
errors: [Error!]!
|
||||||
|
discountErrors: [DiscountError!]!
|
||||||
voucher: Voucher
|
voucher: Voucher
|
||||||
}
|
}
|
||||||
|
|
||||||
type VoucherDelete {
|
type VoucherDelete {
|
||||||
errors: [Error!]!
|
errors: [Error!]!
|
||||||
|
discountErrors: [DiscountError!]!
|
||||||
voucher: Voucher
|
voucher: Voucher
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4757,6 +4787,7 @@ input VoucherInput {
|
||||||
type VoucherRemoveCatalogues {
|
type VoucherRemoveCatalogues {
|
||||||
errors: [Error!]!
|
errors: [Error!]!
|
||||||
voucher: Voucher
|
voucher: Voucher
|
||||||
|
discountErrors: [DiscountError!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
enum VoucherSortField {
|
enum VoucherSortField {
|
||||||
|
@ -4800,6 +4831,7 @@ enum VoucherTypeEnum {
|
||||||
|
|
||||||
type VoucherUpdate {
|
type VoucherUpdate {
|
||||||
errors: [Error!]!
|
errors: [Error!]!
|
||||||
|
discountErrors: [DiscountError!]!
|
||||||
voucher: Voucher
|
voucher: Voucher
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,16 +10,17 @@ import ControlledCheckbox from "@saleor/components/ControlledCheckbox";
|
||||||
import FormSpacer from "@saleor/components/FormSpacer";
|
import FormSpacer from "@saleor/components/FormSpacer";
|
||||||
import SingleSelectField from "@saleor/components/SingleSelectField";
|
import SingleSelectField from "@saleor/components/SingleSelectField";
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
import { UserError } from "@saleor/types";
|
|
||||||
import { AttributeInputTypeEnum } from "@saleor/types/globalTypes";
|
import { AttributeInputTypeEnum } from "@saleor/types/globalTypes";
|
||||||
import { getFieldError } from "@saleor/utils/errors";
|
import { getProductErrorMessage, getFormErrors } from "@saleor/utils/errors";
|
||||||
|
import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment";
|
||||||
import { AttributePageFormData } from "../AttributePage";
|
import { AttributePageFormData } from "../AttributePage";
|
||||||
|
import { getAttributeSlugErrorMessage } from "../../errors";
|
||||||
|
|
||||||
export interface AttributeDetailsProps {
|
export interface AttributeDetailsProps {
|
||||||
canChangeType: boolean;
|
canChangeType: boolean;
|
||||||
data: AttributePageFormData;
|
data: AttributePageFormData;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: ProductErrorFragment[];
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
onChange: (event: React.ChangeEvent<any>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +49,8 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const formErrors = getFormErrors(["name", "slug", "inputType"], errors);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
|
@ -56,21 +59,21 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "name")}
|
error={!!formErrors.name}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Default Label",
|
defaultMessage: "Default Label",
|
||||||
description: "attribute's label"
|
description: "attribute's label"
|
||||||
})}
|
})}
|
||||||
name={"name" as keyof AttributePageFormData}
|
name={"name" as keyof AttributePageFormData}
|
||||||
fullWidth
|
fullWidth
|
||||||
helperText={getFieldError(errors, "name")?.message}
|
helperText={getProductErrorMessage(formErrors.name, intl)}
|
||||||
value={data.name}
|
value={data.name}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
/>
|
/>
|
||||||
<FormSpacer />
|
<FormSpacer />
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "slug")}
|
error={!!formErrors.slug}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Attribute Code",
|
defaultMessage: "Attribute Code",
|
||||||
description: "attribute's slug short code label"
|
description: "attribute's slug short code label"
|
||||||
|
@ -79,7 +82,7 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({
|
||||||
placeholder={slugify(data.name).toLowerCase()}
|
placeholder={slugify(data.name).toLowerCase()}
|
||||||
fullWidth
|
fullWidth
|
||||||
helperText={
|
helperText={
|
||||||
getFieldError(errors, "slug")?.message ||
|
getAttributeSlugErrorMessage(formErrors.slug, intl) ||
|
||||||
intl.formatMessage({
|
intl.formatMessage({
|
||||||
defaultMessage:
|
defaultMessage:
|
||||||
"This is used internally. Make sure you don’t use spaces",
|
"This is used internally. Make sure you don’t use spaces",
|
||||||
|
@ -93,8 +96,8 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({
|
||||||
<SingleSelectField
|
<SingleSelectField
|
||||||
choices={inputTypeChoices}
|
choices={inputTypeChoices}
|
||||||
disabled={disabled || !canChangeType}
|
disabled={disabled || !canChangeType}
|
||||||
error={!!getFieldError(errors, "inputType")}
|
error={!!formErrors.inputType}
|
||||||
hint={getFieldError(errors, "inputType")?.message}
|
hint={getProductErrorMessage(formErrors.inputType, intl)}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Catalog Input type for Store Owner",
|
defaultMessage: "Catalog Input type for Store Owner",
|
||||||
description: "attribute's editor component"
|
description: "attribute's editor component"
|
||||||
|
|
|
@ -12,8 +12,9 @@ import PageHeader from "@saleor/components/PageHeader";
|
||||||
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
||||||
import { sectionNames } from "@saleor/intl";
|
import { sectionNames } from "@saleor/intl";
|
||||||
import { maybe } from "@saleor/misc";
|
import { maybe } from "@saleor/misc";
|
||||||
import { ReorderAction, UserError } from "@saleor/types";
|
import { ReorderAction } from "@saleor/types";
|
||||||
import { AttributeInputTypeEnum } from "@saleor/types/globalTypes";
|
import { AttributeInputTypeEnum } from "@saleor/types/globalTypes";
|
||||||
|
import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment";
|
||||||
import {
|
import {
|
||||||
AttributeDetailsFragment,
|
AttributeDetailsFragment,
|
||||||
AttributeDetailsFragment_values
|
AttributeDetailsFragment_values
|
||||||
|
@ -25,7 +26,7 @@ import AttributeValues from "../AttributeValues";
|
||||||
export interface AttributePageProps {
|
export interface AttributePageProps {
|
||||||
attribute: AttributeDetailsFragment | null;
|
attribute: AttributeDetailsFragment | null;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: ProductErrorFragment[];
|
||||||
saveButtonBarState: ConfirmButtonTransitionState;
|
saveButtonBarState: ConfirmButtonTransitionState;
|
||||||
values: AttributeDetailsFragment_values[];
|
values: AttributeDetailsFragment_values[];
|
||||||
onBack: () => void;
|
onBack: () => void;
|
||||||
|
|
|
@ -11,14 +11,14 @@ import ControlledCheckbox from "@saleor/components/ControlledCheckbox";
|
||||||
import FormSpacer from "@saleor/components/FormSpacer";
|
import FormSpacer from "@saleor/components/FormSpacer";
|
||||||
import Hr from "@saleor/components/Hr";
|
import Hr from "@saleor/components/Hr";
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
import { UserError } from "@saleor/types";
|
import { getFormErrors, getProductErrorMessage } from "@saleor/utils/errors";
|
||||||
import { getFieldError } from "@saleor/utils/errors";
|
import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment";
|
||||||
import { AttributePageFormData } from "../AttributePage";
|
import { AttributePageFormData } from "../AttributePage";
|
||||||
|
|
||||||
export interface AttributePropertiesProps {
|
export interface AttributePropertiesProps {
|
||||||
data: AttributePageFormData;
|
data: AttributePageFormData;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: ProductErrorFragment[];
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
onChange: (event: React.ChangeEvent<any>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,8 @@ const AttributeProperties: React.FC<AttributePropertiesProps> = ({
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const formErrors = getFormErrors(["storefrontSearchPosition"], errors);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle title={intl.formatMessage(commonMessages.properties)} />
|
<CardTitle title={intl.formatMessage(commonMessages.properties)} />
|
||||||
|
@ -86,11 +88,12 @@ const AttributeProperties: React.FC<AttributePropertiesProps> = ({
|
||||||
{data.filterableInStorefront && (
|
{data.filterableInStorefront && (
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "storefrontSearchPosition")}
|
error={!!formErrors.storefrontSearchPosition}
|
||||||
fullWidth
|
fullWidth
|
||||||
helperText={
|
helperText={getProductErrorMessage(
|
||||||
getFieldError(errors, "storefrontSearchPosition")?.message
|
formErrors.storefrontSearchPosition,
|
||||||
}
|
intl
|
||||||
|
)}
|
||||||
name={"storefrontSearchPosition" as keyof AttributePageFormData}
|
name={"storefrontSearchPosition" as keyof AttributePageFormData}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Position in faceted navigation",
|
defaultMessage: "Position in faceted navigation",
|
||||||
|
|
|
@ -14,8 +14,9 @@ import Form from "@saleor/components/Form";
|
||||||
import useModalDialogErrors from "@saleor/hooks/useModalDialogErrors";
|
import useModalDialogErrors from "@saleor/hooks/useModalDialogErrors";
|
||||||
import { buttonMessages } from "@saleor/intl";
|
import { buttonMessages } from "@saleor/intl";
|
||||||
import { maybe } from "@saleor/misc";
|
import { maybe } from "@saleor/misc";
|
||||||
import { UserError } from "@saleor/types";
|
import { getFormErrors } from "@saleor/utils/errors";
|
||||||
import { getFieldError } from "@saleor/utils/errors";
|
import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment";
|
||||||
|
import { getAttributeValueErrorMessage } from "@saleor/attributes/errors";
|
||||||
import { AttributeDetails_attribute_values } from "../../types/AttributeDetails";
|
import { AttributeDetails_attribute_values } from "../../types/AttributeDetails";
|
||||||
|
|
||||||
export interface AttributeValueEditDialogFormData {
|
export interface AttributeValueEditDialogFormData {
|
||||||
|
@ -25,7 +26,7 @@ export interface AttributeValueEditDialogProps {
|
||||||
attributeValue: AttributeDetails_attribute_values | null;
|
attributeValue: AttributeDetails_attribute_values | null;
|
||||||
confirmButtonState: ConfirmButtonTransitionState;
|
confirmButtonState: ConfirmButtonTransitionState;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: ProductErrorFragment[];
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onSubmit: (data: AttributeValueEditDialogFormData) => void;
|
onSubmit: (data: AttributeValueEditDialogFormData) => void;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
|
@ -45,6 +46,7 @@ const AttributeValueEditDialog: React.FC<AttributeValueEditDialogProps> = ({
|
||||||
name: maybe(() => attributeValue.name, "")
|
name: maybe(() => attributeValue.name, "")
|
||||||
};
|
};
|
||||||
const errors = useModalDialogErrors(apiErrors, open);
|
const errors = useModalDialogErrors(apiErrors, open);
|
||||||
|
const formErrors = getFormErrors(["name"], errors);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog onClose={onClose} open={open} fullWidth maxWidth="sm">
|
<Dialog onClose={onClose} open={open} fullWidth maxWidth="sm">
|
||||||
|
@ -68,9 +70,12 @@ const AttributeValueEditDialog: React.FC<AttributeValueEditDialogProps> = ({
|
||||||
<TextField
|
<TextField
|
||||||
autoFocus
|
autoFocus
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "name")}
|
error={!!formErrors.name}
|
||||||
fullWidth
|
fullWidth
|
||||||
helperText={getFieldError(errors, "name")?.message}
|
helperText={getAttributeValueErrorMessage(
|
||||||
|
formErrors.name,
|
||||||
|
intl
|
||||||
|
)}
|
||||||
name={"name" as keyof AttributeValueEditDialogFormData}
|
name={"name" as keyof AttributeValueEditDialogFormData}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Name",
|
defaultMessage: "Name",
|
||||||
|
|
38
src/attributes/errors.ts
Normal file
38
src/attributes/errors.ts
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import { IntlShape, defineMessages } from "react-intl";
|
||||||
|
|
||||||
|
import { ProductErrorCode } from "@saleor/types/globalTypes";
|
||||||
|
import { getProductErrorMessage } from "@saleor/utils/errors";
|
||||||
|
import { ProductErrorFragment } from "./types/ProductErrorFragment";
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
attributeSlugUnique: {
|
||||||
|
defaultMessage: "Attribute with this slug already exists"
|
||||||
|
},
|
||||||
|
attributeValueAlreadyExists: {
|
||||||
|
defaultMessage: "This value already exists within this attribute"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export function getAttributeSlugErrorMessage(
|
||||||
|
err: ProductErrorFragment,
|
||||||
|
intl: IntlShape
|
||||||
|
): string {
|
||||||
|
switch (err?.code) {
|
||||||
|
case ProductErrorCode.UNIQUE:
|
||||||
|
return intl.formatMessage(messages.attributeSlugUnique);
|
||||||
|
default:
|
||||||
|
return getProductErrorMessage(err, intl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAttributeValueErrorMessage(
|
||||||
|
err: ProductErrorFragment,
|
||||||
|
intl: IntlShape
|
||||||
|
): string {
|
||||||
|
switch (err?.code) {
|
||||||
|
case ProductErrorCode.ALREADY_EXISTS:
|
||||||
|
return intl.formatMessage(messages.attributeValueAlreadyExists);
|
||||||
|
default:
|
||||||
|
return getProductErrorMessage(err, intl);
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,12 +35,19 @@ import {
|
||||||
AttributeValueUpdateVariables
|
AttributeValueUpdateVariables
|
||||||
} from "./types/AttributeValueUpdate";
|
} from "./types/AttributeValueUpdate";
|
||||||
|
|
||||||
|
export const productErrorFragment = gql`
|
||||||
|
fragment ProductErrorFragment on ProductError {
|
||||||
|
code
|
||||||
|
field
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
const attributeBulkDelete = gql`
|
const attributeBulkDelete = gql`
|
||||||
|
${productErrorFragment}
|
||||||
mutation AttributeBulkDelete($ids: [ID!]!) {
|
mutation AttributeBulkDelete($ids: [ID!]!) {
|
||||||
attributeBulkDelete(ids: $ids) {
|
attributeBulkDelete(ids: $ids) {
|
||||||
errors {
|
errors: productErrors {
|
||||||
field
|
...ProductErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,11 +58,11 @@ export const AttributeBulkDeleteMutation = TypedMutation<
|
||||||
>(attributeBulkDelete);
|
>(attributeBulkDelete);
|
||||||
|
|
||||||
const attributeDelete = gql`
|
const attributeDelete = gql`
|
||||||
|
${productErrorFragment}
|
||||||
mutation AttributeDelete($id: ID!) {
|
mutation AttributeDelete($id: ID!) {
|
||||||
attributeDelete(id: $id) {
|
attributeDelete(id: $id) {
|
||||||
errors {
|
errors: productErrors {
|
||||||
field
|
...ProductErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,15 +74,15 @@ export const AttributeDeleteMutation = TypedMutation<
|
||||||
|
|
||||||
export const attributeUpdateMutation = gql`
|
export const attributeUpdateMutation = gql`
|
||||||
${attributeDetailsFragment}
|
${attributeDetailsFragment}
|
||||||
|
${productErrorFragment}
|
||||||
mutation AttributeUpdate($id: ID!, $input: AttributeUpdateInput!) {
|
mutation AttributeUpdate($id: ID!, $input: AttributeUpdateInput!) {
|
||||||
attributeUpdate(id: $id, input: $input) {
|
attributeUpdate(id: $id, input: $input) {
|
||||||
errors {
|
|
||||||
field
|
|
||||||
message
|
|
||||||
}
|
|
||||||
attribute {
|
attribute {
|
||||||
...AttributeDetailsFragment
|
...AttributeDetailsFragment
|
||||||
}
|
}
|
||||||
|
errors: productErrors {
|
||||||
|
...ProductErrorFragment
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -86,15 +93,15 @@ export const AttributeUpdateMutation = TypedMutation<
|
||||||
|
|
||||||
const attributeValueDelete = gql`
|
const attributeValueDelete = gql`
|
||||||
${attributeDetailsFragment}
|
${attributeDetailsFragment}
|
||||||
|
${productErrorFragment}
|
||||||
mutation AttributeValueDelete($id: ID!) {
|
mutation AttributeValueDelete($id: ID!) {
|
||||||
attributeValueDelete(id: $id) {
|
attributeValueDelete(id: $id) {
|
||||||
errors {
|
|
||||||
field
|
|
||||||
message
|
|
||||||
}
|
|
||||||
attribute {
|
attribute {
|
||||||
...AttributeDetailsFragment
|
...AttributeDetailsFragment
|
||||||
}
|
}
|
||||||
|
errors: productErrors {
|
||||||
|
...ProductErrorFragment
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -105,15 +112,15 @@ export const AttributeValueDeleteMutation = TypedMutation<
|
||||||
|
|
||||||
export const attributeValueUpdateMutation = gql`
|
export const attributeValueUpdateMutation = gql`
|
||||||
${attributeDetailsFragment}
|
${attributeDetailsFragment}
|
||||||
|
${productErrorFragment}
|
||||||
mutation AttributeValueUpdate($id: ID!, $input: AttributeValueCreateInput!) {
|
mutation AttributeValueUpdate($id: ID!, $input: AttributeValueCreateInput!) {
|
||||||
attributeValueUpdate(id: $id, input: $input) {
|
attributeValueUpdate(id: $id, input: $input) {
|
||||||
errors {
|
|
||||||
field
|
|
||||||
message
|
|
||||||
}
|
|
||||||
attribute {
|
attribute {
|
||||||
...AttributeDetailsFragment
|
...AttributeDetailsFragment
|
||||||
}
|
}
|
||||||
|
errors: productErrors {
|
||||||
|
...ProductErrorFragment
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -124,15 +131,15 @@ export const AttributeValueUpdateMutation = TypedMutation<
|
||||||
|
|
||||||
export const attributeValueCreateMutation = gql`
|
export const attributeValueCreateMutation = gql`
|
||||||
${attributeDetailsFragment}
|
${attributeDetailsFragment}
|
||||||
|
${productErrorFragment}
|
||||||
mutation AttributeValueCreate($id: ID!, $input: AttributeValueCreateInput!) {
|
mutation AttributeValueCreate($id: ID!, $input: AttributeValueCreateInput!) {
|
||||||
attributeValueCreate(attribute: $id, input: $input) {
|
attributeValueCreate(attribute: $id, input: $input) {
|
||||||
errors {
|
|
||||||
field
|
|
||||||
message
|
|
||||||
}
|
|
||||||
attribute {
|
attribute {
|
||||||
...AttributeDetailsFragment
|
...AttributeDetailsFragment
|
||||||
}
|
}
|
||||||
|
errors: productErrors {
|
||||||
|
...ProductErrorFragment
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -143,15 +150,15 @@ export const AttributeValueCreateMutation = TypedMutation<
|
||||||
|
|
||||||
export const attributeCreateMutation = gql`
|
export const attributeCreateMutation = gql`
|
||||||
${attributeDetailsFragment}
|
${attributeDetailsFragment}
|
||||||
|
${productErrorFragment}
|
||||||
mutation AttributeCreate($input: AttributeCreateInput!) {
|
mutation AttributeCreate($input: AttributeCreateInput!) {
|
||||||
attributeCreate(input: $input) {
|
attributeCreate(input: $input) {
|
||||||
errors {
|
|
||||||
field
|
|
||||||
message
|
|
||||||
}
|
|
||||||
attribute {
|
attribute {
|
||||||
...AttributeDetailsFragment
|
...AttributeDetailsFragment
|
||||||
}
|
}
|
||||||
|
errors: productErrors {
|
||||||
|
...ProductErrorFragment
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -161,18 +168,18 @@ export const AttributeCreateMutation = TypedMutation<
|
||||||
>(attributeCreateMutation);
|
>(attributeCreateMutation);
|
||||||
|
|
||||||
const attributeValueReorderMutation = gql`
|
const attributeValueReorderMutation = gql`
|
||||||
|
${productErrorFragment}
|
||||||
mutation AttributeValueReorder($id: ID!, $move: ReorderInput!) {
|
mutation AttributeValueReorder($id: ID!, $move: ReorderInput!) {
|
||||||
attributeReorderValues(attributeId: $id, moves: [$move]) {
|
attributeReorderValues(attributeId: $id, moves: [$move]) {
|
||||||
errors {
|
|
||||||
field
|
|
||||||
message
|
|
||||||
}
|
|
||||||
attribute {
|
attribute {
|
||||||
id
|
id
|
||||||
values {
|
values {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
errors: productErrors {
|
||||||
|
...ProductErrorFragment
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { ProductErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: AttributeBulkDelete
|
// GraphQL mutation operation: AttributeBulkDelete
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface AttributeBulkDelete_attributeBulkDelete_errors {
|
export interface AttributeBulkDelete_attributeBulkDelete_errors {
|
||||||
__typename: "Error";
|
__typename: "ProductError";
|
||||||
|
code: ProductErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttributeBulkDelete_attributeBulkDelete {
|
export interface AttributeBulkDelete_attributeBulkDelete {
|
||||||
|
|
|
@ -2,18 +2,12 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { AttributeCreateInput, AttributeInputTypeEnum, AttributeValueType } from "./../../types/globalTypes";
|
import { AttributeCreateInput, AttributeInputTypeEnum, AttributeValueType, ProductErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: AttributeCreate
|
// GraphQL mutation operation: AttributeCreate
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface AttributeCreate_attributeCreate_errors {
|
|
||||||
__typename: "Error";
|
|
||||||
field: string | null;
|
|
||||||
message: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AttributeCreate_attributeCreate_attribute_values {
|
export interface AttributeCreate_attributeCreate_attribute_values {
|
||||||
__typename: "AttributeValue";
|
__typename: "AttributeValue";
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -37,10 +31,16 @@ export interface AttributeCreate_attributeCreate_attribute {
|
||||||
values: (AttributeCreate_attributeCreate_attribute_values | null)[] | null;
|
values: (AttributeCreate_attributeCreate_attribute_values | null)[] | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AttributeCreate_attributeCreate_errors {
|
||||||
|
__typename: "ProductError";
|
||||||
|
code: ProductErrorCode;
|
||||||
|
field: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface AttributeCreate_attributeCreate {
|
export interface AttributeCreate_attributeCreate {
|
||||||
__typename: "AttributeCreate";
|
__typename: "AttributeCreate";
|
||||||
errors: AttributeCreate_attributeCreate_errors[];
|
|
||||||
attribute: AttributeCreate_attributeCreate_attribute | null;
|
attribute: AttributeCreate_attributeCreate_attribute | null;
|
||||||
|
errors: AttributeCreate_attributeCreate_errors[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttributeCreate {
|
export interface AttributeCreate {
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { ProductErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: AttributeDelete
|
// GraphQL mutation operation: AttributeDelete
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface AttributeDelete_attributeDelete_errors {
|
export interface AttributeDelete_attributeDelete_errors {
|
||||||
__typename: "Error";
|
__typename: "ProductError";
|
||||||
|
code: ProductErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttributeDelete_attributeDelete {
|
export interface AttributeDelete_attributeDelete {
|
||||||
|
|
|
@ -2,18 +2,12 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { AttributeUpdateInput, AttributeInputTypeEnum, AttributeValueType } from "./../../types/globalTypes";
|
import { AttributeUpdateInput, AttributeInputTypeEnum, AttributeValueType, ProductErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: AttributeUpdate
|
// GraphQL mutation operation: AttributeUpdate
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface AttributeUpdate_attributeUpdate_errors {
|
|
||||||
__typename: "Error";
|
|
||||||
field: string | null;
|
|
||||||
message: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AttributeUpdate_attributeUpdate_attribute_values {
|
export interface AttributeUpdate_attributeUpdate_attribute_values {
|
||||||
__typename: "AttributeValue";
|
__typename: "AttributeValue";
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -37,10 +31,16 @@ export interface AttributeUpdate_attributeUpdate_attribute {
|
||||||
values: (AttributeUpdate_attributeUpdate_attribute_values | null)[] | null;
|
values: (AttributeUpdate_attributeUpdate_attribute_values | null)[] | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AttributeUpdate_attributeUpdate_errors {
|
||||||
|
__typename: "ProductError";
|
||||||
|
code: ProductErrorCode;
|
||||||
|
field: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface AttributeUpdate_attributeUpdate {
|
export interface AttributeUpdate_attributeUpdate {
|
||||||
__typename: "AttributeUpdate";
|
__typename: "AttributeUpdate";
|
||||||
errors: AttributeUpdate_attributeUpdate_errors[];
|
|
||||||
attribute: AttributeUpdate_attributeUpdate_attribute | null;
|
attribute: AttributeUpdate_attributeUpdate_attribute | null;
|
||||||
|
errors: AttributeUpdate_attributeUpdate_errors[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttributeUpdate {
|
export interface AttributeUpdate {
|
||||||
|
|
|
@ -2,18 +2,12 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { AttributeValueCreateInput, AttributeInputTypeEnum, AttributeValueType } from "./../../types/globalTypes";
|
import { AttributeValueCreateInput, AttributeInputTypeEnum, AttributeValueType, ProductErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: AttributeValueCreate
|
// GraphQL mutation operation: AttributeValueCreate
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface AttributeValueCreate_attributeValueCreate_errors {
|
|
||||||
__typename: "Error";
|
|
||||||
field: string | null;
|
|
||||||
message: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AttributeValueCreate_attributeValueCreate_attribute_values {
|
export interface AttributeValueCreate_attributeValueCreate_attribute_values {
|
||||||
__typename: "AttributeValue";
|
__typename: "AttributeValue";
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -37,10 +31,16 @@ export interface AttributeValueCreate_attributeValueCreate_attribute {
|
||||||
values: (AttributeValueCreate_attributeValueCreate_attribute_values | null)[] | null;
|
values: (AttributeValueCreate_attributeValueCreate_attribute_values | null)[] | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AttributeValueCreate_attributeValueCreate_errors {
|
||||||
|
__typename: "ProductError";
|
||||||
|
code: ProductErrorCode;
|
||||||
|
field: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface AttributeValueCreate_attributeValueCreate {
|
export interface AttributeValueCreate_attributeValueCreate {
|
||||||
__typename: "AttributeValueCreate";
|
__typename: "AttributeValueCreate";
|
||||||
errors: AttributeValueCreate_attributeValueCreate_errors[];
|
|
||||||
attribute: AttributeValueCreate_attributeValueCreate_attribute | null;
|
attribute: AttributeValueCreate_attributeValueCreate_attribute | null;
|
||||||
|
errors: AttributeValueCreate_attributeValueCreate_errors[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttributeValueCreate {
|
export interface AttributeValueCreate {
|
||||||
|
|
|
@ -2,18 +2,12 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { AttributeInputTypeEnum, AttributeValueType } from "./../../types/globalTypes";
|
import { AttributeInputTypeEnum, AttributeValueType, ProductErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: AttributeValueDelete
|
// GraphQL mutation operation: AttributeValueDelete
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface AttributeValueDelete_attributeValueDelete_errors {
|
|
||||||
__typename: "Error";
|
|
||||||
field: string | null;
|
|
||||||
message: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AttributeValueDelete_attributeValueDelete_attribute_values {
|
export interface AttributeValueDelete_attributeValueDelete_attribute_values {
|
||||||
__typename: "AttributeValue";
|
__typename: "AttributeValue";
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -37,10 +31,16 @@ export interface AttributeValueDelete_attributeValueDelete_attribute {
|
||||||
values: (AttributeValueDelete_attributeValueDelete_attribute_values | null)[] | null;
|
values: (AttributeValueDelete_attributeValueDelete_attribute_values | null)[] | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AttributeValueDelete_attributeValueDelete_errors {
|
||||||
|
__typename: "ProductError";
|
||||||
|
code: ProductErrorCode;
|
||||||
|
field: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface AttributeValueDelete_attributeValueDelete {
|
export interface AttributeValueDelete_attributeValueDelete {
|
||||||
__typename: "AttributeValueDelete";
|
__typename: "AttributeValueDelete";
|
||||||
errors: AttributeValueDelete_attributeValueDelete_errors[];
|
|
||||||
attribute: AttributeValueDelete_attributeValueDelete_attribute | null;
|
attribute: AttributeValueDelete_attributeValueDelete_attribute | null;
|
||||||
|
errors: AttributeValueDelete_attributeValueDelete_errors[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttributeValueDelete {
|
export interface AttributeValueDelete {
|
||||||
|
|
|
@ -2,18 +2,12 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ReorderInput } from "./../../types/globalTypes";
|
import { ReorderInput, ProductErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: AttributeValueReorder
|
// GraphQL mutation operation: AttributeValueReorder
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface AttributeValueReorder_attributeReorderValues_errors {
|
|
||||||
__typename: "Error";
|
|
||||||
field: string | null;
|
|
||||||
message: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AttributeValueReorder_attributeReorderValues_attribute_values {
|
export interface AttributeValueReorder_attributeReorderValues_attribute_values {
|
||||||
__typename: "AttributeValue";
|
__typename: "AttributeValue";
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -25,10 +19,16 @@ export interface AttributeValueReorder_attributeReorderValues_attribute {
|
||||||
values: (AttributeValueReorder_attributeReorderValues_attribute_values | null)[] | null;
|
values: (AttributeValueReorder_attributeReorderValues_attribute_values | null)[] | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AttributeValueReorder_attributeReorderValues_errors {
|
||||||
|
__typename: "ProductError";
|
||||||
|
code: ProductErrorCode;
|
||||||
|
field: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface AttributeValueReorder_attributeReorderValues {
|
export interface AttributeValueReorder_attributeReorderValues {
|
||||||
__typename: "AttributeReorderValues";
|
__typename: "AttributeReorderValues";
|
||||||
errors: AttributeValueReorder_attributeReorderValues_errors[];
|
|
||||||
attribute: AttributeValueReorder_attributeReorderValues_attribute | null;
|
attribute: AttributeValueReorder_attributeReorderValues_attribute | null;
|
||||||
|
errors: AttributeValueReorder_attributeReorderValues_errors[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttributeValueReorder {
|
export interface AttributeValueReorder {
|
||||||
|
|
|
@ -2,18 +2,12 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { AttributeValueCreateInput, AttributeInputTypeEnum, AttributeValueType } from "./../../types/globalTypes";
|
import { AttributeValueCreateInput, AttributeInputTypeEnum, AttributeValueType, ProductErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: AttributeValueUpdate
|
// GraphQL mutation operation: AttributeValueUpdate
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface AttributeValueUpdate_attributeValueUpdate_errors {
|
|
||||||
__typename: "Error";
|
|
||||||
field: string | null;
|
|
||||||
message: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AttributeValueUpdate_attributeValueUpdate_attribute_values {
|
export interface AttributeValueUpdate_attributeValueUpdate_attribute_values {
|
||||||
__typename: "AttributeValue";
|
__typename: "AttributeValue";
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -37,10 +31,16 @@ export interface AttributeValueUpdate_attributeValueUpdate_attribute {
|
||||||
values: (AttributeValueUpdate_attributeValueUpdate_attribute_values | null)[] | null;
|
values: (AttributeValueUpdate_attributeValueUpdate_attribute_values | null)[] | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AttributeValueUpdate_attributeValueUpdate_errors {
|
||||||
|
__typename: "ProductError";
|
||||||
|
code: ProductErrorCode;
|
||||||
|
field: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface AttributeValueUpdate_attributeValueUpdate {
|
export interface AttributeValueUpdate_attributeValueUpdate {
|
||||||
__typename: "AttributeValueUpdate";
|
__typename: "AttributeValueUpdate";
|
||||||
errors: AttributeValueUpdate_attributeValueUpdate_errors[];
|
|
||||||
attribute: AttributeValueUpdate_attributeValueUpdate_attribute | null;
|
attribute: AttributeValueUpdate_attributeValueUpdate_attribute | null;
|
||||||
|
errors: AttributeValueUpdate_attributeValueUpdate_errors[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttributeValueUpdate {
|
export interface AttributeValueUpdate {
|
||||||
|
|
15
src/attributes/types/ProductErrorFragment.ts
Normal file
15
src/attributes/types/ProductErrorFragment.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { ProductErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
|
// ====================================================
|
||||||
|
// GraphQL fragment: ProductErrorFragment
|
||||||
|
// ====================================================
|
||||||
|
|
||||||
|
export interface ProductErrorFragment {
|
||||||
|
__typename: "ProductError";
|
||||||
|
code: ProductErrorCode;
|
||||||
|
field: string | null;
|
||||||
|
}
|
|
@ -5,7 +5,7 @@ import slugify from "slugify";
|
||||||
import useNavigator from "@saleor/hooks/useNavigator";
|
import useNavigator from "@saleor/hooks/useNavigator";
|
||||||
import useNotifier from "@saleor/hooks/useNotifier";
|
import useNotifier from "@saleor/hooks/useNotifier";
|
||||||
import { maybe } from "@saleor/misc";
|
import { maybe } from "@saleor/misc";
|
||||||
import { ReorderEvent, UserError } from "@saleor/types";
|
import { ReorderEvent } from "@saleor/types";
|
||||||
import {
|
import {
|
||||||
add,
|
add,
|
||||||
isSelected,
|
isSelected,
|
||||||
|
@ -14,6 +14,8 @@ import {
|
||||||
updateAtIndex
|
updateAtIndex
|
||||||
} from "@saleor/utils/lists";
|
} from "@saleor/utils/lists";
|
||||||
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||||
|
import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment";
|
||||||
|
import { ProductErrorCode } from "@saleor/types/globalTypes";
|
||||||
import AttributePage from "../../components/AttributePage";
|
import AttributePage from "../../components/AttributePage";
|
||||||
import AttributeValueDeleteDialog from "../../components/AttributeValueDeleteDialog";
|
import AttributeValueDeleteDialog from "../../components/AttributeValueDeleteDialog";
|
||||||
import AttributeValueEditDialog, {
|
import AttributeValueEditDialog, {
|
||||||
|
@ -33,6 +35,12 @@ interface AttributeDetailsProps {
|
||||||
params: AttributeAddUrlQueryParams;
|
params: AttributeAddUrlQueryParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const attributeValueAlreadyExistsError: ProductErrorFragment = {
|
||||||
|
__typename: "ProductError",
|
||||||
|
code: ProductErrorCode.ALREADY_EXISTS,
|
||||||
|
field: "name"
|
||||||
|
};
|
||||||
|
|
||||||
function areValuesEqual(
|
function areValuesEqual(
|
||||||
a: AttributeValueEditDialogFormData,
|
a: AttributeValueEditDialogFormData,
|
||||||
b: AttributeValueEditDialogFormData
|
b: AttributeValueEditDialogFormData
|
||||||
|
@ -48,7 +56,9 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ params }) => {
|
||||||
const [values, setValues] = React.useState<
|
const [values, setValues] = React.useState<
|
||||||
AttributeValueEditDialogFormData[]
|
AttributeValueEditDialogFormData[]
|
||||||
>([]);
|
>([]);
|
||||||
const [valueErrors, setValueErrors] = React.useState<UserError[]>([]);
|
const [valueErrors, setValueErrors] = React.useState<ProductErrorFragment[]>(
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
const id = params.id ? parseInt(params.id, 0) : undefined;
|
const id = params.id ? parseInt(params.id, 0) : undefined;
|
||||||
|
|
||||||
|
@ -57,6 +67,8 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ params }) => {
|
||||||
AttributeAddUrlQueryParams
|
AttributeAddUrlQueryParams
|
||||||
>(navigate, attributeAddUrl, params);
|
>(navigate, attributeAddUrl, params);
|
||||||
|
|
||||||
|
React.useEffect(() => setValueErrors([]), [params.action]);
|
||||||
|
|
||||||
const handleValueDelete = () => {
|
const handleValueDelete = () => {
|
||||||
setValues(remove(values[params.id], values, areValuesEqual));
|
setValues(remove(values[params.id], values, areValuesEqual));
|
||||||
closeModal();
|
closeModal();
|
||||||
|
@ -73,20 +85,7 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ params }) => {
|
||||||
};
|
};
|
||||||
const handleValueUpdate = (input: AttributeValueEditDialogFormData) => {
|
const handleValueUpdate = (input: AttributeValueEditDialogFormData) => {
|
||||||
if (isSelected(input, values, areValuesEqual)) {
|
if (isSelected(input, values, areValuesEqual)) {
|
||||||
setValueErrors([
|
setValueErrors([attributeValueAlreadyExistsError]);
|
||||||
{
|
|
||||||
field: "name",
|
|
||||||
message: intl.formatMessage(
|
|
||||||
{
|
|
||||||
defaultMessage: "A value named {name} already exists",
|
|
||||||
description: "attribute value edit error"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: input.name
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
} else {
|
} else {
|
||||||
setValues(updateAtIndex(input, values, id));
|
setValues(updateAtIndex(input, values, id));
|
||||||
closeModal();
|
closeModal();
|
||||||
|
@ -94,20 +93,7 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ params }) => {
|
||||||
};
|
};
|
||||||
const handleValueCreate = (input: AttributeValueEditDialogFormData) => {
|
const handleValueCreate = (input: AttributeValueEditDialogFormData) => {
|
||||||
if (isSelected(input, values, areValuesEqual)) {
|
if (isSelected(input, values, areValuesEqual)) {
|
||||||
setValueErrors([
|
setValueErrors([attributeValueAlreadyExistsError]);
|
||||||
{
|
|
||||||
field: "name",
|
|
||||||
message: intl.formatMessage(
|
|
||||||
{
|
|
||||||
defaultMessage: "A value named {name} already exists",
|
|
||||||
description: "attribute value edit error"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: input.name
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
} else {
|
} else {
|
||||||
setValues(add(input, values));
|
setValues(add(input, values));
|
||||||
closeModal();
|
closeModal();
|
||||||
|
@ -123,10 +109,7 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ params }) => {
|
||||||
<AttributePage
|
<AttributePage
|
||||||
attribute={null}
|
attribute={null}
|
||||||
disabled={false}
|
disabled={false}
|
||||||
errors={maybe(
|
errors={attributeCreateOpts.data?.attributeCreate.errors || []}
|
||||||
() => attributeCreateOpts.data.attributeCreate.errors,
|
|
||||||
[]
|
|
||||||
)}
|
|
||||||
onBack={() => navigate(attributeListUrl())}
|
onBack={() => navigate(attributeListUrl())}
|
||||||
onDelete={undefined}
|
onDelete={undefined}
|
||||||
onSubmit={input =>
|
onSubmit={input =>
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { maybe } from "@saleor/misc";
|
||||||
import { ReorderEvent } from "@saleor/types";
|
import { ReorderEvent } from "@saleor/types";
|
||||||
import { move } from "@saleor/utils/lists";
|
import { move } from "@saleor/utils/lists";
|
||||||
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||||
|
import { getProductErrorMessage } from "@saleor/utils/errors";
|
||||||
import AttributeDeleteDialog from "../../components/AttributeDeleteDialog";
|
import AttributeDeleteDialog from "../../components/AttributeDeleteDialog";
|
||||||
import AttributePage from "../../components/AttributePage";
|
import AttributePage from "../../components/AttributePage";
|
||||||
import AttributeValueDeleteDialog from "../../components/AttributeValueDeleteDialog";
|
import AttributeValueDeleteDialog from "../../components/AttributeValueDeleteDialog";
|
||||||
|
@ -95,7 +96,10 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ id, params }) => {
|
||||||
const handleValueReorderMutation = (data: AttributeValueReorder) => {
|
const handleValueReorderMutation = (data: AttributeValueReorder) => {
|
||||||
if (data.attributeReorderValues.errors.length !== 0) {
|
if (data.attributeReorderValues.errors.length !== 0) {
|
||||||
notify({
|
notify({
|
||||||
text: data.attributeReorderValues.errors[0].message
|
text: getProductErrorMessage(
|
||||||
|
data.attributeReorderValues.errors[0],
|
||||||
|
intl
|
||||||
|
)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -155,12 +159,10 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ id, params }) => {
|
||||||
<AttributePage
|
<AttributePage
|
||||||
attribute={maybe(() => data.attribute)}
|
attribute={maybe(() => data.attribute)}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
errors={maybe(
|
errors={
|
||||||
() =>
|
attributeUpdateOpts.data
|
||||||
attributeUpdateOpts.data
|
?.attributeUpdate.errors || []
|
||||||
.attributeUpdate.errors,
|
}
|
||||||
[]
|
|
||||||
)}
|
|
||||||
onBack={() =>
|
onBack={() =>
|
||||||
navigate(attributeListUrl())
|
navigate(attributeListUrl())
|
||||||
}
|
}
|
||||||
|
@ -253,12 +255,10 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ id, params }) => {
|
||||||
attributeValueCreateOpts.status
|
attributeValueCreateOpts.status
|
||||||
}
|
}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
errors={maybe(
|
errors={
|
||||||
() =>
|
attributeValueCreateOpts.data
|
||||||
attributeValueCreateOpts.data
|
?.attributeValueCreate.errors || []
|
||||||
.attributeValueCreate.errors,
|
}
|
||||||
[]
|
|
||||||
)}
|
|
||||||
open={params.action === "add-value"}
|
open={params.action === "add-value"}
|
||||||
onClose={closeModal}
|
onClose={closeModal}
|
||||||
onSubmit={input =>
|
onSubmit={input =>
|
||||||
|
@ -280,12 +280,10 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ id, params }) => {
|
||||||
attributeValueUpdateOpts.status
|
attributeValueUpdateOpts.status
|
||||||
}
|
}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
errors={maybe(
|
errors={
|
||||||
() =>
|
attributeValueUpdateOpts.data
|
||||||
attributeValueUpdateOpts.data
|
?.attributeValueUpdate.errors || []
|
||||||
.attributeValueUpdate.errors,
|
}
|
||||||
[]
|
|
||||||
)}
|
|
||||||
open={params.action === "edit-value"}
|
open={params.action === "edit-value"}
|
||||||
onClose={closeModal}
|
onClose={closeModal}
|
||||||
onSubmit={input =>
|
onSubmit={input =>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import gql from "graphql-tag";
|
import gql from "graphql-tag";
|
||||||
|
|
||||||
|
import { accountFragmentError } from "@saleor/customers/mutations";
|
||||||
import { TypedMutation } from "../mutations";
|
import { TypedMutation } from "../mutations";
|
||||||
import {
|
import {
|
||||||
RequestPasswordReset,
|
RequestPasswordReset,
|
||||||
|
@ -64,11 +65,11 @@ export const TypedVerifyTokenMutation = TypedMutation<
|
||||||
>(tokenVerifyMutation);
|
>(tokenVerifyMutation);
|
||||||
|
|
||||||
export const requestPasswordReset = gql`
|
export const requestPasswordReset = gql`
|
||||||
|
${accountFragmentError}
|
||||||
mutation RequestPasswordReset($email: String!, $redirectUrl: String!) {
|
mutation RequestPasswordReset($email: String!, $redirectUrl: String!) {
|
||||||
requestPasswordReset(email: $email, redirectUrl: $redirectUrl) {
|
requestPasswordReset(email: $email, redirectUrl: $redirectUrl) {
|
||||||
errors {
|
errors: accountErrors {
|
||||||
field
|
...AccountErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,14 +80,14 @@ export const RequestPasswordResetMutation = TypedMutation<
|
||||||
>(requestPasswordReset);
|
>(requestPasswordReset);
|
||||||
|
|
||||||
export const setPassword = gql`
|
export const setPassword = gql`
|
||||||
|
${accountFragmentError}
|
||||||
${fragmentUser}
|
${fragmentUser}
|
||||||
mutation SetPassword($email: String!, $password: String!, $token: String!) {
|
mutation SetPassword($email: String!, $password: String!, $token: String!) {
|
||||||
setPassword(email: $email, password: $password, token: $token) {
|
setPassword(email: $email, password: $password, token: $token) {
|
||||||
token
|
errors: accountErrors {
|
||||||
errors {
|
...AccountErrorFragment
|
||||||
field
|
|
||||||
message
|
|
||||||
}
|
}
|
||||||
|
token
|
||||||
user {
|
user {
|
||||||
...User
|
...User
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { AccountErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: RequestPasswordReset
|
// GraphQL mutation operation: RequestPasswordReset
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface RequestPasswordReset_requestPasswordReset_errors {
|
export interface RequestPasswordReset_requestPasswordReset_errors {
|
||||||
__typename: "Error";
|
__typename: "AccountError";
|
||||||
|
code: AccountErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RequestPasswordReset_requestPasswordReset {
|
export interface RequestPasswordReset_requestPasswordReset {
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { PermissionEnum } from "./../../types/globalTypes";
|
import { AccountErrorCode, PermissionEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: SetPassword
|
// GraphQL mutation operation: SetPassword
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface SetPassword_setPassword_errors {
|
export interface SetPassword_setPassword_errors {
|
||||||
__typename: "Error";
|
__typename: "AccountError";
|
||||||
|
code: AccountErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SetPassword_setPassword_user_permissions {
|
export interface SetPassword_setPassword_user_permissions {
|
||||||
|
@ -37,8 +37,8 @@ export interface SetPassword_setPassword_user {
|
||||||
|
|
||||||
export interface SetPassword_setPassword {
|
export interface SetPassword_setPassword {
|
||||||
__typename: "SetPassword";
|
__typename: "SetPassword";
|
||||||
|
errors: SetPassword_setPassword_errors[] | null;
|
||||||
token: string | null;
|
token: string | null;
|
||||||
errors: (SetPassword_setPassword_errors | null)[];
|
|
||||||
user: SetPassword_setPassword_user | null;
|
user: SetPassword_setPassword_user | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import PageHeader from "@saleor/components/PageHeader";
|
||||||
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
||||||
import SeoForm from "@saleor/components/SeoForm";
|
import SeoForm from "@saleor/components/SeoForm";
|
||||||
import { sectionNames } from "@saleor/intl";
|
import { sectionNames } from "@saleor/intl";
|
||||||
import { UserError } from "../../../types";
|
import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment";
|
||||||
import CategoryDetailsForm from "../../components/CategoryDetailsForm";
|
import CategoryDetailsForm from "../../components/CategoryDetailsForm";
|
||||||
|
|
||||||
interface FormData {
|
interface FormData {
|
||||||
|
@ -29,7 +29,7 @@ const initialData: FormData = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface CategoryCreatePageProps {
|
export interface CategoryCreatePageProps {
|
||||||
errors: UserError[];
|
errors: ProductErrorFragment[];
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
saveButtonBarState: ConfirmButtonTransitionState;
|
saveButtonBarState: ConfirmButtonTransitionState;
|
||||||
onSubmit(data: FormData);
|
onSubmit(data: FormData);
|
||||||
|
|
|
@ -9,8 +9,8 @@ import CardTitle from "@saleor/components/CardTitle";
|
||||||
import FormSpacer from "@saleor/components/FormSpacer";
|
import FormSpacer from "@saleor/components/FormSpacer";
|
||||||
import RichTextEditor from "@saleor/components/RichTextEditor";
|
import RichTextEditor from "@saleor/components/RichTextEditor";
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
import { UserError } from "@saleor/types";
|
import { getFormErrors, getProductErrorMessage } from "@saleor/utils/errors";
|
||||||
import { getFieldError } from "@saleor/utils/errors";
|
import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment";
|
||||||
import { maybe } from "../../../misc";
|
import { maybe } from "../../../misc";
|
||||||
import { CategoryDetails_category } from "../../types/CategoryDetails";
|
import { CategoryDetails_category } from "../../types/CategoryDetails";
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ interface CategoryDetailsFormProps {
|
||||||
description: RawDraftContentState;
|
description: RawDraftContentState;
|
||||||
};
|
};
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: ProductErrorFragment[];
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
onChange: (event: React.ChangeEvent<any>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,8 @@ export const CategoryDetailsForm: React.FC<CategoryDetailsFormProps> = ({
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const formErrors = getFormErrors(["name", "descriptionJson"], errors);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
|
@ -49,16 +51,16 @@ export const CategoryDetailsForm: React.FC<CategoryDetailsFormProps> = ({
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
value={data && data.name}
|
value={data && data.name}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
error={!!getFieldError(errors, "name")}
|
error={!!formErrors.name}
|
||||||
helperText={getFieldError(errors, "name")?.message}
|
helperText={getProductErrorMessage(formErrors.name, intl)}
|
||||||
fullWidth
|
fullWidth
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<FormSpacer />
|
<FormSpacer />
|
||||||
<RichTextEditor
|
<RichTextEditor
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "descriptionJson")}
|
error={!!formErrors.descriptionJson}
|
||||||
helperText={getFieldError(errors, "descriptionJson")?.message}
|
helperText={getProductErrorMessage(formErrors.descriptionJson, intl)}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Category Description"
|
defaultMessage: "Category Description"
|
||||||
})}
|
})}
|
||||||
|
|
|
@ -15,8 +15,9 @@ import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
||||||
import SeoForm from "@saleor/components/SeoForm";
|
import SeoForm from "@saleor/components/SeoForm";
|
||||||
import { Tab, TabContainer } from "@saleor/components/Tab";
|
import { Tab, TabContainer } from "@saleor/components/Tab";
|
||||||
import { sectionNames } from "@saleor/intl";
|
import { sectionNames } from "@saleor/intl";
|
||||||
|
import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment";
|
||||||
import { maybe } from "../../../misc";
|
import { maybe } from "../../../misc";
|
||||||
import { TabListActions, UserError } from "../../../types";
|
import { TabListActions } from "../../../types";
|
||||||
import CategoryDetailsForm from "../../components/CategoryDetailsForm";
|
import CategoryDetailsForm from "../../components/CategoryDetailsForm";
|
||||||
import CategoryList from "../../components/CategoryList";
|
import CategoryList from "../../components/CategoryList";
|
||||||
import {
|
import {
|
||||||
|
@ -44,7 +45,7 @@ export interface CategoryUpdatePageProps
|
||||||
extends TabListActions<"productListToolbar" | "subcategoryListToolbar"> {
|
extends TabListActions<"productListToolbar" | "subcategoryListToolbar"> {
|
||||||
changeTab: (index: CategoryPageTab) => void;
|
changeTab: (index: CategoryPageTab) => void;
|
||||||
currentTab: CategoryPageTab;
|
currentTab: CategoryPageTab;
|
||||||
errors: UserError[];
|
errors: ProductErrorFragment[];
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
category: CategoryDetails_category;
|
category: CategoryDetails_category;
|
||||||
products: CategoryDetails_category_products_edges_node[];
|
products: CategoryDetails_category_products_edges_node[];
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import gql from "graphql-tag";
|
import gql from "graphql-tag";
|
||||||
|
|
||||||
import makeMutation from "@saleor/hooks/makeMutation";
|
import makeMutation from "@saleor/hooks/makeMutation";
|
||||||
|
import { productErrorFragment } from "@saleor/attributes/mutations";
|
||||||
import { categoryDetailsFragment } from "./queries";
|
import { categoryDetailsFragment } from "./queries";
|
||||||
import {
|
import {
|
||||||
CategoryBulkDelete,
|
CategoryBulkDelete,
|
||||||
|
@ -20,11 +21,11 @@ import {
|
||||||
} from "./types/CategoryUpdate";
|
} from "./types/CategoryUpdate";
|
||||||
|
|
||||||
export const categoryDeleteMutation = gql`
|
export const categoryDeleteMutation = gql`
|
||||||
|
${productErrorFragment}
|
||||||
mutation CategoryDelete($id: ID!) {
|
mutation CategoryDelete($id: ID!) {
|
||||||
categoryDelete(id: $id) {
|
categoryDelete(id: $id) {
|
||||||
errors {
|
errors: productErrors {
|
||||||
field
|
...ProductErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,15 +37,15 @@ export const useCategoryDeleteMutation = makeMutation<
|
||||||
|
|
||||||
export const categoryCreateMutation = gql`
|
export const categoryCreateMutation = gql`
|
||||||
${categoryDetailsFragment}
|
${categoryDetailsFragment}
|
||||||
|
${productErrorFragment}
|
||||||
mutation CategoryCreate($parent: ID, $input: CategoryInput!) {
|
mutation CategoryCreate($parent: ID, $input: CategoryInput!) {
|
||||||
categoryCreate(parent: $parent, input: $input) {
|
categoryCreate(parent: $parent, input: $input) {
|
||||||
errors {
|
|
||||||
field
|
|
||||||
message
|
|
||||||
}
|
|
||||||
category {
|
category {
|
||||||
...CategoryDetailsFragment
|
...CategoryDetailsFragment
|
||||||
}
|
}
|
||||||
|
errors: productErrors {
|
||||||
|
...ProductErrorFragment
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -55,15 +56,15 @@ export const useCategoryCreateMutation = makeMutation<
|
||||||
|
|
||||||
export const categoryUpdateMutation = gql`
|
export const categoryUpdateMutation = gql`
|
||||||
${categoryDetailsFragment}
|
${categoryDetailsFragment}
|
||||||
|
${productErrorFragment}
|
||||||
mutation CategoryUpdate($id: ID!, $input: CategoryInput!) {
|
mutation CategoryUpdate($id: ID!, $input: CategoryInput!) {
|
||||||
categoryUpdate(id: $id, input: $input) {
|
categoryUpdate(id: $id, input: $input) {
|
||||||
errors {
|
|
||||||
field
|
|
||||||
message
|
|
||||||
}
|
|
||||||
category {
|
category {
|
||||||
...CategoryDetailsFragment
|
...CategoryDetailsFragment
|
||||||
}
|
}
|
||||||
|
errors: productErrors {
|
||||||
|
...ProductErrorFragment
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -73,11 +74,11 @@ export const useCategoryUpdateMutation = makeMutation<
|
||||||
>(categoryUpdateMutation);
|
>(categoryUpdateMutation);
|
||||||
|
|
||||||
export const categoryBulkDeleteMutation = gql`
|
export const categoryBulkDeleteMutation = gql`
|
||||||
|
${productErrorFragment}
|
||||||
mutation CategoryBulkDelete($ids: [ID]!) {
|
mutation CategoryBulkDelete($ids: [ID]!) {
|
||||||
categoryBulkDelete(ids: $ids) {
|
categoryBulkDelete(ids: $ids) {
|
||||||
errors {
|
errors: productErrors {
|
||||||
field
|
...ProductErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { ProductErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: CategoryBulkDelete
|
// GraphQL mutation operation: CategoryBulkDelete
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface CategoryBulkDelete_categoryBulkDelete_errors {
|
export interface CategoryBulkDelete_categoryBulkDelete_errors {
|
||||||
__typename: "Error";
|
__typename: "ProductError";
|
||||||
|
code: ProductErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CategoryBulkDelete_categoryBulkDelete {
|
export interface CategoryBulkDelete_categoryBulkDelete {
|
||||||
|
|
|
@ -2,18 +2,12 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { CategoryInput } from "./../../types/globalTypes";
|
import { CategoryInput, ProductErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: CategoryCreate
|
// GraphQL mutation operation: CategoryCreate
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface CategoryCreate_categoryCreate_errors {
|
|
||||||
__typename: "Error";
|
|
||||||
field: string | null;
|
|
||||||
message: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CategoryCreate_categoryCreate_category_backgroundImage {
|
export interface CategoryCreate_categoryCreate_category_backgroundImage {
|
||||||
__typename: "Image";
|
__typename: "Image";
|
||||||
alt: string | null;
|
alt: string | null;
|
||||||
|
@ -36,10 +30,16 @@ export interface CategoryCreate_categoryCreate_category {
|
||||||
parent: CategoryCreate_categoryCreate_category_parent | null;
|
parent: CategoryCreate_categoryCreate_category_parent | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CategoryCreate_categoryCreate_errors {
|
||||||
|
__typename: "ProductError";
|
||||||
|
code: ProductErrorCode;
|
||||||
|
field: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface CategoryCreate_categoryCreate {
|
export interface CategoryCreate_categoryCreate {
|
||||||
__typename: "CategoryCreate";
|
__typename: "CategoryCreate";
|
||||||
errors: CategoryCreate_categoryCreate_errors[];
|
|
||||||
category: CategoryCreate_categoryCreate_category | null;
|
category: CategoryCreate_categoryCreate_category | null;
|
||||||
|
errors: CategoryCreate_categoryCreate_errors[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CategoryCreate {
|
export interface CategoryCreate {
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { ProductErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: CategoryDelete
|
// GraphQL mutation operation: CategoryDelete
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface CategoryDelete_categoryDelete_errors {
|
export interface CategoryDelete_categoryDelete_errors {
|
||||||
__typename: "Error";
|
__typename: "ProductError";
|
||||||
|
code: ProductErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CategoryDelete_categoryDelete {
|
export interface CategoryDelete_categoryDelete {
|
||||||
|
|
|
@ -2,18 +2,12 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { CategoryInput } from "./../../types/globalTypes";
|
import { CategoryInput, ProductErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: CategoryUpdate
|
// GraphQL mutation operation: CategoryUpdate
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface CategoryUpdate_categoryUpdate_errors {
|
|
||||||
__typename: "Error";
|
|
||||||
field: string | null;
|
|
||||||
message: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CategoryUpdate_categoryUpdate_category_backgroundImage {
|
export interface CategoryUpdate_categoryUpdate_category_backgroundImage {
|
||||||
__typename: "Image";
|
__typename: "Image";
|
||||||
alt: string | null;
|
alt: string | null;
|
||||||
|
@ -36,10 +30,16 @@ export interface CategoryUpdate_categoryUpdate_category {
|
||||||
parent: CategoryUpdate_categoryUpdate_category_parent | null;
|
parent: CategoryUpdate_categoryUpdate_category_parent | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CategoryUpdate_categoryUpdate_errors {
|
||||||
|
__typename: "ProductError";
|
||||||
|
code: ProductErrorCode;
|
||||||
|
field: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface CategoryUpdate_categoryUpdate {
|
export interface CategoryUpdate_categoryUpdate {
|
||||||
__typename: "CategoryUpdate";
|
__typename: "CategoryUpdate";
|
||||||
errors: CategoryUpdate_categoryUpdate_errors[];
|
|
||||||
category: CategoryUpdate_categoryUpdate_category | null;
|
category: CategoryUpdate_categoryUpdate_category | null;
|
||||||
|
errors: CategoryUpdate_categoryUpdate_errors[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CategoryUpdate {
|
export interface CategoryUpdate {
|
||||||
|
|
|
@ -99,7 +99,7 @@ export const CategoryDetails: React.FC<CategoryDetailsProps> = ({
|
||||||
);
|
);
|
||||||
if (backgroundImageError) {
|
if (backgroundImageError) {
|
||||||
notify({
|
notify({
|
||||||
text: backgroundImageError.message
|
text: intl.formatMessage(commonMessages.somethingWentWrong)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ import SeoForm from "@saleor/components/SeoForm";
|
||||||
import VisibilityCard from "@saleor/components/VisibilityCard";
|
import VisibilityCard from "@saleor/components/VisibilityCard";
|
||||||
import useDateLocalize from "@saleor/hooks/useDateLocalize";
|
import useDateLocalize from "@saleor/hooks/useDateLocalize";
|
||||||
import { commonMessages, sectionNames } from "@saleor/intl";
|
import { commonMessages, sectionNames } from "@saleor/intl";
|
||||||
import { UserError } from "../../../types";
|
import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment";
|
||||||
import CollectionDetails from "../CollectionDetails/CollectionDetails";
|
import CollectionDetails from "../CollectionDetails/CollectionDetails";
|
||||||
import { CollectionImage } from "../CollectionImage/CollectionImage";
|
import { CollectionImage } from "../CollectionImage/CollectionImage";
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ export interface CollectionCreatePageFormData {
|
||||||
|
|
||||||
export interface CollectionCreatePageProps {
|
export interface CollectionCreatePageProps {
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: ProductErrorFragment[];
|
||||||
saveButtonBarState: ConfirmButtonTransitionState;
|
saveButtonBarState: ConfirmButtonTransitionState;
|
||||||
onBack: () => void;
|
onBack: () => void;
|
||||||
onSubmit: (data: CollectionCreatePageFormData) => void;
|
onSubmit: (data: CollectionCreatePageFormData) => void;
|
||||||
|
|
|
@ -10,8 +10,8 @@ import FormSpacer from "@saleor/components/FormSpacer";
|
||||||
import RichTextEditor from "@saleor/components/RichTextEditor";
|
import RichTextEditor from "@saleor/components/RichTextEditor";
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
import { maybe } from "@saleor/misc";
|
import { maybe } from "@saleor/misc";
|
||||||
import { UserError } from "@saleor/types";
|
import { getProductErrorMessage, getFormErrors } from "@saleor/utils/errors";
|
||||||
import { getFieldError } from "@saleor/utils/errors";
|
import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment";
|
||||||
import { CollectionDetails_collection } from "../../types/CollectionDetails";
|
import { CollectionDetails_collection } from "../../types/CollectionDetails";
|
||||||
|
|
||||||
export interface CollectionDetailsProps {
|
export interface CollectionDetailsProps {
|
||||||
|
@ -21,7 +21,7 @@ export interface CollectionDetailsProps {
|
||||||
name: string;
|
name: string;
|
||||||
};
|
};
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: ProductErrorFragment[];
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
onChange: (event: React.ChangeEvent<any>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,8 @@ const CollectionDetails: React.FC<CollectionDetailsProps> = ({
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const formErrors = getFormErrors(["name", "descriptionJson"], errors);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
|
@ -49,14 +51,14 @@ const CollectionDetails: React.FC<CollectionDetailsProps> = ({
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
value={data.name}
|
value={data.name}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
error={!!getFieldError(errors, "name")}
|
error={!!formErrors.name}
|
||||||
helperText={getFieldError(errors, "name")?.message}
|
helperText={getProductErrorMessage(formErrors.name, intl)}
|
||||||
fullWidth
|
fullWidth
|
||||||
/>
|
/>
|
||||||
<FormSpacer />
|
<FormSpacer />
|
||||||
<RichTextEditor
|
<RichTextEditor
|
||||||
error={!!getFieldError(errors, "descriptionJson")}
|
error={!!formErrors.descriptionJson}
|
||||||
helperText={getFieldError(errors, "descriptionJson")?.message}
|
helperText={getProductErrorMessage(formErrors.descriptionJson, intl)}
|
||||||
initial={maybe(() => JSON.parse(collection.descriptionJson))}
|
initial={maybe(() => JSON.parse(collection.descriptionJson))}
|
||||||
label={intl.formatMessage(commonMessages.description)}
|
label={intl.formatMessage(commonMessages.description)}
|
||||||
name="description"
|
name="description"
|
||||||
|
|
|
@ -17,8 +17,9 @@ import SeoForm from "@saleor/components/SeoForm";
|
||||||
import VisibilityCard from "@saleor/components/VisibilityCard";
|
import VisibilityCard from "@saleor/components/VisibilityCard";
|
||||||
import useDateLocalize from "@saleor/hooks/useDateLocalize";
|
import useDateLocalize from "@saleor/hooks/useDateLocalize";
|
||||||
import { sectionNames } from "@saleor/intl";
|
import { sectionNames } from "@saleor/intl";
|
||||||
|
import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment";
|
||||||
import { maybe } from "../../../misc";
|
import { maybe } from "../../../misc";
|
||||||
import { ListActions, PageListProps, UserError } from "../../../types";
|
import { ListActions, PageListProps } from "../../../types";
|
||||||
import { CollectionDetails_collection } from "../../types/CollectionDetails";
|
import { CollectionDetails_collection } from "../../types/CollectionDetails";
|
||||||
import CollectionDetails from "../CollectionDetails/CollectionDetails";
|
import CollectionDetails from "../CollectionDetails/CollectionDetails";
|
||||||
import { CollectionImage } from "../CollectionImage/CollectionImage";
|
import { CollectionImage } from "../CollectionImage/CollectionImage";
|
||||||
|
@ -37,7 +38,7 @@ export interface CollectionDetailsPageFormData {
|
||||||
|
|
||||||
export interface CollectionDetailsPageProps extends PageListProps, ListActions {
|
export interface CollectionDetailsPageProps extends PageListProps, ListActions {
|
||||||
collection: CollectionDetails_collection;
|
collection: CollectionDetails_collection;
|
||||||
errors: UserError[];
|
errors: ProductErrorFragment[];
|
||||||
isFeatured: boolean;
|
isFeatured: boolean;
|
||||||
saveButtonBarState: ConfirmButtonTransitionState;
|
saveButtonBarState: ConfirmButtonTransitionState;
|
||||||
onBack: () => void;
|
onBack: () => void;
|
||||||
|
|
|
@ -54,6 +54,7 @@ interface CollectionUpdateOperationsProps {
|
||||||
>;
|
>;
|
||||||
}) => React.ReactNode;
|
}) => React.ReactNode;
|
||||||
onUpdate: (data: CollectionUpdate) => void;
|
onUpdate: (data: CollectionUpdate) => void;
|
||||||
|
onUpdateWithCollection: (data: CollectionUpdateWithHomepage) => void;
|
||||||
onProductAssign: (data: CollectionAssignProduct) => void;
|
onProductAssign: (data: CollectionAssignProduct) => void;
|
||||||
onProductUnassign: (data: UnassignCollectionProduct) => void;
|
onProductUnassign: (data: UnassignCollectionProduct) => void;
|
||||||
onRemove: (data: RemoveCollection) => void;
|
onRemove: (data: RemoveCollection) => void;
|
||||||
|
@ -62,6 +63,7 @@ interface CollectionUpdateOperationsProps {
|
||||||
const CollectionOperations: React.FC<CollectionUpdateOperationsProps> = ({
|
const CollectionOperations: React.FC<CollectionUpdateOperationsProps> = ({
|
||||||
children,
|
children,
|
||||||
onUpdate,
|
onUpdate,
|
||||||
|
onUpdateWithCollection,
|
||||||
onProductAssign,
|
onProductAssign,
|
||||||
onProductUnassign,
|
onProductUnassign,
|
||||||
onRemove
|
onRemove
|
||||||
|
@ -72,7 +74,9 @@ const CollectionOperations: React.FC<CollectionUpdateOperationsProps> = ({
|
||||||
{(...removeCollection) => (
|
{(...removeCollection) => (
|
||||||
<TypedCollectionAssignProductMutation onCompleted={onProductAssign}>
|
<TypedCollectionAssignProductMutation onCompleted={onProductAssign}>
|
||||||
{(...assignProduct) => (
|
{(...assignProduct) => (
|
||||||
<TypedCollectionUpdateWithHomepageMutation onCompleted={onUpdate}>
|
<TypedCollectionUpdateWithHomepageMutation
|
||||||
|
onCompleted={onUpdateWithCollection}
|
||||||
|
>
|
||||||
{(...updateWithHomepage) => (
|
{(...updateWithHomepage) => (
|
||||||
<TypedUnassignCollectionProductMutation
|
<TypedUnassignCollectionProductMutation
|
||||||
onCompleted={onProductUnassign}
|
onCompleted={onProductUnassign}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import gql from "graphql-tag";
|
import gql from "graphql-tag";
|
||||||
|
|
||||||
|
import { productErrorFragment } from "@saleor/attributes/mutations";
|
||||||
import { TypedMutation } from "../mutations";
|
import { TypedMutation } from "../mutations";
|
||||||
import {
|
import {
|
||||||
collectionDetailsFragment,
|
collectionDetailsFragment,
|
||||||
|
@ -38,17 +39,24 @@ import {
|
||||||
UnassignCollectionProductVariables
|
UnassignCollectionProductVariables
|
||||||
} from "./types/UnassignCollectionProduct";
|
} from "./types/UnassignCollectionProduct";
|
||||||
|
|
||||||
|
export const ShopErrorFragment = gql`
|
||||||
|
fragment ShopErrorFragment on ShopError {
|
||||||
|
code
|
||||||
|
field
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
const collectionUpdate = gql`
|
const collectionUpdate = gql`
|
||||||
${collectionDetailsFragment}
|
${collectionDetailsFragment}
|
||||||
|
${productErrorFragment}
|
||||||
mutation CollectionUpdate($id: ID!, $input: CollectionInput!) {
|
mutation CollectionUpdate($id: ID!, $input: CollectionInput!) {
|
||||||
collectionUpdate(id: $id, input: $input) {
|
collectionUpdate(id: $id, input: $input) {
|
||||||
errors {
|
|
||||||
field
|
|
||||||
message
|
|
||||||
}
|
|
||||||
collection {
|
collection {
|
||||||
...CollectionDetailsFragment
|
...CollectionDetailsFragment
|
||||||
}
|
}
|
||||||
|
errors: productErrors {
|
||||||
|
...ProductErrorFragment
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -59,15 +67,16 @@ export const TypedCollectionUpdateMutation = TypedMutation<
|
||||||
|
|
||||||
const collectionUpdateWithHomepage = gql`
|
const collectionUpdateWithHomepage = gql`
|
||||||
${collectionDetailsFragment}
|
${collectionDetailsFragment}
|
||||||
|
${productErrorFragment}
|
||||||
|
${ShopErrorFragment}
|
||||||
mutation CollectionUpdateWithHomepage(
|
mutation CollectionUpdateWithHomepage(
|
||||||
$id: ID!
|
$id: ID!
|
||||||
$input: CollectionInput!
|
$input: CollectionInput!
|
||||||
$homepageId: ID
|
$homepageId: ID
|
||||||
) {
|
) {
|
||||||
homepageCollectionUpdate(collection: $homepageId) {
|
homepageCollectionUpdate(collection: $homepageId) {
|
||||||
errors {
|
errors: shopErrors {
|
||||||
field
|
...ShopErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
shop {
|
shop {
|
||||||
homepageCollection {
|
homepageCollection {
|
||||||
|
@ -76,13 +85,12 @@ const collectionUpdateWithHomepage = gql`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
collectionUpdate(id: $id, input: $input) {
|
collectionUpdate(id: $id, input: $input) {
|
||||||
errors {
|
|
||||||
field
|
|
||||||
message
|
|
||||||
}
|
|
||||||
collection {
|
collection {
|
||||||
...CollectionDetailsFragment
|
...CollectionDetailsFragment
|
||||||
}
|
}
|
||||||
|
errors: productErrors {
|
||||||
|
...ProductErrorFragment
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -93,6 +101,7 @@ export const TypedCollectionUpdateWithHomepageMutation = TypedMutation<
|
||||||
|
|
||||||
const assignCollectionProduct = gql`
|
const assignCollectionProduct = gql`
|
||||||
${collectionProductFragment}
|
${collectionProductFragment}
|
||||||
|
${productErrorFragment}
|
||||||
mutation CollectionAssignProduct(
|
mutation CollectionAssignProduct(
|
||||||
$collectionId: ID!
|
$collectionId: ID!
|
||||||
$productIds: [ID!]!
|
$productIds: [ID!]!
|
||||||
|
@ -102,10 +111,6 @@ const assignCollectionProduct = gql`
|
||||||
$before: String
|
$before: String
|
||||||
) {
|
) {
|
||||||
collectionAddProducts(collectionId: $collectionId, products: $productIds) {
|
collectionAddProducts(collectionId: $collectionId, products: $productIds) {
|
||||||
errors {
|
|
||||||
field
|
|
||||||
message
|
|
||||||
}
|
|
||||||
collection {
|
collection {
|
||||||
id
|
id
|
||||||
products(first: $first, after: $after, before: $before, last: $last) {
|
products(first: $first, after: $after, before: $before, last: $last) {
|
||||||
|
@ -122,6 +127,9 @@ const assignCollectionProduct = gql`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
errors: productErrors {
|
||||||
|
...ProductErrorFragment
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -132,15 +140,15 @@ export const TypedCollectionAssignProductMutation = TypedMutation<
|
||||||
|
|
||||||
const createCollection = gql`
|
const createCollection = gql`
|
||||||
${collectionDetailsFragment}
|
${collectionDetailsFragment}
|
||||||
|
${productErrorFragment}
|
||||||
mutation CreateCollection($input: CollectionCreateInput!) {
|
mutation CreateCollection($input: CollectionCreateInput!) {
|
||||||
collectionCreate(input: $input) {
|
collectionCreate(input: $input) {
|
||||||
errors {
|
|
||||||
field
|
|
||||||
message
|
|
||||||
}
|
|
||||||
collection {
|
collection {
|
||||||
...CollectionDetailsFragment
|
...CollectionDetailsFragment
|
||||||
}
|
}
|
||||||
|
errors: productErrors {
|
||||||
|
...ProductErrorFragment
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -150,11 +158,11 @@ export const TypedCollectionCreateMutation = TypedMutation<
|
||||||
>(createCollection);
|
>(createCollection);
|
||||||
|
|
||||||
const removeCollection = gql`
|
const removeCollection = gql`
|
||||||
|
${productErrorFragment}
|
||||||
mutation RemoveCollection($id: ID!) {
|
mutation RemoveCollection($id: ID!) {
|
||||||
collectionDelete(id: $id) {
|
collectionDelete(id: $id) {
|
||||||
errors {
|
errors: productErrors {
|
||||||
field
|
...ProductErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,6 +173,7 @@ export const TypedCollectionRemoveMutation = TypedMutation<
|
||||||
>(removeCollection);
|
>(removeCollection);
|
||||||
|
|
||||||
const unassignCollectionProduct = gql`
|
const unassignCollectionProduct = gql`
|
||||||
|
${productErrorFragment}
|
||||||
mutation UnassignCollectionProduct(
|
mutation UnassignCollectionProduct(
|
||||||
$collectionId: ID!
|
$collectionId: ID!
|
||||||
$productIds: [ID]!
|
$productIds: [ID]!
|
||||||
|
@ -177,10 +186,6 @@ const unassignCollectionProduct = gql`
|
||||||
collectionId: $collectionId
|
collectionId: $collectionId
|
||||||
products: $productIds
|
products: $productIds
|
||||||
) {
|
) {
|
||||||
errors {
|
|
||||||
field
|
|
||||||
message
|
|
||||||
}
|
|
||||||
collection {
|
collection {
|
||||||
id
|
id
|
||||||
products(first: $first, after: $after, before: $before, last: $last) {
|
products(first: $first, after: $after, before: $before, last: $last) {
|
||||||
|
@ -206,6 +211,9 @@ const unassignCollectionProduct = gql`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
errors: productErrors {
|
||||||
|
...ProductErrorFragment
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -215,11 +223,11 @@ export const TypedUnassignCollectionProductMutation = TypedMutation<
|
||||||
>(unassignCollectionProduct);
|
>(unassignCollectionProduct);
|
||||||
|
|
||||||
const collectionBulkDelete = gql`
|
const collectionBulkDelete = gql`
|
||||||
|
${productErrorFragment}
|
||||||
mutation CollectionBulkDelete($ids: [ID]!) {
|
mutation CollectionBulkDelete($ids: [ID]!) {
|
||||||
collectionBulkDelete(ids: $ids) {
|
collectionBulkDelete(ids: $ids) {
|
||||||
errors {
|
errors: productErrors {
|
||||||
field
|
...ProductErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -230,11 +238,11 @@ export const TypedCollectionBulkDelete = TypedMutation<
|
||||||
>(collectionBulkDelete);
|
>(collectionBulkDelete);
|
||||||
|
|
||||||
const collectionBulkPublish = gql`
|
const collectionBulkPublish = gql`
|
||||||
|
${productErrorFragment}
|
||||||
mutation CollectionBulkPublish($ids: [ID]!, $isPublished: Boolean!) {
|
mutation CollectionBulkPublish($ids: [ID]!, $isPublished: Boolean!) {
|
||||||
collectionBulkPublish(ids: $ids, isPublished: $isPublished) {
|
collectionBulkPublish(ids: $ids, isPublished: $isPublished) {
|
||||||
errors {
|
errors: productErrors {
|
||||||
field
|
...ProductErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,12 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { ProductErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: CollectionAssignProduct
|
// GraphQL mutation operation: CollectionAssignProduct
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface CollectionAssignProduct_collectionAddProducts_errors {
|
|
||||||
__typename: "Error";
|
|
||||||
field: string | null;
|
|
||||||
message: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CollectionAssignProduct_collectionAddProducts_collection_products_edges_node_productType {
|
export interface CollectionAssignProduct_collectionAddProducts_collection_products_edges_node_productType {
|
||||||
__typename: "ProductType";
|
__typename: "ProductType";
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -57,10 +53,16 @@ export interface CollectionAssignProduct_collectionAddProducts_collection {
|
||||||
products: CollectionAssignProduct_collectionAddProducts_collection_products | null;
|
products: CollectionAssignProduct_collectionAddProducts_collection_products | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CollectionAssignProduct_collectionAddProducts_errors {
|
||||||
|
__typename: "ProductError";
|
||||||
|
code: ProductErrorCode;
|
||||||
|
field: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface CollectionAssignProduct_collectionAddProducts {
|
export interface CollectionAssignProduct_collectionAddProducts {
|
||||||
__typename: "CollectionAddProducts";
|
__typename: "CollectionAddProducts";
|
||||||
errors: CollectionAssignProduct_collectionAddProducts_errors[];
|
|
||||||
collection: CollectionAssignProduct_collectionAddProducts_collection | null;
|
collection: CollectionAssignProduct_collectionAddProducts_collection | null;
|
||||||
|
errors: CollectionAssignProduct_collectionAddProducts_errors[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CollectionAssignProduct {
|
export interface CollectionAssignProduct {
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { ProductErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: CollectionBulkDelete
|
// GraphQL mutation operation: CollectionBulkDelete
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface CollectionBulkDelete_collectionBulkDelete_errors {
|
export interface CollectionBulkDelete_collectionBulkDelete_errors {
|
||||||
__typename: "Error";
|
__typename: "ProductError";
|
||||||
|
code: ProductErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CollectionBulkDelete_collectionBulkDelete {
|
export interface CollectionBulkDelete_collectionBulkDelete {
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { ProductErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: CollectionBulkPublish
|
// GraphQL mutation operation: CollectionBulkPublish
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface CollectionBulkPublish_collectionBulkPublish_errors {
|
export interface CollectionBulkPublish_collectionBulkPublish_errors {
|
||||||
__typename: "Error";
|
__typename: "ProductError";
|
||||||
|
code: ProductErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CollectionBulkPublish_collectionBulkPublish {
|
export interface CollectionBulkPublish_collectionBulkPublish {
|
||||||
|
|
|
@ -2,18 +2,12 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { CollectionInput } from "./../../types/globalTypes";
|
import { CollectionInput, ProductErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: CollectionUpdate
|
// GraphQL mutation operation: CollectionUpdate
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface CollectionUpdate_collectionUpdate_errors {
|
|
||||||
__typename: "Error";
|
|
||||||
field: string | null;
|
|
||||||
message: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CollectionUpdate_collectionUpdate_collection_backgroundImage {
|
export interface CollectionUpdate_collectionUpdate_collection_backgroundImage {
|
||||||
__typename: "Image";
|
__typename: "Image";
|
||||||
alt: string | null;
|
alt: string | null;
|
||||||
|
@ -32,10 +26,16 @@ export interface CollectionUpdate_collectionUpdate_collection {
|
||||||
seoTitle: string | null;
|
seoTitle: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CollectionUpdate_collectionUpdate_errors {
|
||||||
|
__typename: "ProductError";
|
||||||
|
code: ProductErrorCode;
|
||||||
|
field: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface CollectionUpdate_collectionUpdate {
|
export interface CollectionUpdate_collectionUpdate {
|
||||||
__typename: "CollectionUpdate";
|
__typename: "CollectionUpdate";
|
||||||
errors: CollectionUpdate_collectionUpdate_errors[];
|
|
||||||
collection: CollectionUpdate_collectionUpdate_collection | null;
|
collection: CollectionUpdate_collectionUpdate_collection | null;
|
||||||
|
errors: CollectionUpdate_collectionUpdate_errors[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CollectionUpdate {
|
export interface CollectionUpdate {
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { CollectionInput } from "./../../types/globalTypes";
|
import { CollectionInput, ShopErrorCode, ProductErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: CollectionUpdateWithHomepage
|
// GraphQL mutation operation: CollectionUpdateWithHomepage
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface CollectionUpdateWithHomepage_homepageCollectionUpdate_errors {
|
export interface CollectionUpdateWithHomepage_homepageCollectionUpdate_errors {
|
||||||
__typename: "Error";
|
__typename: "ShopError";
|
||||||
|
code: ShopErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CollectionUpdateWithHomepage_homepageCollectionUpdate_shop_homepageCollection {
|
export interface CollectionUpdateWithHomepage_homepageCollectionUpdate_shop_homepageCollection {
|
||||||
|
@ -30,12 +30,6 @@ export interface CollectionUpdateWithHomepage_homepageCollectionUpdate {
|
||||||
shop: CollectionUpdateWithHomepage_homepageCollectionUpdate_shop | null;
|
shop: CollectionUpdateWithHomepage_homepageCollectionUpdate_shop | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CollectionUpdateWithHomepage_collectionUpdate_errors {
|
|
||||||
__typename: "Error";
|
|
||||||
field: string | null;
|
|
||||||
message: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CollectionUpdateWithHomepage_collectionUpdate_collection_backgroundImage {
|
export interface CollectionUpdateWithHomepage_collectionUpdate_collection_backgroundImage {
|
||||||
__typename: "Image";
|
__typename: "Image";
|
||||||
alt: string | null;
|
alt: string | null;
|
||||||
|
@ -54,10 +48,16 @@ export interface CollectionUpdateWithHomepage_collectionUpdate_collection {
|
||||||
seoTitle: string | null;
|
seoTitle: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CollectionUpdateWithHomepage_collectionUpdate_errors {
|
||||||
|
__typename: "ProductError";
|
||||||
|
code: ProductErrorCode;
|
||||||
|
field: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface CollectionUpdateWithHomepage_collectionUpdate {
|
export interface CollectionUpdateWithHomepage_collectionUpdate {
|
||||||
__typename: "CollectionUpdate";
|
__typename: "CollectionUpdate";
|
||||||
errors: CollectionUpdateWithHomepage_collectionUpdate_errors[];
|
|
||||||
collection: CollectionUpdateWithHomepage_collectionUpdate_collection | null;
|
collection: CollectionUpdateWithHomepage_collectionUpdate_collection | null;
|
||||||
|
errors: CollectionUpdateWithHomepage_collectionUpdate_errors[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CollectionUpdateWithHomepage {
|
export interface CollectionUpdateWithHomepage {
|
||||||
|
|
|
@ -2,18 +2,12 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { CollectionCreateInput } from "./../../types/globalTypes";
|
import { CollectionCreateInput, ProductErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: CreateCollection
|
// GraphQL mutation operation: CreateCollection
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface CreateCollection_collectionCreate_errors {
|
|
||||||
__typename: "Error";
|
|
||||||
field: string | null;
|
|
||||||
message: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CreateCollection_collectionCreate_collection_backgroundImage {
|
export interface CreateCollection_collectionCreate_collection_backgroundImage {
|
||||||
__typename: "Image";
|
__typename: "Image";
|
||||||
alt: string | null;
|
alt: string | null;
|
||||||
|
@ -32,10 +26,16 @@ export interface CreateCollection_collectionCreate_collection {
|
||||||
seoTitle: string | null;
|
seoTitle: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CreateCollection_collectionCreate_errors {
|
||||||
|
__typename: "ProductError";
|
||||||
|
code: ProductErrorCode;
|
||||||
|
field: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface CreateCollection_collectionCreate {
|
export interface CreateCollection_collectionCreate {
|
||||||
__typename: "CollectionCreate";
|
__typename: "CollectionCreate";
|
||||||
errors: CreateCollection_collectionCreate_errors[];
|
|
||||||
collection: CreateCollection_collectionCreate_collection | null;
|
collection: CreateCollection_collectionCreate_collection | null;
|
||||||
|
errors: CreateCollection_collectionCreate_errors[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CreateCollection {
|
export interface CreateCollection {
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { ProductErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: RemoveCollection
|
// GraphQL mutation operation: RemoveCollection
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface RemoveCollection_collectionDelete_errors {
|
export interface RemoveCollection_collectionDelete_errors {
|
||||||
__typename: "Error";
|
__typename: "ProductError";
|
||||||
|
code: ProductErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RemoveCollection_collectionDelete {
|
export interface RemoveCollection_collectionDelete {
|
||||||
|
|
15
src/collections/types/ShopErrorFragment.ts
Normal file
15
src/collections/types/ShopErrorFragment.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { ShopErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
|
// ====================================================
|
||||||
|
// GraphQL fragment: ShopErrorFragment
|
||||||
|
// ====================================================
|
||||||
|
|
||||||
|
export interface ShopErrorFragment {
|
||||||
|
__typename: "ShopError";
|
||||||
|
code: ShopErrorCode;
|
||||||
|
field: string | null;
|
||||||
|
}
|
|
@ -2,16 +2,12 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { ProductErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: UnassignCollectionProduct
|
// GraphQL mutation operation: UnassignCollectionProduct
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface UnassignCollectionProduct_collectionRemoveProducts_errors {
|
|
||||||
__typename: "Error";
|
|
||||||
field: string | null;
|
|
||||||
message: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface UnassignCollectionProduct_collectionRemoveProducts_collection_products_edges_node_productType {
|
export interface UnassignCollectionProduct_collectionRemoveProducts_collection_products_edges_node_productType {
|
||||||
__typename: "ProductType";
|
__typename: "ProductType";
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -57,10 +53,16 @@ export interface UnassignCollectionProduct_collectionRemoveProducts_collection {
|
||||||
products: UnassignCollectionProduct_collectionRemoveProducts_collection_products | null;
|
products: UnassignCollectionProduct_collectionRemoveProducts_collection_products | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface UnassignCollectionProduct_collectionRemoveProducts_errors {
|
||||||
|
__typename: "ProductError";
|
||||||
|
code: ProductErrorCode;
|
||||||
|
field: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface UnassignCollectionProduct_collectionRemoveProducts {
|
export interface UnassignCollectionProduct_collectionRemoveProducts {
|
||||||
__typename: "CollectionRemoveProducts";
|
__typename: "CollectionRemoveProducts";
|
||||||
errors: UnassignCollectionProduct_collectionRemoveProducts_errors[];
|
|
||||||
collection: UnassignCollectionProduct_collectionRemoveProducts_collection | null;
|
collection: UnassignCollectionProduct_collectionRemoveProducts_collection | null;
|
||||||
|
errors: UnassignCollectionProduct_collectionRemoveProducts_errors[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UnassignCollectionProduct {
|
export interface UnassignCollectionProduct {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useIntl } from "react-intl";
|
||||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||||
import useNavigator from "@saleor/hooks/useNavigator";
|
import useNavigator from "@saleor/hooks/useNavigator";
|
||||||
import useNotifier from "@saleor/hooks/useNotifier";
|
import useNotifier from "@saleor/hooks/useNotifier";
|
||||||
import { maybe } from "../../misc";
|
import { commonMessages } from "@saleor/intl";
|
||||||
import { CollectionCreateInput } from "../../types/globalTypes";
|
import { CollectionCreateInput } from "../../types/globalTypes";
|
||||||
import CollectionCreatePage from "../components/CollectionCreatePage/CollectionCreatePage";
|
import CollectionCreatePage from "../components/CollectionCreatePage/CollectionCreatePage";
|
||||||
import { TypedCollectionCreateMutation } from "../mutations";
|
import { TypedCollectionCreateMutation } from "../mutations";
|
||||||
|
@ -19,9 +19,7 @@ export const CollectionCreate: React.FC = () => {
|
||||||
const handleCollectionCreateSuccess = (data: CreateCollection) => {
|
const handleCollectionCreateSuccess = (data: CreateCollection) => {
|
||||||
if (data.collectionCreate.errors.length === 0) {
|
if (data.collectionCreate.errors.length === 0) {
|
||||||
notify({
|
notify({
|
||||||
text: intl.formatMessage({
|
text: intl.formatMessage(commonMessages.savedChanges)
|
||||||
defaultMessage: "Created collection"
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
navigate(collectionUrl(data.collectionCreate.collection.id));
|
navigate(collectionUrl(data.collectionCreate.collection.id));
|
||||||
} else {
|
} else {
|
||||||
|
@ -31,7 +29,7 @@ export const CollectionCreate: React.FC = () => {
|
||||||
);
|
);
|
||||||
if (backgroundImageError) {
|
if (backgroundImageError) {
|
||||||
notify({
|
notify({
|
||||||
text: backgroundImageError.message
|
text: intl.formatMessage(commonMessages.somethingWentWrong)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,10 +45,7 @@ export const CollectionCreate: React.FC = () => {
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
<CollectionCreatePage
|
<CollectionCreatePage
|
||||||
errors={maybe(
|
errors={createCollectionOpts.data?.collectionCreate.errors || []}
|
||||||
() => createCollectionOpts.data.collectionCreate.errors,
|
|
||||||
[]
|
|
||||||
)}
|
|
||||||
onBack={() => navigate(collectionListUrl())}
|
onBack={() => navigate(collectionListUrl())}
|
||||||
disabled={createCollectionOpts.loading}
|
disabled={createCollectionOpts.loading}
|
||||||
onSubmit={formData =>
|
onSubmit={formData =>
|
||||||
|
|
|
@ -35,6 +35,7 @@ import {
|
||||||
CollectionUrlQueryParams,
|
CollectionUrlQueryParams,
|
||||||
CollectionUrlDialog
|
CollectionUrlDialog
|
||||||
} from "../urls";
|
} from "../urls";
|
||||||
|
import { CollectionUpdateWithHomepage } from "../types/CollectionUpdateWithHomepage";
|
||||||
|
|
||||||
interface CollectionDetailsProps {
|
interface CollectionDetailsProps {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -88,11 +89,18 @@ export const CollectionDetails: React.FC<CollectionDetailsProps> = ({
|
||||||
);
|
);
|
||||||
if (backgroundImageError) {
|
if (backgroundImageError) {
|
||||||
notify({
|
notify({
|
||||||
text: backgroundImageError.message
|
text: intl.formatMessage(commonMessages.somethingWentWrong)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const handleCollectioUpdateWithHomepage = (
|
||||||
|
data: CollectionUpdateWithHomepage
|
||||||
|
) => {
|
||||||
|
if (data.homepageCollectionUpdate.errors.length === 0) {
|
||||||
|
handleCollectionUpdate(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleProductAssign = (data: CollectionAssignProduct) => {
|
const handleProductAssign = (data: CollectionAssignProduct) => {
|
||||||
if (data.collectionAddProducts.errors.length === 0) {
|
if (data.collectionAddProducts.errors.length === 0) {
|
||||||
|
@ -130,6 +138,7 @@ export const CollectionDetails: React.FC<CollectionDetailsProps> = ({
|
||||||
return (
|
return (
|
||||||
<CollectionOperations
|
<CollectionOperations
|
||||||
onUpdate={handleCollectionUpdate}
|
onUpdate={handleCollectionUpdate}
|
||||||
|
onUpdateWithCollection={handleCollectioUpdateWithHomepage}
|
||||||
onProductAssign={handleProductAssign}
|
onProductAssign={handleProductAssign}
|
||||||
onProductUnassign={handleProductUnassign}
|
onProductUnassign={handleProductUnassign}
|
||||||
onRemove={handleCollectionRemove}
|
onRemove={handleCollectionRemove}
|
||||||
|
@ -204,7 +213,7 @@ export const CollectionDetails: React.FC<CollectionDetailsProps> = ({
|
||||||
onAdd={() => openModal("assign")}
|
onAdd={() => openModal("assign")}
|
||||||
onBack={handleBack}
|
onBack={handleBack}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
collection={maybe(() => data.collection)}
|
collection={data?.collection}
|
||||||
errors={
|
errors={
|
||||||
updateCollection.opts?.data?.collectionUpdate.errors || []
|
updateCollection.opts?.data?.collectionUpdate.errors || []
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
import { makeStyles } from "@material-ui/core/styles";
|
import { makeStyles } from "@material-ui/core/styles";
|
||||||
import TextField from "@material-ui/core/TextField";
|
import TextField from "@material-ui/core/TextField";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl, IntlShape } from "react-intl";
|
||||||
|
|
||||||
import { AddressTypeInput } from "@saleor/customers/types";
|
import { AddressTypeInput } from "@saleor/customers/types";
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
import { UserError } from "@saleor/types";
|
import { getFormErrors } from "@saleor/utils/errors";
|
||||||
import { getFieldError } from "@saleor/utils/errors";
|
import { AccountErrorFragment } from "@saleor/customers/types/AccountErrorFragment";
|
||||||
|
import getAccountErrorMessage from "@saleor/utils/errors/account";
|
||||||
|
import { OrderErrorFragment } from "@saleor/orders/types/OrderErrorFragment";
|
||||||
|
import getOrderErrorMessage from "@saleor/utils/errors/order";
|
||||||
import FormSpacer from "../FormSpacer";
|
import FormSpacer from "../FormSpacer";
|
||||||
import SingleAutocompleteSelectField, {
|
import SingleAutocompleteSelectField, {
|
||||||
SingleAutocompleteChoiceType
|
SingleAutocompleteChoiceType
|
||||||
|
@ -28,11 +31,22 @@ interface AddressEditProps {
|
||||||
countryDisplayValue: string;
|
countryDisplayValue: string;
|
||||||
data: AddressTypeInput;
|
data: AddressTypeInput;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
errors: UserError[];
|
errors: Array<AccountErrorFragment | OrderErrorFragment>;
|
||||||
onChange(event: React.ChangeEvent<any>);
|
onChange(event: React.ChangeEvent<any>);
|
||||||
onCountryChange(event: React.ChangeEvent<any>);
|
onCountryChange(event: React.ChangeEvent<any>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getErrorMessage(
|
||||||
|
err: AccountErrorFragment | OrderErrorFragment,
|
||||||
|
intl: IntlShape
|
||||||
|
): string {
|
||||||
|
if (err?.__typename === "AccountError") {
|
||||||
|
return getAccountErrorMessage(err, intl);
|
||||||
|
}
|
||||||
|
|
||||||
|
return getOrderErrorMessage(err, intl);
|
||||||
|
}
|
||||||
|
|
||||||
const AddressEdit: React.FC<AddressEditProps> = props => {
|
const AddressEdit: React.FC<AddressEditProps> = props => {
|
||||||
const {
|
const {
|
||||||
countries,
|
countries,
|
||||||
|
@ -43,18 +57,36 @@ const AddressEdit: React.FC<AddressEditProps> = props => {
|
||||||
onChange,
|
onChange,
|
||||||
onCountryChange
|
onCountryChange
|
||||||
} = props;
|
} = props;
|
||||||
const classes = useStyles(props);
|
|
||||||
|
|
||||||
|
const classes = useStyles(props);
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const formFields: Array<keyof AddressTypeInput> = [
|
||||||
|
"city",
|
||||||
|
"cityArea",
|
||||||
|
"country",
|
||||||
|
"countryArea",
|
||||||
|
"firstName",
|
||||||
|
"lastName",
|
||||||
|
"companyName",
|
||||||
|
"phone",
|
||||||
|
"postalCode",
|
||||||
|
"streetAddress1",
|
||||||
|
"streetAddress2"
|
||||||
|
];
|
||||||
|
const formErrors = getFormErrors<
|
||||||
|
keyof AddressTypeInput,
|
||||||
|
AccountErrorFragment | OrderErrorFragment
|
||||||
|
>(formFields, errors);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={classes.root}>
|
<div className={classes.root}>
|
||||||
<div>
|
<div>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "firstName")}
|
error={!!formErrors.firstName}
|
||||||
helperText={getFieldError(errors, "firstName")?.message}
|
helperText={getErrorMessage(formErrors.firstName, intl)}
|
||||||
label={intl.formatMessage(commonMessages.firstName)}
|
label={intl.formatMessage(commonMessages.firstName)}
|
||||||
name="firstName"
|
name="firstName"
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
|
@ -65,8 +97,8 @@ const AddressEdit: React.FC<AddressEditProps> = props => {
|
||||||
<div>
|
<div>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "lastName")}
|
error={!!formErrors.lastName}
|
||||||
helperText={getFieldError(errors, "lastName")?.message}
|
helperText={getErrorMessage(formErrors.lastName, intl)}
|
||||||
label={intl.formatMessage(commonMessages.lastName)}
|
label={intl.formatMessage(commonMessages.lastName)}
|
||||||
name="lastName"
|
name="lastName"
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
|
@ -80,8 +112,8 @@ const AddressEdit: React.FC<AddressEditProps> = props => {
|
||||||
<div>
|
<div>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "companyName")}
|
error={!!formErrors.companyName}
|
||||||
helperText={getFieldError(errors, "companyName")?.message}
|
helperText={getErrorMessage(formErrors.companyName, intl)}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Company"
|
defaultMessage: "Company"
|
||||||
})}
|
})}
|
||||||
|
@ -94,9 +126,9 @@ const AddressEdit: React.FC<AddressEditProps> = props => {
|
||||||
<div>
|
<div>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "phone")}
|
error={!!formErrors.phone}
|
||||||
fullWidth
|
fullWidth
|
||||||
helperText={getFieldError(errors, "phone")?.message}
|
helperText={getErrorMessage(formErrors.phone, intl)}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Phone"
|
defaultMessage: "Phone"
|
||||||
})}
|
})}
|
||||||
|
@ -109,8 +141,8 @@ const AddressEdit: React.FC<AddressEditProps> = props => {
|
||||||
<FormSpacer />
|
<FormSpacer />
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "streetAddress1")}
|
error={!!formErrors.streetAddress1}
|
||||||
helperText={getFieldError(errors, "streetAddress1")?.message}
|
helperText={getErrorMessage(formErrors.streetAddress1, intl)}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Address line 1"
|
defaultMessage: "Address line 1"
|
||||||
})}
|
})}
|
||||||
|
@ -122,8 +154,8 @@ const AddressEdit: React.FC<AddressEditProps> = props => {
|
||||||
<FormSpacer />
|
<FormSpacer />
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "streetAddress2")}
|
error={!!formErrors.streetAddress2}
|
||||||
helperText={getFieldError(errors, "streetAddress2")?.message}
|
helperText={getErrorMessage(formErrors.streetAddress2, intl)}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Address line 2"
|
defaultMessage: "Address line 2"
|
||||||
})}
|
})}
|
||||||
|
@ -137,8 +169,8 @@ const AddressEdit: React.FC<AddressEditProps> = props => {
|
||||||
<div>
|
<div>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "city")}
|
error={!!formErrors.city}
|
||||||
helperText={getFieldError(errors, "city")?.message}
|
helperText={getErrorMessage(formErrors.city, intl)}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "City"
|
defaultMessage: "City"
|
||||||
})}
|
})}
|
||||||
|
@ -151,8 +183,8 @@ const AddressEdit: React.FC<AddressEditProps> = props => {
|
||||||
<div>
|
<div>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "postalCode")}
|
error={!!formErrors.postalCode}
|
||||||
helperText={getFieldError(errors, "postalCode")?.message}
|
helperText={getErrorMessage(formErrors.postalCode, intl)}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "ZIP / Postal code"
|
defaultMessage: "ZIP / Postal code"
|
||||||
})}
|
})}
|
||||||
|
@ -170,8 +202,8 @@ const AddressEdit: React.FC<AddressEditProps> = props => {
|
||||||
<SingleAutocompleteSelectField
|
<SingleAutocompleteSelectField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
displayValue={countryDisplayValue}
|
displayValue={countryDisplayValue}
|
||||||
error={!!getFieldError(errors, "country")}
|
error={!!formErrors.country}
|
||||||
helperText={getFieldError(errors, "country")?.message}
|
helperText={getErrorMessage(formErrors.country, intl)}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Country"
|
defaultMessage: "Country"
|
||||||
})}
|
})}
|
||||||
|
@ -187,8 +219,8 @@ const AddressEdit: React.FC<AddressEditProps> = props => {
|
||||||
<div>
|
<div>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "countryArea")}
|
error={!!formErrors.countryArea}
|
||||||
helperText={getFieldError(errors, "countryArea")?.message}
|
helperText={getErrorMessage(formErrors.countryArea, intl)}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Country area"
|
defaultMessage: "Country area"
|
||||||
})}
|
})}
|
||||||
|
|
|
@ -15,7 +15,7 @@ import { FormattedMessage } from "react-intl";
|
||||||
import CardTitle from "@saleor/components/CardTitle";
|
import CardTitle from "@saleor/components/CardTitle";
|
||||||
import ResponsiveTable from "@saleor/components/ResponsiveTable";
|
import ResponsiveTable from "@saleor/components/ResponsiveTable";
|
||||||
import Skeleton from "@saleor/components/Skeleton";
|
import Skeleton from "@saleor/components/Skeleton";
|
||||||
import { maybe, renderCollection } from "../../misc";
|
import { maybe, renderCollection, getStringOrPlaceholder } from "../../misc";
|
||||||
import { CountryFragment } from "../../taxes/types/CountryFragment";
|
import { CountryFragment } from "../../taxes/types/CountryFragment";
|
||||||
|
|
||||||
export interface CountryListProps {
|
export interface CountryListProps {
|
||||||
|
@ -98,7 +98,7 @@ const CountryList: React.FC<CountryListProps> = props => {
|
||||||
<CardTitle
|
<CardTitle
|
||||||
title={title}
|
title={title}
|
||||||
toolbar={
|
toolbar={
|
||||||
<Button color="primary" onClick={onCountryAssign}>
|
<Button color="primary" disabled={disabled} onClick={onCountryAssign}>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
defaultMessage="Assign countries"
|
defaultMessage="Assign countries"
|
||||||
description="button"
|
description="button"
|
||||||
|
@ -117,7 +117,7 @@ const CountryList: React.FC<CountryListProps> = props => {
|
||||||
defaultMessage="{number} Countries"
|
defaultMessage="{number} Countries"
|
||||||
description="number of countries"
|
description="number of countries"
|
||||||
values={{
|
values={{
|
||||||
number: maybe(() => countries.length.toString(), "...")
|
number: getStringOrPlaceholder(countries?.length.toString())
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
|
@ -30,7 +30,7 @@ const Story: React.FC<Partial<
|
||||||
MultiAutocompleteSelectFieldProps & {
|
MultiAutocompleteSelectFieldProps & {
|
||||||
enableLoadMore: boolean;
|
enableLoadMore: boolean;
|
||||||
}
|
}
|
||||||
>> = ({ allowCustomValues, enableLoadMore }) => {
|
>> = ({ enableLoadMore, ...rest }) => {
|
||||||
const { change, data: countries } = useMultiAutocomplete([suggestions[0]]);
|
const { change, data: countries } = useMultiAutocomplete([suggestions[0]]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -49,7 +49,7 @@ const Story: React.FC<Partial<
|
||||||
loading={loading}
|
loading={loading}
|
||||||
hasMore={enableLoadMore ? hasMore : false}
|
hasMore={enableLoadMore ? hasMore : false}
|
||||||
onFetchMore={enableLoadMore ? onFetchMore : undefined}
|
onFetchMore={enableLoadMore ? onFetchMore : undefined}
|
||||||
allowCustomValues={allowCustomValues}
|
{...rest}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</ChoiceProvider>
|
</ChoiceProvider>
|
||||||
|
@ -84,4 +84,5 @@ storiesOf("Generics / Multiple select with autocomplete", module)
|
||||||
.add("interactive with custom option", () => (
|
.add("interactive with custom option", () => (
|
||||||
<Story allowCustomValues={true} />
|
<Story allowCustomValues={true} />
|
||||||
))
|
))
|
||||||
.add("interactive with load more", () => <Story enableLoadMore={true} />);
|
.add("interactive with load more", () => <Story enableLoadMore={true} />)
|
||||||
|
.add("interactive with error", () => <Story error={true} />);
|
||||||
|
|
|
@ -59,6 +59,7 @@ export interface MultiAutocompleteSelectFieldProps
|
||||||
extends Partial<FetchMoreProps> {
|
extends Partial<FetchMoreProps> {
|
||||||
allowCustomValues?: boolean;
|
allowCustomValues?: boolean;
|
||||||
displayValues: MultiAutocompleteChoiceType[];
|
displayValues: MultiAutocompleteChoiceType[];
|
||||||
|
error?: boolean;
|
||||||
name: string;
|
name: string;
|
||||||
choices: MultiAutocompleteChoiceType[];
|
choices: MultiAutocompleteChoiceType[];
|
||||||
value: string[];
|
value: string[];
|
||||||
|
@ -70,19 +71,16 @@ export interface MultiAutocompleteSelectFieldProps
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
onChange: (event: React.ChangeEvent<any>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DebounceAutocomplete: React.ComponentType<
|
const DebounceAutocomplete: React.ComponentType<DebounceProps<
|
||||||
DebounceProps<string>
|
string
|
||||||
> = Debounce;
|
>> = Debounce;
|
||||||
|
|
||||||
const MultiAutocompleteSelectFieldComponent: React.FC<
|
const MultiAutocompleteSelectFieldComponent: React.FC<MultiAutocompleteSelectFieldProps> = props => {
|
||||||
MultiAutocompleteSelectFieldProps
|
|
||||||
> = props => {
|
|
||||||
const {
|
const {
|
||||||
allowCustomValues,
|
allowCustomValues,
|
||||||
choices,
|
choices,
|
||||||
|
|
||||||
displayValues,
|
displayValues,
|
||||||
|
error,
|
||||||
hasMore,
|
hasMore,
|
||||||
helperText,
|
helperText,
|
||||||
label,
|
label,
|
||||||
|
@ -147,6 +145,7 @@ const MultiAutocompleteSelectFieldComponent: React.FC<
|
||||||
id: undefined,
|
id: undefined,
|
||||||
onClick: toggleMenu
|
onClick: toggleMenu
|
||||||
}}
|
}}
|
||||||
|
error={error}
|
||||||
helperText={helperText}
|
helperText={helperText}
|
||||||
label={label}
|
label={label}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
@ -191,9 +190,11 @@ const MultiAutocompleteSelectFieldComponent: React.FC<
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const MultiAutocompleteSelectField: React.FC<
|
const MultiAutocompleteSelectField: React.FC<MultiAutocompleteSelectFieldProps> = ({
|
||||||
MultiAutocompleteSelectFieldProps
|
choices,
|
||||||
> = ({ choices, fetchChoices, ...props }) => {
|
fetchChoices,
|
||||||
|
...props
|
||||||
|
}) => {
|
||||||
const [query, setQuery] = React.useState("");
|
const [query, setQuery] = React.useState("");
|
||||||
|
|
||||||
if (fetchChoices) {
|
if (fetchChoices) {
|
||||||
|
|
|
@ -17,9 +17,9 @@ import useModalDialogErrors from "@saleor/hooks/useModalDialogErrors";
|
||||||
import useStateFromProps from "@saleor/hooks/useStateFromProps";
|
import useStateFromProps from "@saleor/hooks/useStateFromProps";
|
||||||
import { buttonMessages } from "@saleor/intl";
|
import { buttonMessages } from "@saleor/intl";
|
||||||
import { maybe } from "@saleor/misc";
|
import { maybe } from "@saleor/misc";
|
||||||
import { UserError } from "@saleor/types";
|
|
||||||
import { AddressInput } from "@saleor/types/globalTypes";
|
import { AddressInput } from "@saleor/types/globalTypes";
|
||||||
import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";
|
import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";
|
||||||
|
import { AccountErrorFragment } from "@saleor/customers/types/AccountErrorFragment";
|
||||||
import { AddressTypeInput } from "../../types";
|
import { AddressTypeInput } from "../../types";
|
||||||
import { CustomerAddresses_user_addresses } from "../../types/CustomerAddresses";
|
import { CustomerAddresses_user_addresses } from "../../types/CustomerAddresses";
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ export interface CustomerAddressDialogProps {
|
||||||
code: string;
|
code: string;
|
||||||
label: string;
|
label: string;
|
||||||
}>;
|
}>;
|
||||||
errors: UserError[];
|
errors: AccountErrorFragment[];
|
||||||
open: boolean;
|
open: boolean;
|
||||||
variant: "create" | "edit";
|
variant: "create" | "edit";
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
|
|
|
@ -9,7 +9,7 @@ import AddressEdit from "@saleor/components/AddressEdit";
|
||||||
import CardTitle from "@saleor/components/CardTitle";
|
import CardTitle from "@saleor/components/CardTitle";
|
||||||
import { FormSpacer } from "@saleor/components/FormSpacer";
|
import { FormSpacer } from "@saleor/components/FormSpacer";
|
||||||
import { SingleAutocompleteChoiceType } from "@saleor/components/SingleAutocompleteSelectField";
|
import { SingleAutocompleteChoiceType } from "@saleor/components/SingleAutocompleteSelectField";
|
||||||
import { UserError } from "../../../types";
|
import { AccountErrorFragment } from "@saleor/customers/types/AccountErrorFragment";
|
||||||
import { AddressTypeInput } from "../../types";
|
import { AddressTypeInput } from "../../types";
|
||||||
|
|
||||||
const useStyles = makeStyles(
|
const useStyles = makeStyles(
|
||||||
|
@ -26,7 +26,7 @@ export interface CustomerCreateAddressProps {
|
||||||
countryDisplayName: string;
|
countryDisplayName: string;
|
||||||
data: AddressTypeInput;
|
data: AddressTypeInput;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: AccountErrorFragment[];
|
||||||
onChange(event: React.ChangeEvent<any>);
|
onChange(event: React.ChangeEvent<any>);
|
||||||
onCountryChange(event: React.ChangeEvent<any>);
|
onCountryChange(event: React.ChangeEvent<any>);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,9 @@ import { useIntl } from "react-intl";
|
||||||
|
|
||||||
import CardTitle from "@saleor/components/CardTitle";
|
import CardTitle from "@saleor/components/CardTitle";
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
import { getFieldError } from "@saleor/utils/errors";
|
import { getFormErrors } from "@saleor/utils/errors";
|
||||||
import { UserError } from "../../../types";
|
import { AccountErrorFragment } from "@saleor/customers/types/AccountErrorFragment";
|
||||||
|
import getAccountErrorMessage from "@saleor/utils/errors/account";
|
||||||
import { CustomerCreatePageFormData } from "../CustomerCreatePage";
|
import { CustomerCreatePageFormData } from "../CustomerCreatePage";
|
||||||
|
|
||||||
const useStyles = makeStyles(
|
const useStyles = makeStyles(
|
||||||
|
@ -26,16 +27,21 @@ const useStyles = makeStyles(
|
||||||
export interface CustomerCreateDetailsProps {
|
export interface CustomerCreateDetailsProps {
|
||||||
data: CustomerCreatePageFormData;
|
data: CustomerCreatePageFormData;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: AccountErrorFragment[];
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
onChange: (event: React.ChangeEvent<any>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CustomerCreateDetails: React.FC<CustomerCreateDetailsProps> = props => {
|
const CustomerCreateDetails: React.FC<CustomerCreateDetailsProps> = props => {
|
||||||
const { data, disabled, errors, onChange } = props;
|
const { data, disabled, errors, onChange } = props;
|
||||||
const classes = useStyles(props);
|
|
||||||
|
|
||||||
|
const classes = useStyles(props);
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const formErrors = getFormErrors(
|
||||||
|
["customerFirstName", "customerLastName", "email"],
|
||||||
|
errors
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
|
@ -48,33 +54,39 @@ const CustomerCreateDetails: React.FC<CustomerCreateDetailsProps> = props => {
|
||||||
<div className={classes.root}>
|
<div className={classes.root}>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "customerFirstName")}
|
error={!!formErrors.customerFirstName}
|
||||||
fullWidth
|
fullWidth
|
||||||
name="customerFirstName"
|
name="customerFirstName"
|
||||||
label={intl.formatMessage(commonMessages.firstName)}
|
label={intl.formatMessage(commonMessages.firstName)}
|
||||||
helperText={getFieldError(errors, "customerFirstName")?.message}
|
helperText={getAccountErrorMessage(
|
||||||
|
formErrors.customerFirstName,
|
||||||
|
intl
|
||||||
|
)}
|
||||||
type="text"
|
type="text"
|
||||||
value={data.customerFirstName}
|
value={data.customerFirstName}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "customerLastName")}
|
error={!!formErrors.customerLastName}
|
||||||
fullWidth
|
fullWidth
|
||||||
name="customerLastName"
|
name="customerLastName"
|
||||||
label={intl.formatMessage(commonMessages.lastName)}
|
label={intl.formatMessage(commonMessages.lastName)}
|
||||||
helperText={getFieldError(errors, "customerLastName")?.message}
|
helperText={getAccountErrorMessage(
|
||||||
|
formErrors.customerLastName,
|
||||||
|
intl
|
||||||
|
)}
|
||||||
type="text"
|
type="text"
|
||||||
value={data.customerLastName}
|
value={data.customerLastName}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "email")}
|
error={!!formErrors.email}
|
||||||
fullWidth
|
fullWidth
|
||||||
name="email"
|
name="email"
|
||||||
label={intl.formatMessage(commonMessages.email)}
|
label={intl.formatMessage(commonMessages.email)}
|
||||||
helperText={getFieldError(errors, "email")?.message}
|
helperText={getAccountErrorMessage(formErrors.email, intl)}
|
||||||
type="email"
|
type="email"
|
||||||
value={data.email}
|
value={data.email}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
|
@ -84,5 +96,6 @@ const CustomerCreateDetails: React.FC<CustomerCreateDetailsProps> = props => {
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
CustomerCreateDetails.displayName = "CustomerCreateDetails";
|
CustomerCreateDetails.displayName = "CustomerCreateDetails";
|
||||||
export default CustomerCreateDetails;
|
export default CustomerCreateDetails;
|
||||||
|
|
|
@ -7,15 +7,16 @@ import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
import CardTitle from "@saleor/components/CardTitle";
|
import CardTitle from "@saleor/components/CardTitle";
|
||||||
import { FormSpacer } from "@saleor/components/FormSpacer";
|
import { FormSpacer } from "@saleor/components/FormSpacer";
|
||||||
import { UserError } from "@saleor/types";
|
import { getFormErrors } from "@saleor/utils/errors";
|
||||||
import { getFieldError } from "@saleor/utils/errors";
|
import getAccountErrorMessage from "@saleor/utils/errors/account";
|
||||||
|
import { AccountErrorFragment } from "@saleor/customers/types/AccountErrorFragment";
|
||||||
|
|
||||||
export interface CustomerCreateNoteProps {
|
export interface CustomerCreateNoteProps {
|
||||||
data: {
|
data: {
|
||||||
note: string;
|
note: string;
|
||||||
};
|
};
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: AccountErrorFragment[];
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
onChange: (event: React.ChangeEvent<any>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +28,8 @@ const CustomerCreateNote: React.FC<CustomerCreateNoteProps> = ({
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const formErrors = getFormErrors(["note"], errors);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
|
@ -42,11 +45,11 @@ const CustomerCreateNote: React.FC<CustomerCreateNoteProps> = ({
|
||||||
<FormSpacer />
|
<FormSpacer />
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "note")}
|
error={!!formErrors.note}
|
||||||
fullWidth
|
fullWidth
|
||||||
multiline
|
multiline
|
||||||
name="note"
|
name="note"
|
||||||
helperText={getFieldError(errors, "note")?.message}
|
helperText={getAccountErrorMessage(formErrors.note, intl)}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Note",
|
defaultMessage: "Note",
|
||||||
description: "note about customer"
|
description: "note about customer"
|
||||||
|
|
|
@ -13,7 +13,7 @@ import useAddressValidation from "@saleor/hooks/useAddressValidation";
|
||||||
import { sectionNames } from "@saleor/intl";
|
import { sectionNames } from "@saleor/intl";
|
||||||
import { AddressInput } from "@saleor/types/globalTypes";
|
import { AddressInput } from "@saleor/types/globalTypes";
|
||||||
import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";
|
import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";
|
||||||
import { UserError } from "../../../types";
|
import { AccountErrorFragment } from "@saleor/customers/types/AccountErrorFragment";
|
||||||
import { AddressTypeInput } from "../../types";
|
import { AddressTypeInput } from "../../types";
|
||||||
import { CustomerCreateData_shop_countries } from "../../types/CustomerCreateData";
|
import { CustomerCreateData_shop_countries } from "../../types/CustomerCreateData";
|
||||||
import CustomerCreateAddress from "../CustomerCreateAddress/CustomerCreateAddress";
|
import CustomerCreateAddress from "../CustomerCreateAddress/CustomerCreateAddress";
|
||||||
|
@ -52,7 +52,7 @@ const initialForm: CustomerCreatePageFormData & AddressTypeInput = {
|
||||||
export interface CustomerCreatePageProps {
|
export interface CustomerCreatePageProps {
|
||||||
countries: CustomerCreateData_shop_countries[];
|
countries: CustomerCreateData_shop_countries[];
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: AccountErrorFragment[];
|
||||||
saveButtonBar: ConfirmButtonTransitionState;
|
saveButtonBar: ConfirmButtonTransitionState;
|
||||||
onBack: () => void;
|
onBack: () => void;
|
||||||
onSubmit: (data: CustomerCreatePageSubmitData) => void;
|
onSubmit: (data: CustomerCreatePageSubmitData) => void;
|
||||||
|
|
|
@ -11,8 +11,9 @@ import CardTitle from "@saleor/components/CardTitle";
|
||||||
import { ControlledCheckbox } from "@saleor/components/ControlledCheckbox";
|
import { ControlledCheckbox } from "@saleor/components/ControlledCheckbox";
|
||||||
import Skeleton from "@saleor/components/Skeleton";
|
import Skeleton from "@saleor/components/Skeleton";
|
||||||
import { maybe } from "@saleor/misc";
|
import { maybe } from "@saleor/misc";
|
||||||
import { UserError } from "@saleor/types";
|
import { getFormErrors } from "@saleor/utils/errors";
|
||||||
import { getFieldError } from "@saleor/utils/errors";
|
import getAccountErrorMessage from "@saleor/utils/errors/account";
|
||||||
|
import { AccountErrorFragment } from "@saleor/customers/types/AccountErrorFragment";
|
||||||
import { CustomerDetails_user } from "../../types/CustomerDetails";
|
import { CustomerDetails_user } from "../../types/CustomerDetails";
|
||||||
|
|
||||||
const useStyles = makeStyles(
|
const useStyles = makeStyles(
|
||||||
|
@ -40,16 +41,18 @@ export interface CustomerDetailsProps {
|
||||||
note: string;
|
note: string;
|
||||||
};
|
};
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: AccountErrorFragment[];
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
onChange: (event: React.ChangeEvent<any>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CustomerDetails: React.FC<CustomerDetailsProps> = props => {
|
const CustomerDetails: React.FC<CustomerDetailsProps> = props => {
|
||||||
const { customer, data, disabled, errors, onChange } = props;
|
const { customer, data, disabled, errors, onChange } = props;
|
||||||
const classes = useStyles(props);
|
|
||||||
|
|
||||||
|
const classes = useStyles(props);
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const formErrors = getFormErrors(["note"], errors);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
|
@ -91,10 +94,10 @@ const CustomerDetails: React.FC<CustomerDetailsProps> = props => {
|
||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "note")}
|
error={!!formErrors.note}
|
||||||
fullWidth
|
fullWidth
|
||||||
multiline
|
multiline
|
||||||
helperText={getFieldError(errors, "note")?.message}
|
helperText={getAccountErrorMessage(formErrors.note, intl)}
|
||||||
name="note"
|
name="note"
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Note",
|
defaultMessage: "Note",
|
||||||
|
|
|
@ -10,8 +10,8 @@ import Grid from "@saleor/components/Grid";
|
||||||
import PageHeader from "@saleor/components/PageHeader";
|
import PageHeader from "@saleor/components/PageHeader";
|
||||||
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
||||||
import { sectionNames } from "@saleor/intl";
|
import { sectionNames } from "@saleor/intl";
|
||||||
|
import { AccountErrorFragment } from "@saleor/customers/types/AccountErrorFragment";
|
||||||
import { getUserName, maybe } from "../../../misc";
|
import { getUserName, maybe } from "../../../misc";
|
||||||
import { UserError } from "../../../types";
|
|
||||||
import { CustomerDetails_user } from "../../types/CustomerDetails";
|
import { CustomerDetails_user } from "../../types/CustomerDetails";
|
||||||
import CustomerAddresses from "../CustomerAddresses";
|
import CustomerAddresses from "../CustomerAddresses";
|
||||||
import CustomerDetails from "../CustomerDetails";
|
import CustomerDetails from "../CustomerDetails";
|
||||||
|
@ -30,7 +30,7 @@ export interface CustomerDetailsPageFormData {
|
||||||
export interface CustomerDetailsPageProps {
|
export interface CustomerDetailsPageProps {
|
||||||
customer: CustomerDetails_user;
|
customer: CustomerDetails_user;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: AccountErrorFragment[];
|
||||||
saveButtonBar: ConfirmButtonTransitionState;
|
saveButtonBar: ConfirmButtonTransitionState;
|
||||||
onBack: () => void;
|
onBack: () => void;
|
||||||
onSubmit: (data: CustomerDetailsPageFormData) => void;
|
onSubmit: (data: CustomerDetailsPageFormData) => void;
|
||||||
|
|
|
@ -10,8 +10,9 @@ import CardTitle from "@saleor/components/CardTitle";
|
||||||
import Grid from "@saleor/components/Grid";
|
import Grid from "@saleor/components/Grid";
|
||||||
import Hr from "@saleor/components/Hr";
|
import Hr from "@saleor/components/Hr";
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
import { UserError } from "@saleor/types";
|
import { AccountErrorFragment } from "@saleor/customers/types/AccountErrorFragment";
|
||||||
import { getFieldError } from "@saleor/utils/errors";
|
import { getFormErrors } from "@saleor/utils/errors";
|
||||||
|
import getAccountErrorMessage from "@saleor/utils/errors/account";
|
||||||
|
|
||||||
const useStyles = makeStyles(
|
const useStyles = makeStyles(
|
||||||
theme => ({
|
theme => ({
|
||||||
|
@ -35,16 +36,18 @@ export interface CustomerInfoProps {
|
||||||
email: string;
|
email: string;
|
||||||
};
|
};
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: AccountErrorFragment[];
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
onChange: (event: React.ChangeEvent<any>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CustomerInfo: React.FC<CustomerInfoProps> = props => {
|
const CustomerInfo: React.FC<CustomerInfoProps> = props => {
|
||||||
const { data, disabled, errors, onChange } = props;
|
const { data, disabled, errors, onChange } = props;
|
||||||
const classes = useStyles(props);
|
|
||||||
|
|
||||||
|
const classes = useStyles(props);
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const formErrors = getFormErrors(["firstName", "lastName", "email"], errors);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
|
@ -62,9 +65,9 @@ const CustomerInfo: React.FC<CustomerInfoProps> = props => {
|
||||||
<Grid variant="uniform">
|
<Grid variant="uniform">
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "firstName")}
|
error={!!formErrors.firstName}
|
||||||
fullWidth
|
fullWidth
|
||||||
helperText={getFieldError(errors, "firstName")?.message}
|
helperText={getAccountErrorMessage(formErrors.firstName, intl)}
|
||||||
name="firstName"
|
name="firstName"
|
||||||
type="text"
|
type="text"
|
||||||
label={intl.formatMessage(commonMessages.firstName)}
|
label={intl.formatMessage(commonMessages.firstName)}
|
||||||
|
@ -73,9 +76,9 @@ const CustomerInfo: React.FC<CustomerInfoProps> = props => {
|
||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "lastName")}
|
error={!!formErrors.lastName}
|
||||||
fullWidth
|
fullWidth
|
||||||
helperText={getFieldError(errors, "lastName")?.message}
|
helperText={getAccountErrorMessage(formErrors.lastName, intl)}
|
||||||
name="lastName"
|
name="lastName"
|
||||||
type="text"
|
type="text"
|
||||||
label={intl.formatMessage(commonMessages.lastName)}
|
label={intl.formatMessage(commonMessages.lastName)}
|
||||||
|
@ -92,9 +95,9 @@ const CustomerInfo: React.FC<CustomerInfoProps> = props => {
|
||||||
</Typography>
|
</Typography>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "email")}
|
error={!!formErrors.email}
|
||||||
fullWidth
|
fullWidth
|
||||||
helperText={getFieldError(errors, "email")?.message}
|
helperText={getAccountErrorMessage(formErrors.email, intl)}
|
||||||
name="email"
|
name="email"
|
||||||
type="email"
|
type="email"
|
||||||
label={intl.formatMessage(commonMessages.email)}
|
label={intl.formatMessage(commonMessages.email)}
|
||||||
|
|
|
@ -36,13 +36,20 @@ import {
|
||||||
UpdateCustomerAddressVariables
|
UpdateCustomerAddressVariables
|
||||||
} from "./types/UpdateCustomerAddress";
|
} from "./types/UpdateCustomerAddress";
|
||||||
|
|
||||||
|
export const accountFragmentError = gql`
|
||||||
|
fragment AccountErrorFragment on AccountError {
|
||||||
|
code
|
||||||
|
field
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
const updateCustomer = gql`
|
const updateCustomer = gql`
|
||||||
|
${accountFragmentError}
|
||||||
${customerDetailsFragment}
|
${customerDetailsFragment}
|
||||||
mutation UpdateCustomer($id: ID!, $input: CustomerInput!) {
|
mutation UpdateCustomer($id: ID!, $input: CustomerInput!) {
|
||||||
customerUpdate(id: $id, input: $input) {
|
customerUpdate(id: $id, input: $input) {
|
||||||
errors {
|
errors: accountErrors {
|
||||||
field
|
...AccountErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
user {
|
user {
|
||||||
...CustomerDetailsFragment
|
...CustomerDetailsFragment
|
||||||
|
@ -56,11 +63,11 @@ export const TypedUpdateCustomerMutation = TypedMutation<
|
||||||
>(updateCustomer);
|
>(updateCustomer);
|
||||||
|
|
||||||
const createCustomer = gql`
|
const createCustomer = gql`
|
||||||
|
${accountFragmentError}
|
||||||
mutation CreateCustomer($input: UserCreateInput!) {
|
mutation CreateCustomer($input: UserCreateInput!) {
|
||||||
customerCreate(input: $input) {
|
customerCreate(input: $input) {
|
||||||
errors {
|
errors: accountErrors {
|
||||||
field
|
...AccountErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
user {
|
user {
|
||||||
id
|
id
|
||||||
|
@ -74,11 +81,11 @@ export const TypedCreateCustomerMutation = TypedMutation<
|
||||||
>(createCustomer);
|
>(createCustomer);
|
||||||
|
|
||||||
const removeCustomer = gql`
|
const removeCustomer = gql`
|
||||||
|
${accountFragmentError}
|
||||||
mutation RemoveCustomer($id: ID!) {
|
mutation RemoveCustomer($id: ID!) {
|
||||||
customerDelete(id: $id) {
|
customerDelete(id: $id) {
|
||||||
errors {
|
errors: accountErrors {
|
||||||
field
|
...AccountErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,6 +96,7 @@ export const TypedRemoveCustomerMutation = TypedMutation<
|
||||||
>(removeCustomer);
|
>(removeCustomer);
|
||||||
|
|
||||||
const setCustomerDefaultAddress = gql`
|
const setCustomerDefaultAddress = gql`
|
||||||
|
${accountFragmentError}
|
||||||
${customerAddressesFragment}
|
${customerAddressesFragment}
|
||||||
mutation SetCustomerDefaultAddress(
|
mutation SetCustomerDefaultAddress(
|
||||||
$addressId: ID!
|
$addressId: ID!
|
||||||
|
@ -96,9 +104,8 @@ const setCustomerDefaultAddress = gql`
|
||||||
$type: AddressTypeEnum!
|
$type: AddressTypeEnum!
|
||||||
) {
|
) {
|
||||||
addressSetDefault(addressId: $addressId, userId: $userId, type: $type) {
|
addressSetDefault(addressId: $addressId, userId: $userId, type: $type) {
|
||||||
errors {
|
errors: accountErrors {
|
||||||
field
|
...AccountErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
user {
|
user {
|
||||||
...CustomerAddressesFragment
|
...CustomerAddressesFragment
|
||||||
|
@ -112,13 +119,13 @@ export const TypedSetCustomerDefaultAddressMutation = TypedMutation<
|
||||||
>(setCustomerDefaultAddress);
|
>(setCustomerDefaultAddress);
|
||||||
|
|
||||||
const createCustomerAddress = gql`
|
const createCustomerAddress = gql`
|
||||||
|
${accountFragmentError}
|
||||||
${customerAddressesFragment}
|
${customerAddressesFragment}
|
||||||
${fragmentAddress}
|
${fragmentAddress}
|
||||||
mutation CreateCustomerAddress($id: ID!, $input: AddressInput!) {
|
mutation CreateCustomerAddress($id: ID!, $input: AddressInput!) {
|
||||||
addressCreate(userId: $id, input: $input) {
|
addressCreate(userId: $id, input: $input) {
|
||||||
errors {
|
errors: accountErrors {
|
||||||
field
|
...AccountErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
address {
|
address {
|
||||||
...AddressFragment
|
...AddressFragment
|
||||||
|
@ -135,12 +142,12 @@ export const TypedCreateCustomerAddressMutation = TypedMutation<
|
||||||
>(createCustomerAddress);
|
>(createCustomerAddress);
|
||||||
|
|
||||||
const updateCustomerAddress = gql`
|
const updateCustomerAddress = gql`
|
||||||
|
${accountFragmentError}
|
||||||
${fragmentAddress}
|
${fragmentAddress}
|
||||||
mutation UpdateCustomerAddress($id: ID!, $input: AddressInput!) {
|
mutation UpdateCustomerAddress($id: ID!, $input: AddressInput!) {
|
||||||
addressUpdate(id: $id, input: $input) {
|
addressUpdate(id: $id, input: $input) {
|
||||||
errors {
|
errors: accountErrors {
|
||||||
field
|
...AccountErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
address {
|
address {
|
||||||
...AddressFragment
|
...AddressFragment
|
||||||
|
@ -154,12 +161,12 @@ export const TypedUpdateCustomerAddressMutation = TypedMutation<
|
||||||
>(updateCustomerAddress);
|
>(updateCustomerAddress);
|
||||||
|
|
||||||
const removeCustomerAddress = gql`
|
const removeCustomerAddress = gql`
|
||||||
|
${accountFragmentError}
|
||||||
${customerAddressesFragment}
|
${customerAddressesFragment}
|
||||||
mutation RemoveCustomerAddress($id: ID!) {
|
mutation RemoveCustomerAddress($id: ID!) {
|
||||||
addressDelete(id: $id) {
|
addressDelete(id: $id) {
|
||||||
errors {
|
errors: accountErrors {
|
||||||
field
|
...AccountErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
user {
|
user {
|
||||||
...CustomerAddressesFragment
|
...CustomerAddressesFragment
|
||||||
|
@ -173,11 +180,11 @@ export const TypedRemoveCustomerAddressMutation = TypedMutation<
|
||||||
>(removeCustomerAddress);
|
>(removeCustomerAddress);
|
||||||
|
|
||||||
export const bulkRemoveCustomers = gql`
|
export const bulkRemoveCustomers = gql`
|
||||||
|
${accountFragmentError}
|
||||||
mutation BulkRemoveCustomers($ids: [ID]!) {
|
mutation BulkRemoveCustomers($ids: [ID]!) {
|
||||||
customerBulkDelete(ids: $ids) {
|
customerBulkDelete(ids: $ids) {
|
||||||
errors {
|
errors: accountErrors {
|
||||||
field
|
...AccountErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
15
src/customers/types/AccountErrorFragment.ts
Normal file
15
src/customers/types/AccountErrorFragment.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { AccountErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
|
// ====================================================
|
||||||
|
// GraphQL fragment: AccountErrorFragment
|
||||||
|
// ====================================================
|
||||||
|
|
||||||
|
export interface AccountErrorFragment {
|
||||||
|
__typename: "AccountError";
|
||||||
|
code: AccountErrorCode;
|
||||||
|
field: string | null;
|
||||||
|
}
|
|
@ -2,14 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { AccountErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: BulkRemoveCustomers
|
// GraphQL mutation operation: BulkRemoveCustomers
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface BulkRemoveCustomers_customerBulkDelete_errors {
|
export interface BulkRemoveCustomers_customerBulkDelete_errors {
|
||||||
__typename: "Error";
|
__typename: "AccountError";
|
||||||
|
code: AccountErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BulkRemoveCustomers_customerBulkDelete {
|
export interface BulkRemoveCustomers_customerBulkDelete {
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { UserCreateInput } from "./../../types/globalTypes";
|
import { UserCreateInput, AccountErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: CreateCustomer
|
// GraphQL mutation operation: CreateCustomer
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface CreateCustomer_customerCreate_errors {
|
export interface CreateCustomer_customerCreate_errors {
|
||||||
__typename: "Error";
|
__typename: "AccountError";
|
||||||
|
code: AccountErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CreateCustomer_customerCreate_user {
|
export interface CreateCustomer_customerCreate_user {
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { AddressInput } from "./../../types/globalTypes";
|
import { AddressInput, AccountErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: CreateCustomerAddress
|
// GraphQL mutation operation: CreateCustomerAddress
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface CreateCustomerAddress_addressCreate_errors {
|
export interface CreateCustomerAddress_addressCreate_errors {
|
||||||
__typename: "Error";
|
__typename: "AccountError";
|
||||||
|
code: AccountErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CreateCustomerAddress_addressCreate_address_country {
|
export interface CreateCustomerAddress_addressCreate_address_country {
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { AccountErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: RemoveCustomer
|
// GraphQL mutation operation: RemoveCustomer
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface RemoveCustomer_customerDelete_errors {
|
export interface RemoveCustomer_customerDelete_errors {
|
||||||
__typename: "Error";
|
__typename: "AccountError";
|
||||||
|
code: AccountErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RemoveCustomer_customerDelete {
|
export interface RemoveCustomer_customerDelete {
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { AccountErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: RemoveCustomerAddress
|
// GraphQL mutation operation: RemoveCustomerAddress
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface RemoveCustomerAddress_addressDelete_errors {
|
export interface RemoveCustomerAddress_addressDelete_errors {
|
||||||
__typename: "Error";
|
__typename: "AccountError";
|
||||||
|
code: AccountErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RemoveCustomerAddress_addressDelete_user_addresses_country {
|
export interface RemoveCustomerAddress_addressDelete_user_addresses_country {
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { AddressTypeEnum } from "./../../types/globalTypes";
|
import { AddressTypeEnum, AccountErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: SetCustomerDefaultAddress
|
// GraphQL mutation operation: SetCustomerDefaultAddress
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface SetCustomerDefaultAddress_addressSetDefault_errors {
|
export interface SetCustomerDefaultAddress_addressSetDefault_errors {
|
||||||
__typename: "Error";
|
__typename: "AccountError";
|
||||||
|
code: AccountErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SetCustomerDefaultAddress_addressSetDefault_user_addresses_country {
|
export interface SetCustomerDefaultAddress_addressSetDefault_user_addresses_country {
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { CustomerInput } from "./../../types/globalTypes";
|
import { CustomerInput, AccountErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: UpdateCustomer
|
// GraphQL mutation operation: UpdateCustomer
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface UpdateCustomer_customerUpdate_errors {
|
export interface UpdateCustomer_customerUpdate_errors {
|
||||||
__typename: "Error";
|
__typename: "AccountError";
|
||||||
|
code: AccountErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdateCustomer_customerUpdate_user_defaultShippingAddress_country {
|
export interface UpdateCustomer_customerUpdate_user_defaultShippingAddress_country {
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { AddressInput } from "./../../types/globalTypes";
|
import { AddressInput, AccountErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: UpdateCustomerAddress
|
// GraphQL mutation operation: UpdateCustomerAddress
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface UpdateCustomerAddress_addressUpdate_errors {
|
export interface UpdateCustomerAddress_addressUpdate_errors {
|
||||||
__typename: "Error";
|
__typename: "AccountError";
|
||||||
|
code: AccountErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdateCustomerAddress_addressUpdate_address_country {
|
export interface UpdateCustomerAddress_addressUpdate_address_country {
|
||||||
|
|
|
@ -41,20 +41,8 @@ export const CustomerCreate: React.FC<{}> = () => {
|
||||||
<CustomerCreatePage
|
<CustomerCreatePage
|
||||||
countries={maybe(() => data.shop.countries, [])}
|
countries={maybe(() => data.shop.countries, [])}
|
||||||
disabled={loading || createCustomerOpts.loading}
|
disabled={loading || createCustomerOpts.loading}
|
||||||
errors={maybe(() => {
|
errors={createCustomerOpts.data?.customerCreate.errors || []}
|
||||||
const errs = createCustomerOpts.data.customerCreate.errors;
|
saveButtonBar={createCustomerOpts.status}
|
||||||
return errs.map(err =>
|
|
||||||
err.field.split(":").length > 1
|
|
||||||
? {
|
|
||||||
...err,
|
|
||||||
field: err.field.split(":")[1]
|
|
||||||
}
|
|
||||||
: err
|
|
||||||
);
|
|
||||||
}, [])}
|
|
||||||
saveButtonBar={
|
|
||||||
createCustomerOpts.loading ? "loading" : "default"
|
|
||||||
}
|
|
||||||
onBack={() => navigate(customerListUrl())}
|
onBack={() => navigate(customerListUrl())}
|
||||||
onSubmit={formData => {
|
onSubmit={formData => {
|
||||||
createCustomer({
|
createCustomer({
|
||||||
|
|
|
@ -8,8 +8,9 @@ import CardTitle from "@saleor/components/CardTitle";
|
||||||
import { ControlledCheckbox } from "@saleor/components/ControlledCheckbox";
|
import { ControlledCheckbox } from "@saleor/components/ControlledCheckbox";
|
||||||
import Grid from "@saleor/components/Grid";
|
import Grid from "@saleor/components/Grid";
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
import { getFieldError } from "@saleor/utils/errors";
|
import { getFormErrors } from "@saleor/utils/errors";
|
||||||
import { UserError } from "../../../types";
|
import getDiscountErrorMessage from "@saleor/utils/errors/discounts";
|
||||||
|
import { DiscountErrorFragment } from "@saleor/discounts/types/DiscountErrorFragment";
|
||||||
|
|
||||||
interface DiscountDatesProps {
|
interface DiscountDatesProps {
|
||||||
data: {
|
data: {
|
||||||
|
@ -21,7 +22,7 @@ interface DiscountDatesProps {
|
||||||
};
|
};
|
||||||
defaultCurrency: string;
|
defaultCurrency: string;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: DiscountErrorFragment[];
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
onChange: (event: React.ChangeEvent<any>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +34,8 @@ const DiscountDates = ({
|
||||||
}: DiscountDatesProps) => {
|
}: DiscountDatesProps) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const formErrors = getFormErrors(["startDate", "endDate"], errors);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
|
@ -45,8 +48,8 @@ const DiscountDates = ({
|
||||||
<Grid variant="uniform">
|
<Grid variant="uniform">
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "startDate")}
|
error={!!formErrors.startDate}
|
||||||
helperText={getFieldError(errors, "startDate")?.message}
|
helperText={getDiscountErrorMessage(formErrors.startDate, intl)}
|
||||||
name={"startDate" as keyof FormData}
|
name={"startDate" as keyof FormData}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
label={intl.formatMessage(commonMessages.startDate)}
|
label={intl.formatMessage(commonMessages.startDate)}
|
||||||
|
@ -59,8 +62,8 @@ const DiscountDates = ({
|
||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "startDate")}
|
error={!!formErrors.startDate}
|
||||||
helperText={getFieldError(errors, "startDate")?.message}
|
helperText={getDiscountErrorMessage(formErrors.startDate, intl)}
|
||||||
name={"startTime" as keyof FormData}
|
name={"startTime" as keyof FormData}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
label={intl.formatMessage(commonMessages.startHour)}
|
label={intl.formatMessage(commonMessages.startHour)}
|
||||||
|
@ -85,8 +88,8 @@ const DiscountDates = ({
|
||||||
<Grid variant="uniform">
|
<Grid variant="uniform">
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "endDate")}
|
error={!!formErrors.endDate}
|
||||||
helperText={getFieldError(errors, "endDate")?.message}
|
helperText={getDiscountErrorMessage(formErrors.endDate, intl)}
|
||||||
name={"endDate" as keyof FormData}
|
name={"endDate" as keyof FormData}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
label={intl.formatMessage(commonMessages.endDate)}
|
label={intl.formatMessage(commonMessages.endDate)}
|
||||||
|
@ -99,8 +102,8 @@ const DiscountDates = ({
|
||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "endDate")}
|
error={!!formErrors.endDate}
|
||||||
helperText={getFieldError(errors, "endDate")?.message}
|
helperText={getDiscountErrorMessage(formErrors.endDate, intl)}
|
||||||
name={"endTime" as keyof FormData}
|
name={"endTime" as keyof FormData}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
label={intl.formatMessage(commonMessages.endHour)}
|
label={intl.formatMessage(commonMessages.endHour)}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import Grid from "@saleor/components/Grid";
|
||||||
import PageHeader from "@saleor/components/PageHeader";
|
import PageHeader from "@saleor/components/PageHeader";
|
||||||
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
||||||
import { sectionNames } from "@saleor/intl";
|
import { sectionNames } from "@saleor/intl";
|
||||||
import { UserError } from "../../../types";
|
import { DiscountErrorFragment } from "@saleor/discounts/types/DiscountErrorFragment";
|
||||||
import { SaleType as SaleTypeEnum } from "../../../types/globalTypes";
|
import { SaleType as SaleTypeEnum } from "../../../types/globalTypes";
|
||||||
import DiscountDates from "../DiscountDates";
|
import DiscountDates from "../DiscountDates";
|
||||||
import SaleInfo from "../SaleInfo";
|
import SaleInfo from "../SaleInfo";
|
||||||
|
@ -30,7 +30,7 @@ export interface FormData {
|
||||||
export interface SaleCreatePageProps {
|
export interface SaleCreatePageProps {
|
||||||
defaultCurrency: string;
|
defaultCurrency: string;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: DiscountErrorFragment[];
|
||||||
saveButtonBarState: ConfirmButtonTransitionState;
|
saveButtonBarState: ConfirmButtonTransitionState;
|
||||||
onBack: () => void;
|
onBack: () => void;
|
||||||
onSubmit: (data: FormData) => void;
|
onSubmit: (data: FormData) => void;
|
||||||
|
|
|
@ -11,8 +11,9 @@ import PageHeader from "@saleor/components/PageHeader";
|
||||||
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
||||||
import { Tab, TabContainer } from "@saleor/components/Tab";
|
import { Tab, TabContainer } from "@saleor/components/Tab";
|
||||||
import { sectionNames } from "@saleor/intl";
|
import { sectionNames } from "@saleor/intl";
|
||||||
|
import { DiscountErrorFragment } from "@saleor/discounts/types/DiscountErrorFragment";
|
||||||
import { maybe, splitDateTime } from "../../../misc";
|
import { maybe, splitDateTime } from "../../../misc";
|
||||||
import { ListProps, TabListActions, UserError } from "../../../types";
|
import { ListProps, TabListActions } from "../../../types";
|
||||||
import { SaleType as SaleTypeEnum } from "../../../types/globalTypes";
|
import { SaleType as SaleTypeEnum } from "../../../types/globalTypes";
|
||||||
import { SaleDetails_sale } from "../../types/SaleDetails";
|
import { SaleDetails_sale } from "../../types/SaleDetails";
|
||||||
import DiscountCategories from "../DiscountCategories";
|
import DiscountCategories from "../DiscountCategories";
|
||||||
|
@ -55,7 +56,7 @@ export interface SaleDetailsPageProps
|
||||||
> {
|
> {
|
||||||
activeTab: SaleDetailsPageTab;
|
activeTab: SaleDetailsPageTab;
|
||||||
defaultCurrency: string;
|
defaultCurrency: string;
|
||||||
errors: UserError[];
|
errors: DiscountErrorFragment[];
|
||||||
sale: SaleDetails_sale;
|
sale: SaleDetails_sale;
|
||||||
saveButtonBarState: ConfirmButtonTransitionState;
|
saveButtonBarState: ConfirmButtonTransitionState;
|
||||||
onBack: () => void;
|
onBack: () => void;
|
||||||
|
|
|
@ -6,14 +6,15 @@ import { useIntl } from "react-intl";
|
||||||
|
|
||||||
import CardTitle from "@saleor/components/CardTitle";
|
import CardTitle from "@saleor/components/CardTitle";
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
import { UserError } from "@saleor/types";
|
import { getFormErrors } from "@saleor/utils/errors";
|
||||||
import { getFieldError } from "@saleor/utils/errors";
|
import { DiscountErrorFragment } from "@saleor/discounts/types/DiscountErrorFragment";
|
||||||
|
import getDiscountErrorMessage from "@saleor/utils/errors/discounts";
|
||||||
import { FormData } from "../SaleDetailsPage";
|
import { FormData } from "../SaleDetailsPage";
|
||||||
|
|
||||||
export interface SaleInfoProps {
|
export interface SaleInfoProps {
|
||||||
data: FormData;
|
data: FormData;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: DiscountErrorFragment[];
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
onChange: (event: React.ChangeEvent<any>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +26,8 @@ const SaleInfo: React.FC<SaleInfoProps> = ({
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const formErrors = getFormErrors(["name"], errors);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
|
@ -33,8 +36,8 @@ const SaleInfo: React.FC<SaleInfoProps> = ({
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "name")}
|
error={!!formErrors.name}
|
||||||
helperText={getFieldError(errors, "name")?.message}
|
helperText={getDiscountErrorMessage(formErrors.name, intl)}
|
||||||
name={"name" as keyof FormData}
|
name={"name" as keyof FormData}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
|
|
|
@ -6,16 +6,17 @@ import { useIntl } from "react-intl";
|
||||||
|
|
||||||
import CardTitle from "@saleor/components/CardTitle";
|
import CardTitle from "@saleor/components/CardTitle";
|
||||||
import { FormChange } from "@saleor/hooks/useForm";
|
import { FormChange } from "@saleor/hooks/useForm";
|
||||||
import { UserError } from "@saleor/types";
|
|
||||||
import { SaleType } from "@saleor/types/globalTypes";
|
import { SaleType } from "@saleor/types/globalTypes";
|
||||||
import { getFieldError } from "@saleor/utils/errors";
|
import { getFormErrors } from "@saleor/utils/errors";
|
||||||
|
import getDiscountErrorMessage from "@saleor/utils/errors/discounts";
|
||||||
|
import { DiscountErrorFragment } from "@saleor/discounts/types/DiscountErrorFragment";
|
||||||
import { FormData } from "../SaleDetailsPage";
|
import { FormData } from "../SaleDetailsPage";
|
||||||
|
|
||||||
export interface SaleValueProps {
|
export interface SaleValueProps {
|
||||||
currencySymbol: string;
|
currencySymbol: string;
|
||||||
data: FormData;
|
data: FormData;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: DiscountErrorFragment[];
|
||||||
onChange: FormChange;
|
onChange: FormChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +29,8 @@ const SaleValue: React.FC<SaleValueProps> = ({
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const formErrors = getFormErrors(["value"], errors);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
|
@ -44,12 +47,12 @@ const SaleValue: React.FC<SaleValueProps> = ({
|
||||||
defaultMessage: "Discount Value",
|
defaultMessage: "Discount Value",
|
||||||
description: "sale discount"
|
description: "sale discount"
|
||||||
})}
|
})}
|
||||||
error={!!getFieldError(errors, "value")}
|
error={!!formErrors.value}
|
||||||
name="value"
|
name="value"
|
||||||
InputProps={{
|
InputProps={{
|
||||||
endAdornment: data.type === SaleType.FIXED ? currencySymbol : "%"
|
endAdornment: data.type === SaleType.FIXED ? currencySymbol : "%"
|
||||||
}}
|
}}
|
||||||
helperText={getFieldError(errors, "value")?.message}
|
helperText={getDiscountErrorMessage(formErrors.value, intl)}
|
||||||
value={data.value}
|
value={data.value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -10,7 +10,7 @@ import Grid from "@saleor/components/Grid";
|
||||||
import PageHeader from "@saleor/components/PageHeader";
|
import PageHeader from "@saleor/components/PageHeader";
|
||||||
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
||||||
import { sectionNames } from "@saleor/intl";
|
import { sectionNames } from "@saleor/intl";
|
||||||
import { UserError } from "../../../types";
|
import { DiscountErrorFragment } from "@saleor/discounts/types/DiscountErrorFragment";
|
||||||
import {
|
import {
|
||||||
DiscountValueTypeEnum,
|
DiscountValueTypeEnum,
|
||||||
VoucherTypeEnum
|
VoucherTypeEnum
|
||||||
|
@ -21,8 +21,8 @@ import VoucherInfo from "../VoucherInfo";
|
||||||
import VoucherLimits from "../VoucherLimits";
|
import VoucherLimits from "../VoucherLimits";
|
||||||
import VoucherRequirements from "../VoucherRequirements";
|
import VoucherRequirements from "../VoucherRequirements";
|
||||||
import VoucherTypes from "../VoucherTypes";
|
import VoucherTypes from "../VoucherTypes";
|
||||||
|
|
||||||
import VoucherValue from "../VoucherValue";
|
import VoucherValue from "../VoucherValue";
|
||||||
|
|
||||||
export interface FormData {
|
export interface FormData {
|
||||||
applyOncePerCustomer: boolean;
|
applyOncePerCustomer: boolean;
|
||||||
applyOncePerOrder: boolean;
|
applyOncePerOrder: boolean;
|
||||||
|
@ -45,7 +45,7 @@ export interface FormData {
|
||||||
export interface VoucherCreatePageProps {
|
export interface VoucherCreatePageProps {
|
||||||
defaultCurrency: string;
|
defaultCurrency: string;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: DiscountErrorFragment[];
|
||||||
saveButtonBarState: ConfirmButtonTransitionState;
|
saveButtonBarState: ConfirmButtonTransitionState;
|
||||||
onBack: () => void;
|
onBack: () => void;
|
||||||
onSubmit: (data: FormData) => void;
|
onSubmit: (data: FormData) => void;
|
||||||
|
|
|
@ -8,15 +8,16 @@ import CardTitle from "@saleor/components/CardTitle";
|
||||||
import { ControlledCheckbox } from "@saleor/components/ControlledCheckbox";
|
import { ControlledCheckbox } from "@saleor/components/ControlledCheckbox";
|
||||||
import Grid from "@saleor/components/Grid";
|
import Grid from "@saleor/components/Grid";
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
import { getFieldError } from "@saleor/utils/errors";
|
import { getFormErrors } from "@saleor/utils/errors";
|
||||||
import { UserError } from "../../../types";
|
import getDiscountErrorMessage from "@saleor/utils/errors/discounts";
|
||||||
|
import { DiscountErrorFragment } from "@saleor/discounts/types/DiscountErrorFragment";
|
||||||
import { FormData } from "../VoucherDetailsPage";
|
import { FormData } from "../VoucherDetailsPage";
|
||||||
|
|
||||||
interface VoucherDatesProps {
|
interface VoucherDatesProps {
|
||||||
data: FormData;
|
data: FormData;
|
||||||
defaultCurrency: string;
|
defaultCurrency: string;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: DiscountErrorFragment[];
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
onChange: (event: React.ChangeEvent<any>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +29,8 @@ const VoucherDates = ({
|
||||||
}: VoucherDatesProps) => {
|
}: VoucherDatesProps) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const formErrors = getFormErrors(["startDate", "endDate"], errors);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
|
@ -40,8 +43,8 @@ const VoucherDates = ({
|
||||||
<Grid variant="uniform">
|
<Grid variant="uniform">
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "startDate")}
|
error={!!formErrors.startDate}
|
||||||
helperText={getFieldError(errors, "startDate")?.message}
|
helperText={getDiscountErrorMessage(formErrors.startDate, intl)}
|
||||||
name={"startDate" as keyof FormData}
|
name={"startDate" as keyof FormData}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
label={intl.formatMessage(commonMessages.startDate)}
|
label={intl.formatMessage(commonMessages.startDate)}
|
||||||
|
@ -54,8 +57,8 @@ const VoucherDates = ({
|
||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "startDate")}
|
error={!!formErrors.startDate}
|
||||||
helperText={getFieldError(errors, "startDate")?.message}
|
helperText={getDiscountErrorMessage(formErrors.startDate, intl)}
|
||||||
name={"startTime" as keyof FormData}
|
name={"startTime" as keyof FormData}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
label={intl.formatMessage(commonMessages.startHour)}
|
label={intl.formatMessage(commonMessages.startHour)}
|
||||||
|
@ -80,8 +83,8 @@ const VoucherDates = ({
|
||||||
<Grid variant="uniform">
|
<Grid variant="uniform">
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "endDate")}
|
error={!!formErrors.endDate}
|
||||||
helperText={getFieldError(errors, "endDate")?.message}
|
helperText={getDiscountErrorMessage(formErrors.endDate, intl)}
|
||||||
name={"endDate" as keyof FormData}
|
name={"endDate" as keyof FormData}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
label={intl.formatMessage(commonMessages.endDate)}
|
label={intl.formatMessage(commonMessages.endDate)}
|
||||||
|
@ -94,8 +97,8 @@ const VoucherDates = ({
|
||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "endDate")}
|
error={!!formErrors.endDate}
|
||||||
helperText={getFieldError(errors, "endDate")?.message}
|
helperText={getDiscountErrorMessage(formErrors.endDate, intl)}
|
||||||
name={"endTime" as keyof FormData}
|
name={"endTime" as keyof FormData}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
label={intl.formatMessage(commonMessages.endHour)}
|
label={intl.formatMessage(commonMessages.endHour)}
|
||||||
|
|
|
@ -14,8 +14,9 @@ import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
||||||
import { Tab, TabContainer } from "@saleor/components/Tab";
|
import { Tab, TabContainer } from "@saleor/components/Tab";
|
||||||
import { RequirementsPicker } from "@saleor/discounts/types";
|
import { RequirementsPicker } from "@saleor/discounts/types";
|
||||||
import { sectionNames } from "@saleor/intl";
|
import { sectionNames } from "@saleor/intl";
|
||||||
|
import { DiscountErrorFragment } from "@saleor/discounts/types/DiscountErrorFragment";
|
||||||
import { maybe, splitDateTime } from "../../../misc";
|
import { maybe, splitDateTime } from "../../../misc";
|
||||||
import { ListProps, TabListActions, UserError } from "../../../types";
|
import { ListProps, TabListActions } from "../../../types";
|
||||||
import {
|
import {
|
||||||
DiscountValueTypeEnum,
|
DiscountValueTypeEnum,
|
||||||
VoucherTypeEnum
|
VoucherTypeEnum
|
||||||
|
@ -72,7 +73,7 @@ export interface VoucherDetailsPageProps
|
||||||
> {
|
> {
|
||||||
activeTab: VoucherDetailsPageTab;
|
activeTab: VoucherDetailsPageTab;
|
||||||
defaultCurrency: string;
|
defaultCurrency: string;
|
||||||
errors: UserError[];
|
errors: DiscountErrorFragment[];
|
||||||
saveButtonBarState: ConfirmButtonTransitionState;
|
saveButtonBarState: ConfirmButtonTransitionState;
|
||||||
voucher: VoucherDetails_voucher;
|
voucher: VoucherDetails_voucher;
|
||||||
onBack: () => void;
|
onBack: () => void;
|
||||||
|
|
|
@ -7,14 +7,15 @@ import { FormattedMessage, useIntl } from "react-intl";
|
||||||
import Button from "@material-ui/core/Button";
|
import Button from "@material-ui/core/Button";
|
||||||
import CardTitle from "@saleor/components/CardTitle";
|
import CardTitle from "@saleor/components/CardTitle";
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
import { getFieldError } from "@saleor/utils/errors";
|
import { DiscountErrorFragment } from "@saleor/discounts/types/DiscountErrorFragment";
|
||||||
import { generateCode } from "../../../misc";
|
import { getFormErrors } from "@saleor/utils/errors";
|
||||||
import { UserError } from "../../../types";
|
import getDiscountErrorMessage from "@saleor/utils/errors/discounts";
|
||||||
import { FormData } from "../VoucherDetailsPage";
|
import { FormData } from "../VoucherDetailsPage";
|
||||||
|
import { generateCode } from "../../../misc";
|
||||||
|
|
||||||
interface VoucherInfoProps {
|
interface VoucherInfoProps {
|
||||||
data: FormData;
|
data: FormData;
|
||||||
errors: UserError[];
|
errors: DiscountErrorFragment[];
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
variant: "create" | "update";
|
variant: "create" | "update";
|
||||||
onChange: (event: any) => void;
|
onChange: (event: any) => void;
|
||||||
|
@ -29,6 +30,8 @@ const VoucherInfo = ({
|
||||||
}: VoucherInfoProps) => {
|
}: VoucherInfoProps) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const formErrors = getFormErrors(["code"], errors);
|
||||||
|
|
||||||
const onGenerateCode = () =>
|
const onGenerateCode = () =>
|
||||||
onChange({
|
onChange({
|
||||||
target: {
|
target: {
|
||||||
|
@ -55,9 +58,9 @@ const VoucherInfo = ({
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={variant === "update" || disabled}
|
disabled={variant === "update" || disabled}
|
||||||
error={!!getFieldError(errors, "code")}
|
error={!!formErrors.code}
|
||||||
fullWidth
|
fullWidth
|
||||||
helperText={getFieldError(errors, "code")?.message}
|
helperText={getDiscountErrorMessage(formErrors.code, intl)}
|
||||||
name={"code" as keyof FormData}
|
name={"code" as keyof FormData}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Discount Code"
|
defaultMessage: "Discount Code"
|
||||||
|
|
|
@ -6,15 +6,16 @@ import { useIntl } from "react-intl";
|
||||||
|
|
||||||
import CardTitle from "@saleor/components/CardTitle";
|
import CardTitle from "@saleor/components/CardTitle";
|
||||||
import { ControlledCheckbox } from "@saleor/components/ControlledCheckbox";
|
import { ControlledCheckbox } from "@saleor/components/ControlledCheckbox";
|
||||||
import { getFieldError } from "@saleor/utils/errors";
|
import { getFormErrors } from "@saleor/utils/errors";
|
||||||
import { UserError } from "../../../types";
|
import { DiscountErrorFragment } from "@saleor/discounts/types/DiscountErrorFragment";
|
||||||
|
import getDiscountErrorMessage from "@saleor/utils/errors/discounts";
|
||||||
import { FormData } from "../VoucherDetailsPage";
|
import { FormData } from "../VoucherDetailsPage";
|
||||||
|
|
||||||
interface VoucherLimitsProps {
|
interface VoucherLimitsProps {
|
||||||
data: FormData;
|
data: FormData;
|
||||||
defaultCurrency: string;
|
defaultCurrency: string;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: DiscountErrorFragment[];
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
onChange: (event: React.ChangeEvent<any>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +27,8 @@ const VoucherLimits = ({
|
||||||
}: VoucherLimitsProps) => {
|
}: VoucherLimitsProps) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const formErrors = getFormErrors(["usageLimit"], errors);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
|
@ -47,8 +50,8 @@ const VoucherLimits = ({
|
||||||
{data.hasUsageLimit && (
|
{data.hasUsageLimit && (
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "usageLimit")}
|
error={!!formErrors.usageLimit}
|
||||||
helperText={getFieldError(errors, "usageLimit")?.message}
|
helperText={getDiscountErrorMessage(formErrors.usageLimit, intl)}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Limit of Uses",
|
defaultMessage: "Limit of Uses",
|
||||||
description: "voucher"
|
description: "voucher"
|
||||||
|
|
|
@ -8,15 +8,16 @@ import CardTitle from "@saleor/components/CardTitle";
|
||||||
import { FormSpacer } from "@saleor/components/FormSpacer";
|
import { FormSpacer } from "@saleor/components/FormSpacer";
|
||||||
import RadioGroupField from "@saleor/components/RadioGroupField";
|
import RadioGroupField from "@saleor/components/RadioGroupField";
|
||||||
import { RequirementsPicker } from "@saleor/discounts/types";
|
import { RequirementsPicker } from "@saleor/discounts/types";
|
||||||
import { UserError } from "@saleor/types";
|
import { DiscountErrorFragment } from "@saleor/discounts/types/DiscountErrorFragment";
|
||||||
import { getFieldError } from "@saleor/utils/errors";
|
import { getFormErrors } from "@saleor/utils/errors";
|
||||||
|
import getDiscountErrorMessage from "@saleor/utils/errors/discounts";
|
||||||
import { FormData } from "../VoucherDetailsPage";
|
import { FormData } from "../VoucherDetailsPage";
|
||||||
|
|
||||||
interface VoucherRequirementsProps {
|
interface VoucherRequirementsProps {
|
||||||
data: FormData;
|
data: FormData;
|
||||||
defaultCurrency: string;
|
defaultCurrency: string;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: DiscountErrorFragment[];
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
onChange: (event: React.ChangeEvent<any>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +29,11 @@ const VoucherRequirements = ({
|
||||||
}: VoucherRequirementsProps) => {
|
}: VoucherRequirementsProps) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const formErrors = getFormErrors(
|
||||||
|
["minSpent", "minCheckoutItemsQuantity"],
|
||||||
|
errors
|
||||||
|
);
|
||||||
|
|
||||||
const minimalOrderValueText = intl.formatMessage({
|
const minimalOrderValueText = intl.formatMessage({
|
||||||
defaultMessage: "Minimal order value",
|
defaultMessage: "Minimal order value",
|
||||||
description: "voucher requirement"
|
description: "voucher requirement"
|
||||||
|
@ -77,8 +83,8 @@ const VoucherRequirements = ({
|
||||||
{data.requirementsPicker === RequirementsPicker.ORDER ? (
|
{data.requirementsPicker === RequirementsPicker.ORDER ? (
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "minSpent")}
|
error={!!formErrors.minSpent}
|
||||||
helperText={getFieldError(errors, "minSpent")?.message}
|
helperText={getDiscountErrorMessage(formErrors.minSpent, intl)}
|
||||||
label={minimalOrderValueText}
|
label={minimalOrderValueText}
|
||||||
name={"minSpent" as keyof FormData}
|
name={"minSpent" as keyof FormData}
|
||||||
value={data.minSpent}
|
value={data.minSpent}
|
||||||
|
@ -88,10 +94,11 @@ const VoucherRequirements = ({
|
||||||
) : data.requirementsPicker === RequirementsPicker.ITEM ? (
|
) : data.requirementsPicker === RequirementsPicker.ITEM ? (
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "minCheckoutItemsQuantity")}
|
error={!!formErrors.minCheckoutItemsQuantity}
|
||||||
helperText={
|
helperText={getDiscountErrorMessage(
|
||||||
getFieldError(errors, "minCheckoutItemsQuantity")?.message
|
formErrors.minCheckoutItemsQuantity,
|
||||||
}
|
intl
|
||||||
|
)}
|
||||||
label={minimalQuantityText}
|
label={minimalQuantityText}
|
||||||
name={"minCheckoutItemsQuantity" as keyof FormData}
|
name={"minCheckoutItemsQuantity" as keyof FormData}
|
||||||
value={data.minCheckoutItemsQuantity}
|
value={data.minCheckoutItemsQuantity}
|
||||||
|
|
|
@ -6,14 +6,15 @@ import { useIntl } from "react-intl";
|
||||||
import CardTitle from "@saleor/components/CardTitle";
|
import CardTitle from "@saleor/components/CardTitle";
|
||||||
import Grid from "@saleor/components/Grid";
|
import Grid from "@saleor/components/Grid";
|
||||||
import RadioGroupField from "@saleor/components/RadioGroupField";
|
import RadioGroupField from "@saleor/components/RadioGroupField";
|
||||||
import { getFieldError } from "@saleor/utils/errors";
|
import { DiscountErrorFragment } from "@saleor/discounts/types/DiscountErrorFragment";
|
||||||
import { UserError } from "../../../types";
|
import { getFormErrors } from "@saleor/utils/errors";
|
||||||
import { DiscountValueTypeEnum } from "../../../types/globalTypes";
|
import getDiscountErrorMessage from "@saleor/utils/errors/discounts";
|
||||||
import { FormData } from "../VoucherDetailsPage";
|
import { FormData } from "../VoucherDetailsPage";
|
||||||
|
import { DiscountValueTypeEnum } from "../../../types/globalTypes";
|
||||||
|
|
||||||
interface VoucherTypesProps {
|
interface VoucherTypesProps {
|
||||||
data: FormData;
|
data: FormData;
|
||||||
errors: UserError[];
|
errors: DiscountErrorFragment[];
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
onChange: (event: React.ChangeEvent<any>) => void;
|
||||||
}
|
}
|
||||||
|
@ -26,6 +27,8 @@ const VoucherTypes = ({
|
||||||
}: VoucherTypesProps) => {
|
}: VoucherTypesProps) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const formErrors = getFormErrors(["discountType"], errors);
|
||||||
|
|
||||||
const voucherTypeChoices = [
|
const voucherTypeChoices = [
|
||||||
{
|
{
|
||||||
label: intl.formatMessage({
|
label: intl.formatMessage({
|
||||||
|
@ -63,8 +66,8 @@ const VoucherTypes = ({
|
||||||
<RadioGroupField
|
<RadioGroupField
|
||||||
choices={voucherTypeChoices}
|
choices={voucherTypeChoices}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "discountType")}
|
error={!!formErrors.discountType}
|
||||||
hint={getFieldError(errors, "discountType")?.message}
|
hint={getDiscountErrorMessage(formErrors.discountType, intl)}
|
||||||
name={"discountType" as keyof FormData}
|
name={"discountType" as keyof FormData}
|
||||||
value={data.discountType}
|
value={data.discountType}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
|
|
|
@ -11,8 +11,9 @@ import { FormSpacer } from "@saleor/components/FormSpacer";
|
||||||
import Hr from "@saleor/components/Hr";
|
import Hr from "@saleor/components/Hr";
|
||||||
import RadioGroupField from "@saleor/components/RadioGroupField";
|
import RadioGroupField from "@saleor/components/RadioGroupField";
|
||||||
import TextFieldWithChoice from "@saleor/components/TextFieldWithChoice";
|
import TextFieldWithChoice from "@saleor/components/TextFieldWithChoice";
|
||||||
import { getFieldError } from "@saleor/utils/errors";
|
import { DiscountErrorFragment } from "@saleor/discounts/types/DiscountErrorFragment";
|
||||||
import { UserError } from "../../../types";
|
import { getFormErrors } from "@saleor/utils/errors";
|
||||||
|
import getDiscountErrorMessage from "@saleor/utils/errors/discounts";
|
||||||
import { DiscountValueTypeEnum } from "../../../types/globalTypes";
|
import { DiscountValueTypeEnum } from "../../../types/globalTypes";
|
||||||
import { translateVoucherTypes } from "../../translations";
|
import { translateVoucherTypes } from "../../translations";
|
||||||
import { FormData } from "../VoucherDetailsPage";
|
import { FormData } from "../VoucherDetailsPage";
|
||||||
|
@ -20,7 +21,7 @@ import { FormData } from "../VoucherDetailsPage";
|
||||||
interface VoucherValueProps {
|
interface VoucherValueProps {
|
||||||
data: FormData;
|
data: FormData;
|
||||||
defaultCurrency: string;
|
defaultCurrency: string;
|
||||||
errors: UserError[];
|
errors: DiscountErrorFragment[];
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
variant: string;
|
variant: string;
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
onChange: (event: React.ChangeEvent<any>) => void;
|
||||||
|
@ -48,6 +49,8 @@ const VoucherValue: React.FC<VoucherValueProps> = props => {
|
||||||
const classes = useStyles(props);
|
const classes = useStyles(props);
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const formErrors = getFormErrors(["discountValue", "type"], errors);
|
||||||
|
|
||||||
const translatedVoucherTypes = translateVoucherTypes(intl);
|
const translatedVoucherTypes = translateVoucherTypes(intl);
|
||||||
const voucherTypeChoices = Object.values(VoucherType).map(type => ({
|
const voucherTypeChoices = Object.values(VoucherType).map(type => ({
|
||||||
label: translatedVoucherTypes[type],
|
label: translatedVoucherTypes[type],
|
||||||
|
@ -65,7 +68,7 @@ const VoucherValue: React.FC<VoucherValueProps> = props => {
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<TextFieldWithChoice
|
<TextFieldWithChoice
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "discountValue")}
|
error={!!formErrors.discountValue}
|
||||||
ChoiceProps={{
|
ChoiceProps={{
|
||||||
label:
|
label:
|
||||||
data.discountType === DiscountValueTypeEnum.FIXED
|
data.discountType === DiscountValueTypeEnum.FIXED
|
||||||
|
@ -74,7 +77,7 @@ const VoucherValue: React.FC<VoucherValueProps> = props => {
|
||||||
name: "discountType" as keyof FormData,
|
name: "discountType" as keyof FormData,
|
||||||
values: null
|
values: null
|
||||||
}}
|
}}
|
||||||
helperText={getFieldError(errors, "discountValue")?.message}
|
helperText={getDiscountErrorMessage(formErrors.discountValue, intl)}
|
||||||
name={"value" as keyof FormData}
|
name={"value" as keyof FormData}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
|
@ -94,8 +97,8 @@ const VoucherValue: React.FC<VoucherValueProps> = props => {
|
||||||
<RadioGroupField
|
<RadioGroupField
|
||||||
choices={voucherTypeChoices}
|
choices={voucherTypeChoices}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "type")}
|
error={!!formErrors.type}
|
||||||
hint={getFieldError(errors, "type")?.message}
|
hint={getDiscountErrorMessage(formErrors.type, intl)}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Voucher Specific Information"
|
defaultMessage: "Voucher Specific Information"
|
||||||
})}
|
})}
|
||||||
|
|
|
@ -38,13 +38,20 @@ import { VoucherCreate, VoucherCreateVariables } from "./types/VoucherCreate";
|
||||||
import { VoucherDelete, VoucherDeleteVariables } from "./types/VoucherDelete";
|
import { VoucherDelete, VoucherDeleteVariables } from "./types/VoucherDelete";
|
||||||
import { VoucherUpdate, VoucherUpdateVariables } from "./types/VoucherUpdate";
|
import { VoucherUpdate, VoucherUpdateVariables } from "./types/VoucherUpdate";
|
||||||
|
|
||||||
|
const discountErrorFragment = gql`
|
||||||
|
fragment DiscountErrorFragment on DiscountError {
|
||||||
|
code
|
||||||
|
field
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
const saleUpdate = gql`
|
const saleUpdate = gql`
|
||||||
|
${discountErrorFragment}
|
||||||
${saleFragment}
|
${saleFragment}
|
||||||
mutation SaleUpdate($input: SaleInput!, $id: ID!) {
|
mutation SaleUpdate($input: SaleInput!, $id: ID!) {
|
||||||
saleUpdate(id: $id, input: $input) {
|
saleUpdate(id: $id, input: $input) {
|
||||||
errors {
|
errors: discountErrors {
|
||||||
field
|
...DiscountErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
sale {
|
sale {
|
||||||
...SaleFragment
|
...SaleFragment
|
||||||
|
@ -57,6 +64,7 @@ export const TypedSaleUpdate = TypedMutation<SaleUpdate, SaleUpdateVariables>(
|
||||||
);
|
);
|
||||||
|
|
||||||
const saleCataloguesAdd = gql`
|
const saleCataloguesAdd = gql`
|
||||||
|
${discountErrorFragment}
|
||||||
${saleDetailsFragment}
|
${saleDetailsFragment}
|
||||||
mutation SaleCataloguesAdd(
|
mutation SaleCataloguesAdd(
|
||||||
$input: CatalogueInput!
|
$input: CatalogueInput!
|
||||||
|
@ -67,9 +75,8 @@ const saleCataloguesAdd = gql`
|
||||||
$last: Int
|
$last: Int
|
||||||
) {
|
) {
|
||||||
saleCataloguesAdd(id: $id, input: $input) {
|
saleCataloguesAdd(id: $id, input: $input) {
|
||||||
errors {
|
errors: discountErrors {
|
||||||
field
|
...DiscountErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
sale {
|
sale {
|
||||||
...SaleDetailsFragment
|
...SaleDetailsFragment
|
||||||
|
@ -83,6 +90,7 @@ export const TypedSaleCataloguesAdd = TypedMutation<
|
||||||
>(saleCataloguesAdd);
|
>(saleCataloguesAdd);
|
||||||
|
|
||||||
const saleCataloguesRemove = gql`
|
const saleCataloguesRemove = gql`
|
||||||
|
${discountErrorFragment}
|
||||||
${saleDetailsFragment}
|
${saleDetailsFragment}
|
||||||
mutation SaleCataloguesRemove(
|
mutation SaleCataloguesRemove(
|
||||||
$input: CatalogueInput!
|
$input: CatalogueInput!
|
||||||
|
@ -93,9 +101,8 @@ const saleCataloguesRemove = gql`
|
||||||
$last: Int
|
$last: Int
|
||||||
) {
|
) {
|
||||||
saleCataloguesRemove(id: $id, input: $input) {
|
saleCataloguesRemove(id: $id, input: $input) {
|
||||||
errors {
|
errors: discountErrors {
|
||||||
field
|
...DiscountErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
sale {
|
sale {
|
||||||
...SaleDetailsFragment
|
...SaleDetailsFragment
|
||||||
|
@ -109,12 +116,12 @@ export const TypedSaleCataloguesRemove = TypedMutation<
|
||||||
>(saleCataloguesRemove);
|
>(saleCataloguesRemove);
|
||||||
|
|
||||||
const saleCreate = gql`
|
const saleCreate = gql`
|
||||||
|
${discountErrorFragment}
|
||||||
${saleFragment}
|
${saleFragment}
|
||||||
mutation SaleCreate($input: SaleInput!) {
|
mutation SaleCreate($input: SaleInput!) {
|
||||||
saleCreate(input: $input) {
|
saleCreate(input: $input) {
|
||||||
errors {
|
errors: discountErrors {
|
||||||
field
|
...DiscountErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
sale {
|
sale {
|
||||||
...SaleFragment
|
...SaleFragment
|
||||||
|
@ -127,11 +134,11 @@ export const TypedSaleCreate = TypedMutation<SaleCreate, SaleCreateVariables>(
|
||||||
);
|
);
|
||||||
|
|
||||||
const saleDelete = gql`
|
const saleDelete = gql`
|
||||||
|
${discountErrorFragment}
|
||||||
mutation SaleDelete($id: ID!) {
|
mutation SaleDelete($id: ID!) {
|
||||||
saleDelete(id: $id) {
|
saleDelete(id: $id) {
|
||||||
errors {
|
errors: discountErrors {
|
||||||
field
|
...DiscountErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,12 +163,12 @@ export const TypedSaleBulkDelete = TypedMutation<
|
||||||
>(saleBulkDelete);
|
>(saleBulkDelete);
|
||||||
|
|
||||||
const voucherUpdate = gql`
|
const voucherUpdate = gql`
|
||||||
|
${discountErrorFragment}
|
||||||
${voucherFragment}
|
${voucherFragment}
|
||||||
mutation VoucherUpdate($input: VoucherInput!, $id: ID!) {
|
mutation VoucherUpdate($input: VoucherInput!, $id: ID!) {
|
||||||
voucherUpdate(id: $id, input: $input) {
|
voucherUpdate(id: $id, input: $input) {
|
||||||
errors {
|
errors: discountErrors {
|
||||||
field
|
...DiscountErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
voucher {
|
voucher {
|
||||||
...VoucherFragment
|
...VoucherFragment
|
||||||
|
@ -175,6 +182,7 @@ export const TypedVoucherUpdate = TypedMutation<
|
||||||
>(voucherUpdate);
|
>(voucherUpdate);
|
||||||
|
|
||||||
const voucherCataloguesAdd = gql`
|
const voucherCataloguesAdd = gql`
|
||||||
|
${discountErrorFragment}
|
||||||
${voucherDetailsFragment}
|
${voucherDetailsFragment}
|
||||||
mutation VoucherCataloguesAdd(
|
mutation VoucherCataloguesAdd(
|
||||||
$input: CatalogueInput!
|
$input: CatalogueInput!
|
||||||
|
@ -185,9 +193,8 @@ const voucherCataloguesAdd = gql`
|
||||||
$last: Int
|
$last: Int
|
||||||
) {
|
) {
|
||||||
voucherCataloguesAdd(id: $id, input: $input) {
|
voucherCataloguesAdd(id: $id, input: $input) {
|
||||||
errors {
|
errors: discountErrors {
|
||||||
field
|
...DiscountErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
voucher {
|
voucher {
|
||||||
...VoucherDetailsFragment
|
...VoucherDetailsFragment
|
||||||
|
@ -201,6 +208,7 @@ export const TypedVoucherCataloguesAdd = TypedMutation<
|
||||||
>(voucherCataloguesAdd);
|
>(voucherCataloguesAdd);
|
||||||
|
|
||||||
const voucherCataloguesRemove = gql`
|
const voucherCataloguesRemove = gql`
|
||||||
|
${discountErrorFragment}
|
||||||
${voucherDetailsFragment}
|
${voucherDetailsFragment}
|
||||||
mutation VoucherCataloguesRemove(
|
mutation VoucherCataloguesRemove(
|
||||||
$input: CatalogueInput!
|
$input: CatalogueInput!
|
||||||
|
@ -211,9 +219,8 @@ const voucherCataloguesRemove = gql`
|
||||||
$last: Int
|
$last: Int
|
||||||
) {
|
) {
|
||||||
voucherCataloguesRemove(id: $id, input: $input) {
|
voucherCataloguesRemove(id: $id, input: $input) {
|
||||||
errors {
|
errors: discountErrors {
|
||||||
field
|
...DiscountErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
voucher {
|
voucher {
|
||||||
...VoucherDetailsFragment
|
...VoucherDetailsFragment
|
||||||
|
@ -227,12 +234,12 @@ export const TypedVoucherCataloguesRemove = TypedMutation<
|
||||||
>(voucherCataloguesRemove);
|
>(voucherCataloguesRemove);
|
||||||
|
|
||||||
const voucherCreate = gql`
|
const voucherCreate = gql`
|
||||||
|
${discountErrorFragment}
|
||||||
${voucherFragment}
|
${voucherFragment}
|
||||||
mutation VoucherCreate($input: VoucherInput!) {
|
mutation VoucherCreate($input: VoucherInput!) {
|
||||||
voucherCreate(input: $input) {
|
voucherCreate(input: $input) {
|
||||||
errors {
|
errors: discountErrors {
|
||||||
field
|
...DiscountErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
voucher {
|
voucher {
|
||||||
...VoucherFragment
|
...VoucherFragment
|
||||||
|
@ -246,11 +253,11 @@ export const TypedVoucherCreate = TypedMutation<
|
||||||
>(voucherCreate);
|
>(voucherCreate);
|
||||||
|
|
||||||
const voucherDelete = gql`
|
const voucherDelete = gql`
|
||||||
|
${discountErrorFragment}
|
||||||
mutation VoucherDelete($id: ID!) {
|
mutation VoucherDelete($id: ID!) {
|
||||||
voucherDelete(id: $id) {
|
voucherDelete(id: $id) {
|
||||||
errors {
|
errors: discountErrors {
|
||||||
field
|
...DiscountErrorFragment
|
||||||
message
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
15
src/discounts/types/DiscountErrorFragment.ts
Normal file
15
src/discounts/types/DiscountErrorFragment.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { DiscountErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
|
// ====================================================
|
||||||
|
// GraphQL fragment: DiscountErrorFragment
|
||||||
|
// ====================================================
|
||||||
|
|
||||||
|
export interface DiscountErrorFragment {
|
||||||
|
__typename: "DiscountError";
|
||||||
|
code: DiscountErrorCode;
|
||||||
|
field: string | null;
|
||||||
|
}
|
|
@ -2,16 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { CatalogueInput, SaleType } from "./../../types/globalTypes";
|
import { CatalogueInput, DiscountErrorCode, SaleType } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: SaleCataloguesAdd
|
// GraphQL mutation operation: SaleCataloguesAdd
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface SaleCataloguesAdd_saleCataloguesAdd_errors {
|
export interface SaleCataloguesAdd_saleCataloguesAdd_errors {
|
||||||
__typename: "Error";
|
__typename: "DiscountError";
|
||||||
|
code: DiscountErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SaleCataloguesAdd_saleCataloguesAdd_sale_products_edges_node_productType {
|
export interface SaleCataloguesAdd_saleCataloguesAdd_sale_products_edges_node_productType {
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { CatalogueInput, SaleType } from "./../../types/globalTypes";
|
import { CatalogueInput, DiscountErrorCode, SaleType } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: SaleCataloguesRemove
|
// GraphQL mutation operation: SaleCataloguesRemove
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface SaleCataloguesRemove_saleCataloguesRemove_errors {
|
export interface SaleCataloguesRemove_saleCataloguesRemove_errors {
|
||||||
__typename: "Error";
|
__typename: "DiscountError";
|
||||||
|
code: DiscountErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SaleCataloguesRemove_saleCataloguesRemove_sale_products_edges_node_productType {
|
export interface SaleCataloguesRemove_saleCataloguesRemove_sale_products_edges_node_productType {
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { SaleInput, SaleType } from "./../../types/globalTypes";
|
import { SaleInput, DiscountErrorCode, SaleType } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: SaleCreate
|
// GraphQL mutation operation: SaleCreate
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface SaleCreate_saleCreate_errors {
|
export interface SaleCreate_saleCreate_errors {
|
||||||
__typename: "Error";
|
__typename: "DiscountError";
|
||||||
|
code: DiscountErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SaleCreate_saleCreate_sale {
|
export interface SaleCreate_saleCreate_sale {
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { DiscountErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: SaleDelete
|
// GraphQL mutation operation: SaleDelete
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface SaleDelete_saleDelete_errors {
|
export interface SaleDelete_saleDelete_errors {
|
||||||
__typename: "Error";
|
__typename: "DiscountError";
|
||||||
|
code: DiscountErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SaleDelete_saleDelete {
|
export interface SaleDelete_saleDelete {
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { SaleInput, SaleType } from "./../../types/globalTypes";
|
import { SaleInput, DiscountErrorCode, SaleType } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: SaleUpdate
|
// GraphQL mutation operation: SaleUpdate
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface SaleUpdate_saleUpdate_errors {
|
export interface SaleUpdate_saleUpdate_errors {
|
||||||
__typename: "Error";
|
__typename: "DiscountError";
|
||||||
|
code: DiscountErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SaleUpdate_saleUpdate_sale {
|
export interface SaleUpdate_saleUpdate_sale {
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { CatalogueInput, DiscountValueTypeEnum, VoucherTypeEnum } from "./../../types/globalTypes";
|
import { CatalogueInput, DiscountErrorCode, DiscountValueTypeEnum, VoucherTypeEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: VoucherCataloguesAdd
|
// GraphQL mutation operation: VoucherCataloguesAdd
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface VoucherCataloguesAdd_voucherCataloguesAdd_errors {
|
export interface VoucherCataloguesAdd_voucherCataloguesAdd_errors {
|
||||||
__typename: "Error";
|
__typename: "DiscountError";
|
||||||
|
code: DiscountErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VoucherCataloguesAdd_voucherCataloguesAdd_voucher_countries {
|
export interface VoucherCataloguesAdd_voucherCataloguesAdd_voucher_countries {
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { CatalogueInput, DiscountValueTypeEnum, VoucherTypeEnum } from "./../../types/globalTypes";
|
import { CatalogueInput, DiscountErrorCode, DiscountValueTypeEnum, VoucherTypeEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: VoucherCataloguesRemove
|
// GraphQL mutation operation: VoucherCataloguesRemove
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface VoucherCataloguesRemove_voucherCataloguesRemove_errors {
|
export interface VoucherCataloguesRemove_voucherCataloguesRemove_errors {
|
||||||
__typename: "Error";
|
__typename: "DiscountError";
|
||||||
|
code: DiscountErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VoucherCataloguesRemove_voucherCataloguesRemove_voucher_countries {
|
export interface VoucherCataloguesRemove_voucherCataloguesRemove_voucher_countries {
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { VoucherInput, DiscountValueTypeEnum } from "./../../types/globalTypes";
|
import { VoucherInput, DiscountErrorCode, DiscountValueTypeEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: VoucherCreate
|
// GraphQL mutation operation: VoucherCreate
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface VoucherCreate_voucherCreate_errors {
|
export interface VoucherCreate_voucherCreate_errors {
|
||||||
__typename: "Error";
|
__typename: "DiscountError";
|
||||||
|
code: DiscountErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VoucherCreate_voucherCreate_voucher_countries {
|
export interface VoucherCreate_voucherCreate_voucher_countries {
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { DiscountErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: VoucherDelete
|
// GraphQL mutation operation: VoucherDelete
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface VoucherDelete_voucherDelete_errors {
|
export interface VoucherDelete_voucherDelete_errors {
|
||||||
__typename: "Error";
|
__typename: "DiscountError";
|
||||||
|
code: DiscountErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VoucherDelete_voucherDelete {
|
export interface VoucherDelete_voucherDelete {
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { VoucherInput, DiscountValueTypeEnum } from "./../../types/globalTypes";
|
import { VoucherInput, DiscountErrorCode, DiscountValueTypeEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: VoucherUpdate
|
// GraphQL mutation operation: VoucherUpdate
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface VoucherUpdate_voucherUpdate_errors {
|
export interface VoucherUpdate_voucherUpdate_errors {
|
||||||
__typename: "Error";
|
__typename: "DiscountError";
|
||||||
|
code: DiscountErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VoucherUpdate_voucherUpdate_voucher_countries {
|
export interface VoucherUpdate_voucherUpdate_voucher_countries {
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useIntl } from "react-intl";
|
|
||||||
|
|
||||||
import { AddressTypeInput } from "@saleor/customers/types";
|
import { AddressTypeInput } from "@saleor/customers/types";
|
||||||
import { commonMessages } from "@saleor/intl";
|
|
||||||
import { transformFormToAddress } from "@saleor/misc";
|
import { transformFormToAddress } from "@saleor/misc";
|
||||||
import { UserError } from "@saleor/types";
|
import { AddressInput, AccountErrorCode } from "@saleor/types/globalTypes";
|
||||||
import { AddressInput } from "@saleor/types/globalTypes";
|
|
||||||
import { add, remove } from "@saleor/utils/lists";
|
import { add, remove } from "@saleor/utils/lists";
|
||||||
|
import { AccountErrorFragment } from "@saleor/customers/types/AccountErrorFragment";
|
||||||
|
|
||||||
interface UseAddressValidation<T> {
|
interface UseAddressValidation<T> {
|
||||||
errors: UserError[];
|
errors: AccountErrorFragment[];
|
||||||
submit: (data: T & AddressTypeInput) => void;
|
submit: (data: T & AddressTypeInput) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function useAddressValidation<T>(
|
function useAddressValidation<T>(
|
||||||
onSubmit: (address: T & AddressInput) => void
|
onSubmit: (address: T & AddressInput) => void
|
||||||
): UseAddressValidation<T> {
|
): UseAddressValidation<T> {
|
||||||
const intl = useIntl();
|
const [validationErrors, setValidationErrors] = useState<
|
||||||
const [validationErrors, setValidationErrors] = useState<UserError[]>([]);
|
AccountErrorFragment[]
|
||||||
|
>([]);
|
||||||
|
|
||||||
const countryRequiredError = {
|
const countryRequiredError: AccountErrorFragment = {
|
||||||
field: "country",
|
__typename: "AccountError",
|
||||||
message: intl.formatMessage(commonMessages.requiredField)
|
code: AccountErrorCode.REQUIRED,
|
||||||
|
field: "country"
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -12,8 +12,9 @@ import ConfirmButton, {
|
||||||
} from "@saleor/components/ConfirmButton";
|
} from "@saleor/components/ConfirmButton";
|
||||||
import Form from "@saleor/components/Form";
|
import Form from "@saleor/components/Form";
|
||||||
import { buttonMessages } from "@saleor/intl";
|
import { buttonMessages } from "@saleor/intl";
|
||||||
import { getFieldError } from "@saleor/utils/errors";
|
import { MenuErrorFragment } from "@saleor/navigation/types/MenuErrorFragment";
|
||||||
import { UserError } from "@saleor/types";
|
import { getFormErrors } from "@saleor/utils/errors";
|
||||||
|
import getMenuErrorMessage from "@saleor/utils/errors/menu";
|
||||||
|
|
||||||
export interface MenuCreateDialogFormData {
|
export interface MenuCreateDialogFormData {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -22,7 +23,7 @@ export interface MenuCreateDialogFormData {
|
||||||
export interface MenuCreateDialogProps {
|
export interface MenuCreateDialogProps {
|
||||||
confirmButtonState: ConfirmButtonTransitionState;
|
confirmButtonState: ConfirmButtonTransitionState;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: MenuErrorFragment[];
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
onConfirm: (data: MenuCreateDialogFormData) => void;
|
onConfirm: (data: MenuCreateDialogFormData) => void;
|
||||||
|
@ -42,6 +43,8 @@ const MenuCreateDialog: React.FC<MenuCreateDialogProps> = ({
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const formErrors = getFormErrors(["name"], errors);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog onClose={onClose} maxWidth="sm" fullWidth open={open}>
|
<Dialog onClose={onClose} maxWidth="sm" fullWidth open={open}>
|
||||||
<DialogTitle>
|
<DialogTitle>
|
||||||
|
@ -57,9 +60,9 @@ const MenuCreateDialog: React.FC<MenuCreateDialogProps> = ({
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!getFieldError(errors, "name")}
|
error={!!formErrors.name}
|
||||||
fullWidth
|
fullWidth
|
||||||
helperText={getFieldError(errors, "name")?.message}
|
helperText={getMenuErrorMessage(formErrors.name, intl)}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Menu Title",
|
defaultMessage: "Menu Title",
|
||||||
id: "menuCreateDialogMenuTitleLabel"
|
id: "menuCreateDialogMenuTitleLabel"
|
||||||
|
|
|
@ -10,6 +10,7 @@ import Form from "@saleor/components/Form";
|
||||||
import Grid from "@saleor/components/Grid";
|
import Grid from "@saleor/components/Grid";
|
||||||
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
||||||
import { sectionNames } from "@saleor/intl";
|
import { sectionNames } from "@saleor/intl";
|
||||||
|
import { MenuErrorFragment } from "@saleor/navigation/types/MenuErrorFragment";
|
||||||
import { maybe } from "../../../misc";
|
import { maybe } from "../../../misc";
|
||||||
import { MenuDetails_menu } from "../../types/MenuDetails";
|
import { MenuDetails_menu } from "../../types/MenuDetails";
|
||||||
import { MenuItemType } from "../MenuItemDialog";
|
import { MenuItemType } from "../MenuItemDialog";
|
||||||
|
@ -28,6 +29,7 @@ export interface MenuDetailsSubmitData extends MenuDetailsFormData {
|
||||||
export interface MenuDetailsPageProps {
|
export interface MenuDetailsPageProps {
|
||||||
saveButtonState: ConfirmButtonTransitionState;
|
saveButtonState: ConfirmButtonTransitionState;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
|
errors: MenuErrorFragment[];
|
||||||
menu: MenuDetails_menu;
|
menu: MenuDetails_menu;
|
||||||
onBack: () => void;
|
onBack: () => void;
|
||||||
onDelete: () => void;
|
onDelete: () => void;
|
||||||
|
@ -39,6 +41,7 @@ export interface MenuDetailsPageProps {
|
||||||
|
|
||||||
const MenuDetailsPage: React.FC<MenuDetailsPageProps> = ({
|
const MenuDetailsPage: React.FC<MenuDetailsPageProps> = ({
|
||||||
disabled,
|
disabled,
|
||||||
|
errors,
|
||||||
menu,
|
menu,
|
||||||
saveButtonState,
|
saveButtonState,
|
||||||
onBack,
|
onBack,
|
||||||
|
@ -98,6 +101,7 @@ const MenuDetailsPage: React.FC<MenuDetailsPageProps> = ({
|
||||||
<MenuProperties
|
<MenuProperties
|
||||||
data={data}
|
data={data}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
errors={errors}
|
||||||
onChange={change}
|
onChange={change}
|
||||||
/>
|
/>
|
||||||
<CardSpacer />
|
<CardSpacer />
|
||||||
|
|
|
@ -21,9 +21,10 @@ import { buttonMessages, sectionNames } from "@saleor/intl";
|
||||||
import { SearchCategories_search_edges_node } from "@saleor/searches/types/SearchCategories";
|
import { SearchCategories_search_edges_node } from "@saleor/searches/types/SearchCategories";
|
||||||
import { SearchCollections_search_edges_node } from "@saleor/searches/types/SearchCollections";
|
import { SearchCollections_search_edges_node } from "@saleor/searches/types/SearchCollections";
|
||||||
import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages";
|
import { SearchPages_search_edges_node } from "@saleor/searches/types/SearchPages";
|
||||||
import { UserError } from "@saleor/types";
|
|
||||||
import { getErrors, getFieldError } from "@saleor/utils/errors";
|
|
||||||
import { getMenuItemByValue, IMenu } from "@saleor/utils/menu";
|
import { getMenuItemByValue, IMenu } from "@saleor/utils/menu";
|
||||||
|
import { MenuErrorFragment } from "@saleor/navigation/types/MenuErrorFragment";
|
||||||
|
import { getFieldError, getFormErrors } from "@saleor/utils/errors";
|
||||||
|
import getMenuErrorMessage from "@saleor/utils/errors/menu";
|
||||||
|
|
||||||
export type MenuItemType = "category" | "collection" | "link" | "page";
|
export type MenuItemType = "category" | "collection" | "link" | "page";
|
||||||
export interface MenuItemData {
|
export interface MenuItemData {
|
||||||
|
@ -38,7 +39,7 @@ export interface MenuItemDialogFormData extends MenuItemData {
|
||||||
export interface MenuItemDialogProps {
|
export interface MenuItemDialogProps {
|
||||||
confirmButtonState: ConfirmButtonTransitionState;
|
confirmButtonState: ConfirmButtonTransitionState;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: UserError[];
|
errors: MenuErrorFragment[];
|
||||||
initial?: MenuItemDialogFormData;
|
initial?: MenuItemDialogFormData;
|
||||||
initialDisplayValue?: string;
|
initialDisplayValue?: string;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
|
@ -112,7 +113,11 @@ const MenuItemDialog: React.FC<MenuItemDialogProps> = ({
|
||||||
initialDisplayValue
|
initialDisplayValue
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const mutationErrors = getErrors(errors);
|
const mutationErrors = errors.filter(err => err.field === null);
|
||||||
|
const formErrors = getFormErrors(["name"], errors);
|
||||||
|
const idError = ["category", "collection", "page", "url"]
|
||||||
|
.map(field => getFieldError(errors, field))
|
||||||
|
.reduce((acc, err) => acc || err);
|
||||||
|
|
||||||
let options: IMenu = [];
|
let options: IMenu = [];
|
||||||
|
|
||||||
|
@ -208,10 +213,6 @@ const MenuItemDialog: React.FC<MenuItemDialogProps> = ({
|
||||||
|
|
||||||
const handleSubmit = () => onSubmit(data);
|
const handleSubmit = () => onSubmit(data);
|
||||||
|
|
||||||
const idError = ["category", "collection", "page", "url"]
|
|
||||||
.map(field => getFieldError(errors, field))
|
|
||||||
.reduce((acc, err) => acc || err);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
|
@ -252,8 +253,8 @@ const MenuItemDialog: React.FC<MenuItemDialogProps> = ({
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
name="name"
|
name="name"
|
||||||
error={!!getFieldError(errors, "name")}
|
error={!!formErrors.name}
|
||||||
helperText={getFieldError(errors, "name")?.message}
|
helperText={getMenuErrorMessage(formErrors.name, intl)}
|
||||||
/>
|
/>
|
||||||
<FormSpacer />
|
<FormSpacer />
|
||||||
<AutocompleteSelectMenu
|
<AutocompleteSelectMenu
|
||||||
|
@ -269,7 +270,7 @@ const MenuItemDialog: React.FC<MenuItemDialogProps> = ({
|
||||||
loading={loading}
|
loading={loading}
|
||||||
options={options}
|
options={options}
|
||||||
error={!!idError}
|
error={!!idError}
|
||||||
helperText={idError?.message}
|
helperText={getMenuErrorMessage(idError, intl)}
|
||||||
placeholder={intl.formatMessage({
|
placeholder={intl.formatMessage({
|
||||||
defaultMessage: "Start typing to begin search...",
|
defaultMessage: "Start typing to begin search...",
|
||||||
id: "menuItemDialogLinkPlaceholder"
|
id: "menuItemDialogLinkPlaceholder"
|
||||||
|
@ -280,8 +281,8 @@ const MenuItemDialog: React.FC<MenuItemDialogProps> = ({
|
||||||
<>
|
<>
|
||||||
<FormSpacer />
|
<FormSpacer />
|
||||||
{mutationErrors.map(err => (
|
{mutationErrors.map(err => (
|
||||||
<Typography key={err} color="error">
|
<Typography key={err.code} color="error">
|
||||||
{err}
|
{getMenuErrorMessage(err, intl)}
|
||||||
</Typography>
|
</Typography>
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -6,21 +6,28 @@ import { useIntl } from "react-intl";
|
||||||
|
|
||||||
import CardTitle from "@saleor/components/CardTitle";
|
import CardTitle from "@saleor/components/CardTitle";
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
|
import { MenuErrorFragment } from "@saleor/navigation/types/MenuErrorFragment";
|
||||||
|
import { getFormErrors } from "@saleor/utils/errors";
|
||||||
|
import getMenuErrorMessage from "@saleor/utils/errors/menu";
|
||||||
import { MenuDetailsFormData } from "../MenuDetailsPage";
|
import { MenuDetailsFormData } from "../MenuDetailsPage";
|
||||||
|
|
||||||
export interface MenuPropertiesProps {
|
export interface MenuPropertiesProps {
|
||||||
data: MenuDetailsFormData;
|
data: MenuDetailsFormData;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
|
errors: MenuErrorFragment[];
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
onChange: (event: React.ChangeEvent<any>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MenuProperties: React.FC<MenuPropertiesProps> = ({
|
const MenuProperties: React.FC<MenuPropertiesProps> = ({
|
||||||
data,
|
data,
|
||||||
disabled,
|
disabled,
|
||||||
|
errors,
|
||||||
onChange
|
onChange
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const formErrors = getFormErrors(["name"], errors);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
|
@ -29,12 +36,14 @@ const MenuProperties: React.FC<MenuPropertiesProps> = ({
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
error={!!formErrors.name}
|
||||||
name={"name" as keyof MenuDetailsFormData}
|
name={"name" as keyof MenuDetailsFormData}
|
||||||
fullWidth
|
fullWidth
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Menu Title",
|
defaultMessage: "Menu Title",
|
||||||
id: "menuPropertiesMenuTitle"
|
id: "menuPropertiesMenuTitle"
|
||||||
})}
|
})}
|
||||||
|
helperText={getMenuErrorMessage(formErrors.name, intl)}
|
||||||
value={data.name}
|
value={data.name}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
/>
|
/>
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue