@atlaskit/global-search
Version:
A cross-product search component (batteries included)
219 lines (207 loc) • 7.51 kB
JavaScript
import * as Rusha from 'rusha';
import { sanitizeSearchQuery, sanitizeContainerId, DEFAULT_GAS_CHANNEL, DEFAULT_GAS_ATTRIBUTES, DEFAULT_GAS_SOURCE } from './analytics-util';
function stripUGC(referralContextIdentifiers) {
if (referralContextIdentifiers) {
const {
searchReferrerId,
currentContentId,
currentContainerId
} = referralContextIdentifiers;
return {
searchReferrerId,
currentContentId,
currentContainerId
};
}
}
const fireGasEvent = (createAnalyticsEvent, action, actionSubject, actionSubjectId, eventType, extraAtrributes, nonPrivacySafeAttributes) => {
if (createAnalyticsEvent) {
const event = createAnalyticsEvent({});
const payload = {
action,
actionSubject,
actionSubjectId,
eventType,
source: DEFAULT_GAS_SOURCE,
attributes: { ...extraAtrributes,
...DEFAULT_GAS_ATTRIBUTES
}
};
if (nonPrivacySafeAttributes) {
payload.nonPrivacySafeAttributes = nonPrivacySafeAttributes;
}
event.update(payload).fire(DEFAULT_GAS_CHANNEL);
}
};
export function firePreQueryShownEvent(eventAttributes, elapsedMs, renderTimeMs, searchSessionId, createAnalyticsEvent, abTest, referralContextIdentifiers, retrievedFromAggregator) {
fireGasEvent(createAnalyticsEvent, 'shown', 'searchResults', 'preQuerySearchResults', 'ui', {
preQueryRequestDurationMs: elapsedMs,
renderTimeMs,
searchSessionId: searchSessionId,
referralContextIdentifiers: stripUGC(referralContextIdentifiers),
...eventAttributes,
retrievedFromAggregator,
...abTest
});
}
export function fireExperimentExposureEvent(abTest, searchSessionId, createAnalyticsEvent) {
fireGasEvent(createAnalyticsEvent, 'exposed', 'quickSearchExperiment', '', 'operational', {
searchSessionId,
abTest,
// send nested structure for backwards compat
...abTest // send destructured object for easier querying of props
});
}
const getQueryAttributes = query => {
const sanitizedQuery = sanitizeSearchQuery(query);
return {
queryLength: sanitizedQuery.length,
wordCount: sanitizedQuery.length > 0 ? sanitizedQuery.split(/\s/).length : 0,
queryHash: sanitizedQuery ? hash(sanitizedQuery) : '',
isNonZeroNumericQuery: !!+sanitizedQuery
};
};
const getNonPrivacySafeAttributes = query => {
return {
query: sanitizeSearchQuery(query)
};
};
export function fireTextEnteredEvent(query, searchSessionId, queryVersion, createAnalyticsEvent) {
fireGasEvent(createAnalyticsEvent, 'entered', 'text', 'globalSearchInputBar', 'track', {
queryId: null,
queryVersion: queryVersion,
...getQueryAttributes(query),
searchSessionId: searchSessionId
}, getNonPrivacySafeAttributes(query));
}
export function fireDismissedEvent(searchSessionId, createAnalyticsEvent) {
fireGasEvent(createAnalyticsEvent, 'dismissed', 'globalSearchDrawer', '', 'ui', {
searchSessionId
});
}
export function firePostQueryShownEvent(resultsDetails, timings, searchSessionId, query, filtersApplied, createAnalyticsEvent, abTest, referralContextIdentifiers) {
const event = createAnalyticsEvent({});
const {
elapsedMs,
...otherPerformanceTimings
} = timings;
const payload = {
action: 'shown',
actionSubject: 'searchResults',
actionSubjectId: 'postQuerySearchResults',
eventType: 'ui',
source: DEFAULT_GAS_SOURCE,
attributes: { ...getQueryAttributes(query),
filtersApplied,
postQueryRequestDurationMs: elapsedMs,
searchSessionId,
referralContextIdentifiers: stripUGC(referralContextIdentifiers),
...otherPerformanceTimings,
...resultsDetails,
...DEFAULT_GAS_ATTRIBUTES,
...abTest
}
};
event.update(payload).fire(DEFAULT_GAS_CHANNEL);
}
const transformSearchResultEventData = eventData => ({
resultContentId: eventData.resultId,
type: eventData.contentType,
sectionId: eventData.type,
sectionIndex: eventData.sectionIndex,
globalIndex: eventData.index,
indexWithinSection: eventData.indexWithinSection,
containerId: sanitizeContainerId(eventData.containerId),
resultCount: eventData.resultCount,
experimentId: eventData.experimentId,
isRecentResult: eventData.isRecentResult
});
const hash = str => Rusha.createHash().update(str).digest('hex');
export function fireSelectedSearchResult(eventData, searchSessionId, referralContextIdentifiers, createAnalyticsEvent) {
const {
method,
newTab,
query,
queryVersion
} = eventData;
fireGasEvent(createAnalyticsEvent, 'selected', 'navigationItem', 'searchResult', 'track', {
queryVersion,
queryId: null,
...getQueryAttributes(query),
trigger: method,
searchSessionId: searchSessionId,
newTab,
...transformSearchResultEventData(eventData),
referralContextIdentifiers: stripUGC(referralContextIdentifiers)
});
}
export function fireSelectedAdvancedSearch(eventData, searchSessionId, referralContextIdentifiers, createAnalyticsEvent) {
const {
method,
newTab,
query,
queryVersion
} = eventData;
fireGasEvent(createAnalyticsEvent, 'selected', 'navigationItem', `advanced_${eventData.resultId}`, 'track', {
trigger: method,
searchSessionId: searchSessionId,
newTab,
queryVersion,
queryId: null,
isLoading: eventData.isLoading,
...getQueryAttributes(query),
wasOnNoResultsScreen: eventData.wasOnNoResultsScreen || false,
...transformSearchResultEventData(eventData),
referralContextIdentifiers: stripUGC(referralContextIdentifiers)
});
}
export function fireHighlightedSearchResult(eventData, searchSessionId, referralContextIdentifiers, createAnalyticsEvent) {
const {
key
} = eventData;
fireGasEvent(createAnalyticsEvent, 'highlighted', 'navigationItem', 'searchResult', 'ui', {
searchSessionId: searchSessionId,
...transformSearchResultEventData(eventData),
key,
referralContextIdentifiers: stripUGC(referralContextIdentifiers)
});
}
export function fireShowMoreButtonClickEvent(searchSessionId, currentSize, totalResultSize, buttonIdentifier, pageSize, createAnalyticsEvent) {
fireGasEvent(createAnalyticsEvent, 'clicked', 'button', buttonIdentifier, 'ui', {
searchSessionId,
currentSize,
totalResultSize,
pageSize
});
}
export function fireMoreFiltersButtonClickEvent(searchSessionId, createAnalyticsEvent) {
fireGasEvent(createAnalyticsEvent, 'clicked', 'button', 'showMoreFilters', 'ui', {
searchSessionId
});
}
export function fireSpaceFilterShownEvent(searchSessionId, createAnalyticsEvent) {
fireGasEvent(createAnalyticsEvent, 'shown', 'filter', 'spaceFilterButton', 'ui', {
searchSessionId
});
}
export function fireAutocompleteRenderedEvent(duration, searchSessionId, query, autocompleteText, queryVersion, fromCache, createAnalyticsEvent) {
fireGasEvent(createAnalyticsEvent, 'rendered', 'autocomplete', '', 'operational', {
duration,
searchSessionId,
...getQueryAttributes(query),
autocompleteTextHash: hash(autocompleteText),
queryVersion,
fromCache
}, { ...getNonPrivacySafeAttributes(query),
autocompleteText
});
}
export function fireAutocompleteCompletedEvent(searchSessionId, query, completedText, createAnalyticsEvent) {
fireGasEvent(createAnalyticsEvent, 'completed', 'autocomplete', '', 'ui', {
searchSessionId,
...getQueryAttributes(query),
completedTextHash: hash(completedText)
}, { ...getNonPrivacySafeAttributes(query),
completedText
});
}