import { Component, Input, OnChanges, ChangeDetectorRef, OnInit, OnDestroy, Output, EventEmitter, SimpleChanges } from '@angular/core'; import { FormControl } from '@angular/forms'; import { BomService, BomItemService, BomModel, AnalyticsService, SocketsService, MessageBusService, ListItemModel, PermissionsService, AnalyticsEvent } from '@arrow/bom/core'; import { ConfigService } from '@arrow/bom/config'; import { Subscription } from 'rxjs'; import { EndCustomer, RowBase as Row } from '../ORM'; import { WptDialog } from '@arrow/warpaint/dialog'; import { CreateCpnComponent } from '../modals/create-cpn/create-cpn.component'; const CPN_CREATION_FAILURE_ERROR_CODE = 40001; @Component({ selector: 'bom-part-name', templateUrl: 'part-name.component.html', styleUrls: ['part-name.component.scss'] }) export class PartNameComponent implements OnChanges, OnInit, OnDestroy { @Input() row: Row; @Input() item: ListItemModel; @Input() itemLoading: boolean; @Input() partNameControl: FormControl; @Input() bom: BomModel; @Input() isUserUploadedData?: boolean; @Input() isDefaultView?: boolean; @Input() customerType?: any; @Output() toggleAlts?: EventEmitter = new EventEmitter(); @Output() toggleDatasheet?: EventEmitter = new EventEmitter(); hasAlternates: boolean; hasCpns: boolean; showEditPartName: boolean; permissions: any; subscriptions: Array = []; selectedValue: string; CpnMapCreationError: boolean; viewSelect = false; viewEc = false; isMyArrow = false; selectedCPN: any; selectedEc: string; appliedCPN = ''; appliedEC: EndCustomer; availableECs: EndCustomer[] = []; cpnMapCreationErrorMessage = 'There was an error creating this CPN. Please create it manually using the CPN link in the Part Number column.'; constructor( private _messageBus: MessageBusService, private bomItemService: BomItemService, public config: ConfigService, private analyticsService: AnalyticsService, private sockets: SocketsService, private cdRef: ChangeDetectorRef, private ps: PermissionsService, private wptDialog: WptDialog ) {} ngOnInit(): void { this.isMyArrow = this.config.getTarget() === 'myarrow'; // myarrow|models this.subscriptions.push( this.ps.getPermissions().subscribe((permissions: any) => { this.permissions = permissions; this.cdRef.markForCheck(); this.cdRef.detectChanges(); }) ); } ngOnDestroy() { this.subscriptions.forEach((sub: Subscription) => sub.unsubscribe()); } ngOnChanges(changes: SimpleChanges) { this.hasAlternates = !!this.item.alternates.length; if (changes['row']) { if (this.row.cpnToEcRel) { this.hasCpns = !!this.row.cpnToEcRel.cpns.length; } if (this.row.pricing) { this.appliedCPN = this.row.pricing.appliedCPN || ''; this.appliedEC = this.row.pricing.appliedEC; } if (this.row.cpnToEcRel && this.row.pricing) { this.availableECs = this.row.cpnToEcRel.ecMap.get(this.appliedCPN) || []; } if (this.row.errorCode) { this.CpnMapCreationError = this.row.errorCode === CPN_CREATION_FAILURE_ERROR_CODE; } } } // // /** // * Reverts the partName input to its original (item.partName or item.originalName) // * closes the input // */ // cancelEditPartName(item: ListItemModel) { // const originalName = item.partName || item.originalName; // this.partNameControl.setValue(originalName); // this.closeEditPartName(item); // } // // /** // * Reverts the partName input to its original (item.partName or item.originalName) // * reverts partName model to original partname // */ // revertPartNameChange( // originalName: string, // originalPartName: string, // item: ListItemModel // ) { // this.partNameControl.setValue(originalName); // item.partName = originalPartName; // revert in case of error response // } /** * If edited partName is valid and different to the original, update form control & partName with the new part name * set the item to loading state (disabled when we get data), set bom to not fully loaded, cart to not fully loaded * Send socket request to update row with the new partName * @param value partName input value */ updatePartName( value: string, item: ListItemModel, bom: BomModel, row: Row ): void { const originalName = item.partName || item.originalName; // if partName doesn't exist, use originalName (unmatched parts) // Close the edit box this.showEditPartName = false; // If nothing has changed or empty partname, don't bother updating if (value === originalName || !value.length) { return; } // Set item to loading this.bomItemService.setItemLoading(item.rowId, true); if (!item.hiddenAlts) { this.bomItemService.toggleAlternates(item.rowId, true); } // Update item model item.resetAllProperties(); item.partName = value; this._messageBus.to('ch:loader', { payload: true }); this._messageBus.to('ch:cart', { payload: true }); this.sockets.emitAction('updateRow', { bomId: bom.id, rowId: row.id, pn: value, mfr: null, qty: 0, pid: -1 }); } // Toggle CPN & EC dropDowns toggleSelect( dropDownId: string, isMyArrow: boolean, item: ListItemModel, row: Row, bom: BomModel, availableECs: EndCustomer[] ) { if (isMyArrow) { const dialogRef = this.wptDialog.open(CreateCpnComponent, { // Ensure modal window content is scrollable on smaller screen resolutions (i.e. 320px) panelClass: 'bom-create-cpn-cdk-overlay-pane', // See _normalize.scss data: { row: row, dropdownID: dropDownId, customerType: this.customerType } }); dialogRef.afterClosed().subscribe(result => { if (result) { this.setCPNandEC(result.cpn, result.ec, item, row, bom, availableECs); } }); } else { if (dropDownId === 'viewSelect') this.viewSelect = !this.viewSelect; if (dropDownId === 'viewEc') this.viewEc = !this.viewEc; } } //Sets CPN and EC if both are present setCPNandEC( selectedCPN: any, selectedEC: any, item: ListItemModel, row: Row, bom: BomModel, availableECs: EndCustomer[] ) { item.isLoading = true; //Temporary patch row.errorCode = 0; if ( Object.keys(selectedCPN).length !== 0 && Object.keys(selectedEC).length !== 0 && selectedCPN.endCustomers.findIndex(x => x.name === selectedEC.name) !== -1 ) { availableECs = row.cpnToEcRel.ecMap.get(selectedCPN.cpn) || []; this.appliedCPN = selectedCPN.cpn; this.sockets.emitAction('setCPN', { bomId: bom.id, rowId: row.id, cpn: selectedCPN.cpn, custId: selectedEC.id, custName: selectedEC.name }); } else if (Object.keys(selectedCPN).length !== 0) { availableECs = row.cpnToEcRel.ecMap.get(selectedCPN.cpn) || []; this.appliedCPN = selectedCPN.cpn; this.sockets.emitAction('setCPN', { bomId: bom.id, rowId: row.id, cpn: selectedCPN.cpn, custId: -1 }); } else { // Send empty string to clear availableECs = []; this.sockets.emitAction('setCPN', { bomId: bom.id, rowId: row.id, cpn: '', custId: -1 }); } } // Set CPN setCpn( selectedCPN: any, item: ListItemModel, row: Row, bom: BomModel, availableECs: EndCustomer[] ) { // this.row.loading = true; item.isLoading = true; this.analyticsService.googleTrackEvent(AnalyticsEvent.CLICK, { category: 'BOM', action: 'CPN Select', label: selectedCPN === 'noCpn' ? '' : selectedCPN }); if (selectedCPN !== 'noCpn') { availableECs = this.row.cpnToEcRel.ecMap.get(selectedCPN) || []; this.appliedCPN = selectedCPN; this.sockets.emitAction('setCPN', { bomId: bom.id, rowId: row.id, cpn: selectedCPN, custId: -1 }); } else { // Send empy string to clear availableECs = []; this.sockets.emitAction('setCPN', { bomId: bom.id, rowId: row.id, cpn: '', custId: -1 }); } } //TODO apply EC setEc(selectedEc: EndCustomer, item: ListItemModel, row: Row, bom: BomModel) { item.isLoading = true; if (selectedEc.id !== -1 && this.appliedCPN) { this.sockets.emitAction('setCPN', { bomId: bom.id, rowId: row.id, cpn: this.appliedCPN, custId: selectedEc.id, custName: selectedEc.name }); this.analyticsService.googleTrackEvent(AnalyticsEvent.CLICK, { category: 'BOM', action: 'EC Select', label: selectedEc.name }); } else { this.sockets.emitAction('setCPN', { bomId: bom.id, rowId: row.id, cpn: this.appliedCPN, custId: -1, custName: '' }); this.analyticsService.googleTrackEvent(AnalyticsEvent.CLICK, { category: 'BOM', action: 'CPN Select', label: '' }); } } // /** // * Calls toggleEditPartName on 'Enter' key press // * @param event - key press event object // */ // editNameKeyPressed(event: any): void { // if (event.key === 'Enter') { // this.showEditPartName = !this.showEditPartName; // } // } /** * Emits the alternatives toggle change event sending the toggled hidden alternatives state, list item * is listening to the event */ toggleAlternatives(): void { // this.bomItemService.toggleAlternates(this.item.rowId, !this.item.hiddenAlts); this.toggleAlts.emit(true); } /** * Emits the datasheet id toggle change event sending the toggled hidden alternatives state, list item * is listening to the event */ toggleDatasheetID(): void { this.toggleDatasheet.emit(true); } /** * Closes the input, sends the item loading change state event that list item is listening to (list item * updates children components on event) */ closeEditPartName(item: ListItemModel) { this.showEditPartName = false; this.bomItemService.setItemLoading(item.rowId, false); } /** * Google analytic tracking for PDP link click */ trackPartNameClick(item: ListItemModel): void { this.analyticsService.googleTrack(AnalyticsEvent.PRODUCT_LIST_CLICK, item); } }