// Licensed to Cloudera, Inc. under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. Cloudera, Inc. licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { getLastKnownConfig } from '../config/hueConfig';
import { post } from '../api/utils';
import { hueWindow } from '../types/types';
// HOW TO TRACK EVENTS
// a) Calling the hueAnalytics.log or hueAnalytics.convert manually
// b) Using the attribute "data-hue-analytics" on a clickable HTML element
// and set a string value containing the area followed by a colon and the action e.g.
// Remove
//
// Setting the additional attribute data-hue-analytics-prio="true" will cause the interaction
// to be logged in the Hue backend, independent of the collect_usage setting. This should be used
// with caution to prevent flooding the log.
const formatGaData = (
area: string,
action: string
): { type: string; name: string; params: { action: string; version: string } } => ({
type: 'event',
name: area,
params: {
action,
version: (window).HUE_VERSION || ''
}
});
// Check and warning for when the analytics log/convert are called incorrectly
// by legacy non typescript code. We want this to fail silenctly in hueDebugAnalytics mode.
const validateParameterTypes = (area: string, action: string): boolean => {
const typedWindow = window;
if (typedWindow.DEV && typedWindow.hueDebugAnalytics) {
if (typeof area !== 'string') {
console.error(`hueAnalytics parameter "area" must be a string`);
}
if (typeof action !== 'string') {
console.error(`hueAnalytics parameter "action" must be a string`);
}
}
return typeof area === 'string' && typeof action === 'string';
};
export const hueAnalytics = {
log(area: string, action: string, isPrioritised?: boolean): void {
const config = getLastKnownConfig();
const typedWindow = window;
if (isPrioritised) {
this.convert(area, action);
}
if (config?.hue_config?.collect_usage) {
if (!validateParameterTypes(area, action)) {
return;
}
const { type, name, params } = formatGaData(area, action);
// Quick debug mode to check that the analytics logging is working when developing new features
// Turn on by typing "window.hueDebugAnalytics = true;" in the browser JS console or setting
// "window.hueDebugAnalytics = true" in hue.js;
if (typedWindow.DEV && typedWindow.hueDebugAnalytics) {
console.info('Analytics debug:', type, name, params);
}
if (!typedWindow.DEV) {
typedWindow.gtag?.(type, name, params);
}
}
},
convert(area: string, action: string): void {
if (!validateParameterTypes(area, action)) {
return;
}
post('/desktop/log_analytics', {
area,
action
});
}
};
export const setupGlobalListenersForAnalytics = (): void => {
document.addEventListener('click', event => {
const eventTarget = event?.target as HTMLElement;
const analyticsDataAttribute = eventTarget.dataset?.hueAnalytics;
if (analyticsDataAttribute) {
const [area, action] = analyticsDataAttribute.split(':');
const isPrioritised = !!eventTarget.dataset.hueAnalyticsPrio;
return hueAnalytics.log(area, action, isPrioritised);
}
});
};
export default hueAnalytics;