Use error codes in webhook section

This commit is contained in:
dominik-zeglen 2020-03-18 12:03:20 +01:00
parent d92a8028cb
commit 6ab6cf4e68
21 changed files with 866 additions and 163 deletions

View file

@ -13,7 +13,7 @@ export const searchServiceAccount = gql`
search: serviceAccounts( search: serviceAccounts(
after: $after after: $after
first: $first first: $first
filter: { search: $query } filter: { search: $query, isActive: true }
) { ) {
edges { edges {
node { node {

View file

@ -131353,16 +131353,16 @@ exports[`Storyshots Views / Webhooks / Create webhook default 1`] = `
class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id" class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id"
> >
<label <label
class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-outlined-id" class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-outlined-id MuiFormLabel-error-id MuiInputLabel-error-id"
data-shrink="false" data-shrink="false"
> >
Webhook Name Webhook Name
</label> </label>
<div <div
class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id" class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-error-id MuiOutlinedInput-error-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id"
> >
<input <input
aria-invalid="false" aria-invalid="true"
class="MuiInputBase-input-id MuiOutlinedInput-input-id" class="MuiInputBase-input-id MuiOutlinedInput-input-id"
name="name" name="name"
type="text" type="text"
@ -131383,6 +131383,11 @@ exports[`Storyshots Views / Webhooks / Create webhook default 1`] = `
</legend> </legend>
</fieldset> </fieldset>
</div> </div>
<p
class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-error-id"
>
Invalid value
</p>
</div> </div>
<div <div
class="FormSpacer-spacer-id" class="FormSpacer-spacer-id"
@ -131464,16 +131469,16 @@ exports[`Storyshots Views / Webhooks / Create webhook default 1`] = `
class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id" class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id"
> >
<label <label
class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-outlined-id" class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-outlined-id MuiFormLabel-error-id MuiInputLabel-error-id"
data-shrink="false" data-shrink="false"
> >
Target URL Target URL
</label> </label>
<div <div
class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id" class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-error-id MuiOutlinedInput-error-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id"
> >
<input <input
aria-invalid="false" aria-invalid="true"
class="MuiInputBase-input-id MuiOutlinedInput-input-id" class="MuiInputBase-input-id MuiOutlinedInput-input-id"
name="targetUrl" name="targetUrl"
type="text" type="text"
@ -131495,9 +131500,9 @@ exports[`Storyshots Views / Webhooks / Create webhook default 1`] = `
</fieldset> </fieldset>
</div> </div>
<p <p
class="MuiFormHelperText-root-id MuiFormHelperText-contained-id" class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-error-id"
> >
This URL will receive webhook POST requests Invalid value
</p> </p>
</div> </div>
<div <div
@ -131507,16 +131512,16 @@ exports[`Storyshots Views / Webhooks / Create webhook default 1`] = `
class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id" class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id"
> >
<label <label
class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-outlined-id" class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-outlined-id MuiFormLabel-error-id MuiInputLabel-error-id"
data-shrink="false" data-shrink="false"
> >
Secrect Key Secrect Key
</label> </label>
<div <div
class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id" class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-error-id MuiOutlinedInput-error-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id"
> >
<input <input
aria-invalid="false" aria-invalid="true"
class="MuiInputBase-input-id MuiOutlinedInput-input-id" class="MuiInputBase-input-id MuiOutlinedInput-input-id"
name="secretKey" name="secretKey"
type="text" type="text"
@ -131538,9 +131543,9 @@ exports[`Storyshots Views / Webhooks / Create webhook default 1`] = `
</fieldset> </fieldset>
</div> </div>
<p <p
class="MuiFormHelperText-root-id MuiFormHelperText-contained-id" class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-error-id"
> >
secret key is used to create a hash signature with each payload. *optional field Invalid value
</p> </p>
</div> </div>
</div> </div>
@ -132037,7 +132042,7 @@ exports[`Storyshots Views / Webhooks / Create webhook form errors 1`] = `
<p <p
class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-error-id" class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-error-id"
> >
This field is required Invalid value
</p> </p>
</div> </div>
</div> </div>
@ -132547,6 +132552,11 @@ exports[`Storyshots Views / Webhooks / Create webhook loading 1`] = `
</legend> </legend>
</fieldset> </fieldset>
</div> </div>
<p
class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-error-id MuiFormHelperText-filled-id"
>
Invalid value
</p>
</div> </div>
<div <div
class="FormSpacer-spacer-id" class="FormSpacer-spacer-id"
@ -133066,6 +133076,12 @@ exports[`Storyshots Views / Webhooks / Delete webhook default 1`] = `
/> />
`; `;
exports[`Storyshots Views / Webhooks / Delete webhook unnamed webhook 1`] = `
<div
style="padding:24px"
/>
`;
exports[`Storyshots Views / Webhooks / Webhook details default 1`] = ` exports[`Storyshots Views / Webhooks / Webhook details default 1`] = `
<div <div
style="padding:24px" style="padding:24px"
@ -133127,16 +133143,16 @@ exports[`Storyshots Views / Webhooks / Webhook details default 1`] = `
class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id" class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id"
> >
<label <label
class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-shrink-id MuiInputLabel-outlined-id MuiFormLabel-filled-id" class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-shrink-id MuiInputLabel-outlined-id MuiFormLabel-error-id MuiInputLabel-error-id MuiFormLabel-filled-id"
data-shrink="true" data-shrink="true"
> >
Webhook Name Webhook Name
</label> </label>
<div <div
class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id" class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-error-id MuiOutlinedInput-error-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id"
> >
<input <input
aria-invalid="false" aria-invalid="true"
class="MuiInputBase-input-id MuiOutlinedInput-input-id" class="MuiInputBase-input-id MuiOutlinedInput-input-id"
name="name" name="name"
type="text" type="text"
@ -133238,16 +133254,16 @@ exports[`Storyshots Views / Webhooks / Webhook details default 1`] = `
class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id" class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id"
> >
<label <label
class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-shrink-id MuiInputLabel-outlined-id MuiFormLabel-filled-id" class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-shrink-id MuiInputLabel-outlined-id MuiFormLabel-error-id MuiInputLabel-error-id MuiFormLabel-filled-id"
data-shrink="true" data-shrink="true"
> >
Target URL Target URL
</label> </label>
<div <div
class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id" class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-error-id MuiOutlinedInput-error-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id"
> >
<input <input
aria-invalid="false" aria-invalid="true"
class="MuiInputBase-input-id MuiOutlinedInput-input-id" class="MuiInputBase-input-id MuiOutlinedInput-input-id"
name="targetUrl" name="targetUrl"
type="text" type="text"
@ -133269,9 +133285,9 @@ exports[`Storyshots Views / Webhooks / Webhook details default 1`] = `
</fieldset> </fieldset>
</div> </div>
<p <p
class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-filled-id" class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-error-id MuiFormHelperText-filled-id"
> >
This URL will receive webhook POST requests Invalid value
</p> </p>
</div> </div>
<div <div
@ -133281,16 +133297,16 @@ exports[`Storyshots Views / Webhooks / Webhook details default 1`] = `
class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id" class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id"
> >
<label <label
class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-shrink-id MuiInputLabel-outlined-id MuiFormLabel-filled-id" class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-shrink-id MuiInputLabel-outlined-id MuiFormLabel-error-id MuiInputLabel-error-id MuiFormLabel-filled-id"
data-shrink="true" data-shrink="true"
> >
Secrect Key Secrect Key
</label> </label>
<div <div
class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id" class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-error-id MuiOutlinedInput-error-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id"
> >
<input <input
aria-invalid="false" aria-invalid="true"
class="MuiInputBase-input-id MuiOutlinedInput-input-id" class="MuiInputBase-input-id MuiOutlinedInput-input-id"
name="secretKey" name="secretKey"
type="text" type="text"
@ -133312,9 +133328,9 @@ exports[`Storyshots Views / Webhooks / Webhook details default 1`] = `
</fieldset> </fieldset>
</div> </div>
<p <p
class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-filled-id" class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-error-id MuiFormHelperText-filled-id"
> >
secret key is used to create a hash signature with each payload. *optional field Invalid value
</p> </p>
</div> </div>
</div> </div>
@ -133811,7 +133827,7 @@ exports[`Storyshots Views / Webhooks / Webhook details form errors 1`] = `
<p <p
class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-error-id MuiFormHelperText-filled-id" class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-error-id MuiFormHelperText-filled-id"
> >
This field is required Invalid value
</p> </p>
</div> </div>
</div> </div>
@ -134834,6 +134850,584 @@ exports[`Storyshots Views / Webhooks / Webhook details loading 1`] = `
</div> </div>
`; `;
exports[`Storyshots Views / Webhooks / Webhook details unnamed 1`] = `
<div
style="padding:24px"
>
<form>
<div
class="Container-root-id"
>
<div
class="ExtendedPageHeader-root-id ExtendedPageHeader-block-id"
>
<div
class="MuiTypography-root-id PageHeader-title-id MuiTypography-h5-id"
>
Unnamed Webhook Details
</div>
<div
class="ExtendedPageHeader-action-id"
>
<div
class="PageHeader-root-id"
/>
</div>
</div>
<div
class="Grid-root-id Grid-default-id"
>
<div>
<div
class="MuiPaper-root-id MuiPaper-elevation0-id MuiCard-root-id MuiPaper-rounded-id"
>
<div
class="CardTitle-root-id"
>
<span
class="MuiTypography-root-id CardTitle-title-id MuiTypography-h5-id"
>
Webhook Information
</span>
<div
class="CardTitle-toolbar-id"
/>
</div>
<div
class="CardTitle-children-id"
/>
<hr
class="CardTitle-hr-id"
/>
<div
class="MuiCardContent-root-id"
>
<div
class="MuiTypography-root-id WebhookInfo-title-id MuiTypography-body1-id"
>
General Informations
</div>
<div
class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id"
>
<label
class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-outlined-id"
data-shrink="false"
>
Webhook Name
</label>
<div
class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id"
>
<input
aria-invalid="false"
class="MuiInputBase-input-id MuiOutlinedInput-input-id"
name="name"
type="text"
/>
<fieldset
aria-hidden="true"
class="PrivateNotchedOutline-root-id MuiOutlinedInput-notchedOutline-id"
style="padding-left:8px"
>
<legend
class="PrivateNotchedOutline-legend-id"
style="width:0.01px"
>
<span>
</span>
</legend>
</fieldset>
</div>
</div>
<div
class="FormSpacer-spacer-id"
/>
<hr
class="Hr-root-id"
/>
<div
class="FormSpacer-spacer-id"
/>
<div
class="MuiTypography-root-id WebhookInfo-title-id MuiTypography-body1-id"
>
Webhook specific information
</div>
<div
class="SingleAutocompleteSelectField-container-id"
>
<div
class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id"
>
<label
class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-shrink-id MuiInputLabel-outlined-id MuiFormLabel-filled-id"
data-shrink="true"
>
Assign to Service Account
</label>
<div
aria-autocomplete="list"
aria-expanded="false"
class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id MuiInputBase-adornedEnd-id MuiOutlinedInput-adornedEnd-id"
role="combobox"
>
<input
aria-invalid="false"
autocomplete="off"
class="MuiInputBase-input-id MuiOutlinedInput-input-id MuiInputBase-inputAdornedEnd-id MuiOutlinedInput-inputAdornedEnd-id"
type="text"
value="Test Account 2"
/>
<div>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-id"
focusable="false"
role="presentation"
viewBox="0 0 24 24"
>
<g
style="fill-rule:evenodd"
>
<path
d="M7 10l5 5 5-5z"
/>
</g>
</svg>
</div>
<fieldset
aria-hidden="true"
class="PrivateNotchedOutline-root-id MuiOutlinedInput-notchedOutline-id"
style="padding-left:8px"
>
<legend
class="PrivateNotchedOutline-legend-id"
style="width:0"
>
<span>
</span>
</legend>
</fieldset>
</div>
</div>
</div>
<div
class="FormSpacer-spacer-id"
/>
<div
class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id"
>
<label
class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-shrink-id MuiInputLabel-outlined-id MuiFormLabel-filled-id"
data-shrink="true"
>
Target URL
</label>
<div
class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id"
>
<input
aria-invalid="false"
class="MuiInputBase-input-id MuiOutlinedInput-input-id"
name="targetUrl"
type="text"
value="http://www.getsaleor.com"
/>
<fieldset
aria-hidden="true"
class="PrivateNotchedOutline-root-id MuiOutlinedInput-notchedOutline-id"
style="padding-left:8px"
>
<legend
class="PrivateNotchedOutline-legend-id"
style="width:0"
>
<span>
</span>
</legend>
</fieldset>
</div>
<p
class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-filled-id"
>
This URL will receive webhook POST requests
</p>
</div>
<div
class="FormSpacer-spacer-id"
/>
<div
class="MuiFormControl-root-id MuiTextField-root-id MuiFormControl-fullWidth-id"
>
<label
class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-shrink-id MuiInputLabel-outlined-id MuiFormLabel-filled-id"
data-shrink="true"
>
Secrect Key
</label>
<div
class="MuiInputBase-root-id MuiOutlinedInput-root-id MuiInputBase-fullWidth-id MuiInputBase-formControl-id"
>
<input
aria-invalid="false"
class="MuiInputBase-input-id MuiOutlinedInput-input-id"
name="secretKey"
type="text"
value="zxczx_asdas"
/>
<fieldset
aria-hidden="true"
class="PrivateNotchedOutline-root-id MuiOutlinedInput-notchedOutline-id"
style="padding-left:8px"
>
<legend
class="PrivateNotchedOutline-legend-id"
style="width:0"
>
<span>
</span>
</legend>
</fieldset>
</div>
<p
class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-filled-id"
>
secret key is used to create a hash signature with each payload. *optional field
</p>
</div>
</div>
</div>
</div>
<div>
<div
class="MuiPaper-root-id MuiPaper-elevation0-id MuiCard-root-id MuiPaper-rounded-id"
>
<div
class="CardTitle-root-id"
>
<span
class="MuiTypography-root-id CardTitle-title-id MuiTypography-h5-id"
>
Events
</span>
<div
class="CardTitle-toolbar-id"
/>
</div>
<div
class="CardTitle-children-id"
/>
<hr
class="CardTitle-hr-id"
/>
<div
class="MuiCardContent-root-id"
>
<div
class="MuiTypography-root-id MuiTypography-body1-id"
>
Expand or restrict webhooks permissions to register certain events in Saleor system.
</div>
<label
class="MuiFormControlLabel-root-id"
>
<button
class="MuiButtonBase-root-id Checkbox-root-id"
tabindex="0"
type="button"
>
<input
class="Checkbox-box-id"
name="allEvents"
type="checkbox"
value="false"
/>
</button>
<span
class="MuiTypography-root-id MuiFormControlLabel-label-id MuiTypography-body1-id"
>
All events
</span>
</label>
<hr
class="Hr-root-id"
/>
<div>
<label
class="MuiFormControlLabel-root-id"
>
<button
class="MuiButtonBase-root-id Checkbox-root-id"
tabindex="0"
type="button"
>
<input
class="Checkbox-box-id"
name="CHECKOUT_QUANTITY_CHANGED"
type="checkbox"
value="false"
/>
</button>
<span
class="MuiTypography-root-id MuiFormControlLabel-label-id MuiTypography-body1-id"
>
Changed quantity in checkout
</span>
</label>
</div>
<div>
<label
class="MuiFormControlLabel-root-id"
>
<button
class="MuiButtonBase-root-id Checkbox-root-id"
tabindex="0"
type="button"
>
<input
class="Checkbox-box-id"
name="CUSTOMER_CREATED"
type="checkbox"
value="false"
/>
</button>
<span
class="MuiTypography-root-id MuiFormControlLabel-label-id MuiTypography-body1-id"
>
Customer created
</span>
</label>
</div>
<div>
<label
class="MuiFormControlLabel-root-id"
>
<button
class="MuiButtonBase-root-id Checkbox-root-id"
tabindex="0"
type="button"
>
<input
class="Checkbox-box-id"
name="FULFILLMENT_CREATED"
type="checkbox"
value="false"
/>
</button>
<span
class="MuiTypography-root-id MuiFormControlLabel-label-id MuiTypography-body1-id"
>
Fulfillment created
</span>
</label>
</div>
<div>
<label
class="MuiFormControlLabel-root-id"
>
<button
class="MuiButtonBase-root-id Checkbox-root-id"
tabindex="0"
type="button"
>
<input
class="Checkbox-box-id"
name="ORDER_CANCELLED"
type="checkbox"
value="false"
/>
</button>
<span
class="MuiTypography-root-id MuiFormControlLabel-label-id MuiTypography-body1-id"
>
Order cancelled
</span>
</label>
</div>
<div>
<label
class="MuiFormControlLabel-root-id"
>
<button
class="MuiButtonBase-root-id Checkbox-root-id"
tabindex="0"
type="button"
>
<input
class="Checkbox-box-id"
name="ORDER_CREATED"
type="checkbox"
value="false"
/>
</button>
<span
class="MuiTypography-root-id MuiFormControlLabel-label-id MuiTypography-body1-id"
>
Order created
</span>
</label>
</div>
<div>
<label
class="MuiFormControlLabel-root-id"
>
<button
class="MuiButtonBase-root-id Checkbox-root-id"
tabindex="0"
type="button"
>
<input
class="Checkbox-box-id"
name="ORDER_FULFILLED"
type="checkbox"
value="false"
/>
</button>
<span
class="MuiTypography-root-id MuiFormControlLabel-label-id MuiTypography-body1-id"
>
Order fulfilled
</span>
</label>
</div>
<div>
<label
class="MuiFormControlLabel-root-id"
>
<button
class="MuiButtonBase-root-id Checkbox-root-id"
tabindex="0"
type="button"
>
<input
class="Checkbox-box-id"
name="ORDER_FULLY_PAID"
type="checkbox"
value="false"
/>
</button>
<span
class="MuiTypography-root-id MuiFormControlLabel-label-id MuiTypography-body1-id"
>
Order fully paid
</span>
</label>
</div>
<div>
<label
class="MuiFormControlLabel-root-id"
>
<button
class="MuiButtonBase-root-id Checkbox-root-id"
tabindex="0"
type="button"
>
<input
class="Checkbox-box-id"
name="ORDER_UPDATED"
type="checkbox"
value="false"
/>
</button>
<span
class="MuiTypography-root-id MuiFormControlLabel-label-id MuiTypography-body1-id"
>
Order updated
</span>
</label>
</div>
<div>
<label
class="MuiFormControlLabel-root-id"
>
<button
class="MuiButtonBase-root-id Checkbox-root-id"
tabindex="0"
type="button"
>
<input
class="Checkbox-box-id"
name="PRODUCT_CREATED"
type="checkbox"
value="false"
/>
</button>
<span
class="MuiTypography-root-id MuiFormControlLabel-label-id MuiTypography-body1-id"
>
Product created
</span>
</label>
</div>
</div>
</div>
<div
class="FormSpacer-spacer-id"
/>
<div
class="MuiPaper-root-id MuiPaper-elevation0-id MuiCard-root-id MuiPaper-rounded-id"
>
<div
class="CardTitle-root-id"
>
<span
class="MuiTypography-root-id CardTitle-title-id MuiTypography-h5-id"
>
Webhook Status
</span>
<div
class="CardTitle-toolbar-id"
/>
</div>
<div
class="CardTitle-children-id"
/>
<hr
class="CardTitle-hr-id"
/>
<div
class="MuiCardContent-root-id"
>
<div
class="MuiTypography-root-id MuiTypography-body1-id"
>
If you want to disable this webhook please uncheck the box below.
</div>
<label
class="MuiFormControlLabel-root-id"
>
<button
class="MuiButtonBase-root-id Checkbox-root-id"
tabindex="0"
type="button"
>
<input
class="Checkbox-box-id Checkbox-checked-id"
name="isActive"
type="checkbox"
value="true"
/>
</button>
<span
class="MuiTypography-root-id MuiFormControlLabel-label-id MuiTypography-body1-id"
>
Webhook is active
</span>
</label>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
`;
exports[`Storyshots Views / Webhooks / Webhook list default 1`] = ` exports[`Storyshots Views / Webhooks / Webhook list default 1`] = `
<div <div
style="padding:24px" style="padding:24px"
@ -135259,6 +135853,66 @@ exports[`Storyshots Views / Webhooks / Webhook list default 1`] = `
</button> </button>
</td> </td>
</tr> </tr>
<tr
class="MuiTableRow-root-id WebhooksList-tableRow-id MuiTableRow-hover-id"
>
<td
class="MuiTableCell-root-id MuiTableCell-body-id WebhooksList-colName-id WebhooksList-colNameUnnamed-id"
>
Unnamed webhook
</td>
<td
class="MuiTableCell-root-id MuiTableCell-body-id WebhooksList-colActive-id"
>
Test Account 2
</td>
<td
class="MuiTableCell-root-id MuiTableCell-body-id WebhooksList-colAction-id"
>
<button
class="MuiButtonBase-root-id MuiIconButton-root-id MuiIconButton-colorPrimary-id"
tabindex="0"
type="button"
>
<span
class="MuiIconButton-label-id"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-id"
focusable="false"
role="presentation"
viewBox="0 0 24 24"
>
<path
d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34a.9959.9959 0 00-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"
/>
</svg>
</span>
</button>
<button
class="MuiButtonBase-root-id MuiIconButton-root-id MuiIconButton-colorPrimary-id"
tabindex="0"
type="button"
>
<span
class="MuiIconButton-label-id"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-id"
focusable="false"
role="presentation"
viewBox="0 0 24 24"
>
<path
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
/>
</svg>
</span>
</button>
</td>
</tr>
</tbody> </tbody>
</table> </table>
</div> </div>

View file

@ -0,0 +1,28 @@
import { IntlShape } from "react-intl";
import { WebhookErrorCode } from "@saleor/types/globalTypes";
import { commonMessages } from "@saleor/intl";
import { WebhookErrorFragment } from "@saleor/webhooks/types/WebhookErrorFragment";
import commonErrorMessages from "./common";
function getWebhookErrorMessage(
err: Omit<WebhookErrorFragment, "__typename"> | undefined,
intl: IntlShape
): string {
if (err) {
switch (err.code) {
case WebhookErrorCode.GRAPHQL_ERROR:
return intl.formatMessage(commonErrorMessages.graphqlError);
case WebhookErrorCode.REQUIRED:
return intl.formatMessage(commonMessages.requiredField);
case WebhookErrorCode.INVALID:
return intl.formatMessage(commonErrorMessages.invalid);
default:
return intl.formatMessage(commonErrorMessages.unknownError);
}
}
return undefined;
}
export default getWebhookErrorMessage;

View file

@ -7,16 +7,15 @@ 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 { maybe } from "@saleor/misc";
import { SearchServiceAccount_search_edges_node } from "@saleor/searches/types/SearchServiceAccount"; import { SearchServiceAccount_search_edges_node } from "@saleor/searches/types/SearchServiceAccount";
import { WebhookEventTypeEnum } from "@saleor/types/globalTypes"; import { WebhookEventTypeEnum } from "@saleor/types/globalTypes";
import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler"; import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";
import WebhookEvents from "@saleor/webhooks/components/WebhookEvents"; import WebhookEvents from "@saleor/webhooks/components/WebhookEvents";
import WebhookInfo from "@saleor/webhooks/components/WebhookInfo"; import WebhookInfo from "@saleor/webhooks/components/WebhookInfo";
import WebhookStatus from "@saleor/webhooks/components/WebhookStatus"; import WebhookStatus from "@saleor/webhooks/components/WebhookStatus";
import { WebhookCreate_webhookCreate_webhookErrors } from "@saleor/webhooks/types/WebhookCreate";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
import { WebhookErrorFragment } from "@saleor/webhooks/types/WebhookErrorFragment";
export interface FormData { export interface FormData {
events: WebhookEventTypeEnum[]; events: WebhookEventTypeEnum[];
@ -30,7 +29,7 @@ export interface FormData {
export interface WebhookCreatePageProps { export interface WebhookCreatePageProps {
disabled: boolean; disabled: boolean;
errors: WebhookCreate_webhookCreate_webhookErrors[]; errors: WebhookErrorFragment[];
services?: SearchServiceAccount_search_edges_node[]; services?: SearchServiceAccount_search_edges_node[];
saveButtonBarState: ConfirmButtonTransitionState; saveButtonBarState: ConfirmButtonTransitionState;
fetchServiceAccounts: (data: string) => void; fetchServiceAccounts: (data: string) => void;
@ -60,14 +59,11 @@ const WebhookCreatePage: React.FC<WebhookCreatePageProps> = ({
const [selectedServiceAcccount, setSelectedServiceAcccount] = React.useState( const [selectedServiceAcccount, setSelectedServiceAcccount] = React.useState(
"" ""
); );
const servicesChoiceList = maybe( const servicesChoiceList =
() => services?.map(node => ({
services.map(node => ({
label: node.name, label: node.name,
value: node.id value: node.id
})), })) || [];
[]
);
return ( return (
<Form initial={initialForm} onSubmit={onSubmit}> <Form initial={initialForm} onSubmit={onSubmit}>

View file

@ -21,15 +21,10 @@ storiesOf("Views / Webhooks / Create webhook", module)
.add("form errors", () => ( .add("form errors", () => (
<WebhookCreatePage <WebhookCreatePage
{...props} {...props}
errors={[ errors={["name", "targetUrl", "secretKey", null].map(field => ({
{
code: WebhookErrorCode.INVALID,
field: null
}
].map(error => ({
__typename: "WebhookError", __typename: "WebhookError",
message: "Generic form error", code: WebhookErrorCode.INVALID,
...error field
}))} }))}
/> />
)); ));

View file

@ -16,4 +16,5 @@ const props: WebhookDeleteDialogProps = {
storiesOf("Views / Webhooks / Delete webhook", module) storiesOf("Views / Webhooks / Delete webhook", module)
.addDecorator(Decorator) .addDecorator(Decorator)
.add("default", () => <WebhookDeleteDialog {...props} />); .add("default", () => <WebhookDeleteDialog {...props} />)
.add("unnamed webhook", () => <WebhookDeleteDialog {...props} name={null} />);

View file

@ -4,6 +4,7 @@ import { FormattedMessage, useIntl } from "react-intl";
import ActionDialog from "@saleor/components/ActionDialog"; import ActionDialog from "@saleor/components/ActionDialog";
import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton"; import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton";
import { getStringOrPlaceholder } from "@saleor/misc";
export interface WebhookDeleteDialogProps { export interface WebhookDeleteDialogProps {
confirmButtonState: ConfirmButtonTransitionState; confirmButtonState: ConfirmButtonTransitionState;
@ -35,13 +36,20 @@ const WebhookDeleteDialog: React.FC<WebhookDeleteDialogProps> = ({
variant="delete" variant="delete"
> >
<DialogContentText> <DialogContentText>
{["", null].includes(name) ? (
<FormattedMessage
defaultMessage="Are you sure you want to delete this webhook?"
description="delete webhook"
/>
) : (
<FormattedMessage <FormattedMessage
defaultMessage="Are you sure you want to delete {name}?" defaultMessage="Are you sure you want to delete {name}?"
description="delete webhook" description="delete webhook"
values={{ values={{
name: <strong>{name}</strong> name: <strong>{getStringOrPlaceholder(name)}</strong>
}} }}
/> />
)}
</DialogContentText> </DialogContentText>
</ActionDialog> </ActionDialog>
); );

View file

@ -14,14 +14,15 @@ import SingleAutocompleteSelectField, {
} from "@saleor/components/SingleAutocompleteSelectField"; } from "@saleor/components/SingleAutocompleteSelectField";
import { ChangeEvent } from "@saleor/hooks/useForm"; import { ChangeEvent } from "@saleor/hooks/useForm";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { WebhookCreate_webhookCreate_webhookErrors } from "@saleor/webhooks/types/WebhookCreate"; import { getFormErrors } from "@saleor/utils/errors";
import { getFieldError } from "@saleor/utils/errors"; import getWebhookErrorMessage from "@saleor/utils/errors/webhooks";
import { WebhookErrorFragment } from "@saleor/webhooks/types/WebhookErrorFragment";
import { FormData } from "../WebhooksDetailsPage"; import { FormData } from "../WebhooksDetailsPage";
interface WebhookInfoProps { interface WebhookInfoProps {
data: FormData; data: FormData;
disabled: boolean; disabled: boolean;
errors: WebhookCreate_webhookCreate_webhookErrors[]; errors: WebhookErrorFragment[];
serviceDisplayValue: string; serviceDisplayValue: string;
services: SingleAutocompleteChoiceType[]; services: SingleAutocompleteChoiceType[];
onChange: (event: React.ChangeEvent<any>) => void; onChange: (event: React.ChangeEvent<any>) => void;
@ -55,8 +56,9 @@ const WebhookInfo: React.FC<WebhookInfoProps> = ({
}) => { }) => {
const classes = useStyles({}); const classes = useStyles({});
const intl = useIntl(); const intl = useIntl();
const serviceAccountsError =
errors.filter(error => error.field === null).length > 0; const serviceAccountError = errors.find(error => error.field === null);
const formErrors = getFormErrors(["name", "targetUrl", "secretKey"], errors);
return ( return (
<Card> <Card>
@ -72,8 +74,8 @@ const WebhookInfo: React.FC<WebhookInfoProps> = ({
</Typography> </Typography>
<TextField <TextField
disabled={disabled} disabled={disabled}
error={!!getFieldError(errors, "name")} error={!!formErrors.name}
helperText={getFieldError(errors, "name")?.message} helperText={getWebhookErrorMessage(formErrors.name, intl)}
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Webhook Name", defaultMessage: "Webhook Name",
description: "webhook" description: "webhook"
@ -98,11 +100,8 @@ const WebhookInfo: React.FC<WebhookInfoProps> = ({
label={intl.formatMessage({ label={intl.formatMessage({
defaultMessage: "Assign to Service Account" defaultMessage: "Assign to Service Account"
})} })}
error={serviceAccountsError} error={!!serviceAccountError}
helperText={ helperText={getWebhookErrorMessage(serviceAccountError, intl)}
serviceAccountsError &&
intl.formatMessage(commonMessages.requiredField)
}
name="serviceAccount" name="serviceAccount"
onChange={serviceOnChange} onChange={serviceOnChange}
value={data.serviceAccount} value={data.serviceAccount}
@ -115,9 +114,9 @@ const WebhookInfo: React.FC<WebhookInfoProps> = ({
<FormSpacer /> <FormSpacer />
<TextField <TextField
disabled={disabled} disabled={disabled}
error={!!getFieldError(errors, "targetUrl")} error={!!formErrors.targetUrl}
helperText={ helperText={
getFieldError(errors, "targetUrl")?.message || getWebhookErrorMessage(formErrors.targetUrl, intl) ||
intl.formatMessage({ intl.formatMessage({
defaultMessage: "This URL will receive webhook POST requests", defaultMessage: "This URL will receive webhook POST requests",
description: "webhook target url help text" description: "webhook target url help text"
@ -135,9 +134,9 @@ const WebhookInfo: React.FC<WebhookInfoProps> = ({
<FormSpacer /> <FormSpacer />
<TextField <TextField
disabled={disabled} disabled={disabled}
error={!!getFieldError(errors, "secretKey")} error={!!formErrors.secretKey}
helperText={ helperText={
getFieldError(errors, "secretKey")?.message || getWebhookErrorMessage(formErrors.secretKey, intl) ||
intl.formatMessage({ intl.formatMessage({
defaultMessage: defaultMessage:
"secret key is used to create a hash signature with each payload. *optional field", "secret key is used to create a hash signature with each payload. *optional field",

View file

@ -22,6 +22,9 @@ const props: WebhooksDetailsPageProps = {
storiesOf("Views / Webhooks / Webhook details", module) storiesOf("Views / Webhooks / Webhook details", module)
.addDecorator(Decorator) .addDecorator(Decorator)
.add("default", () => <WebhooksDetailsPage {...props} />) .add("default", () => <WebhooksDetailsPage {...props} />)
.add("unnamed", () => (
<WebhooksDetailsPage {...props} webhook={{ ...webhook, name: null }} />
))
.add("loading", () => ( .add("loading", () => (
<WebhooksDetailsPage <WebhooksDetailsPage
{...props} {...props}
@ -33,15 +36,10 @@ storiesOf("Views / Webhooks / Webhook details", module)
.add("form errors", () => ( .add("form errors", () => (
<WebhooksDetailsPage <WebhooksDetailsPage
{...props} {...props}
errors={[ errors={["name", "targetUrl", "secretKey", null].map(field => ({
{
code: WebhookErrorCode.INVALID,
field: null
}
].map(error => ({
__typename: "WebhookError", __typename: "WebhookError",
message: "Generic form error", code: WebhookErrorCode.INVALID,
...error field
}))} }))}
/> />
)); ));

View file

@ -11,15 +11,16 @@ import PageHeader from "@saleor/components/PageHeader";
import SaveButtonBar from "@saleor/components/SaveButtonBar"; import SaveButtonBar from "@saleor/components/SaveButtonBar";
import useStateFromProps from "@saleor/hooks/useStateFromProps"; import useStateFromProps from "@saleor/hooks/useStateFromProps";
import { sectionNames } from "@saleor/intl"; import { sectionNames } from "@saleor/intl";
import { maybe } from "@saleor/misc"; import { maybe, getStringOrPlaceholder } from "@saleor/misc";
import { SearchServiceAccount_search_edges_node } from "@saleor/searches/types/SearchServiceAccount"; import { SearchServiceAccount_search_edges_node } from "@saleor/searches/types/SearchServiceAccount";
import { WebhookEventTypeEnum } from "@saleor/types/globalTypes"; import { WebhookEventTypeEnum } from "@saleor/types/globalTypes";
import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler"; import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler";
import WebhookEvents from "@saleor/webhooks/components/WebhookEvents"; import WebhookEvents from "@saleor/webhooks/components/WebhookEvents";
import WebhookInfo from "@saleor/webhooks/components/WebhookInfo"; import WebhookInfo from "@saleor/webhooks/components/WebhookInfo";
import WebhookStatus from "@saleor/webhooks/components/WebhookStatus"; import WebhookStatus from "@saleor/webhooks/components/WebhookStatus";
import { WebhookCreate_webhookCreate_webhookErrors } from "@saleor/webhooks/types/WebhookCreate";
import { WebhookDetails_webhook } from "@saleor/webhooks/types/WebhookDetails"; import { WebhookDetails_webhook } from "@saleor/webhooks/types/WebhookDetails";
import { WebhookErrorFragment } from "@saleor/webhooks/types/WebhookErrorFragment";
import { isUnnamed } from "@saleor/webhooks/utils";
export interface FormData { export interface FormData {
events: WebhookEventTypeEnum[]; events: WebhookEventTypeEnum[];
@ -33,7 +34,7 @@ export interface FormData {
export interface WebhooksDetailsPageProps { export interface WebhooksDetailsPageProps {
disabled: boolean; disabled: boolean;
errors: WebhookCreate_webhookCreate_webhookErrors[]; errors: WebhookErrorFragment[];
webhook: WebhookDetails_webhook; webhook: WebhookDetails_webhook;
services?: SearchServiceAccount_search_edges_node[]; services?: SearchServiceAccount_search_edges_node[];
saveButtonBarState: ConfirmButtonTransitionState; saveButtonBarState: ConfirmButtonTransitionState;
@ -94,15 +95,22 @@ const WebhooksDetailsPage: React.FC<WebhooksDetailsPageProps> = ({
{intl.formatMessage(sectionNames.webhooks)} {intl.formatMessage(sectionNames.webhooks)}
</AppHeader> </AppHeader>
<PageHeader <PageHeader
title={intl.formatMessage( title={
isUnnamed(webhook)
? intl.formatMessage({
defaultMessage: "Unnamed Webhook Details",
description: "header"
})
: intl.formatMessage(
{ {
defaultMessage: "{webhookName} Details", defaultMessage: "{webhookName} Details",
description: "header" description: "header"
}, },
{ {
webhookName: maybe(() => webhook.name, "...") webhookName: getStringOrPlaceholder(webhook?.name)
}
)
} }
)}
/> />
<Grid> <Grid>
<div> <div>

View file

@ -8,16 +8,18 @@ import TableRow from "@material-ui/core/TableRow";
import DeleteIcon from "@material-ui/icons/Delete"; import DeleteIcon from "@material-ui/icons/Delete";
import EditIcon from "@material-ui/icons/Edit"; import EditIcon from "@material-ui/icons/Edit";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl, FormattedMessage } from "react-intl";
import classNames from "classnames";
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 TablePagination from "@saleor/components/TablePagination"; import TablePagination from "@saleor/components/TablePagination";
import { maybe, renderCollection, stopPropagation } from "@saleor/misc"; import { renderCollection, stopPropagation } from "@saleor/misc";
import { ListProps, SortPage } from "@saleor/types"; import { ListProps, SortPage } from "@saleor/types";
import { WebhookListUrlSortField } from "@saleor/webhooks/urls"; import { WebhookListUrlSortField } from "@saleor/webhooks/urls";
import TableCellHeader from "@saleor/components/TableCellHeader"; import TableCellHeader from "@saleor/components/TableCellHeader";
import { getArrowDirection } from "@saleor/utils/sort"; import { getArrowDirection } from "@saleor/utils/sort";
import { isUnnamed } from "@saleor/webhooks/utils";
import { Webhooks_webhooks_edges_node } from "../../types/Webhooks"; import { Webhooks_webhooks_edges_node } from "../../types/Webhooks";
export interface WebhooksListProps export interface WebhooksListProps
@ -49,6 +51,9 @@ const useStyles = makeStyles(
paddingLeft: 0, paddingLeft: 0,
width: 250 width: 250
}, },
colNameUnnamed: {
color: theme.palette.text.secondary
},
table: { table: {
tableLayout: "fixed" tableLayout: "fixed"
}, },
@ -143,14 +148,19 @@ const WebhooksList: React.FC<WebhooksListProps> = ({
onClick={webhook ? onRowClick(webhook.id) : undefined} onClick={webhook ? onRowClick(webhook.id) : undefined}
key={webhook ? webhook.id : "skeleton"} key={webhook ? webhook.id : "skeleton"}
> >
<TableCell className={classes.colName}> <TableCell
{maybe<React.ReactNode>(() => webhook.name, <Skeleton />)} className={classNames(classes.colName, {
[classes.colNameUnnamed]: isUnnamed(webhook)
})}
>
{isUnnamed(webhook) ? (
<FormattedMessage defaultMessage="Unnamed webhook" />
) : (
webhook?.name || <Skeleton />
)}
</TableCell> </TableCell>
<TableCell className={classes.colActive}> <TableCell className={classes.colActive}>
{maybe<React.ReactNode>( {webhook?.serviceAccount?.name || <Skeleton />}
() => webhook.serviceAccount.name,
<Skeleton />
)}
</TableCell> </TableCell>
<TableCell className={classes.colAction}> <TableCell className={classes.colAction}>
<IconButton <IconButton

View file

@ -23,6 +23,17 @@ export const webhookList: Webhooks_webhooks_edges_node[] = [
id: "Jzx1ss23sEt==", id: "Jzx1ss23sEt==",
name: "Test Account 2" name: "Test Account 2"
} }
},
{
__typename: "Webhook",
id: "Jzx12123sEt==",
isActive: false,
name: null,
serviceAccount: {
__typename: "ServiceAccount",
id: "Jzx1ss23sEt==",
name: "Test Account 2"
}
} }
]; ];
export const webhook: WebhookDetails_webhook = { export const webhook: WebhookDetails_webhook = {

View file

@ -6,18 +6,20 @@ import { WebhookCreate, WebhookCreateVariables } from "./types/WebhookCreate";
import { WebhookDelete, WebhookDeleteVariables } from "./types/WebhookDelete"; import { WebhookDelete, WebhookDeleteVariables } from "./types/WebhookDelete";
import { WebhookUpdate, WebhookUpdateVariables } from "./types/WebhookUpdate"; import { WebhookUpdate, WebhookUpdateVariables } from "./types/WebhookUpdate";
const webhookErrorFragment = gql`
fragment WebhookErrorFragment on WebhookError {
code
field
}
`;
const webhookCreate = gql` const webhookCreate = gql`
${webhooksDetailsFragment} ${webhooksDetailsFragment}
${webhookErrorFragment}
mutation WebhookCreate($input: WebhookCreateInput!) { mutation WebhookCreate($input: WebhookCreateInput!) {
webhookCreate(input: $input) { webhookCreate(input: $input) {
errors { errors: webhookErrors {
field ...WebhookErrorFragment
message
}
webhookErrors {
code
message
field
} }
webhook { webhook {
...WebhooksDetailsFragment ...WebhooksDetailsFragment
@ -32,16 +34,11 @@ export const TypedWebhookCreate = TypedMutation<
const webhookUpdate = gql` const webhookUpdate = gql`
${webhooksDetailsFragment} ${webhooksDetailsFragment}
${webhookErrorFragment}
mutation WebhookUpdate($id: ID!, $input: WebhookUpdateInput!) { mutation WebhookUpdate($id: ID!, $input: WebhookUpdateInput!) {
webhookUpdate(id: $id, input: $input) { webhookUpdate(id: $id, input: $input) {
errors { errors: webhookErrors {
field ...WebhookErrorFragment
message
}
webhookErrors {
code
message
field
} }
webhook { webhook {
...WebhooksDetailsFragment ...WebhooksDetailsFragment
@ -55,11 +52,11 @@ export const TypedWebhookUpdate = TypedMutation<
>(webhookUpdate); >(webhookUpdate);
const webhookDelete = gql` const webhookDelete = gql`
${webhookErrorFragment}
mutation WebhookDelete($id: ID!) { mutation WebhookDelete($id: ID!) {
webhookDelete(id: $id) { webhookDelete(id: $id) {
errors { errors: webhookErrors {
field ...WebhookErrorFragment
message
} }
} }
} }

View file

@ -9,15 +9,8 @@ import { WebhookCreateInput, WebhookErrorCode } from "./../../types/globalTypes"
// ==================================================== // ====================================================
export interface WebhookCreate_webhookCreate_errors { export interface WebhookCreate_webhookCreate_errors {
__typename: "Error";
field: string | null;
message: string | null;
}
export interface WebhookCreate_webhookCreate_webhookErrors {
__typename: "WebhookError"; __typename: "WebhookError";
code: WebhookErrorCode; code: WebhookErrorCode;
message: string | null;
field: string | null; field: string | null;
} }
@ -38,7 +31,6 @@ export interface WebhookCreate_webhookCreate_webhook {
export interface WebhookCreate_webhookCreate { export interface WebhookCreate_webhookCreate {
__typename: "WebhookCreate"; __typename: "WebhookCreate";
errors: WebhookCreate_webhookCreate_errors[]; errors: WebhookCreate_webhookCreate_errors[];
webhookErrors: WebhookCreate_webhookCreate_webhookErrors[];
webhook: WebhookCreate_webhookCreate_webhook | null; webhook: WebhookCreate_webhookCreate_webhook | null;
} }

View file

@ -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 { WebhookErrorCode } from "./../../types/globalTypes";
// ==================================================== // ====================================================
// GraphQL mutation operation: WebhookDelete // GraphQL mutation operation: WebhookDelete
// ==================================================== // ====================================================
export interface WebhookDelete_webhookDelete_errors { export interface WebhookDelete_webhookDelete_errors {
__typename: "Error"; __typename: "WebhookError";
code: WebhookErrorCode;
field: string | null; field: string | null;
message: string | null;
} }
export interface WebhookDelete_webhookDelete { export interface WebhookDelete_webhookDelete {

View file

@ -0,0 +1,15 @@
/* tslint:disable */
/* eslint-disable */
// This file was automatically generated and should not be edited.
import { WebhookErrorCode } from "./../../types/globalTypes";
// ====================================================
// GraphQL fragment: WebhookErrorFragment
// ====================================================
export interface WebhookErrorFragment {
__typename: "WebhookError";
code: WebhookErrorCode;
field: string | null;
}

View file

@ -9,15 +9,8 @@ import { WebhookUpdateInput, WebhookErrorCode } from "./../../types/globalTypes"
// ==================================================== // ====================================================
export interface WebhookUpdate_webhookUpdate_errors { export interface WebhookUpdate_webhookUpdate_errors {
__typename: "Error";
field: string | null;
message: string | null;
}
export interface WebhookUpdate_webhookUpdate_webhookErrors {
__typename: "WebhookError"; __typename: "WebhookError";
code: WebhookErrorCode; code: WebhookErrorCode;
message: string | null;
field: string | null; field: string | null;
} }
@ -38,7 +31,6 @@ export interface WebhookUpdate_webhookUpdate_webhook {
export interface WebhookUpdate_webhookUpdate { export interface WebhookUpdate_webhookUpdate {
__typename: "WebhookUpdate"; __typename: "WebhookUpdate";
errors: WebhookUpdate_webhookUpdate_errors[]; errors: WebhookUpdate_webhookUpdate_errors[];
webhookErrors: WebhookUpdate_webhookUpdate_webhookErrors[];
webhook: WebhookUpdate_webhookUpdate_webhook | null; webhook: WebhookUpdate_webhookUpdate_webhook | null;
} }

5
src/webhooks/utils.ts Normal file
View file

@ -0,0 +1,5 @@
import { WebhookFragment } from "./types/WebhookFragment";
export function isUnnamed(webhook: WebhookFragment): boolean {
return ["", null].includes(webhook?.name);
}

View file

@ -10,7 +10,7 @@ import usePaginator, {
createPaginationState createPaginationState
} from "@saleor/hooks/usePaginator"; } from "@saleor/hooks/usePaginator";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import { maybe } from "@saleor/misc"; import { maybe, getStringOrPlaceholder } from "@saleor/misc";
import { ListViews } from "@saleor/types"; import { ListViews } from "@saleor/types";
import WebhookDeleteDialog from "@saleor/webhooks/components/WebhookDeleteDialog"; import WebhookDeleteDialog from "@saleor/webhooks/components/WebhookDeleteDialog";
import { WebhookDelete } from "@saleor/webhooks/types/WebhookDelete"; import { WebhookDelete } from "@saleor/webhooks/types/WebhookDelete";
@ -171,7 +171,7 @@ export const WebhooksList: React.FC<WebhooksListProps> = ({ params }) => {
disabled={loading} disabled={loading}
settings={settings} settings={settings}
sort={getSortParams(params)} sort={getSortParams(params)}
webhooks={maybe(() => data.webhooks.edges.map(edge => edge.node))} webhooks={data?.webhooks.edges.map(edge => edge.node)}
pageInfo={pageInfo} pageInfo={pageInfo}
onAdd={() => navigate(webhookAddUrl)} onAdd={() => navigate(webhookAddUrl)}
onBack={() => navigate(configurationMenuUrl)} onBack={() => navigate(configurationMenuUrl)}
@ -184,12 +184,10 @@ export const WebhooksList: React.FC<WebhooksListProps> = ({ params }) => {
/> />
<WebhookDeleteDialog <WebhookDeleteDialog
confirmButtonState={webhookDeleteOpts.status} confirmButtonState={webhookDeleteOpts.status}
name={maybe( name={
() => data?.webhooks.edges.find(edge => edge.node.id === params.id)
data.webhooks.edges.find(edge => edge.node.id === params.id) ?.node?.name
.node.name, }
"..."
)}
onClose={closeModal} onClose={closeModal}
onConfirm={handleRemoveConfirm} onConfirm={handleRemoveConfirm}
open={params.action === "remove"} open={params.action === "remove"}
@ -205,7 +203,7 @@ export const WebhooksList: React.FC<WebhooksListProps> = ({ params }) => {
confirmButtonState="default" confirmButtonState="default"
onClose={closeModal} onClose={closeModal}
onSubmit={handleTabDelete} onSubmit={handleTabDelete}
tabName={maybe(() => tabs[currentTab - 1].name, "...")} tabName={getStringOrPlaceholder(tabs[currentTab - 1]?.name)}
/> />
</> </>
); );

View file

@ -8,7 +8,6 @@ import { WebhookEventTypeEnum } from "@saleor/types/globalTypes";
import { WebhookCreate as WebhookCreateData } from "@saleor/webhooks/types/WebhookCreate"; import { WebhookCreate as WebhookCreateData } from "@saleor/webhooks/types/WebhookCreate";
import React from "react"; import React from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
import { maybe } from "../../misc";
import WebhookCreatePage, { FormData } from "../components/WebhookCreatePage"; import WebhookCreatePage, { FormData } from "../components/WebhookCreatePage";
import { TypedWebhookCreate } from "../mutations"; import { TypedWebhookCreate } from "../mutations";
import { webhookListUrl, WebhookListUrlQueryParams, webhookUrl } from "../urls"; import { webhookListUrl, WebhookListUrlQueryParams, webhookUrl } from "../urls";
@ -30,7 +29,7 @@ export const WebhooksCreate: React.FC<WebhooksCreateProps> = () => {
}); });
const onSubmit = (data: WebhookCreateData) => { const onSubmit = (data: WebhookCreateData) => {
if (data.webhookCreate.webhookErrors.length === 0) { if (data.webhookCreate.errors.length === 0) {
notify({ notify({
text: intl.formatMessage(commonMessages.savedChanges) text: intl.formatMessage(commonMessages.savedChanges)
}); });
@ -69,13 +68,10 @@ export const WebhooksCreate: React.FC<WebhooksCreateProps> = () => {
/> />
<WebhookCreatePage <WebhookCreatePage
disabled={false} disabled={false}
errors={maybe( errors={webhookCreateOpts.data?.webhookCreate.errors || []}
() => webhookCreateOpts.data.webhookCreate.webhookErrors,
[]
)}
fetchServiceAccounts={searchServiceAccount} fetchServiceAccounts={searchServiceAccount}
services={maybe(() => services={searchServiceAccountOpt.data?.search.edges.map(
searchServiceAccountOpt.data.search.edges.map(edge => edge.node) edge => edge.node
)} )}
onBack={handleBack} onBack={handleBack}
onSubmit={handleSubmit} onSubmit={handleSubmit}

View file

@ -13,7 +13,7 @@ import { WebhookDelete } from "@saleor/webhooks/types/WebhookDelete";
import { WebhookUpdate } from "@saleor/webhooks/types/WebhookUpdate"; import { WebhookUpdate } from "@saleor/webhooks/types/WebhookUpdate";
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers"; import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
import NotFoundPage from "@saleor/components/NotFoundPage"; import NotFoundPage from "@saleor/components/NotFoundPage";
import { maybe, getStringOrPlaceholder } from "../../misc"; import { getStringOrPlaceholder } from "../../misc";
import WebhooksDetailsPage from "../components/WebhooksDetailsPage"; import WebhooksDetailsPage from "../components/WebhooksDetailsPage";
import { TypedWebhookDelete, TypedWebhookUpdate } from "../mutations"; import { TypedWebhookDelete, TypedWebhookUpdate } from "../mutations";
import { TypedWebhooksDetailsQuery } from "../queries"; import { TypedWebhooksDetailsQuery } from "../queries";
@ -58,14 +58,14 @@ export const WebhooksDetails: React.FC<WebhooksDetailsProps> = ({
}; };
const onWebhookUpdate = (data: WebhookUpdate) => { const onWebhookUpdate = (data: WebhookUpdate) => {
const errors = data.webhookUpdate?.webhookErrors; const errors = data.webhookUpdate?.errors;
const webhook = data.webhookUpdate?.webhook; const webhook = data.webhookUpdate?.webhook;
if (errors.length === 0 && webhook) { if (errors.length === 0 && webhook) {
notify({ notify({
text: intl.formatMessage(commonMessages.savedChanges) text: intl.formatMessage(commonMessages.savedChanges)
}); });
navigate(webhookUrl(webhook.id)); closeModal();
} }
}; };
@ -87,7 +87,7 @@ export const WebhooksDetails: React.FC<WebhooksDetailsProps> = ({
const webhook = webhookDetails?.data?.webhook; const webhook = webhookDetails?.data?.webhook;
const formErrors = const formErrors =
webhookUpdateOpts.data?.webhookUpdate.webhookErrors || []; webhookUpdateOpts.data?.webhookUpdate.errors || [];
if (webhook === null) { if (webhook === null) {
return <NotFoundPage onBack={handleOnBack} />; return <NotFoundPage onBack={handleOnBack} />;
@ -106,10 +106,8 @@ export const WebhooksDetails: React.FC<WebhooksDetailsProps> = ({
saveButtonBarState={webhookUpdateOpts.status} saveButtonBarState={webhookUpdateOpts.status}
webhook={webhook} webhook={webhook}
fetchServiceAccounts={searchServiceAccount} fetchServiceAccounts={searchServiceAccount}
services={maybe(() => services={searchServiceAccountOpt.data?.search.edges.map(
searchServiceAccountOpt.data.search.edges.map(
edge => edge.node edge => edge.node
)
)} )}
onBack={handleOnBack} onBack={handleOnBack}
onDelete={() => openModal("remove")} onDelete={() => openModal("remove")}
@ -133,7 +131,7 @@ export const WebhooksDetails: React.FC<WebhooksDetailsProps> = ({
/> />
<WebhookDeleteDialog <WebhookDeleteDialog
confirmButtonState={webhookDeleteOpts.status} confirmButtonState={webhookDeleteOpts.status}
name={getStringOrPlaceholder(webhook?.name)} name={webhook?.name}
onClose={closeModal} onClose={closeModal}
onConfirm={handleRemoveConfirm} onConfirm={handleRemoveConfirm}
open={params.action === "remove"} open={params.action === "remove"}