diff --git a/packages/admin-ui/src/lib/catalog/src/components/product-options-editor/product-options-editor.component.html b/packages/admin-ui/src/lib/catalog/src/components/product-options-editor/product-options-editor.component.html index 3143baed8e..fe1d49515b 100644 --- a/packages/admin-ui/src/lib/catalog/src/components/product-options-editor/product-options-editor.component.html +++ b/packages/admin-ui/src/lib/catalog/src/components/product-options-editor/product-options-editor.component.html @@ -56,6 +56,15 @@ formControlName="code" /> +
+ + +
@@ -64,6 +73,9 @@ + + + @@ -83,6 +95,15 @@ /> +
{{ 'common.name' | translate }} {{ 'common.code' | translate }}{{ 'common.custom-fields' | translate }}
+ +
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 eb982e2b3c..d98245a0a7 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 @@ -1,14 +1,12 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core'; -import { FormArray, FormBuilder, FormControl, FormGroup } from '@angular/forms'; +import { FormArray, FormBuilder, FormGroup } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { BaseDetailComponent, - CreateFacetInput, createUpdatedTranslatable, CustomFieldConfig, DataService, - FacetWithValues, findTranslation, GetProductVariantOptions, LanguageCode, @@ -17,7 +15,7 @@ import { ProductOption, ProductOptionGroup, ServerConfigService, - UpdateFacetInput, + TranslationOf, UpdateProductOptionGroupInput, UpdateProductOptionInput, } from '@vendure/admin-ui/core'; @@ -92,7 +90,7 @@ export class ProductOptionsEditorComponent mergeMap(([{ optionGroups }, languageCode, product]) => { const updateOperations: Array> = []; for (const optionGroupForm of this.getOptionGroups()) { - if (optionGroupForm.get('name')?.dirty || optionGroupForm.get('code')?.dirty) { + if (optionGroupForm.dirty) { const optionGroupEntity = optionGroups.find( og => og.id === optionGroupForm.value.id, ); @@ -109,7 +107,7 @@ export class ProductOptionsEditorComponent } for (const optionForm of this.getOptions(optionGroupForm)) { - if (optionForm.get('name')?.dirty || optionForm.get('code')?.dirty) { + if (optionForm.dirty) { const optionGroup = optionGroups .find(og => og.id === optionGroupForm.value.id) ?.options.find(o => o.id === optionForm.value.id); @@ -175,7 +173,7 @@ export class ProductOptionsEditorComponent const input = createUpdatedTranslatable({ translatable: option, updatedFields: optionFormGroup.value, - customFieldConfig: this.optionGroupCustomFields, + customFieldConfig: this.optionCustomFields, languageCode, defaultTranslation: { languageCode, @@ -186,34 +184,100 @@ export class ProductOptionsEditorComponent } protected setFormValues(entity: GetProductVariantOptions.Product, languageCode: LanguageCode): void { - const groupsFormArray = new FormArray([]); + const groupsForm = this.detailForm.get('optionGroups') as FormArray; for (const optionGroup of entity.optionGroups) { const groupTranslation = findTranslation(optionGroup, languageCode); - const group = { - id: optionGroup.id, - createdAt: optionGroup.createdAt, - updatedAt: optionGroup.updatedAt, - code: optionGroup.code, - name: groupTranslation ? groupTranslation.name : '', - }; - const optionsFormArray = new FormArray([]); + const groupForm = this.setOptionGroupForm(optionGroup, groupsForm, groupTranslation); + this.setCustomFieldsForm(this.optionGroupCustomFields, groupForm, optionGroup, groupTranslation); + + let optionsForm = groupForm.get('options') as FormArray; + if (!optionsForm) { + optionsForm = this.formBuilder.array([]); + groupForm.addControl('options', optionsForm); + } for (const option of optionGroup.options) { const optionTranslation = findTranslation(option, languageCode); - const optionControl = this.formBuilder.group({ - id: option.id, - createdAt: option.createdAt, - updatedAt: option.updatedAt, - code: option.code, - name: optionTranslation ? optionTranslation.name : '', - }); - optionsFormArray.push(optionControl); + const optionForm = this.setOptionForm(option, optionsForm, optionTranslation); + + this.setCustomFieldsForm(this.optionCustomFields, optionForm, option, optionTranslation); + } + } + } + + protected setCustomFieldsForm< + T extends GetProductVariantOptions.OptionGroups | GetProductVariantOptions.Options, + >( + customFields: CustomFieldConfig[], + formGroup: FormGroup, + entity: T, + currentTranslation?: TranslationOf, + ) { + if (customFields.length) { + let customValueFieldsGroup = formGroup.get(['customFields']); + if (!customValueFieldsGroup) { + customValueFieldsGroup = this.formBuilder.group( + customFields.reduce((hash, field) => ({ ...hash, [field.name]: '' }), {}), + ); + formGroup.addControl('customFields', customValueFieldsGroup); } + this.setCustomFieldFormValues(customFields, customValueFieldsGroup, entity, currentTranslation); + } + } + + protected setOptionGroupForm( + entity: GetProductVariantOptions.OptionGroups, + groupsForm: FormArray, + currentTranslation?: TranslationOf, + ) { + const group = { + id: entity.id, + createdAt: entity.createdAt, + updatedAt: entity.updatedAt, + code: entity.code, + name: currentTranslation?.name ?? '', + }; + let groupForm = groupsForm.controls.find(control => control.value.id === entity.id) as + | FormGroup + | undefined; + if (groupForm) { + groupForm.get('id')?.setValue(group.id); + groupForm.get('code')?.setValue(group.code); + groupForm.get('name')?.setValue(group.name); + groupForm.get('createdAt')?.setValue(group.name); + groupForm.get('updatedAt')?.setValue(group.name); + } else { + groupForm = this.formBuilder.group(group); + groupsForm.push(groupForm); + } + return groupForm; + } - const groupControl = this.formBuilder.group(group); - groupControl.addControl('options', optionsFormArray); - groupsFormArray.push(groupControl); + protected setOptionForm( + entity: GetProductVariantOptions.Options, + optionsForm: FormArray, + currentTranslation?: TranslationOf, + ) { + const group = { + id: entity.id, + createdAt: entity.createdAt, + updatedAt: entity.updatedAt, + code: entity.code, + name: currentTranslation?.name ?? '', + }; + let optionForm = optionsForm.controls.find(control => control.value.id === entity.id) as + | FormGroup + | undefined; + if (optionForm) { + optionForm.get('id')?.setValue(group.id); + optionForm.get('code')?.setValue(group.code); + optionForm.get('name')?.setValue(group.name); + optionForm.get('createdAt')?.setValue(group.name); + optionForm.get('updatedAt')?.setValue(group.name); + } else { + optionForm = this.formBuilder.group(group); + optionsForm.push(optionForm); } - this.detailForm.setControl('optionGroups', groupsFormArray); + return optionForm; } }