import isObject from 'lodash/isObject'; import {renameEvent} from '../../../report/util'; import {removeByIndex, replaceByIndex} from '../../../util/array'; import CustomEventPropertyFilter from '../../property-filter-menu/models/custom-event-property-filter'; import MPCustomEvent from './custom-event'; import {Alternative, LabelPart, MPEvent} from './types'; export default class EventSelector { public static fromAlternative({event, valid_segfilter}: Alternative): EventSelector { let options: Partial = {event}; if (valid_segfilter) { const {filters} = valid_segfilter; options = { ...options, propertyFilters: filters.map(filter => CustomEventPropertyFilter.fromSegfilter(filter)), }; } return new EventSelector(options); } public event: MPEvent; public propertyFilters: Array; constructor(options: Partial = {}) { const {event, propertyFilters = []} = options; // event is either string for normal event or object representing custom event this.event = isObject(event) ? new MPCustomEvent(event as Partial) : event; this.propertyFilters = propertyFilters.map(pf => new CustomEventPropertyFilter(pf)); } public toAlternative(): Alternative { return { event: this.isCustomEvent(this.event) ? this.event.getSerializedName() : this.event, valid_segfilter: { filters: this.propertyFilters.map(pf => pf.toSegfilter()), op: `and`, }, }; } public getLabelParts(): Array { const propertyFilterParts = this.propertyFilters.reduce((parts, propertyFilter, index, arr) => { const operator = index !== arr.length - 1 ? [{label: `\nAND`, highlight: false}] : []; return [...parts, ...propertyFilter.getLabelParts(), ...operator]; }, [{label: `where`, highlight: false}]); return [ {label: this.getEventLabel(), highlight: true}, ...(this.propertyFilters.length ? propertyFilterParts : []), ]; } public isValid(): boolean { return !!this.event && this.propertyFilters.every(pf => pf.isValid()); } public hasSelectedEvent(): boolean { return !!this.event; } public getEventLabel(): string { const name = this.isCustomEvent(this.event) ? this.event.name : this.event; return renameEvent(name); } public getEventName(): string { return this.isCustomEvent(this.event) ? this.event.getSerializedName() : this.event; } public cloneEventSelector(newAttributes: Partial): EventSelector { return new EventSelector({ event: this.event, propertyFilters: this.propertyFilters, ...newAttributes, }); } public updateEvent(event: MPEvent): EventSelector { return new EventSelector({event}); } public commitPropertyFilter(propertyFilter: CustomEventPropertyFilter, index: number): EventSelector { let propertyFilters; if (index >= this.propertyFilters.length) { propertyFilters = [...this.propertyFilters, propertyFilter]; } else { propertyFilters = replaceByIndex(this.propertyFilters, index, propertyFilter); } return this.cloneEventSelector({propertyFilters}); } public removePropertyFilterAtIndex(index: number): EventSelector { return this.cloneEventSelector({ propertyFilters: removeByIndex(this.propertyFilters, index), }); } private isCustomEvent(event: MPEvent): event is MPCustomEvent { return event instanceof MPCustomEvent; } }