diff --git a/admin-ui/src/app/catalog/components/product-variants-list/product-variants-list.component.scss b/admin-ui/src/app/catalog/components/product-variants-list/product-variants-list.component.scss
index 203ac6a9a9..d8a2cb7bf2 100644
--- a/admin-ui/src/app/catalog/components/product-variants-list/product-variants-list.component.scss
+++ b/admin-ui/src/app/catalog/components/product-variants-list/product-variants-list.component.scss
@@ -59,6 +59,10 @@
}
}
+ .right-controls {
+ display: flex;
+ }
+
.variant-form-input-row {
display: flex;
flex-wrap: wrap;
diff --git a/admin-ui/src/app/catalog/components/product-variants-list/product-variants-list.component.ts b/admin-ui/src/app/catalog/components/product-variants-list/product-variants-list.component.ts
index 33dc8a0606..5d4cc7c61a 100644
--- a/admin-ui/src/app/catalog/components/product-variants-list/product-variants-list.component.ts
+++ b/admin-ui/src/app/catalog/components/product-variants-list/product-variants-list.component.ts
@@ -48,6 +48,7 @@ export class ProductVariantsListComponent implements OnChanges, OnInit, OnDestro
@Output() selectionChange = new EventEmitter
();
@Output() selectFacetValueClick = new EventEmitter();
@Output() updateProductOption = new EventEmitter();
+ @Output() deleteVariant = new EventEmitter();
selectedVariantIds: string[] = [];
private facetValues: FacetValue.Fragment[];
private formSubscription: Subscription;
@@ -163,6 +164,10 @@ export class ProductVariantsListComponent implements OnChanges, OnInit, OnDestro
});
}
+ deleteVariantClick(id: string) {
+ this.deleteVariant.emit(id);
+ }
+
private getFacetValueIds(index: number): string[] {
const formValue: VariantFormValue = this.formArray.at(index).value;
return formValue.facetValueIds;
diff --git a/admin-ui/src/app/catalog/providers/product-detail.service.ts b/admin-ui/src/app/catalog/providers/product-detail.service.ts
index 45508a37d3..32a987cfd3 100644
--- a/admin-ui/src/app/catalog/providers/product-detail.service.ts
+++ b/admin-ui/src/app/catalog/providers/product-detail.service.ts
@@ -1,11 +1,12 @@
import { Injectable } from '@angular/core';
-import { BehaviorSubject, forkJoin, Observable, of } from 'rxjs';
-import { map, mergeMap, shareReplay, skip } from 'rxjs/operators';
+import { BehaviorSubject, forkJoin, Observable, of, throwError } from 'rxjs';
+import { map, mergeMap, shareReplay, skip, switchMap } from 'rxjs/operators';
import { normalizeString } from 'shared/normalize-string';
import {
CreateProductInput,
CreateProductVariantInput,
+ DeletionResult,
FacetWithValues,
LanguageCode,
UpdateProductInput,
@@ -145,4 +146,16 @@ export class ProductDetailService {
updateProductOption(input: UpdateProductOptionInput) {
return this.dataService.product.updateProductOption(input);
}
+
+ deleteProductVariant(id: string, productId: string) {
+ return this.dataService.product.deleteProductVariant(id).pipe(
+ switchMap(result => {
+ if (result.deleteProductVariant.result === DeletionResult.DELETED) {
+ return this.dataService.product.getProduct(productId).single$;
+ } else {
+ return throwError(result.deleteProductVariant.message);
+ }
+ }),
+ );
+ }
}
diff --git a/admin-ui/src/app/common/generated-types.ts b/admin-ui/src/app/common/generated-types.ts
index 4293619352..a3ef6e1903 100644
--- a/admin-ui/src/app/common/generated-types.ts
+++ b/admin-ui/src/app/common/generated-types.ts
@@ -1553,32 +1553,18 @@ export type Mutation = {
assignRoleToAdministrator: Administrator,
/** Create a new Asset */
createAssets: Array,
- login: LoginResult,
- logout: Scalars['Boolean'],
- /** Create a new Channel */
- createChannel: Channel,
- /** Update an existing Channel */
- updateChannel: Channel,
/** Create a new Collection */
createCollection: Collection,
/** Update an existing Collection */
updateCollection: Collection,
/** Move a Collection to a different parent or index */
moveCollection: Collection,
- /** Create a new Country */
- createCountry: Country,
- /** Update an existing Country */
- updateCountry: Country,
- /** Delete a Country */
- deleteCountry: DeletionResponse,
- /** Create a new CustomerGroup */
- createCustomerGroup: CustomerGroup,
- /** Update an existing CustomerGroup */
- updateCustomerGroup: CustomerGroup,
- /** Add Customers to a CustomerGroup */
- addCustomersToGroup: CustomerGroup,
- /** Remove Customers from a CustomerGroup */
- removeCustomersFromGroup: CustomerGroup,
+ /** Create a new Channel */
+ createChannel: Channel,
+ /** Update an existing Channel */
+ updateChannel: Channel,
+ login: LoginResult,
+ logout: Scalars['Boolean'],
/** Create a new Customer. If a password is provided, a new User will also be created an linked to the Customer. */
createCustomer: Customer,
/** Update an existing Customer */
@@ -1591,6 +1577,12 @@ export type Mutation = {
updateCustomerAddress: Address,
/** Update an existing Address */
deleteCustomerAddress: Scalars['Boolean'],
+ /** Create a new Country */
+ createCountry: Country,
+ /** Update an existing Country */
+ updateCountry: Country,
+ /** Delete a Country */
+ deleteCountry: DeletionResponse,
/** Create a new Facet */
createFacet: Facet,
/** Update an existing Facet */
@@ -1603,14 +1595,16 @@ export type Mutation = {
updateFacetValues: Array,
/** Delete one or more FacetValues */
deleteFacetValues: Array,
- importProducts?: Maybe,
+ /** Create a new CustomerGroup */
+ createCustomerGroup: CustomerGroup,
+ /** Update an existing CustomerGroup */
+ updateCustomerGroup: CustomerGroup,
+ /** Add Customers to a CustomerGroup */
+ addCustomersToGroup: CustomerGroup,
+ /** Remove Customers from a CustomerGroup */
+ removeCustomersFromGroup: CustomerGroup,
updateGlobalSettings: GlobalSettings,
- settlePayment: Payment,
- fulfillOrder: Fulfillment,
- cancelOrder: Order,
- refundOrder: Refund,
- settleRefund: Refund,
- addNoteToOrder: Order,
+ importProducts?: Maybe,
/** Update an existing PaymentMethod */
updatePaymentMethod: PaymentMethod,
/** Create a new ProductOptionGroup */
@@ -1621,7 +1615,12 @@ export type Mutation = {
createProductOption: ProductOption,
/** Create a new ProductOption within a ProductOptionGroup */
updateProductOption: ProductOption,
- reindex: JobInfo,
+ settlePayment: Payment,
+ fulfillOrder: Fulfillment,
+ cancelOrder: Order,
+ refundOrder: Refund,
+ settleRefund: Refund,
+ addNoteToOrder: Order,
/** Create a new Product */
createProduct: Product,
/** Update an existing Product */
@@ -1641,22 +1640,23 @@ export type Mutation = {
createPromotion: Promotion,
updatePromotion: Promotion,
deletePromotion: DeletionResponse,
- /** Create a new Role */
- createRole: Role,
- /** Update an existing Role */
- updateRole: Role,
+ reindex: JobInfo,
/** Create a new ShippingMethod */
createShippingMethod: ShippingMethod,
/** Update an existing ShippingMethod */
updateShippingMethod: ShippingMethod,
- /** Create a new TaxCategory */
- createTaxCategory: TaxCategory,
- /** Update an existing TaxCategory */
- updateTaxCategory: TaxCategory,
/** Create a new TaxRate */
createTaxRate: TaxRate,
/** Update an existing TaxRate */
updateTaxRate: TaxRate,
+ /** Create a new Role */
+ createRole: Role,
+ /** Update an existing Role */
+ updateRole: Role,
+ /** Create a new TaxCategory */
+ createTaxCategory: TaxCategory,
+ /** Update an existing TaxCategory */
+ updateTaxCategory: TaxCategory,
/** Create a new Zone */
createZone: Zone,
/** Update an existing Zone */
@@ -1696,23 +1696,6 @@ export type MutationCreateAssetsArgs = {
};
-export type MutationLoginArgs = {
- username: Scalars['String'],
- password: Scalars['String'],
- rememberMe?: Maybe
-};
-
-
-export type MutationCreateChannelArgs = {
- input: CreateChannelInput
-};
-
-
-export type MutationUpdateChannelArgs = {
- input: UpdateChannelInput
-};
-
-
export type MutationCreateCollectionArgs = {
input: CreateCollectionInput
};
@@ -1728,40 +1711,20 @@ export type MutationMoveCollectionArgs = {
};
-export type MutationCreateCountryArgs = {
- input: CreateCountryInput
-};
-
-
-export type MutationUpdateCountryArgs = {
- input: UpdateCountryInput
-};
-
-
-export type MutationDeleteCountryArgs = {
- id: Scalars['ID']
-};
-
-
-export type MutationCreateCustomerGroupArgs = {
- input: CreateCustomerGroupInput
-};
-
-
-export type MutationUpdateCustomerGroupArgs = {
- input: UpdateCustomerGroupInput
+export type MutationCreateChannelArgs = {
+ input: CreateChannelInput
};
-export type MutationAddCustomersToGroupArgs = {
- customerGroupId: Scalars['ID'],
- customerIds: Array
+export type MutationUpdateChannelArgs = {
+ input: UpdateChannelInput
};
-export type MutationRemoveCustomersFromGroupArgs = {
- customerGroupId: Scalars['ID'],
- customerIds: Array
+export type MutationLoginArgs = {
+ username: Scalars['String'],
+ password: Scalars['String'],
+ rememberMe?: Maybe
};
@@ -1797,6 +1760,21 @@ export type MutationDeleteCustomerAddressArgs = {
};
+export type MutationCreateCountryArgs = {
+ input: CreateCountryInput
+};
+
+
+export type MutationUpdateCountryArgs = {
+ input: UpdateCountryInput
+};
+
+
+export type MutationDeleteCountryArgs = {
+ id: Scalars['ID']
+};
+
+
export type MutationCreateFacetArgs = {
input: CreateFacetInput
};
@@ -1829,43 +1807,35 @@ export type MutationDeleteFacetValuesArgs = {
};
-export type MutationImportProductsArgs = {
- csvFile: Scalars['Upload']
-};
-
-
-export type MutationUpdateGlobalSettingsArgs = {
- input: UpdateGlobalSettingsInput
-};
-
-
-export type MutationSettlePaymentArgs = {
- id: Scalars['ID']
+export type MutationCreateCustomerGroupArgs = {
+ input: CreateCustomerGroupInput
};
-export type MutationFulfillOrderArgs = {
- input: FulfillOrderInput
+export type MutationUpdateCustomerGroupArgs = {
+ input: UpdateCustomerGroupInput
};
-export type MutationCancelOrderArgs = {
- input: CancelOrderInput
+export type MutationAddCustomersToGroupArgs = {
+ customerGroupId: Scalars['ID'],
+ customerIds: Array
};
-export type MutationRefundOrderArgs = {
- input: RefundOrderInput
+export type MutationRemoveCustomersFromGroupArgs = {
+ customerGroupId: Scalars['ID'],
+ customerIds: Array
};
-export type MutationSettleRefundArgs = {
- input: SettleRefundInput
+export type MutationUpdateGlobalSettingsArgs = {
+ input: UpdateGlobalSettingsInput
};
-export type MutationAddNoteToOrderArgs = {
- input: AddNoteToOrderInput
+export type MutationImportProductsArgs = {
+ csvFile: Scalars['Upload']
};
@@ -1894,6 +1864,36 @@ export type MutationUpdateProductOptionArgs = {
};
+export type MutationSettlePaymentArgs = {
+ id: Scalars['ID']
+};
+
+
+export type MutationFulfillOrderArgs = {
+ input: FulfillOrderInput
+};
+
+
+export type MutationCancelOrderArgs = {
+ input: CancelOrderInput
+};
+
+
+export type MutationRefundOrderArgs = {
+ input: RefundOrderInput
+};
+
+
+export type MutationSettleRefundArgs = {
+ input: SettleRefundInput
+};
+
+
+export type MutationAddNoteToOrderArgs = {
+ input: AddNoteToOrderInput
+};
+
+
export type MutationCreateProductArgs = {
input: CreateProductInput
};
@@ -1951,43 +1951,43 @@ export type MutationDeletePromotionArgs = {
};
-export type MutationCreateRoleArgs = {
- input: CreateRoleInput
+export type MutationCreateShippingMethodArgs = {
+ input: CreateShippingMethodInput
};
-export type MutationUpdateRoleArgs = {
- input: UpdateRoleInput
+export type MutationUpdateShippingMethodArgs = {
+ input: UpdateShippingMethodInput
};
-export type MutationCreateShippingMethodArgs = {
- input: CreateShippingMethodInput
+export type MutationCreateTaxRateArgs = {
+ input: CreateTaxRateInput
};
-export type MutationUpdateShippingMethodArgs = {
- input: UpdateShippingMethodInput
+export type MutationUpdateTaxRateArgs = {
+ input: UpdateTaxRateInput
};
-export type MutationCreateTaxCategoryArgs = {
- input: CreateTaxCategoryInput
+export type MutationCreateRoleArgs = {
+ input: CreateRoleInput
};
-export type MutationUpdateTaxCategoryArgs = {
- input: UpdateTaxCategoryInput
+export type MutationUpdateRoleArgs = {
+ input: UpdateRoleInput
};
-export type MutationCreateTaxRateArgs = {
- input: CreateTaxRateInput
+export type MutationCreateTaxCategoryArgs = {
+ input: CreateTaxCategoryInput
};
-export type MutationUpdateTaxRateArgs = {
- input: UpdateTaxRateInput
+export type MutationUpdateTaxCategoryArgs = {
+ input: UpdateTaxCategoryInput
};
@@ -2533,47 +2533,47 @@ export type Query = {
administrator?: Maybe,
assets: AssetList,
asset?: Maybe,
- me?: Maybe,
- channels: Array,
- channel?: Maybe,
- activeChannel: Channel,
collections: CollectionList,
collection?: Maybe,
collectionFilters: Array,
- countries: CountryList,
- country?: Maybe,
- customerGroups: Array,
- customerGroup?: Maybe,
+ channels: Array,
+ channel?: Maybe,
+ activeChannel: Channel,
+ me?: Maybe,
customers: CustomerList,
customer?: Maybe,
+ countries: CountryList,
+ country?: Maybe,
facets: FacetList,
facet?: Maybe,
+ customerGroups: Array,
+ customerGroup?: Maybe,
globalSettings: GlobalSettings,
job?: Maybe,
jobs: Array,
- order?: Maybe,
- orders: OrderList,
paymentMethods: PaymentMethodList,
paymentMethod?: Maybe,
productOptionGroups: Array,
productOptionGroup?: Maybe,
- search: SearchResponse,
+ order?: Maybe,
+ orders: OrderList,
products: ProductList,
/** Get a Product either by id or slug. If neither id nor slug is speicified, an error will result. */
product?: Maybe,
promotion?: Maybe,
promotions: PromotionList,
adjustmentOperations: AdjustmentOperations,
- roles: RoleList,
- role?: Maybe,
+ search: SearchResponse,
shippingMethods: ShippingMethodList,
shippingMethod?: Maybe,
shippingEligibilityCheckers: Array,
shippingCalculators: Array,
- taxCategories: Array,
- taxCategory?: Maybe,
taxRates: TaxRateList,
taxRate?: Maybe,
+ roles: RoleList,
+ role?: Maybe,
+ taxCategories: Array,
+ taxCategory?: Maybe,
zones: Array,
zone?: Maybe,
networkStatus: NetworkStatus,
@@ -2602,11 +2602,6 @@ export type QueryAssetArgs = {
};
-export type QueryChannelArgs = {
- id: Scalars['ID']
-};
-
-
export type QueryCollectionsArgs = {
languageCode?: Maybe,
options?: Maybe
@@ -2619,27 +2614,27 @@ export type QueryCollectionArgs = {
};
-export type QueryCountriesArgs = {
- options?: Maybe
+export type QueryChannelArgs = {
+ id: Scalars['ID']
};
-export type QueryCountryArgs = {
- id: Scalars['ID']
+export type QueryCustomersArgs = {
+ options?: Maybe
};
-export type QueryCustomerGroupArgs = {
+export type QueryCustomerArgs = {
id: Scalars['ID']
};
-export type QueryCustomersArgs = {
- options?: Maybe
+export type QueryCountriesArgs = {
+ options?: Maybe
};
-export type QueryCustomerArgs = {
+export type QueryCountryArgs = {
id: Scalars['ID']
};
@@ -2656,6 +2651,11 @@ export type QueryFacetArgs = {
};
+export type QueryCustomerGroupArgs = {
+ id: Scalars['ID']
+};
+
+
export type QueryJobArgs = {
jobId: Scalars['String']
};
@@ -2666,16 +2666,6 @@ export type QueryJobsArgs = {
};
-export type QueryOrderArgs = {
- id: Scalars['ID']
-};
-
-
-export type QueryOrdersArgs = {
- options?: Maybe
-};
-
-
export type QueryPaymentMethodsArgs = {
options?: Maybe
};
@@ -2698,8 +2688,13 @@ export type QueryProductOptionGroupArgs = {
};
-export type QuerySearchArgs = {
- input: SearchInput
+export type QueryOrderArgs = {
+ id: Scalars['ID']
+};
+
+
+export type QueryOrdersArgs = {
+ options?: Maybe
};
@@ -2726,13 +2721,8 @@ export type QueryPromotionsArgs = {
};
-export type QueryRolesArgs = {
- options?: Maybe
-};
-
-
-export type QueryRoleArgs = {
- id: Scalars['ID']
+export type QuerySearchArgs = {
+ input: SearchInput
};
@@ -2746,17 +2736,27 @@ export type QueryShippingMethodArgs = {
};
-export type QueryTaxCategoryArgs = {
+export type QueryTaxRatesArgs = {
+ options?: Maybe
+};
+
+
+export type QueryTaxRateArgs = {
id: Scalars['ID']
};
-export type QueryTaxRatesArgs = {
- options?: Maybe
+export type QueryRolesArgs = {
+ options?: Maybe
};
-export type QueryTaxRateArgs = {
+export type QueryRoleArgs = {
+ id: Scalars['ID']
+};
+
+
+export type QueryTaxCategoryArgs = {
id: Scalars['ID']
};
@@ -3776,6 +3776,13 @@ export type UpdateProductOptionMutationVariables = {
export type UpdateProductOptionMutation = ({ __typename?: 'Mutation' } & { updateProductOption: ({ __typename?: 'ProductOption' } & Pick) });
+export type DeleteProductVariantMutationVariables = {
+ id: Scalars['ID']
+};
+
+
+export type DeleteProductVariantMutation = ({ __typename?: 'Mutation' } & { deleteProductVariant: ({ __typename?: 'DeletionResponse' } & Pick) });
+
export type ConfigurableOperationFragment = ({ __typename?: 'ConfigurableOperation' } & Pick & { args: Array<({ __typename?: 'ConfigArg' } & Pick)> });
export type PromotionFragment = ({ __typename?: 'Promotion' } & Pick & { conditions: Array<({ __typename?: 'ConfigurableOperation' } & ConfigurableOperationFragment)>, actions: Array<({ __typename?: 'ConfigurableOperation' } & ConfigurableOperationFragment)> });
@@ -4623,6 +4630,12 @@ export namespace UpdateProductOption {
export type UpdateProductOption = UpdateProductOptionMutation['updateProductOption'];
}
+export namespace DeleteProductVariant {
+ export type Variables = DeleteProductVariantMutationVariables;
+ export type Mutation = DeleteProductVariantMutation;
+ export type DeleteProductVariant = DeleteProductVariantMutation['deleteProductVariant'];
+}
+
export namespace ConfigurableOperation {
export type Fragment = ConfigurableOperationFragment;
export type Args = (NonNullable);
diff --git a/admin-ui/src/app/data/definitions/product-definitions.ts b/admin-ui/src/app/data/definitions/product-definitions.ts
index 2fc08b8ba4..8174229709 100644
--- a/admin-ui/src/app/data/definitions/product-definitions.ts
+++ b/admin-ui/src/app/data/definitions/product-definitions.ts
@@ -325,3 +325,12 @@ export const UPDATE_PRODUCT_OPTION = gql`
}
}
`;
+
+export const DELETE_PRODUCT_VARIANT = gql`
+ mutation DeleteProductVariant($id: ID!) {
+ deleteProductVariant(id: $id) {
+ result
+ message
+ }
+ }
+`;
diff --git a/admin-ui/src/app/data/providers/product-data.service.ts b/admin-ui/src/app/data/providers/product-data.service.ts
index b147f1dd75..ed199cf247 100644
--- a/admin-ui/src/app/data/providers/product-data.service.ts
+++ b/admin-ui/src/app/data/providers/product-data.service.ts
@@ -10,6 +10,7 @@ import {
CreateProductVariantInput,
CreateProductVariants,
DeleteProduct,
+ DeleteProductVariant,
GetAssetList,
GetProductList,
GetProductOptionGroups,
@@ -33,6 +34,7 @@ import {
CREATE_PRODUCT_OPTION_GROUP,
CREATE_PRODUCT_VARIANTS,
DELETE_PRODUCT,
+ DELETE_PRODUCT_VARIANT,
GET_ASSET_LIST,
GET_PRODUCT_LIST,
GET_PRODUCT_OPTION_GROUPS,
@@ -158,6 +160,15 @@ export class ProductDataService {
);
}
+ deleteProductVariant(id: string) {
+ return this.baseDataService.mutate(
+ DELETE_PRODUCT_VARIANT,
+ {
+ id,
+ },
+ );
+ }
+
createProductOptionGroups(productOptionGroup: CreateProductOptionGroupInput) {
const input: CreateProductOptionGroup.Variables = {
input: productOptionGroup,
diff --git a/admin-ui/src/i18n-messages/en.json b/admin-ui/src/i18n-messages/en.json
index c100378429..4b4b8fc943 100644
--- a/admin-ui/src/i18n-messages/en.json
+++ b/admin-ui/src/i18n-messages/en.json
@@ -33,6 +33,7 @@
"confirm-delete-facet": "Delete facet?",
"confirm-delete-facet-value": "Delete facet value?",
"confirm-delete-product": "Delete product?",
+ "confirm-delete-product-variant": "Delete product variant?",
"create-new-collection": "Create new collection",
"create-new-facet": "Create new facet",
"create-new-product": "New product",