Loading src/app/app-products.module.ts +2 −1 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ import { EditProductOfferingsComponent } from './p_product/admin/productCatalogM import { PreviewMarketPlaceItemComponent } from './p_product/marketplace/preview-market-place-item/preview-market-place-item.component'; import { AssignProductOfferingsComponent } from './p_product/admin/productCatalogManagement/edit-product-categories/assign-product-offerings/assign-product-offerings.component'; import { AssignSubcategoriesComponent } from './p_product/admin/productCatalogManagement/edit-product-categories/assign-subcategories/assign-subcategories.component'; import { ConfirmCharacteristicAssignmentComponent } from './p_product/admin/productCatalogManagement/edit-product-specs/assign-service-specification/confirm-characteristic-assignment/confirm-characteristic-assignment.component'; @NgModule({ Loading @@ -42,6 +42,7 @@ import { AssignSubcategoriesComponent } from './p_product/admin/productCatalogMa DeleteProductCategoriesComponent, DeleteProductSpecsComponent, AssignServiceSpecificationComponent, ConfirmCharacteristicAssignmentComponent, ListProductOfferingsComponent, DeleteProductOfferingComponent, EditProductOfferingsComponent, Loading src/app/p_product/admin/productCatalogManagement/edit-product-specs/assign-service-specification/assign-service-specification.component.ts +104 −12 Original line number Diff line number Diff line import { Component, OnInit, Inject, ViewChild, ElementRef } from '@angular/core'; import { UntypedFormControl } from '@angular/forms'; import { MatAutocomplete, MatAutocompleteSelectedEvent, MatAutocompleteTrigger } from '@angular/material/autocomplete'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { ToastrService } from 'ngx-toastr'; import { Observable } from 'rxjs'; import { map, startWith } from 'rxjs/operators' import { ProductSpecification, ProductSpecificationUpdate } from 'src/app/openApis/productCatalogManagement/models'; import { ProductSpecificationService } from 'src/app/openApis/productCatalogManagement/services'; import { ServiceSpecification } from 'src/app/openApis/serviceCatalogManagement/models'; import { ServiceSpecificationService } from 'src/app/openApis/serviceCatalogManagement/services'; import { ConfirmCharacteristicAssignmentComponent } from './confirm-characteristic-assignment/confirm-characteristic-assignment.component'; @Component({ selector: 'app-assign-service-specification', Loading @@ -24,7 +27,10 @@ export class AssignServiceSpecificationComponent implements OnInit { }, private dialogRef: MatDialogRef<AssignServiceSpecificationComponent>, private productSpecService: ProductSpecificationService, private serviceSpecService: ServiceSpecificationService private serviceSpecService: ServiceSpecificationService, private toast: ToastrService, private dialog: MatDialog ) { } @ViewChild('specInput') specInput: ElementRef<HTMLInputElement>; Loading @@ -51,6 +57,8 @@ export class AssignServiceSpecificationComponent implements OnInit { data => this.nonSelectedSpecs = data, error => console.error(error), () => { //remove self from available spec list as well as the allready assigned specs const initiallyAssignedSpecIDs: string[] = this.data.productSpec.serviceSpecification.map(el => el.id) this.nonSelectedSpecs = this.nonSelectedSpecs.filter(spec => !initiallyAssignedSpecIDs.includes(spec.id)) Loading @@ -68,13 +76,26 @@ export class AssignServiceSpecificationComponent implements OnInit { } selected(event: MatAutocompleteSelectedEvent): void { this.selectedSpecs.push(event.option.value); this.dataSource.data = this.selectedSpecs this.nonSelectedSpecs = this.nonSelectedSpecs.filter(el => el.name != event.option.value.name) const selectedLiteSpec = event.option.value; //retrieve full service specs details, @type and spec characteristics once a service spec is selected this.specInput.nativeElement.value = ''; this.specInputCtrl.setValue(null); this.serviceSpecService.retrieveServiceSpecification({ id: selectedLiteSpec.id }).subscribe( (fullSpec: ServiceSpecification) => { this.selectedSpecs.push(fullSpec); this.dataSource.data = this.selectedSpecs; this.nonSelectedSpecs = this.nonSelectedSpecs.filter( el => el.name != selectedLiteSpec.name ); }, (error) => { this.toast.error('Failed to fetch full service specification details', error); } ); } private _filter(value: string): ProductSpecification[] { Loading Loading @@ -103,16 +124,87 @@ export class AssignServiceSpecificationComponent implements OnInit { confirmAssignment() { const updateRelationshipsObj: ProductSpecificationUpdate = { serviceSpecification: this.selectedSpecs.map(spec =>{ return {id: spec.id, name: spec.name}}) const hasConfigurableCFSS = this.selectedSpecs.some(spec => { const s = spec as any; const type = s['@type'] || 'ServiceSpecification'; const chars = s.serviceSpecCharacteristic || []; const hasConfigurable = chars.some(c => c.configurable === true); return type === 'CustomerFacingServiceSpecification' && hasConfigurable; }); if (hasConfigurableCFSS) { // Open the dialog to ask the user const dialogRef = this.dialog.open(ConfirmCharacteristicAssignmentComponent, { width: '600px', disableClose: true }); dialogRef.afterClosed().subscribe(result => { // result === true (Yes), result === false (No), result === undefined (Cancel) if (result === true) { this.executeAssignment(true); } else if (result === false) { this.executeAssignment(false); } }); } else { this.executeAssignment(false); } } executeAssignment(importCharacteristics: boolean) { const serviceRefs: any[] = []; const newProductCharacteristics: any[] = []; this.selectedSpecs.forEach(spec => { const sourceSpec = spec as any; const type = sourceSpec['@type'] || 'ServiceSpecification'; serviceRefs.push({ id: sourceSpec.id, name: sourceSpec.name, '@type': type }); if (importCharacteristics && type === 'CustomerFacingServiceSpecification') { const serviceChars = sourceSpec.serviceSpecCharacteristic || []; const configurableChars = serviceChars.filter(char => char.configurable === true); const mappedChars = configurableChars.map(char => ({ name: char.name, description: char.description, valueType: char.valueType, configurable: char.configurable, minCardinality: char.minCardinality, maxCardinality: char.maxCardinality, productSpecCharacteristicValue: char.serviceSpecCharacteristicValue, '@type': 'ProductSpecCharacteristic' })); newProductCharacteristics.push(...mappedChars); } }); const existingChars = this.data.productSpec.productSpecCharacteristic || []; const finalCharacteristics = [...existingChars, ...newProductCharacteristics]; this.productSpecService.patchProductSpecification({id: this.data.productSpec.id, productSpecification: updateRelationshipsObj}).subscribe( const updateRelationshipsObj: ProductSpecificationUpdate = { serviceSpecification: serviceRefs, productSpecCharacteristic: finalCharacteristics }; // console.log(updateRelationshipsObj); this.productSpecService.patchProductSpecification({ id: this.data.productSpec.id, productSpecification: updateRelationshipsObj }).subscribe( data => {}, error => console.error(error), error => this.toast.error('Failed to update Product Specification', error), () => {this.dialogRef.close('updated')} ) } } src/app/p_product/admin/productCatalogManagement/edit-product-specs/assign-service-specification/confirm-characteristic-assignment/confirm-characteristic-assignment.component.html 0 → 100644 +14 −0 Original line number Diff line number Diff line <h2 mat-dialog-title>Import Characteristics?</h2> <mat-dialog-content class="mat-typography"> <p> The selected <b>CustomerFacingServiceSpecification</b>(s) contain configurable characteristics. </p> <p> Do you want to automatically add these as <b>Product Characteristics</b> to the Product Specification? </p> </mat-dialog-content> <mat-dialog-actions align="end"> <button (click)="onCancel()" class="btn btn-danger">Cancel</button> <button (click)="onNo()" class="btn btn-primary ml-2">No, just link Service Specification</button> <button (click)="onYes()" class="btn btn-success mt-2">Yes, Import Characteristics</button> </mat-dialog-actions> No newline at end of file src/app/p_product/admin/productCatalogManagement/edit-product-specs/assign-service-specification/confirm-characteristic-assignment/confirm-characteristic-assignment.component.ts 0 → 100644 +26 −0 Original line number Diff line number Diff line import { Component } from '@angular/core'; import { MatDialogRef } from '@angular/material/dialog'; @Component({ selector: 'app-confirm-characteristic-assignment', templateUrl: './confirm-characteristic-assignment.component.html', styles: [] }) export class ConfirmCharacteristicAssignmentComponent { constructor( public dialogRef: MatDialogRef<ConfirmCharacteristicAssignmentComponent> ) {} onCancel(): void { this.dialogRef.close(); // Returns undefined } onNo(): void { this.dialogRef.close(false); // Returns false } onYes(): void { this.dialogRef.close(true); // Returns true } } No newline at end of file src/app/p_product/admin/productCatalogManagement/edit-product-specs/edit-product-spec-characteristics/edit-product-spec-characteristics.component.ts +11 −5 Original line number Diff line number Diff line Loading @@ -184,22 +184,28 @@ export class EditProductSpecCharacteristicsComponent implements OnInit { submitDialog() { if (this.newSpec) { this.data.productSpec.productSpecCharacteristic.push(this.editFormCharacteristic.getRawValue()) } else { const updateCharacteristIndex = this.data.productSpec.productSpecCharacteristic.findIndex(char => char.uuid === this.data.specToBeUpdated.uuid) this.data.productSpec.productSpecCharacteristic[updateCharacteristIndex] = this.editFormCharacteristic.getRawValue() } console.log(this.newSpec); console.log(this.data.productSpec); const updateCharacteristicObj: ProductSpecificationUpdate = { productSpecCharacteristic: this.data.productSpec.productSpecCharacteristic } this.specService.patchProductSpecification({ id: this.data.productSpec.id, productSpecification: updateCharacteristicObj }).subscribe( data => { }, error => { console.error(error); this.toast.error("An error occurred upon updating Spec Characteristics") }, () => { this.dialogRef.close('updated') } ) console.log(updateCharacteristicObj); // this.specService.patchProductSpecification({ id: this.data.productSpec.id, productSpecification: updateCharacteristicObj }).subscribe( // data => { }, // error => { console.error(error); this.toast.error("An error occurred upon updating Spec Characteristics") }, // () => { this.dialogRef.close('updated') } // ) } ngOnDestroy(): void { Loading Loading
src/app/app-products.module.ts +2 −1 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ import { EditProductOfferingsComponent } from './p_product/admin/productCatalogM import { PreviewMarketPlaceItemComponent } from './p_product/marketplace/preview-market-place-item/preview-market-place-item.component'; import { AssignProductOfferingsComponent } from './p_product/admin/productCatalogManagement/edit-product-categories/assign-product-offerings/assign-product-offerings.component'; import { AssignSubcategoriesComponent } from './p_product/admin/productCatalogManagement/edit-product-categories/assign-subcategories/assign-subcategories.component'; import { ConfirmCharacteristicAssignmentComponent } from './p_product/admin/productCatalogManagement/edit-product-specs/assign-service-specification/confirm-characteristic-assignment/confirm-characteristic-assignment.component'; @NgModule({ Loading @@ -42,6 +42,7 @@ import { AssignSubcategoriesComponent } from './p_product/admin/productCatalogMa DeleteProductCategoriesComponent, DeleteProductSpecsComponent, AssignServiceSpecificationComponent, ConfirmCharacteristicAssignmentComponent, ListProductOfferingsComponent, DeleteProductOfferingComponent, EditProductOfferingsComponent, Loading
src/app/p_product/admin/productCatalogManagement/edit-product-specs/assign-service-specification/assign-service-specification.component.ts +104 −12 Original line number Diff line number Diff line import { Component, OnInit, Inject, ViewChild, ElementRef } from '@angular/core'; import { UntypedFormControl } from '@angular/forms'; import { MatAutocomplete, MatAutocompleteSelectedEvent, MatAutocompleteTrigger } from '@angular/material/autocomplete'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { ToastrService } from 'ngx-toastr'; import { Observable } from 'rxjs'; import { map, startWith } from 'rxjs/operators' import { ProductSpecification, ProductSpecificationUpdate } from 'src/app/openApis/productCatalogManagement/models'; import { ProductSpecificationService } from 'src/app/openApis/productCatalogManagement/services'; import { ServiceSpecification } from 'src/app/openApis/serviceCatalogManagement/models'; import { ServiceSpecificationService } from 'src/app/openApis/serviceCatalogManagement/services'; import { ConfirmCharacteristicAssignmentComponent } from './confirm-characteristic-assignment/confirm-characteristic-assignment.component'; @Component({ selector: 'app-assign-service-specification', Loading @@ -24,7 +27,10 @@ export class AssignServiceSpecificationComponent implements OnInit { }, private dialogRef: MatDialogRef<AssignServiceSpecificationComponent>, private productSpecService: ProductSpecificationService, private serviceSpecService: ServiceSpecificationService private serviceSpecService: ServiceSpecificationService, private toast: ToastrService, private dialog: MatDialog ) { } @ViewChild('specInput') specInput: ElementRef<HTMLInputElement>; Loading @@ -51,6 +57,8 @@ export class AssignServiceSpecificationComponent implements OnInit { data => this.nonSelectedSpecs = data, error => console.error(error), () => { //remove self from available spec list as well as the allready assigned specs const initiallyAssignedSpecIDs: string[] = this.data.productSpec.serviceSpecification.map(el => el.id) this.nonSelectedSpecs = this.nonSelectedSpecs.filter(spec => !initiallyAssignedSpecIDs.includes(spec.id)) Loading @@ -68,13 +76,26 @@ export class AssignServiceSpecificationComponent implements OnInit { } selected(event: MatAutocompleteSelectedEvent): void { this.selectedSpecs.push(event.option.value); this.dataSource.data = this.selectedSpecs this.nonSelectedSpecs = this.nonSelectedSpecs.filter(el => el.name != event.option.value.name) const selectedLiteSpec = event.option.value; //retrieve full service specs details, @type and spec characteristics once a service spec is selected this.specInput.nativeElement.value = ''; this.specInputCtrl.setValue(null); this.serviceSpecService.retrieveServiceSpecification({ id: selectedLiteSpec.id }).subscribe( (fullSpec: ServiceSpecification) => { this.selectedSpecs.push(fullSpec); this.dataSource.data = this.selectedSpecs; this.nonSelectedSpecs = this.nonSelectedSpecs.filter( el => el.name != selectedLiteSpec.name ); }, (error) => { this.toast.error('Failed to fetch full service specification details', error); } ); } private _filter(value: string): ProductSpecification[] { Loading Loading @@ -103,16 +124,87 @@ export class AssignServiceSpecificationComponent implements OnInit { confirmAssignment() { const updateRelationshipsObj: ProductSpecificationUpdate = { serviceSpecification: this.selectedSpecs.map(spec =>{ return {id: spec.id, name: spec.name}}) const hasConfigurableCFSS = this.selectedSpecs.some(spec => { const s = spec as any; const type = s['@type'] || 'ServiceSpecification'; const chars = s.serviceSpecCharacteristic || []; const hasConfigurable = chars.some(c => c.configurable === true); return type === 'CustomerFacingServiceSpecification' && hasConfigurable; }); if (hasConfigurableCFSS) { // Open the dialog to ask the user const dialogRef = this.dialog.open(ConfirmCharacteristicAssignmentComponent, { width: '600px', disableClose: true }); dialogRef.afterClosed().subscribe(result => { // result === true (Yes), result === false (No), result === undefined (Cancel) if (result === true) { this.executeAssignment(true); } else if (result === false) { this.executeAssignment(false); } }); } else { this.executeAssignment(false); } } executeAssignment(importCharacteristics: boolean) { const serviceRefs: any[] = []; const newProductCharacteristics: any[] = []; this.selectedSpecs.forEach(spec => { const sourceSpec = spec as any; const type = sourceSpec['@type'] || 'ServiceSpecification'; serviceRefs.push({ id: sourceSpec.id, name: sourceSpec.name, '@type': type }); if (importCharacteristics && type === 'CustomerFacingServiceSpecification') { const serviceChars = sourceSpec.serviceSpecCharacteristic || []; const configurableChars = serviceChars.filter(char => char.configurable === true); const mappedChars = configurableChars.map(char => ({ name: char.name, description: char.description, valueType: char.valueType, configurable: char.configurable, minCardinality: char.minCardinality, maxCardinality: char.maxCardinality, productSpecCharacteristicValue: char.serviceSpecCharacteristicValue, '@type': 'ProductSpecCharacteristic' })); newProductCharacteristics.push(...mappedChars); } }); const existingChars = this.data.productSpec.productSpecCharacteristic || []; const finalCharacteristics = [...existingChars, ...newProductCharacteristics]; this.productSpecService.patchProductSpecification({id: this.data.productSpec.id, productSpecification: updateRelationshipsObj}).subscribe( const updateRelationshipsObj: ProductSpecificationUpdate = { serviceSpecification: serviceRefs, productSpecCharacteristic: finalCharacteristics }; // console.log(updateRelationshipsObj); this.productSpecService.patchProductSpecification({ id: this.data.productSpec.id, productSpecification: updateRelationshipsObj }).subscribe( data => {}, error => console.error(error), error => this.toast.error('Failed to update Product Specification', error), () => {this.dialogRef.close('updated')} ) } }
src/app/p_product/admin/productCatalogManagement/edit-product-specs/assign-service-specification/confirm-characteristic-assignment/confirm-characteristic-assignment.component.html 0 → 100644 +14 −0 Original line number Diff line number Diff line <h2 mat-dialog-title>Import Characteristics?</h2> <mat-dialog-content class="mat-typography"> <p> The selected <b>CustomerFacingServiceSpecification</b>(s) contain configurable characteristics. </p> <p> Do you want to automatically add these as <b>Product Characteristics</b> to the Product Specification? </p> </mat-dialog-content> <mat-dialog-actions align="end"> <button (click)="onCancel()" class="btn btn-danger">Cancel</button> <button (click)="onNo()" class="btn btn-primary ml-2">No, just link Service Specification</button> <button (click)="onYes()" class="btn btn-success mt-2">Yes, Import Characteristics</button> </mat-dialog-actions> No newline at end of file
src/app/p_product/admin/productCatalogManagement/edit-product-specs/assign-service-specification/confirm-characteristic-assignment/confirm-characteristic-assignment.component.ts 0 → 100644 +26 −0 Original line number Diff line number Diff line import { Component } from '@angular/core'; import { MatDialogRef } from '@angular/material/dialog'; @Component({ selector: 'app-confirm-characteristic-assignment', templateUrl: './confirm-characteristic-assignment.component.html', styles: [] }) export class ConfirmCharacteristicAssignmentComponent { constructor( public dialogRef: MatDialogRef<ConfirmCharacteristicAssignmentComponent> ) {} onCancel(): void { this.dialogRef.close(); // Returns undefined } onNo(): void { this.dialogRef.close(false); // Returns false } onYes(): void { this.dialogRef.close(true); // Returns true } } No newline at end of file
src/app/p_product/admin/productCatalogManagement/edit-product-specs/edit-product-spec-characteristics/edit-product-spec-characteristics.component.ts +11 −5 Original line number Diff line number Diff line Loading @@ -184,22 +184,28 @@ export class EditProductSpecCharacteristicsComponent implements OnInit { submitDialog() { if (this.newSpec) { this.data.productSpec.productSpecCharacteristic.push(this.editFormCharacteristic.getRawValue()) } else { const updateCharacteristIndex = this.data.productSpec.productSpecCharacteristic.findIndex(char => char.uuid === this.data.specToBeUpdated.uuid) this.data.productSpec.productSpecCharacteristic[updateCharacteristIndex] = this.editFormCharacteristic.getRawValue() } console.log(this.newSpec); console.log(this.data.productSpec); const updateCharacteristicObj: ProductSpecificationUpdate = { productSpecCharacteristic: this.data.productSpec.productSpecCharacteristic } this.specService.patchProductSpecification({ id: this.data.productSpec.id, productSpecification: updateCharacteristicObj }).subscribe( data => { }, error => { console.error(error); this.toast.error("An error occurred upon updating Spec Characteristics") }, () => { this.dialogRef.close('updated') } ) console.log(updateCharacteristicObj); // this.specService.patchProductSpecification({ id: this.data.productSpec.id, productSpecification: updateCharacteristicObj }).subscribe( // data => { }, // error => { console.error(error); this.toast.error("An error occurred upon updating Spec Characteristics") }, // () => { this.dialogRef.close('updated') } // ) } ngOnDestroy(): void { Loading