Fix bugs in forms (#1941)

* Fix plugin config form

* Add missing webhooks

* Fix rate description field

* Fix auth race condition

* Fix customer removal

* Fix staff member deletion

* Fix shipping rate submitting
This commit is contained in:
Dominik Żegleń 2022-03-23 15:12:56 +01:00 committed by GitHub
parent 26659a0be7
commit ed1c189b02
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 844 additions and 413 deletions

File diff suppressed because it is too large Load diff

View file

@ -22,6 +22,11 @@ export const SectionRoute: React.FC<SectionRouteProps> = ({
}) => {
const { user } = useUser();
// Prevents race condition
if (user === undefined) {
return null;
}
const hasSectionPermissions = () => {
if (!permissions) {
return true;

View file

@ -137,7 +137,13 @@ const CustomerDetailsViewInner: React.FC<CustomerDetailsViewProps> = ({
<ActionDialog
confirmButtonState={removeCustomerOpts.status}
onClose={() => navigate(customerUrl(id), { replace: true })}
onConfirm={() => removeCustomer()}
onConfirm={() =>
removeCustomer({
variables: {
id
}
})
}
title={intl.formatMessage({
defaultMessage: "Delete Customer",
description: "dialog header"

View file

@ -2066,12 +2066,13 @@ export type ObjectWithMetadataFieldPolicy = {
privateMetadata?: FieldPolicy<any> | FieldReadFunction<any>,
metadata?: FieldPolicy<any> | FieldReadFunction<any>
};
export type OrderKeySpecifier = ('id' | 'privateMetadata' | 'metadata' | 'created' | 'status' | 'user' | 'trackingClientId' | 'billingAddress' | 'shippingAddress' | 'shippingMethodName' | 'collectionPointName' | 'channel' | 'fulfillments' | 'lines' | 'actions' | 'availableShippingMethods' | 'shippingMethods' | 'availableCollectionPoints' | 'invoices' | 'number' | 'original' | 'origin' | 'isPaid' | 'paymentStatus' | 'paymentStatusDisplay' | 'payments' | 'total' | 'undiscountedTotal' | 'shippingMethod' | 'shippingPrice' | 'shippingTaxRate' | 'token' | 'voucher' | 'giftCards' | 'displayGrossPrices' | 'customerNote' | 'weight' | 'redirectUrl' | 'subtotal' | 'statusDisplay' | 'canFinalize' | 'totalAuthorized' | 'totalCaptured' | 'events' | 'totalBalance' | 'userEmail' | 'isShippingRequired' | 'deliveryMethod' | 'languageCode' | 'languageCodeEnum' | 'discount' | 'discountName' | 'translatedDiscountName' | 'discounts' | 'errors' | OrderKeySpecifier)[];
export type OrderKeySpecifier = ('id' | 'privateMetadata' | 'metadata' | 'created' | 'updatedAt' | 'status' | 'user' | 'trackingClientId' | 'billingAddress' | 'shippingAddress' | 'shippingMethodName' | 'collectionPointName' | 'channel' | 'fulfillments' | 'lines' | 'actions' | 'availableShippingMethods' | 'shippingMethods' | 'availableCollectionPoints' | 'invoices' | 'number' | 'original' | 'origin' | 'isPaid' | 'paymentStatus' | 'paymentStatusDisplay' | 'payments' | 'total' | 'undiscountedTotal' | 'shippingMethod' | 'shippingPrice' | 'shippingTaxRate' | 'token' | 'voucher' | 'giftCards' | 'displayGrossPrices' | 'customerNote' | 'weight' | 'redirectUrl' | 'subtotal' | 'statusDisplay' | 'canFinalize' | 'totalAuthorized' | 'totalCaptured' | 'events' | 'totalBalance' | 'userEmail' | 'isShippingRequired' | 'deliveryMethod' | 'languageCode' | 'languageCodeEnum' | 'discount' | 'discountName' | 'translatedDiscountName' | 'discounts' | 'errors' | OrderKeySpecifier)[];
export type OrderFieldPolicy = {
id?: FieldPolicy<any> | FieldReadFunction<any>,
privateMetadata?: FieldPolicy<any> | FieldReadFunction<any>,
metadata?: FieldPolicy<any> | FieldReadFunction<any>,
created?: FieldPolicy<any> | FieldReadFunction<any>,
updatedAt?: FieldPolicy<any> | FieldReadFunction<any>,
status?: FieldPolicy<any> | FieldReadFunction<any>,
user?: FieldPolicy<any> | FieldReadFunction<any>,
trackingClientId?: FieldPolicy<any> | FieldReadFunction<any>,
@ -2722,7 +2723,7 @@ export type PreorderThresholdFieldPolicy = {
quantity?: FieldPolicy<any> | FieldReadFunction<any>,
soldUnits?: FieldPolicy<any> | FieldReadFunction<any>
};
export type ProductKeySpecifier = ('id' | 'privateMetadata' | 'metadata' | 'seoTitle' | 'seoDescription' | 'name' | 'description' | 'productType' | 'slug' | 'category' | 'updatedAt' | 'chargeTaxes' | 'weight' | 'defaultVariant' | 'rating' | 'channel' | 'descriptionJson' | 'thumbnail' | 'pricing' | 'isAvailable' | 'taxType' | 'attributes' | 'channelListings' | 'mediaById' | 'imageById' | 'variants' | 'media' | 'images' | 'collections' | 'translation' | 'availableForPurchase' | 'isAvailableForPurchase' | ProductKeySpecifier)[];
export type ProductKeySpecifier = ('id' | 'privateMetadata' | 'metadata' | 'seoTitle' | 'seoDescription' | 'name' | 'description' | 'productType' | 'slug' | 'category' | 'created' | 'updatedAt' | 'chargeTaxes' | 'weight' | 'defaultVariant' | 'rating' | 'channel' | 'descriptionJson' | 'thumbnail' | 'pricing' | 'isAvailable' | 'taxType' | 'attributes' | 'channelListings' | 'mediaById' | 'imageById' | 'variants' | 'media' | 'images' | 'collections' | 'translation' | 'availableForPurchase' | 'isAvailableForPurchase' | ProductKeySpecifier)[];
export type ProductFieldPolicy = {
id?: FieldPolicy<any> | FieldReadFunction<any>,
privateMetadata?: FieldPolicy<any> | FieldReadFunction<any>,
@ -2734,6 +2735,7 @@ export type ProductFieldPolicy = {
productType?: FieldPolicy<any> | FieldReadFunction<any>,
slug?: FieldPolicy<any> | FieldReadFunction<any>,
category?: FieldPolicy<any> | FieldReadFunction<any>,
created?: FieldPolicy<any> | FieldReadFunction<any>,
updatedAt?: FieldPolicy<any> | FieldReadFunction<any>,
chargeTaxes?: FieldPolicy<any> | FieldReadFunction<any>,
weight?: FieldPolicy<any> | FieldReadFunction<any>,
@ -3001,7 +3003,7 @@ export type ProductUpdateFieldPolicy = {
errors?: FieldPolicy<any> | FieldReadFunction<any>,
product?: FieldPolicy<any> | FieldReadFunction<any>
};
export type ProductVariantKeySpecifier = ('id' | 'privateMetadata' | 'metadata' | 'name' | 'sku' | 'product' | 'trackInventory' | 'quantityLimitPerCustomer' | 'weight' | 'channel' | 'channelListings' | 'pricing' | 'attributes' | 'margin' | 'quantityOrdered' | 'revenue' | 'images' | 'media' | 'translation' | 'digitalContent' | 'stocks' | 'quantityAvailable' | 'preorder' | ProductVariantKeySpecifier)[];
export type ProductVariantKeySpecifier = ('id' | 'privateMetadata' | 'metadata' | 'name' | 'sku' | 'product' | 'trackInventory' | 'quantityLimitPerCustomer' | 'weight' | 'channel' | 'channelListings' | 'pricing' | 'attributes' | 'margin' | 'quantityOrdered' | 'revenue' | 'images' | 'media' | 'translation' | 'digitalContent' | 'stocks' | 'quantityAvailable' | 'preorder' | 'created' | 'updatedAt' | ProductVariantKeySpecifier)[];
export type ProductVariantFieldPolicy = {
id?: FieldPolicy<any> | FieldReadFunction<any>,
privateMetadata?: FieldPolicy<any> | FieldReadFunction<any>,
@ -3025,7 +3027,9 @@ export type ProductVariantFieldPolicy = {
digitalContent?: FieldPolicy<any> | FieldReadFunction<any>,
stocks?: FieldPolicy<any> | FieldReadFunction<any>,
quantityAvailable?: FieldPolicy<any> | FieldReadFunction<any>,
preorder?: FieldPolicy<any> | FieldReadFunction<any>
preorder?: FieldPolicy<any> | FieldReadFunction<any>,
created?: FieldPolicy<any> | FieldReadFunction<any>,
updatedAt?: FieldPolicy<any> | FieldReadFunction<any>
};
export type ProductVariantBulkCreateKeySpecifier = ('count' | 'productVariants' | 'bulkProductErrors' | 'errors' | ProductVariantBulkCreateKeySpecifier)[];
export type ProductVariantBulkCreateFieldPolicy = {
@ -3249,7 +3253,7 @@ export type RequestPasswordResetFieldPolicy = {
accountErrors?: FieldPolicy<any> | FieldReadFunction<any>,
errors?: FieldPolicy<any> | FieldReadFunction<any>
};
export type SaleKeySpecifier = ('id' | 'privateMetadata' | 'metadata' | 'name' | 'type' | 'startDate' | 'endDate' | 'categories' | 'collections' | 'products' | 'variants' | 'translation' | 'channelListings' | 'discountValue' | 'currency' | SaleKeySpecifier)[];
export type SaleKeySpecifier = ('id' | 'privateMetadata' | 'metadata' | 'name' | 'type' | 'startDate' | 'endDate' | 'created' | 'updatedAt' | 'categories' | 'collections' | 'products' | 'variants' | 'translation' | 'channelListings' | 'discountValue' | 'currency' | SaleKeySpecifier)[];
export type SaleFieldPolicy = {
id?: FieldPolicy<any> | FieldReadFunction<any>,
privateMetadata?: FieldPolicy<any> | FieldReadFunction<any>,
@ -3258,6 +3262,8 @@ export type SaleFieldPolicy = {
type?: FieldPolicy<any> | FieldReadFunction<any>,
startDate?: FieldPolicy<any> | FieldReadFunction<any>,
endDate?: FieldPolicy<any> | FieldReadFunction<any>,
created?: FieldPolicy<any> | FieldReadFunction<any>,
updatedAt?: FieldPolicy<any> | FieldReadFunction<any>,
categories?: FieldPolicy<any> | FieldReadFunction<any>,
collections?: FieldPolicy<any> | FieldReadFunction<any>,
products?: FieldPolicy<any> | FieldReadFunction<any>,
@ -3770,7 +3776,7 @@ export type UploadErrorFieldPolicy = {
message?: FieldPolicy<any> | FieldReadFunction<any>,
code?: FieldPolicy<any> | FieldReadFunction<any>
};
export type UserKeySpecifier = ('id' | 'privateMetadata' | 'metadata' | 'email' | 'firstName' | 'lastName' | 'isStaff' | 'isActive' | 'addresses' | 'checkout' | 'checkoutTokens' | 'giftCards' | 'note' | 'orders' | 'userPermissions' | 'permissionGroups' | 'editableGroups' | 'avatar' | 'events' | 'storedPaymentSources' | 'languageCode' | 'defaultShippingAddress' | 'defaultBillingAddress' | 'lastLogin' | 'dateJoined' | UserKeySpecifier)[];
export type UserKeySpecifier = ('id' | 'privateMetadata' | 'metadata' | 'email' | 'firstName' | 'lastName' | 'isStaff' | 'isActive' | 'addresses' | 'checkout' | 'checkoutTokens' | 'giftCards' | 'note' | 'orders' | 'userPermissions' | 'permissionGroups' | 'editableGroups' | 'avatar' | 'events' | 'storedPaymentSources' | 'languageCode' | 'defaultShippingAddress' | 'defaultBillingAddress' | 'lastLogin' | 'dateJoined' | 'updatedAt' | UserKeySpecifier)[];
export type UserFieldPolicy = {
id?: FieldPolicy<any> | FieldReadFunction<any>,
privateMetadata?: FieldPolicy<any> | FieldReadFunction<any>,
@ -3796,7 +3802,8 @@ export type UserFieldPolicy = {
defaultShippingAddress?: FieldPolicy<any> | FieldReadFunction<any>,
defaultBillingAddress?: FieldPolicy<any> | FieldReadFunction<any>,
lastLogin?: FieldPolicy<any> | FieldReadFunction<any>,
dateJoined?: FieldPolicy<any> | FieldReadFunction<any>
dateJoined?: FieldPolicy<any> | FieldReadFunction<any>,
updatedAt?: FieldPolicy<any> | FieldReadFunction<any>
};
export type UserAvatarDeleteKeySpecifier = ('user' | 'accountErrors' | 'errors' | UserAvatarDeleteKeySpecifier)[];
export type UserAvatarDeleteFieldPolicy = {

View file

@ -29,12 +29,6 @@ export type Scalars = {
* String, Boolean, Int, Float, List or Object.
*/
GenericScalar: any;
/**
* Allows use of a JSON String for input / output from the GraphQL schema.
*
* Use of this type is *not recommended* as you lose the benefits of having a defined, static
* schema (one of the key benefits of GraphQL).
*/
JSONString: any;
/**
* Positive Decimal scalar implementation.
@ -46,7 +40,7 @@ export type Scalars = {
/** Variables of this type must be set to null in mutations. They will be replaced with a filename from a following multipart part containing a binary file. See: https://github.com/jaydenseric/graphql-multipart-request-spec. */
Upload: any;
WeightScalar: any;
/** Anything */
/** _Any value scalar as defined by Federation spec. */
_Any: any;
};
@ -1085,6 +1079,7 @@ export type CustomerFilterInput = {
placedOrders?: InputMaybe<DateRangeInput>;
search?: InputMaybe<Scalars['String']>;
metadata?: InputMaybe<Array<InputMaybe<MetadataFilter>>>;
updatedAt?: InputMaybe<DateTimeRangeInput>;
};
export type CustomerInput = {
@ -1292,12 +1287,10 @@ export type ExportFileFilterInput = {
};
export enum ExportFileSortField {
/** Sort export file by status. */
STATUS = 'STATUS',
/** Sort export file by created at. */
CREATED_AT = 'CREATED_AT',
/** Sort export file by updated at. */
UPDATED_AT = 'UPDATED_AT'
UPDATED_AT = 'UPDATED_AT',
LAST_MODIFIED_AT = 'LAST_MODIFIED_AT'
}
export type ExportFileSortingInput = {
@ -1416,9 +1409,9 @@ export type GiftCardBulkCreateInput = {
};
export type GiftCardCreateInput = {
/** New in Saleor 3.1. The gift card tags to add. */
/** New in Saleor 3.1. The gift card tags to add. Note: this feature is in a preview state and can be subject to changes at later point. */
addTags?: InputMaybe<Array<Scalars['String']>>;
/** New in Saleor 3.1. The gift card expiry date. */
/** New in Saleor 3.1. The gift card expiry date. Note: this feature is in a preview state and can be subject to changes at later point. */
expiryDate?: InputMaybe<Scalars['Date']>;
/**
* Start date of the gift card in ISO 8601 format.
@ -1436,9 +1429,9 @@ export type GiftCardCreateInput = {
balance: PriceInput;
/** Email of the customer to whom gift card will be sent. */
userEmail?: InputMaybe<Scalars['String']>;
/** New in Saleor 3.1. Slug of a channel from which the email should be sent. */
/** New in Saleor 3.1. Slug of a channel from which the email should be sent. Note: this feature is in a preview state and can be subject to changes at later point. */
channel?: InputMaybe<Scalars['String']>;
/** New in Saleor 3.1. Determine if gift card is active. */
/** New in Saleor 3.1. Determine if gift card is active. Note: this feature is in a preview state and can be subject to changes at later point. */
isActive: Scalars['Boolean'];
/**
* Code to use the gift card.
@ -1446,7 +1439,7 @@ export type GiftCardCreateInput = {
* DEPRECATED: this field will be removed in Saleor 4.0. The code is now auto generated.
*/
code?: InputMaybe<Scalars['String']>;
/** New in Saleor 3.1. The gift card note from the staff member. */
/** New in Saleor 3.1. The gift card note from the staff member. Note: this feature is in a preview state and can be subject to changes at later point. */
note?: InputMaybe<Scalars['String']>;
};
@ -1546,9 +1539,9 @@ export type GiftCardTagFilterInput = {
};
export type GiftCardUpdateInput = {
/** New in Saleor 3.1. The gift card tags to add. */
/** New in Saleor 3.1. The gift card tags to add. Note: this feature is in a preview state and can be subject to changes at later point. */
addTags?: InputMaybe<Array<Scalars['String']>>;
/** New in Saleor 3.1. The gift card expiry date. */
/** New in Saleor 3.1. The gift card expiry date. Note: this feature is in a preview state and can be subject to changes at later point. */
expiryDate?: InputMaybe<Scalars['Date']>;
/**
* Start date of the gift card in ISO 8601 format.
@ -1562,9 +1555,9 @@ export type GiftCardUpdateInput = {
* DEPRECATED: this field will be removed in Saleor 4.0. Use `expiryDate` from `expirySettings` instead.
*/
endDate?: InputMaybe<Scalars['Date']>;
/** New in Saleor 3.1. The gift card tags to remove. */
/** New in Saleor 3.1. The gift card tags to remove. Note: this feature is in a preview state and can be subject to changes at later point. */
removeTags?: InputMaybe<Array<Scalars['String']>>;
/** New in Saleor 3.1. The gift card balance amount. */
/** New in Saleor 3.1. The gift card balance amount. Note: this feature is in a preview state and can be subject to changes at later point. */
balanceAmount?: InputMaybe<Scalars['PositiveDecimal']>;
};
@ -2529,7 +2522,8 @@ export enum MetadataErrorCode {
GRAPHQL_ERROR = 'GRAPHQL_ERROR',
INVALID = 'INVALID',
NOT_FOUND = 'NOT_FOUND',
REQUIRED = 'REQUIRED'
REQUIRED = 'REQUIRED',
NOT_UPDATED = 'NOT_UPDATED'
}
export type MetadataFilter = {
@ -2719,6 +2713,7 @@ export type OrderFilterInput = {
search?: InputMaybe<Scalars['String']>;
metadata?: InputMaybe<Array<InputMaybe<MetadataFilter>>>;
channels?: InputMaybe<Array<InputMaybe<Scalars['ID']>>>;
updatedAt?: InputMaybe<DateTimeRangeInput>;
isClickAndCollect?: InputMaybe<Scalars['Boolean']>;
isPreorder?: InputMaybe<Scalars['Boolean']>;
ids?: InputMaybe<Array<InputMaybe<Scalars['ID']>>>;
@ -2839,8 +2834,20 @@ export type OrderSettingsUpdateInput = {
export enum OrderSortField {
/** Sort orders by number. */
NUMBER = 'NUMBER',
/** Sort orders by creation date. */
/**
* Sort orders by creation date.
*
* DEPRECATED: this field will be removed in Saleor 4.0.
*/
CREATION_DATE = 'CREATION_DATE',
/**
* Sort orders by creation date.
*
* DEPRECATED: this field will be removed in Saleor 4.0.
*/
CREATED_AT = 'CREATED_AT',
/** Sort orders by last modified at. */
LAST_MODIFIED_AT = 'LAST_MODIFIED_AT',
/** Sort orders by customer. */
CUSTOMER = 'CUSTOMER',
/** Sort orders by payment. */
@ -3343,6 +3350,7 @@ export type ProductFilterInput = {
metadata?: InputMaybe<Array<InputMaybe<MetadataFilter>>>;
price?: InputMaybe<PriceRangeInput>;
minimalPrice?: InputMaybe<PriceRangeInput>;
updatedAt?: InputMaybe<DateTimeRangeInput>;
productTypes?: InputMaybe<Array<InputMaybe<Scalars['ID']>>>;
giftCard?: InputMaybe<Scalars['Boolean']>;
ids?: InputMaybe<Array<InputMaybe<Scalars['ID']>>>;
@ -3430,6 +3438,8 @@ export enum ProductOrderField {
/** Sort products by a minimal price of a product's variant. */
MINIMAL_PRICE = 'MINIMAL_PRICE',
/** Sort products by update date. */
LAST_MODIFIED = 'LAST_MODIFIED',
/** Sort products by update date. */
DATE = 'DATE',
/** Sort products by type. */
TYPE = 'TYPE',
@ -3437,6 +3447,10 @@ export enum ProductOrderField {
PUBLISHED = 'PUBLISHED',
/** Sort products by publication date. */
PUBLICATION_DATE = 'PUBLICATION_DATE',
/** Sort products by publication date. */
PUBLISHED_AT = 'PUBLISHED_AT',
/** Sort products by update date. */
LAST_MODIFIED_AT = 'LAST_MODIFIED_AT',
/** Sort products by collection. Note: This option is available only for the `Collection.products` query. */
COLLECTION = 'COLLECTION',
/** Sort products by rating. */
@ -3521,9 +3535,9 @@ export type ProductVariantBulkCreateInput = {
trackInventory?: InputMaybe<Scalars['Boolean']>;
/** Weight of the Product Variant. */
weight?: InputMaybe<Scalars['WeightScalar']>;
/** New in Saleor 3.1. Determines if variant is in preorder. */
/** New in Saleor 3.1. Determines if variant is in preorder. Note: this feature is in a preview state and can be subject to changes at later point. */
preorder?: InputMaybe<PreorderSettingsInput>;
/** New in Saleor 3.1. Determines maximum quantity of `ProductVariant`,that can be bought in a single checkout. */
/** New in Saleor 3.1. Determines maximum quantity of `ProductVariant`,that can be bought in a single checkout. Note: this feature is in a preview state and can be subject to changes at later point. */
quantityLimitPerCustomer?: InputMaybe<Scalars['Int']>;
/** Stocks of a product available for sale. */
stocks?: InputMaybe<Array<StockInput>>;
@ -3538,7 +3552,7 @@ export type ProductVariantChannelListingAddInput = {
price: Scalars['PositiveDecimal'];
/** Cost price of the variant in channel. */
costPrice?: InputMaybe<Scalars['PositiveDecimal']>;
/** New in Saleor 3.1. The threshold for preorder variant in channel. */
/** New in Saleor 3.1. The threshold for preorder variant in channel. Note: this feature is in a preview state and can be subject to changes at later point. */
preorderThreshold?: InputMaybe<Scalars['Int']>;
};
@ -3551,9 +3565,9 @@ export type ProductVariantCreateInput = {
trackInventory?: InputMaybe<Scalars['Boolean']>;
/** Weight of the Product Variant. */
weight?: InputMaybe<Scalars['WeightScalar']>;
/** New in Saleor 3.1. Determines if variant is in preorder. */
/** New in Saleor 3.1. Determines if variant is in preorder. Note: this feature is in a preview state and can be subject to changes at later point. */
preorder?: InputMaybe<PreorderSettingsInput>;
/** New in Saleor 3.1. Determines maximum quantity of `ProductVariant`,that can be bought in a single checkout. */
/** New in Saleor 3.1. Determines maximum quantity of `ProductVariant`,that can be bought in a single checkout. Note: this feature is in a preview state and can be subject to changes at later point. */
quantityLimitPerCustomer?: InputMaybe<Scalars['Int']>;
/** Product ID of which type is the variant. */
product: Scalars['ID'];
@ -3566,6 +3580,7 @@ export type ProductVariantFilterInput = {
sku?: InputMaybe<Array<InputMaybe<Scalars['String']>>>;
metadata?: InputMaybe<Array<InputMaybe<MetadataFilter>>>;
isPreorder?: InputMaybe<Scalars['Boolean']>;
updatedAt?: InputMaybe<DateTimeRangeInput>;
};
export type ProductVariantInput = {
@ -3577,12 +3592,24 @@ export type ProductVariantInput = {
trackInventory?: InputMaybe<Scalars['Boolean']>;
/** Weight of the Product Variant. */
weight?: InputMaybe<Scalars['WeightScalar']>;
/** New in Saleor 3.1. Determines if variant is in preorder. */
/** New in Saleor 3.1. Determines if variant is in preorder. Note: this feature is in a preview state and can be subject to changes at later point. */
preorder?: InputMaybe<PreorderSettingsInput>;
/** New in Saleor 3.1. Determines maximum quantity of `ProductVariant`,that can be bought in a single checkout. */
/** New in Saleor 3.1. Determines maximum quantity of `ProductVariant`,that can be bought in a single checkout. Note: this feature is in a preview state and can be subject to changes at later point. */
quantityLimitPerCustomer?: InputMaybe<Scalars['Int']>;
};
export enum ProductVariantSortField {
/** Sort products variants by last modified at. */
LAST_MODIFIED_AT = 'LAST_MODIFIED_AT'
}
export type ProductVariantSortingInput = {
/** Specifies the direction in which to sort products. */
direction: OrderDirection;
/** Sort productVariants by the selected field. */
field: ProductVariantSortField;
};
export type PublishableChannelListingInput = {
/** ID of a channel. */
channelId: Scalars['ID'];
@ -3624,6 +3651,7 @@ export type SaleFilterInput = {
started?: InputMaybe<DateTimeRangeInput>;
search?: InputMaybe<Scalars['String']>;
metadata?: InputMaybe<Array<InputMaybe<MetadataFilter>>>;
updatedAt?: InputMaybe<DateTimeRangeInput>;
};
export type SaleInput = {
@ -3656,7 +3684,11 @@ export enum SaleSortField {
/** Sort sales by value. */
VALUE = 'VALUE',
/** Sort sales by type. */
TYPE = 'TYPE'
TYPE = 'TYPE',
/** Sort sales by created at. */
CREATED_AT = 'CREATED_AT',
/** Sort sales by last modified at. */
LAST_MODIFIED_AT = 'LAST_MODIFIED_AT'
}
export type SaleSortingInput = {
@ -3848,7 +3880,7 @@ export type ShopSettingsInput = {
reserveStockDurationAnonymousUser?: InputMaybe<Scalars['Int']>;
/** New in Saleor 3.1. Default number of minutes stock will be reserved for authenticated checkout. Enter 0 or null to disable. */
reserveStockDurationAuthenticatedUser?: InputMaybe<Scalars['Int']>;
/** New in Saleor 3.1. Default number of maximum line quantity in single checkout. Minimum possible value is 1, default value is 50. */
/** New in Saleor 3.1. Default number of maximum line quantity in single checkout. Minimum possible value is 1, default value is 50. Note: this feature is in a preview state and can be subject to changes at later point. */
limitQuantityPerCheckout?: InputMaybe<Scalars['Int']>;
};
@ -4058,7 +4090,11 @@ export enum UserSortField {
/** Sort users by email. */
EMAIL = 'EMAIL',
/** Sort users by order count. */
ORDER_COUNT = 'ORDER_COUNT'
ORDER_COUNT = 'ORDER_COUNT',
/** Sort users by created at. */
CREATED_AT = 'CREATED_AT',
/** Sort users by last modified at. */
LAST_MODIFIED_AT = 'LAST_MODIFIED_AT'
}
export type UserSortingInput = {
@ -4251,9 +4287,9 @@ export type WarehouseUpdateInput = {
name?: InputMaybe<Scalars['String']>;
/** Address of the warehouse. */
address?: InputMaybe<AddressInput>;
/** New in Saleor 3.1. Click and collect options: local, all or disabled */
/** New in Saleor 3.1. Click and collect options: local, all or disabled. Note: this feature is in a preview state and can be subject to changes at later point. */
clickAndCollectOption?: InputMaybe<WarehouseClickAndCollectOptionEnum>;
/** New in Saleor 3.1. Visibility of warehouse stocks */
/** New in Saleor 3.1. Visibility of warehouse stocks. Note: this feature is in a preview state and can be subject to changes at later point. */
isPrivate?: InputMaybe<Scalars['Boolean']>;
};
@ -4409,7 +4445,9 @@ export enum WebhookEventTypeEnum {
PAYMENT_PROCESS = 'PAYMENT_PROCESS',
PAYMENT_REFUND = 'PAYMENT_REFUND',
PAYMENT_VOID = 'PAYMENT_VOID',
SHIPPING_LIST_METHODS_FOR_CHECKOUT = 'SHIPPING_LIST_METHODS_FOR_CHECKOUT'
SHIPPING_LIST_METHODS_FOR_CHECKOUT = 'SHIPPING_LIST_METHODS_FOR_CHECKOUT',
ORDER_FILTER_SHIPPING_METHODS = 'ORDER_FILTER_SHIPPING_METHODS',
CHECKOUT_FILTER_SHIPPING_METHODS = 'CHECKOUT_FILTER_SHIPPING_METHODS'
}
/** Enum determining type of webhook. */
@ -4421,7 +4459,9 @@ export enum WebhookEventTypeSyncEnum {
PAYMENT_PROCESS = 'PAYMENT_PROCESS',
PAYMENT_REFUND = 'PAYMENT_REFUND',
PAYMENT_VOID = 'PAYMENT_VOID',
SHIPPING_LIST_METHODS_FOR_CHECKOUT = 'SHIPPING_LIST_METHODS_FOR_CHECKOUT'
SHIPPING_LIST_METHODS_FOR_CHECKOUT = 'SHIPPING_LIST_METHODS_FOR_CHECKOUT',
ORDER_FILTER_SHIPPING_METHODS = 'ORDER_FILTER_SHIPPING_METHODS',
CHECKOUT_FILTER_SHIPPING_METHODS = 'CHECKOUT_FILTER_SHIPPING_METHODS'
}
/** An enumeration. */
@ -6696,7 +6736,7 @@ export type ProductListQueryVariables = Exact<{
}>;
export type ProductListQuery = { __typename: 'Query', products: { __typename: 'ProductCountableConnection', totalCount: number | null, edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', updatedAt: any | null, id: string, name: string, attributes?: Array<{ __typename: 'SelectedAttribute', attribute: { __typename: 'Attribute', id: string }, values: Array<{ __typename: 'AttributeValue', id: string, name: string | null, slug: string | null, reference: string | null, boolean: boolean | null, date: any | null, dateTime: any | null, value: string | null, file: { __typename: 'File', url: string, contentType: string | null } | null } | null> }>, thumbnail: { __typename: 'Image', url: string } | null, productType: { __typename: 'ProductType', id: string, name: string, hasVariants: boolean }, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, pricing?: { __typename: 'ProductPricingInfo', priceRange: { __typename: 'TaxedMoneyRange', start: { __typename: 'TaxedMoney', net: { __typename: 'Money', amount: number, currency: string } } | null, stop: { __typename: 'TaxedMoney', net: { __typename: 'Money', amount: number, currency: string } } | null } | null } | null, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', hasPreviousPage: boolean, hasNextPage: boolean, startCursor: string | null, endCursor: string | null } } | null };
export type ProductListQuery = { __typename: 'Query', products: { __typename: 'ProductCountableConnection', totalCount: number | null, edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', updatedAt: any, id: string, name: string, attributes?: Array<{ __typename: 'SelectedAttribute', attribute: { __typename: 'Attribute', id: string }, values: Array<{ __typename: 'AttributeValue', id: string, name: string | null, slug: string | null, reference: string | null, boolean: boolean | null, date: any | null, dateTime: any | null, value: string | null, file: { __typename: 'File', url: string, contentType: string | null } | null } | null> }>, thumbnail: { __typename: 'Image', url: string } | null, productType: { __typename: 'ProductType', id: string, name: string, hasVariants: boolean }, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, pricing?: { __typename: 'ProductPricingInfo', priceRange: { __typename: 'TaxedMoneyRange', start: { __typename: 'TaxedMoney', net: { __typename: 'Money', amount: number, currency: string } } | null, stop: { __typename: 'TaxedMoney', net: { __typename: 'Money', amount: number, currency: string } } | null } | null } | null, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', hasPreviousPage: boolean, hasNextPage: boolean, startCursor: string | null, endCursor: string | null } } | null };
export type ProductCountQueryVariables = Exact<{
filter?: InputMaybe<ProductFilterInput>;

View file

@ -3,6 +3,7 @@ import CardTitle from "@saleor/components/CardTitle";
import Hr from "@saleor/components/Hr";
import {
ConfigurationItemFragment,
ConfigurationItemInput,
ConfigurationTypeFieldEnum
} from "@saleor/graphql";
import { buttonMessages } from "@saleor/intl";
@ -12,6 +13,7 @@ import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
interface PluginAuthorizationProps {
data: ConfigurationItemInput[];
fields: ConfigurationItemFragment[];
onClear: (field: string) => void;
onEdit: (field: string) => void;
@ -37,7 +39,7 @@ const useStyles = makeStyles(
);
const PluginAuthorization: React.FC<PluginAuthorizationProps> = props => {
const { fields, onClear, onEdit } = props;
const { data, fields, onClear, onEdit } = props;
const classes = useStyles(props);
const intl = useIntl();
@ -55,7 +57,12 @@ const PluginAuthorization: React.FC<PluginAuthorizationProps> = props => {
})}
/>
<CardContent>
{secretFields.map((field, fieldIndex) => (
{secretFields.map((field, fieldIndex) => {
const inputData = data.find(
dataField => dataField.name === field.name
);
return (
<React.Fragment key={field.name}>
<div className={classes.item} key={field.name}>
{field.type === ConfigurationTypeFieldEnum.SECRET ||
@ -63,7 +70,7 @@ const PluginAuthorization: React.FC<PluginAuthorizationProps> = props => {
<div>
<Typography variant="body1">{field.label}</Typography>
{field.value !== null && (
<Typography>**** {field.value}</Typography>
<Typography>**** {inputData.value}</Typography>
)}
</div>
) : (
@ -95,7 +102,8 @@ const PluginAuthorization: React.FC<PluginAuthorizationProps> = props => {
<Hr className={classes.hr} />
)}
</React.Fragment>
))}
);
})}
</CardContent>
</Card>
);

View file

@ -55,7 +55,7 @@ const PluginsDetailsPage: React.FC<PluginsDetailsPageProps> = ({
}) => {
const intl = useIntl();
const initialFormData = (): PluginDetailsPageFormData => ({
const initialFormData: PluginDetailsPageFormData = {
active: selectedConfig?.active,
configuration: selectedConfig?.configuration
?.filter(
@ -65,14 +65,14 @@ const PluginsDetailsPage: React.FC<PluginsDetailsPageProps> = ({
...field,
value: field.value || ""
}))
});
};
const selectedChannelId = selectedConfig?.channel?.id;
return (
<Form
confirmLeave
initial={initialFormData()}
initial={initialFormData}
onSubmit={onSubmit}
key={selectedChannelId}
disabled={disabled}
@ -82,23 +82,16 @@ const PluginsDetailsPage: React.FC<PluginsDetailsPageProps> = ({
const { name, value } = event.target;
const newData = {
active: name === "active" ? value : data.active,
configuration: data.configuration
configuration: data.configuration.map(configItem =>
configItem.name === name
? {
...configItem,
value
}
: configItem
)
};
if (newData.configuration) {
newData.configuration.map(item => {
if (item.name === name) {
item.value = value;
}
});
selectedConfig.configuration.map(item => {
if (item.name === name) {
item.value = value;
}
});
}
set(newData);
};
return (
@ -149,7 +142,8 @@ const PluginsDetailsPage: React.FC<PluginsDetailsPageProps> = ({
<>
<CardSpacer />
<PluginAuthorization
fields={selectedConfig?.configuration}
data={data.configuration}
fields={selectedConfig.configuration}
onClear={onClear}
onEdit={onEdit}
/>

View file

@ -1,9 +1,7 @@
import { OutputData } from "@editorjs/editorjs";
import { ChannelShippingData } from "@saleor/channels/utils";
import CardSpacer from "@saleor/components/CardSpacer";
import ChannelsAvailabilityCard from "@saleor/components/ChannelsAvailabilityCard";
import Container from "@saleor/components/Container";
import Form, { FormDataWithOpts } from "@saleor/components/Form";
import { WithFormId } from "@saleor/components/Form/ExitFormDialogProvider";
import Grid from "@saleor/components/Grid";
import PageHeader from "@saleor/components/PageHeader";
@ -16,7 +14,8 @@ import {
ShippingMethodTypeEnum,
ShippingMethodTypeFragment
} from "@saleor/graphql";
import { SubmitPromise } from "@saleor/hooks/useForm";
import useForm, { SubmitPromise } from "@saleor/hooks/useForm";
import useHandleFormSubmit from "@saleor/hooks/useHandleFormSubmit";
import { Backlink, ConfirmButtonTransitionState } from "@saleor/macaw-ui";
import { validatePrice } from "@saleor/products/utils/validation";
import OrderValue from "@saleor/shipping/components/OrderValue";
@ -24,7 +23,8 @@ import OrderWeight from "@saleor/shipping/components/OrderWeight";
import PricingCard from "@saleor/shipping/components/PricingCard";
import ShippingRateInfo from "@saleor/shipping/components/ShippingRateInfo";
import { createChannelsChangeHandler } from "@saleor/shipping/handlers";
import React from "react";
import useRichText from "@saleor/utils/richText/useRichText";
import React, { FormEventHandler } from "react";
import { FormattedMessage, useIntl } from "react-intl";
import ShippingZonePostalCodes from "../ShippingZonePostalCodes";
@ -86,36 +86,53 @@ export const ShippingZoneRatesCreatePage: React.FC<ShippingZoneRatesCreatePagePr
type: null
};
const checkIfSaveIsDisabled = (
data: FormDataWithOpts<ShippingZoneRateCommonFormData>
) => {
const formDisabled = data.channelListings?.some(channel =>
validatePrice(channel.price)
);
const {
change,
data: formData,
hasChanged,
setChanged,
setIsSubmitDisabled,
triggerChange
} = useForm(initialForm, undefined, { confirmLeave: true, formId });
return disabled || formDisabled || (!data.hasChanged && !hasChannelChanged);
const handleFormSubmit = useHandleFormSubmit({
formId,
onSubmit,
setChanged
});
const [description, changeDescription] = useRichText({
initial: null,
triggerChange
});
// Prevents closing ref in submit functions
const getData = () => ({
...formData,
description: description.current
});
const data = getData();
const handleFormElementSubmit: FormEventHandler = event => {
event.preventDefault();
handleFormSubmit(getData());
};
const handleSubmit = () => handleFormSubmit(getData());
return (
<Form
confirmLeave
initial={initialForm}
onSubmit={onSubmit}
formId={formId}
checkIfSaveIsDisabled={checkIfSaveIsDisabled}
>
{({ change, data, isSaveDisabled, submit, triggerChange, set }) => {
const handleChannelsChange = createChannelsChangeHandler(
shippingChannels,
onChannelsChange,
triggerChange
);
const onDescriptionChange = (description: OutputData) => {
set({ description });
triggerChange();
};
const formDisabled = data.channelListings?.some(channel =>
validatePrice(channel.price)
);
const isSaveDisabled =
disabled || formDisabled || (!hasChanged && !hasChannelChanged);
setIsSubmitDisabled(isSaveDisabled);
return (
<form onSubmit={handleFormElementSubmit}>
<Container>
<Backlink onClick={onBack}>
<FormattedMessage defaultMessage="Shipping" />
@ -140,7 +157,7 @@ export const ShippingZoneRatesCreatePage: React.FC<ShippingZoneRatesCreatePagePr
disabled={disabled}
errors={errors}
onChange={change}
onDescriptionChange={onDescriptionChange}
onDescriptionChange={changeDescription}
/>
<CardSpacer />
{isPriceVariant ? (
@ -192,13 +209,11 @@ export const ShippingZoneRatesCreatePage: React.FC<ShippingZoneRatesCreatePagePr
disabled={isSaveDisabled}
onCancel={onBack}
onDelete={onDelete}
onSubmit={submit}
onSubmit={handleSubmit}
state={saveButtonBarState}
/>
</Container>
);
}}
</Form>
</form>
);
};

View file

@ -1,9 +1,7 @@
import { OutputData } from "@editorjs/editorjs";
import { ChannelShippingData } from "@saleor/channels/utils";
import CardSpacer from "@saleor/components/CardSpacer";
import ChannelsAvailabilityCard from "@saleor/components/ChannelsAvailabilityCard";
import Container from "@saleor/components/Container";
import Form, { FormDataWithOpts } from "@saleor/components/Form";
import { WithFormId } from "@saleor/components/Form/ExitFormDialogProvider";
import Grid from "@saleor/components/Grid";
import Metadata from "@saleor/components/Metadata/Metadata";
@ -18,7 +16,8 @@ import {
ShippingMethodTypeFragment,
ShippingZoneQuery
} from "@saleor/graphql";
import { SubmitPromise } from "@saleor/hooks/useForm";
import useForm, { SubmitPromise } from "@saleor/hooks/useForm";
import useHandleFormSubmit from "@saleor/hooks/useHandleFormSubmit";
import { Backlink, ConfirmButtonTransitionState } from "@saleor/macaw-ui";
import { validatePrice } from "@saleor/products/utils/validation";
import OrderValue from "@saleor/shipping/components/OrderValue";
@ -30,7 +29,8 @@ import { createChannelsChangeHandler } from "@saleor/shipping/handlers";
import { ListActions, ListProps } from "@saleor/types";
import { mapEdgesToItems, mapMetadataItemToInput } from "@saleor/utils/maps";
import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger";
import React from "react";
import useRichText from "@saleor/utils/richText/useRichText";
import React, { FormEventHandler } from "react";
import { FormattedMessage } from "react-intl";
import ShippingZonePostalCodes from "../ShippingZonePostalCodes";
@ -94,7 +94,7 @@ export const ShippingZoneRatesPage: React.FC<ShippingZoneRatesPageProps> = ({
}) => {
const isPriceVariant = variant === ShippingMethodTypeEnum.PRICE;
const initialForm: ShippingZoneRateUpdateFormData = {
const initialForm: Omit<ShippingZoneRateUpdateFormData, "description"> = {
channelListings: shippingChannels,
maxDays: rate?.maximumDeliveryDays?.toString() || "",
maxValue: rate?.maximumOrderWeight?.value.toString() || "",
@ -102,50 +102,66 @@ export const ShippingZoneRatesPage: React.FC<ShippingZoneRatesPageProps> = ({
minDays: rate?.minimumDeliveryDays?.toString() || "",
minValue: rate?.minimumOrderWeight?.value.toString() || "",
name: rate?.name || "",
description: rate?.description && JSON.parse(rate.description),
orderValueRestricted: !!rate?.channelListings.length,
privateMetadata: rate?.privateMetadata.map(mapMetadataItemToInput),
type: rate?.type || null
};
const {
change,
data: formData,
hasChanged,
setChanged,
setIsSubmitDisabled,
triggerChange
} = useForm(initialForm, undefined, { confirmLeave: true, formId });
const handleFormSubmit = useHandleFormSubmit({
formId,
onSubmit,
setChanged
});
const [description, changeDescription] = useRichText({
initial: rate?.description,
triggerChange
});
const {
makeChangeHandler: makeMetadataChangeHandler
} = useMetadataChangeTrigger();
const checkIfSaveIsDisabled = (
data: FormDataWithOpts<ShippingZoneRateUpdateFormData>
) => {
const formDisabled = data.channelListings?.some(channel =>
validatePrice(channel.price)
);
const formIsUnchanged =
!data.hasChanged && !hasChannelChanged && !havePostalCodesChanged;
// Prevents closing ref in submit functions
const getData = () => ({
...formData,
description: description.current
});
const data = getData();
return disabled || formDisabled || formIsUnchanged;
const handleFormElementSubmit: FormEventHandler = event => {
event.preventDefault();
handleFormSubmit(getData());
};
const handleSubmit = () => handleFormSubmit(getData());
return (
<Form
confirmLeave
initial={initialForm}
onSubmit={onSubmit}
formId={formId}
checkIfSaveIsDisabled={checkIfSaveIsDisabled}
>
{({ change, data, isSaveDisabled, submit, set, triggerChange }) => {
const handleChannelsChange = createChannelsChangeHandler(
shippingChannels,
onChannelsChange,
triggerChange
);
const onDescriptionChange = (description: OutputData) => {
set({ description });
triggerChange();
};
const formDisabled = formData.channelListings?.some(channel =>
validatePrice(channel.price)
);
const changeMetadata = makeMetadataChangeHandler(change);
const formIsUnchanged =
!hasChanged && !hasChannelChanged && !havePostalCodesChanged;
const isSaveDisabled = disabled || formDisabled || formIsUnchanged;
setIsSubmitDisabled(isSaveDisabled);
return (
<form onSubmit={handleFormElementSubmit}>
<Container>
<Backlink onClick={onBack}>
<FormattedMessage defaultMessage="Shipping" />
@ -158,7 +174,7 @@ export const ShippingZoneRatesPage: React.FC<ShippingZoneRatesPageProps> = ({
disabled={disabled}
errors={errors}
onChange={change}
onDescriptionChange={onDescriptionChange}
onDescriptionChange={changeDescription}
/>
<CardSpacer />
{isPriceVariant ? (
@ -223,13 +239,11 @@ export const ShippingZoneRatesPage: React.FC<ShippingZoneRatesPageProps> = ({
disabled={isSaveDisabled}
onCancel={onBack}
onDelete={onDelete}
onSubmit={submit}
onSubmit={handleSubmit}
state={saveButtonBarState}
/>
</Container>
);
}}
</Form>
</form>
);
};

View file

@ -224,7 +224,11 @@ export const StaffDetails: React.FC<OrderListProps> = ({ id, params }) => {
confirmButtonState={deleteResult.status}
variant="delete"
onClose={closeModal}
onConfirm={deleteStaffMember}
onConfirm={() =>
deleteStaffMember({
variables: { id }
})
}
>
<DialogContentText>
<FormattedMessage