diff --git a/packages/admin-ui/src/lib/catalog/src/components/product-detail/product-detail.component.ts b/packages/admin-ui/src/lib/catalog/src/components/product-detail/product-detail.component.ts index 3242769378..bd26011da6 100644 --- a/packages/admin-ui/src/lib/catalog/src/components/product-detail/product-detail.component.ts +++ b/packages/admin-ui/src/lib/catalog/src/components/product-detail/product-detail.component.ts @@ -23,7 +23,6 @@ import { unicodePatternValidator, UpdateProductInput, UpdateProductMutation, - UpdateProductOptionInput, UpdateProductVariantInput, UpdateProductVariantsMutation, } from '@vendure/admin-ui/core'; @@ -256,28 +255,6 @@ export class ProductDetailComponent }); } - updateProductOption(input: UpdateProductOptionInput & { autoUpdate: boolean }) { - combineLatest(this.entity$, this.languageCode$) - .pipe( - take(1), - mergeMap(([product, languageCode]) => - this.productDetailService.updateProductOption(input, product, languageCode), - ), - ) - .subscribe( - () => { - this.notificationService.success(_('common.notify-update-success'), { - entity: 'ProductOption', - }); - }, - err => { - this.notificationService.error(_('common.notify-update-error'), { - entity: 'ProductOption', - }); - }, - ); - } - removeProductFacetValue(facetValueId: string) { const productGroup = this.detailForm; const currentFacetValueIds = productGroup.value.facetValueIds ?? []; diff --git a/packages/admin-ui/src/lib/catalog/src/components/product-options-editor/product-options-editor.component.ts b/packages/admin-ui/src/lib/catalog/src/components/product-options-editor/product-options-editor.component.ts index 51832bc0de..27c45a9cf7 100644 --- a/packages/admin-ui/src/lib/catalog/src/components/product-options-editor/product-options-editor.component.ts +++ b/packages/admin-ui/src/lib/catalog/src/components/product-options-editor/product-options-editor.component.ts @@ -99,6 +99,7 @@ export class ProductOptionsEditorComponent extends BaseDetailComponent { const updateOperations: Array> = []; + const updatedProductOptionInputs: UpdateProductOptionInput[] = []; for (const optionGroupForm of this.getOptionGroups()) { if (optionGroupForm.dirty) { const optionGroupEntity = optionGroups.find( @@ -127,17 +128,21 @@ export class ProductOptionsEditorComponent extends BaseDetailComponent, languageCode: LanguageCode, ) { - const variants$ = input.autoUpdate + const variants$ = autoUpdateProductNames ? this.dataService.product .getProductVariantsForProduct({}, product.id) .mapSingle(({ productVariants }) => productVariants.items) @@ -237,44 +238,67 @@ export class ProductDetailService { return variants$.pipe( mergeMap(variants => { let updateProductVariantNames$: Observable = of([]); - if (input.autoUpdate) { - // Update any ProductVariants' names which include the option name - let oldOptionName: string | undefined; - const newOptionName = findTranslation(input, languageCode)?.name; - if (!newOptionName) { - updateProductVariantNames$ = of([]); + if (autoUpdateProductNames) { + const replacementMap = new Map(); + + for (const input of inputs) { + const newOptionName = findTranslation(input, languageCode)?.name; + let oldOptionName: string | undefined; + for (const variant of variants) { + if (oldOptionName) { + continue; + } + if (variant.options.map(o => o.id).includes(input.id)) { + if (!oldOptionName) { + oldOptionName = findTranslation( + variant.options.find(o => o.id === input.id), + languageCode, + )?.name; + } + } + } + if (oldOptionName && newOptionName) { + replacementMap.set(oldOptionName, newOptionName); + } } + const variantsToUpdate: UpdateProductVariantInput[] = []; - for (const variant of variants) { - if (variant.options.map(o => o.id).includes(input.id)) { - if (!oldOptionName) { - oldOptionName = findTranslation( - variant.options.find(o => o.id === input.id), - languageCode, - )?.name; + if (replacementMap.size) { + const oldOptionNames = Array.from(replacementMap.keys()); + for (const variant of variants) { + const variantName = findTranslation(variant, languageCode)?.name; + if (!variantName) { + continue; } - const variantName = findTranslation(variant, languageCode)?.name || ''; - if (oldOptionName && newOptionName && variantName.includes(oldOptionName)) { - variantsToUpdate.push({ - id: variant.id, - translations: [ - { - languageCode, - name: replaceLast(variantName, oldOptionName, newOptionName), - }, - ], - }); + if (!oldOptionNames.some(oldOptionName => variantName.includes(oldOptionName))) { + continue; } + const updatedVariantName = oldOptionNames.reduce( + (name, oldOptionName) => + replaceLast(name, oldOptionName, replacementMap.get(oldOptionName)!), + variantName, + ); + variantsToUpdate.push({ + id: variant.id, + translations: [ + { + languageCode, + name: updatedVariantName, + }, + ], + }); } } if (variantsToUpdate.length) { updateProductVariantNames$ = this.dataService.product.updateProductVariants(variantsToUpdate); + } else { + updateProductVariantNames$ = of([]); } } - return this.dataService.product - .updateProductOption(input) - .pipe(mergeMap(() => updateProductVariantNames$)); + return forkJoin( + inputs.map(input => this.dataService.product.updateProductOption(input)), + ).pipe(mergeMap(() => updateProductVariantNames$)); }), ); }