diff options
author | jejacks0n <jjackson@gitlab.com> | 2019-09-06 12:56:40 -0600 |
---|---|---|
committer | jejacks0n <jjackson@gitlab.com> | 2019-09-06 15:02:44 -0600 |
commit | ba550e468cee09fdc80cb74043b9f54446a81a32 (patch) | |
tree | df9d454e9e27301f8aba7dd3bf24f9afcab76cef | |
parent | 5e7b3f6285236c7dcfada72635df2f9baf620379 (diff) | |
download | gitlab-ce-tracking-performance.tar.gz |
Restructures Vue mixin to not be globaltracking-performance
This includes refactors around usage in Vue components and specs.
7 files changed, 55 insertions, 70 deletions
diff --git a/app/assets/javascripts/sidebar/components/assignees/assignee_title.vue b/app/assets/javascripts/sidebar/components/assignees/assignee_title.vue index 3568c66f612..ea5441f31e9 100644 --- a/app/assets/javascripts/sidebar/components/assignees/assignee_title.vue +++ b/app/assets/javascripts/sidebar/components/assignees/assignee_title.vue @@ -1,8 +1,10 @@ <script> import { n__ } from '~/locale'; +import Tracking from '~/tracking'; export default { name: 'AssigneeTitle', + mixins: [Tracking.mixin({ label: 'right_sidebar' })], props: { loading: { type: Boolean, diff --git a/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue b/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue index 6fd14560d04..ea5edb3ce3f 100644 --- a/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue +++ b/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue @@ -1,5 +1,6 @@ <script> import { __ } from '~/locale'; +import Tracking from '~/tracking'; import icon from '~/vue_shared/components/icon.vue'; import toggleButton from '~/vue_shared/components/toggle_button.vue'; import tooltip from '~/vue_shared/directives/tooltip'; @@ -18,6 +19,7 @@ export default { icon, toggleButton, }, + mixins: [Tracking.mixin({ label: 'right_sidebar' })], props: { loading: { type: Boolean, diff --git a/app/assets/javascripts/sidebar/mount_sidebar.js b/app/assets/javascripts/sidebar/mount_sidebar.js index 5dcf1a3125c..6f8214b18ee 100644 --- a/app/assets/javascripts/sidebar/mount_sidebar.js +++ b/app/assets/javascripts/sidebar/mount_sidebar.js @@ -8,10 +8,8 @@ import LockIssueSidebar from './components/lock/lock_issue_sidebar.vue'; import sidebarParticipants from './components/participants/sidebar_participants.vue'; import sidebarSubscriptions from './components/subscriptions/sidebar_subscriptions.vue'; import Translate from '../vue_shared/translate'; -import Tracking from '~/tracking'; Vue.use(Translate); -Vue.use(Tracking, { label: 'right_sidebar' }); function mountAssigneesComponent(mediator) { const el = document.getElementById('js-vue-sidebar-assignees'); diff --git a/app/assets/javascripts/tracking.js b/app/assets/javascripts/tracking.js index f04cfa7432a..e1519d49018 100644 --- a/app/assets/javascripts/tracking.js +++ b/app/assets/javascripts/tracking.js @@ -18,6 +18,33 @@ const DEFAULT_SNOWPLOW_OPTIONS = { activityTrackingEnabled: false, }; +const eventHandler = (e, func, opts = {}) => { + const el = e.target.closest('[data-track-event]'); + const action = el && el.dataset.trackEvent; + if (!action) return; + + let value = el.dataset.trackValue || el.value || undefined; + if (el.type === 'checkbox' && !el.checked) value = false; + + const data = { + label: el.dataset.trackLabel, + property: el.dataset.trackProperty, + value, + context: el.dataset.trackContext, + }; + + func(opts.category, action + (opts.suffix || ''), _.omit(data, _.isUndefined)); +}; + +const eventHandlers = (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 default class Tracking { static trackable() { return !['1', 'yes'].includes( @@ -39,58 +66,34 @@ export default class Tracking { return window.snowplow('trackStructEvent', category, action, label, property, value, contexts); } - static install(Vue, defaults = {}) { - Vue.mixin({ - methods: { - track(action, data) { - let category = defaults.category || data.category; - // eslint-disable-next-line no-underscore-dangle - category = category || this.$options.name || this.$options._componentTag; - Tracking.event(category || 'unspecified', action, { ...defaults, ...data }); - }, - }, - }); - } - static bindDocument(category = document.body.dataset.page, documentOverride = null) { const el = documentOverride || document; if (!this.enabled() || el.trackingBound) return []; el.trackingBound = true; - const handlers = this.eventHandlers(category); + const handlers = eventHandlers(category, (...args) => this.event(...args)); handlers.forEach(event => el.addEventListener(event.name, event.func)); return handlers; } - static eventHandlers(category) { - const handler = opts => e => this.handleEvent(e, { ...{ 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; - } - - static handleEvent(e, opts = {}) { - const el = e.target.closest('[data-track-event]'); - const action = el && el.dataset.trackEvent; - if (!action) return; - - const data = { - label: el.dataset.trackLabel, - property: el.dataset.trackProperty, - value: this.elementValue(el), - context: el.dataset.trackContext, + static mixin(opts) { + return { + data() { + return { + tracking: { + // eslint-disable-next-line no-underscore-dangle + category: this.$options.name || this.$options._componentTag, + }, + }; + }, + methods: { + track(action, data) { + const category = opts.category || data.category || this.tracking.category; + Tracking.event(category || 'unspecified', action, { ...opts, ...this.tracking, ...data }); + }, + }, }; - - this.event(opts.category, action + (opts.suffix || ''), _.omit(data, _.isUndefined)); - } - - static elementValue(el) { - let value = el.dataset.trackValue || el.value || undefined; - if (el.type === 'checkbox' && !el.checked) value = false; - return value; } } diff --git a/spec/frontend/tracking_spec.js b/spec/frontend/tracking_spec.js index e6eea073dba..8432974b3a5 100644 --- a/spec/frontend/tracking_spec.js +++ b/spec/frontend/tracking_spec.js @@ -1,5 +1,4 @@ import { setHTMLFixture } from './helpers/fixtures'; -import Vue from 'vue'; import Tracking, { initUserTracking } from '~/tracking'; describe('Tracking', () => { @@ -109,27 +108,6 @@ describe('Tracking', () => { }); }); - describe('.install', () => { - let eventSpy; - - Vue.use(Tracking, { category: '_category_', context: { foo: 'bar' } }); - - beforeEach(() => { - eventSpy = jest.spyOn(Tracking, 'event'); - }); - - it('installs a track method', () => { - const component = new (Vue.extend({}))(); - component.track('_action_', { label: '_label_' }); - - expect(eventSpy).toHaveBeenCalledWith('_category_', '_action_', { - category: '_category_', // disregarded within Tracking.event - label: '_label_', - context: { foo: 'bar' }, - }); - }); - }); - describe('tracking interface events', () => { let eventSpy; diff --git a/spec/javascripts/sidebar/assignee_title_spec.js b/spec/javascripts/sidebar/assignee_title_spec.js index 067d40888eb..7ba9d39da68 100644 --- a/spec/javascripts/sidebar/assignee_title_spec.js +++ b/spec/javascripts/sidebar/assignee_title_spec.js @@ -1,8 +1,6 @@ import Vue from 'vue'; import AssigneeTitle from '~/sidebar/components/assignees/assignee_title.vue'; -import Tracking, { mockTracking, triggerEvent } from 'spec/helpers/tracking_helper'; - -Vue.use(Tracking); +import { mockTracking, triggerEvent } from 'spec/helpers/tracking_helper'; describe('AssigneeTitle component', () => { let component; @@ -117,6 +115,10 @@ describe('AssigneeTitle component', () => { const spy = mockTracking('_category_', component.$el, spyOn); triggerEvent('.js-sidebar-dropdown-toggle'); - expect(spy).toHaveBeenCalled(); + expect(spy).toHaveBeenCalledWith('AssigneeTitle', 'click_edit_button', { + label: 'right_sidebar', + category: 'AssigneeTitle', + property: 'assignee', + }); }); }); diff --git a/spec/javascripts/sidebar/subscriptions_spec.js b/spec/javascripts/sidebar/subscriptions_spec.js index c0af4c014ac..a97608d6b8a 100644 --- a/spec/javascripts/sidebar/subscriptions_spec.js +++ b/spec/javascripts/sidebar/subscriptions_spec.js @@ -60,7 +60,7 @@ describe('Subscriptions', function() { expect(vm.$emit).toHaveBeenCalledWith('toggleSubscription', jasmine.any(Object)); }); - it('calls trackEvent when toggled', () => { + it('tracks the event when toggled', () => { vm = mountComponent(Subscriptions, { subscribed: true }); const spy = mockTracking('_category_', vm.$el, spyOn); vm.toggleSubscription(); |