103 lines
2.5 KiB
JavaScript
103 lines
2.5 KiB
JavaScript
|
import { omitBy, isUndefined } from 'lodash';
|
||
|
import { TRACKING_CONTEXT_SCHEMA } from '~/experimentation/constants';
|
||
|
import { getExperimentData } from '~/experimentation/utils';
|
||
|
import {
|
||
|
ACTION_ATTR_SELECTOR,
|
||
|
LOAD_ACTION_ATTR_SELECTOR,
|
||
|
DEPRECATED_EVENT_ATTR_SELECTOR,
|
||
|
DEPRECATED_LOAD_EVENT_ATTR_SELECTOR,
|
||
|
} from './constants';
|
||
|
|
||
|
export const addExperimentContext = (opts) => {
|
||
|
const { experiment, ...options } = opts;
|
||
|
|
||
|
if (experiment) {
|
||
|
const data = getExperimentData(experiment);
|
||
|
if (data) {
|
||
|
const context = { schema: TRACKING_CONTEXT_SCHEMA, data };
|
||
|
return { ...options, context };
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return options;
|
||
|
};
|
||
|
|
||
|
export const createEventPayload = (el, { suffix = '' } = {}) => {
|
||
|
const {
|
||
|
trackAction,
|
||
|
trackEvent,
|
||
|
trackValue,
|
||
|
trackExtra,
|
||
|
trackExperiment,
|
||
|
trackContext,
|
||
|
trackLabel,
|
||
|
trackProperty,
|
||
|
} = el?.dataset || {};
|
||
|
|
||
|
const action = (trackAction || trackEvent) + (suffix || '');
|
||
|
let value = trackValue || el.value || undefined;
|
||
|
|
||
|
if (el.type === 'checkbox' && !el.checked) {
|
||
|
value = 0;
|
||
|
}
|
||
|
|
||
|
let extra = trackExtra;
|
||
|
|
||
|
if (extra !== undefined) {
|
||
|
try {
|
||
|
extra = JSON.parse(extra);
|
||
|
} catch (e) {
|
||
|
extra = undefined;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const context = addExperimentContext({
|
||
|
experiment: trackExperiment,
|
||
|
context: trackContext,
|
||
|
});
|
||
|
|
||
|
const data = {
|
||
|
label: trackLabel,
|
||
|
property: trackProperty,
|
||
|
value,
|
||
|
extra,
|
||
|
...context,
|
||
|
};
|
||
|
|
||
|
return {
|
||
|
action,
|
||
|
data: omitBy(data, isUndefined),
|
||
|
};
|
||
|
};
|
||
|
|
||
|
export const eventHandler = (e, func, opts = {}) => {
|
||
|
const actionSelector = `${ACTION_ATTR_SELECTOR}:not(${LOAD_ACTION_ATTR_SELECTOR})`;
|
||
|
const deprecatedEventSelector = `${DEPRECATED_EVENT_ATTR_SELECTOR}:not(${DEPRECATED_LOAD_EVENT_ATTR_SELECTOR})`;
|
||
|
const el = e.target.closest(`${actionSelector}, ${deprecatedEventSelector}`);
|
||
|
|
||
|
if (!el) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const { action, data } = createEventPayload(el, opts);
|
||
|
func(opts.category, action, data);
|
||
|
};
|
||
|
|
||
|
export const getEventHandlers = (category, func) => {
|
||
|
const handler = (opts) => (e) => eventHandler(e, func, { ...{ category }, ...opts });
|
||
|
const handlers = [];
|
||
|
|
||
|
handlers.push({ name: 'click', func: handler() });
|
||
|
handlers.push({ name: 'show.bs.dropdown', func: handler({ suffix: '_show' }) });
|
||
|
handlers.push({ name: 'hide.bs.dropdown', func: handler({ suffix: '_hide' }) });
|
||
|
|
||
|
return handlers;
|
||
|
};
|
||
|
|
||
|
export const renameKey = (o, oldKey, newKey) => {
|
||
|
const ret = {};
|
||
|
delete Object.assign(ret, o, { [newKey]: o[oldKey] })[oldKey];
|
||
|
|
||
|
return ret;
|
||
|
};
|