Separate sync and async app webhooks (#1635)
* Separate sync and async app webhooks * Remove create webhook page and cleanups * Update util * Auto unselect events when anyEvent choice is selected * Update test snapshots
This commit is contained in:
parent
e875b02adc
commit
147d8c89cb
26 changed files with 1722 additions and 12976 deletions
|
@ -8046,10 +8046,6 @@
|
|||
"context": "webhooks section name",
|
||||
"string": "Webhooks"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookCreatePage_dot_3493926696": {
|
||||
"context": "header",
|
||||
"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?"
|
||||
|
@ -8062,238 +8058,78 @@
|
|||
"context": "dialog header",
|
||||
"string": "Delete Webhook"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_1013231747": {
|
||||
"context": "event",
|
||||
"string": "Confirm payment"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_1087314240": {
|
||||
"context": "event",
|
||||
"string": "Checkout updated"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_1366770851": {
|
||||
"context": "event",
|
||||
"string": "Order confirmed"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_1368317066": {
|
||||
"context": "event",
|
||||
"string": "Invoice deleted"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_1368438665": {
|
||||
"context": "event",
|
||||
"string": "Shipping methods for checkout listed"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_1436364351": {
|
||||
"context": "section header",
|
||||
"string": "Events"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_144149815": {
|
||||
"context": "event",
|
||||
"string": "Product variant deleted"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_1564545489": {
|
||||
"context": "event",
|
||||
"string": "Draft order deleted"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_1594316266": {
|
||||
"context": "event",
|
||||
"string": "Fulfillment canceled"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_1606361075": {
|
||||
"context": "event",
|
||||
"string": "Order updated"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_1616635110": {
|
||||
"context": "event",
|
||||
"string": "User notified"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_1624692657": {
|
||||
"context": "event",
|
||||
"string": "Refund payment"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_2126893364": {
|
||||
"context": "event",
|
||||
"string": "Product variant updated"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_2240725235": {
|
||||
"context": "event",
|
||||
"string": "Checkout created"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_2315238863": {
|
||||
"context": "event",
|
||||
"string": "Product variant out of stock"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_2328272362": {
|
||||
"context": "event",
|
||||
"string": "Sale deleted"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_2454751033": {
|
||||
"context": "event",
|
||||
"string": "All events"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_2745028894": {
|
||||
"context": "event",
|
||||
"string": "Page deleted"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_2862596150": {
|
||||
"context": "event",
|
||||
"string": "Invoice sent"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_2899821092": {
|
||||
"context": "event",
|
||||
"string": "Product created"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_3051538277": {
|
||||
"context": "webhook events",
|
||||
"string": "Expand or restrict webhooks permissions to register certain events in Saleor system."
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_3285325968": {
|
||||
"context": "event",
|
||||
"string": "Product variant created"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_3316426878": {
|
||||
"context": "event",
|
||||
"string": "Product updated"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_3345061702": {
|
||||
"context": "event",
|
||||
"string": "Order fully paid"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_337693660": {
|
||||
"context": "event",
|
||||
"string": "Void payment"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_3400883706": {
|
||||
"context": "event",
|
||||
"string": "Order created"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_3418398751": {
|
||||
"context": "event",
|
||||
"string": "Draft order updated"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_36047288": {
|
||||
"context": "event",
|
||||
"string": "Translation created"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_3610454973": {
|
||||
"context": "event",
|
||||
"string": "Draft order created"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_3617444329": {
|
||||
"context": "event",
|
||||
"string": "Order cancelled"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_3618648517": {
|
||||
"context": "event",
|
||||
"string": "Page updated"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_3671033983": {
|
||||
"context": "event",
|
||||
"string": "Product deleted"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_3742472683": {
|
||||
"context": "event",
|
||||
"string": "Capture payment"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_3907151399": {
|
||||
"context": "event",
|
||||
"string": "Order fulfilled"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_3970234993": {
|
||||
"context": "event",
|
||||
"string": "Customer created"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_4053089191": {
|
||||
"context": "event",
|
||||
"string": "List payment gateways"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_4175628606": {
|
||||
"context": "event",
|
||||
"string": "Sale created"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_4186057882": {
|
||||
"context": "event",
|
||||
"string": "Invoice requested"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_4281441551": {
|
||||
"context": "event",
|
||||
"string": "Fulfillment created"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_4292269645": {
|
||||
"context": "event",
|
||||
"string": "Process payment"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_482477254": {
|
||||
"context": "event",
|
||||
"string": "Translation updated"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_523513128": {
|
||||
"context": "event",
|
||||
"string": "Sale updated"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_679080833": {
|
||||
"context": "event",
|
||||
"string": "Page created"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_69923590": {
|
||||
"context": "event",
|
||||
"string": "Product variant back in stock"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_759562905": {
|
||||
"context": "event",
|
||||
"string": "Authorize payment"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_787792649": {
|
||||
"context": "event",
|
||||
"string": "Customer updated"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookInfo_dot_1089569085": {
|
||||
"context": "webhook",
|
||||
"string": "Secret Key"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookInfo_dot_1690209105": {
|
||||
"context": "webhook",
|
||||
"string": "Target URL"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookInfo_dot_1826224431": {
|
||||
"context": "webhook",
|
||||
"string": "Webhook Name"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookInfo_dot_330298209": {
|
||||
"context": "section header",
|
||||
"string": "Webhook Information"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookInfo_dot_3763861707": {
|
||||
"context": "webhook target url help text",
|
||||
"string": "This URL will receive webhook POST requests"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookInfo_dot_3809115222": {
|
||||
"context": "webhook secret key help text",
|
||||
"string": "secret key is used to create a hash signature with each payload. *optional field"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookInfo_dot_4194304040": {
|
||||
"context": "webhook specific information",
|
||||
"string": "Webhook specific information"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookStatus_dot_2772025990": {
|
||||
"context": "webhooks active",
|
||||
"string": "Webhook is active"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookStatus_dot_313090629": {
|
||||
"context": "webhook active",
|
||||
"string": "If you want to disable this webhook please uncheck the box below."
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookStatus_dot_596557805": {
|
||||
"context": "section header",
|
||||
"string": "Webhook Status"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhooksDetailsPage_dot_1595053355": {
|
||||
"src_dot_webhooks_dot_components_dot_WebhookDetailsPage_dot_header": {
|
||||
"context": "header",
|
||||
"string": "Unnamed Webhook Details"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhooksDetailsPage_dot_408706360": {
|
||||
"src_dot_webhooks_dot_components_dot_WebhookDetailsPage_dot_headerCreate": {
|
||||
"context": "header",
|
||||
"string": "Create Webhook"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookDetailsPage_dot_headerNamed": {
|
||||
"context": "header",
|
||||
"string": "{webhookName} Details"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_assignPermissionsToAsynchronousEvents": {
|
||||
"context": "section description",
|
||||
"string": "Assign permissions to register asynchronous events for this webhook."
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_assignPermissionsToSynchronousEvents": {
|
||||
"context": "section description",
|
||||
"string": "Assign permissions to register synchronous events for this webhook."
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_asynchronousEvents": {
|
||||
"context": "section subheader",
|
||||
"string": "Asynchronous events"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_events": {
|
||||
"context": "section header",
|
||||
"string": "Events"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_registeredEvents": {
|
||||
"context": "input label",
|
||||
"string": "Registered events"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_synchronousEvents": {
|
||||
"context": "section subheader",
|
||||
"string": "Synchronous events"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookInfo_dot_secretKey": {
|
||||
"context": "webhook input label",
|
||||
"string": "Secret Key"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookInfo_dot_secretKeyDescription": {
|
||||
"context": "webhook input help text",
|
||||
"string": "secret key is used to create a hash signature with each payload. *optional field"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookInfo_dot_targetUrl": {
|
||||
"context": "webhook input label",
|
||||
"string": "Target URL"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookInfo_dot_targetUrlDescription": {
|
||||
"context": "webhook input help text",
|
||||
"string": "This URL will receive webhook POST requests"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookInfo_dot_webhookInformation": {
|
||||
"context": "section header",
|
||||
"string": "Webhook Information"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookInfo_dot_webhookName": {
|
||||
"context": "webhook input label",
|
||||
"string": "Webhook Name"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookStatus_dot_webhookActive": {
|
||||
"context": "webhooks active label",
|
||||
"string": "Webhook is active"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookStatus_dot_webhookActiveDescription": {
|
||||
"context": "webhook active description",
|
||||
"string": "If you want to disable this webhook please uncheck the box below."
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookStatus_dot_webhookStatus": {
|
||||
"context": "section header",
|
||||
"string": "Webhook Status"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhooksList_dot_1153324159": {
|
||||
"string": "No webhooks found"
|
||||
},
|
||||
|
|
124
schema.graphql
124
schema.graphql
|
@ -804,6 +804,12 @@ type BulkStockError {
|
|||
index: Int
|
||||
}
|
||||
|
||||
input CardInput {
|
||||
code: String!
|
||||
cvc: String
|
||||
money: MoneyInput!
|
||||
}
|
||||
|
||||
input CatalogueInput {
|
||||
products: [ID]
|
||||
categories: [ID]
|
||||
|
@ -1108,6 +1114,7 @@ type CheckoutError {
|
|||
message: String
|
||||
code: CheckoutErrorCode!
|
||||
variants: [ID!]
|
||||
lines: [ID!]
|
||||
addressType: AddressTypeEnum
|
||||
}
|
||||
|
||||
|
@ -1139,6 +1146,14 @@ enum CheckoutErrorCode {
|
|||
UNAVAILABLE_VARIANT_IN_CHANNEL
|
||||
}
|
||||
|
||||
input CheckoutFilterInput {
|
||||
customer: String
|
||||
created: DateRangeInput
|
||||
search: String
|
||||
metadata: [MetadataFilter]
|
||||
channels: [ID]
|
||||
}
|
||||
|
||||
type CheckoutLanguageCodeUpdate {
|
||||
checkout: Checkout
|
||||
checkoutErrors: [CheckoutError!]! @deprecated(reason: "This field will be removed in Saleor 4.0. Use `errors` field instead.")
|
||||
|
@ -1181,6 +1196,11 @@ type CheckoutLinesAdd {
|
|||
errors: [CheckoutError!]!
|
||||
}
|
||||
|
||||
type CheckoutLinesDelete {
|
||||
checkout: Checkout
|
||||
errors: [CheckoutError!]!
|
||||
}
|
||||
|
||||
type CheckoutLinesUpdate {
|
||||
checkout: Checkout
|
||||
checkoutErrors: [CheckoutError!]! @deprecated(reason: "This field will be removed in Saleor 4.0. Use `errors` field instead.")
|
||||
|
@ -1212,6 +1232,17 @@ type CheckoutShippingMethodUpdate {
|
|||
errors: [CheckoutError!]!
|
||||
}
|
||||
|
||||
enum CheckoutSortField {
|
||||
CREATION_DATE
|
||||
CUSTOMER
|
||||
PAYMENT
|
||||
}
|
||||
|
||||
input CheckoutSortingInput {
|
||||
direction: OrderDirection!
|
||||
field: CheckoutSortField!
|
||||
}
|
||||
|
||||
type ChoiceValue {
|
||||
raw: String
|
||||
verbose: String
|
||||
|
@ -3713,6 +3744,11 @@ type Money {
|
|||
amount: Float!
|
||||
}
|
||||
|
||||
input MoneyInput {
|
||||
currency: String!
|
||||
amount: PositiveDecimal!
|
||||
}
|
||||
|
||||
type MoneyRange {
|
||||
start: Money
|
||||
stop: Money
|
||||
|
@ -3812,6 +3848,7 @@ type Mutation {
|
|||
paymentRefund(amount: PositiveDecimal, paymentId: ID!): PaymentRefund
|
||||
paymentVoid(paymentId: ID!): PaymentVoid
|
||||
paymentInitialize(channel: String, gateway: String!, paymentData: JSONString): PaymentInitialize
|
||||
paymentCheckBalance(input: PaymentCheckBalanceInput!): PaymentCheckBalance
|
||||
pageCreate(input: PageCreateInput!): PageCreate
|
||||
pageDelete(id: ID!): PageDelete
|
||||
pageBulkDelete(ids: [ID]!): PageBulkDelete
|
||||
|
@ -3914,7 +3951,8 @@ type Mutation {
|
|||
checkoutCustomerAttach(checkoutId: ID, customerId: ID, token: UUID): CheckoutCustomerAttach
|
||||
checkoutCustomerDetach(checkoutId: ID, token: UUID): CheckoutCustomerDetach
|
||||
checkoutEmailUpdate(checkoutId: ID, email: String!, token: UUID): CheckoutEmailUpdate
|
||||
checkoutLineDelete(checkoutId: ID, lineId: ID, token: UUID): CheckoutLineDelete
|
||||
checkoutLineDelete(checkoutId: ID, lineId: ID, token: UUID): CheckoutLineDelete @deprecated(reason: "DEPRECATED: Will be removed in Saleor 4.0. Use `checkoutLinesDelete` instead.")
|
||||
checkoutLinesDelete(linesIds: [ID]!, token: UUID!): CheckoutLinesDelete
|
||||
checkoutLinesAdd(checkoutId: ID, lines: [CheckoutLineInput]!, token: UUID): CheckoutLinesAdd
|
||||
checkoutLinesUpdate(checkoutId: ID, lines: [CheckoutLineInput]!, token: UUID): CheckoutLinesUpdate
|
||||
checkoutRemovePromoCode(checkoutId: ID, promoCode: String, promoCodeId: ID, token: UUID): CheckoutRemovePromoCode
|
||||
|
@ -4881,6 +4919,19 @@ enum PaymentChargeStatusEnum {
|
|||
CANCELLED
|
||||
}
|
||||
|
||||
type PaymentCheckBalance {
|
||||
data: JSONString
|
||||
paymentErrors: [PaymentError!]! @deprecated(reason: "This field will be removed in Saleor 4.0. Use `errors` field instead.")
|
||||
errors: [PaymentError!]!
|
||||
}
|
||||
|
||||
input PaymentCheckBalanceInput {
|
||||
gatewayId: String!
|
||||
method: String!
|
||||
channel: String!
|
||||
card: CardInput!
|
||||
}
|
||||
|
||||
type PaymentCountableConnection {
|
||||
pageInfo: PageInfo!
|
||||
edges: [PaymentCountableEdge!]!
|
||||
|
@ -4912,6 +4963,7 @@ enum PaymentErrorCode {
|
|||
PAYMENT_ERROR
|
||||
NOT_SUPPORTED_GATEWAY
|
||||
CHANNEL_INACTIVE
|
||||
BALANCE_CHECK_ERROR
|
||||
}
|
||||
|
||||
input PaymentFilterInput {
|
||||
|
@ -5902,7 +5954,7 @@ type Query {
|
|||
exportFiles(filter: ExportFileFilterInput, sortBy: ExportFileSortingInput, before: String, after: String, first: Int, last: Int): ExportFileCountableConnection
|
||||
taxTypes: [TaxType]
|
||||
checkout(token: UUID): Checkout
|
||||
checkouts(channel: String, before: String, after: String, first: Int, last: Int): CheckoutCountableConnection
|
||||
checkouts(sortBy: CheckoutSortingInput, filter: CheckoutFilterInput, channel: String, before: String, after: String, first: Int, last: Int): CheckoutCountableConnection
|
||||
checkoutLines(before: String, after: String, first: Int, last: Int): CheckoutLineCountableConnection
|
||||
channel(id: ID): Channel
|
||||
channels: [Channel!]
|
||||
|
@ -7207,7 +7259,9 @@ type Webhook implements Node {
|
|||
isActive: Boolean!
|
||||
secretKey: String
|
||||
id: ID!
|
||||
events: [WebhookEvent!]!
|
||||
events: [WebhookEvent!]! @deprecated(reason: "This field will be removed in Saleor 4.0. Use `asyncEvents` or `syncEvents` instead.")
|
||||
syncEvents: [WebhookEventSync!]!
|
||||
asyncEvents: [WebhookEventAsync!]!
|
||||
app: App!
|
||||
}
|
||||
|
||||
|
@ -7221,6 +7275,8 @@ input WebhookCreateInput {
|
|||
name: String
|
||||
targetUrl: String
|
||||
events: [WebhookEventTypeEnum]
|
||||
asyncEvents: [WebhookEventTypeAsync!]
|
||||
syncEvents: [WebhookEventTypeSync!]
|
||||
app: ID
|
||||
isActive: Boolean
|
||||
secretKey: String
|
||||
|
@ -7251,6 +7307,55 @@ type WebhookEvent {
|
|||
name: String!
|
||||
}
|
||||
|
||||
type WebhookEventAsync {
|
||||
eventType: WebhookEventTypeAsync!
|
||||
name: String!
|
||||
}
|
||||
|
||||
type WebhookEventSync {
|
||||
eventType: WebhookEventTypeSync!
|
||||
name: String!
|
||||
}
|
||||
|
||||
enum WebhookEventTypeAsync {
|
||||
ANY_EVENTS
|
||||
ORDER_CREATED
|
||||
ORDER_CONFIRMED
|
||||
ORDER_FULLY_PAID
|
||||
ORDER_UPDATED
|
||||
ORDER_CANCELLED
|
||||
ORDER_FULFILLED
|
||||
DRAFT_ORDER_CREATED
|
||||
DRAFT_ORDER_UPDATED
|
||||
DRAFT_ORDER_DELETED
|
||||
SALE_CREATED
|
||||
SALE_UPDATED
|
||||
SALE_DELETED
|
||||
INVOICE_REQUESTED
|
||||
INVOICE_DELETED
|
||||
INVOICE_SENT
|
||||
CUSTOMER_CREATED
|
||||
CUSTOMER_UPDATED
|
||||
PRODUCT_CREATED
|
||||
PRODUCT_UPDATED
|
||||
PRODUCT_DELETED
|
||||
PRODUCT_VARIANT_CREATED
|
||||
PRODUCT_VARIANT_UPDATED
|
||||
PRODUCT_VARIANT_DELETED
|
||||
PRODUCT_VARIANT_OUT_OF_STOCK
|
||||
PRODUCT_VARIANT_BACK_IN_STOCK
|
||||
CHECKOUT_CREATED
|
||||
CHECKOUT_UPDATED
|
||||
FULFILLMENT_CREATED
|
||||
FULFILLMENT_CANCELED
|
||||
NOTIFY_USER
|
||||
PAGE_CREATED
|
||||
PAGE_UPDATED
|
||||
PAGE_DELETED
|
||||
TRANSLATION_CREATED
|
||||
TRANSLATION_UPDATED
|
||||
}
|
||||
|
||||
enum WebhookEventTypeEnum {
|
||||
ANY_EVENTS
|
||||
ORDER_CREATED
|
||||
|
@ -7298,6 +7403,17 @@ enum WebhookEventTypeEnum {
|
|||
TRANSLATION_UPDATED
|
||||
}
|
||||
|
||||
enum WebhookEventTypeSync {
|
||||
PAYMENT_AUTHORIZE
|
||||
PAYMENT_CAPTURE
|
||||
PAYMENT_CONFIRM
|
||||
PAYMENT_LIST_GATEWAYS
|
||||
PAYMENT_PROCESS
|
||||
PAYMENT_REFUND
|
||||
PAYMENT_VOID
|
||||
SHIPPING_LIST_METHODS_FOR_CHECKOUT
|
||||
}
|
||||
|
||||
enum WebhookSampleEventTypeEnum {
|
||||
ORDER_CREATED
|
||||
ORDER_CONFIRMED
|
||||
|
@ -7354,6 +7470,8 @@ input WebhookUpdateInput {
|
|||
name: String
|
||||
targetUrl: String
|
||||
events: [WebhookEventTypeEnum]
|
||||
asyncEvents: [WebhookEventTypeAsync!]
|
||||
syncEvents: [WebhookEventTypeSync!]
|
||||
app: ID
|
||||
isActive: Boolean
|
||||
secretKey: String
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1817,6 +1817,45 @@ export enum WebhookErrorCode {
|
|||
UNIQUE = "UNIQUE",
|
||||
}
|
||||
|
||||
export enum WebhookEventTypeAsync {
|
||||
ANY_EVENTS = "ANY_EVENTS",
|
||||
CHECKOUT_CREATED = "CHECKOUT_CREATED",
|
||||
CHECKOUT_UPDATED = "CHECKOUT_UPDATED",
|
||||
CUSTOMER_CREATED = "CUSTOMER_CREATED",
|
||||
CUSTOMER_UPDATED = "CUSTOMER_UPDATED",
|
||||
DRAFT_ORDER_CREATED = "DRAFT_ORDER_CREATED",
|
||||
DRAFT_ORDER_DELETED = "DRAFT_ORDER_DELETED",
|
||||
DRAFT_ORDER_UPDATED = "DRAFT_ORDER_UPDATED",
|
||||
FULFILLMENT_CANCELED = "FULFILLMENT_CANCELED",
|
||||
FULFILLMENT_CREATED = "FULFILLMENT_CREATED",
|
||||
INVOICE_DELETED = "INVOICE_DELETED",
|
||||
INVOICE_REQUESTED = "INVOICE_REQUESTED",
|
||||
INVOICE_SENT = "INVOICE_SENT",
|
||||
NOTIFY_USER = "NOTIFY_USER",
|
||||
ORDER_CANCELLED = "ORDER_CANCELLED",
|
||||
ORDER_CONFIRMED = "ORDER_CONFIRMED",
|
||||
ORDER_CREATED = "ORDER_CREATED",
|
||||
ORDER_FULFILLED = "ORDER_FULFILLED",
|
||||
ORDER_FULLY_PAID = "ORDER_FULLY_PAID",
|
||||
ORDER_UPDATED = "ORDER_UPDATED",
|
||||
PAGE_CREATED = "PAGE_CREATED",
|
||||
PAGE_DELETED = "PAGE_DELETED",
|
||||
PAGE_UPDATED = "PAGE_UPDATED",
|
||||
PRODUCT_CREATED = "PRODUCT_CREATED",
|
||||
PRODUCT_DELETED = "PRODUCT_DELETED",
|
||||
PRODUCT_UPDATED = "PRODUCT_UPDATED",
|
||||
PRODUCT_VARIANT_BACK_IN_STOCK = "PRODUCT_VARIANT_BACK_IN_STOCK",
|
||||
PRODUCT_VARIANT_CREATED = "PRODUCT_VARIANT_CREATED",
|
||||
PRODUCT_VARIANT_DELETED = "PRODUCT_VARIANT_DELETED",
|
||||
PRODUCT_VARIANT_OUT_OF_STOCK = "PRODUCT_VARIANT_OUT_OF_STOCK",
|
||||
PRODUCT_VARIANT_UPDATED = "PRODUCT_VARIANT_UPDATED",
|
||||
SALE_CREATED = "SALE_CREATED",
|
||||
SALE_DELETED = "SALE_DELETED",
|
||||
SALE_UPDATED = "SALE_UPDATED",
|
||||
TRANSLATION_CREATED = "TRANSLATION_CREATED",
|
||||
TRANSLATION_UPDATED = "TRANSLATION_UPDATED",
|
||||
}
|
||||
|
||||
export enum WebhookEventTypeEnum {
|
||||
ANY_EVENTS = "ANY_EVENTS",
|
||||
CHECKOUT_CREATED = "CHECKOUT_CREATED",
|
||||
|
@ -1864,6 +1903,17 @@ export enum WebhookEventTypeEnum {
|
|||
TRANSLATION_UPDATED = "TRANSLATION_UPDATED",
|
||||
}
|
||||
|
||||
export enum WebhookEventTypeSync {
|
||||
PAYMENT_AUTHORIZE = "PAYMENT_AUTHORIZE",
|
||||
PAYMENT_CAPTURE = "PAYMENT_CAPTURE",
|
||||
PAYMENT_CONFIRM = "PAYMENT_CONFIRM",
|
||||
PAYMENT_LIST_GATEWAYS = "PAYMENT_LIST_GATEWAYS",
|
||||
PAYMENT_PROCESS = "PAYMENT_PROCESS",
|
||||
PAYMENT_REFUND = "PAYMENT_REFUND",
|
||||
PAYMENT_VOID = "PAYMENT_VOID",
|
||||
SHIPPING_LIST_METHODS_FOR_CHECKOUT = "SHIPPING_LIST_METHODS_FOR_CHECKOUT",
|
||||
}
|
||||
|
||||
export enum WeightUnitsEnum {
|
||||
G = "G",
|
||||
KG = "KG",
|
||||
|
@ -2963,6 +3013,8 @@ export interface WebhookCreateInput {
|
|||
name?: string | null;
|
||||
targetUrl?: string | null;
|
||||
events?: (WebhookEventTypeEnum | null)[] | null;
|
||||
asyncEvents?: WebhookEventTypeAsync[] | null;
|
||||
syncEvents?: WebhookEventTypeSync[] | null;
|
||||
app?: string | null;
|
||||
isActive?: boolean | null;
|
||||
secretKey?: string | null;
|
||||
|
@ -2972,6 +3024,8 @@ export interface WebhookUpdateInput {
|
|||
name?: string | null;
|
||||
targetUrl?: string | null;
|
||||
events?: (WebhookEventTypeEnum | null)[] | null;
|
||||
asyncEvents?: WebhookEventTypeAsync[] | null;
|
||||
syncEvents?: WebhookEventTypeSync[] | null;
|
||||
app?: string | null;
|
||||
isActive?: boolean | null;
|
||||
secretKey?: string | null;
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton";
|
||||
import Container from "@saleor/components/Container";
|
||||
import Form from "@saleor/components/Form";
|
||||
import FormSpacer from "@saleor/components/FormSpacer";
|
||||
import Grid from "@saleor/components/Grid";
|
||||
import PageHeader from "@saleor/components/PageHeader";
|
||||
import Savebar from "@saleor/components/Savebar";
|
||||
import { WebhookErrorFragment } from "@saleor/fragments/types/WebhookErrorFragment";
|
||||
import { Backlink } from "@saleor/macaw-ui";
|
||||
import { WebhookEventTypeEnum } from "@saleor/types/globalTypes";
|
||||
import WebhookEvents from "@saleor/webhooks/components/WebhookEvents";
|
||||
import WebhookInfo from "@saleor/webhooks/components/WebhookInfo";
|
||||
import WebhookStatus from "@saleor/webhooks/components/WebhookStatus";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
export interface FormData {
|
||||
events: WebhookEventTypeEnum[];
|
||||
isActive: boolean;
|
||||
name: string;
|
||||
secretKey: string | null;
|
||||
targetUrl: string;
|
||||
allEvents: boolean;
|
||||
}
|
||||
|
||||
export interface WebhookCreatePageProps {
|
||||
appName: string;
|
||||
disabled: boolean;
|
||||
errors: WebhookErrorFragment[];
|
||||
saveButtonBarState: ConfirmButtonTransitionState;
|
||||
onBack: () => void;
|
||||
onSubmit: (data: FormData) => void;
|
||||
}
|
||||
|
||||
const WebhookCreatePage: React.FC<WebhookCreatePageProps> = ({
|
||||
appName = "",
|
||||
disabled,
|
||||
errors,
|
||||
saveButtonBarState,
|
||||
onBack,
|
||||
onSubmit
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
const initialForm: FormData = {
|
||||
allEvents: false,
|
||||
events: [],
|
||||
isActive: false,
|
||||
name: "",
|
||||
secretKey: "",
|
||||
targetUrl: ""
|
||||
};
|
||||
|
||||
return (
|
||||
<Form initial={initialForm} onSubmit={onSubmit}>
|
||||
{({ data, hasChanged, submit, change }) => (
|
||||
<Container>
|
||||
<Backlink onClick={onBack}>{appName}</Backlink>
|
||||
<PageHeader
|
||||
title={intl.formatMessage({
|
||||
defaultMessage: "Create Webhook",
|
||||
description: "header"
|
||||
})}
|
||||
/>
|
||||
<Grid>
|
||||
<div>
|
||||
<WebhookInfo
|
||||
data={data}
|
||||
disabled={disabled}
|
||||
errors={errors}
|
||||
onChange={change}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<WebhookEvents
|
||||
data={data}
|
||||
disabled={disabled}
|
||||
onChange={change}
|
||||
/>
|
||||
<FormSpacer />
|
||||
<WebhookStatus
|
||||
data={data.isActive}
|
||||
disabled={disabled}
|
||||
onChange={change}
|
||||
/>
|
||||
</div>
|
||||
</Grid>
|
||||
<Savebar
|
||||
disabled={disabled || !hasChanged}
|
||||
state={saveButtonBarState}
|
||||
onCancel={onBack}
|
||||
onSubmit={submit}
|
||||
/>
|
||||
</Container>
|
||||
)}
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
WebhookCreatePage.displayName = "WebhookCreatePage";
|
||||
export default WebhookCreatePage;
|
|
@ -1,29 +0,0 @@
|
|||
import Decorator from "@saleor/storybook/Decorator";
|
||||
import { WebhookErrorCode } from "@saleor/types/globalTypes";
|
||||
import { storiesOf } from "@storybook/react";
|
||||
import React from "react";
|
||||
|
||||
import WebhookCreatePage, { WebhookCreatePageProps } from "./WebhookCreatePage";
|
||||
|
||||
const props: WebhookCreatePageProps = {
|
||||
appName: "App",
|
||||
disabled: false,
|
||||
errors: [],
|
||||
onBack: () => undefined,
|
||||
onSubmit: () => undefined,
|
||||
saveButtonBarState: "default"
|
||||
};
|
||||
storiesOf("Views / Apps / Webhooks / Create webhook", module)
|
||||
.addDecorator(Decorator)
|
||||
.add("default", () => <WebhookCreatePage {...props} />)
|
||||
.add("loading", () => <WebhookCreatePage {...props} disabled={true} />)
|
||||
.add("form errors", () => (
|
||||
<WebhookCreatePage
|
||||
{...props}
|
||||
errors={["name", "targetUrl", "secretKey", null].map(field => ({
|
||||
__typename: "WebhookError",
|
||||
code: WebhookErrorCode.INVALID,
|
||||
field
|
||||
}))}
|
||||
/>
|
||||
));
|
|
@ -1,2 +0,0 @@
|
|||
export { default } from "./WebhookCreatePage";
|
||||
export * from "./WebhookCreatePage";
|
|
@ -4,11 +4,11 @@ import { storiesOf } from "@storybook/react";
|
|||
import React from "react";
|
||||
|
||||
import { webhook } from "../../fixtures";
|
||||
import WebhooksDetailsPage, {
|
||||
WebhooksDetailsPageProps
|
||||
} from "./WebhooksDetailsPage";
|
||||
import WebhookDetailsPage, {
|
||||
WebhookDetailsPageProps
|
||||
} from "./WebhookDetailsPage";
|
||||
|
||||
const props: WebhooksDetailsPageProps = {
|
||||
const props: WebhookDetailsPageProps = {
|
||||
appName: "app",
|
||||
disabled: false,
|
||||
errors: [],
|
||||
|
@ -19,15 +19,16 @@ const props: WebhooksDetailsPageProps = {
|
|||
};
|
||||
storiesOf("Views / Apps / Webhooks / Webhook details", module)
|
||||
.addDecorator(Decorator)
|
||||
.add("default", () => <WebhooksDetailsPage {...props} />)
|
||||
.add("default", () => <WebhookDetailsPage {...props} />)
|
||||
.add("undefined", () => <WebhookDetailsPage {...props} webhook={undefined} />)
|
||||
.add("unnamed", () => (
|
||||
<WebhooksDetailsPage {...props} webhook={{ ...webhook, name: null }} />
|
||||
<WebhookDetailsPage {...props} webhook={{ ...webhook, name: null }} />
|
||||
))
|
||||
.add("loading", () => (
|
||||
<WebhooksDetailsPage {...props} webhook={undefined} disabled={true} />
|
||||
<WebhookDetailsPage {...props} webhook={undefined} disabled={true} />
|
||||
))
|
||||
.add("form errors", () => (
|
||||
<WebhooksDetailsPage
|
||||
<WebhookDetailsPage
|
||||
{...props}
|
||||
errors={["name", "targetUrl", "secretKey", null].map(field => ({
|
||||
__typename: "WebhookError",
|
|
@ -0,0 +1,134 @@
|
|||
import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton";
|
||||
import Container from "@saleor/components/Container";
|
||||
import Form from "@saleor/components/Form";
|
||||
import FormSpacer from "@saleor/components/FormSpacer";
|
||||
import Grid from "@saleor/components/Grid";
|
||||
import PageHeader from "@saleor/components/PageHeader";
|
||||
import Savebar from "@saleor/components/Savebar";
|
||||
import { WebhookErrorFragment } from "@saleor/fragments/types/WebhookErrorFragment";
|
||||
import { Backlink } from "@saleor/macaw-ui";
|
||||
import {
|
||||
WebhookEventTypeAsync,
|
||||
WebhookEventTypeSync
|
||||
} from "@saleor/types/globalTypes";
|
||||
import WebhookEvents from "@saleor/webhooks/components/WebhookEvents";
|
||||
import WebhookInfo from "@saleor/webhooks/components/WebhookInfo";
|
||||
import WebhookStatus from "@saleor/webhooks/components/WebhookStatus";
|
||||
import {
|
||||
createAsyncEventsSelectHandler,
|
||||
createSyncEventsSelectHandler
|
||||
} from "@saleor/webhooks/handlers";
|
||||
import { WebhookDetails_webhook } from "@saleor/webhooks/types/WebhookDetails";
|
||||
import {
|
||||
mapAsyncEventsToChoices,
|
||||
mapSyncEventsToChoices
|
||||
} from "@saleor/webhooks/utils";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { getHeaderTitle } from "./messages";
|
||||
|
||||
export interface FormData {
|
||||
syncEvents: WebhookEventTypeSync[];
|
||||
asyncEvents: WebhookEventTypeAsync[];
|
||||
isActive: boolean;
|
||||
name: string;
|
||||
secretKey: string | null;
|
||||
targetUrl: string;
|
||||
}
|
||||
|
||||
export interface WebhookDetailsPageProps {
|
||||
appName: string;
|
||||
disabled: boolean;
|
||||
errors: WebhookErrorFragment[];
|
||||
webhook?: WebhookDetails_webhook;
|
||||
saveButtonBarState: ConfirmButtonTransitionState;
|
||||
onBack: () => void;
|
||||
onSubmit: (data: FormData) => void;
|
||||
}
|
||||
|
||||
const WebhookDetailsPage: React.FC<WebhookDetailsPageProps> = ({
|
||||
appName,
|
||||
disabled,
|
||||
errors,
|
||||
webhook,
|
||||
saveButtonBarState,
|
||||
onBack,
|
||||
onSubmit
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
|
||||
const initialForm: FormData = {
|
||||
syncEvents: webhook?.syncEvents?.map(event => event.eventType) || [],
|
||||
asyncEvents: webhook?.asyncEvents?.map(event => event.eventType) || [],
|
||||
isActive: !!webhook?.isActive,
|
||||
name: webhook?.name || "",
|
||||
secretKey: webhook?.secretKey || "",
|
||||
targetUrl: webhook?.targetUrl || ""
|
||||
};
|
||||
|
||||
return (
|
||||
<Form initial={initialForm} onSubmit={onSubmit}>
|
||||
{({ data, hasChanged, submit, change }) => {
|
||||
const syncEventsChoices = disabled
|
||||
? []
|
||||
: mapSyncEventsToChoices(Object.values(WebhookEventTypeSync));
|
||||
const asyncEventsChoices = disabled
|
||||
? []
|
||||
: mapAsyncEventsToChoices(
|
||||
Object.values(WebhookEventTypeAsync),
|
||||
data.asyncEvents
|
||||
);
|
||||
|
||||
const handleSyncEventsSelect = createSyncEventsSelectHandler(
|
||||
change,
|
||||
data.syncEvents
|
||||
);
|
||||
const handleAsyncEventsSelect = createAsyncEventsSelectHandler(
|
||||
change,
|
||||
data.asyncEvents
|
||||
);
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Backlink onClick={onBack}>{appName}</Backlink>
|
||||
<PageHeader title={getHeaderTitle(intl, webhook)} />
|
||||
<Grid>
|
||||
<div>
|
||||
<WebhookInfo
|
||||
data={data}
|
||||
disabled={disabled}
|
||||
errors={errors}
|
||||
onChange={change}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<WebhookEvents
|
||||
data={data}
|
||||
syncEventsChoices={syncEventsChoices}
|
||||
asyncEventsChoices={asyncEventsChoices}
|
||||
onSyncEventChange={handleSyncEventsSelect}
|
||||
onAsyncEventChange={handleAsyncEventsSelect}
|
||||
/>
|
||||
<FormSpacer />
|
||||
<WebhookStatus
|
||||
data={data.isActive}
|
||||
disabled={disabled}
|
||||
onChange={change}
|
||||
/>
|
||||
</div>
|
||||
</Grid>
|
||||
<Savebar
|
||||
disabled={disabled || !hasChanged}
|
||||
state={saveButtonBarState}
|
||||
onCancel={onBack}
|
||||
onSubmit={submit}
|
||||
/>
|
||||
</Container>
|
||||
);
|
||||
}}
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
WebhookDetailsPage.displayName = "WebhookDetailsPage";
|
||||
export default WebhookDetailsPage;
|
2
src/webhooks/components/WebhookDetailsPage/index.ts
Normal file
2
src/webhooks/components/WebhookDetailsPage/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export { default } from "./WebhookDetailsPage";
|
||||
export * from "./WebhookDetailsPage";
|
35
src/webhooks/components/WebhookDetailsPage/messages.ts
Normal file
35
src/webhooks/components/WebhookDetailsPage/messages.ts
Normal file
|
@ -0,0 +1,35 @@
|
|||
import { getStringOrPlaceholder } from "@saleor/misc";
|
||||
import { WebhookDetails_webhook } from "@saleor/webhooks/types/WebhookDetails";
|
||||
import { isUnnamed } from "@saleor/webhooks/utils";
|
||||
import { IntlShape } from "react-intl";
|
||||
import { defineMessages } from "react-intl";
|
||||
|
||||
export const messages = defineMessages({
|
||||
header: {
|
||||
defaultMessage: "Unnamed Webhook Details",
|
||||
description: "header"
|
||||
},
|
||||
headerNamed: {
|
||||
defaultMessage: "{webhookName} Details",
|
||||
description: "header"
|
||||
},
|
||||
headerCreate: {
|
||||
defaultMessage: "Create Webhook",
|
||||
description: "header"
|
||||
}
|
||||
});
|
||||
|
||||
export const getHeaderTitle = (
|
||||
intl: IntlShape,
|
||||
webhook?: WebhookDetails_webhook
|
||||
) => {
|
||||
if (!webhook) {
|
||||
return intl.formatMessage(messages.headerCreate);
|
||||
}
|
||||
if (isUnnamed(webhook)) {
|
||||
return intl.formatMessage(messages.header);
|
||||
}
|
||||
return intl.formatMessage(messages.headerNamed, {
|
||||
webhookName: getStringOrPlaceholder(webhook?.name)
|
||||
});
|
||||
};
|
|
@ -1,294 +1,95 @@
|
|||
import { Card, CardContent, Typography } from "@material-ui/core";
|
||||
import VerticalSpacer from "@saleor/apps/components/VerticalSpacer";
|
||||
import CardTitle from "@saleor/components/CardTitle";
|
||||
import ControlledCheckbox from "@saleor/components/ControlledCheckbox";
|
||||
import Hr from "@saleor/components/Hr";
|
||||
import MultiAutocompleteSelectField, {
|
||||
MultiAutocompleteChoiceType
|
||||
} from "@saleor/components/MultiAutocompleteSelectField";
|
||||
import { ChangeEvent } from "@saleor/hooks/useForm";
|
||||
import { WebhookEventTypeEnum } from "@saleor/types/globalTypes";
|
||||
import { toggle } from "@saleor/utils/lists";
|
||||
import {
|
||||
WebhookEventTypeAsync,
|
||||
WebhookEventTypeSync
|
||||
} from "@saleor/types/globalTypes";
|
||||
import {
|
||||
mapAsyncEventsToChoices,
|
||||
mapSyncEventsToChoices
|
||||
} from "@saleor/webhooks/utils";
|
||||
import React from "react";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { messages } from "./messages";
|
||||
|
||||
interface WebhookEventsProps {
|
||||
data: {
|
||||
allEvents: boolean;
|
||||
events: string[];
|
||||
syncEvents: WebhookEventTypeSync[];
|
||||
asyncEvents: WebhookEventTypeAsync[];
|
||||
};
|
||||
disabled: boolean;
|
||||
onChange: (event: ChangeEvent, cb?: () => void) => void;
|
||||
syncEventsChoices: MultiAutocompleteChoiceType[];
|
||||
asyncEventsChoices: MultiAutocompleteChoiceType[];
|
||||
onSyncEventChange: (event: ChangeEvent) => void;
|
||||
onAsyncEventChange: (event: ChangeEvent) => void;
|
||||
}
|
||||
|
||||
const WebhookEvents: React.FC<WebhookEventsProps> = ({
|
||||
data,
|
||||
disabled,
|
||||
onChange
|
||||
syncEventsChoices,
|
||||
asyncEventsChoices,
|
||||
onSyncEventChange,
|
||||
onAsyncEventChange
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
const eventsEnum = Object.values(WebhookEventTypeEnum);
|
||||
|
||||
const translatedEvents: Record<WebhookEventTypeEnum, string> = {
|
||||
[WebhookEventTypeEnum.ANY_EVENTS]: intl.formatMessage({
|
||||
defaultMessage: "All events",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.CHECKOUT_CREATED]: intl.formatMessage({
|
||||
defaultMessage: "Checkout created",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.CHECKOUT_UPDATED]: intl.formatMessage({
|
||||
defaultMessage: "Checkout updated",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.CUSTOMER_CREATED]: intl.formatMessage({
|
||||
defaultMessage: "Customer created",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.CUSTOMER_UPDATED]: intl.formatMessage({
|
||||
defaultMessage: "Customer updated",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.CHECKOUT_CREATED]: intl.formatMessage({
|
||||
defaultMessage: "Checkout created",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.CHECKOUT_UPDATED]: intl.formatMessage({
|
||||
defaultMessage: "Checkout updated",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.ORDER_CANCELLED]: intl.formatMessage({
|
||||
defaultMessage: "Order cancelled",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.ORDER_CREATED]: intl.formatMessage({
|
||||
defaultMessage: "Order created",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.ORDER_CONFIRMED]: intl.formatMessage({
|
||||
defaultMessage: "Order confirmed",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.ORDER_FULFILLED]: intl.formatMessage({
|
||||
defaultMessage: "Order fulfilled",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.ORDER_FULLY_PAID]: intl.formatMessage({
|
||||
defaultMessage: "Order fully paid",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.ORDER_UPDATED]: intl.formatMessage({
|
||||
defaultMessage: "Order updated",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.DRAFT_ORDER_CREATED]: intl.formatMessage({
|
||||
defaultMessage: "Draft order created",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.DRAFT_ORDER_DELETED]: intl.formatMessage({
|
||||
defaultMessage: "Draft order deleted",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.DRAFT_ORDER_UPDATED]: intl.formatMessage({
|
||||
defaultMessage: "Draft order updated",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.SALE_CREATED]: intl.formatMessage({
|
||||
defaultMessage: "Sale created",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.SALE_UPDATED]: intl.formatMessage({
|
||||
defaultMessage: "Sale updated",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.SALE_DELETED]: intl.formatMessage({
|
||||
defaultMessage: "Sale deleted",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.PAGE_CREATED]: intl.formatMessage({
|
||||
defaultMessage: "Page created",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.PAGE_DELETED]: intl.formatMessage({
|
||||
defaultMessage: "Page deleted",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.PAGE_UPDATED]: intl.formatMessage({
|
||||
defaultMessage: "Page updated",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.PAYMENT_AUTHORIZE]: intl.formatMessage({
|
||||
defaultMessage: "Authorize payment",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.PAYMENT_CAPTURE]: intl.formatMessage({
|
||||
defaultMessage: "Capture payment",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.PAYMENT_CONFIRM]: intl.formatMessage({
|
||||
defaultMessage: "Confirm payment",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.PAYMENT_LIST_GATEWAYS]: intl.formatMessage({
|
||||
defaultMessage: "List payment gateways",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.PAYMENT_PROCESS]: intl.formatMessage({
|
||||
defaultMessage: "Process payment",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.PAYMENT_REFUND]: intl.formatMessage({
|
||||
defaultMessage: "Refund payment",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.PAYMENT_VOID]: intl.formatMessage({
|
||||
defaultMessage: "Void payment",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.PRODUCT_CREATED]: intl.formatMessage({
|
||||
defaultMessage: "Product created",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.PRODUCT_UPDATED]: intl.formatMessage({
|
||||
defaultMessage: "Product updated",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.PRODUCT_DELETED]: intl.formatMessage({
|
||||
defaultMessage: "Product deleted",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.PRODUCT_VARIANT_BACK_IN_STOCK]: intl.formatMessage({
|
||||
defaultMessage: "Product variant back in stock",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.PRODUCT_VARIANT_OUT_OF_STOCK]: intl.formatMessage({
|
||||
defaultMessage: "Product variant out of stock",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.PRODUCT_VARIANT_CREATED]: intl.formatMessage({
|
||||
defaultMessage: "Product variant created",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.PRODUCT_VARIANT_UPDATED]: intl.formatMessage({
|
||||
defaultMessage: "Product variant updated",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.PRODUCT_VARIANT_DELETED]: intl.formatMessage({
|
||||
defaultMessage: "Product variant deleted",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.PRODUCT_VARIANT_BACK_IN_STOCK]: intl.formatMessage({
|
||||
defaultMessage: "Product variant back in stock",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.PRODUCT_VARIANT_OUT_OF_STOCK]: intl.formatMessage({
|
||||
defaultMessage: "Product variant out of stock",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.SHIPPING_LIST_METHODS_FOR_CHECKOUT]: intl.formatMessage(
|
||||
{
|
||||
defaultMessage: "Shipping methods for checkout listed",
|
||||
description: "event"
|
||||
}
|
||||
),
|
||||
[WebhookEventTypeEnum.FULFILLMENT_CANCELED]: intl.formatMessage({
|
||||
defaultMessage: "Fulfillment canceled",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.FULFILLMENT_CREATED]: intl.formatMessage({
|
||||
defaultMessage: "Fulfillment created",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.FULFILLMENT_CANCELED]: intl.formatMessage({
|
||||
defaultMessage: "Fulfillment canceled",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.INVOICE_REQUESTED]: intl.formatMessage({
|
||||
defaultMessage: "Invoice requested",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.INVOICE_SENT]: intl.formatMessage({
|
||||
defaultMessage: "Invoice sent",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.INVOICE_DELETED]: intl.formatMessage({
|
||||
defaultMessage: "Invoice deleted",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.PAGE_CREATED]: intl.formatMessage({
|
||||
defaultMessage: "Page created",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.PAGE_UPDATED]: intl.formatMessage({
|
||||
defaultMessage: "Page updated",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.PAGE_DELETED]: intl.formatMessage({
|
||||
defaultMessage: "Page deleted",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.NOTIFY_USER]: intl.formatMessage({
|
||||
defaultMessage: "User notified",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.TRANSLATION_CREATED]: intl.formatMessage({
|
||||
defaultMessage: "Translation created",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.TRANSLATION_UPDATED]: intl.formatMessage({
|
||||
defaultMessage: "Translation updated",
|
||||
description: "event"
|
||||
}),
|
||||
[WebhookEventTypeEnum.FULFILLMENT_CANCELED]: intl.formatMessage({
|
||||
defaultMessage: "Translation updated",
|
||||
description: "event"
|
||||
})
|
||||
};
|
||||
|
||||
const handleEventsChange = (event: ChangeEvent) =>
|
||||
onChange({
|
||||
target: {
|
||||
name: "events",
|
||||
value: toggle(event.target.name, data.events, (a, b) => a === b)
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardTitle
|
||||
title={intl.formatMessage({
|
||||
defaultMessage: "Events",
|
||||
description: "section header"
|
||||
})}
|
||||
/>
|
||||
<CardTitle title={intl.formatMessage(messages.events)} />
|
||||
<CardContent>
|
||||
<Typography>
|
||||
{intl.formatMessage({
|
||||
defaultMessage:
|
||||
"Expand or restrict webhooks permissions to register certain events in Saleor system.",
|
||||
description: "webhook events"
|
||||
})}
|
||||
<Typography variant="caption">
|
||||
<FormattedMessage {...messages.synchronousEvents} />
|
||||
</Typography>
|
||||
<ControlledCheckbox
|
||||
checked={data.allEvents}
|
||||
disabled={disabled}
|
||||
label={translatedEvents.ANY_EVENTS}
|
||||
name="allEvents"
|
||||
onChange={onChange}
|
||||
<VerticalSpacer />
|
||||
<Typography variant="body1">
|
||||
<FormattedMessage
|
||||
{...messages.assignPermissionsToSynchronousEvents}
|
||||
/>
|
||||
{!data.allEvents && (
|
||||
<>
|
||||
</Typography>
|
||||
<VerticalSpacer />
|
||||
<MultiAutocompleteSelectField
|
||||
displayValues={mapSyncEventsToChoices(data.syncEvents)}
|
||||
label={intl.formatMessage(messages.registeredEvents)}
|
||||
choices={syncEventsChoices}
|
||||
name="syncEvents"
|
||||
value={data.syncEvents}
|
||||
onChange={onSyncEventChange}
|
||||
data-test="syncEvents"
|
||||
testId="syncEvent"
|
||||
/>
|
||||
<VerticalSpacer spacing={2} />
|
||||
<Hr />
|
||||
{eventsEnum.slice(1).map(event => (
|
||||
<div key={event}>
|
||||
<ControlledCheckbox
|
||||
checked={data.events.includes(event)}
|
||||
disabled={disabled}
|
||||
label={translatedEvents[event]}
|
||||
name={event}
|
||||
onChange={handleEventsChange}
|
||||
<VerticalSpacer spacing={2} />
|
||||
<Typography variant="caption">
|
||||
<FormattedMessage {...messages.asynchronousEvents} />
|
||||
</Typography>
|
||||
<VerticalSpacer />
|
||||
<Typography variant="body1">
|
||||
<FormattedMessage
|
||||
{...messages.assignPermissionsToAsynchronousEvents}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
</Typography>
|
||||
<VerticalSpacer />
|
||||
<MultiAutocompleteSelectField
|
||||
displayValues={mapAsyncEventsToChoices(
|
||||
data.asyncEvents,
|
||||
data.asyncEvents
|
||||
)}
|
||||
label={intl.formatMessage(messages.registeredEvents)}
|
||||
choices={asyncEventsChoices}
|
||||
name="asyncEvents"
|
||||
value={data.asyncEvents}
|
||||
onChange={onAsyncEventChange}
|
||||
data-test="asyncEvents"
|
||||
testId="asyncEvent"
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
|
|
30
src/webhooks/components/WebhookEvents/messages.ts
Normal file
30
src/webhooks/components/WebhookEvents/messages.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
import { defineMessages } from "react-intl";
|
||||
|
||||
export const messages = defineMessages({
|
||||
events: {
|
||||
defaultMessage: "Events",
|
||||
description: "section header"
|
||||
},
|
||||
synchronousEvents: {
|
||||
defaultMessage: "Synchronous events",
|
||||
description: "section subheader"
|
||||
},
|
||||
asynchronousEvents: {
|
||||
defaultMessage: "Asynchronous events",
|
||||
description: "section subheader"
|
||||
},
|
||||
assignPermissionsToSynchronousEvents: {
|
||||
defaultMessage:
|
||||
"Assign permissions to register synchronous events for this webhook.",
|
||||
description: "section description"
|
||||
},
|
||||
assignPermissionsToAsynchronousEvents: {
|
||||
defaultMessage:
|
||||
"Assign permissions to register asynchronous events for this webhook.",
|
||||
description: "section description"
|
||||
},
|
||||
registeredEvents: {
|
||||
defaultMessage: "Registered events",
|
||||
description: "input label"
|
||||
}
|
||||
});
|
|
@ -4,13 +4,13 @@ import FormSpacer from "@saleor/components/FormSpacer";
|
|||
import Hr from "@saleor/components/Hr";
|
||||
import { WebhookErrorFragment } from "@saleor/fragments/types/WebhookErrorFragment";
|
||||
import { commonMessages } from "@saleor/intl";
|
||||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
import { getFormErrors } from "@saleor/utils/errors";
|
||||
import getWebhookErrorMessage from "@saleor/utils/errors/webhooks";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { FormData } from "../WebhooksDetailsPage";
|
||||
import { FormData } from "../WebhookDetailsPage";
|
||||
import { messages } from "./messages";
|
||||
|
||||
interface WebhookInfoProps {
|
||||
data: FormData;
|
||||
|
@ -19,51 +19,29 @@ interface WebhookInfoProps {
|
|||
onChange: (event: React.ChangeEvent<any>) => void;
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(
|
||||
() => ({
|
||||
status: {
|
||||
paddingTop: 20
|
||||
},
|
||||
title: {
|
||||
fontSize: 16,
|
||||
lineHeight: 1.9,
|
||||
paddingBottom: 10
|
||||
}
|
||||
}),
|
||||
{ name: "WebhookInfo" }
|
||||
);
|
||||
|
||||
const WebhookInfo: React.FC<WebhookInfoProps> = ({
|
||||
data,
|
||||
disabled,
|
||||
errors,
|
||||
onChange
|
||||
}) => {
|
||||
const classes = useStyles({});
|
||||
const intl = useIntl();
|
||||
|
||||
const formErrors = getFormErrors(["name", "targetUrl", "secretKey"], errors);
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardTitle
|
||||
title={intl.formatMessage({
|
||||
defaultMessage: "Webhook Information",
|
||||
description: "section header"
|
||||
})}
|
||||
/>
|
||||
<CardTitle title={intl.formatMessage(messages.webhookInformation)} />
|
||||
<CardContent>
|
||||
<Typography className={classes.title}>
|
||||
<Typography variant="caption">
|
||||
{intl.formatMessage(commonMessages.generalInformations)}
|
||||
</Typography>
|
||||
<FormSpacer />
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
error={!!formErrors.name}
|
||||
helperText={getWebhookErrorMessage(formErrors.name, intl)}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Webhook Name",
|
||||
description: "webhook"
|
||||
})}
|
||||
label={intl.formatMessage(messages.webhookName)}
|
||||
fullWidth
|
||||
name="name"
|
||||
value={data.name}
|
||||
|
@ -72,27 +50,14 @@ const WebhookInfo: React.FC<WebhookInfoProps> = ({
|
|||
<FormSpacer />
|
||||
<Hr />
|
||||
<FormSpacer />
|
||||
<Typography className={classes.title}>
|
||||
{intl.formatMessage({
|
||||
defaultMessage: "Webhook specific information",
|
||||
description: "webhook specific information"
|
||||
})}
|
||||
</Typography>
|
||||
<FormSpacer />
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
error={!!formErrors.targetUrl}
|
||||
helperText={
|
||||
getWebhookErrorMessage(formErrors.targetUrl, intl) ||
|
||||
intl.formatMessage({
|
||||
defaultMessage: "This URL will receive webhook POST requests",
|
||||
description: "webhook target url help text"
|
||||
})
|
||||
intl.formatMessage(messages.targetUrlDescription)
|
||||
}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Target URL",
|
||||
description: "webhook"
|
||||
})}
|
||||
label={intl.formatMessage(messages.targetUrl)}
|
||||
fullWidth
|
||||
name="targetUrl"
|
||||
value={data.targetUrl}
|
||||
|
@ -104,16 +69,9 @@ const WebhookInfo: React.FC<WebhookInfoProps> = ({
|
|||
error={!!formErrors.secretKey}
|
||||
helperText={
|
||||
getWebhookErrorMessage(formErrors.secretKey, intl) ||
|
||||
intl.formatMessage({
|
||||
defaultMessage:
|
||||
"secret key is used to create a hash signature with each payload. *optional field",
|
||||
description: "webhook secret key help text"
|
||||
})
|
||||
intl.formatMessage(messages.secretKeyDescription)
|
||||
}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Secret Key",
|
||||
description: "webhook"
|
||||
})}
|
||||
label={intl.formatMessage(messages.secretKey)}
|
||||
fullWidth
|
||||
name="secretKey"
|
||||
value={data.secretKey}
|
||||
|
|
29
src/webhooks/components/WebhookInfo/messages.ts
Normal file
29
src/webhooks/components/WebhookInfo/messages.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { defineMessages } from "react-intl";
|
||||
|
||||
export const messages = defineMessages({
|
||||
webhookInformation: {
|
||||
defaultMessage: "Webhook Information",
|
||||
description: "section header"
|
||||
},
|
||||
webhookName: {
|
||||
defaultMessage: "Webhook Name",
|
||||
description: "webhook input label"
|
||||
},
|
||||
targetUrl: {
|
||||
defaultMessage: "Target URL",
|
||||
description: "webhook input label"
|
||||
},
|
||||
secretKey: {
|
||||
defaultMessage: "Secret Key",
|
||||
description: "webhook input label"
|
||||
},
|
||||
targetUrlDescription: {
|
||||
defaultMessage: "This URL will receive webhook POST requests",
|
||||
description: "webhook input help text"
|
||||
},
|
||||
secretKeyDescription: {
|
||||
defaultMessage:
|
||||
"secret key is used to create a hash signature with each payload. *optional field",
|
||||
description: "webhook input help text"
|
||||
}
|
||||
});
|
|
@ -5,7 +5,8 @@ import { ChangeEvent } from "@saleor/hooks/useForm";
|
|||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { FormData } from "../WebhooksDetailsPage";
|
||||
import { FormData } from "../WebhookDetailsPage";
|
||||
import { messages } from "./messages";
|
||||
|
||||
interface WebhookStatusProps {
|
||||
data: boolean;
|
||||
|
@ -21,26 +22,14 @@ const WebhookStatus: React.FC<WebhookStatusProps> = ({
|
|||
const intl = useIntl();
|
||||
return (
|
||||
<Card>
|
||||
<CardTitle
|
||||
title={intl.formatMessage({
|
||||
defaultMessage: "Webhook Status",
|
||||
description: "section header"
|
||||
})}
|
||||
/>
|
||||
<CardTitle title={intl.formatMessage(messages.webhookStatus)} />
|
||||
<CardContent>
|
||||
<Typography>
|
||||
{intl.formatMessage({
|
||||
defaultMessage:
|
||||
"If you want to disable this webhook please uncheck the box below.",
|
||||
description: "webhook active"
|
||||
})}
|
||||
<Typography variant="body1">
|
||||
{intl.formatMessage(messages.webhookActiveDescription)}
|
||||
</Typography>
|
||||
<ControlledCheckbox
|
||||
name={"isActive" as keyof FormData}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Webhook is active",
|
||||
description: "webhooks active"
|
||||
})}
|
||||
label={intl.formatMessage(messages.webhookActive)}
|
||||
checked={data}
|
||||
onChange={onChange}
|
||||
disabled={disabled}
|
||||
|
|
17
src/webhooks/components/WebhookStatus/messages.ts
Normal file
17
src/webhooks/components/WebhookStatus/messages.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { defineMessages } from "react-intl";
|
||||
|
||||
export const messages = defineMessages({
|
||||
webhookStatus: {
|
||||
defaultMessage: "Webhook Status",
|
||||
description: "section header"
|
||||
},
|
||||
webhookActive: {
|
||||
defaultMessage: "Webhook is active",
|
||||
description: "webhooks active label"
|
||||
},
|
||||
webhookActiveDescription: {
|
||||
defaultMessage:
|
||||
"If you want to disable this webhook please uncheck the box below.",
|
||||
description: "webhook active description"
|
||||
}
|
||||
});
|
|
@ -1,121 +0,0 @@
|
|||
import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton";
|
||||
import Container from "@saleor/components/Container";
|
||||
import Form from "@saleor/components/Form";
|
||||
import FormSpacer from "@saleor/components/FormSpacer";
|
||||
import Grid from "@saleor/components/Grid";
|
||||
import PageHeader from "@saleor/components/PageHeader";
|
||||
import Savebar from "@saleor/components/Savebar";
|
||||
import { WebhookErrorFragment } from "@saleor/fragments/types/WebhookErrorFragment";
|
||||
import { Backlink } from "@saleor/macaw-ui";
|
||||
import { getStringOrPlaceholder } from "@saleor/misc";
|
||||
import { WebhookEventTypeEnum } from "@saleor/types/globalTypes";
|
||||
import WebhookEvents from "@saleor/webhooks/components/WebhookEvents";
|
||||
import WebhookInfo from "@saleor/webhooks/components/WebhookInfo";
|
||||
import WebhookStatus from "@saleor/webhooks/components/WebhookStatus";
|
||||
import { WebhookDetails_webhook } from "@saleor/webhooks/types/WebhookDetails";
|
||||
import { isUnnamed } from "@saleor/webhooks/utils";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
export interface FormData {
|
||||
events: WebhookEventTypeEnum[];
|
||||
isActive: boolean;
|
||||
name: string;
|
||||
secretKey: string | null;
|
||||
targetUrl: string;
|
||||
allEvents: boolean;
|
||||
}
|
||||
|
||||
export interface WebhooksDetailsPageProps {
|
||||
appName: string;
|
||||
disabled: boolean;
|
||||
errors: WebhookErrorFragment[];
|
||||
webhook: WebhookDetails_webhook;
|
||||
saveButtonBarState: ConfirmButtonTransitionState;
|
||||
onBack: () => void;
|
||||
onSubmit: (data: FormData) => void;
|
||||
}
|
||||
|
||||
const WebhooksDetailsPage: React.FC<WebhooksDetailsPageProps> = ({
|
||||
appName,
|
||||
disabled,
|
||||
errors,
|
||||
webhook,
|
||||
saveButtonBarState,
|
||||
onBack,
|
||||
onSubmit
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
const initialForm: FormData = {
|
||||
allEvents: !!webhook?.events?.find(
|
||||
event => event.eventType === WebhookEventTypeEnum.ANY_EVENTS
|
||||
),
|
||||
events:
|
||||
webhook?.events
|
||||
?.map(event => event.eventType)
|
||||
.filter(event => event !== WebhookEventTypeEnum.ANY_EVENTS) || [],
|
||||
isActive: !!webhook?.isActive,
|
||||
name: webhook?.name || "",
|
||||
secretKey: webhook?.secretKey || "",
|
||||
targetUrl: webhook?.targetUrl || ""
|
||||
};
|
||||
|
||||
return (
|
||||
<Form initial={initialForm} onSubmit={onSubmit}>
|
||||
{({ data, hasChanged, submit, change }) => (
|
||||
<Container>
|
||||
<Backlink onClick={onBack}>{appName}</Backlink>
|
||||
<PageHeader
|
||||
title={
|
||||
isUnnamed(webhook)
|
||||
? intl.formatMessage({
|
||||
defaultMessage: "Unnamed Webhook Details",
|
||||
description: "header"
|
||||
})
|
||||
: intl.formatMessage(
|
||||
{
|
||||
defaultMessage: "{webhookName} Details",
|
||||
description: "header"
|
||||
},
|
||||
{
|
||||
webhookName: getStringOrPlaceholder(webhook?.name)
|
||||
}
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Grid>
|
||||
<div>
|
||||
<WebhookInfo
|
||||
data={data}
|
||||
disabled={disabled}
|
||||
errors={errors}
|
||||
onChange={change}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<WebhookEvents
|
||||
data={data}
|
||||
onChange={change}
|
||||
disabled={disabled}
|
||||
/>
|
||||
<FormSpacer />
|
||||
<WebhookStatus
|
||||
data={data.isActive}
|
||||
disabled={disabled}
|
||||
onChange={change}
|
||||
/>
|
||||
</div>
|
||||
</Grid>
|
||||
<Savebar
|
||||
disabled={disabled || !hasChanged}
|
||||
state={saveButtonBarState}
|
||||
onCancel={onBack}
|
||||
onSubmit={submit}
|
||||
/>
|
||||
</Container>
|
||||
)}
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
WebhooksDetailsPage.displayName = "WebhooksDetailsPage";
|
||||
export default WebhooksDetailsPage;
|
|
@ -1,2 +0,0 @@
|
|||
export { default } from "./WebhooksDetailsPage";
|
||||
export * from "./WebhooksDetailsPage";
|
|
@ -7,7 +7,8 @@ export const webhook: WebhookDetails_webhook = {
|
|||
id: "Jzx1ss23sEt==",
|
||||
name: "Test App 2"
|
||||
},
|
||||
events: [],
|
||||
syncEvents: [],
|
||||
asyncEvents: [],
|
||||
id: "Jzx123sEt==",
|
||||
isActive: true,
|
||||
name: "Webhook Test 2",
|
||||
|
|
37
src/webhooks/handlers.ts
Normal file
37
src/webhooks/handlers.ts
Normal file
|
@ -0,0 +1,37 @@
|
|||
import { ChangeEvent } from "@saleor/hooks/useForm";
|
||||
import {
|
||||
WebhookEventTypeAsync,
|
||||
WebhookEventTypeSync
|
||||
} from "@saleor/types/globalTypes";
|
||||
import { toggle } from "@saleor/utils/lists";
|
||||
|
||||
import { filterSelectedAsyncEvents } from "./utils";
|
||||
|
||||
export const createSyncEventsSelectHandler = (
|
||||
change: (event: ChangeEvent, cb?: () => void) => void,
|
||||
syncEvents: WebhookEventTypeSync[]
|
||||
) => (event: ChangeEvent) => {
|
||||
const events = toggle(event.target.value, syncEvents, (a, b) => a === b);
|
||||
|
||||
change({
|
||||
target: {
|
||||
name: "syncEvents",
|
||||
value: events
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const createAsyncEventsSelectHandler = (
|
||||
change: (event: ChangeEvent, cb?: () => void) => void,
|
||||
asyncEvents: WebhookEventTypeAsync[]
|
||||
) => (event: ChangeEvent) => {
|
||||
const events = toggle(event.target.value, asyncEvents, (a, b) => a === b);
|
||||
const filteredEvents = filterSelectedAsyncEvents(events);
|
||||
|
||||
change({
|
||||
target: {
|
||||
name: "asyncEvents",
|
||||
value: filteredEvents
|
||||
}
|
||||
});
|
||||
};
|
|
@ -12,7 +12,10 @@ const webhooksDetails = gql`
|
|||
query WebhookDetails($id: ID!) {
|
||||
webhook(id: $id) {
|
||||
...WebhookFragment
|
||||
events {
|
||||
syncEvents {
|
||||
eventType
|
||||
}
|
||||
asyncEvents {
|
||||
eventType
|
||||
}
|
||||
secretKey
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { WebhookEventTypeEnum } from "./../../types/globalTypes";
|
||||
import { WebhookEventTypeSync, WebhookEventTypeAsync } from "./../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: WebhookDetails
|
||||
|
@ -15,9 +15,14 @@ export interface WebhookDetails_webhook_app {
|
|||
name: string | null;
|
||||
}
|
||||
|
||||
export interface WebhookDetails_webhook_events {
|
||||
__typename: "WebhookEvent";
|
||||
eventType: WebhookEventTypeEnum;
|
||||
export interface WebhookDetails_webhook_syncEvents {
|
||||
__typename: "WebhookEventSync";
|
||||
eventType: WebhookEventTypeSync;
|
||||
}
|
||||
|
||||
export interface WebhookDetails_webhook_asyncEvents {
|
||||
__typename: "WebhookEventAsync";
|
||||
eventType: WebhookEventTypeAsync;
|
||||
}
|
||||
|
||||
export interface WebhookDetails_webhook {
|
||||
|
@ -26,7 +31,8 @@ export interface WebhookDetails_webhook {
|
|||
name: string;
|
||||
isActive: boolean;
|
||||
app: WebhookDetails_webhook_app;
|
||||
events: WebhookDetails_webhook_events[];
|
||||
syncEvents: WebhookDetails_webhook_syncEvents[];
|
||||
asyncEvents: WebhookDetails_webhook_asyncEvents[];
|
||||
secretKey: string | null;
|
||||
targetUrl: string;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,47 @@
|
|||
import { MultiAutocompleteChoiceType } from "@saleor/components/MultiAutocompleteSelectField";
|
||||
import { WebhookFragment } from "@saleor/fragments/types/WebhookFragment";
|
||||
import {
|
||||
WebhookEventTypeAsync,
|
||||
WebhookEventTypeSync
|
||||
} from "@saleor/types/globalTypes";
|
||||
|
||||
export function isUnnamed(webhook: WebhookFragment): boolean {
|
||||
return ["", null].includes(webhook?.name);
|
||||
}
|
||||
|
||||
export function mapSyncEventsToChoices(
|
||||
events: WebhookEventTypeSync[]
|
||||
): MultiAutocompleteChoiceType[] {
|
||||
return events.map(event => ({
|
||||
label: event,
|
||||
value: event
|
||||
}));
|
||||
}
|
||||
|
||||
export function mapAsyncEventsToChoices(
|
||||
events: WebhookEventTypeAsync[],
|
||||
selectedEvents: WebhookEventTypeAsync[]
|
||||
): MultiAutocompleteChoiceType[] {
|
||||
const isAnyAsyncEventSelected = selectedEvents.includes(
|
||||
WebhookEventTypeAsync.ANY_EVENTS
|
||||
);
|
||||
|
||||
return events.map(event => ({
|
||||
label: event,
|
||||
value: event,
|
||||
disabled:
|
||||
event !== WebhookEventTypeAsync.ANY_EVENTS && isAnyAsyncEventSelected
|
||||
}));
|
||||
}
|
||||
|
||||
export const filterSelectedAsyncEvents = (
|
||||
asyncEvents: WebhookEventTypeAsync[]
|
||||
) => {
|
||||
const anyEvent = asyncEvents.find(
|
||||
event => event === WebhookEventTypeAsync.ANY_EVENTS
|
||||
);
|
||||
if (anyEvent) {
|
||||
return [anyEvent];
|
||||
}
|
||||
return asyncEvents;
|
||||
};
|
||||
|
|
|
@ -4,11 +4,11 @@ import { WindowTitle } from "@saleor/components/WindowTitle";
|
|||
import useNavigator from "@saleor/hooks/useNavigator";
|
||||
import useNotifier from "@saleor/hooks/useNotifier";
|
||||
import { commonMessages } from "@saleor/intl";
|
||||
import { WebhookEventTypeEnum } from "@saleor/types/globalTypes";
|
||||
import { WebhookEventTypeAsync } from "@saleor/types/globalTypes";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import WebhookCreatePage, { FormData } from "../components/WebhookCreatePage";
|
||||
import WebhookDetailsPage, { FormData } from "../components/WebhookDetailsPage";
|
||||
import { useWebhookCreateMutation } from "../mutations";
|
||||
import { WebhookCreate as WebhookCreateData } from "../types/WebhookCreate";
|
||||
import { webhookUrl } from "../urls";
|
||||
|
@ -44,9 +44,12 @@ export const WebhooksCreate: React.FC<WebhooksCreateProps> = ({ id }) => {
|
|||
variables: {
|
||||
input: {
|
||||
app: id,
|
||||
events: data.allEvents
|
||||
? [WebhookEventTypeEnum.ANY_EVENTS]
|
||||
: data.events,
|
||||
syncEvents: data.syncEvents,
|
||||
asyncEvents: data.asyncEvents.includes(
|
||||
WebhookEventTypeAsync.ANY_EVENTS
|
||||
)
|
||||
? [WebhookEventTypeAsync.ANY_EVENTS]
|
||||
: data.asyncEvents,
|
||||
isActive: data.isActive,
|
||||
name: data.name,
|
||||
secretKey: data.secretKey,
|
||||
|
@ -63,7 +66,7 @@ export const WebhooksCreate: React.FC<WebhooksCreateProps> = ({ id }) => {
|
|||
description: "window title"
|
||||
})}
|
||||
/>
|
||||
<WebhookCreatePage
|
||||
<WebhookDetailsPage
|
||||
appName={data?.app?.name}
|
||||
disabled={false}
|
||||
errors={webhookCreateOpts.data?.webhookCreate.errors || []}
|
||||
|
|
|
@ -4,13 +4,13 @@ import { WindowTitle } from "@saleor/components/WindowTitle";
|
|||
import useNavigator from "@saleor/hooks/useNavigator";
|
||||
import useNotifier from "@saleor/hooks/useNotifier";
|
||||
import { commonMessages } from "@saleor/intl";
|
||||
import { WebhookEventTypeEnum } from "@saleor/types/globalTypes";
|
||||
import { WebhookEventTypeAsync } from "@saleor/types/globalTypes";
|
||||
import { WebhookUpdate } from "@saleor/webhooks/types/WebhookUpdate";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { getStringOrPlaceholder } from "../../misc";
|
||||
import WebhooksDetailsPage from "../components/WebhooksDetailsPage";
|
||||
import WebhookDetailsPage from "../components/WebhookDetailsPage";
|
||||
import { useWebhookUpdateMutation } from "../mutations";
|
||||
import { useWebhooksDetailsQuery } from "../queries";
|
||||
|
||||
|
@ -57,7 +57,7 @@ export const WebhooksDetails: React.FC<WebhooksDetailsProps> = ({ id }) => {
|
|||
<WindowTitle
|
||||
title={getStringOrPlaceholder(webhookDetails?.webhook?.name)}
|
||||
/>
|
||||
<WebhooksDetailsPage
|
||||
<WebhookDetailsPage
|
||||
appName={webhook?.app?.name}
|
||||
disabled={loading}
|
||||
errors={formErrors}
|
||||
|
@ -69,9 +69,12 @@ export const WebhooksDetails: React.FC<WebhooksDetailsProps> = ({ id }) => {
|
|||
variables: {
|
||||
id,
|
||||
input: {
|
||||
events: data.allEvents
|
||||
? [WebhookEventTypeEnum.ANY_EVENTS]
|
||||
: data.events,
|
||||
syncEvents: data.syncEvents,
|
||||
asyncEvents: data.asyncEvents.includes(
|
||||
WebhookEventTypeAsync.ANY_EVENTS
|
||||
)
|
||||
? [WebhookEventTypeAsync.ANY_EVENTS]
|
||||
: data.asyncEvents,
|
||||
isActive: data.isActive,
|
||||
name: data.name,
|
||||
secretKey: data.secretKey,
|
||||
|
|
Loading…
Reference in a new issue