2019-08-31 20:51:14 -07:00
|
|
|
import { inject as service } from '@ember/service';
|
|
|
|
import RouterService from '@ember/routing/router-service';
|
2019-09-04 21:46:02 -07:00
|
|
|
import DwellTime from '@datahub/tracking/utils/dwell-time';
|
2019-08-31 20:51:14 -07:00
|
|
|
import { Time } from '@datahub/metadata-types/types/common/time';
|
|
|
|
import { action } from '@ember/object';
|
2019-09-04 21:46:02 -07:00
|
|
|
import { searchTrackingEvent } from '@datahub/tracking/constants/event-tracking/search';
|
2019-08-31 20:51:14 -07:00
|
|
|
import { DataModelName } from '@datahub/data-models/constants/entity';
|
|
|
|
import Service from '@ember/service';
|
2019-09-04 21:46:02 -07:00
|
|
|
import { isRouteEntityPageRoute } from '@datahub/data-models/utils/entity-route-name-resolver';
|
|
|
|
import { SuccessfulDwellTimeLength, searchRouteName } from '@datahub/tracking/constants/site-search-tracking';
|
|
|
|
import Transition from '@ember/routing/-private/transition';
|
|
|
|
import UnifiedTracking from '@datahub/tracking/services/unified-tracking';
|
2019-08-31 20:51:14 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Search service is used to maintain the same
|
|
|
|
* state on different parts of the app. Right now the only thing
|
|
|
|
* we need to persist is the keywords.
|
|
|
|
*/
|
|
|
|
export default class Search extends Service {
|
|
|
|
/**
|
|
|
|
* Keyword or query for the current search
|
|
|
|
*/
|
|
|
|
keyword: string;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Current entity of the search
|
|
|
|
*/
|
|
|
|
entity?: DataModelName;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Optional urn of the clicked search result
|
|
|
|
* @type {string}
|
|
|
|
*/
|
|
|
|
private clickedSearchResultUrn?: string;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* On service instantiation a reference to a DwellTime instance is cached here to track dwell time
|
|
|
|
* @type {DwellTime}
|
|
|
|
* @memberof Search
|
|
|
|
*/
|
|
|
|
dwellTimeTracker: DwellTime;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* References the application service to track user events, metrics and interaction
|
|
|
|
*/
|
2019-09-04 21:46:02 -07:00
|
|
|
@service('unified-tracking')
|
|
|
|
tracking: UnifiedTracking;
|
2019-08-31 20:51:14 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Router service used in tracking dwell time
|
|
|
|
*/
|
|
|
|
@service
|
2019-09-04 21:46:02 -07:00
|
|
|
router: RouterService;
|
2019-08-31 20:51:14 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Performs a set of operation when a search result is clicked
|
|
|
|
* @param {string} urn
|
|
|
|
* @returns {void}
|
|
|
|
* @memberof Search
|
|
|
|
*/
|
|
|
|
didClickSearchResult(urn: string): void {
|
|
|
|
// When a search result is clicked, initiate dwell time tracking
|
|
|
|
this.dwellTimeTracker.beginTracking();
|
|
|
|
// Also, track event as a click event
|
|
|
|
this.clickedSearchResultUrn = urn;
|
|
|
|
this.tracking.trackEvent({ ...searchTrackingEvent.SearchResultClick, name: this.clickedSearchResultUrn });
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the threshold value of the successful amount of dwell time on the component
|
|
|
|
* @instance
|
|
|
|
*/
|
|
|
|
successfulDwellTimeLength = SuccessfulDwellTimeLength;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Track SAT Click as an event
|
|
|
|
* This is inferred based on
|
|
|
|
* 1) Time spent or more specifically dwell time on viewing the entity page (see DwellTime class for differentiation)
|
|
|
|
* @link {DwellTime}
|
|
|
|
* 2) navigation sequence i.e. click from a search implied by dwell time, that lands on an entity page
|
|
|
|
* @param {number} dwellTime
|
|
|
|
* @returns boolean
|
|
|
|
*/
|
|
|
|
@action
|
2019-09-04 21:46:02 -07:00
|
|
|
trackSatClick(dwellTime: number, transition: Transition): boolean {
|
2019-08-31 20:51:14 -07:00
|
|
|
const isSATClick = this.isSATClick(dwellTime, transition);
|
|
|
|
|
|
|
|
if (isSATClick) {
|
|
|
|
this.tracking.trackEvent({ ...searchTrackingEvent.SearchResultSATClick, name: this.clickedSearchResultUrn });
|
|
|
|
}
|
|
|
|
|
|
|
|
return isSATClick;
|
|
|
|
}
|
|
|
|
|
|
|
|
init(): void {
|
|
|
|
super.init();
|
|
|
|
|
|
|
|
// Instantiate a DwellTime instance to track dwell time, which is essentially time spent on a search result page
|
|
|
|
this.dwellTimeTracker = new DwellTime(searchRouteName, this.router, this.trackSatClick);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Determines if the click can be judged as a satisfied click
|
|
|
|
* @param {Time} dwellTime the amount of time in milliseconds the user has dwelled on the page
|
2019-09-04 21:46:02 -07:00
|
|
|
* @param {Transition} { to, from } the current ember transition object containing the RouteInfo object being transitioned to or from
|
2019-08-31 20:51:14 -07:00
|
|
|
*/
|
2019-09-04 21:46:02 -07:00
|
|
|
isSATClick(dwellTime: Time, { to, from }: Transition): boolean {
|
2019-08-31 20:51:14 -07:00
|
|
|
const isReturningToSearch = Boolean(to && to.name === searchRouteName);
|
|
|
|
// If the user is returning to the search page, check if the dwellTime is meets or exceeds what is considered a successful amount of time
|
|
|
|
const isSufficientDwellTimeOnSearchReturn = isReturningToSearch && dwellTime >= this.successfulDwellTimeLength;
|
|
|
|
|
|
|
|
// If the dwell time is sufficient and the user is returning to search, or the user is navigating away from an entity route
|
|
|
|
// to a route that is not search this is considered a satisfied click
|
|
|
|
return isSufficientDwellTimeOnSearchReturn || (isRouteEntityPageRoute(from) && !isReturningToSearch);
|
|
|
|
}
|
|
|
|
}
|