import { Component, OnInit, OnDestroy, NgZone, EventEmitter, Output, Input } from '@angular/core'; import { Subscription } from 'rxjs'; import { TranslateService } from '@ngx-translate/core'; import { SocketsService, DialogService, AnalyticsService, MessageBusService, AnalyticsEvent, ApiSocketListenAction } from '@arrow/bom/core'; @Component({ selector: 'bom-filters', templateUrl: 'filters.component.html', styleUrls: ['filters.component.scss'] }) export class FiltersComponent implements OnInit, OnDestroy { hasSelection: boolean = false; selectedFilters: Object = {}; subscriptions: Array = []; data: Object; @Input() isSearching: boolean = false; @Output() filterChanged = new EventEmitter(); constructor( private _messageBus: MessageBusService, private _sockets: SocketsService, private _dialog: DialogService, private _analyticsService: AnalyticsService, private _translate: TranslateService, private _zone: NgZone ) {} ngOnInit() { // On filters data this.subscriptions.push( this._sockets.observeAction(ApiSocketListenAction.FILTER_COUNTS) .subscribe((data: any) => { this._zone.run(() => { if (data && data.length) { this._messageBus.to('ch:filters', { payload: false }); this.data = data[0]; // response data is a 1 element array } else { this._dialog.alert( this._translate.instant('An-error-has-occurred'), this._translate.instant('Unable-to-load-filter-data') ); } }) }) ); } ngOnDestroy() { this.subscriptions.forEach((sub: Subscription) => sub.unsubscribe()); } /** * Triggered when a child filter is changed. * Converts all in coming filters to an object the api will understand. * @param filter is an Object containing the filters selection and type. * @param selectedFilters */ filterChange( filter: { selection: string; type: string }, selectedFilters: Object ): void { const keys: Array = Object.keys(selectedFilters); let index: number; // looks in the this.selectedFilters for keys associate to known filter types // and pushes selection to that types array. If the key doesn't exist it is added. if (keys.find(type => type === filter.type)) { // attempt to find index of the filter selection index = selectedFilters[filter.type].indexOf(filter.selection); if (index >= 0) { // if filter selection exists remove it selectedFilters[filter.type].splice(index, 1); this._analyticsService.googleTrackEvent(AnalyticsEvent.CLICK, { category: 'BOM', action: 'Filter Removed', label: `${filter.type} - ${filter.selection}` }); } else { // if filter doesn't exist add it selectedFilters[filter.type].push(filter.selection); this._analyticsService.googleTrackEvent(AnalyticsEvent.CLICK, { category: 'BOM', action: 'Filter Added', label: `${filter.type} - ${filter.selection}` }); } } else { selectedFilters[filter.type] = [filter.selection]; this._analyticsService.googleTrackEvent(AnalyticsEvent.CLICK, { category: 'BOM', action: 'Filter Added', label: `${filter.type} - ${filter.selection}` }); } // send formatted data to the api this.filterChanged.emit(selectedFilters); this.setSelectedStatus(selectedFilters); } /** * Looks through the filterList array to find if any of the contained arrays * have items if they do they the selected state is set to true. * @param selectedFilters */ setSelectedStatus(selectedFilters: Object) { const keys: Array = Object.keys(selectedFilters); this.hasSelection = keys.find( (key: string) => selectedFilters[key] && selectedFilters[key].length > 0 ); } }